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

Last change on this file since 2001 was 2001, checked in by sandervl, 26 years ago

Memory map fixes

File size: 12.2 KB
Line 
1/* $Id: windllbase.cpp,v 1.6 1999-12-06 21:31:43 sandervl Exp $ */
2
3/*
4 * Win32 Dll base class
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_DOSFILEMGR /* File Manager values */
13#define INCL_DOSERRORS /* DOS Error values */
14#define INCL_DOSPROCESS /* DOS Process values */
15#define INCL_DOSMODULEMGR
16#define INCL_DOSMISC /* DOS Miscellanous values */
17#define INCL_WIN
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <iostream.h>
23#include <fstream.h>
24#include <misc.h>
25#include <win32type.h>
26#include <pefile.h>
27#include <windllbase.h>
28#include <wprocess.h>
29#include "exceptions.h"
30#include "exceptutil.h"
31#include "cio.h"
32#include "vmutex.h"
33#include "oslibmisc.h"
34#include "oslibdos.h"
35#include "profile.h"
36
37VMutex dlllistmutex; //protects linked lists of heaps
38
39//******************************************************************************
40//******************************************************************************
41Win32DllBase::Win32DllBase(HINSTANCE hinstance, WIN32DLLENTRY DllEntryPoint)
42 : Win32ImageBase(hinstance),
43 referenced(0), fSkipEntryCalls(FALSE),
44 fAttachedToProcess(FALSE), fUnloaded(FALSE)
45{
46 dllEntryPoint = DllEntryPoint;
47
48 dlllistmutex.enter();
49 next = head;
50 head = this;
51 dlllistmutex.leave();
52
53 dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule));
54}
55//******************************************************************************
56//******************************************************************************
57Win32DllBase::~Win32DllBase()
58{
59 Win32DllBase *dll = head;
60
61 dprintf(("Win32DllBase::~Win32DllBase %s", szModule));
62
63 if(errorState == NO_ERROR && !fUnloaded)
64 {
65 detachProcess();
66 }
67
68 dlllistmutex.enter();
69 if(head == this) {
70 head = next;
71 }
72 else {
73 while(dll && dll->next != this) {
74 dll = dll->next;
75 }
76 if(dll == NULL) {
77 dprintf(("~Win32DllBase: Can't find dll!\n"));
78 dlllistmutex.leave();
79 return;
80 }
81 dll->next = next;
82 }
83 dlllistmutex.leave();
84}
85//******************************************************************************
86//ASSUMPTION: called by FreeLibrary
87//******************************************************************************
88ULONG Win32DllBase::Release()
89{
90 ULONG ret = --referenced;
91
92 if(ret == 0) {
93 dprintf(("Win32DllBase::Release, referenced == 0\n"));
94 delete this;
95 }
96 return(ret);
97}
98//******************************************************************************
99//******************************************************************************
100BOOL Win32DllBase::attachProcess()
101{
102 WINEXCEPTION_FRAME exceptFrame;
103 USHORT sel;
104 THDB *thdb;
105 BOOL rc, fSetExceptionHandler;
106
107 if(fAttachedToProcess)
108 return TRUE;
109
110 fAttachedToProcess = TRUE;
111
112 thdb = GetThreadTHDB();
113 fSetExceptionHandler = (!thdb || thdb->teb_sel != GetFS());
114
115 //Note: The Win32 exception structure references by FS:[0] is the same
116 // in OS/2
117 if(fSetExceptionHandler) {
118 OS2SetExceptionHandler((void *)&exceptFrame);
119 sel = SetWin32TIB();
120 }
121
122 //Allocate TLS index for this module
123 tlsAlloc();
124 tlsAttachThread(); //setup TLS (main thread)
125
126 if(fSkipEntryCalls || dllEntryPoint == NULL) {
127 dprintf(("attachProcess not required for dll %s", szModule));
128 if(fSetExceptionHandler) {
129 SetFS(sel);
130 OS2UnsetExceptionHandler((void *)&exceptFrame);
131 }
132 return(TRUE);
133 }
134
135 dprintf(("attachProcess to dll %s", szModule));
136
137 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, 0);
138
139 dprintf(("attachProcess to dll %s DONE", szModule));
140
141 if(fSetExceptionHandler) {
142 SetFS(sel);
143 OS2UnsetExceptionHandler((void *)&exceptFrame);
144 }
145 return rc;
146}
147//******************************************************************************
148//******************************************************************************
149BOOL Win32DllBase::detachProcess()
150{
151 WINEXCEPTION_FRAME exceptFrame;
152 USHORT sel;
153 BOOL rc;
154
155 if(fSkipEntryCalls || dllEntryPoint == NULL) {
156 tlsDetachThread(); //destroy TLS (main thread)
157 fUnloaded = TRUE;
158 return(TRUE);
159 }
160
161 dprintf(("detachProcess from dll %s", szModule));
162
163 //Note: The Win32 exception structure references by FS:[0] is the same
164 // in OS/2
165 OS2SetExceptionHandler((void *)&exceptFrame);
166
167 fUnloaded = TRUE;
168 sel = SetWin32TIB();
169 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, 0);
170 SetFS(sel);
171 tlsDetachThread(); //destroy TLS (main thread)
172 tlsDelete();
173
174 OS2UnsetExceptionHandler((void *)&exceptFrame);
175
176 return rc;
177}
178//******************************************************************************
179//******************************************************************************
180BOOL Win32DllBase::attachThread()
181{
182 WINEXCEPTION_FRAME exceptFrame;
183 BOOL rc;
184
185 if(fSkipEntryCalls || dllEntryPoint == NULL)
186 return(TRUE);
187
188 dprintf(("attachThread to dll %s", szModule));
189
190 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
191
192 dprintf(("attachThread to dll %s DONE", szModule));
193
194 return rc;
195}
196//******************************************************************************
197//******************************************************************************
198BOOL Win32DllBase::detachThread()
199{
200 WINEXCEPTION_FRAME exceptFrame;
201 BOOL rc;
202
203 if(fSkipEntryCalls || dllEntryPoint == NULL)
204 return(TRUE);
205
206 dprintf(("attachThread from dll %s", szModule));
207
208 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
209 return rc;
210}
211//******************************************************************************
212//Send DLL_THREAD_ATTACH message to all dlls for a new thread
213//******************************************************************************
214void Win32DllBase::attachThreadToAllDlls()
215{
216 Win32DllBase *dll = Win32DllBase::head;
217 while(dll) {
218 dll->attachThread();
219 dll = dll->getNext();
220 }
221}
222//******************************************************************************
223//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
224//******************************************************************************
225void Win32DllBase::detachThreadFromAllDlls()
226{
227 Win32DllBase *dll = Win32DllBase::head;
228 while(dll) {
229 dll->detachThread();
230 dll = dll->getNext();
231 }
232}
233//******************************************************************************
234//Setup TLS structure for all dlls for a new thread
235//******************************************************************************
236void Win32DllBase::tlsAttachThreadToAllDlls()
237{
238 Win32DllBase *dll = Win32DllBase::head;
239 while(dll) {
240 dll->tlsAttachThread();
241 dll = dll->getNext();
242 }
243}
244//******************************************************************************
245//Destroy TLS structure for all dlls for a thread that's about to die
246//******************************************************************************
247void Win32DllBase::tlsDetachThreadFromAllDlls()
248{
249 Win32DllBase *dll = Win32DllBase::head;
250 while(dll) {
251 dll->tlsDetachThread();
252 dll = dll->getNext();
253 }
254}
255//******************************************************************************
256//******************************************************************************
257void Win32DllBase::deleteAll()
258{
259#ifdef DEBUG
260 dlllistmutex.enter();
261 Win32DllBase *dll = head;
262
263 dprintf(("Win32DllBase::deleteAll: List of loaded dlls:"));
264 while(dll) {
265 dprintf(("DLL %s", dll->szModule));
266 dll = dll->next;
267 }
268 dlllistmutex.leave();
269#endif
270
271 while(Win32DllBase::head) {
272 delete Win32DllBase::head;
273 }
274}
275//******************************************************************************
276//Add renaming profile strings for ole32 & netapi32 to odin.ini if they aren't
277//already there
278//******************************************************************************
279void Win32DllBase::setDefaultRenaming()
280{
281 char renameddll[CCHMAXPATH];
282
283 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll,
284 sizeof(renameddll)-1) <= 1)
285 {
286 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2");
287 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32");
288 }
289 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "", renameddll,
290 sizeof(renameddll)-1) <= 1)
291 {
292 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLEAUT32", "OLAUTOS2");
293 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLAUTOS2", "OLEAUT32");
294 }
295 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll,
296 sizeof(renameddll)-1) <= 1)
297 {
298 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
299 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
300 }
301}
302//******************************************************************************
303//rename dll if necessary:
304// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
305// or
306// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
307//******************************************************************************
308void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
309{
310 char modname[CCHMAXPATH];
311 char renameddll[CCHMAXPATH];
312 char *namestart;
313 char *sectionname;
314
315 if(fWinToOS2) {
316 sectionname = DLLRENAMEWIN_SECTION;
317 }
318 else {
319 sectionname = DLLRENAMEOS2_SECTION;
320 }
321 namestart = OSLibStripPath(dllname);
322 strcpy(modname, namestart);
323 char *dot = strrchr(modname, '.');
324 if(dot)
325 *dot = 0;
326 strupr(modname);
327 if(ODIN_PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
328 sizeof(renameddll)-1) > 1)
329 {
330 if(namestart == dllname) {
331 strcpy(dllname, renameddll);
332 }
333 else {
334 *namestart = 0;
335 strcat(dllname, renameddll);
336 }
337 strcat(dllname, ".dll");
338 }
339 return;
340}
341//******************************************************************************
342//******************************************************************************
343Win32DllBase *Win32DllBase::findModule(char *dllname)
344{
345 Win32DllBase *dll;
346 char szDllName[CCHMAXPATH];
347 char *dot, *temp;
348
349 dprintf(("findModule %s", dllname));
350
351 strcpy(szDllName, OSLibStripPath(dllname));
352 strupr(szDllName);
353 dot = strstr(szDllName, ".");
354 if(dot)
355 *dot = 0;
356
357 dlllistmutex.enter();
358 dll = head;
359 while(dll) {
360 if(strcmpi(szDllName, dll->szModule) == 0) {
361 dlllistmutex.leave();
362 return(dll);
363 }
364
365 dll = dll->next;
366 }
367 dlllistmutex.leave();
368 return(NULL);
369}
370//******************************************************************************
371//******************************************************************************
372Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
373{
374 dprintf(("findModule %X", DllEntryPoint));
375
376 dlllistmutex.enter();
377 Win32DllBase *mod = Win32DllBase::head;
378 while(mod != NULL) {
379 dbgCheckObj(mod);
380 if(mod->dllEntryPoint == DllEntryPoint) {
381 dlllistmutex.leave();
382 return(mod);
383 }
384 mod = mod->next;
385 }
386 dlllistmutex.leave();
387 return(NULL);
388}
389//******************************************************************************
390//******************************************************************************
391Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
392{
393 dlllistmutex.enter();
394
395 Win32DllBase *mod = Win32DllBase::head;
396 while(mod != NULL) {
397 dbgCheckObj(mod);
398 if(mod->hinstance == hinstance) {
399 dlllistmutex.leave();
400 return(mod);
401 }
402 mod = mod->next;
403 }
404 dlllistmutex.leave();
405 return(NULL);
406}
407//******************************************************************************
408//******************************************************************************
409BOOL Win32DllBase::isDll()
410{
411 return TRUE;
412}
413//******************************************************************************
414//******************************************************************************
415void Win32DllBase::setThreadLibraryCalls(BOOL fEnable)
416{
417 // if fEnable == true, do call the ATTACH_THREAD, DETACH_THREAD functions
418 // if fEnable == false, do not call the ATTACH_THREAD, DETACH_THREAD functions
419 fSkipEntryCalls = !fEnable;
420}
421
422//******************************************************************************
423//******************************************************************************
424Win32DllBase *Win32DllBase::head = NULL;
Note: See TracBrowser for help on using the repository browser.