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

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

Forgot to append .dll if no extension is found in Win32DllBase::findModule

File size: 25.4 KB
Line 
1/* $Id: windllbase.cpp,v 1.21 2000-10-30 16:38:54 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 dot = strstr(szDllName, ".");
735 if(dot == NULL) {
736 //if there's no extension or trainling dot, we
737 //assume it's a dll (see Win32 SDK docs)
738 strcat(szDllName, DLL_EXTENSION);
739 }
740 else {
741 if(dot[1] == 0) {
742 //a trailing dot means the module has no extension (SDK docs)
743 *dot = 0;
744 }
745 }
746
747 dlllistmutex.enter();
748 dll = head;
749 while(dll) {
750 if(strcmpi(szDllName, dll->szModule) == 0) {
751 dlllistmutex.leave();
752 return(dll);
753 }
754 dll = dll->next;
755 }
756 dlllistmutex.leave();
757 return(NULL);
758}
759//******************************************************************************
760//******************************************************************************
761Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
762{
763 dprintf2(("findModule %X", DllEntryPoint));
764
765 dlllistmutex.enter();
766 Win32DllBase *mod = Win32DllBase::head;
767 while(mod != NULL) {
768 dbgCheckObj(mod);
769 if(mod->dllEntryPoint == DllEntryPoint) {
770 dlllistmutex.leave();
771 return(mod);
772 }
773 mod = mod->next;
774 }
775 dlllistmutex.leave();
776 return(NULL);
777}
778//******************************************************************************
779//******************************************************************************
780Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
781{
782 dlllistmutex.enter();
783
784 Win32DllBase *mod = Win32DllBase::head;
785 while(mod != NULL) {
786 dbgCheckObj(mod);
787 if(mod->hinstance == hinstance) {
788 dlllistmutex.leave();
789 return(mod);
790 }
791 mod = mod->next;
792 }
793 dlllistmutex.leave();
794 return(NULL);
795}
796//******************************************************************************
797//******************************************************************************
798Win32DllBase *Win32DllBase::findModuleByAddr(ULONG address)
799{
800 dlllistmutex.enter();
801
802 Win32DllBase *mod = Win32DllBase::head;
803 while(mod != NULL) {
804 dbgCheckObj(mod);
805 if(mod->insideModule(address)) {
806 dlllistmutex.leave();
807 return(mod);
808 }
809 mod = mod->next;
810 }
811 dlllistmutex.leave();
812 return(NULL);
813}
814//******************************************************************************
815//******************************************************************************
816BOOL Win32DllBase::isDll()
817{
818 return TRUE;
819}
820//******************************************************************************
821//******************************************************************************
822Win32DllBase *Win32DllBase::head = NULL;
823Queue Win32DllBase::loadLibDlls;
Note: See TracBrowser for help on using the repository browser.