Changeset 6015 for trunk/src/kernel32/windlllx.cpp
- Timestamp:
- Jun 15, 2001, 11:42:49 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/windlllx.cpp
r5782 r6015 1 /* $Id: windlllx.cpp,v 1. 19 2001-05-22 14:25:36 sandervlExp $ */1 /* $Id: windlllx.cpp,v 1.20 2001-06-15 09:42:48 bird Exp $ */ 2 2 3 3 /* … … 6 6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 7 * 8 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug 8 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug 9 9 * (wrong unload order of dlls) 10 10 * … … 18 18 #define INCL_DOSMISC /* DOS Miscellanous values */ 19 19 #define INCL_WIN 20 #include <os2wrap.h> 20 #include <os2wrap.h> //Odin32 OS/2 api wrappers 21 21 #include <os2newapi.h> 22 22 #include <stdio.h> … … 37 37 #include <exe386.h> 38 38 39 #define DBG_LOCALLOG 39 #define DBG_LOCALLOG DBG_windlllx 40 40 #include "dbglocal.h" 41 41 … … 44 44 //System dlls set EntryPoint to 0 45 45 //Parameters: 46 // HINSTANCE hInstance 46 // HINSTANCE hInstance - OS/2 module handle 47 47 // WIN32DLLENTRY EntryPoint - Win32 dll entrypoint address 48 48 // PVOID pResData - pointer to win32 resource data … … 54 54 //Returns: Odin32 module handle 55 55 //****************************************************************************** 56 DWORD WIN32API RegisterLxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, 57 PVOID pResData, 58 DWORD MajorImageVersion, 56 DWORD WIN32API RegisterLxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, 57 PVOID pResData, 58 DWORD MajorImageVersion, 59 59 DWORD MinorImageVersion, 60 60 DWORD Subsystem) 61 { 61 { 62 62 APIRET rc; 63 63 Win32LxDll *windll; … … 66 66 67 67 if(OSLibGetDllName(hInstance, szFileName, sizeof(szFileName)) == FALSE) { 68 69 68 dprintf(("ERROR: RegisterLxDll: OSLibGetDllName %x failed!!", hInstance)); 69 return 0; 70 70 } 71 71 dprintf(("RegisterLxDll %x %s", hInstance, szFileName)); 72 //Make sure DosLoadModule is called at least once for a dll (to make sure 72 //Make sure DosLoadModule is called at least once for a dll (to make sure 73 73 //OS/2 doesn't unload the dll when it's still needed) 74 74 rc = DosLoadModule(szErrName, sizeof(szErrName), szFileName, &hInstance); 75 if(rc != 0) { 76 77 75 if(rc != 0) { 76 dprintf(("ERROR: RegisterLxDll: DosLoadModule %s failed (rc=%d)!!", szFileName, rc)); 77 return 0; 78 78 } 79 79 … … 81 81 MinorImageVersion, Subsystem); 82 82 if(windll == NULL) { 83 84 83 dprintf(("RegisterLxDll: windll == NULL!!!")); 84 return 0; 85 85 } 86 86 if(!fPeLoader) { 87 88 89 90 91 92 87 windll->AddRef(); 88 89 if(windll->attachProcess() == 0) 90 return 0; 91 92 return windll->getInstanceHandle(); 93 93 } 94 94 IMAGE_DOS_HEADER doshdr; … … 105 105 rc = DosQueryHeaderInfo(hInstance, 0, &doshdr, sizeof(IMAGE_DOS_HEADER), QHINF_READFILE); 106 106 if(rc) { 107 107 goto hdrerror; 108 108 } 109 109 rc = DosQueryHeaderInfo(hInstance, doshdr.e_lfanew, &lxhdr, sizeof(e32_exe), QHINF_READFILE); 110 110 if(rc) { 111 111 goto hdrerror; 112 112 } 113 113 offset = doshdr.e_lfanew + lxhdr.e32_impmod; 114 114 for(i=0;i<lxhdr.e32_impmodcnt;i++) { 115 116 117 118 119 120 121 122 123 124 125 126 127 128 115 rc = DosQueryHeaderInfo(hInstance, offset, &modsize, 1, QHINF_READFILE); 116 if(rc) { 117 goto hdrerror; 118 } 119 rc = DosQueryHeaderInfo(hInstance, offset+1, &modulename, min(modsize, sizeof(modulename)), QHINF_READFILE); 120 if(rc) { 121 goto hdrerror; 122 } 123 modulename[modsize] = 0; 124 windlldep = Win32DllBase::findModule(modulename, TRUE); 125 if(windlldep && strcmp(windlldep->getModuleName(), windll->getModuleName())) { 126 dprintf(("RegisterLxDll: Add dependency %s -> %s", windll->getModuleName(), modulename)); 127 windll->addDependency(windlldep); 128 } 129 129 else dprintf(("HARMLESS WARNING: Can't find dll %s referenced by %s", modulename, windll->getModuleName())); 130 130 offset += modsize + 1; 131 131 } 132 132 return windll->getInstanceHandle(); … … 146 146 //Don't do it either after ExitProcess has been called 147 147 if(!fPeLoader || WinExe == NULL) 148 148 return TRUE; 149 149 150 150 windll = Win32DllBase::findModule(hInstance); 151 151 if(!windll) { 152 153 152 dprintf(("UnregisterLxDll: Can't find dll with handle %x (already deleted)", hInstance)); 153 return TRUE; //already deleted by Win32LxDll::Release 154 154 } 155 155 dprintf(("UnregisterLxDll %s", windll->getModuleName())); … … 162 162 Win32LxDll::Win32LxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, PVOID pResData, 163 163 DWORD MajorImageVersion, DWORD MinorImageVersion, 164 DWORD Subsystem) 164 DWORD Subsystem) 165 165 : Win32ImageBase(hInstance), 166 Win32LxImage(hInstance, pResData), 166 Win32LxImage(hInstance, pResData), 167 167 Win32DllBase(hInstance, EntryPoint) 168 168 { … … 170 170 this->MinorImageVersion = MinorImageVersion; 171 171 this->Subsystem = Subsystem; 172 172 173 173 if(EntryPoint == NULL) { 174 175 174 fSkipThreadEntryCalls = TRUE; 175 fAttachedToProcess = TRUE; 176 176 } 177 177 hinstanceOS2 = hInstance; … … 206 206 207 207 if(!fPeLoader) 208 209 210 if(referenced == 1) 208 return ret; 209 210 if(referenced == 1) 211 211 { 212 213 214 215 216 217 218 219 212 item = loadedDlls.Head(); 213 while(item) { 214 dll = (Win32DllBase *)loadedDlls.getItem(item); 215 if(dll == NULL) { 216 dprintf(("ERROR: Win32DllBase::AddRef: dll item == NULL!!")); 217 DebugInt3(); 218 return -1; 219 } 220 220 #ifdef DEBUG 221 221 dll->AddRef(getModuleName()); 222 222 #else 223 223 dll->AddRef(); 224 224 #endif 225 226 227 228 229 230 225 item = loadedDlls.getNext(item); 226 } 227 if(attachProcess() == 0) { 228 dprintf(("WARNING: Dll %s refused to be loaded; aborting", getName())); 229 return -1; 230 } 231 231 } 232 return ret; 232 return ret; 233 233 } 234 234 //****************************************************************************** 235 235 //****************************************************************************** 236 236 ULONG Win32LxDll::Release() 237 { 237 { 238 238 HINSTANCE hinst; 239 239 WIN32DLLENTRY EntryPointTmp = dllEntryPoint; … … 250 250 ret = Win32DllBase::Release(); 251 251 if(ret == 0 && !fNoUnload) {//only set for kernel32.dll (fDisableUnload) 252 252 //DosFreeModule sends a termination message to the dll. 253 253 //The LX dll informs us when it's removed (UnregisterDll call) 254 255 254 rc = DosFreeModule(hinst); 255 if(rc) { 256 256 dprintf(("Win32LxDll::Release: DosFreeModule %x returned %d", hinst, rc)); 257 257 if(rc == ERROR_INVALID_ACCESS && !fExitProcess) { … … 263 263 // don't fail! 264 264 dprintf(("WORKAROUND: Re-register the dll so future LoadLibrary calls don't fail!")); 265 RegisterLxDll(hinst, EntryPointTmp, pResDataTmp, 266 MajorImageVersionTmp, 265 RegisterLxDll(hinst, EntryPointTmp, pResDataTmp, 266 MajorImageVersionTmp, 267 267 MinorImageVersionTmp, 268 268 SubsystemTmp); … … 286 286 else DebugInt3(); 287 287 } 288 288 } 289 289 } 290 290 return(ret); … … 292 292 //****************************************************************************** 293 293 //****************************************************************************** 294 BOOL Win32LxDll::isLxDll() 294 BOOL Win32LxDll::isPe2LxDll() const 295 { 296 return FALSE; 297 } 298 //****************************************************************************** 299 //****************************************************************************** 300 BOOL Win32LxDll::isLxDll() const 295 301 { 296 302 return TRUE; … … 298 304 //****************************************************************************** 299 305 //****************************************************************************** 300 void Win32LxDll::setDllHandleOS2(HINSTANCE hInstanceOS2) 301 { 306 void Win32LxDll::setDllHandleOS2(HINSTANCE hInstanceOS2) 307 { 302 308 //Loaded with LoadLibrary(Ex); no need for a 2nd DosLoadModule 303 309 //Dlls that are indirectly loaded (i.e. GDI32->KERNEL32 dependancy) need 304 310 //this additional DosLoadModule (and setDllHandleOS2 isn't called for those) 305 311 if(this->hinstanceOS2) { 306 312 DosFreeModule(this->hinstanceOS2); 307 313 } 308 314 this->hinstanceOS2 = hInstanceOS2; … … 312 318 Win32LxDll *Win32LxDll::findModuleByOS2Handle(HINSTANCE hinstance) 313 319 { 314 dlllistmutex.enter(); 315 316 Win32DllBase *mod = Win32DllBase::getFirst(); 317 while(mod != NULL) { 318 if(mod->isLxDll()) { 319 Win32LxDll *lxdll = (Win32LxDll *)mod; 320 if(lxdll->hinstanceOS2 == hinstance) { 321 dlllistmutex.leave(); 322 return(lxdll); 323 } 320 dlllistmutex.enter(); 321 322 Win32DllBase *mod = Win32DllBase::getFirst(); 323 while (mod != NULL) 324 { 325 if (mod->isLxDll()) 326 { 327 Win32LxDll *lxdll = (Win32LxDll *)mod; 328 if (lxdll->hinstanceOS2 == hinstance) 329 { 330 dlllistmutex.leave(); 331 return(lxdll); 332 } 324 333 } 325 326 }327 dlllistmutex.leave();328 return(NULL);329 } 330 //****************************************************************************** 331 //****************************************************************************** 334 mod = mod->getNext(); 335 } 336 dlllistmutex.leave(); 337 return(NULL); 338 } 339 //****************************************************************************** 340 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.