source: trunk/src/kernel32/windllbase.cpp@ 1663

Last change on this file since 1663 was 1663, checked in by sandervl, 26 years ago

heapstring fixes + dll renaming support added

File size: 10.9 KB
Line 
1/* $Id: windllbase.cpp,v 1.3 1999-11-09 14:19:47 sandervl Exp $ */
2
3/*
4 * Win32 Dll base class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_DOSFILEMGR /* File Manager values */
13#define INCL_DOSERRORS /* DOS Error values */
14#define INCL_DOSPROCESS /* DOS Process values */
15#define INCL_DOSMODULEMGR
16#define INCL_DOSMISC /* DOS Miscellanous values */
17#define INCL_WIN
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <iostream.h>
23#include <fstream.h>
24#include <misc.h>
25#include <win32type.h>
26#include <pefile.h>
27#include <windllbase.h>
28#include <wprocess.h>
29#include "exceptions.h"
30#include "exceptutil.h"
31#include "cio.h"
32#include "vmutex.h"
33#include "oslibmisc.h"
34#include "oslibdos.h"
35#include "profile.h"
36
37VMutex dlllistmutex; //protects linked lists of heaps
38
39//******************************************************************************
40//******************************************************************************
41Win32DllBase::Win32DllBase(HINSTANCE hinstance, WIN32DLLENTRY DllEntryPoint)
42 : Win32ImageBase(hinstance),
43 referenced(0), fSkipEntryCalls(FALSE),
44 fAttachedToProcess(FALSE), fUnloaded(FALSE)
45{
46 dllEntryPoint = DllEntryPoint;
47
48 dlllistmutex.enter();
49 next = head;
50 head = this;
51 dlllistmutex.leave();
52
53 dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule));
54}
55//******************************************************************************
56//******************************************************************************
57Win32DllBase::~Win32DllBase()
58{
59 Win32DllBase *dll = head;
60
61 dprintf(("Win32DllBase::~Win32DllBase %s", szModule));
62
63 if(errorState == NO_ERROR && !fUnloaded)
64 {
65 detachProcess();
66 }
67
68 dlllistmutex.enter();
69 if(head == this) {
70 head = next;
71 }
72 else {
73 while(dll && dll->next != this) {
74 dll = dll->next;
75 }
76 if(dll == NULL) {
77 dprintf(("~Win32DllBase: Can't find dll!\n"));
78 dlllistmutex.leave();
79 return;
80 }
81 dll->next = next;
82 }
83 dlllistmutex.leave();
84}
85//******************************************************************************
86//ASSUMPTION: called by FreeLibrary
87//******************************************************************************
88ULONG Win32DllBase::Release()
89{
90 ULONG ret = --referenced;
91
92 if(ret == 0) {
93 dprintf(("Win32DllBase::Release, referenced == 0\n"));
94 delete this;
95 }
96 return(ret);
97}
98//******************************************************************************
99//******************************************************************************
100BOOL Win32DllBase::attachProcess()
101{
102 WINEXCEPTION_FRAME exceptFrame;
103 USHORT sel;
104 BOOL rc;
105
106 if(fAttachedToProcess)
107 return TRUE;
108
109 fAttachedToProcess = TRUE;
110
111 //Allocate TLS index for this module
112 tlsAlloc();
113 tlsAttachThread(); //setup TLS (main thread)
114
115 if(fSkipEntryCalls || dllEntryPoint == NULL) {
116 dprintf(("attachProcess not required for dll %s", szModule));
117 return(TRUE);
118 }
119
120 dprintf(("attachProcess to dll %s", szModule));
121
122 //Note: The Win32 exception structure references by FS:[0] is the same
123 // in OS/2
124 OS2SetExceptionHandler((void *)&exceptFrame);
125
126 sel = SetWin32TIB();
127 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, 0);
128 SetFS(sel);
129
130 OS2UnsetExceptionHandler((void *)&exceptFrame);
131
132 return rc;
133}
134//******************************************************************************
135//******************************************************************************
136BOOL Win32DllBase::detachProcess()
137{
138 WINEXCEPTION_FRAME exceptFrame;
139 USHORT sel;
140 BOOL rc;
141
142 if(fSkipEntryCalls || dllEntryPoint == NULL) {
143 tlsDetachThread(); //destroy TLS (main thread)
144 fUnloaded = TRUE;
145 return(TRUE);
146 }
147
148 dprintf(("detachProcess from dll %s", szModule));
149
150 //Note: The Win32 exception structure references by FS:[0] is the same
151 // in OS/2
152 OS2SetExceptionHandler((void *)&exceptFrame);
153
154 fUnloaded = TRUE;
155 sel = SetWin32TIB();
156 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, 0);
157 SetFS(sel);
158 tlsDetachThread(); //destroy TLS (main thread)
159 tlsDelete();
160
161 OS2UnsetExceptionHandler((void *)&exceptFrame);
162
163 return rc;
164}
165//******************************************************************************
166//******************************************************************************
167BOOL Win32DllBase::attachThread()
168{
169 WINEXCEPTION_FRAME exceptFrame;
170 BOOL rc;
171
172 if(fSkipEntryCalls || dllEntryPoint == NULL)
173 return(TRUE);
174
175 dprintf(("attachThread to dll %s", szModule));
176 //Note: The Win32 exception structure references by FS:[0] is the same
177 // in OS/2
178 OS2SetExceptionHandler((void *)&exceptFrame);
179
180 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
181
182 OS2UnsetExceptionHandler((void *)&exceptFrame);
183 return rc;
184}
185//******************************************************************************
186//******************************************************************************
187BOOL Win32DllBase::detachThread()
188{
189 WINEXCEPTION_FRAME exceptFrame;
190 BOOL rc;
191
192 if(fSkipEntryCalls || dllEntryPoint == NULL)
193 return(TRUE);
194
195 dprintf(("attachThread from dll %s", szModule));
196
197 //Note: The Win32 exception structure references by FS:[0] is the same
198 // in OS/2
199 OS2SetExceptionHandler((void *)&exceptFrame);
200
201 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
202
203 OS2UnsetExceptionHandler((void *)&exceptFrame);
204 return rc;
205}
206//******************************************************************************
207//Send DLL_THREAD_ATTACH message to all dlls for a new thread
208//******************************************************************************
209void Win32DllBase::attachThreadToAllDlls()
210{
211 Win32DllBase *dll = Win32DllBase::head;
212 while(dll) {
213 dll->attachThread();
214 dll = dll->getNext();
215 }
216}
217//******************************************************************************
218//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
219//******************************************************************************
220void Win32DllBase::detachThreadFromAllDlls()
221{
222 Win32DllBase *dll = Win32DllBase::head;
223 while(dll) {
224 dll->detachThread();
225 dll = dll->getNext();
226 }
227}
228//******************************************************************************
229//Setup TLS structure for all dlls for a new thread
230//******************************************************************************
231void Win32DllBase::tlsAttachThreadToAllDlls()
232{
233 Win32DllBase *dll = Win32DllBase::head;
234 while(dll) {
235 dll->tlsAttachThread();
236 dll = dll->getNext();
237 }
238}
239//******************************************************************************
240//Destroy TLS structure for all dlls for a thread that's about to die
241//******************************************************************************
242void Win32DllBase::tlsDetachThreadFromAllDlls()
243{
244 Win32DllBase *dll = Win32DllBase::head;
245 while(dll) {
246 dll->tlsDetachThread();
247 dll = dll->getNext();
248 }
249}
250//******************************************************************************
251//******************************************************************************
252void Win32DllBase::deleteAll()
253{
254#ifdef DEBUG
255 dlllistmutex.enter();
256 Win32DllBase *dll = head;
257
258 dprintf(("Win32DllBase::deleteAll: List of loaded dlls:"));
259 while(dll) {
260 dprintf(("DLL %s", dll->szModule));
261 dll = dll->next;
262 }
263 dlllistmutex.leave();
264#endif
265
266 while(Win32DllBase::head) {
267 delete Win32DllBase::head;
268 }
269}
270//******************************************************************************
271//rename dll if necessary:
272// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
273// or
274// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
275//******************************************************************************
276void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
277{
278 char modname[CCHMAXPATH];
279 char renameddll[CCHMAXPATH];
280 char *namestart;
281 char *sectionname;
282
283 if(fWinToOS2) {
284 sectionname = DLLRENAMEWIN_SECTION;
285 }
286 else {
287 sectionname = DLLRENAMEOS2_SECTION;
288 }
289 namestart = OSLibStripPath(dllname);
290 strcpy(modname, namestart);
291 char *dot = strrchr(modname, '.');
292 if(dot)
293 *dot = 0;
294 strupr(modname);
295 if(ODIN_PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
296 sizeof(renameddll)-1) > 1)
297 {
298 if(namestart == dllname) {
299 strcpy(dllname, renameddll);
300 }
301 else {
302 *namestart = 0;
303 strcat(dllname, renameddll);
304 }
305 strcat(dllname, ".dll");
306 }
307 return;
308}
309//******************************************************************************
310//******************************************************************************
311Win32DllBase *Win32DllBase::findModule(char *dllname)
312{
313 Win32DllBase *dll;
314 char szDllName[CCHMAXPATH];
315 char *dot, *temp;
316
317 dprintf(("findModule %s", dllname));
318
319 strcpy(szDllName, OSLibStripPath(dllname));
320 strupr(szDllName);
321 dot = strstr(szDllName, ".");
322 if(dot)
323 *dot = 0;
324
325 dlllistmutex.enter();
326 dll = head;
327 while(dll) {
328 if(strcmpi(szDllName, dll->szModule) == 0) {
329 dlllistmutex.leave();
330 return(dll);
331 }
332
333 dll = dll->next;
334 }
335 dlllistmutex.leave();
336 return(NULL);
337}
338//******************************************************************************
339//******************************************************************************
340Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
341{
342 dprintf(("findModule %X", DllEntryPoint));
343
344 dlllistmutex.enter();
345 Win32DllBase *mod = Win32DllBase::head;
346 while(mod != NULL) {
347 dbgCheckObj(mod);
348 if(mod->dllEntryPoint == DllEntryPoint) {
349 dlllistmutex.leave();
350 return(mod);
351 }
352 mod = mod->next;
353 }
354 dlllistmutex.leave();
355 return(NULL);
356}
357//******************************************************************************
358//******************************************************************************
359Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
360{
361 dlllistmutex.enter();
362
363 Win32DllBase *mod = Win32DllBase::head;
364 while(mod != NULL) {
365 dbgCheckObj(mod);
366 if(mod->hinstance == hinstance) {
367 dlllistmutex.leave();
368 return(mod);
369 }
370 mod = mod->next;
371 }
372 dlllistmutex.leave();
373 return(NULL);
374}
375//******************************************************************************
376//******************************************************************************
377BOOL Win32DllBase::isDll()
378{
379 return TRUE;
380}
381//******************************************************************************
382//******************************************************************************
383void Win32DllBase::setThreadLibraryCalls(BOOL fEnable)
384{
385 // if fEnable == true, do call the ATTACH_THREAD, DETACH_THREAD functions
386 // if fEnable == false, do not call the ATTACH_THREAD, DETACH_THREAD functions
387 fSkipEntryCalls = !fEnable;
388}
389
390//******************************************************************************
391//******************************************************************************
392Win32DllBase *Win32DllBase::head = NULL;
Note: See TracBrowser for help on using the repository browser.