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

Dll dependency changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/windlllx.cpp

    r2802 r3059  
    1 /* $Id: windlllx.cpp,v 1.8 2000-02-16 14:22:11 sandervl Exp $ */
     1/* $Id: windlllx.cpp,v 1.9 2000-03-09 19:03:21 sandervl Exp $ */
    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);
Note: See TracChangeset for help on using the changeset viewer.