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

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

Rewrite for new win32 image classes

File size: 9.5 KB
Line 
1/* $Id: windllbase.cpp,v 1.1 1999-09-15 23:39:07 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
36VMutex dlllistmutex; //protects linked lists of heaps
37
38//******************************************************************************
39//******************************************************************************
40Win32DllBase::Win32DllBase(HINSTANCE hinstance, WIN32DLLENTRY DllEntryPoint)
41 : Win32ImageBase(hinstance),
42 referenced(0), fSkipEntryCalls(FALSE),
43 fAttachedToProcess(FALSE), fUnloaded(FALSE)
44{
45 dllEntryPoint = DllEntryPoint;
46
47 dlllistmutex.enter();
48 next = head;
49 head = this;
50 dlllistmutex.leave();
51
52 dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule));
53}
54//******************************************************************************
55//******************************************************************************
56Win32DllBase::~Win32DllBase()
57{
58 Win32DllBase *dll = head;
59
60 dprintf(("Win32DllBase::~Win32DllBase %s", szModule));
61
62 if(errorState == NO_ERROR && !fUnloaded)
63 {
64 detachProcess();
65 }
66
67 dlllistmutex.enter();
68 if(head == this) {
69 head = next;
70 }
71 else {
72 while(dll && dll->next != this) {
73 dll = dll->next;
74 }
75 if(dll == NULL) {
76 dprintf(("~Win32DllBase: Can't find dll!\n"));
77 dlllistmutex.leave();
78 return;
79 }
80 dll->next = next;
81 }
82 dlllistmutex.leave();
83}
84//******************************************************************************
85//ASSUMPTION: called by FreeLibrary
86//******************************************************************************
87ULONG Win32DllBase::Release()
88{
89 ULONG ret = --referenced;
90
91 if(ret == 0) {
92 dprintf(("Win32DllBase::Release, referenced == 0\n"));
93 delete this;
94 }
95 return(ret);
96}
97//******************************************************************************
98//******************************************************************************
99BOOL Win32DllBase::attachProcess()
100{
101 WINEXCEPTION_FRAME exceptFrame;
102 USHORT sel;
103 BOOL rc;
104
105 if(fAttachedToProcess)
106 return TRUE;
107
108 fAttachedToProcess = TRUE;
109
110 //Allocate TLS index for this module
111 tlsAlloc();
112 tlsAttachThread(); //setup TLS (main thread)
113
114 if(fSkipEntryCalls || dllEntryPoint == NULL) {
115 dprintf(("attachProcess not required for dll %s", szModule));
116 return(TRUE);
117 }
118
119 dprintf(("attachProcess to dll %s", szModule));
120
121 //Note: The Win32 exception structure references by FS:[0] is the same
122 // in OS/2
123 OS2SetExceptionHandler((void *)&exceptFrame);
124
125 sel = SetWin32TIB();
126 rc = dllEntryPoint(hinstance, DLL_PROCESS_ATTACH, 0);
127 SetFS(sel);
128
129 OS2UnsetExceptionHandler((void *)&exceptFrame);
130
131 return rc;
132}
133//******************************************************************************
134//******************************************************************************
135BOOL Win32DllBase::detachProcess()
136{
137 WINEXCEPTION_FRAME exceptFrame;
138 USHORT sel;
139 BOOL rc;
140
141 if(fSkipEntryCalls || dllEntryPoint == NULL) {
142 tlsDetachThread(); //destroy TLS (main thread)
143 fUnloaded = TRUE;
144 return(TRUE);
145 }
146
147 dprintf(("detachProcess from dll %s", szModule));
148
149 //Note: The Win32 exception structure references by FS:[0] is the same
150 // in OS/2
151 OS2SetExceptionHandler((void *)&exceptFrame);
152
153 fUnloaded = TRUE;
154 sel = SetWin32TIB();
155 rc = dllEntryPoint(hinstance, DLL_PROCESS_DETACH, 0);
156 SetFS(sel);
157 tlsDetachThread(); //destroy TLS (main thread)
158 tlsDelete();
159
160 OS2UnsetExceptionHandler((void *)&exceptFrame);
161
162 return rc;
163}
164//******************************************************************************
165//******************************************************************************
166BOOL Win32DllBase::attachThread()
167{
168 WINEXCEPTION_FRAME exceptFrame;
169 BOOL rc;
170
171 if(fSkipEntryCalls || dllEntryPoint == NULL)
172 return(TRUE);
173
174 dprintf(("attachThread to dll %s", szModule));
175 //Note: The Win32 exception structure references by FS:[0] is the same
176 // in OS/2
177 OS2SetExceptionHandler((void *)&exceptFrame);
178
179 rc = dllEntryPoint(hinstance, DLL_THREAD_ATTACH, 0);
180
181 OS2UnsetExceptionHandler((void *)&exceptFrame);
182 return rc;
183}
184//******************************************************************************
185//******************************************************************************
186BOOL Win32DllBase::detachThread()
187{
188 WINEXCEPTION_FRAME exceptFrame;
189 BOOL rc;
190
191 if(fSkipEntryCalls || dllEntryPoint == NULL)
192 return(TRUE);
193
194 dprintf(("attachThread from dll %s", szModule));
195
196 //Note: The Win32 exception structure references by FS:[0] is the same
197 // in OS/2
198 OS2SetExceptionHandler((void *)&exceptFrame);
199
200 rc = dllEntryPoint(hinstance, DLL_THREAD_DETACH, 0);
201
202 OS2UnsetExceptionHandler((void *)&exceptFrame);
203 return rc;
204}
205//******************************************************************************
206//Send DLL_THREAD_ATTACH message to all dlls for a new thread
207//******************************************************************************
208void Win32DllBase::attachThreadToAllDlls()
209{
210 Win32DllBase *dll = Win32DllBase::head;
211 while(dll) {
212 dll->attachThread();
213 dll = dll->getNext();
214 }
215}
216//******************************************************************************
217//Send DLL_THREAD_DETACH message to all dlls for thread that's about to die
218//******************************************************************************
219void Win32DllBase::detachThreadFromAllDlls()
220{
221 Win32DllBase *dll = Win32DllBase::head;
222 while(dll) {
223 dll->detachThread();
224 dll = dll->getNext();
225 }
226}
227//******************************************************************************
228//Setup TLS structure for all dlls for a new thread
229//******************************************************************************
230void Win32DllBase::tlsAttachThreadToAllDlls()
231{
232 Win32DllBase *dll = Win32DllBase::head;
233 while(dll) {
234 dll->tlsAttachThread();
235 dll = dll->getNext();
236 }
237}
238//******************************************************************************
239//Destroy TLS structure for all dlls for a thread that's about to die
240//******************************************************************************
241void Win32DllBase::tlsDetachThreadFromAllDlls()
242{
243 Win32DllBase *dll = Win32DllBase::head;
244 while(dll) {
245 dll->tlsDetachThread();
246 dll = dll->getNext();
247 }
248}
249//******************************************************************************
250//******************************************************************************
251void Win32DllBase::deleteAll()
252{
253#ifdef DEBUG
254 dlllistmutex.enter();
255 Win32DllBase *dll = head;
256
257 dprintf(("Win32DllBase::deleteAll: List of loaded dlls:"));
258 while(dll) {
259 dprintf(("DLL %s", dll->szModule));
260 dll = dll->next;
261 }
262 dlllistmutex.leave();
263#endif
264
265 while(Win32DllBase::head) {
266 delete Win32DllBase::head;
267 }
268}
269//******************************************************************************
270//******************************************************************************
271Win32DllBase *Win32DllBase::findModule(char *dllname)
272{
273 Win32DllBase *dll;
274 char szDllName[CCHMAXPATH];
275 char *dot, *temp;
276
277 dprintf(("findModule %s", dllname));
278
279 strcpy(szDllName, OSLibStripPath(dllname));
280 strupr(szDllName);
281 dot = strstr(szDllName, ".");
282 if(dot)
283 *dot = 0;
284
285 dlllistmutex.enter();
286 dll = head;
287 while(dll) {
288 if(strcmpi(szDllName, dll->szModule) == 0) {
289 dlllistmutex.leave();
290 return(dll);
291 }
292
293 dll = dll->next;
294 }
295 dlllistmutex.leave();
296 return(NULL);
297}
298//******************************************************************************
299//******************************************************************************
300Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
301{
302 dprintf(("findModule %X", DllEntryPoint));
303
304 dlllistmutex.enter();
305 Win32DllBase *mod = Win32DllBase::head;
306 while(mod != NULL) {
307 dbgCheckObj(mod);
308 if(mod->dllEntryPoint == DllEntryPoint) {
309 dlllistmutex.leave();
310 return(mod);
311 }
312 mod = mod->next;
313 }
314 dlllistmutex.leave();
315 return(NULL);
316}
317//******************************************************************************
318//******************************************************************************
319Win32DllBase *Win32DllBase::findModule(HINSTANCE hinstance)
320{
321 dlllistmutex.enter();
322
323 Win32DllBase *mod = Win32DllBase::head;
324 while(mod != NULL) {
325 dbgCheckObj(mod);
326 if(mod->hinstance == hinstance) {
327 dlllistmutex.leave();
328 return(mod);
329 }
330 mod = mod->next;
331 }
332 dlllistmutex.leave();
333 return(NULL);
334}
335//******************************************************************************
336//******************************************************************************
337BOOL Win32DllBase::isDll()
338{
339 return TRUE;
340}
341//******************************************************************************
342//******************************************************************************
343Win32DllBase *Win32DllBase::head = NULL;
Note: See TracBrowser for help on using the repository browser.