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

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

GetFileAttributes, pe loader & command line fixes

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