Changeset 3059 for trunk/src/kernel32/windlllx.cpp
- Timestamp:
- Mar 9, 2000, 8:03:23 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/windlllx.cpp
r2802 r3059 1 /* $Id: windlllx.cpp,v 1. 8 2000-02-16 14:22:11 sandervl Exp $ */1 /* $Id: windlllx.cpp,v 1.9 2000-03-09 19:03:21 sandervl Exp $ */ 2 2 3 3 /* 4 4 * Win32 LX Dll class (compiled in OS/2 using Odin32 api) 5 5 * 6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * 6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl) 8 7 * 9 8 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug 10 9 * (wrong unload order of dlls) 11 * TODO: Unloading of system dlls is not correct for the PE loader12 * (they're always put at the head of the list even though there13 * might be a dependency with a win32 dll)14 10 * 15 11 * Project Odin Software License can be found in LICENSE.TXT … … 23 19 #define INCL_WIN 24 20 #include <os2wrap.h> //Odin32 OS/2 api wrappers 21 #include <os2newapi.h> 25 22 #include <stdio.h> 26 23 #include <string.h> … … 32 29 #include <windllbase.h> 33 30 #include <windlllx.h> 31 #include "winexepe2lx.h" 34 32 #include <odinlx.h> 35 33 #include "oslibmisc.h" 34 35 #include <exe386.h> 36 36 37 37 #define DBG_LOCALLOG DBG_windlllx … … 47 47 { 48 48 Win32LxDll *windll; 49 Win32DllBase *windlldep; 49 50 50 51 windll = (Win32LxDll *)Win32DllBase::findModule(hInstance); … … 59 60 return FALSE; 60 61 } 61 windll->AddRef(); 62 if(windll->attachProcess() == 0) 63 return 0; 64 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 } 65 108 return windll->getInstanceHandle(); 109 110 hdrerror: 111 dprintf(("DosQueryHeaderInfo returned %d", rc)); 112 return windll->getInstanceHandle(); 66 113 } 67 114 //****************************************************************************** … … 70 117 BOOL WIN32API UnregisterLxDll(HINSTANCE hInstance) 71 118 { 72 #if 173 return TRUE;74 #else75 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; 76 125 77 126 windll = (Win32LxDll *)Win32DllBase::findModule(hInstance); 78 127 if(!windll) { 79 dprintf(("UnregisterLxDll: Can't find dll with handle %x!!!", hInstance)); 80 return FALSE; 81 } 82 windll->detachProcess(); 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) 83 133 delete windll; 84 134 return TRUE; 85 #endif86 135 } 87 136 //****************************************************************************** … … 101 150 Win32LxDll::~Win32LxDll() 102 151 { 103 dprintf(("Win32LxDll::~Win32LxDll %s", szModule)); 104 } 105 //****************************************************************************** 106 //ASSUMPTION: called by FreeLibrary 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 //****************************************************************************** 157 void 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 181 ULONG Win32LxDll::AddRef(char *parentname) 182 #else 183 ULONG 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 //****************************************************************************** 107 222 //****************************************************************************** 108 223 ULONG Win32LxDll::Release() 109 224 { 110 ULONG ret = --referenced;111 225 HINSTANCE hinst; 112 113 if(ret == 0) { 114 dprintf(("Win32LxDll::Release, referenced == 0\n")); 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) { 115 236 //DosFreeModule sends a termination message to the dll. 116 237 //The LX dll informs us when it's removed (UnregisterDll call) 117 hinst = hinstance; 118 delete this; 119 DosFreeModule(hinst); 238 rc = DosFreeModule(hinst); 239 if(rc) { 240 dprintf(("Win32LxDll::Release: DosFreeModule %x returned %d", hinst, rc)); 241 } 120 242 } 121 243 return(ret);
Note:
See TracChangeset
for help on using the changeset viewer.