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

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

TLS index allocation + RtlUnwind fixes

File size: 25.6 KB
Line 
1/* $Id: windllbase.cpp,v 1.24 2001-02-14 10:36:45 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 TEB *teb;
390 BOOL rc, fSetExceptionHandler;
391
392 if(fAttachedToProcess || fSkipEntryCalls)
393 return TRUE;
394
395 fAttachedToProcess = TRUE;
396
397 teb = GetThreadTEB();
398 fSetExceptionHandler = (!teb || teb->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 if(dllEntryPoint == NULL) {
408 dprintf(("attachProcess not required for dll %s", szModule));
409 if(fSetExceptionHandler) {
410 SetFS(sel);
411 OS2UnsetExceptionHandler((void *)&exceptFrame);
412 }
413 return(TRUE);
414 }
415
416 dprintf(("attachProcess to dll %s", szModule));
417
418 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
419 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
420 // and non-NULL for static loads.
421 // same goes for process termination
422 LPVOID lpvReserved;
423
424 if (isDynamicLib())
425 lpvReserved = NULL;
426 else
427 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
428
429 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, lpvReserved);
430
431 dprintf(("attachProcess to dll %s DONE", szModule));
432
433 if(fSetExceptionHandler) {
434 SetFS(sel);
435 OS2UnsetExceptionHandler((void *)&exceptFrame);
436 }
437 else
438 if(teb) {
439 if(teb->teb_sel != GetFS()) {
440 dprintf(("Win32DllBase::attachProcess: FS was changed by dll entrypoint!!!!"));
441 DebugInt3();
442 }
443 }
444 return rc;
445}
446//******************************************************************************
447//******************************************************************************
448BOOL Win32DllBase::detachProcess()
449{
450 WINEXCEPTION_FRAME exceptFrame;
451 USHORT sel;
452 BOOL rc;
453
454 if(fSkipEntryCalls) {
455 fUnloaded = TRUE;
456 return TRUE;
457 }
458
459 if(dllEntryPoint == NULL) {
460 tlsDetachThread(); //destroy TLS (main thread)
461 fUnloaded = TRUE;
462 return(TRUE);
463 }
464
465 dprintf(("detachProcess from dll %s", szModule));
466
467 //Note: The Win32 exception structure references by FS:[0] is the same
468 // in OS/2
469 OS2SetExceptionHandler((void *)&exceptFrame);
470
471 fUnloaded = TRUE;
472 sel = SetWin32TIB();
473
474 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
475 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
476 // and non-NULL for static loads.
477 // same goes for process termination
478 LPVOID lpvReserved;
479
480 if (isDynamicLib())
481 lpvReserved = NULL;
482 else
483 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
484
485 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, lpvReserved);
486
487 SetFS(sel);
488 tlsDetachThread(); //destroy TLS (main thread)
489 tlsDelete();
490
491 OS2UnsetExceptionHandler((void *)&exceptFrame);
492
493 return rc;
494}
495//******************************************************************************
496//******************************************************************************
497BOOL Win32DllBase::attachThread()
498{
499 WINEXCEPTION_FRAME exceptFrame;
500 BOOL rc;
501
502 if(fSkipThreadEntryCalls || dllEntryPoint == NULL)
503 return(TRUE);
504
505 dprintf(("attachThread to dll %s", szModule));
506
507 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
508
509 dprintf(("attachThread to dll %s DONE", szModule));
510
511 return rc;
512}
513//******************************************************************************
514//******************************************************************************
515BOOL Win32DllBase::detachThread()
516{
517 WINEXCEPTION_FRAME exceptFrame;
518 BOOL rc;
519
520 if(fSkipThreadEntryCalls || dllEntryPoint == NULL)
521 return(TRUE);
522
523 dprintf(("detachThread from dll %s", szModule));
524
525 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
526 return rc;
527}
528//******************************************************************************
529//Send DLL_THREAD_ATTACH message to all dlls for a new thread
530//******************************************************************************
531void Win32DllBase::attachThreadToAllDlls()
532{
533 dlllistmutex.enter();
534 Win32DllBase *dll = Win32DllBase::head;
535 while(dll) {
536 dll->attachThread();
537 dll = dll->getNext();
538 }
539 dlllistmutex.leave();
540}
541//******************************************************************************
542//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
543//******************************************************************************
544void Win32DllBase::detachThreadFromAllDlls()
545{
546 dlllistmutex.enter();
547 Win32DllBase *dll = Win32DllBase::head;
548 while(dll) {
549 dll->detachThread();
550 dll = dll->getNext();
551 }
552 dlllistmutex.leave();
553}
554//******************************************************************************
555//Setup TLS structure for all dlls for a new thread
556//******************************************************************************
557void Win32DllBase::tlsAttachThreadToAllDlls()
558{
559 dlllistmutex.enter();
560 Win32DllBase *dll = Win32DllBase::head;
561 while(dll) {
562 dll->tlsAttachThread();
563 dll = dll->getNext();
564 }
565 dlllistmutex.leave();
566}
567//******************************************************************************
568//Destroy TLS structure for all dlls for a thread that's about to die
569//******************************************************************************
570void Win32DllBase::tlsDetachThreadFromAllDlls()
571{
572 dlllistmutex.enter();
573 Win32DllBase *dll = Win32DllBase::head;
574 while(dll) {
575 dll->tlsDetachThread();
576 dll = dll->getNext();
577 }
578 dlllistmutex.leave();
579}
580//******************************************************************************
581//******************************************************************************
582void Win32DllBase::deleteAll()
583{
584 Win32DllBase *dll = Win32DllBase::head;
585
586 dprintf(("Win32DllBase::deleteAll"));
587
588#ifdef DEBUG_ENABLELOG_LEVEL2
589 if(dll) dll->printListOfDlls();
590#endif
591
592 dlllistmutex.enter();
593 while(dll) {
594 dll->Release();
595 dll = Win32DllBase::head;
596 }
597 dlllistmutex.leave();
598 dprintf(("Win32DllBase::deleteAll Done!"));
599}
600//******************************************************************************
601//Delete dlls loaded by LoadLibrary(Ex) in LIFO order
602//******************************************************************************
603void Win32DllBase::deleteDynamicLibs()
604{
605 Win32DllBase *dll = head;
606 QueueItem *item;
607
608 dprintf(("Win32DllBase::deleteDynamicLibs"));
609#ifdef DEBUG_ENABLELOG_LEVEL2
610 if(dll) dll->printListOfDlls();
611#endif
612
613 dlllistmutex.enter();
614
615 item = loadLibDlls.Head();
616 while(item) {
617 dll = (Win32DllBase *)loadLibDlls.getItem(item);
618 int dynref = dll->nrDynamicLibRef;
619 if(dynref) {
620 while(dynref) {
621 dynref--;
622 dll->decDynamicLib();
623 dll->Release();
624 }
625 }
626 else DebugInt3();
627 item = loadLibDlls.Head(); //queue could have been changed, so start from the beginning
628 }
629
630 dlllistmutex.leave();
631 dprintf(("Win32DllBase::deleteDynamicLibs end"));
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(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll,
648 sizeof(renameddll)-1) <= 1)
649 {
650 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2");
651 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32");
652 }
653 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "", renameddll,
654 sizeof(renameddll)-1) <= 1)
655 {
656 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "OLAUTOS2");
657 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLAUTOS2", "OLEAUT32");
658 }
659 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll,
660 sizeof(renameddll)-1) <= 1)
661 {
662 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
663 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
664 }
665 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "WINSPOOL", "", renameddll,
666 sizeof(renameddll)-1) <= 1)
667 {
668 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "WINSPOOL", "WINSPOOL.DLL");
669 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WINSPOOL", "WINSPOOL.DRV");
670 }
671 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "MCICDA", "", renameddll,
672 sizeof(renameddll)-1) <= 1)
673 {
674 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "MCICDA", "MCICDA.DLL");
675 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "MCICDA", "MCICDA.DRV");
676 }
677}
678//******************************************************************************
679//rename dll if necessary:
680// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
681// or
682// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
683//******************************************************************************
684void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
685{
686 char modname[CCHMAXPATH];
687 char renameddll[CCHMAXPATH];
688 char *namestart;
689 char *sectionname;
690
691 if(fWinToOS2) {
692 sectionname = DLLRENAMEWIN_SECTION;
693 }
694 else {
695 sectionname = DLLRENAMEOS2_SECTION;
696 }
697 namestart = OSLibStripPath(dllname);
698 strcpy(modname, namestart);
699 char *dot = strrchr(modname, '.');
700 if(dot)
701 *dot = 0;
702 strupr(modname);
703 if(PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
704 sizeof(renameddll)-1) > 1)
705 {
706 if(namestart == dllname) {
707 strcpy(dllname, renameddll);
708 }
709 else {
710 *namestart = 0;
711 strcat(dllname, renameddll);
712 }
713 if(!strchr(dllname, '.')) {
714 strcat(dllname, DLL_EXTENSION);
715 }
716 strupr(dllname);
717 }
718 return;
719}
720//******************************************************************************
721//******************************************************************************
722Win32DllBase *Win32DllBase::findModule(char *dllname, BOOL fRenameFirst)
723{
724 Win32DllBase *dll;
725 char szDllName[CCHMAXPATH];
726 char *dot, *temp;
727
728//// dprintf2(("findModule %s", dllname));
729
730 strcpy(szDllName, OSLibStripPath(dllname));
731 strupr(szDllName);
732
733 if(fRenameFirst) {
734 renameDll(szDllName, FALSE);
735 }
736 dot = strstr(szDllName, ".");
737 if(dot == NULL) {
738 //if there's no extension or trainling dot, we
739 //assume it's a dll (see Win32 SDK docs)
740 strcat(szDllName, DLL_EXTENSION);
741 }
742 else {
743 if(dot[1] == 0) {
744 //a trailing dot means the module has no extension (SDK docs)
745 *dot = 0;
746 }
747 }
748
749 dlllistmutex.enter();
750 dll = head;
751 while(dll) {
752 if(strcmpi(szDllName, dll->szModule) == 0) {
753 dlllistmutex.leave();
754 return(dll);
755 }
756 dll = dll->next;
757 }
758 dlllistmutex.leave();
759 return(NULL);
760}
761//******************************************************************************
762//******************************************************************************
763Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
764{
765 dprintf2(("findModule %X", DllEntryPoint));
766
767 dlllistmutex.enter();
768 Win32DllBase *mod = Win32DllBase::head;
769 while(mod != NULL) {
770 dbgCheckObj(mod);
771 if(mod->dllEntryPoint == DllEntryPoint) {
772 dlllistmutex.leave();
773 return(mod);
774 }
775 mod = mod->next;
776 }
777 dlllistmutex.leave();
778 return(NULL);
779}
780//******************************************************************************
781//******************************************************************************
782Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
783{
784 dlllistmutex.enter();
785
786 Win32DllBase *mod = Win32DllBase::head;
787 while(mod != NULL) {
788 dbgCheckObj(mod);
789 if(mod->hinstance == hinstance) {
790 dlllistmutex.leave();
791 return(mod);
792 }
793 mod = mod->next;
794 }
795 dlllistmutex.leave();
796 return(NULL);
797}
798//******************************************************************************
799//******************************************************************************
800Win32DllBase *Win32DllBase::findModuleByAddr(ULONG address)
801{
802 dlllistmutex.enter();
803
804 Win32DllBase *mod = Win32DllBase::head;
805 while(mod != NULL) {
806 dbgCheckObj(mod);
807 if(mod->insideModule(address)) {
808 dlllistmutex.leave();
809 return(mod);
810 }
811 mod = mod->next;
812 }
813 dlllistmutex.leave();
814 return(NULL);
815}
816//******************************************************************************
817//******************************************************************************
818BOOL Win32DllBase::isDll()
819{
820 return TRUE;
821}
822//******************************************************************************
823//******************************************************************************
824Win32DllBase *Win32DllBase::head = NULL;
825Queue Win32DllBase::loadLibDlls;
Note: See TracBrowser for help on using the repository browser.