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

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

crtdll rename entry + atom fs corruption fixes

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