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

Last change on this file since 3854 was 3854, checked in by sandervl, 25 years ago

dll unload fix + detach skip fix

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