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

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

thread fixes + heap wrappers

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