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

Last change on this file since 8923 was 8923, checked in by sandervl, 23 years ago

added method to detach process from all dlls

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