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

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

SearchPathA fix (multiple dirs), add rename odin.ini entry for winspool.drv, extra pointer checks in Read/WriteProcessMemory

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