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

Last change on this file since 3830 was 3704, checked in by phaller, 25 years ago

Fix: StarCraft STORM.DLL requires reserved DllEntryPoint parameter

File size: 22.8 KB
Line 
1/* $Id: windllbase.cpp,v 1.14 2000-06-14 02:27:33 phaller Exp $ */
2
3/*
4 * Win32 Dll base class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * Unloading of a dll always happens in order of dependency (taking nr of
9 * loads into account)
10 * Unloading of dynamically loaded dll (with LoadLibrary) in deleteAll
11 * is done in LIFO order (NT exhibits the same behaviour)
12 *
13 * RemoveCircularDependency: TODO: Send process detach message here??
14 *
15 * Project Odin Software License can be found in LICENSE.TXT
16 *
17 */
18#define INCL_DOSFILEMGR /* File Manager values */
19#define INCL_DOSERRORS /* DOS Error values */
20#define INCL_DOSPROCESS /* DOS Process values */
21#define INCL_DOSMODULEMGR
22#define INCL_DOSMISC /* DOS Miscellanous values */
23#define INCL_WIN
24#include <os2wrap.h> //Odin32 OS/2 api wrappers
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <iostream.h>
29#include <fstream.h>
30#include <misc.h>
31#include <win32api.h>
32#include <pefile.h>
33#include <windllbase.h>
34#include <wprocess.h>
35#include "exceptions.h"
36#include "exceptutil.h"
37#include "cio.h"
38#include "vmutex.h"
39#include "oslibmisc.h"
40#include "oslibdos.h"
41#include "profile.h"
42
43#define DBG_LOCALLOG DBG_windllbase
44#include "dbglocal.h"
45
46VMutex dlllistmutex; //protects linked lists of heaps
47
48//******************************************************************************
49//******************************************************************************
50Win32DllBase::Win32DllBase(HINSTANCE hinstance, WIN32DLLENTRY DllEntryPoint,
51 Win32ImageBase *parent)
52 : Win32ImageBase(hinstance),
53 referenced(0), fSkipEntryCalls(FALSE), next(NULL), fInserted(FALSE),
54 fAttachedToProcess(FALSE), fUnloaded(FALSE),
55 nrDynamicLibRef(0), fLoadLibrary(FALSE), fDisableUnload(FALSE)
56{
57 dllEntryPoint = DllEntryPoint;
58
59 setUnloadOrder(parent);
60
61 dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule));
62}
63//******************************************************************************
64//******************************************************************************
65Win32DllBase::~Win32DllBase()
66{
67 dprintf(("Win32DllBase::~Win32DllBase %s", szModule));
68
69 if(errorState == NO_ERROR && !fUnloaded)
70 {
71 detachProcess();
72 }
73
74 dlllistmutex.enter();
75 if(head == this) {
76 head = next;
77 }
78 else {
79 Win32DllBase *dll = head;
80 while(dll && dll->next != this) {
81 dll = dll->next;
82 }
83 if(dll == NULL) {
84 dprintf(("~Win32DllBase: Can't find dll!\n"));
85 dlllistmutex.leave();
86 return;
87 }
88 dll->next = next;
89 }
90 dlllistmutex.leave();
91}
92//******************************************************************************
93//******************************************************************************
94void Win32DllBase::loadLibrary()
95{
96 //dummy
97}
98//******************************************************************************
99//******************************************************************************
100void Win32DllBase::incDynamicLib()
101{
102 if(nrDynamicLibRef == 0) {
103 dlllistmutex.enter();
104 loadLibDlls.Push((ULONG)this);
105 dlllistmutex.leave();
106 }
107 nrDynamicLibRef++;
108}
109//******************************************************************************
110//******************************************************************************
111void Win32DllBase::decDynamicLib()
112{
113 nrDynamicLibRef--;
114 if(nrDynamicLibRef == 0) {
115 dlllistmutex.enter();
116 loadLibDlls.Remove((ULONG)this);
117 dlllistmutex.leave();
118 }
119}
120//******************************************************************************
121//unload of dlls needs to be done in reverse order of dependencies
122//Note: Only necessary for pe loader; the OS/2 loader takes care of this
123//for win32k/pe2lx
124//******************************************************************************
125void Win32DllBase::setUnloadOrder(Win32ImageBase *parent)
126{
127 Win32DllBase *dll;
128 Win32DllBase *parentdll = NULL;
129
130 dlllistmutex.enter();
131 if(parent) {
132 dll = head;
133 while(dll) {
134 if(dll->getInstanceHandle() == parent->getInstanceHandle()) {
135 parentdll = dll;
136 break;
137 }
138 dll = dll->next;
139 }
140 }
141
142 //first check if this dll is already at a lower position (further down the list)
143 //than the parent
144 if(parentdll && fInserted) {//already in the list?
145 dll = parentdll->next;
146 while(dll) {
147 if(dll->getInstanceHandle() == getInstanceHandle()) {
148 dlllistmutex.leave();
149 return; //it's at a lower position, so no need to change anything
150 }
151 dll = dll->next;
152 }
153
154 //it's already in the list but not at the right position; remove it now
155 if(head == this) {
156 head = next;
157 }
158 else {
159 dll = head;
160 while(dll->next) {
161 if(dll->next == this) {
162 dll->next = next;
163 break;
164 }
165 dll = dll->next;
166 }
167 }
168 }
169 else
170 if(fInserted) {//already in the list?
171 dlllistmutex.leave();
172 return;
173 }
174 //(re)insert it in the list after it's parent
175 if(parentdll) {
176 next = parentdll->next;
177 parentdll->next = this;
178 }
179 else {//no parent or exe, just add it at the start of the list
180 next = head;
181 head = this;
182 }
183 fInserted = TRUE;
184
185 //Now do the same thing for the child dependencies
186 QueueItem *item;
187
188 item = loadedDlls.Head();
189 while(item) {
190 dll = (Win32DllBase *)loadedDlls.getItem(item);
191 //Check for circular dependencies (i.e. in Lotus Notes)
192 if(dll != parentdll) {
193 dll->setUnloadOrder(this);
194 }
195
196 item = loadedDlls.getNext(item);
197 }
198
199 dlllistmutex.leave();
200}
201//******************************************************************************
202//******************************************************************************
203#ifdef DEBUG
204ULONG Win32DllBase::AddRef(char *parentname)
205#else
206ULONG Win32DllBase::AddRef()
207#endif
208{
209 Win32DllBase *dll;
210
211 dprintf(("Win32DllBase::AddRef %s->%s %d", parentname, getModuleName(), referenced+1));
212 ++referenced;
213#ifdef DEBUG
214 if(referenced == 1) {
215#ifdef DEBUG_ENABLELOG_LEVEL2
216 printListOfDlls();
217#endif
218 //printDependencies(NULL);
219 }
220#endif
221
222 return referenced;
223}
224//******************************************************************************
225//******************************************************************************
226ULONG Win32DllBase::Release()
227{
228 Queue queue;
229 QueueItem *item;
230 Win32DllBase *dll;
231 LONG ret;
232
233 dprintf(("Win32DllBase::Release %s %d", getModuleName(), referenced-1));
234
235 ret = --referenced;
236 if(ret <= 0) {
237 //make copy of linked list of dependencies
238 queue = loadedDlls;
239
240 //remove any circular dependencies on this dll that might be present
241 item = queue.Head();
242 while(item) {
243 dll = (Win32DllBase *)queue.getItem(item);
244 if(dll == NULL) {
245 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!"));
246 DebugInt3();
247 return -1;
248 }
249 dll->RemoveCircularDependency(this);
250 item = queue.getNext(item);
251 }
252#ifdef DEBUG
253 //printDependencies(NULL);
254#endif
255 dprintf(("Win32DllBase::Release %s referenced == 0", getModuleName()));
256
257 //delete dll object
258 delete this;
259
260 //unreference all of it's dependencies
261 item = queue.Head();
262 while(item) {
263 dll = (Win32DllBase *)queue.getItem(item);
264 if(dll == NULL) {
265 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!"));
266 DebugInt3();
267 return -1;
268 }
269 dll->Release();
270 item = queue.getNext(item);
271 }
272 }
273 return(ret);
274}
275//******************************************************************************
276//Lotus Notes has several ugly circular dependencies in it's dlls.
277//Remove them before they cause problems.
278//******************************************************************************
279BOOL Win32DllBase::RemoveCircularDependency(Win32DllBase *parent)
280{
281 QueueItem *item, *tmp;
282 Win32DllBase *dll;
283 BOOL ret = FALSE;
284
285 //remove any circular dependencies on this dll that might be present
286 item = loadedDlls.Head();
287 while(item) {
288 dll = (Win32DllBase *)loadedDlls.getItem(item);
289 if(dll == NULL) {
290 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!"));
291 DebugInt3();
292 return FALSE;
293 }
294 tmp = loadedDlls.getNext(item);
295 if(dll == parent) {
296 dprintf(("Removing CIRCULAR dependency %s->%s", parent->getModuleName(), dll->getModuleName()));
297 loadedDlls.Remove(item);
298 ret = TRUE;
299 }
300//// else ret |= dll->RemoveCircularDependency(parent);
301 item = tmp;
302 }
303 //TODO: Send process detach message here??
304 return ret;
305}
306//******************************************************************************
307//There's a slight problem with our dependency procedure.
308//example: gdi32 is loaded -> depends on kernel32 (which is already loaded)
309// kernel32's reference count isn't updated
310// (when we load gdi32, we don't know which dlls it depends on and which
311// of those are already loaded and which aren't)
312//-> solution: Determine reference counts of dependant lx dlls and update those
313// reference counts
314//******************************************************************************
315void Win32DllBase::updateDependencies()
316{
317 QueueItem *item;
318 Win32DllBase *dll, *depdll;
319 ULONG refcount;
320
321 dlllistmutex.enter();
322 item = loadedDlls.Head();
323 while(item) {
324 depdll = (Win32DllBase *)loadedDlls.getItem(item);
325 if(depdll == NULL) {
326 dprintf(("updateDependencies: depdll == NULL!!"));
327 DebugInt3();
328 return;
329 }
330 refcount = 0;
331 dll = head;
332
333 while(dll) {
334 if(dll->dependsOn(depdll)) {
335 refcount++;
336 }
337 dll = dll->getNext();
338 }
339 if(refcount > depdll->referenced) {
340 dprintf(("Win32DllBase::updateDependencies changing refcount of %s to %d (old=%d)", depdll->getModuleName(), refcount, depdll->referenced));
341 depdll->referenced = refcount;
342 }
343
344 item = loadedDlls.getNext(item);
345 }
346 dlllistmutex.leave();
347}
348//******************************************************************************
349//******************************************************************************
350#ifdef DEBUG
351void Win32DllBase::printDependencies(char *parent)
352{
353 QueueItem *item;
354 Win32DllBase *dll;
355 ULONG ret;
356
357 dprintf(("Dependency list: %s->%s %d", parent, getModuleName(), referenced));
358 item = loadedDlls.Head();
359 while(item) {
360 dll = (Win32DllBase *)loadedDlls.getItem(item);
361 if(dll == NULL) {
362 return;
363 }
364 dll->printDependencies(getModuleName());
365 item = loadedDlls.getNext(item);
366 }
367}
368//******************************************************************************
369//******************************************************************************
370#ifdef DEBUG_ENABLELOG_LEVEL2
371void Win32DllBase::printListOfDlls()
372{
373 Win32DllBase *dll;
374
375 dll = head;
376
377 dprintf2(("Win32DllBase::Win32DllBase: List of loaded dlls:"));
378 while(dll) {
379 dprintf2(("DLL %s %d", dll->szModule, dll->referenced));
380 dll = dll->next;
381 }
382}
383#endif
384#endif
385//******************************************************************************
386//******************************************************************************
387BOOL Win32DllBase::attachProcess()
388{
389 WINEXCEPTION_FRAME exceptFrame;
390 USHORT sel;
391 THDB *thdb;
392 BOOL rc, fSetExceptionHandler;
393
394 if(fAttachedToProcess)
395 return TRUE;
396
397 fAttachedToProcess = TRUE;
398
399 thdb = GetThreadTHDB();
400 fSetExceptionHandler = (!thdb || thdb->teb_sel != GetFS());
401
402 //Note: The Win32 exception structure references by FS:[0] is the same
403 // in OS/2
404 if(fSetExceptionHandler) {
405 OS2SetExceptionHandler((void *)&exceptFrame);
406 sel = SetWin32TIB();
407 }
408
409 //Allocate TLS index for this module
410 tlsAlloc();
411 tlsAttachThread(); //setup TLS (main thread)
412
413 if(fSkipEntryCalls || dllEntryPoint == NULL) {
414 dprintf(("attachProcess not required for dll %s", szModule));
415 if(fSetExceptionHandler) {
416 SetFS(sel);
417 OS2UnsetExceptionHandler((void *)&exceptFrame);
418 }
419 return(TRUE);
420 }
421
422 dprintf(("attachProcess to dll %s", szModule));
423
424 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
425 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
426 // and non-NULL for static loads.
427 // same goes for process termination
428 LPVOID lpvReserved;
429
430 if (isDynamicLib())
431 lpvReserved = NULL;
432 else
433 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
434
435 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, lpvReserved);
436
437 dprintf(("attachProcess to dll %s DONE", szModule));
438
439 if(fSetExceptionHandler) {
440 SetFS(sel);
441 OS2UnsetExceptionHandler((void *)&exceptFrame);
442 }
443 else
444 if(thdb) {
445 if(thdb->teb_sel != GetFS()) {
446 dprintf(("Win32DllBase::attachProcess: FS was changed by dll entrypoint!!!!"));
447 DebugInt3();
448 }
449 }
450 return rc;
451}
452//******************************************************************************
453//******************************************************************************
454BOOL Win32DllBase::detachProcess()
455{
456 WINEXCEPTION_FRAME exceptFrame;
457 USHORT sel;
458 BOOL rc;
459
460 if(fSkipEntryCalls || dllEntryPoint == NULL) {
461 tlsDetachThread(); //destroy TLS (main thread)
462 fUnloaded = TRUE;
463 return(TRUE);
464 }
465
466 dprintf(("detachProcess from dll %s", szModule));
467
468 //Note: The Win32 exception structure references by FS:[0] is the same
469 // in OS/2
470 OS2SetExceptionHandler((void *)&exceptFrame);
471
472 fUnloaded = TRUE;
473 sel = SetWin32TIB();
474
475 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
476 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
477 // and non-NULL for static loads.
478 // same goes for process termination
479 LPVOID lpvReserved;
480
481 if (isDynamicLib())
482 lpvReserved = NULL;
483 else
484 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
485
486 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, lpvReserved);
487
488 SetFS(sel);
489 tlsDetachThread(); //destroy TLS (main thread)
490 tlsDelete();
491
492 OS2UnsetExceptionHandler((void *)&exceptFrame);
493
494 return rc;
495}
496//******************************************************************************
497//******************************************************************************
498BOOL Win32DllBase::attachThread()
499{
500 WINEXCEPTION_FRAME exceptFrame;
501 BOOL rc;
502
503 if(fSkipEntryCalls || dllEntryPoint == NULL)
504 return(TRUE);
505
506 dprintf(("attachThread to dll %s", szModule));
507
508 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
509
510 dprintf(("attachThread to dll %s DONE", szModule));
511
512 return rc;
513}
514//******************************************************************************
515//******************************************************************************
516BOOL Win32DllBase::detachThread()
517{
518 WINEXCEPTION_FRAME exceptFrame;
519 BOOL rc;
520
521 if(fSkipEntryCalls || dllEntryPoint == NULL)
522 return(TRUE);
523
524 dprintf(("detachThread from dll %s", szModule));
525
526 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
527 return rc;
528}
529//******************************************************************************
530//Send DLL_THREAD_ATTACH message to all dlls for a new thread
531//******************************************************************************
532void Win32DllBase::attachThreadToAllDlls()
533{
534 dlllistmutex.enter();
535 Win32DllBase *dll = Win32DllBase::head;
536 while(dll) {
537 dll->attachThread();
538 dll = dll->getNext();
539 }
540 dlllistmutex.leave();
541}
542//******************************************************************************
543//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
544//******************************************************************************
545void Win32DllBase::detachThreadFromAllDlls()
546{
547 dlllistmutex.enter();
548 Win32DllBase *dll = Win32DllBase::head;
549 while(dll) {
550 dll->detachThread();
551 dll = dll->getNext();
552 }
553 dlllistmutex.leave();
554}
555//******************************************************************************
556//Setup TLS structure for all dlls for a new thread
557//******************************************************************************
558void Win32DllBase::tlsAttachThreadToAllDlls()
559{
560 dlllistmutex.enter();
561 Win32DllBase *dll = Win32DllBase::head;
562 while(dll) {
563 dll->tlsAttachThread();
564 dll = dll->getNext();
565 }
566 dlllistmutex.leave();
567}
568//******************************************************************************
569//Destroy TLS structure for all dlls for a thread that's about to die
570//******************************************************************************
571void Win32DllBase::tlsDetachThreadFromAllDlls()
572{
573 dlllistmutex.enter();
574 Win32DllBase *dll = Win32DllBase::head;
575 while(dll) {
576 dll->tlsDetachThread();
577 dll = dll->getNext();
578 }
579 dlllistmutex.leave();
580}
581//******************************************************************************
582//******************************************************************************
583void Win32DllBase::deleteAll()
584{
585 Win32DllBase *dll = Win32DllBase::head;
586
587 dprintf(("Win32DllBase::deleteAll"));
588
589#ifdef DEBUG_ENABLELOG_LEVEL2
590 if(dll) dll->printListOfDlls();
591#endif
592
593 dlllistmutex.enter();
594 while(dll) {
595 dll->Release();
596 dll = Win32DllBase::head;
597 }
598 dlllistmutex.leave();
599 dprintf(("Win32DllBase::deleteAll Done!"));
600}
601//******************************************************************************
602//Delete dlls loaded by LoadLibrary(Ex) in LIFO order
603//******************************************************************************
604void Win32DllBase::deleteDynamicLibs()
605{
606 Win32DllBase *dll = head;
607 QueueItem *item;
608
609 dprintf(("Win32DllBase::deleteDynamicLibs"));
610#ifdef DEBUG_ENABLELOG_LEVEL2
611 if(dll) dll->printListOfDlls();
612#endif
613
614 dlllistmutex.enter();
615
616 item = loadLibDlls.Head();
617 while(item) {
618 dll = (Win32DllBase *)loadLibDlls.getItem(item);
619 int dynref = dll->nrDynamicLibRef;
620 if(dynref) {
621 while(dynref) {
622 dynref--;
623 dll->decDynamicLib();
624 dll->Release();
625 }
626 }
627 else DebugInt3();
628 item = loadLibDlls.Head(); //queue could have been changed, so start from the beginning
629 }
630
631 dlllistmutex.leave();
632}
633//******************************************************************************
634//******************************************************************************
635Win32DllBase *Win32DllBase::getFirst()
636{
637 return head;
638}
639//******************************************************************************
640//Add renaming profile strings for ole32 & netapi32 to odin.ini if they aren't
641//already there
642//******************************************************************************
643void Win32DllBase::setDefaultRenaming()
644{
645 char renameddll[CCHMAXPATH];
646
647 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll,
648 sizeof(renameddll)-1) <= 1)
649 {
650 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2");
651 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32");
652 }
653 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "", renameddll,
654 sizeof(renameddll)-1) <= 1)
655 {
656 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "OLAUTOS2");
657 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLAUTOS2", "OLEAUT32");
658 }
659 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll,
660 sizeof(renameddll)-1) <= 1)
661 {
662 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
663 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
664 }
665}
666//******************************************************************************
667//rename dll if necessary:
668// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
669// or
670// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
671//******************************************************************************
672void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
673{
674 char modname[CCHMAXPATH];
675 char renameddll[CCHMAXPATH];
676 char *namestart;
677 char *sectionname;
678
679 if(fWinToOS2) {
680 sectionname = DLLRENAMEWIN_SECTION;
681 }
682 else {
683 sectionname = DLLRENAMEOS2_SECTION;
684 }
685 namestart = OSLibStripPath(dllname);
686 strcpy(modname, namestart);
687 char *dot = strrchr(modname, '.');
688 if(dot)
689 *dot = 0;
690 strupr(modname);
691 if(ODIN_PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
692 sizeof(renameddll)-1) > 1)
693 {
694 if(namestart == dllname) {
695 strcpy(dllname, renameddll);
696 }
697 else {
698 *namestart = 0;
699 strcat(dllname, renameddll);
700 }
701 strcat(dllname, ".dll");
702 }
703 return;
704}
705//******************************************************************************
706//******************************************************************************
707Win32DllBase *Win32DllBase::findModule(char *dllname, BOOL fRenameFirst)
708{
709 Win32DllBase *dll;
710 char szDllName[CCHMAXPATH];
711 char *dot, *temp;
712
713//// dprintf2(("findModule %s", dllname));
714
715 strcpy(szDllName, OSLibStripPath(dllname));
716 strupr(szDllName);
717
718 if(fRenameFirst) {
719 renameDll(szDllName, FALSE);
720 }
721
722 dot = strstr(szDllName, ".");
723 if(dot)
724 *dot = 0;
725
726 dlllistmutex.enter();
727 dll = head;
728 while(dll) {
729 if(strcmpi(szDllName, dll->szModule) == 0) {
730 dlllistmutex.leave();
731 return(dll);
732 }
733
734 dll = dll->next;
735 }
736 dlllistmutex.leave();
737 return(NULL);
738}
739//******************************************************************************
740//******************************************************************************
741Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
742{
743 dprintf2(("findModule %X", DllEntryPoint));
744
745 dlllistmutex.enter();
746 Win32DllBase *mod = Win32DllBase::head;
747 while(mod != NULL) {
748 dbgCheckObj(mod);
749 if(mod->dllEntryPoint == DllEntryPoint) {
750 dlllistmutex.leave();
751 return(mod);
752 }
753 mod = mod->next;
754 }
755 dlllistmutex.leave();
756 return(NULL);
757}
758//******************************************************************************
759//******************************************************************************
760Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
761{
762 dlllistmutex.enter();
763
764 Win32DllBase *mod = Win32DllBase::head;
765 while(mod != NULL) {
766 dbgCheckObj(mod);
767 if(mod->hinstance == hinstance) {
768 dlllistmutex.leave();
769 return(mod);
770 }
771 mod = mod->next;
772 }
773 dlllistmutex.leave();
774 return(NULL);
775}
776//******************************************************************************
777//******************************************************************************
778Win32DllBase *Win32DllBase::findModuleByAddr(ULONG address)
779{
780 dlllistmutex.enter();
781
782 Win32DllBase *mod = Win32DllBase::head;
783 while(mod != NULL) {
784 dbgCheckObj(mod);
785 if(mod->insideModule(address)) {
786 dlllistmutex.leave();
787 return(mod);
788 }
789 mod = mod->next;
790 }
791 dlllistmutex.leave();
792 return(NULL);
793}
794//******************************************************************************
795//******************************************************************************
796BOOL Win32DllBase::isDll()
797{
798 return TRUE;
799}
800//******************************************************************************
801//******************************************************************************
802void Win32DllBase::setThreadLibraryCalls(BOOL fEnable)
803{
804 // if fEnable == true, do call the ATTACH_THREAD, DETACH_THREAD functions
805 // if fEnable == false, do not call the ATTACH_THREAD, DETACH_THREAD functions
806 fSkipEntryCalls = !fEnable;
807}
808
809//******************************************************************************
810//******************************************************************************
811Win32DllBase *Win32DllBase::head = NULL;
812Queue Win32DllBase::loadLibDlls;
Note: See TracBrowser for help on using the repository browser.