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

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

Removed obsolete code for Glide drivers and IOPL

File size: 27.7 KB
Line 
1/* $Id: windllbase.cpp,v 1.31 2002-12-20 10:38:57 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.