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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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