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

Last change on this file since 5782 was 5782, checked in by sandervl, 24 years ago

Check name before adding dependency for module

File size: 25.8 KB
Line 
1/* $Id: windllbase.cpp,v 1.25 2001-05-22 14:25:34 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
255 dprintf(("Win32DllBase::Release %s referenced == 0", getModuleName()));
256
257 //delete dll object
258 delete this;
259
260 //unreference all of it's dependencies
261 item = queue.Head();
262 while(item) {
263 dll = (Win32DllBase *)queue.getItem(item);
264 if(dll == NULL) {
265 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!"));
266 DebugInt3();
267 return -1;
268 }
269 dll->Release();
270 item = queue.getNext(item);
271 }
272 }
273 return(ret);
274}
275//******************************************************************************
276//Lotus Notes has several ugly circular dependencies in it's dlls.
277//Remove them before they cause problems.
278//******************************************************************************
279BOOL Win32DllBase::RemoveCircularDependency(Win32DllBase *parent)
280{
281 QueueItem *item, *tmp;
282 Win32DllBase *dll;
283 BOOL ret = FALSE;
284
285 //remove any circular dependencies on this dll that might be present
286 item = loadedDlls.Head();
287 while(item) {
288 dll = (Win32DllBase *)loadedDlls.getItem(item);
289 if(dll == NULL) {
290 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!"));
291 DebugInt3();
292 return FALSE;
293 }
294 tmp = loadedDlls.getNext(item);
295 if(dll == parent) {
296 dprintf(("Removing CIRCULAR dependency %s->%s", parent->getModuleName(), dll->getModuleName()));
297 loadedDlls.Remove(item);
298 ret = TRUE;
299 }
300//// else ret |= dll->RemoveCircularDependency(parent);
301 item = tmp;
302 }
303 //TODO: Send process detach message here??
304 return ret;
305}
306//******************************************************************************
307//There's a slight problem with our dependency procedure.
308//example: gdi32 is loaded -> depends on kernel32 (which is already loaded)
309// kernel32's reference count isn't updated
310// (when we load gdi32, we don't know which dlls it depends on and which
311// of those are already loaded and which aren't)
312//-> solution: Determine reference counts of dependant lx dlls and update those
313// reference counts
314//******************************************************************************
315void Win32DllBase::updateDependencies()
316{
317 QueueItem *item;
318 Win32DllBase *dll, *depdll;
319 ULONG refcount;
320
321 dlllistmutex.enter();
322 item = loadedDlls.Head();
323 while(item) {
324 depdll = (Win32DllBase *)loadedDlls.getItem(item);
325 if(depdll == NULL) {
326 dprintf(("updateDependencies: depdll == NULL!!"));
327 DebugInt3();
328 return;
329 }
330 refcount = 0;
331 dll = head;
332
333 while(dll) {
334 if(dll->dependsOn(depdll)) {
335 refcount++;
336 }
337 dll = dll->getNext();
338 }
339 if(refcount > depdll->referenced) {
340 dprintf(("Win32DllBase::updateDependencies changing refcount of %s to %d (old=%d)", depdll->getModuleName(), refcount, depdll->referenced));
341 depdll->referenced = refcount;
342 }
343 item = loadedDlls.getNext(item);
344 }
345 dlllistmutex.leave();
346}
347//******************************************************************************
348//******************************************************************************
349#ifdef DEBUG
350void Win32DllBase::printDependencies(char *parent)
351{
352 QueueItem *item;
353 Win32DllBase *dll;
354 ULONG ret;
355
356 dprintf(("Dependency list: %s->%s %d", parent, getModuleName(), referenced));
357 item = loadedDlls.Head();
358 while(item) {
359 dll = (Win32DllBase *)loadedDlls.getItem(item);
360 if(dll == NULL) {
361 return;
362 }
363 dll->printDependencies(getModuleName());
364 item = loadedDlls.getNext(item);
365 }
366}
367//******************************************************************************
368//******************************************************************************
369#ifdef DEBUG_ENABLELOG_LEVEL2
370void Win32DllBase::printListOfDlls()
371{
372 Win32DllBase *dll;
373
374 dll = head;
375
376 dprintf2(("Win32DllBase::Win32DllBase: List of loaded dlls:"));
377 while(dll) {
378 dprintf2(("DLL %s %d", dll->szModule, dll->referenced));
379 dll = dll->next;
380 }
381}
382#endif
383#endif
384//******************************************************************************
385//******************************************************************************
386BOOL Win32DllBase::attachProcess()
387{
388 WINEXCEPTION_FRAME exceptFrame;
389 USHORT sel;
390 TEB *teb;
391 BOOL rc, fSetExceptionHandler;
392
393 if(fAttachedToProcess || fSkipEntryCalls)
394 return TRUE;
395
396 fAttachedToProcess = TRUE;
397
398 teb = GetThreadTEB();
399 fSetExceptionHandler = (!teb || teb->teb_sel != GetFS());
400
401 //Note: The Win32 exception structure references by FS:[0] is the same
402 // in OS/2
403 if(fSetExceptionHandler) {
404 OS2SetExceptionHandler((void *)&exceptFrame);
405 sel = SetWin32TIB();
406 }
407
408 if(dllEntryPoint == NULL) {
409 dprintf(("attachProcess not required for dll %s", szModule));
410 if(fSetExceptionHandler) {
411 SetFS(sel);
412 OS2UnsetExceptionHandler((void *)&exceptFrame);
413 }
414 return(TRUE);
415 }
416
417 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
418 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
419 // and non-NULL for static loads.
420 // same goes for process termination
421 LPVOID lpvReserved;
422
423 if (isDynamicLib())
424 lpvReserved = NULL;
425 else
426 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
427
428#ifdef DEBUG
429 int time1, time2;
430 dprintf(("attachProcess to dll %s", szModule));
431 time1 = GetTickCount();
432#endif
433
434 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, lpvReserved);
435
436#ifdef DEBUG
437 time2 = GetTickCount();
438 dprintf(("attachProcess to dll %s DONE in %x msec", szModule, time2-time1));
439#endif
440
441 if(fSetExceptionHandler) {
442 SetFS(sel);
443 OS2UnsetExceptionHandler((void *)&exceptFrame);
444 }
445 else
446 if(teb) {
447 if(teb->teb_sel != GetFS()) {
448 dprintf(("Win32DllBase::attachProcess: FS was changed by dll entrypoint!!!!"));
449 DebugInt3();
450 }
451 }
452 return rc;
453}
454//******************************************************************************
455//******************************************************************************
456BOOL Win32DllBase::detachProcess()
457{
458 WINEXCEPTION_FRAME exceptFrame;
459 USHORT sel;
460 BOOL rc;
461
462 if(fSkipEntryCalls) {
463 fUnloaded = TRUE;
464 return TRUE;
465 }
466
467 if(dllEntryPoint == NULL) {
468 tlsDetachThread(); //destroy TLS (main thread)
469 fUnloaded = TRUE;
470 return(TRUE);
471 }
472
473 dprintf(("detachProcess from dll %s", szModule));
474
475 //Note: The Win32 exception structure references by FS:[0] is the same
476 // in OS/2
477 OS2SetExceptionHandler((void *)&exceptFrame);
478
479 fUnloaded = TRUE;
480 sel = SetWin32TIB();
481
482 // @@@PH 2000/06/13 lpvReserved, Starcraft STORM.DLL
483 // if DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
484 // and non-NULL for static loads.
485 // same goes for process termination
486 LPVOID lpvReserved;
487
488 if (isDynamicLib())
489 lpvReserved = NULL;
490 else
491 lpvReserved = (LPVOID)0xdeadface; // some arbitrary value
492
493 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, lpvReserved);
494
495 SetFS(sel);
496 tlsDetachThread(); //destroy TLS (main thread)
497 tlsDelete();
498
499 OS2UnsetExceptionHandler((void *)&exceptFrame);
500
501 return rc;
502}
503//******************************************************************************
504//******************************************************************************
505BOOL Win32DllBase::attachThread()
506{
507 WINEXCEPTION_FRAME exceptFrame;
508 BOOL rc;
509
510 if(fSkipThreadEntryCalls || dllEntryPoint == NULL)
511 return(TRUE);
512
513 dprintf(("attachThread to dll %s", szModule));
514
515 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
516
517 dprintf(("attachThread to dll %s DONE", szModule));
518
519 return rc;
520}
521//******************************************************************************
522//******************************************************************************
523BOOL Win32DllBase::detachThread()
524{
525 WINEXCEPTION_FRAME exceptFrame;
526 BOOL rc;
527
528 if(fSkipThreadEntryCalls || dllEntryPoint == NULL)
529 return(TRUE);
530
531 dprintf(("detachThread from dll %s", szModule));
532
533 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
534 return rc;
535}
536//******************************************************************************
537//Send DLL_THREAD_ATTACH message to all dlls for a new thread
538//******************************************************************************
539void Win32DllBase::attachThreadToAllDlls()
540{
541 dlllistmutex.enter();
542 Win32DllBase *dll = Win32DllBase::head;
543 while(dll) {
544 dll->attachThread();
545 dll = dll->getNext();
546 }
547 dlllistmutex.leave();
548}
549//******************************************************************************
550//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
551//******************************************************************************
552void Win32DllBase::detachThreadFromAllDlls()
553{
554 dlllistmutex.enter();
555 Win32DllBase *dll = Win32DllBase::head;
556 while(dll) {
557 dll->detachThread();
558 dll = dll->getNext();
559 }
560 dlllistmutex.leave();
561}
562//******************************************************************************
563//Setup TLS structure for all dlls for a new thread
564//******************************************************************************
565void Win32DllBase::tlsAttachThreadToAllDlls()
566{
567 dlllistmutex.enter();
568 Win32DllBase *dll = Win32DllBase::head;
569 while(dll) {
570 dll->tlsAttachThread();
571 dll = dll->getNext();
572 }
573 dlllistmutex.leave();
574}
575//******************************************************************************
576//Destroy TLS structure for all dlls for a thread that's about to die
577//******************************************************************************
578void Win32DllBase::tlsDetachThreadFromAllDlls()
579{
580 dlllistmutex.enter();
581 Win32DllBase *dll = Win32DllBase::head;
582 while(dll) {
583 dll->tlsDetachThread();
584 dll = dll->getNext();
585 }
586 dlllistmutex.leave();
587}
588//******************************************************************************
589//******************************************************************************
590void Win32DllBase::deleteAll()
591{
592 Win32DllBase *dll = Win32DllBase::head;
593
594 dprintf(("Win32DllBase::deleteAll"));
595
596#ifdef DEBUG_ENABLELOG_LEVEL2
597 if(dll) dll->printListOfDlls();
598#endif
599
600 dlllistmutex.enter();
601 while(dll) {
602 dll->Release();
603 dll = Win32DllBase::head;
604 }
605 dlllistmutex.leave();
606 dprintf(("Win32DllBase::deleteAll Done!"));
607}
608//******************************************************************************
609//Delete dlls loaded by LoadLibrary(Ex) in LIFO order
610//******************************************************************************
611void Win32DllBase::deleteDynamicLibs()
612{
613 Win32DllBase *dll = head;
614 QueueItem *item;
615
616 dprintf(("Win32DllBase::deleteDynamicLibs"));
617#ifdef DEBUG_ENABLELOG_LEVEL2
618 if(dll) dll->printListOfDlls();
619#endif
620
621 dlllistmutex.enter();
622
623 item = loadLibDlls.Head();
624 while(item) {
625 dll = (Win32DllBase *)loadLibDlls.getItem(item);
626 int dynref = dll->nrDynamicLibRef;
627 if(dynref) {
628 while(dynref) {
629 dynref--;
630 dll->decDynamicLib();
631 dll->Release();
632 }
633 }
634 else DebugInt3();
635 item = loadLibDlls.Head(); //queue could have been changed, so start from the beginning
636 }
637
638 dlllistmutex.leave();
639 dprintf(("Win32DllBase::deleteDynamicLibs end"));
640}
641//******************************************************************************
642//******************************************************************************
643Win32DllBase *Win32DllBase::getFirst()
644{
645 return head;
646}
647//******************************************************************************
648//Add renaming profile strings for ole32 & netapi32 to odin.ini if they aren't
649//already there
650//******************************************************************************
651void Win32DllBase::setDefaultRenaming()
652{
653 char renameddll[CCHMAXPATH];
654
655 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll,
656 sizeof(renameddll)-1) <= 1)
657 {
658 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2");
659 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32");
660 }
661 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "", renameddll,
662 sizeof(renameddll)-1) <= 1)
663 {
664 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "OLAUTOS2");
665 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLAUTOS2", "OLEAUT32");
666 }
667 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll,
668 sizeof(renameddll)-1) <= 1)
669 {
670 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
671 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
672 }
673 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "WINSPOOL", "", renameddll,
674 sizeof(renameddll)-1) <= 1)
675 {
676 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "WINSPOOL", "WINSPOOL.DLL");
677 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WINSPOOL", "WINSPOOL.DRV");
678 }
679 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "MCICDA", "", renameddll,
680 sizeof(renameddll)-1) <= 1)
681 {
682 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "MCICDA", "MCICDA.DLL");
683 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "MCICDA", "MCICDA.DRV");
684 }
685}
686//******************************************************************************
687//rename dll if necessary:
688// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
689// or
690// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
691//******************************************************************************
692void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
693{
694 char modname[CCHMAXPATH];
695 char renameddll[CCHMAXPATH];
696 char *namestart;
697 char *sectionname;
698
699 if(fWinToOS2) {
700 sectionname = DLLRENAMEWIN_SECTION;
701 }
702 else {
703 sectionname = DLLRENAMEOS2_SECTION;
704 }
705 namestart = OSLibStripPath(dllname);
706 strcpy(modname, namestart);
707 char *dot = strrchr(modname, '.');
708 if(dot)
709 *dot = 0;
710 strupr(modname);
711 if(PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
712 sizeof(renameddll)-1) > 1)
713 {
714 if(namestart == dllname) {
715 strcpy(dllname, renameddll);
716 }
717 else {
718 *namestart = 0;
719 strcat(dllname, renameddll);
720 }
721 if(!strchr(dllname, '.')) {
722 strcat(dllname, DLL_EXTENSION);
723 }
724 strupr(dllname);
725 }
726 return;
727}
728//******************************************************************************
729//******************************************************************************
730Win32DllBase *Win32DllBase::findModule(char *dllname, BOOL fRenameFirst)
731{
732 Win32DllBase *dll;
733 char szDllName[CCHMAXPATH];
734 char *dot, *temp;
735
736//// dprintf2(("findModule %s", dllname));
737
738 strcpy(szDllName, OSLibStripPath(dllname));
739 strupr(szDllName);
740
741 if(fRenameFirst) {
742 renameDll(szDllName, FALSE);
743 }
744 dot = strstr(szDllName, ".");
745 if(dot == NULL) {
746 //if there's no extension or trainling dot, we
747 //assume it's a dll (see Win32 SDK docs)
748 strcat(szDllName, DLL_EXTENSION);
749 }
750 else {
751 if(dot[1] == 0) {
752 //a trailing dot means the module has no extension (SDK docs)
753 *dot = 0;
754 }
755 }
756
757 dlllistmutex.enter();
758 dll = head;
759 while(dll) {
760 if(strcmpi(szDllName, dll->szModule) == 0) {
761 dlllistmutex.leave();
762 return(dll);
763 }
764 dll = dll->next;
765 }
766 dlllistmutex.leave();
767 return(NULL);
768}
769//******************************************************************************
770//******************************************************************************
771Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
772{
773 dprintf2(("findModule %X", DllEntryPoint));
774
775 dlllistmutex.enter();
776 Win32DllBase *mod = Win32DllBase::head;
777 while(mod != NULL) {
778 dbgCheckObj(mod);
779 if(mod->dllEntryPoint == DllEntryPoint) {
780 dlllistmutex.leave();
781 return(mod);
782 }
783 mod = mod->next;
784 }
785 dlllistmutex.leave();
786 return(NULL);
787}
788//******************************************************************************
789//******************************************************************************
790Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
791{
792 dlllistmutex.enter();
793
794 Win32DllBase *mod = Win32DllBase::head;
795 while(mod != NULL) {
796 dbgCheckObj(mod);
797 if(mod->hinstance == hinstance) {
798 dlllistmutex.leave();
799 return(mod);
800 }
801 mod = mod->next;
802 }
803 dlllistmutex.leave();
804 return(NULL);
805}
806//******************************************************************************
807//******************************************************************************
808Win32DllBase *Win32DllBase::findModuleByAddr(ULONG address)
809{
810 dlllistmutex.enter();
811
812 Win32DllBase *mod = Win32DllBase::head;
813 while(mod != NULL) {
814 dbgCheckObj(mod);
815 if(mod->insideModule(address)) {
816 dlllistmutex.leave();
817 return(mod);
818 }
819 mod = mod->next;
820 }
821 dlllistmutex.leave();
822 return(NULL);
823}
824//******************************************************************************
825//******************************************************************************
826BOOL Win32DllBase::isDll()
827{
828 return TRUE;
829}
830//******************************************************************************
831//******************************************************************************
832Win32DllBase *Win32DllBase::head = NULL;
833Queue Win32DllBase::loadLibDlls;
Note: See TracBrowser for help on using the repository browser.