Changeset 3059


Ignore:
Timestamp:
Mar 9, 2000, 8:03:23 PM (25 years ago)
Author:
sandervl
Message:

Dll dependency changes

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.72 2000-03-03 11:15:58 sandervl Exp $
     1; $Id: KERNEL32.DEF,v 1.73 2000-03-09 19:03:19 sandervl Exp $
    22
    33;Created by BLAST for IBM's compiler
     
    2020   DosQuerySysState            =  DOSCALLS.368
    2121  _DosQuerySysState            =  DOSCALLS.368
    22 
    23   _O32_RegCloseKey             = PMWINX.541
    24   _O32_RegCreateKeyEx          = PMWINX.543
    25   _O32_RegOpenKeyEx            = PMWINX.550
    26   _O32_RegQueryValueEx         = PMWINX.553
    27   _O32_RegSetValueEx           = PMWINX.555
    28 
    29 
    3022
    3123EXPORTS
  • TabularUnified trunk/src/kernel32/dbglocal.cpp

    r2859 r3059  
    1 /* $Id: dbglocal.cpp,v 1.2 2000-02-22 19:12:52 sandervl Exp $ */
     1/* $Id: dbglocal.cpp,v 1.3 2000-03-09 19:03:18 sandervl Exp $ */
    22
    33/*
     
    110110"codepage",
    111111"debug",
    112 "oslibdebug"
     112"oslibdebug",
     113"registry",
     114"queue"
    113115};
    114116//******************************************************************************
  • TabularUnified trunk/src/kernel32/dbglocal.h

    r2859 r3059  
    1 /* $Id: dbglocal.h,v 1.2 2000-02-22 19:12:53 sandervl Exp $ */
     1/* $Id: dbglocal.h,v 1.3 2000-03-09 19:03:18 sandervl Exp $ */
    22
    33/*
     
    111111#define DBG_debug          90
    112112#define DBG_oslibdebug     91
    113 #define DBG_MAXFILES       92
     113#define DBG_registry       92
     114#define DBG_queue          93
     115#define DBG_MAXFILES       94
    114116
    115117extern USHORT DbgEnabled[DBG_MAXFILES];
  • TabularUnified trunk/src/kernel32/initterm.cpp

    r2984 r3059  
    1 /* $Id: initterm.cpp,v 1.36 2000-03-03 11:15:58 sandervl Exp $ */
     1/* $Id: initterm.cpp,v 1.37 2000-03-09 19:03:18 sandervl Exp $ */
    22
    33/*
     
    4747#include "hmdevio.h"
    4848#include <windllbase.h>
     49#include "winexepe2lx.h"
    4950#include "initsystem.h"
    5051#include <exitlist.h>
     
    128129                return 0UL;
    129130
     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
    130139            /*******************************************************************/
    131140            /* 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 bird Exp $
     1# $Id: makefile,v 1.90 2000-03-09 19:03:19 sandervl Exp $
    22
    33#
     
    117117$(OBJDIR)\dbglocal.obj \
    118118$(OBJDIR)\registry.obj \
     119$(OBJDIR)\queue.obj \
    119120$(OBJDIR)\kernelrsrc.obj
    120121
     
    160161# Dep rule - makes depenencies for C, C++ and Asm files.
    161162dep:
    162     $(DEPEND) -I$(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \
     163    $(DEPEND) -I. -I$(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \
    163164        *.c *.cpp *.h *.asm *.inc $(PDWIN32_INCLUDE)\*.h
    164165
  • 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 $ */
    22
    33/*
     
    316316
    317317    va_start(argptr, tekst);
    318     if(thdb) {
    319         thdb->logfile = (DWORD)flog;
    320         fprintf(flog, "t%d", thdb->threadId);
    321     }
    322318    vfprintf((FILE *)logfile, tekst, argptr);
    323319    if(thdb) thdb->logfile = 0;
  • TabularUnified trunk/src/kernel32/mmap.cpp

    r2973 r3059  
    1 /* $Id: mmap.cpp,v 1.35 2000-03-02 19:17:21 sandervl Exp $ */
     1/* $Id: mmap.cpp,v 1.36 2000-03-09 19:03:19 sandervl Exp $ */
    22
    33/*
     
    502502}
    503503//******************************************************************************
    504 //Assumes mutex has been acquired
    505504//******************************************************************************
    506505void Win32MemMap::deleteAll()
     
    510509
    511510  //delete all maps created by this process
     511  globalviewMutex.enter();
    512512  while(map) {
    513513        nextmap = map->next;
     
    525525        map = nextmap;
    526526  }
     527  globalviewMutex.leave();
    527528}
    528529//******************************************************************************
     
    691692  Win32MemMapView *view = mapviews;
    692693
     694  globalviewMutex.enter();
    693695  if(view != NULL) {
    694696        while(view) {
     
    700702        }
    701703  }
     704  globalviewMutex.leave();
    702705  return view;
    703706}
  • TabularUnified trunk/src/kernel32/windllbase.cpp

    r3005 r3059  
    1 /* $Id: windllbase.cpp,v 1.10 2000-03-04 19:52:36 sandervl Exp $ */
     1/* $Id: windllbase.cpp,v 1.11 2000-03-09 19:03:20 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    77 *
    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??
    1114 *
    1215 * Project Odin Software License can be found in LICENSE.TXT
     
    2629#include <fstream.h>
    2730#include <misc.h>
    28 #include <win32type.h>
     31#include <win32api.h>
    2932#include <pefile.h>
    3033#include <windllbase.h>
     
    4851                           Win32ImageBase *parent)
    4952                 : 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)
    5256{
    5357  dllEntryPoint = DllEntryPoint;
    5458
    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 
    9261  dprintf(("Win32DllBase::Win32DllBase %x %s", hinstance, szModule));
    9362}
     
    12291}
    12392//******************************************************************************
    124 //ASSUMPTION: called by FreeLibrary
     93//******************************************************************************
     94void Win32DllBase::loadLibrary()
     95{
     96  //dummy
     97}
     98//******************************************************************************
     99//******************************************************************************
     100void Win32DllBase::incDynamicLib()
     101{
     102  if(nrDynamicLibRef == 0) {
     103        dlllistmutex.enter();
     104        loadLibDlls.Push((ULONG)this);
     105        dlllistmutex.leave();
     106  }
     107  nrDynamicLibRef++;
     108}
     109//******************************************************************************
     110//******************************************************************************
     111void 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//******************************************************************************
     125void 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
     204ULONG Win32DllBase::AddRef(char *parentname)
     205#else
     206ULONG 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//******************************************************************************
    125225//******************************************************************************
    126226ULONG Win32DllBase::Release()
    127227{
    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
    132258        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        }
    133272  }
    134273  return(ret);
    135274}
     275//******************************************************************************
     276//Lotus Notes has several ugly circular dependencies in it's dlls.
     277//Remove them before they cause problems.
     278//******************************************************************************
     279BOOL 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//******************************************************************************
     315void 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
     351void 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
     371void 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
    136385//******************************************************************************
    137386//******************************************************************************
     
    252501void Win32DllBase::attachThreadToAllDlls()
    253502{
     503  dlllistmutex.enter();
    254504  Win32DllBase *dll = Win32DllBase::head;
    255505  while(dll) {
     
    257507        dll = dll->getNext();
    258508  }
     509  dlllistmutex.leave();
    259510}
    260511//******************************************************************************
     
    263514void Win32DllBase::detachThreadFromAllDlls()
    264515{
     516  dlllistmutex.enter();
    265517  Win32DllBase *dll = Win32DllBase::head;
    266518  while(dll) {
     
    268520        dll = dll->getNext();
    269521  }
     522  dlllistmutex.leave();
    270523}
    271524//******************************************************************************
     
    274527void Win32DllBase::tlsAttachThreadToAllDlls()
    275528{
     529  dlllistmutex.enter();
    276530  Win32DllBase *dll = Win32DllBase::head;
    277531  while(dll) {
     
    279533        dll = dll->getNext();
    280534  }
     535  dlllistmutex.leave();
    281536}
    282537//******************************************************************************
     
    285540void Win32DllBase::tlsDetachThreadFromAllDlls()
    286541{
     542  dlllistmutex.enter();
    287543  Win32DllBase *dll = Win32DllBase::head;
    288544  while(dll) {
     
    290546        dll = dll->getNext();
    291547  }
    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//******************************************************************************
     552void 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();
    303563  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//******************************************************************************
     573void 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();
    309581#endif
    310582
    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//******************************************************************************
     604Win32DllBase *Win32DllBase::getFirst()
     605{
     606  return head;
    319607}
    320608//******************************************************************************
     
    386674//******************************************************************************
    387675//******************************************************************************
    388 Win32DllBase *Win32DllBase::findModule(char *dllname)
     676Win32DllBase *Win32DllBase::findModule(char *dllname, BOOL fRenameFirst)
    389677{
    390678 Win32DllBase *dll;
     
    392680 char *dot, *temp;
    393681
    394   dprintf(("findModule %s", dllname));
     682////  dprintf2(("findModule %s", dllname));
    395683
    396684  strcpy(szDllName, OSLibStripPath(dllname));
    397685  strupr(szDllName);
     686
     687  if(fRenameFirst) {
     688        renameDll(szDllName, FALSE);
     689  }
     690
    398691  dot = strstr(szDllName, ".");
    399692  if(dot)
     
    417710Win32DllBase *Win32DllBase::findModule(WIN32DLLENTRY DllEntryPoint)
    418711{
    419    dprintf(("findModule %X", DllEntryPoint));
     712   dprintf2(("findModule %X", DllEntryPoint));
    420713
    421714   dlllistmutex.enter();
     
    468761//******************************************************************************
    469762Win32DllBase *Win32DllBase::head = NULL;
     763Queue         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 $ */
    22
    33/*
    44 * Win32 LX Dll class (compiled in OS/2 using Odin32 api)
    55 *
    6  * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
    7  *
     6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl)
    87 *
    98 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug
    109 *       (wrong unload order of dlls)
    11  * TODO: Unloading of system dlls is not correct for the PE loader
    12  *       (they're always put at the head of the list even though there
    13  *        might be a dependency with a win32 dll)
    1410 *
    1511 * Project Odin Software License can be found in LICENSE.TXT
     
    2319#define INCL_WIN
    2420#include <os2wrap.h>    //Odin32 OS/2 api wrappers
     21#include <os2newapi.h>
    2522#include <stdio.h>
    2623#include <string.h>
     
    3229#include <windllbase.h>
    3330#include <windlllx.h>
     31#include "winexepe2lx.h"
    3432#include <odinlx.h>
    3533#include "oslibmisc.h"
     34
     35#include <exe386.h>
    3636
    3737#define DBG_LOCALLOG    DBG_windlllx
     
    4747{
    4848 Win32LxDll *windll;
     49 Win32DllBase *windlldep;
    4950
    5051   windll = (Win32LxDll *)Win32DllBase::findModule(hInstance);
     
    5960        return FALSE;
    6061   }
    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   }
    65108   return windll->getInstanceHandle();
     109
     110hdrerror:
     111   dprintf(("DosQueryHeaderInfo returned %d", rc));
     112   return windll->getInstanceHandle();
    66113}
    67114//******************************************************************************
     
    70117BOOL WIN32API UnregisterLxDll(HINSTANCE hInstance)
    71118{
    72 #if 1
    73    return TRUE;
    74 #else
    75119 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;
    76125
    77126   windll = (Win32LxDll *)Win32DllBase::findModule(hInstance);
    78127   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)
    83133   delete windll;
    84134   return TRUE;
    85 #endif
    86135}
    87136//******************************************************************************
     
    101150Win32LxDll::~Win32LxDll()
    102151{
    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//******************************************************************************
     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//******************************************************************************
    107222//******************************************************************************
    108223ULONG Win32LxDll::Release()
    109224{
    110  ULONG ret = --referenced;
    111225 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) {
    115236        //DosFreeModule sends a termination message to the dll.
    116237        //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        }
    120242  }
    121243  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 $ */
    22
    33/*
     
    1616#define INCL_DOSERRORS      /* DOS Error values */
    1717#define INCL_DOSMODULEMGR   /* DOS Module management */
    18 
     18#define INCL_DOSSEMAPHORES
    1919
    2020/*******************************************************************************
  • TabularUnified trunk/src/kernel32/winexebase.cpp

    r3005 r3059  
    1 /* $Id: winexebase.cpp,v 1.6 2000-03-04 19:52:36 sandervl Exp $ */
     1/* $Id: winexebase.cpp,v 1.7 2000-03-09 19:03:21 sandervl Exp $ */
    22
    33/*
     
    5959Win32ExeBase::~Win32ExeBase()
    6060{
    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
    6489  Win32DllBase::deleteAll();
    65   Win32DllBase::deleteAll(TRUE);
    6690
    6791  WinExe = NULL;
  • TabularUnified trunk/src/kernel32/winexepe2lx.cpp

    r2802 r3059  
    1 /* $Id: winexepe2lx.cpp,v 1.4 2000-02-16 14:22:11 sandervl Exp $ */
     1/* $Id: winexepe2lx.cpp,v 1.5 2000-03-09 19:03:22 sandervl Exp $ */
    22
    33/*
     
    3737
    3838
     39BOOL fPe2Lx = FALSE;
     40
    3941/**
    4042 * Register a Pe2Lx Executable module.
     
    5658{
    5759    Win32Pe2LxExe *pWinPe2LxExe;
     60
     61    fPe2Lx = TRUE;
    5862
    5963    /* I/O init. */
  • TabularUnified trunk/src/kernel32/winimagebase.cpp

    r2859 r3059  
    1 /* $Id: winimagebase.cpp,v 1.9 2000-02-22 19:12:53 sandervl Exp $ */
     1/* $Id: winimagebase.cpp,v 1.10 2000-03-09 19:03:22 sandervl Exp $ */
    22
    33/*
     
    9898}
    9999//******************************************************************************
     100//Add image to dependency list of this image
     101//******************************************************************************
     102void Win32ImageBase::addDependency(Win32DllBase *image)
     103{
     104  loadedDlls.Push((ULONG)image);
     105}
     106//******************************************************************************
     107//******************************************************************************
     108BOOL 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//******************************************************************************
    100126//Returns required OS version for this image
    101127//******************************************************************************
  • TabularUnified trunk/src/kernel32/winimagepeldr.cpp

    r3005 r3059  
    1 /* $Id: winimagepeldr.cpp,v 1.34 2000-03-04 19:52:36 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.35 2000-03-09 19:03:22 sandervl Exp $ */
    22
    33/*
     
    3737#include <misc.h>
    3838#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"
    4242#include <pefile.h>
    4343#include <unicode.h>
     
    13891389                        return(FALSE);
    13901390                }
     1391                //Mark this dll as loaded by DosLoadModule
     1392                WinDll->setLoadLibrary();
     1393                WinDll->AddRef();
    13911394        }
    13921395        else {
     
    14061409                    return(FALSE);
    14071410                }
     1411#ifdef DEBUG
     1412                WinDll->AddRef(getModuleName());
     1413#else
     1414                WinDll->AddRef();
     1415#endif
    14081416                if(WinDll->attachProcess() == FALSE) {
    14091417                    dprintf((LOG, "attachProcess failed!" ));
     1418                    delete WinDll;
    14101419                    errorState = ERROR_INTERNAL;
    14111420                    return(FALSE);
    14121421                }
    14131422        }
     1423
    14141424        dprintf((LOG, "**********************************************************************" ));
    14151425        dprintf((LOG, "**********************  Finished Loading Module  *********************" ));
    14161426        dprintf((LOG, "**********************************************************************" ));
    14171427    }
    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);
    14211447
    14221448    pulImport  = (PULONG)((ULONG)pulImport + (ULONG)win32file);
  • TabularUnified trunk/src/kernel32/wprocess.cpp

    r3005 r3059  
    1 /* $Id: wprocess.cpp,v 1.71 2000-03-04 19:52:37 sandervl Exp $ */
     1/* $Id: wprocess.cpp,v 1.72 2000-03-09 19:03:23 sandervl Exp $ */
    22
    33/*
     
    2020
    2121#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"
    2627#include <vmutex.h>
    2728
     
    382383  if(winmod) {
    383384        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        }
    385397        return(TRUE);
    386398  }
     
    404416  module = Win32DllBase::findModule((LPSTR)lpszLibFile);
    405417  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();
    406426        module->AddRef();
    407     dprintf(("iLoadLibrary: found %s -> handle %x", lpszLibFile, module->getInstanceHandle()));
     427        dprintf(("iLoadLibrary: found %s -> handle %x", lpszLibFile, module->getInstanceHandle()));
    408428        return module->getInstanceHandle();
    409429  }
     
    421441  if(hDll)
    422442  {
    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;
    424452  }
    425453
    426454  if(!strstr(modname, ".")) {
    427     strcat(modname,".DLL");
     455        strcat(modname,".DLL");
    428456  }
    429457
     
    432460        module = Win32DllBase::findModule((char *)modname);
    433461        if(module) {//don't load it again
     462            module->incDynamicLib();
    434463            module->AddRef();
    435464            return module->getInstanceHandle();
     
    449478            peldrDll->setNoEntryCalls();
    450479        }
    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();
    455482
    456483        if(peldrDll->attachProcess() == FALSE) {
     
    459486            return(0);
    460487        }
    461         peldrDll->AddRef();
    462488        return peldrDll->getInstanceHandle();
    463489  }
Note: See TracChangeset for help on using the changeset viewer.