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

Last change on this file since 10433 was 10433, checked in by bird, 22 years ago

#682: Test for DEBUG_LOGGING not DEBUG. dprintf may be used in release.

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