source: trunk/src/kernel32/windlllx.cpp@ 3059

Last change on this file since 3059 was 3059, checked in by sandervl, 25 years ago

Dll dependency changes

File size: 7.6 KB
Line 
1/* $Id: windlllx.cpp,v 1.9 2000-03-09 19:03:21 sandervl Exp $ */
2
3/*
4 * Win32 LX Dll class (compiled in OS/2 using Odin32 api)
5 *
6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug
9 * (wrong unload order of dlls)
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#define INCL_DOSFILEMGR /* File Manager values */
15#define INCL_DOSERRORS /* DOS Error values */
16#define INCL_DOSPROCESS /* DOS Process values */
17#define INCL_DOSMODULEMGR
18#define INCL_DOSMISC /* DOS Miscellanous values */
19#define INCL_WIN
20#include <os2wrap.h> //Odin32 OS/2 api wrappers
21#include <os2newapi.h>
22#include <stdio.h>
23#include <string.h>
24#include <stdlib.h>
25#include <iostream.h>
26#include <fstream.h>
27#include <misc.h>
28#include <win32type.h>
29#include <windllbase.h>
30#include <windlllx.h>
31#include "winexepe2lx.h"
32#include <odinlx.h>
33#include "oslibmisc.h"
34
35#include <exe386.h>
36
37#define DBG_LOCALLOG DBG_windlllx
38#include "dbglocal.h"
39
40//******************************************************************************
41//Create LX Dll object and send process attach message
42//System dlls set EntryPoint to 0
43//Returns: Odin32 module handle
44//******************************************************************************
45DWORD WIN32API RegisterLxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint,
46 PVOID pResData)
47{
48 Win32LxDll *windll;
49 Win32DllBase *windlldep;
50
51 windll = (Win32LxDll *)Win32DllBase::findModule(hInstance);
52 if(windll) {
53 char *name = OSLibGetDllName(hInstance);
54 dprintf(("RegisterLxDll: Register existing dll %x %s", hInstance, name));
55 return FALSE;
56 }
57 windll = new Win32LxDll(hInstance, EntryPoint, pResData);
58 if(windll == NULL) {
59 dprintf(("RegisterLxDll: windll == NULL!!!"));
60 return FALSE;
61 }
62 if(fPe2Lx) {
63 windll->AddRef();
64
65 if(windll->attachProcess() == 0)
66 return 0;
67
68 return windll->getInstanceHandle();
69 }
70 IMAGE_DOS_HEADER doshdr;
71 struct e32_exe lxhdr;
72 ULONG offset;
73 char modulename[CCHMAXPATH];
74 char modsize;
75 APIRET rc;
76 int i;
77
78 //SvL: This code reads the import name table of the dll to get the dependencies
79 // on other dlls.
80 //DosQueryHeaderInfo is an undocumented api, but works very well.
81 //(no need to save FS here as we'll return to OS/2 immediately)
82 rc = DosQueryHeaderInfo(hInstance, 0, &doshdr, sizeof(IMAGE_DOS_HEADER), QHINF_READFILE);
83 if(rc) {
84 goto hdrerror;
85 }
86 rc = DosQueryHeaderInfo(hInstance, doshdr.e_lfanew, &lxhdr, sizeof(e32_exe), QHINF_READFILE);
87 if(rc) {
88 goto hdrerror;
89 }
90 offset = doshdr.e_lfanew + lxhdr.e32_impmod;
91 for(i=0;i<lxhdr.e32_impmodcnt;i++) {
92 rc = DosQueryHeaderInfo(hInstance, offset, &modsize, 1, QHINF_READFILE);
93 if(rc) {
94 goto hdrerror;
95 }
96 rc = DosQueryHeaderInfo(hInstance, offset+1, &modulename, min(modsize, sizeof(modulename)), QHINF_READFILE);
97 if(rc) {
98 goto hdrerror;
99 }
100 modulename[modsize] = 0;
101 windlldep = Win32DllBase::findModule(modulename, TRUE);
102 if(windlldep) {
103 dprintf(("RegisterLxDll: Add dependency %s -> %s", windll->getModuleName(), modulename));
104 windll->addDependency(windlldep);
105 }
106 offset += modsize + 1;
107 }
108 return windll->getInstanceHandle();
109
110hdrerror:
111 dprintf(("DosQueryHeaderInfo returned %d", rc));
112 return windll->getInstanceHandle();
113}
114//******************************************************************************
115//Destroy LX Dll object
116//******************************************************************************
117BOOL WIN32API UnregisterLxDll(HINSTANCE hInstance)
118{
119 Win32LxDll *windll;
120
121 //Don't proceed for pe2lx/win32k (os/2 dll unload dependency bug)
122 //Don't do it either after ExitProcess has been called
123 if(fPe2Lx || WinExe == NULL)
124 return TRUE;
125
126 windll = (Win32LxDll *)Win32DllBase::findModule(hInstance);
127 if(!windll) {
128 dprintf(("UnregisterLxDll: Can't find dll with handle %x (already deleted)", hInstance));
129 return TRUE; //already deleted by Win32LxDll::Release
130 }
131 dprintf(("UnregisterLxDll %s", windll->getModuleName()));
132 //This can only happen for LX dependencies (i.e. wininet loads wsock32)
133 delete windll;
134 return TRUE;
135}
136//******************************************************************************
137//******************************************************************************
138Win32LxDll::Win32LxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, PVOID pResData)
139 : Win32ImageBase(hInstance),
140 Win32LxImage(hInstance, pResData),
141 Win32DllBase(hInstance, EntryPoint)
142{
143 if(EntryPoint == NULL) {
144 fSkipEntryCalls = TRUE;
145 fAttachedToProcess = TRUE;
146 }
147}
148//******************************************************************************
149//******************************************************************************
150Win32LxDll::~Win32LxDll()
151{
152}
153//******************************************************************************
154//Load it again so OS/2 takes care of the reference count (to make sure
155//a dll isn't unloaded when the win32 app still needs it)
156//******************************************************************************
157void Win32LxDll::loadLibrary()
158{
159 char szModuleFailure[CCHMAXPATH] = "";
160 ULONG hInstanceNewDll;
161 APIRET rc;
162
163 if(fLoadLibrary) {
164 DebugInt3();
165 return;
166 }
167
168 dprintf(("Win32LxDll::loadLibrary %s", getModuleName()));
169 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), getFullPath(), (HMODULE *)&hInstanceNewDll);
170 if(rc) {
171 dprintf(("DosLoadModule returned %X for %s\n", rc, szModuleFailure));
172 DebugInt3(); //should NEVER happen
173 return;
174 }
175 //only do this once, so set the fLoadLibrary flag to true
176 setLoadLibrary();
177}
178//******************************************************************************
179//******************************************************************************
180#ifdef DEBUG
181ULONG Win32LxDll::AddRef(char *parentname)
182#else
183ULONG Win32LxDll::AddRef()
184#endif
185{
186 Win32DllBase *dll;
187 QueueItem *item;
188 ULONG ret;
189
190#ifdef DEBUG
191 ret = Win32DllBase::AddRef(parentname);
192#else
193 ret = Win32DllBase::AddRef();
194#endif
195
196 if(fPe2Lx)
197 return ret;
198
199 if(referenced == 1)
200 {
201 item = loadedDlls.Head();
202 while(item) {
203 dll = (Win32DllBase *)loadedDlls.getItem(item);
204 if(dll == NULL) {
205 dprintf(("ERROR: Win32DllBase::AddRef: dll item == NULL!!"));
206 DebugInt3();
207 return -1;
208 }
209#ifdef DEBUG
210 dll->AddRef(getModuleName());
211#else
212 dll->AddRef();
213#endif
214 item = loadedDlls.getNext(item);
215 }
216 if(attachProcess() == 0)
217 return 0;
218 }
219 return ret;
220}
221//******************************************************************************
222//******************************************************************************
223ULONG Win32LxDll::Release()
224{
225 HINSTANCE hinst;
226 ULONG ret;
227 APIRET rc;
228 BOOL fLoadLib = fLoadLibrary;
229
230 if(fDisableUnload) {//only set for kernel32.dll
231 fLoadLib = FALSE;
232 }
233 hinst = hinstance;
234 ret = Win32DllBase::Release();
235 if(ret == 0 && fLoadLib) {
236 //DosFreeModule sends a termination message to the dll.
237 //The LX dll informs us when it's removed (UnregisterDll call)
238 rc = DosFreeModule(hinst);
239 if(rc) {
240 dprintf(("Win32LxDll::Release: DosFreeModule %x returned %d", hinst, rc));
241 }
242 }
243 return(ret);
244}
245//******************************************************************************
246//******************************************************************************
247BOOL Win32LxDll::isLxDll()
248{
249 return TRUE;
250}
251//******************************************************************************
252//******************************************************************************
Note: See TracBrowser for help on using the repository browser.