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

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

Rewrite of PE loader code, EB's fixes + VirtualProtect bugfix

File size: 11.8 KB
Line 
1/* $Id: windllbase.cpp,v 1.5 1999-11-22 20:35:52 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, "NETAPI32", "", renameddll,
290 sizeof(renameddll)-1) <= 1)
291 {
292 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
293 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
294 }
295}
296//******************************************************************************
297//rename dll if necessary:
298// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
299// or
300// OS/2 to Win32 : (i.e. OLE32OS2 -> OLE32)
301//******************************************************************************
302void Win32DllBase::renameDll(char *dllname, BOOL fWinToOS2)
303{
304 char modname[CCHMAXPATH];
305 char renameddll[CCHMAXPATH];
306 char *namestart;
307 char *sectionname;
308
309 if(fWinToOS2) {
310 sectionname = DLLRENAMEWIN_SECTION;
311 }
312 else {
313 sectionname = DLLRENAMEOS2_SECTION;
314 }
315 namestart = OSLibStripPath(dllname);
316 strcpy(modname, namestart);
317 char *dot = strrchr(modname, '.');
318 if(dot)
319 *dot = 0;
320 strupr(modname);
321 if(ODIN_PROFILE_GetOdinIniString(sectionname, modname, "", renameddll,
322 sizeof(renameddll)-1) > 1)
323 {
324 if(namestart == dllname) {
325 strcpy(dllname, renameddll);
326 }
327 else {
328 *namestart = 0;
329 strcat(dllname, renameddll);
330 }
331 strcat(dllname, ".dll");
332 }
333 return;
334}
335//******************************************************************************
336//******************************************************************************
337Win32DllBase *Win32DllBase::findModule(char *dllname)
338{
339 Win32DllBase *dll;
340 char szDllName[CCHMAXPATH];
341 char *dot, *temp;
342
343 dprintf(("findModule %s", dllname));
344
345 strcpy(szDllName, OSLibStripPath(dllname));
346 strupr(szDllName);
347 dot = strstr(szDllName, ".");
348 if(dot)
349 *dot = 0;
350
351 dlllistmutex.enter();
352 dll = head;
353 while(dll) {
354 if(strcmpi(szDllName, dll->szModule) == 0) {
355 dlllistmutex.leave();
356 return(dll);
357 }
358
359 dll = dll->next;
360 }
361 dlllistmutex.leave();
362 return(NULL);
363}
364//******************************************************************************
365//******************************************************************************
366Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
367{
368 dprintf(("findModule %X", DllEntryPoint));
369
370 dlllistmutex.enter();
371 Win32DllBase *mod = Win32DllBase::head;
372 while(mod != NULL) {
373 dbgCheckObj(mod);
374 if(mod->dllEntryPoint == DllEntryPoint) {
375 dlllistmutex.leave();
376 return(mod);
377 }
378 mod = mod->next;
379 }
380 dlllistmutex.leave();
381 return(NULL);
382}
383//******************************************************************************
384//******************************************************************************
385Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
386{
387 dlllistmutex.enter();
388
389 Win32DllBase *mod = Win32DllBase::head;
390 while(mod != NULL) {
391 dbgCheckObj(mod);
392 if(mod->hinstance == hinstance) {
393 dlllistmutex.leave();
394 return(mod);
395 }
396 mod = mod->next;
397 }
398 dlllistmutex.leave();
399 return(NULL);
400}
401//******************************************************************************
402//******************************************************************************
403BOOL Win32DllBase::isDll()
404{
405 return TRUE;
406}
407//******************************************************************************
408//******************************************************************************
409void Win32DllBase::setThreadLibraryCalls(BOOL fEnable)
410{
411 // if fEnable == true, do call the ATTACH_THREAD, DETACH_THREAD functions
412 // if fEnable == false, do not call the ATTACH_THREAD, DETACH_THREAD functions
413 fSkipEntryCalls = !fEnable;
414}
415
416//******************************************************************************
417//******************************************************************************
418Win32DllBase *Win32DllBase::head = NULL;
Note: See TracBrowser for help on using the repository browser.