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

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

added dll load hook and function to override named or ordinal exports

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