Ignore:
Timestamp:
Jun 15, 2001, 11:42:49 AM (24 years ago)
Author:
bird
Message:

Corrected Pe2Lx bug in LoadLibrary. Added isPe2LxDLL.

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 sandervl Exp $ */
     1/* $Id: windlllx.cpp,v 1.20 2001-06-15 09:42:48 bird Exp $ */
    22
    33/*
     
    66 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl)
    77 *
    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
    99 *       (wrong unload order of dlls)
    1010 *
     
    1818#define INCL_DOSMISC             /* DOS Miscellanous values  */
    1919#define INCL_WIN
    20 #include <os2wrap.h>    //Odin32 OS/2 api wrappers
     20#include <os2wrap.h>    //Odin32 OS/2 api wrappers
    2121#include <os2newapi.h>
    2222#include <stdio.h>
     
    3737#include <exe386.h>
    3838
    39 #define DBG_LOCALLOG    DBG_windlllx
     39#define DBG_LOCALLOG    DBG_windlllx
    4040#include "dbglocal.h"
    4141
     
    4444//System dlls set EntryPoint to 0
    4545//Parameters:
    46 //  HINSTANCE hInstance         - OS/2 module handle
     46//  HINSTANCE hInstance     - OS/2 module handle
    4747//  WIN32DLLENTRY EntryPoint    - Win32 dll entrypoint address
    4848//  PVOID pResData              - pointer to win32 resource data
     
    5454//Returns: Odin32 module handle
    5555//******************************************************************************
    56 DWORD WIN32API RegisterLxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, 
    57                              PVOID pResData, 
    58                              DWORD MajorImageVersion, 
     56DWORD WIN32API RegisterLxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint,
     57                             PVOID pResData,
     58                             DWORD MajorImageVersion,
    5959                             DWORD MinorImageVersion,
    6060                             DWORD Subsystem)
    61 { 
     61{
    6262 APIRET        rc;
    6363 Win32LxDll    *windll;
     
    6666
    6767   if(OSLibGetDllName(hInstance, szFileName, sizeof(szFileName)) == FALSE) {
    68         dprintf(("ERROR: RegisterLxDll: OSLibGetDllName %x failed!!", hInstance));
    69         return 0;
     68    dprintf(("ERROR: RegisterLxDll: OSLibGetDllName %x failed!!", hInstance));
     69    return 0;
    7070   }
    7171   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
    7373   //OS/2 doesn't unload the dll when it's still needed)
    7474   rc = DosLoadModule(szErrName, sizeof(szErrName), szFileName, &hInstance);
    75    if(rc != 0) { 
    76         dprintf(("ERROR: RegisterLxDll: DosLoadModule %s failed (rc=%d)!!", szFileName, rc));
    77         return 0;
     75   if(rc != 0) {
     76    dprintf(("ERROR: RegisterLxDll: DosLoadModule %s failed (rc=%d)!!", szFileName, rc));
     77    return 0;
    7878   }
    7979
     
    8181                           MinorImageVersion, Subsystem);
    8282   if(windll == NULL) {
    83         dprintf(("RegisterLxDll: windll == NULL!!!"));
    84         return 0;
     83    dprintf(("RegisterLxDll: windll == NULL!!!"));
     84    return 0;
    8585   }
    8686   if(!fPeLoader) {
    87         windll->AddRef();
    88 
    89         if(windll->attachProcess() == 0)
    90                 return 0;
    91 
    92         return windll->getInstanceHandle();
     87    windll->AddRef();
     88
     89    if(windll->attachProcess() == 0)
     90        return 0;
     91
     92    return windll->getInstanceHandle();
    9393   }
    9494   IMAGE_DOS_HEADER doshdr;
     
    105105   rc = DosQueryHeaderInfo(hInstance, 0, &doshdr, sizeof(IMAGE_DOS_HEADER), QHINF_READFILE);
    106106   if(rc) {
    107         goto hdrerror;
     107    goto hdrerror;
    108108   }
    109109   rc = DosQueryHeaderInfo(hInstance, doshdr.e_lfanew, &lxhdr, sizeof(e32_exe), QHINF_READFILE);
    110110   if(rc) {
    111         goto hdrerror;
     111    goto hdrerror;
    112112   }
    113113   offset = doshdr.e_lfanew + lxhdr.e32_impmod;
    114114   for(i=0;i<lxhdr.e32_impmodcnt;i++) {
    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         }
     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    }
    129129        else    dprintf(("HARMLESS WARNING: Can't find dll %s referenced by %s", modulename, windll->getModuleName()));
    130         offset += modsize + 1;
     130    offset += modsize + 1;
    131131   }
    132132   return windll->getInstanceHandle();
     
    146146   //Don't do it either after ExitProcess has been called
    147147   if(!fPeLoader || WinExe == NULL)
    148         return TRUE;
     148    return TRUE;
    149149
    150150   windll = Win32DllBase::findModule(hInstance);
    151151   if(!windll) {
    152         dprintf(("UnregisterLxDll: Can't find dll with handle %x (already deleted)", hInstance));
    153         return TRUE; //already deleted by Win32LxDll::Release
     152    dprintf(("UnregisterLxDll: Can't find dll with handle %x (already deleted)", hInstance));
     153    return TRUE; //already deleted by Win32LxDll::Release
    154154   }
    155155   dprintf(("UnregisterLxDll %s", windll->getModuleName()));
     
    162162Win32LxDll::Win32LxDll(HINSTANCE hInstance, WIN32DLLENTRY EntryPoint, PVOID pResData,
    163163                       DWORD MajorImageVersion, DWORD MinorImageVersion,
    164                        DWORD Subsystem) 
     164                       DWORD Subsystem)
    165165                : Win32ImageBase(hInstance),
    166                   Win32LxImage(hInstance, pResData), 
     166                  Win32LxImage(hInstance, pResData),
    167167                  Win32DllBase(hInstance, EntryPoint)
    168168{
     
    170170  this->MinorImageVersion = MinorImageVersion;
    171171  this->Subsystem         = Subsystem;
    172  
     172
    173173  if(EntryPoint == NULL) {
    174         fSkipThreadEntryCalls    = TRUE;
    175         fAttachedToProcess = TRUE;
     174    fSkipThreadEntryCalls    = TRUE;
     175    fAttachedToProcess = TRUE;
    176176  }
    177177  hinstanceOS2 = hInstance;
     
    206206
    207207  if(!fPeLoader)
    208         return ret;
    209 
    210   if(referenced == 1) 
     208    return ret;
     209
     210  if(referenced == 1)
    211211  {
    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                 }
     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        }
    220220#ifdef DEBUG
    221                 dll->AddRef(getModuleName());
     221        dll->AddRef(getModuleName());
    222222#else
    223                 dll->AddRef();
     223        dll->AddRef();
    224224#endif
    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         }
     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    }
    231231  }
    232   return ret; 
     232  return ret;
    233233}
    234234//******************************************************************************
    235235//******************************************************************************
    236236ULONG Win32LxDll::Release()
    237 { 
     237{
    238238 HINSTANCE     hinst;
    239239 WIN32DLLENTRY EntryPointTmp        = dllEntryPoint;
     
    250250  ret = Win32DllBase::Release();
    251251  if(ret == 0 && !fNoUnload) {//only set for kernel32.dll (fDisableUnload)
    252         //DosFreeModule sends a termination message to the dll.
     252    //DosFreeModule sends a termination message to the dll.
    253253        //The LX dll informs us when it's removed (UnregisterDll call)
    254         rc = DosFreeModule(hinst);
    255         if(rc) {
     254    rc = DosFreeModule(hinst);
     255    if(rc) {
    256256            dprintf(("Win32LxDll::Release: DosFreeModule %x returned %d", hinst, rc));
    257257            if(rc == ERROR_INVALID_ACCESS && !fExitProcess) {
     
    263263                //            don't fail!
    264264                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,
    267267                              MinorImageVersionTmp,
    268268                              SubsystemTmp);
     
    286286                else    DebugInt3();
    287287            }
    288         }
     288    }
    289289  }
    290290  return(ret);
     
    292292//******************************************************************************
    293293//******************************************************************************
    294 BOOL Win32LxDll::isLxDll()
     294BOOL Win32LxDll::isPe2LxDll() const
     295{
     296  return FALSE;
     297}
     298//******************************************************************************
     299//******************************************************************************
     300BOOL Win32LxDll::isLxDll() const
    295301{
    296302  return TRUE;
     
    298304//******************************************************************************
    299305//******************************************************************************
    300 void Win32LxDll::setDllHandleOS2(HINSTANCE hInstanceOS2) 
    301 { 
     306void Win32LxDll::setDllHandleOS2(HINSTANCE hInstanceOS2)
     307{
    302308  //Loaded with LoadLibrary(Ex); no need for a 2nd DosLoadModule
    303309  //Dlls that are indirectly loaded (i.e. GDI32->KERNEL32 dependancy) need
    304310  //this additional DosLoadModule (and setDllHandleOS2 isn't called for those)
    305311  if(this->hinstanceOS2) {
    306         DosFreeModule(this->hinstanceOS2);
     312    DosFreeModule(this->hinstanceOS2);
    307313  }
    308314  this->hinstanceOS2 = hInstanceOS2;
     
    312318Win32LxDll *Win32LxDll::findModuleByOS2Handle(HINSTANCE hinstance)
    313319{
    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            }
    324333        }
    325         mod = mod->getNext();
    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.