Changeset 3059
- Timestamp:
- Mar 9, 2000, 8:03:23 PM (25 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 7 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/kernel32/KERNEL32.DEF ¶
r2984 r3059 1 ; $Id: KERNEL32.DEF,v 1.7 2 2000-03-03 11:15:58sandervl Exp $1 ; $Id: KERNEL32.DEF,v 1.73 2000-03-09 19:03:19 sandervl Exp $ 2 2 3 3 ;Created by BLAST for IBM's compiler … … 20 20 DosQuerySysState = DOSCALLS.368 21 21 _DosQuerySysState = DOSCALLS.368 22 23 _O32_RegCloseKey = PMWINX.54124 _O32_RegCreateKeyEx = PMWINX.54325 _O32_RegOpenKeyEx = PMWINX.55026 _O32_RegQueryValueEx = PMWINX.55327 _O32_RegSetValueEx = PMWINX.55528 29 30 22 31 23 EXPORTS -
TabularUnified trunk/src/kernel32/dbglocal.cpp ¶
r2859 r3059 1 /* $Id: dbglocal.cpp,v 1. 2 2000-02-22 19:12:52sandervl Exp $ */1 /* $Id: dbglocal.cpp,v 1.3 2000-03-09 19:03:18 sandervl Exp $ */ 2 2 3 3 /* … … 110 110 "codepage", 111 111 "debug", 112 "oslibdebug" 112 "oslibdebug", 113 "registry", 114 "queue" 113 115 }; 114 116 //****************************************************************************** -
TabularUnified trunk/src/kernel32/dbglocal.h ¶
r2859 r3059 1 /* $Id: dbglocal.h,v 1. 2 2000-02-22 19:12:53sandervl Exp $ */1 /* $Id: dbglocal.h,v 1.3 2000-03-09 19:03:18 sandervl Exp $ */ 2 2 3 3 /* … … 111 111 #define DBG_debug 90 112 112 #define DBG_oslibdebug 91 113 #define DBG_MAXFILES 92 113 #define DBG_registry 92 114 #define DBG_queue 93 115 #define DBG_MAXFILES 94 114 116 115 117 extern USHORT DbgEnabled[DBG_MAXFILES]; -
TabularUnified trunk/src/kernel32/initterm.cpp ¶
r2984 r3059 1 /* $Id: initterm.cpp,v 1.3 6 2000-03-03 11:15:58 sandervl Exp $ */1 /* $Id: initterm.cpp,v 1.37 2000-03-09 19:03:18 sandervl Exp $ */ 2 2 3 3 /* … … 47 47 #include "hmdevio.h" 48 48 #include <windllbase.h> 49 #include "winexepe2lx.h" 49 50 #include "initsystem.h" 50 51 #include <exitlist.h> … … 128 129 return 0UL; 129 130 131 //SvL: Kernel32 is a special case; pe.exe loads it, so increase 132 // the reference count here 133 Win32DllBase *module = Win32DllBase::findModule(hModule); 134 if(module && !fPe2Lx) { 135 module->AddRef(); 136 module->DisableUnload(); 137 } 138 130 139 /*******************************************************************/ 131 140 /* A DosExitList routine must be used to clean up if runtime calls */ -
TabularUnified trunk/src/kernel32/makefile ¶
r3036 r3059 1 # $Id: makefile,v 1. 89 2000-03-07 11:08:01 birdExp $1 # $Id: makefile,v 1.90 2000-03-09 19:03:19 sandervl Exp $ 2 2 3 3 # … … 117 117 $(OBJDIR)\dbglocal.obj \ 118 118 $(OBJDIR)\registry.obj \ 119 $(OBJDIR)\queue.obj \ 119 120 $(OBJDIR)\kernelrsrc.obj 120 121 … … 160 161 # Dep rule - makes depenencies for C, C++ and Asm files. 161 162 dep: 162 $(DEPEND) -I $(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \163 $(DEPEND) -I. -I$(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \ 163 164 *.c *.cpp *.h *.asm *.inc $(PDWIN32_INCLUDE)\*.h 164 165 -
TabularUnified trunk/src/kernel32/misc.cpp ¶
r2516 r3059 1 /* $Id: misc.cpp,v 1. 19 2000-01-25 21:00:39 sandervl Exp $ */1 /* $Id: misc.cpp,v 1.20 2000-03-09 19:03:19 sandervl Exp $ */ 2 2 3 3 /* … … 316 316 317 317 va_start(argptr, tekst); 318 if(thdb) {319 thdb->logfile = (DWORD)flog;320 fprintf(flog, "t%d", thdb->threadId);321 }322 318 vfprintf((FILE *)logfile, tekst, argptr); 323 319 if(thdb) thdb->logfile = 0; -
TabularUnified trunk/src/kernel32/mmap.cpp ¶
r2973 r3059 1 /* $Id: mmap.cpp,v 1.3 5 2000-03-02 19:17:21sandervl Exp $ */1 /* $Id: mmap.cpp,v 1.36 2000-03-09 19:03:19 sandervl Exp $ */ 2 2 3 3 /* … … 502 502 } 503 503 //****************************************************************************** 504 //Assumes mutex has been acquired505 504 //****************************************************************************** 506 505 void Win32MemMap::deleteAll() … … 510 509 511 510 //delete all maps created by this process 511 globalviewMutex.enter(); 512 512 while(map) { 513 513 nextmap = map->next; … … 525 525 map = nextmap; 526 526 } 527 globalviewMutex.leave(); 527 528 } 528 529 //****************************************************************************** … … 691 692 Win32MemMapView *view = mapviews; 692 693 694 globalviewMutex.enter(); 693 695 if(view != NULL) { 694 696 while(view) { … … 700 702 } 701 703 } 704 globalviewMutex.leave(); 702 705 return view; 703 706 } -
TabularUnified trunk/src/kernel32/windllbase.cpp ¶
r3005 r3059 1 /* $Id: windllbase.cpp,v 1.1 0 2000-03-04 19:52:36sandervl Exp $ */1 /* $Id: windllbase.cpp,v 1.11 2000-03-09 19:03:20 sandervl Exp $ */ 2 2 3 3 /* … … 6 6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 7 * 8 * TODO: Unloading of system dlls is not correct for the PE loader 9 * (they're always put at the head of the list even though there 10 * might be a dependency with a win32 dll) 8 * Unloading of a dll always happens in order of dependency (taking nr of 9 * loads into account) 10 * Unloading of dynamically loaded dll (with LoadLibrary) in deleteAll 11 * is done in LIFO order (NT exhibits the same behaviour) 12 * 13 * RemoveCircularDependency: TODO: Send process detach message here?? 11 14 * 12 15 * Project Odin Software License can be found in LICENSE.TXT … … 26 29 #include <fstream.h> 27 30 #include <misc.h> 28 #include <win32 type.h>31 #include <win32api.h> 29 32 #include <pefile.h> 30 33 #include <windllbase.h> … … 48 51 Win32ImageBase *parent) 49 52 : Win32ImageBase(hinstance), 50 referenced(0), fSkipEntryCalls(FALSE), 51 fAttachedToProcess(FALSE), fUnloaded(FALSE), fDynamicLoad(FALSE) 53 referenced(0), fSkipEntryCalls(FALSE), next(NULL), fInserted(FALSE), 54 fAttachedToProcess(FALSE), fUnloaded(FALSE), 55 nrDynamicLibRef(0), fLoadLibrary(FALSE), fDisableUnload(FALSE) 52 56 { 53 57 dllEntryPoint = DllEntryPoint; 54 58 55 dlllistmutex.enter(); 56 //unload of dlls needs to be done in reverse order of dependencies 57 //Note: Only necessary for pe loader; the OS/2 loader takes care of this 58 //for win32k/pe2lx 59 if(parent && parent->isDll()) { 60 Win32DllBase *dll = head; 61 while(dll) { 62 if(dll->getInstanceHandle() == parent->getInstanceHandle()) { 63 break; 64 } 65 dll = dll->next; 66 } 67 if(dll) { 68 //insert this dll in list after it's parent 69 next = dll->next; 70 dll->next = this; 71 } 72 else DebugInt3(); 73 } 74 else { 75 next = head; 76 head = this; 77 } 78 dlllistmutex.leave(); 79 80 #ifdef DEBUG_ENABLELOG_LEVEL2 81 dlllistmutex.enter(); 82 Win32DllBase *dll = head; 83 84 dprintf2(("Win32DllBase::Win32DllBase: List of loaded dlls:")); 85 while(dll) { 86 dprintf2(("DLL %s", dll->szModule)); 87 dll = dll->next; 88 } 89 dlllistmutex.leave(); 90 #endif 91 59 setUnloadOrder(parent); 60 92 61 dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule)); 93 62 } … … 122 91 } 123 92 //****************************************************************************** 124 //ASSUMPTION: called by FreeLibrary 93 //****************************************************************************** 94 void Win32DllBase::loadLibrary() 95 { 96 //dummy 97 } 98 //****************************************************************************** 99 //****************************************************************************** 100 void Win32DllBase::incDynamicLib() 101 { 102 if(nrDynamicLibRef == 0) { 103 dlllistmutex.enter(); 104 loadLibDlls.Push((ULONG)this); 105 dlllistmutex.leave(); 106 } 107 nrDynamicLibRef++; 108 } 109 //****************************************************************************** 110 //****************************************************************************** 111 void Win32DllBase::decDynamicLib() 112 { 113 nrDynamicLibRef--; 114 if(nrDynamicLibRef == 0) { 115 dlllistmutex.enter(); 116 loadLibDlls.Remove((ULONG)this); 117 dlllistmutex.leave(); 118 } 119 } 120 //****************************************************************************** 121 //unload of dlls needs to be done in reverse order of dependencies 122 //Note: Only necessary for pe loader; the OS/2 loader takes care of this 123 //for win32k/pe2lx 124 //****************************************************************************** 125 void Win32DllBase::setUnloadOrder(Win32ImageBase *parent) 126 { 127 Win32DllBase *dll; 128 Win32DllBase *parentdll = NULL; 129 130 dlllistmutex.enter(); 131 if(parent) { 132 dll = head; 133 while(dll) { 134 if(dll->getInstanceHandle() == parent->getInstanceHandle()) { 135 parentdll = dll; 136 break; 137 } 138 dll = dll->next; 139 } 140 } 141 142 //first check if this dll is already at a lower position (further down the list) 143 //than the parent 144 if(parentdll && fInserted) {//already in the list? 145 dll = parentdll->next; 146 while(dll) { 147 if(dll->getInstanceHandle() == getInstanceHandle()) { 148 dlllistmutex.leave(); 149 return; //it's at a lower position, so no need to change anything 150 } 151 dll = dll->next; 152 } 153 154 //it's already in the list but not at the right position; remove it now 155 if(head == this) { 156 head = next; 157 } 158 else { 159 dll = head; 160 while(dll->next) { 161 if(dll->next == this) { 162 dll->next = next; 163 break; 164 } 165 dll = dll->next; 166 } 167 } 168 } 169 else 170 if(fInserted) {//already in the list? 171 dlllistmutex.leave(); 172 return; 173 } 174 //(re)insert it in the list after it's parent 175 if(parentdll) { 176 next = parentdll->next; 177 parentdll->next = this; 178 } 179 else {//no parent or exe, just add it at the start of the list 180 next = head; 181 head = this; 182 } 183 fInserted = TRUE; 184 185 //Now do the same thing for the child dependencies 186 QueueItem *item; 187 188 item = loadedDlls.Head(); 189 while(item) { 190 dll = (Win32DllBase *)loadedDlls.getItem(item); 191 //Check for circular dependencies (i.e. in Lotus Notes) 192 if(dll != parentdll) { 193 dll->setUnloadOrder(this); 194 } 195 196 item = loadedDlls.getNext(item); 197 } 198 199 dlllistmutex.leave(); 200 } 201 //****************************************************************************** 202 //****************************************************************************** 203 #ifdef DEBUG 204 ULONG Win32DllBase::AddRef(char *parentname) 205 #else 206 ULONG Win32DllBase::AddRef() 207 #endif 208 { 209 Win32DllBase *dll; 210 211 dprintf(("Win32DllBase::AddRef %s->%s %d", parentname, getModuleName(), referenced+1)); 212 ++referenced; 213 #ifdef DEBUG 214 if(referenced == 1) { 215 #ifdef DEBUG_ENABLELOG_LEVEL2 216 printListOfDlls(); 217 #endif 218 //printDependencies(NULL); 219 } 220 #endif 221 222 return referenced; 223 } 224 //****************************************************************************** 125 225 //****************************************************************************** 126 226 ULONG Win32DllBase::Release() 127 227 { 128 ULONG ret = --referenced; 129 130 if(ret == 0) { 131 dprintf(("Win32DllBase::Release, referenced == 0\n")); 228 Queue queue; 229 QueueItem *item; 230 Win32DllBase *dll; 231 LONG ret; 232 233 dprintf(("Win32DllBase::Release %s %d", getModuleName(), referenced-1)); 234 235 ret = --referenced; 236 if(ret <= 0) { 237 //make copy of linked list of dependencies 238 queue = loadedDlls; 239 240 //remove any circular dependencies on this dll that might be present 241 item = queue.Head(); 242 while(item) { 243 dll = (Win32DllBase *)queue.getItem(item); 244 if(dll == NULL) { 245 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!")); 246 DebugInt3(); 247 return -1; 248 } 249 dll->RemoveCircularDependency(this); 250 item = queue.getNext(item); 251 } 252 #ifdef DEBUG 253 //printDependencies(NULL); 254 #endif 255 dprintf(("Win32DllBase::Release %s referenced == 0", getModuleName())); 256 257 //delete dll object 132 258 delete this; 259 260 //unreference all of it's dependencies 261 item = queue.Head(); 262 while(item) { 263 dll = (Win32DllBase *)queue.getItem(item); 264 if(dll == NULL) { 265 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!")); 266 DebugInt3(); 267 return -1; 268 } 269 dll->Release(); 270 item = queue.getNext(item); 271 } 133 272 } 134 273 return(ret); 135 274 } 275 //****************************************************************************** 276 //Lotus Notes has several ugly circular dependencies in it's dlls. 277 //Remove them before they cause problems. 278 //****************************************************************************** 279 BOOL Win32DllBase::RemoveCircularDependency(Win32DllBase *parent) 280 { 281 QueueItem *item, *tmp; 282 Win32DllBase *dll; 283 BOOL ret = FALSE; 284 285 //remove any circular dependencies on this dll that might be present 286 item = loadedDlls.Head(); 287 while(item) { 288 dll = (Win32DllBase *)loadedDlls.getItem(item); 289 if(dll == NULL) { 290 dprintf(("ERROR: Win32DllBase::Release: dll item == NULL!!")); 291 DebugInt3(); 292 return FALSE; 293 } 294 tmp = loadedDlls.getNext(item); 295 if(dll == parent) { 296 dprintf(("Removing CIRCULAR dependency %s->%s", parent->getModuleName(), dll->getModuleName())); 297 loadedDlls.Remove(item); 298 ret = TRUE; 299 } 300 //// else ret |= dll->RemoveCircularDependency(parent); 301 item = tmp; 302 } 303 //TODO: Send process detach message here?? 304 return ret; 305 } 306 //****************************************************************************** 307 //There's a slight problem with our dependency procedure. 308 //example: gdi32 is loaded -> depends on kernel32 (which is already loaded) 309 // kernel32's reference count isn't updated 310 // (when we load gdi32, we don't know which dlls it depends on and which 311 // of those are already loaded and which aren't) 312 //-> solution: Determine reference counts of dependant lx dlls and update those 313 // reference counts 314 //****************************************************************************** 315 void Win32DllBase::updateDependencies() 316 { 317 QueueItem *item; 318 Win32DllBase *dll, *depdll; 319 ULONG refcount; 320 321 dlllistmutex.enter(); 322 item = loadedDlls.Head(); 323 while(item) { 324 depdll = (Win32DllBase *)loadedDlls.getItem(item); 325 if(depdll == NULL) { 326 dprintf(("updateDependencies: depdll == NULL!!")); 327 DebugInt3(); 328 return; 329 } 330 refcount = 0; 331 dll = head; 332 333 while(dll) { 334 if(dll->dependsOn(depdll)) { 335 refcount++; 336 } 337 dll = dll->getNext(); 338 } 339 if(refcount > depdll->referenced) { 340 dprintf(("Win32DllBase::updateDependencies changing refcount of %s to %d (old=%d)", depdll->getModuleName(), refcount, depdll->referenced)); 341 depdll->referenced = refcount; 342 } 343 344 item = loadedDlls.getNext(item); 345 } 346 dlllistmutex.leave(); 347 } 348 //****************************************************************************** 349 //****************************************************************************** 350 #ifdef DEBUG 351 void Win32DllBase::printDependencies(char *parent) 352 { 353 QueueItem *item; 354 Win32DllBase *dll; 355 ULONG ret; 356 357 dprintf(("Dependency list: %s->%s %d", parent, getModuleName(), referenced)); 358 item = loadedDlls.Head(); 359 while(item) { 360 dll = (Win32DllBase *)loadedDlls.getItem(item); 361 if(dll == NULL) { 362 return; 363 } 364 dll->printDependencies(getModuleName()); 365 item = loadedDlls.getNext(item); 366 } 367 } 368 //****************************************************************************** 369 //****************************************************************************** 370 #ifdef DEBUG_ENABLELOG_LEVEL2 371 void Win32DllBase::printListOfDlls() 372 { 373 Win32DllBase *dll; 374 375 dll = head; 376 377 dprintf2(("Win32DllBase::Win32DllBase: List of loaded dlls:")); 378 while(dll) { 379 dprintf2(("DLL %s %d", dll->szModule, dll->referenced)); 380 dll = dll->next; 381 } 382 } 383 #endif 384 #endif 136 385 //****************************************************************************** 137 386 //****************************************************************************** … … 252 501 void Win32DllBase::attachThreadToAllDlls() 253 502 { 503 dlllistmutex.enter(); 254 504 Win32DllBase *dll = Win32DllBase::head; 255 505 while(dll) { … … 257 507 dll = dll->getNext(); 258 508 } 509 dlllistmutex.leave(); 259 510 } 260 511 //****************************************************************************** … … 263 514 void Win32DllBase::detachThreadFromAllDlls() 264 515 { 516 dlllistmutex.enter(); 265 517 Win32DllBase *dll = Win32DllBase::head; 266 518 while(dll) { … … 268 520 dll = dll->getNext(); 269 521 } 522 dlllistmutex.leave(); 270 523 } 271 524 //****************************************************************************** … … 274 527 void Win32DllBase::tlsAttachThreadToAllDlls() 275 528 { 529 dlllistmutex.enter(); 276 530 Win32DllBase *dll = Win32DllBase::head; 277 531 while(dll) { … … 279 533 dll = dll->getNext(); 280 534 } 535 dlllistmutex.leave(); 281 536 } 282 537 //****************************************************************************** … … 285 540 void Win32DllBase::tlsDetachThreadFromAllDlls() 286 541 { 542 dlllistmutex.enter(); 287 543 Win32DllBase *dll = Win32DllBase::head; 288 544 while(dll) { … … 290 546 dll = dll->getNext(); 291 547 } 292 } 293 //****************************************************************************** 294 //****************************************************************************** 295 void Win32DllBase::deleteAll(BOOL fDynamicLoad) 296 { 297 Win32DllBase *dll = Win32DllBase::head, *tmp; 298 299 #ifdef DEBUG 300 dlllistmutex.enter(); 301 302 dprintf(("Win32DllBase::deleteAll: List of loaded dlls:")); 548 dlllistmutex.leave(); 549 } 550 //****************************************************************************** 551 //****************************************************************************** 552 void Win32DllBase::deleteAll() 553 { 554 Win32DllBase *dll = Win32DllBase::head; 555 556 dprintf(("Win32DllBase::deleteAll")); 557 558 #ifdef DEBUG_ENABLELOG_LEVEL2 559 if(dll) dll->printListOfDlls(); 560 #endif 561 562 dlllistmutex.enter(); 303 563 while(dll) { 304 dprintf(("DLL %s", dll->szModule)); 305 dll = dll->next; 306 } 307 dlllistmutex.leave(); 308 dll = Win32DllBase::head; 564 dll->Release(); 565 dll = Win32DllBase::head; 566 } 567 dlllistmutex.leave(); 568 dprintf(("Win32DllBase::deleteAll Done!")); 569 } 570 //****************************************************************************** 571 //Delete dlls loaded by LoadLibrary(Ex) in LIFO order 572 //****************************************************************************** 573 void Win32DllBase::deleteDynamicLibs() 574 { 575 Win32DllBase *dll = head; 576 QueueItem *item; 577 578 dprintf(("Win32DllBase::deleteDynamicLibs")); 579 #ifdef DEBUG_ENABLELOG_LEVEL2 580 if(dll) dll->printListOfDlls(); 309 581 #endif 310 582 311 while(dll) { 312 if(fDynamicLoad || !dll->fDynamicLoad) { 313 tmp = dll->next; 314 dll->Release(); 315 dll = tmp; 316 } 317 else dll = dll->next; 318 } 583 dlllistmutex.enter(); 584 585 item = loadLibDlls.Head(); 586 while(item) { 587 dll = (Win32DllBase *)loadLibDlls.getItem(item); 588 int dynref = dll->nrDynamicLibRef; 589 if(dynref) { 590 while(dynref) { 591 dynref--; 592 dll->decDynamicLib(); 593 dll->Release(); 594 } 595 } 596 else DebugInt3(); 597 item = loadLibDlls.Head(); //queue could have been changed, so start from the beginning 598 } 599 600 dlllistmutex.leave(); 601 } 602 //****************************************************************************** 603 //****************************************************************************** 604 Win32DllBase *Win32DllBase::getFirst() 605 { 606 return head; 319 607 } 320 608 //****************************************************************************** … … 386 674 //****************************************************************************** 387 675 //****************************************************************************** 388 Win32DllBase *Win32DllBase::findModule(char *dllname )676 Win32DllBase *Win32DllBase::findModule(char *dllname, BOOL fRenameFirst) 389 677 { 390 678 Win32DllBase *dll; … … 392 680 char *dot, *temp; 393 681 394 dprintf(("findModule %s", dllname));682 //// dprintf2(("findModule %s", dllname)); 395 683 396 684 strcpy(szDllName, OSLibStripPath(dllname)); 397 685 strupr(szDllName); 686 687 if(fRenameFirst) { 688 renameDll(szDllName, FALSE); 689 } 690 398 691 dot = strstr(szDllName, "."); 399 692 if(dot) … … 417 710 Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint) 418 711 { 419 dprintf (("findModule %X", DllEntryPoint));712 dprintf2(("findModule %X", DllEntryPoint)); 420 713 421 714 dlllistmutex.enter(); … … 468 761 //****************************************************************************** 469 762 Win32DllBase *Win32DllBase::head = NULL; 763 Queue Win32DllBase::loadLibDlls; -
TabularUnified 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); -
TabularUnified trunk/src/kernel32/windllpe2lx.cpp ¶
r2802 r3059 1 /* $Id: windllpe2lx.cpp,v 1. 6 2000-02-16 14:22:11 sandervl Exp $ */1 /* $Id: windllpe2lx.cpp,v 1.7 2000-03-09 19:03:21 sandervl Exp $ */ 2 2 3 3 /* … … 16 16 #define INCL_DOSERRORS /* DOS Error values */ 17 17 #define INCL_DOSMODULEMGR /* DOS Module management */ 18 18 #define INCL_DOSSEMAPHORES 19 19 20 20 /******************************************************************************* -
TabularUnified trunk/src/kernel32/winexebase.cpp ¶
r3005 r3059 1 /* $Id: winexebase.cpp,v 1. 6 2000-03-04 19:52:36sandervl Exp $ */1 /* $Id: winexebase.cpp,v 1.7 2000-03-09 19:03:21 sandervl Exp $ */ 2 2 3 3 /* … … 59 59 Win32ExeBase::~Win32ExeBase() 60 60 { 61 //First delete all dlls that were loaded by the exe or dlls 62 //Then delete all dlls loaded by LoadLibrary (to avoid that we 63 //delete some dlls before the dll, that loaded it, is destroyed) 61 QueueItem *item; 62 Win32DllBase *dll; 63 64 //First delete all dlls loaded by LoadLibrary 65 //Then delete all dlls that were loaded by the exe 66 //(NOTE: This is what NT does; first delete loadlib dlls in LIFO order and 67 // then the exe dlls) 68 Win32DllBase::deleteDynamicLibs(); 69 70 dprintf(("Win32ExeBase::~Win32ExeBase")); 71 #ifdef DEBUG_ENABLELOG_LEVEL2 72 item = loadedDlls.Head(); 73 dll = (Win32DllBase *)loadedDlls.getItem(item); 74 dll->printListOfDlls(); 75 #endif 76 77 item = loadedDlls.Head(); 78 while(item) { 79 dll = (Win32DllBase *)loadedDlls.getItem(item); 80 if(dll == NULL) { 81 dprintf(("ERROR: Win32ExeBase::~Win32ExeBase: dll item == NULL!!")); 82 DebugInt3(); 83 break; 84 } 85 dll->Release(); 86 item = loadedDlls.getNext(item); 87 } 88 64 89 Win32DllBase::deleteAll(); 65 Win32DllBase::deleteAll(TRUE);66 90 67 91 WinExe = NULL; -
TabularUnified trunk/src/kernel32/winexepe2lx.cpp ¶
r2802 r3059 1 /* $Id: winexepe2lx.cpp,v 1. 4 2000-02-16 14:22:11sandervl Exp $ */1 /* $Id: winexepe2lx.cpp,v 1.5 2000-03-09 19:03:22 sandervl Exp $ */ 2 2 3 3 /* … … 37 37 38 38 39 BOOL fPe2Lx = FALSE; 40 39 41 /** 40 42 * Register a Pe2Lx Executable module. … … 56 58 { 57 59 Win32Pe2LxExe *pWinPe2LxExe; 60 61 fPe2Lx = TRUE; 58 62 59 63 /* I/O init. */ -
TabularUnified trunk/src/kernel32/winimagebase.cpp ¶
r2859 r3059 1 /* $Id: winimagebase.cpp,v 1. 9 2000-02-22 19:12:53sandervl Exp $ */1 /* $Id: winimagebase.cpp,v 1.10 2000-03-09 19:03:22 sandervl Exp $ */ 2 2 3 3 /* … … 98 98 } 99 99 //****************************************************************************** 100 //Add image to dependency list of this image 101 //****************************************************************************** 102 void Win32ImageBase::addDependency(Win32DllBase *image) 103 { 104 loadedDlls.Push((ULONG)image); 105 } 106 //****************************************************************************** 107 //****************************************************************************** 108 BOOL Win32ImageBase::dependsOn(Win32DllBase *image) 109 { 110 QueueItem *item; 111 BOOL ret = FALSE; 112 113 dlllistmutex.enter(); 114 item = loadedDlls.Head(); 115 while(item) { 116 if(loadedDlls.getItem(item) == (ULONG)image) { 117 ret = TRUE; 118 break; 119 } 120 item = loadedDlls.getNext(item); 121 } 122 dlllistmutex.leave(); 123 return ret; 124 } 125 //****************************************************************************** 100 126 //Returns required OS version for this image 101 127 //****************************************************************************** -
TabularUnified trunk/src/kernel32/winimagepeldr.cpp ¶
r3005 r3059 1 /* $Id: winimagepeldr.cpp,v 1.3 4 2000-03-04 19:52:36sandervl Exp $ */1 /* $Id: winimagepeldr.cpp,v 1.35 2000-03-09 19:03:22 sandervl Exp $ */ 2 2 3 3 /* … … 37 37 #include <misc.h> 38 38 #include <win32api.h> 39 #include <winimagebase.h>40 #include <winimagepeldr.h>41 #include <windllpeldr.h>39 #include "winimagebase.h" 40 #include "winimagepeldr.h" 41 #include "windllpeldr.h" 42 42 #include <pefile.h> 43 43 #include <unicode.h> … … 1389 1389 return(FALSE); 1390 1390 } 1391 //Mark this dll as loaded by DosLoadModule 1392 WinDll->setLoadLibrary(); 1393 WinDll->AddRef(); 1391 1394 } 1392 1395 else { … … 1406 1409 return(FALSE); 1407 1410 } 1411 #ifdef DEBUG 1412 WinDll->AddRef(getModuleName()); 1413 #else 1414 WinDll->AddRef(); 1415 #endif 1408 1416 if(WinDll->attachProcess() == FALSE) { 1409 1417 dprintf((LOG, "attachProcess failed!" )); 1418 delete WinDll; 1410 1419 errorState = ERROR_INTERNAL; 1411 1420 return(FALSE); 1412 1421 } 1413 1422 } 1423 1414 1424 dprintf((LOG, "**********************************************************************" )); 1415 1425 dprintf((LOG, "********************** Finished Loading Module *********************" )); 1416 1426 dprintf((LOG, "**********************************************************************" )); 1417 1427 } 1418 else dprintf((LOG, "Already found ", pszCurModule )); 1419 1420 WinDll->AddRef(); 1428 else { 1429 if(WinDll->isLxDll() && !WinDll->isLoaded()) { 1430 //can happen with i.e. wininet 1431 //wininet depends on wsock32; when the app loads wsock32 afterwards 1432 //with LoadLibrary or as a child of another dll, we need to make 1433 //sure it's loaded once with DosLoadModule 1434 WinDll->loadLibrary(); 1435 } 1436 WinDll->AddRef(); 1437 1438 dprintf((LOG, "Already found ", pszCurModule)); 1439 } 1440 //add the dll we just loaded to dependency list for this image 1441 addDependency((Win32DllBase *)WinDll); 1442 1443 //Make sure the dependency list is correct (already done 1444 //in the ctor of Win32DllBase, but for LX dlls the parent is 1445 //then set to NULL; so change it here again 1446 WinDll->setUnloadOrder(this); 1421 1447 1422 1448 pulImport = (PULONG)((ULONG)pulImport + (ULONG)win32file); -
TabularUnified trunk/src/kernel32/wprocess.cpp ¶
r3005 r3059 1 /* $Id: wprocess.cpp,v 1.7 1 2000-03-04 19:52:37sandervl Exp $ */1 /* $Id: wprocess.cpp,v 1.72 2000-03-09 19:03:23 sandervl Exp $ */ 2 2 3 3 /* … … 20 20 21 21 #include <unicode.h> 22 #include <windllbase.h> 23 #include <winexebase.h> 24 #include <windllpeldr.h> 25 #include <winfakepeldr.h> 22 #include "windllbase.h" 23 #include "winexebase.h" 24 #include "windllpeldr.h" 25 #include "winexepe2lx.h" 26 #include "winfakepeldr.h" 26 27 #include <vmutex.h> 27 28 … … 382 383 if(winmod) { 383 384 dprintf(("FreeLibrary %s", winmod->getName())); 384 winmod->Release(); 385 //Only free it when the nrDynamicLibRef != 0 386 //This prevent problems after ExitProcess: 387 //i.e. dll A is referenced by our exe and loaded with LoadLibrary by dll B 388 // During ExitProcess it's unloaded once (before dll B), dll B calls 389 // FreeLibrary, but our exe also has a reference -> unloaded too many times 390 if(winmod->isDynamicLib()) { 391 winmod->decDynamicLib(); 392 winmod->Release(); 393 } 394 else { 395 dprintf(("Skipping dynamic unload as nrDynamicLibRef == 0")); 396 } 385 397 return(TRUE); 386 398 } … … 404 416 module = Win32DllBase::findModule((LPSTR)lpszLibFile); 405 417 if(module) { 418 if(module->isLxDll() && !module->isLoaded() && !fPe2Lx) { 419 //can happen with i.e. wininet 420 //wininet depends on wsock32; when the app loads wsock32 afterwards 421 //with LoadLibrary or as a child of another dll, we need to make 422 //sure it's loaded once with DosLoadModule 423 module->setLoadLibrary(); 424 } 425 module->incDynamicLib(); 406 426 module->AddRef(); 407 dprintf(("iLoadLibrary: found %s -> handle %x", lpszLibFile, module->getInstanceHandle()));427 dprintf(("iLoadLibrary: found %s -> handle %x", lpszLibFile, module->getInstanceHandle())); 408 428 return module->getInstanceHandle(); 409 429 } … … 421 441 if(hDll) 422 442 { 423 return hDll; //converted dll or win32k took care of it 443 module = Win32DllBase::findModule(hDll); 444 if(module && module->isLxDll() && !fPe2Lx) { 445 module->setLoadLibrary(); 446 module->AddRef(); 447 } 448 if(module) 449 module->incDynamicLib(); 450 //system dll, converted dll or win32k took care of it 451 return hDll; 424 452 } 425 453 426 454 if(!strstr(modname, ".")) { 427 strcat(modname,".DLL");455 strcat(modname,".DLL"); 428 456 } 429 457 … … 432 460 module = Win32DllBase::findModule((char *)modname); 433 461 if(module) {//don't load it again 462 module->incDynamicLib(); 434 463 module->AddRef(); 435 464 return module->getInstanceHandle(); … … 449 478 peldrDll->setNoEntryCalls(); 450 479 } 451 //Set flag so this dll doesn't get automatically deleted in ExitProcess 452 //(the first time); give application the chance to free it first 453 //If it's not freed, we delete it the 2nd time in ExitProcess 454 peldrDll->SetDynamicallyLoaded(); 480 peldrDll->incDynamicLib(); 481 peldrDll->AddRef(); 455 482 456 483 if(peldrDll->attachProcess() == FALSE) { … … 459 486 return(0); 460 487 } 461 peldrDll->AddRef();462 488 return peldrDll->getInstanceHandle(); 463 489 }
Note:
See TracChangeset
for help on using the changeset viewer.