Changeset 1811 for trunk/src


Ignore:
Timestamp:
Nov 22, 1999, 9:35:52 PM (26 years ago)
Author:
sandervl
Message:

Rewrite of PE loader code, EB's fixes + VirtualProtect bugfix

Location:
trunk/src/kernel32
Files:
16 edited

Legend:

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

    r1713 r1811  
    1 /* $Id: HandleManager.cpp,v 1.25 1999-11-12 14:57:13 sandervl Exp $ */
     1/* $Id: HandleManager.cpp,v 1.26 1999-11-22 20:35:49 sandervl Exp $ */
    22
    33/*
     
    15631563  if (-1 == iIndex)                                               /* error ? */
    15641564  {
    1565     SetLastError(ERROR_INVALID_HANDLE);       /* set win32 error information */
    1566     return WAIT_FAILED;                         /* signal failure */
     1565    dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n",
     1566             hObject));
     1567   
     1568    // maybe handles from CreateProcess() ...
     1569    dwResult = O32_WaitForSingleObject(hObject, dwTimeout);
     1570    return (dwResult);
    15671571  }
    15681572
  • trunk/src/kernel32/exceptions.cpp

    r1741 r1811  
    1 /* $Id: exceptions.cpp,v 1.29 1999-11-14 17:25:04 sandervl Exp $ */
     1/* $Id: exceptions.cpp,v 1.30 1999-11-22 20:35:49 sandervl Exp $ */
    22
    33/*
     
    938938                                   PVOID                        p)
    939939{
    940   dprintfException(pERepRec, pERegRec, pCtxRec, p);
    941 
    942940  /* Access violation at a known location */
    943941  switch(pERepRec->ExceptionNum)
     
    950948  case XCPT_FLOAT_STACK_CHECK:
    951949  case XCPT_FLOAT_UNDERFLOW:
     950        dprintfException(pERepRec, pERegRec, pCtxRec, p);
    952951        dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n"));
    953952        if(fIsOS2Image == FALSE)  //Only for real win32 apps
     
    971970  case XCPT_PROCESS_TERMINATE:
    972971  case XCPT_ASYNC_PROCESS_TERMINATE:
     972        dprintfException(pERepRec, pERegRec, pCtxRec, p);
    973973        SetExceptionChain((ULONG)-1);
    974974        return (XCPT_CONTINUE_SEARCH);
     
    10211021  case XCPT_IN_PAGE_ERROR:
    10221022CrashAndBurn:
     1023        dprintfException(pERepRec, pERegRec, pCtxRec, p);
    10231024        if(fIsOS2Image == FALSE)  //Only for real win32 apps
    10241025        {
     
    10511052
    10521053  default: //non-continuable exceptions
     1054        dprintfException(pERepRec, pERegRec, pCtxRec, p);
    10531055        return (XCPT_CONTINUE_SEARCH);
    10541056  }
  • trunk/src/kernel32/hmopen32.cpp

    r1727 r1811  
    1 /* $Id: hmopen32.cpp,v 1.13 1999-11-13 18:50:22 sandervl Exp $ */
     1/* $Id: hmopen32.cpp,v 1.14 1999-11-22 20:35:49 sandervl Exp $ */
    22
    33/*
     
    284284
    285285#if 1
    286   Win32MemMap *map;
    287   DWORD offset;
    288 
    289   //SvL: DosRead doesn't like writing to memory addresses returned by
    290   //     DosAliasMem -> search for original memory mapped pointer and use
    291   //     that one
    292   map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
    293   if(map) {
    294         lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
    295         DWORD nrpages = nNumberOfBytesToRead/4096;
    296         if(offset & 0xfff)
    297                 nrpages++;
    298         else
    299         if(nNumberOfBytesToRead & 0xfff)
    300                 nrpages++;
    301 
    302         map->commitPage(offset & ~0xfff, TRUE, nrpages);
    303   }
    304   else  lpRealBuf = (LPVOID)lpBuffer;
    305  
    306286  bRC = O32_ReadFile(pHMHandleData->hHMHandle,
    307                      (PVOID)lpRealBuf,
     287                     (PVOID)lpBuffer,
    308288                     nNumberOfBytesToRead,
    309289                     lpNumberOfBytesRead,
  • trunk/src/kernel32/initterm.cpp

    r1768 r1811  
    1 /* $Id: initterm.cpp,v 1.25 1999-11-18 09:20:08 bird Exp $ */
     1/* $Id: initterm.cpp,v 1.26 1999-11-22 20:35:50 sandervl Exp $ */
    22
    33/*
     
    4545#include "directory.h"
    4646#include "hmdevio.h"
     47#include <windllbase.h>
    4748
    4849/*-------------------------------------------------------------------*/
     
    138139            InitDirectories();
    139140            RegisterDevices();
     141            Win32DllBase::setDefaultRenaming();
    140142            break;
    141143        }
  • trunk/src/kernel32/makefile

    r1769 r1811  
    1 # $Id: makefile,v 1.58 1999-11-18 09:20:29 bird Exp $
     1# $Id: makefile,v 1.59 1999-11-22 20:35:50 sandervl Exp $
    22
    33#
     
    340340
    341341virtual.obj:   virtual.cpp $(PDWIN32_INCLUDE)\win\virtual.h $(PDWIN32_INCLUDE)\handlemanager.h mmap.h
    342 mmap.obj:      mmap.cpp mmap.h $(PDWIN32_INCLUDE)\vmutex.h oslibdos.h $(PDWIN32_INCLUDE)\heapshared.h
     342mmap.obj:      mmap.cpp mmap.h $(PDWIN32_INCLUDE)\vmutex.h oslibdos.h $(PDWIN32_INCLUDE)\heapshared.h $(PDWIN32_INCLUDE)\winimagepeldr.h
    343343
    344344pefile.OBJ:    pefile.cpp $(PDWIN32_INCLUDE)\pefile.h $(PDWIN32_INCLUDE)\winres.h
  • trunk/src/kernel32/mmap.cpp

    r1687 r1811  
    1 /* $Id: mmap.cpp,v 1.22 1999-11-10 14:16:01 sandervl Exp $ */
     1/* $Id: mmap.cpp,v 1.23 1999-11-22 20:35:50 sandervl Exp $ */
    22
    33/*
     
    2929#include "mmap.h"
    3030#include "oslibdos.h"
     31#include <winimagepeldr.h>
    3132
    3233//Global DLL Data
     
    4243//******************************************************************************
    4344Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
    44                : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0)
     45               : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), image(0)
    4546{
    4647  globalmapMutex.enter();
     
    6061  }
    6162  else  lpszMapName = NULL;
     63}
     64//******************************************************************************
     65//Map constructor used for executable image maps (only used internally)
     66//******************************************************************************
     67Win32MemMap::Win32MemMap(Win32PeLdrImage *pImage, ULONG baseAddress, ULONG size)
     68               : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0)
     69{
     70  globalmapMutex.enter();
     71  next    = memmaps;
     72  memmaps = this;
     73  globalmapMutex.leave();
     74
     75  hMemFile   = -1;
     76
     77  mSize      = size;
     78  mProtFlags = PAGE_READWRITE;
     79  mProcessId = GetCurrentProcess();
     80
     81  pMapping   = (LPVOID)baseAddress;
     82
     83  image      = pImage;
     84  lpszMapName= NULL;
    6285}
    6386//******************************************************************************
     
    107130        free(lpszMapName);
    108131  }
    109   if(pMapping) {
     132  if(pMapping && !image) {
    110133        if(lpszMapName) {
    111134                OSLibDosFreeMem(pMapping);
     
    154177//  mapMutex.enter();
    155178
     179  if(image) {
     180        return image->commitPage(pageAddr, fWriteAccess);
     181  }
    156182  newProt  = mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY);
    157183
     
    199225                        goto fail;
    200226                }
    201                 if(mProtFlags & PAGE_READONLY) {
     227                if(mProtFlags != PAGE_READWRITE) {
    202228                        if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) {
    203229                                goto fail;
     
    211237                goto fail;
    212238        }
    213         if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE) {
    214                 goto fail;
     239        if(!(memInfo.State & MEM_COMMIT))
     240        {//if it's already committed, then the app tried to write to it
     241                if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE)
     242                        goto fail;
    215243        }
    216244  }
     
    282310#endif
    283311
    284   if(nrMappings == 0) {//if not mapped, reserve/commit entire view
     312  //Memory has already been allocated for executable image maps (only used internally)
     313  if(!pMapping && nrMappings == 0) {//if not mapped, reserve/commit entire view
    285314        //SvL: Always read/write access or else ReadFile will crash once we
    286315        //     start committing pages.
     
    332361 ULONG nrBytesWritten, size;
    333362 int   i;
     363
     364  if(image) //no flushing for image maps
     365        return TRUE;
    334366
    335367  dprintf(("Win32MemMap::flushView: %x %x", lpvBase, cbFlush));
     
    447479        nextmap = map->next;
    448480        if(map->getProcessId() == processId) {
    449                 CloseHandle(memmaps->hMemMap);
     481                //Delete map directly for executable images (only used internally)
     482                if(map->getImage()) {
     483                        delete map;
     484                }
     485                else    CloseHandle(memmaps->hMemMap);
    450486        }
    451487        else {
     
    492528  }
    493529 
    494   if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) {
    495         dprintf(("new OSLibDosAliasMem FAILED"));
    496         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    497         errorState = 1;
    498         return;
     530  //view == memory mapping for executable images (only used internally)
     531  if(map->getImage()) {
     532        pMapView = map->getMappingAddr();
     533  }
     534  else {
     535        if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) {
     536                dprintf(("new OSLibDosAliasMem FAILED"));
     537                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     538                errorState = 1;
     539                return;
     540        }
    499541  }
    500542
     
    530572        mParentMap->flushView(mOffset, mSize);
    531573
    532   OSLibDosFreeMem(pMapView);
     574  //Don't free memory for executable image map views (only used internally)
     575  if(!mParentMap->getImage())
     576        OSLibDosFreeMem(pMapView);
    533577
    534578  globalviewMutex.enter();
  • trunk/src/kernel32/mmap.h

    r1687 r1811  
    1 /* $Id: mmap.h,v 1.11 1999-11-10 14:16:01 sandervl Exp $ */
     1/* $Id: mmap.h,v 1.12 1999-11-22 20:35:50 sandervl Exp $ */
    22
    33/*
     
    2828
    2929class Win32MemMapView;
     30class Win32PeLdrImage;
    3031
    3132//******************************************************************************
     
    3536public:
    3637   Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName);
     38   //Use by PE loader image class only:
     39   Win32MemMap(Win32PeLdrImage *pImage, ULONG lpImageMem, ULONG size);
    3740  ~Win32MemMap();
    3841
     
    4750   LPVOID getMappingAddr()               { return pMapping; };
    4851   DWORD  getProcessId()                 { return mProcessId;};
     52Win32PeLdrImage *getImage()              { return image; };
     53
     54   BOOL   isImageMap()                   { return image != NULL; };
    4955
    5056   void   AddRef()                       { ++referenced; };
     
    9399
    94100   VMutex mapMutex;
     101
     102   Win32PeLdrImage *image;
    95103
    96104private:
  • trunk/src/kernel32/oslibdos.cpp

    r1710 r1811  
    1 /* $Id: oslibdos.cpp,v 1.8 1999-11-12 11:38:40 sandervl Exp $ */
     1/* $Id: oslibdos.cpp,v 1.9 1999-11-22 20:35:50 sandervl Exp $ */
    22
    33/*
     
    2626
    2727//******************************************************************************
     28//TODO: Assumes entire memory range has the same protection flags!
     29//TODO: Check if this works for code aliases...
    2830//******************************************************************************
    2931DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
    3032{
    31   return DosAliasMem(pb, cb, ppbAlias, fl);
     33 DWORD rc;
     34 DWORD attr;
     35 DWORD size = cb;
     36
     37  cb = (cb-1) & ~0xfff;
     38  cb+= PAGE_SIZE;
     39
     40  rc = DosQueryMem(pb, &size, &attr);
     41  if(rc) {
     42        dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
     43        return rc;
     44  }
     45  size = (size-1) & ~0xfff;
     46  size+= PAGE_SIZE;
     47  if(size != cb) {
     48        dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
     49        return 5;
     50  }
     51  attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
     52  if(attr != fl) {
     53        rc = DosSetMem(pb, size, fl);
     54        if(rc) {
     55                dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
     56                attr = fl;
     57                //just continue for now
     58                //return rc;
     59        }
     60  }
     61  rc = DosAliasMem(pb, cb, ppbAlias, 2);
     62  if(rc) {
     63        dprintf(("OSLibDosAliasMem: DosAliasMem %x %x return %d", pb, cb, rc));
     64        return rc;
     65  }
     66  if(attr != fl) {
     67        rc = DosSetMem(pb, size, attr);
     68        if(rc) {
     69                dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
     70                return rc;
     71        }
     72  }
     73  return 0;
    3274}
    3375//******************************************************************************
  • trunk/src/kernel32/oslibdos.h

    r1710 r1811  
    1 /* $Id: oslibdos.h,v 1.7 1999-11-12 11:38:40 sandervl Exp $ */
     1/* $Id: oslibdos.h,v 1.8 1999-11-22 20:35:50 sandervl Exp $ */
    22
    33/*
     
    9494DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method);
    9595
     96#ifndef PAGE_SIZE
     97#define PAGE_SIZE 4096
    9698#endif
     99
     100#endif
  • trunk/src/kernel32/pefile.cpp

    r956 r1811  
    1 /* $Id: pefile.cpp,v 1.5 1999-09-15 23:38:01 sandervl Exp $ */
     1/* $Id: pefile.cpp,v 1.6 1999-11-22 20:35:51 sandervl Exp $ */
    22
    33/*
     
    1212#include <string.h>
    1313#include <stdlib.h>
    14 #ifdef __WATCOMC__
    15 #include <mem.h>
    16 #endif
    1714#include <win32type.h>
    1815#include <pefile.h>
     
    7370    }
    7471
    75     return (LPVOID)(((ULONG)lpFile + (ULONG)(poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress -
    76                     sh.VirtualAddress) + (ULONG)sh.PointerToRawData));
     72    return (LPVOID)((ULONG)lpFile + poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress);
    7773}
    7874//******************************************************************************
     
    149145    return FALSE;
    150146}
    151 //******************************************************************************
    152 //******************************************************************************
    153 int GetNumberOfResources(LPVOID lpFile)
    154 {
    155   PIMAGE_RESOURCE_DIRECTORY          prdRoot, prdType;
    156   PIMAGE_RESOURCE_DIRECTORY_ENTRY    prde;
    157   int                                nCnt=0, i, j, id;
    158   char                              *resname;
    159 
    160     if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset
    161                     (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
    162         return 0;
    163 
    164     prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
    165 
    166     for (i=0; i<prdRoot->NumberOfNamedEntries+prdRoot->NumberOfIdEntries; i++)
    167     {
    168         prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdRoot + (ULONG)prde->u2.OffsetToData);
    169 
    170         if(i<prdRoot->NumberOfNamedEntries) {
    171                 //SvL: 30-10-'97, high bit is set, so clear to get real offset
    172                 prde->u1.Name &= ~0x80000000;
    173                 for(j=0;j<MAX_RES;j++) {
    174                         resname = UnicodeToFixedAsciiString(*(WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name), (WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name + sizeof(WCHAR)));  // first word = string length
    175                         if(strcmp(resname, ResTypes[j]) == 0)
    176                                 break;
    177                 }
    178                 if(j == MAX_RES) {
    179                         //SvL: 30-10-'97, not found = custom resource type (correct?)
    180                         id = NTRT_RCDATA;
    181                 }
    182                 else    id = j;
    183         }
    184         else    id = prde->u1.Id;
    185 
    186         prdType = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)prdType ^ 0x80000000);
    187 
    188         if(id == NTRT_STRING) {
    189                 //String tables can contain up to 16 individual resources!
    190                 nCnt += prdType->NumberOfNamedEntries*16 + prdType->NumberOfIdEntries*16;
    191         }
    192         else {
    193                 //Only icon groups are stored as resources in the LX file
    194                 //Icon groups contain one or more icons
    195                 if(id != NTRT_ICON)
    196                         nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
    197         }       
    198         prde++;
    199     }
    200 
    201     return nCnt;
    202 }
    203147/** Get Section Header for the given RVA - returns boolean according to the result
    204148 *
  • trunk/src/kernel32/profile.cpp

    r1663 r1811  
    1 /* $Id: profile.cpp,v 1.20 1999-11-09 14:19:46 sandervl Exp $ */
     1/* $Id: profile.cpp,v 1.21 1999-11-22 20:35:51 sandervl Exp $ */
    22
    33/*
     
    715715    else
    716716    {
    717        ret = PROFILE_GetSection( PROFILE_OdinProfile, section, (char*)buffer, len, TRUE, FALSE );
     717        ret = PROFILE_GetSection( PROFILE_OdinProfile, section, (char*)buffer, len, TRUE, FALSE );
    718718    }
    719719    LeaveCriticalSection( &PROFILE_CritSect );
     
    963963      fclose( f );
    964964      strncpy(PROFILE_OdinIniUsed,p,MAX_PATHNAME_LEN-1);
    965     } else
     965    }
     966    else
    966967    {
    967968      HINSTANCE hInstance = LoadLibraryA("KERNEL32.DLL");
  • trunk/src/kernel32/profile.h

    r1663 r1811  
    1 /* $Id: profile.h,v 1.4 1999-11-09 14:19:46 sandervl Exp $ */
     1/* $Id: profile.h,v 1.5 1999-11-22 20:35:51 sandervl Exp $ */
    22/*
    33 * Profile header for initterm
     
    2424                                          LPCSTR def_val, LPSTR buffer,
    2525                                          UINT len);
     26
     27int ODIN_EXTERN(PROFILE_SetOdinIniString)(LPCSTR section_name, LPCSTR key_name,
     28                                          LPCSTR value);
     29
    2630#endif
  • trunk/src/kernel32/virtual.cpp

    r1687 r1811  
    1 /* $Id: virtual.cpp,v 1.22 1999-11-10 14:16:01 sandervl Exp $ */
     1/* $Id: virtual.cpp,v 1.23 1999-11-22 20:35:52 sandervl Exp $ */
    22
    33/*
     
    501501  ULONG offset = ((ULONG)lpvAddress & 0xFFF);
    502502  npages = (cbSize >> 12);
    503   if(cbSize & 0xFFF + offset) {
     503
     504  if( (cbSize & 0xFFF) + offset > 0 ) {
     505        npages++;
     506  }
     507
     508  if( (cbSize & 0xFFF) + offset >= 4096 ) {
    504509        npages++;
    505510  }
  • trunk/src/kernel32/windllbase.cpp

    r1670 r1811  
    1 /* $Id: windllbase.cpp,v 1.4 1999-11-09 19:22:32 sandervl Exp $ */
     1/* $Id: windllbase.cpp,v 1.5 1999-11-22 20:35:52 sandervl Exp $ */
    22
    33/*
     
    274274}
    275275//******************************************************************************
     276//Add renaming profile strings for ole32 & netapi32 to odin.ini if they aren't
     277//already there
     278//******************************************************************************
     279void Win32DllBase::setDefaultRenaming()
     280{
     281 char renameddll[CCHMAXPATH];
     282
     283  if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll,
     284                                   sizeof(renameddll)-1) <= 1)
     285  {
     286        ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2");
     287        ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32");
     288  }
     289  if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll,
     290                                   sizeof(renameddll)-1) <= 1)
     291  {
     292        ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32");
     293        ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32");
     294  }
     295}
     296//******************************************************************************
    276297//rename dll if necessary:
    277298// Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2)
  • trunk/src/kernel32/winimagepeldr.cpp

    r1720 r1811  
    1 /* $Id: winimagepeldr.cpp,v 1.13 1999-11-13 15:41:11 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.14 1999-11-22 20:35:52 sandervl Exp $ */
    22
    33/*
     
    4545#include <win\virtual.h>
    4646#include "oslibdos.h"
     47#include "mmap.h"
    4748
    4849char szErrorTitle[]     = "Odin";
     
    7475    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    7576    nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
    76     fImgMapping(0)
     77    memmap(NULL), pFixups(NULL)
    7778{
    7879 HFILE  dllfile;
     
    120121Win32PeLdrImage::~Win32PeLdrImage()
    121122{
     123  if(memmap)
     124        delete memmap;
     125
     126  if(hFile) {
     127        OSLibDosClose(hFile);
     128        hFile = 0;
     129  }
     130
    122131  if(realBaseAddress)
    123132        DosFreeMem((PVOID)realBaseAddress);
     
    128137  if(ordexports)
    129138        free(ordexports);
    130 
    131   //SvL: Only happens for images that aren't really loaded (RSRC_LOAD)
    132   if(fImgMapping) CloseHandle(fImgMapping);
    133   fImgMapping = 0;
    134139}
    135140//******************************************************************************
     
    137142BOOL Win32PeLdrImage::init(ULONG reservedMem)
    138143{
    139  LPVOID win32file     = NULL;
    140  ULONG  filesize, ulRead;
     144 LPVOID win32file = NULL;
     145 ULONG  filesize, ulRead, ulNewPos;
    141146 PIMAGE_SECTION_HEADER psh;
    142147 IMAGE_SECTION_HEADER sh;
     
    144149 int    nSections, i;
    145150 char   szFullPath[CCHMAXPATH] = "";
    146 
    147   fImgMapping = VIRTUAL_MapFileA(szFileName, &win32file);
    148 
    149   if (fImgMapping == -1) {
    150         strcpy(szErrorModule, OSLibStripPath(szFileName));
     151 IMAGE_DOS_HEADER doshdr;
     152 ULONG  signature;
     153
     154  hFile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
     155
     156  //default error:
     157  strcpy(szErrorModule, OSLibStripPath(szFileName));
     158  if(hFile == NULL) {
    151159        goto failure;
    152160  }
    153 
    154   if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
    155         setFullPath(szFullPath);
    156   }
    157 
    158   if(GetPEFileHeader (win32file, &fh) == FALSE) {
     161  //read dos header
     162  if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {
     163        goto failure;
     164  }
     165  if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) {
     166        goto failure;
     167  }
     168  //read signature dword
     169  if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {
     170        goto failure;
     171  }
     172  //read pe header
     173  if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) {
     174        goto failure;
     175  }
     176  //read optional header
     177  if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) {
     178        goto failure;
     179  }
     180  if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) {
    159181        fout << "Not a valid PE file (probably a 16 bits windows exe/dll)!" << endl;
    160182        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    161183        goto failure;
     184  }
     185
     186  if(oh.SizeOfImage == 0) {//just in case
     187        oh.SizeOfImage = OSLibDosGetFileSize(hFile);
     188  }
     189
     190  imageSize = oh.SizeOfImage;
     191  //Allocate memory told hold the entire image
     192  if(allocSections(reservedMem) == FALSE) {
     193        fout << "Failed to allocate image memory, rc " << errorState << endl;
     194        goto failure;
     195  }
     196
     197  memmap = new Win32MemMap(this, realBaseAddress, imageSize);
     198  if(memmap == NULL || !memmap->Init(0)) {
     199        strcpy(szErrorModule, OSLibStripPath(szFileName));
     200        goto failure;
     201  }
     202  win32file = memmap->mapViewOfFile(0, 0, 2);
     203
     204  if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
     205        setFullPath(szFullPath);
    162206  }
    163207
     
    183227  }
    184228
    185   GetPEOptionalHeader (win32file, &oh);
    186229  fout << "PE file           : " << szFileName << endl;
    187230  fout << "PE Optional header: " << endl;
     
    200243  fout << "FileAlignment     : " << oh.FileAlignment << endl;
    201244  fout << "Subsystem         : " << oh.Subsystem << endl;
     245  fout << "Image Size        : " << oh.SizeOfImage << endl;
     246  fout << "Header Size       : " << oh.SizeOfHeaders << endl;
     247
     248  //get header page
     249  commitPage(realBaseAddress, FALSE);
    202250
    203251  nSections = NR_SECTIONS(win32file);
     
    205253  if(loadType == REAL_LOAD)
    206254  {
     255   imageSize = 0;
    207256   if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) {
    208257    fout << endl << "*************************PE SECTIONS START**************************" << endl;
     
    215264        if(strcmp(psh[i].Name, ".reloc") == 0) {
    216265            fout << ".reloc" << endl << endl;
    217             addSection(SECTION_RELOC, (char *)win32file+psh[i].PointerToRawData,
     266            addSection(SECTION_RELOC, psh[i].PointerToRawData,
    218267                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    219268                   psh[i].Misc.VirtualSize);
     
    222271        if(strcmp(psh[i].Name, ".edata") == 0) {
    223272            fout << ".edata" << endl << endl;
    224             addSection(SECTION_EXPORT, (char *)win32file+psh[i].PointerToRawData,
     273            addSection(SECTION_EXPORT, psh[i].PointerToRawData,
    225274                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    226275                   psh[i].Misc.VirtualSize);
     
    229278        if(strcmp(psh[i].Name, ".rsrc") == 0) {
    230279            fout << ".rsrc" << endl << endl;
    231             addSection(SECTION_RESOURCE, (char *)win32file+psh[i].PointerToRawData,
     280            addSection(SECTION_RESOURCE, psh[i].PointerToRawData,
    232281                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    233282                   psh[i].Misc.VirtualSize);
     
    243292                        fout << "TLS SizeOfZeroFill       " << hex(tlsDir->SizeOfZeroFill) << endl;
    244293                        fout << "TLS Characteristics      " << hex(tlsDir->Characteristics) << endl;
    245                         addSection(SECTION_TLS, (char *)win32file+psh[i].PointerToRawData,
     294                        addSection(SECTION_TLS, psh[i].PointerToRawData,
    246295                                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    247296                                   psh[i].Misc.VirtualSize);
     
    252301        if(strcmp(psh[i].Name, ".debug") == 0) {
    253302            fout << ".rdebug" << endl << endl;
    254             addSection(SECTION_DEBUG, (char *)win32file+psh[i].PointerToRawData,
     303            addSection(SECTION_DEBUG,  psh[i].PointerToRawData,
    255304                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    256305                   psh[i].Misc.VirtualSize);
     
    265314                type |= SECTION_CODE;
    266315            }
    267             addSection(type, (char *)win32file+psh[i].PointerToRawData,
     316            addSection(type, psh[i].PointerToRawData,
    268317                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    269318                   psh[i].Misc.VirtualSize);
     
    278327        {
    279328            fout << "Code Section" << endl << endl;
    280             addSection(SECTION_CODE, (char *)win32file+psh[i].PointerToRawData,
     329            addSection(SECTION_CODE, psh[i].PointerToRawData,
    281330                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    282331                   psh[i].Misc.VirtualSize);
     
    285334        if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
    286335            fout << "Read Only Data Section" << endl << endl;
    287             addSection(SECTION_READONLYDATA, (char *)win32file+psh[i].PointerToRawData,
     336            addSection(SECTION_READONLYDATA, psh[i].PointerToRawData,
    288337                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    289338                   psh[i].Misc.VirtualSize);
     
    292341        if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
    293342            fout << "Uninitialized Data Section" << endl << endl;
    294             addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
     343            addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
    295344                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    296345                   psh[i].Misc.VirtualSize);
     
    299348        if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
    300349            fout << "Initialized Data Section" << endl << endl;
    301             addSection(SECTION_INITDATA, (char *)win32file+psh[i].PointerToRawData,
     350            addSection(SECTION_INITDATA, psh[i].PointerToRawData,
    302351                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    303352                   psh[i].Misc.VirtualSize);
     
    306355        if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) {
    307356            fout << "Other Section, stored as read/write uninit data" << endl << endl;
    308             addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
     357            addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
    309358                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    310359                   psh[i].Misc.VirtualSize);
     
    319368        if(GetSectionHdrByName (win32file, &sh, ".rsrc"))
    320369        {
    321             addSection(SECTION_RESOURCE, (char *)win32file+sh.PointerToRawData,
     370            addSection(SECTION_RESOURCE, sh.PointerToRawData,
    322371                       sh.SizeOfRawData, sh.VirtualAddress + oh.ImageBase,
    323372                       sh.Misc.VirtualSize);
     
    335384        imageSize = imageVirtEnd - oh.ImageBase;
    336385  }
    337   if(allocSections(reservedMem) == FALSE) {
    338         fout << "Failed to allocate image memory, rc " << errorState << endl;
    339         goto failure;
    340   }
     386  if(imageSize < oh.SizeOfImage) {
     387        imageSize = oh.SizeOfImage;
     388  }
     389
    341390  fout << "OS/2 base address " << realBaseAddress << endl;
    342   if(storeSections((char *)win32file) == FALSE) {
    343         fout << "Failed to store sections, rc " << errorState << endl;
    344         goto failure;
    345   }
    346391  if(oh.AddressOfEntryPoint) {
    347392        entryPoint = realBaseAddress + oh.AddressOfEntryPoint;
     
    350395        fout << "EntryPoint == NULL" << endl;
    351396        entryPoint = NULL;
     397  }
     398
     399  //set memory protection flags
     400  if(setMemFlags() == FALSE) {
     401        fout << "Failed to set memory protection" << endl;
     402        goto failure;
    352403  }
    353404
     
    361412                goto failure;
    362413        }
    363         setTLSAddress((char *)(sect->realvirtaddr + (tlsDir->StartAddressOfRawData - sect->virtaddr)));
     414        setTLSAddress((char *)sect->realvirtaddr);
    364415        setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);
    365416        setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);
     
    381432
    382433   if(realBaseAddress != oh.ImageBase) {
    383         if(setFixups((PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC)) == FALSE) {
    384                 fout << "Failed to set fixups" << endl;
    385                 goto failure;
    386         }
     434        pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
     435        commitPage((ULONG)pFixups, FALSE);
    387436   }
    388437   if(fh.Characteristics & IMAGE_FILE_DLL) {
     
    394443  }
    395444
     445  for (i=0; i<nSections; i++) {
     446        commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
     447  }
     448
    396449  //SvL: Use pointer to image header as module handle now. Some apps needs this
    397450  hinstance = (HINSTANCE)realBaseAddress;
     
    413466  }
    414467 
    415   //set final memory protection flags (storeSections sets them to read/write)
    416   if(setMemFlags() == FALSE) {
    417         fout << "Failed to set memory protection" << endl;
    418         goto failure;
    419   }
    420   CloseHandle(fImgMapping);
    421   fImgMapping = 0;
    422 
    423468  return(TRUE);
    424469failure:
    425   if(fImgMapping) CloseHandle(fImgMapping);
    426   fImgMapping = 0;
     470  if(memmap) {
     471        delete memmap;
     472        memmap = NULL;
     473  }
     474  if(hFile) {
     475        OSLibDosClose(hFile);
     476        hFile = 0;
     477  }
    427478  errorState = ERROR_INTERNAL;
    428479  return FALSE;
    429480}
    430481//******************************************************************************
    431 //******************************************************************************
    432 void Win32PeLdrImage::addSection(ULONG type, char *rawdata, ULONG rawsize, ULONG virtaddress, ULONG virtsize)
     482//commits image page(s) when an access violation exception is dispatched
     483//virtAddress = address of exception (rounded down to page boundary)
     484//******************************************************************************
     485BOOL Win32PeLdrImage::commitPage(ULONG virtAddress, BOOL fWriteAccess, int fPageCmd)
     486{
     487 Section *section;
     488 ULONG    offset, size, sectionsize, protflags, fileoffset, range, attr;
     489 ULONG    ulNewPos, ulRead;
     490 APIRET   rc;
     491
     492  rc = DosQueryMem((PVOID)virtAddress, &range, &attr);
     493  if(rc) {
     494        dprintf(("Win32PeLdrImage::commitPage: DosQueryMem returned %d", rc));
     495        return FALSE;
     496  }
     497  if(attr & PAG_COMMIT) {
     498        dprintf(("Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress));
     499        return FALSE;
     500  }
     501
     502  section = findSectionByOS2Addr(virtAddress);
     503  if(section == NULL) {
     504        size        = 4096;
     505        sectionsize = 4096;
     506        protflags   = PAG_READ|PAG_WRITE; //readonly?
     507        section = findPreviousSectionByOS2Addr(virtAddress);
     508        if(section == NULL) {//access to header
     509                fileoffset = virtAddress - realBaseAddress;
     510        }
     511        else {
     512                offset = virtAddress - (section->realvirtaddr + section->virtualsize);
     513                fileoffset = section->rawoffset + section->rawsize + offset;
     514        }
     515  } 
     516  else {
     517        protflags   = section->pageflags;
     518        offset      = virtAddress - section->realvirtaddr;
     519        sectionsize = section->virtualsize - offset;
     520        if(offset > section->rawsize) {
     521                //unintialized data (set to 0)
     522                size = 0;
     523                fileoffset = -1;
     524        } 
     525        else {
     526                size = section->rawsize-offset;
     527                fileoffset = section->rawoffset + offset;
     528        }
     529        if(fWriteAccess & !(section->pageflags & PAG_WRITE)) {
     530                dprintf(("Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress));
     531                return FALSE;
     532        }
     533  }
     534  if(fPageCmd == SINGLE_PAGE) {
     535        size = min(size, PAGE_SIZE);
     536        sectionsize = min(sectionsize, PAGE_SIZE);
     537  }
     538  else
     539  if(fPageCmd == SECTION_PAGES) {
     540        size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE);
     541        sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE);
     542  }
     543  size = min(size, range);
     544  sectionsize = min(sectionsize, range);
     545
     546  if(fileoffset != -1) {
     547        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
     548        if(rc) {
     549                dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     550                return FALSE;
     551        }
     552
     553        if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) {
     554                dprintf(("Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset));
     555                return FALSE;
     556        }
     557        if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) {
     558                dprintf(("Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress));
     559                return FALSE;
     560        }
     561        if(ulRead != size) {
     562                dprintf(("Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes for 0x%x!", size, ulRead, virtAddress));
     563                return FALSE;
     564        }
     565        if(realBaseAddress != oh.ImageBase) {
     566                setFixups(virtAddress, sectionsize);
     567        }
     568
     569        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
     570        if(rc) {
     571                dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     572                return FALSE;
     573        }
     574  }
     575  else {
     576        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
     577        if(rc) {
     578                dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     579                return FALSE;
     580        }
     581        if(realBaseAddress != oh.ImageBase) {
     582                setFixups(virtAddress, sectionsize);
     583        }
     584        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
     585        if(rc) {
     586                dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     587                return FALSE;
     588        }
     589  }
     590  return TRUE;
     591}
     592//******************************************************************************
     593//******************************************************************************
     594void Win32PeLdrImage::addSection(ULONG type, ULONG rawoffset, ULONG rawsize, ULONG virtaddress, ULONG virtsize)
    433595{
    434596  virtsize = max(rawsize, virtsize);
    435597
     598  section[nrsections].rawoffset      = rawoffset;
    436599  section[nrsections].type           = type;
    437   section[nrsections].rawdata        = rawdata;
    438600  section[nrsections].rawsize        = rawsize;
    439601  section[nrsections].virtaddr       = virtaddress;
     
    458620
    459621  if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    460         fout << "No fixups, might not run!" << endl;
    461622        return allocFixedMem(reservedMem);
    462623  }
    463   rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);
     624  rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem);
    464625  if(rc) {
     626        dprintf(("Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc));
    465627        errorState = rc;
    466628        return(FALSE);
     
    490652  }
    491653  return NULL;
     654}
     655//******************************************************************************
     656//******************************************************************************
     657Section *Win32PeLdrImage::findSectionByOS2Addr(ULONG addr)
     658{
     659  for(int i=0;i<nrsections;i++) {
     660        if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) {
     661                return &section[i];
     662        }
     663  }
     664  return NULL;
     665}
     666//******************************************************************************
     667//******************************************************************************
     668Section *Win32PeLdrImage::findPreviousSectionByOS2Addr(ULONG addr)
     669{
     670 ULONG lowestAddr = 0xffffffff;
     671 ULONG index = -1;
     672
     673  for(int i=0;i<nrsections;i++) {
     674        if(section[i].realvirtaddr > addr) {
     675                if(section[i].realvirtaddr < lowestAddr) {
     676                        lowestAddr = section[i].realvirtaddr;
     677                        index = i;
     678                }
     679        }
     680  }
     681  if(index == -1)
     682        return NULL;
     683
     684  return &section[index];
    492685}
    493686//******************************************************************************
     
    503696 ULONG  diff, i, baseAddress;
    504697 APIRET rc;
     698 BOOL   allocFlags = flAllocMem;
    505699
    506700  realBaseAddress = 0;
     
    521715  }
    522716
     717  if(oh.ImageBase < 512*1024*124) {
     718        allocFlags = 0;
     719  }
    523720  while(TRUE) {
    524         rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | flAllocMem);
     721        rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags);
    525722        if(rc) break;
    526723
     
    536733                diff = oh.ImageBase - address;
    537734                if(diff) {
    538                         rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | flAllocMem);
     735                        rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags);
    539736                        if(rc) break;
    540737                }
    541                 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);
     738                rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags);
    542739                if(rc) break;
    543740
     
    561758//******************************************************************************
    562759//******************************************************************************
    563 BOOL Win32PeLdrImage::storeSections(char *win32file)
     760BOOL Win32PeLdrImage::setMemFlags()
    564761{
    565762 int i;
    566  APIRET rc;
    567  ULONG  pagFlags = PAG_COMMIT;
    568  ULONG  headersize;
    569763 WINIMAGE_LOOKUP *imgLookup;
    570764
    571   //Commit memory for image header
    572   headersize = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) +
    573                sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections;
    574 
    575   if(headersize + sizeof(WINIMAGE_LOOKUP) < PAGE_SIZE) {
    576         headersize = PAGE_SIZE;
    577   }
    578   else {//ooops, just in case this doesn't work
    579         fout << "ERROR: storeSections: header too big!!!!!! Fatal error" << endl;
    580         return FALSE;
    581   }
    582 
    583   rc = DosSetMem((PVOID)realBaseAddress, headersize, pagFlags | PAG_WRITE | PAG_READ);
    584   if(rc) {
    585         fout << "DosSetMem failed for Image header! " << rc << endl;
    586         return FALSE;
    587   }
    588   // Store the NT header at the load addr
    589   memcpy((char *)realBaseAddress, win32file, sizeof(IMAGE_DOS_HEADER));
    590   memcpy((char *)PE_HEADER(realBaseAddress), PE_HEADER(win32file), sizeof(IMAGE_NT_HEADERS));
    591   memcpy(PE_SECTIONS(realBaseAddress), PE_SECTIONS(win32file),
    592          sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections );
    593 
    594765  imgLookup = WINIMAGE_LOOKUPADDR(realBaseAddress);
    595   imgLookup->image = this;
    596 #ifdef DEBUG
    597   imgLookup->magic = MAGIC_WINIMAGE;
    598 #endif
     766  imgLookup->magic1 = MAGIC_WINIMAGE;
     767  imgLookup->image  = this;
     768  imgLookup->magic2 = MAGIC_WINIMAGE;
    599769
    600770  // Process all the image sections
     
    602772        section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase);
    603773  }
     774
    604775  for(i=0;i<nrsections;i++) {
    605         pagFlags = PAG_COMMIT;
    606         switch(section[i].type) {
     776        switch(section[i].type)
     777        {
    607778        case SECTION_CODE:
    608779        case (SECTION_CODE | SECTION_IMPORT):
    609         case SECTION_INITDATA:
    610         case SECTION_UNINITDATA:
    611         case SECTION_IMPORT:
    612         case SECTION_READONLYDATA:
    613         case SECTION_RESOURCE:
    614         case SECTION_TLS:
    615                 pagFlags |= PAG_WRITE | PAG_READ;
    616                 break;
    617         case SECTION_EXPORT:
    618         case SECTION_DEBUG:
    619         case SECTION_RELOC:
    620                 pagFlags = 0;   //don't commit
    621                 break;
    622         }
    623         if(pagFlags == 0)   continue;   //debug or export section
    624 
    625         rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
    626         if(rc) {
    627                 errorState = rc;
    628                 return(FALSE);
    629         }
    630         if(section[i].type != SECTION_UNINITDATA) {
    631                 assert(section[i].rawdata);
    632                 memcpy((char *)section[i].realvirtaddr, section[i].rawdata, section[i].rawsize);
    633         }
    634   }
    635   return(TRUE);
    636 }
    637 //******************************************************************************
    638 //******************************************************************************
    639 BOOL Win32PeLdrImage::setMemFlags()
    640 {
    641  int i;
    642  APIRET rc;
    643  ULONG  pagFlags = 0;
    644 
    645   for(i=0;i<nrsections;i++) {
    646         pagFlags = 0;
    647         switch(section[i].type) {
    648         case SECTION_CODE:
    649         case (SECTION_CODE | SECTION_IMPORT):
    650                 pagFlags |= PAG_EXECUTE | PAG_READ;
     780                section[i].pageflags = PAG_EXECUTE | PAG_READ;
    651781                break;
    652782        case SECTION_INITDATA:
    653783        case SECTION_UNINITDATA:
    654784        case SECTION_IMPORT: //TODO: read only?
    655                 pagFlags |= PAG_WRITE | PAG_READ;
     785                section[i].pageflags = PAG_WRITE | PAG_READ;
    656786                break;
    657787        case SECTION_READONLYDATA:
    658788        case SECTION_RESOURCE:
    659789        case SECTION_TLS:
    660                 pagFlags |= PAG_READ;
     790        default:
     791                section[i].pageflags = PAG_READ;
    661792                break;
    662         default:
    663                 continue;
    664793        }
    665         rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
    666         if(rc) {
    667                 errorState = rc;
    668                 return(FALSE);
    669         }
     794  }
     795  return(TRUE);
     796}
     797//******************************************************************************
     798//******************************************************************************
     799BOOL Win32PeLdrImage::setFixups(ULONG virtAddress, ULONG size)
     800{
     801 int   i, j;
     802 char *page;
     803 ULONG count, newpage;
     804 Section *section;
     805 PIMAGE_BASE_RELOCATION prel = pFixups;
     806
     807  if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
     808        return(TRUE);
     809  }
     810
     811  virtAddress -= realBaseAddress;
     812
     813  if(prel) {
     814        j = 1;
     815        while(prel->VirtualAddress && prel->VirtualAddress < virtAddress) {
     816                prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
     817        }
     818        while(prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) {
     819                page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
     820                count  = (prel->SizeOfBlock - 8)/2;
     821                j++;
     822                for(i=0;i<count;i++) {
     823                        int type   = prel->TypeOffset[i] >> 12;
     824                        int offset = prel->TypeOffset[i] & 0xFFF;
     825                        int fixupsize = 0;
     826
     827                        switch(type)
     828                        {
     829                        case IMAGE_REL_BASED_HIGHLOW:
     830                                fixupsize = 4;
     831                                break;
     832                        case IMAGE_REL_BASED_HIGH:
     833                        case IMAGE_REL_BASED_LOW:
     834                                fixupsize = 2;
     835                                break;
     836                        }                       
     837                        //If the fixup crosses the final page boundary,
     838                        //then we have to load another page
     839                        if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
     840                        {
     841                                newpage  = realBaseAddress + prel->VirtualAddress + offset + fixupsize;
     842                                newpage &= ~0xFFF;
     843
     844                                section  = findSectionByOS2Addr(newpage);
     845                                if(section == NULL) {
     846                                        //should never happen
     847                                        dprintf(("::setFixups -> section == NULL!!"));
     848                                        return FALSE;
     849                                }               
     850                                //SvL: Read page from disk
     851                                commitPage(newpage, TRUE, SINGLE_PAGE);
     852
     853                                //SvL: Enable write access
     854                                DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE);
     855                        }
     856
     857                        switch(type)
     858                        {
     859                        case IMAGE_REL_BASED_ABSOLUTE:
     860                                break;  //skip
     861                        case IMAGE_REL_BASED_HIGHLOW:
     862                                AddOff32Fixup(prel->VirtualAddress + offset);
     863                                break;
     864                        case IMAGE_REL_BASED_HIGH:
     865                                AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
     866                                break;
     867                        case IMAGE_REL_BASED_LOW:
     868                                AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
     869                                break;
     870                        case IMAGE_REL_BASED_HIGHADJ:
     871                        case IMAGE_REL_BASED_MIPS_JMPADDR:
     872                        default:
     873                                break;
     874                        }
     875                        if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
     876                        {
     877                                //SvL: Restore original page protection flags
     878                                DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags);
     879                        }
     880
     881                }
     882                prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
     883        }//while
     884  }
     885  else {
     886        dprintf(("Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size));
     887        return(FALSE);
    670888  }
    671889  return(TRUE);
     
    680898
    681899  if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    682     return(TRUE);
     900        return(TRUE);
    683901  }
    684902
     
    701919            case IMAGE_REL_BASED_HIGHLOW:
    702920////                fout << "address " << offset << " type " << type << endl;
    703                 AddOff32Fixup(oh.ImageBase +
    704                           prel->VirtualAddress + offset);
     921                AddOff32Fixup(prel->VirtualAddress + offset);
    705922                break;
    706923            case IMAGE_REL_BASED_HIGH:
    707                 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, TRUE);
     924                AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
    708925                break;
    709926            case IMAGE_REL_BASED_LOW:
    710                 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, FALSE);
     927                AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
    711928                break;
    712929            case IMAGE_REL_BASED_HIGHADJ:
     
    734951 ULONG *fixup;
    735952
    736   fixup   = (ULONG *)(fixupaddr - oh.ImageBase + realBaseAddress);
     953  fixup   = (ULONG *)(fixupaddr + realBaseAddress);
    737954  orgaddr = *fixup;
    738955  *fixup  = realBaseAddress + (*fixup - oh.ImageBase);
     
    745962 USHORT *fixup;
    746963
    747   fixup   = (USHORT *)(fixupaddr - oh.ImageBase + realBaseAddress);
     964  fixup   = (USHORT *)(fixupaddr + realBaseAddress);
    748965  orgaddr = *fixup;
    749966  if(fHighFixup) {
     
    761978 ULONG  apiaddr;
    762979
    763   import  = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
     980  import  = (ULONG *)impaddr;
    764981  apiaddr = WinDll->getApi(ordinal);
    765982  if(apiaddr == 0)
    766983  {
    767     dprintf(("KERNEL32:Win32PeLdrImage - %s.%u not found\n",
    768              WinDll->getName(),
    769              ordinal));
     984        dprintf(("KERNEL32:Win32PeLdrImage - %s.%u not found\n",
     985                 WinDll->getName(),
     986                 ordinal));
    770987
    771988        fout << "--->>> NOT FOUND!" << endl;
     
    781998 ULONG  apiaddr;
    782999
    783   import = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
     1000  import = (ULONG *)impaddr;
    7841001  apiaddr = WinDll->getApi(impname);
    7851002  if(apiaddr == 0)
    7861003  {
    787     dprintf(("KERNEL32:Win32PeLdrImage - %s.%s not found\n",
    788              WinDll->getName(),
    789              impname));
     1004        dprintf(("KERNEL32:Win32PeLdrImage - %s.%s not found\n",
     1005                WinDll->getName(),
     1006                impname));
    7901007
    7911008        fout << "--->>> NOT FOUND!" << endl;
     
    8101027
    8111028        fout << "Exported Functions: " << endl;
    812     ptrOrd     = (USHORT *)((ULONG)ped->AddressOfNameOrdinals -
    813                     (ULONG)sh.VirtualAddress +
    814                             (ULONG)sh.PointerToRawData + (ULONG)win32file);
    815     ptrNames   = (ULONG *)((ULONG)ped->AddressOfNames -
    816                   (ULONG)sh.VirtualAddress +
    817                           (ULONG)sh.PointerToRawData + (ULONG)win32file);
    818     ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions -
    819                   (ULONG)sh.VirtualAddress +
    820                           (ULONG)sh.PointerToRawData + (ULONG)win32file);
     1029    ptrOrd     = (USHORT *)((ULONG)ped->AddressOfNameOrdinals +
     1030                            (ULONG)win32file);
     1031    ptrNames   = (ULONG *)((ULONG)ped->AddressOfNames +
     1032                            (ULONG)win32file);
     1033    ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions +
     1034                            (ULONG)win32file);
    8211035    nrOrdExports  = ped->NumberOfFunctions;
    8221036    nrNameExports = ped->NumberOfNames;
     
    8261040    for(i=0;i<ped->NumberOfNames;i++) {
    8271041        ord       = ptrOrd[i] + ped->Base;
    828         name      = (char *)((ULONG)ptrNames[i] - (ULONG)sh.VirtualAddress +
    829                              (ULONG)sh.PointerToRawData + (ULONG)win32file);
     1042        name      = (char *)((ULONG)ptrNames[i] + (ULONG)win32file);
    8301043        RVAExport = ptrAddress[ptrOrd[i]];
    8311044#ifdef FORWARDERS
     
    8331046#endif
    8341047            //points to code (virtual address relative to oh.ImageBase
    835                 fout << "address 0x";
    836                 fout.setf(ios::hex, ios::basefield);
     1048            AddNameExport(oh.ImageBase + RVAExport, name, ord);
     1049            fout << "address 0x";
     1050            fout.setf(ios::hex, ios::basefield);
    8371051            fout << RVAExport;
    838                     fout.setf(ios::dec, ios::basefield);
    839                 fout << " " << name << "@" << ord << endl;
    840             AddNameExport(oh.ImageBase + RVAExport, name, ord);
     1052            fout.setf(ios::dec, ios::basefield);
     1053            fout << " " << name << "@" << ord << endl;
    8411054#ifdef FORWARDERS
    8421055
    8431056        }
    8441057        else {//forwarder
    845             char *forward = (char *)((ULONG)RVAExport -
    846                          (ULONG)sh.VirtualAddress +
    847                                      (ULONG)sh.PointerToRawData +
    848                              (ULONG)win32file);
     1058            char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file);
    8491059            fout << RVAExport << " " << name << " @" << ord << " is forwarder to " << (int)forward << endl;
    8501060        }
     
    8681078        }
    8691079        else {//forwarder or empty
    870             char *forward = (char *)((ULONG)RVAExport -
    871                          (ULONG)sh.VirtualAddress +
    872                                      (ULONG)sh.PointerToRawData +
    873                              (ULONG)win32file);
     1080            char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file);
    8741081            fout << "ord " << ord << " at 0x";
    875                     fout.setf(ios::hex, ios::basefield);
     1082            fout.setf(ios::hex, ios::basefield);
    8761083            fout << RVAExport << " is forwarder to 0x" << (int)forward << endl;
    877                     fout.setf(ios::dec, ios::basefield);
     1084            fout.setf(ios::dec, ios::basefield);
    8781085        }
    8791086#endif
     
    9391146 IMAGE_SECTION_HEADER     shExtra = {0};
    9401147 PIMAGE_OPTIONAL_HEADER   pOH;
    941  int    i,j;
     1148 int    i,j, nrPages;
    9421149 BOOL   fBorland = 0;
    9431150 int    cModules;
     
    9491156 int    Size;
    9501157 Win32PeLdrDll *WinDll;
     1158 Section *section;
    9511159
    9521160/* "algorithm:"
     
    9751183    //test RVA inside ID-Section
    9761184    if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
    977         pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
     1185        pszTmp = (char*)(pID[i].Name + (ULONG)win32file);
    9781186    }
    9791187    else {
     
    9831191                 return FALSE;
    9841192        }
    985         pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
     1193        pszTmp = (char*)(pID[i].Name + (ULONG)win32file);
    9861194    }
    9871195    Size += strlen(pszTmp) + 1;
     
    9971205    //test RVA inside ID-Section
    9981206    if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
    999         pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
     1207        pszTmp = (char*)(pID[i].Name + (ULONG)win32file);
    10001208    }
    10011209    else {
     
    10091217            }
    10101218        }
    1011         pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
     1219        pszTmp = (char*)(pID[i].Name + (ULONG)win32file);
    10121220    }
    10131221
     
    10411249    }
    10421250    //light borland-style test
    1043     if (pID[i].u.OriginalFirstThunk == 0 || fBorland)
    1044         pulImport = (ULONG*)pID[i].FirstThunk;
     1251    if (pID[i].u.OriginalFirstThunk == 0 || fBorland) {
     1252            pulImport = (ULONG*)pID[i].FirstThunk;
     1253    }
    10451254    else    pulImport = (ULONG*)pID[i].u.OriginalFirstThunk;
    10461255
     
    11311340    WinDll->AddRef();
    11321341
    1133     pulImport  = (PULONG)((ULONG)pulImport - shExtra.VirtualAddress + (ULONG)win32file + shExtra.PointerToRawData);
     1342    pulImport  = (PULONG)((ULONG)pulImport + (ULONG)win32file);
    11341343    j          = 0;
    1135     ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase;
     1344    ulCurFixup = (ULONG)pID[i].FirstThunk + (ULONG)win32file;
     1345
     1346    section    = findSectionByOS2Addr(ulCurFixup);
     1347    if(section == NULL) {
     1348        fout.setf(ios::hex, ios::basefield);
     1349        fout << "Unable to find section for " << ulCurFixup << endl;
     1350        return FALSE;
     1351    }
     1352    //SvL: Read page from disk
     1353    commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE);
     1354    //SvL: Enable write access
     1355    DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE);
     1356    nrPages    = 1;
     1357
    11361358    while (pulImport[j] != 0) {
    11371359        if (pulImport[j] & IMAGE_ORDINAL_FLAG) { //ordinal
     
    11511373            }
    11521374            //KSO - Aug 6 1998 1:15am:this eases comparing...
    1153             char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + shExtra.PointerToRawData - shExtra.VirtualAddress + 2);
     1375            char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + 2);
    11541376            fout.setf(ios::hex, ios::basefield);
    11551377            fout << "0x" << ulCurFixup << " Imported function " << pszFunctionName << endl;
     
    11571379            StoreImportByName(WinDll, pszFunctionName, ulCurFixup);
    11581380        }
    1159             ulCurFixup += sizeof(IMAGE_THUNK_DATA);
     1381        ulCurFixup += sizeof(IMAGE_THUNK_DATA);
    11601382        j++;
     1383        if((ulCurFixup & 0xfff) == 0) {
     1384                commitPage(ulCurFixup & ~0xfff, TRUE, SINGLE_PAGE);
     1385                DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE);
     1386                nrPages++;
     1387        }
    11611388    }
     1389    //SvL: And restore original protection flags
     1390    ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase;
     1391    DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE*nrPages, section->pageflags);
     1392
    11621393    fout << "**********************************************************************" << endl;
    11631394    fout << "************** End Import Module " << pszCurModule << endl;
     
    11841415  do {
    11851416    r = WinMessageBox(HWND_DESKTOP, NULLHANDLE, "The application has called a non-existing api\n",
    1186                   "Internal Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE);
     1417                  "Internal Odin Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE);
    11871418  }
    11881419  while(r == MBID_RETRY); //giggle
  • trunk/src/kernel32/wprocess.cpp

    r1708 r1811  
    1 /* $Id: wprocess.cpp,v 1.49 1999-11-11 19:10:09 sandervl Exp $ */
     1/* $Id: wprocess.cpp,v 1.50 1999-11-22 20:35:52 sandervl Exp $ */
    22
    33/*
     
    265265  SetOS2ExceptionChain(-1);
    266266
     267  Win32DllExitList(0);
     268 
     269  //Note: Needs to be done after Win32DllExitList (destruction of exe + dll objects)
    267270  //Flush and delete all open memory mapped files
    268271  Win32MemMap::deleteAll();
    269 
    270   Win32DllExitList(0);
    271272
    272273  //Restore original OS/2 TIB selector
Note: See TracChangeset for help on using the changeset viewer.