Changeset 712 for trunk/src


Ignore:
Timestamp:
Aug 27, 1999, 6:51:01 PM (26 years ago)
Author:
sandervl
Message:

Implemented multiple views of memory mapped files + some bugfixes to PE loader code

Location:
trunk/src/kernel32
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/KERNEL32.DEF

    r690 r712  
    1 ; $Id: KERNEL32.DEF,v 1.30 1999-08-25 14:27:06 sandervl Exp $
     1; $Id: KERNEL32.DEF,v 1.31 1999-08-27 16:51:00 sandervl Exp $
    22
    33;Created by BLAST for IBM's compiler
     
    1616  _DosQueryModFromEIP          =  DOSCALLS.360
    1717   DosQueryModFromEIP          =  DOSCALLS.360
     18   DosAliasMem                 =  DOSCALLS.298
     19  _DosAliasMem                 =  DOSCALLS.298
    1820
    1921
  • trunk/src/kernel32/exceptions.cpp

    r710 r712  
    1 /* $Id: exceptions.cpp,v 1.16 1999-08-27 10:44:21 phaller Exp $ */
     1/* $Id: exceptions.cpp,v 1.17 1999-08-27 16:50:59 sandervl Exp $ */
    22
    33/*
     
    868868                                   PVOID                        p)
    869869{
    870   /*********************************
    871    * Internally handled exceptions *
    872    *********************************/
    873 
    874   /* Access violation at a known location */
    875   if (pERepRec->ExceptionNum == XCPT_ACCESS_VIOLATION)
    876   {
    877     Win32MemMap *map;
    878     BOOL fWriteAccess = FALSE;
    879 
    880     if(pERepRec->ExceptionInfo[1] == 0 &&
    881        pERepRec->ExceptionInfo[1] == XCPT_DATA_UNKNOWN)
    882       goto continueFail;
    883 
    884     map = Win32MemMap::findMap(pERepRec->ExceptionInfo[1]);
    885      if(map == NULL)
    886       goto continueFail;
    887 
    888     switch(pERepRec->ExceptionInfo[0])
    889     {
    890       case XCPT_READ_ACCESS:
    891         if(map->hasReadAccess() == FALSE)
    892           goto continueFail;
    893       break;
    894 
    895       case XCPT_WRITE_ACCESS:
    896         if(map->hasWriteAccess() == FALSE)
    897            goto continueFail;
    898         fWriteAccess = TRUE;
    899         break;
    900 
    901       case XCPT_EXECUTE_ACCESS:
    902         if(map->hasExecuteAccess() == FALSE)
    903           goto continueFail;
    904         break;
    905 
    906      default:
    907        goto continueFail;
    908    }
    909 
    910    //Might want to consider mapping more than one page if access is at
    911    //a high offset in the page
    912    //@@@PH: mapping 16k or 32k might be significally faster in terms of transfer speed
    913    if(map->commitPage((LPVOID)pERepRec->ExceptionInfo[1], 1, fWriteAccess) == TRUE)
    914       return (XCPT_CONTINUE_EXECUTION);
    915 
    916    //no break;
    917   }
    918 continueFail:
    919 
    920 
    921   /************************
    922    * Pass-thru exceptions *
    923    ************************/
    924 
    925870  //  pERegRec->prev_structure = 0;
    926871  dprintfException(pERepRec, pERegRec, pCtxRec, p);
     
    929874  switch(pERepRec->ExceptionNum)
    930875  {
    931     case XCPT_FLOAT_DENORMAL_OPERAND:
    932     case XCPT_FLOAT_DIVIDE_BY_ZERO:
    933     case XCPT_FLOAT_INEXACT_RESULT:
    934     case XCPT_FLOAT_INVALID_OPERATION:
    935     case XCPT_FLOAT_OVERFLOW:
    936     case XCPT_FLOAT_STACK_CHECK:
    937     case XCPT_FLOAT_UNDERFLOW:
    938       dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception, fix and continue\n"));
     876  case XCPT_FLOAT_DENORMAL_OPERAND:
     877  case XCPT_FLOAT_DIVIDE_BY_ZERO:
     878  case XCPT_FLOAT_INEXACT_RESULT:
     879  case XCPT_FLOAT_INVALID_OPERATION:
     880  case XCPT_FLOAT_OVERFLOW:
     881  case XCPT_FLOAT_STACK_CHECK:
     882  case XCPT_FLOAT_UNDERFLOW:
     883        dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception, fix and continue\n"));
    939884        pCtxRec->ctx_env[0] |= 0x1F;
    940885        pCtxRec->ctx_stack[0].losig = 0;
    941886        pCtxRec->ctx_stack[0].hisig = 0;
    942887        pCtxRec->ctx_stack[0].signexp = 0;
    943       return (XCPT_CONTINUE_EXECUTION);
    944 
    945     case XCPT_PROCESS_TERMINATE:
    946     case XCPT_ASYNC_PROCESS_TERMINATE:
    947       SetExceptionChain((ULONG)0);
    948       return (XCPT_CONTINUE_SEARCH);
    949 
    950     case XCPT_ACCESS_VIOLATION:
    951     case XCPT_BREAKPOINT:
    952     case XCPT_ARRAY_BOUNDS_EXCEEDED:
    953     case XCPT_DATATYPE_MISALIGNMENT:
    954     case XCPT_ILLEGAL_INSTRUCTION:
    955     case XCPT_PRIVILEGED_INSTRUCTION:
    956     case XCPT_INVALID_LOCK_SEQUENCE:
    957     case XCPT_INTEGER_DIVIDE_BY_ZERO:
    958     case XCPT_INTEGER_OVERFLOW:
    959     case XCPT_SINGLE_STEP:
    960     case XCPT_GUARD_PAGE_VIOLATION:
    961     case XCPT_UNABLE_TO_GROW_STACK:
    962     case XCPT_IN_PAGE_ERROR:
    963     case XCPT_SIGNAL:
    964       dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
    965       pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
    966       pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
    967       pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
    968       pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
    969       return (XCPT_CONTINUE_EXECUTION);
    970 
    971     default: //non-continuable exceptions
     888
     889        return (XCPT_CONTINUE_EXECUTION);
     890
     891  case XCPT_PROCESS_TERMINATE:
     892  case XCPT_ASYNC_PROCESS_TERMINATE:
     893        SetExceptionChain((ULONG)0);
     894        return (XCPT_CONTINUE_SEARCH);
     895
     896  case XCPT_ACCESS_VIOLATION:
     897  {     
     898   Win32MemMap *map;
     899   BOOL  fWriteAccess = FALSE;
     900   ULONG offset, accessflag;
     901
     902        if(pERepRec->ExceptionInfo[1] == 0 && pERepRec->ExceptionInfo[1] == XCPT_DATA_UNKNOWN) {
     903                goto continueFail;
     904        }
     905        switch(pERepRec->ExceptionInfo[0]) {
     906        case XCPT_READ_ACCESS:
     907                accessflag = MEMMAP_ACCESS_READ;
     908                break;
     909        case XCPT_WRITE_ACCESS:
     910                accessflag = MEMMAP_ACCESS_WRITE;
     911                fWriteAccess = TRUE;
     912                break;
     913        case XCPT_EXECUTE_ACCESS:
     914                accessflag = MEMMAP_ACCESS_EXECUTE;
     915                break;
     916        default:
     917                goto continueFail;
     918        }
     919
     920        map = Win32MemMapView::findMapByView(pERepRec->ExceptionInfo[1], &offset, accessflag);
     921        if(map == NULL) {
     922                goto continueFail;
     923        }
     924        if(map->commitPage(offset, fWriteAccess) == TRUE)
     925                return (XCPT_CONTINUE_EXECUTION);
     926
     927        //no break;
     928  }
     929continueFail:
     930
     931  case XCPT_BREAKPOINT:
     932  case XCPT_ARRAY_BOUNDS_EXCEEDED:
     933  case XCPT_DATATYPE_MISALIGNMENT:
     934  case XCPT_ILLEGAL_INSTRUCTION:
     935  case XCPT_PRIVILEGED_INSTRUCTION:
     936  case XCPT_INVALID_LOCK_SEQUENCE:
     937  case XCPT_INTEGER_DIVIDE_BY_ZERO:
     938  case XCPT_INTEGER_OVERFLOW:
     939  case XCPT_SINGLE_STEP:
     940  case XCPT_GUARD_PAGE_VIOLATION:
     941  case XCPT_UNABLE_TO_GROW_STACK:
     942  case XCPT_IN_PAGE_ERROR:
     943  case XCPT_SIGNAL:
     944        dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
     945        pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
     946        pCtxRec->ctx_RegEsp = pCtxRec->ctx_RegEsp + 0x10;
     947        pCtxRec->ctx_RegEax = pERepRec->ExceptionNum;
     948        pCtxRec->ctx_RegEbx = pCtxRec->ctx_RegEip;
     949        return (XCPT_CONTINUE_EXECUTION);
     950
     951  default: //non-continuable exceptions
    972952        return (XCPT_CONTINUE_SEARCH);
    973953  }
     
    1019999 USHORT sel = GetFS();
    10201000
    1021     SetExceptionChain(val);
     1001    SetExceptionChain(val);   
    10221002    SetFS(sel);
    10231003}
  • trunk/src/kernel32/hmmmap.cpp

    r690 r712  
    1 /* $Id: hmmmap.cpp,v 1.5 1999-08-25 14:27:06 sandervl Exp $ */
     1/* $Id: hmmmap.cpp,v 1.6 1999-08-27 16:51:00 sandervl Exp $ */
    22
    33/*
     
    6767  }
    6868
    69   map = new Win32MemMap(hFile, size_low, protect, (LPSTR)name);
    70   if(map == NULL) {
    71         dprintf(("CreateFileMappingA: can't create Win32MemMap object!"));
    72         return ERROR_OUTOFMEMORY;
    73   } 
     69  map = Win32MemMap::findMap((LPSTR)name);
     70  if(map != NULL) {
     71        dprintf(("CreateFileMappingA: duplicating map %s!", name));
    7472
    75   if(map->Init(pHMHandleData->hHMHandle) == FALSE) {
    76         delete map;
    77         return ERROR_GEN_FAILURE;
     73        DWORD protflags = map->getProtFlags();
     74        switch(protect) {
     75        case FILE_MAP_WRITE:
     76                if(!(protflags & PAGE_WRITECOPY))
     77                        dprintf(("Different flags for duplicate!"));
     78                break;
     79        case FILE_MAP_READ:
     80                if(!(protflags & (PAGE_READWRITE | PAGE_READONLY)))
     81                        dprintf(("Different flags for duplicate!"));
     82                break;
     83        case FILE_MAP_COPY:
     84                if(!(protflags & PAGE_WRITECOPY))
     85                        dprintf(("Different flags for duplicate!"));
     86                break;
     87        }
     88        //TODO:
     89        //Is it allowed to open an existing view with different flags?
     90        //(i.e. write access to readonly object)
     91  }
     92  else {
     93        map = new Win32MemMap(hFile, size_low, protect, (LPSTR)name);
     94
     95        if(map == NULL) {
     96                dprintf(("CreateFileMappingA: can't create Win32MemMap object!"));
     97                return ERROR_OUTOFMEMORY;
     98        }
     99
     100        if(map->Init(pHMHandleData->hHMHandle) == FALSE) {
     101                delete map;
     102                return ERROR_GEN_FAILURE;
     103        }
    78104  }
    79105  map->AddRef();
  • trunk/src/kernel32/mmap.cpp

    r708 r712  
    1 /* $Id: mmap.cpp,v 1.16 1999-08-26 17:56:25 sandervl Exp $ */
     1/* $Id: mmap.cpp,v 1.17 1999-08-27 16:51:00 sandervl Exp $ */
    22
    33/*
    4  * Win32 Memory mapped file class
     4 * Win32 Memory mapped file & view classes
    55 *
    66 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
     
    2828#include <handlemanager.h>
    2929#include "mmap.h"
     30#include "oslibdos.h"
    3031
    3132VMutex globalmapMutex;
     33VMutex globalviewMutex;
    3234
    3335//******************************************************************************
     
    3537//******************************************************************************
    3638Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
    37                : fMapped(FALSE), pMapping(NULL), mMapAccess(0), referenced(0)
     39               : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0)
    3840{
    3941  globalmapMutex.enter();
     
    7274        }
    7375  }
     76
     77  dprintf(("CreateFileMappingA for file %x, prot %x size %d, name %s", hMemFile, mProtFlags, mSize, lpszMapName));
    7478  this->hMemMap = hMemMap;
    7579  mapMutex.leave();
     
    8387Win32MemMap::~Win32MemMap()
    8488{
    85   unmapViewOfFile();
     89  for(int i=0;i<nrMappings;i++) {
     90        Win32MemMapView::deleteView(this); //delete all views of our memory mapped file
     91  }
     92  mapMutex.enter();
    8693  if(lpszMapName) {
    8794        free(lpszMapName);
    8895  }
    89   mapMutex.enter();
    9096  if(pMapping) {
    9197        VirtualFree(pMapping, mSize, MEM_RELEASE);
     
    118124}
    119125//******************************************************************************
    120 //******************************************************************************
    121 BOOL Win32MemMap::hasReadAccess()
    122 {
    123   return TRUE; //should have at least this
    124 }
    125 //******************************************************************************
    126 //******************************************************************************
    127 BOOL Win32MemMap::hasWriteAccess()
    128 {
    129   return !(mProtFlags & PAGE_READONLY);
    130 }
    131 //******************************************************************************
    132 //Might want to add this feature for memory mapping executable & dll files in
    133 //the loader (done in Win32 with the SEC_IMAGE flag?)
    134 //******************************************************************************
    135 BOOL Win32MemMap::hasExecuteAccess()
    136 {
    137   return FALSE;
    138 }
    139 //******************************************************************************
    140126//We determine whether a page has been modified by checking it's protection flags
    141127//If the write flag is set, this means commitPage had to enable this due to a pagefault
    142128//(all pages are readonly until the app tries to write to it)
    143129//******************************************************************************
    144 BOOL Win32MemMap::commitPage(LPVOID lpPageFaultAddr, ULONG nrpages, BOOL fWriteAccess)
     130BOOL Win32MemMap::commitPage(ULONG offset, BOOL fWriteAccess)
    145131{
    146132 MEMORY_BASIC_INFORMATION memInfo;
    147  DWORD pageAddr = (DWORD)lpPageFaultAddr & ~0xFFF;
    148  DWORD oldProt, newProt, nrBytesRead, offset, size;
    149  
     133 LPVOID lpPageFaultAddr = (LPVOID)((ULONG)pMapping + offset);
     134 DWORD pageAddr         = (DWORD)lpPageFaultAddr & ~0xFFF;
     135 DWORD oldProt, newProt, nrBytesRead, size;
     136
    150137//  mapMutex.enter();
     138 
    151139  newProt  = mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY);
    152140
    153   dprintf(("Win32MemMap::commitPage %x (faultaddr %x), nr of pages %d", pageAddr, lpPageFaultAddr, nrpages));
     141  dprintf(("Win32MemMap::commitPage %x (faultaddr %x)", pageAddr, lpPageFaultAddr));
    154142  if(hMemFile != -1) {
    155         if(VirtualQuery((LPSTR)pageAddr, &memInfo, nrpages*PAGE_SIZE) == 0) {
    156                 dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
    157                 goto fail;
    158         }
     143        if(VirtualQuery((LPSTR)pageAddr, &memInfo, NRPAGES_TOCOMMIT*PAGE_SIZE) == 0) {
     144                dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed for %x", pageAddr, NRPAGES_TOCOMMIT*PAGE_SIZE));
     145                goto fail;
     146        }
     147        //Only changes the state of the pages with the same attribute flags
     148        //(returned in memInfo.RegionSize)
     149        //If it's smaller than the mNrPages, it simply means one or more of the
     150        //other pages have already been committed
    159151        if(memInfo.State & MEM_COMMIT)
    160152        {//if it's already committed, then the app tried to write to it
    161153                if(!fWriteAccess) {
    162                         dprintf(("Win32MemMap::commitPage: Huh? Already committed and not trying to write (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
    163                         goto fail;
    164                 }
    165                 if(VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt) == FALSE) {
    166                         dprintf(("Win32MemMap::commitPage: Failed to set write flag on page (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
     154                        dprintf(("Win32MemMap::commitPage: Huh? Already committed and not trying to write (%x,%x) failed for %x", pageAddr, memInfo.RegionSize));
     155                        goto fail;
     156                }
     157                if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) {
     158                        dprintf(("Win32MemMap::commitPage: Failed to set write flag on page (%x,%x) failed for %x", pageAddr, memInfo.RegionSize));
    167159                        goto fail;
    168160                }
    169161        }
    170162        else {
    171                 if(VirtualAlloc((LPVOID)pageAddr, nrpages*PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE) == FALSE) {
     163                if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, PAGE_READWRITE) == FALSE) {
    172164                        goto fail;
    173165                }
    174166                offset = pageAddr - (ULONG)pMapping;
    175                 size   = nrpages*PAGE_SIZE;
     167                size   = memInfo.RegionSize;
    176168                if(offset + size > mSize) {
     169                        dprintf(("Adjusting size from %d to %d", size, mSize - offset));
    177170                        size = mSize - offset;
    178171                }
     
    190183                }
    191184                if(mProtFlags & PAGE_READONLY) {
    192                         if(VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt) == FALSE) {
     185                        if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) {
    193186                                goto fail;
    194187                        }
     
    197190  }
    198191  else {
    199         if(VirtualAlloc((LPVOID)pageAddr, nrpages*PAGE_SIZE, MEM_COMMIT, newProt) == FALSE) {
     192        if(VirtualQuery((LPSTR)pageAddr, &memInfo, NRPAGES_TOCOMMIT*PAGE_SIZE) == 0) {
     193                dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed for %x", pageAddr, NRPAGES_TOCOMMIT*PAGE_SIZE));
     194                goto fail;
     195        }
     196        if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE) {
    200197                goto fail;
    201198        }
     
    209206}
    210207//******************************************************************************
    211 //******************************************************************************
    212 BOOL Win32MemMap::unmapViewOfFile()
    213 {
    214   if(fMapped == FALSE)
    215         return FALSE;
    216 
    217   flushView(pMapping, mSize);
     208//todo: unalias memory
     209//******************************************************************************
     210BOOL Win32MemMap::unmapViewOfFile(Win32MemMapView *view)
     211{
    218212  mapMutex.enter();
    219   if(pMapping) {
     213
     214  if(nrMappings == 0)
     215        goto fail;
     216
     217  delete view;
     218
     219  if(--nrMappings) {
    220220        VirtualFree(pMapping, mSize, MEM_RELEASE);
    221   }
    222   pMapping = NULL;
    223   fMapped = FALSE;
     221        pMapping = NULL;
     222  }
    224223  mapMutex.leave();
    225224  return TRUE;
     225fail:
     226  mapMutex.leave();
     227  return FALSE;
    226228}
    227229//******************************************************************************
     
    232234  ULONG memFlags = (mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY));
    233235  ULONG fAlloc   = 0;
    234   LPVOID mapview;
    235 
     236  Win32MemMapView *mapview;
     237
     238  if(fdwAccess & ~(FILE_MAP_WRITE|FILE_MAP_READ|FILE_MAP_COPY))
     239        goto parmfail;
    236240  if((fdwAccess & FILE_MAP_WRITE) && !(mProtFlags & PAGE_READWRITE))
    237241        goto parmfail;
     
    240244  if((fdwAccess & FILE_MAP_COPY) && !(mProtFlags & PAGE_WRITECOPY))
    241245        goto parmfail;
     246  if(offset+size > mSize)
     247        goto parmfail;
    242248
    243249//TODO: If committed, read file into memory
    244 #if 0 
     250#if 0
    245251  if(mProtFlags & SEC_COMMIT)
    246252        fAlloc |= MEM_COMMIT;
     
    252258#endif
    253259
    254   if(fMapped == FALSE) {//if not mapped, reserve/commit entire view
     260  if(nrMappings == 0) {//if not mapped, reserve/commit entire view
    255261        //SvL: Always read/write access or else ReadFile will crash once we
    256         //     start decommitting pages.
     262        //     start committing pages.
    257263        //     This is most likely an OS/2 bug and doesn't happen in Aurora
    258264        //     when allocating memory with the PAG_ANY bit set. (without this
     
    263269                goto fail;
    264270        }
    265         fMapped = TRUE;
    266   }
    267   mapview = (LPVOID)((ULONG)pMapping + offset);
    268   mapMutex.leave();
    269   return mapview;
     271  }
     272  mapview = new Win32MemMapView(this, offset, (size == 0) ? mSize : size, fdwAccess);
     273  if(mapview == NULL) {
     274        goto fail;
     275  }
     276  if(mapview->everythingOk() == FALSE) {
     277        delete mapview;
     278        goto fail;
     279  }
     280  nrMappings++;
     281  mapMutex.leave();
     282  return mapview->getViewAddr();
    270283
    271284parmfail:
     
    279292//We determine whether a page has been modified by checking it's protection flags
    280293//If the write flag is set, this means commitPage had to enable this due to a pagefault
    281 //(all pages are readonly until the app tries to modify it)
     294//(all pages are readonly until the app tries to modify the contents of the page)
    282295//
    283296//TODO: Are apps allowed to change the protection flags of memory mapped pages?
    284297//      I'm assuming they aren't for now.
    285298//******************************************************************************
    286 BOOL Win32MemMap::flushView(LPVOID lpvBase, ULONG cbFlush)
    287 {
     299BOOL Win32MemMap::flushView(ULONG offset, ULONG cbFlush)
     300{
     301 LPVOID lpvBase = (LPVOID)((ULONG)pMapping+offset);
    288302 MEMORY_BASIC_INFORMATION memInfo;
    289  ULONG nrpages, nrBytesWritten, offset, size;
     303 ULONG nrBytesWritten, size;
    290304 int   i;
    291305
    292 //  mapMutex.enter();
    293306  dprintf(("Win32MemMap::flushView: %x %x", lpvBase, cbFlush));
    294   if(fMapped == FALSE)
     307  if(nrMappings == 0)
    295308        goto parmfail;
    296309
     
    307320        goto success; //TODO: Return an error here?
    308321
    309   nrpages = cbFlush/PAGE_SIZE;
    310   if(cbFlush & 0xFFF)  nrpages++;
    311 
    312   for(i=0;i<nrpages;i++) {
    313         if(VirtualQuery((LPSTR)lpvBase+i*PAGE_SIZE, &memInfo, PAGE_SIZE) == 0) {
     322  while(cbFlush) {
     323        if(VirtualQuery((LPSTR)lpvBase, &memInfo, cbFlush) == 0) {
    314324                dprintf(("Win32MemMap::flushView: VirtualQuery (%x,%x) failed for %x", lpvBase, cbFlush, (ULONG)lpvBase+i*PAGE_SIZE));
    315325                goto fail;
    316326        }
    317         //If a page is reserved or write protected, we won't bother flushing it to disk
     327        //If a page (or range of pages) is reserved or write protected, we
     328        //won't bother flushing it to disk
    318329        if(memInfo.State & MEM_COMMIT &&
    319330           memInfo.AllocationProtect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))
    320331        {//committed and allowed for writing?
    321                 offset = (ULONG)lpvBase+i*PAGE_SIZE - (ULONG)pMapping;
    322                 size   = PAGE_SIZE;
    323                 if(offset + size > mSize) {
    324                         size = mSize - offset;
     332                offset = (ULONG)lpvBase - (ULONG)pMapping;
     333                size   = memInfo.RegionSize;
     334                if(size > cbFlush) {
     335                        size = cbFlush;
    325336                }
    326337                dprintf(("Win32MemMap::flushView for offset %x, size %d", offset, size));
     
    330341                        goto fail;
    331342                }
    332                 if(WriteFile(hMemFile, (LPSTR)lpvBase+i*PAGE_SIZE, size, &nrBytesWritten, NULL) == FALSE) {
    333                         dprintf(("Win32MemMap::flushView: WriteFile failed for %x", (ULONG)lpvBase+i*PAGE_SIZE));
     343                if(WriteFile(hMemFile, (LPSTR)lpvBase, size, &nrBytesWritten, NULL) == FALSE) {
     344                        dprintf(("Win32MemMap::flushView: WriteFile failed for %x", (ULONG)lpvBase));
    334345                        goto fail;
    335346                }
    336347                if(nrBytesWritten != size) {
    337                         dprintf(("Win32MemMap::flushView: WriteFile didn't write all bytes for %x", (ULONG)lpvBase+i*PAGE_SIZE));
    338                         goto fail;
    339                 }
    340         }
     348                        dprintf(("Win32MemMap::flushView: WriteFile didn't write all bytes for %x", (ULONG)lpvBase));
     349                        goto fail;
     350                }
     351        }
     352        lpvBase = (LPVOID)((ULONG)lpvBase + memInfo.RegionSize);
     353
     354        if(cbFlush < memInfo.RegionSize)
     355                break;
     356
     357        cbFlush -= memInfo.RegionSize;
    341358  }
    342359success:
    343 //  mapMutex.leave();
    344360  return TRUE;
    345361parmfail:
    346362  SetLastError(ERROR_INVALID_PARAMETER);
    347 //  mapMutex.leave();
    348363  return FALSE;
    349364fail:
    350 //  mapMutex.leave();
    351365  return FALSE;
    352366}
     
    390404}
    391405//******************************************************************************
     406//Assumes mutex has been acquired
    392407//******************************************************************************
    393408void Win32MemMap::deleteAll()
     
    400415//******************************************************************************
    401416Win32MemMap *Win32MemMap::memmaps = NULL;
     417
     418//******************************************************************************
     419//******************************************************************************
     420Win32MemMapView::Win32MemMapView(Win32MemMap *map, ULONG offset, ULONG size,
     421                                 ULONG fdwAccess)
     422{
     423 LPVOID           viewaddr = (LPVOID)((ULONG)map->getMappingAddr()+offset);
     424 ULONG            accessAttr = 0;
     425 Win32MemMapView *tmpview  = mapviews;
     426
     427  errorState = 0;
     428  mParentMap = map;
     429  mSize    = size;
     430  mOffset  = offset;
     431
     432  switch(fdwAccess) {
     433  case FILE_MAP_READ:
     434        accessAttr = PAG_READ;
     435        mfAccess   = MEMMAP_ACCESS_READ;
     436        break;
     437  case FILE_MAP_WRITE:
     438  case FILE_MAP_COPY:
     439        accessAttr = (PAG_READ|PAG_WRITE);
     440        mfAccess   = MEMMAP_ACCESS_WRITE;
     441        break;
     442  }
     443  if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) {
     444        dprintf(("new OSLibDosAliasMem FAILED"));
     445        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     446        errorState = 1;
     447        return;
     448  }
     449
     450  dprintf(("Win32MemMapView::Win32MemMapView: created %x (alias for %x), size %d", pMapView, viewaddr, size));
     451
     452  globalviewMutex.enter();
     453  if(tmpview == NULL || tmpview->getViewAddr() > pMapView) {
     454        next     = mapviews;
     455        mapviews = this;
     456  }
     457  else {
     458        while(tmpview->next) {
     459                if(tmpview->next->getViewAddr() > pMapView) {
     460                        break;
     461                }
     462                tmpview = tmpview->next;
     463        }
     464        next          = tmpview->next;
     465        tmpview->next = this;
     466  }
     467  globalviewMutex.leave();
     468}
     469//******************************************************************************
     470//******************************************************************************
     471Win32MemMapView::~Win32MemMapView()
     472{
     473  if(errorState != 0)
     474        return;
     475
     476  if(mfAccess != MEMMAP_ACCESS_READ)
     477        mParentMap->flushView(mOffset, mSize);
     478
     479  OSLibDosFreeMem(pMapView);
     480
     481  globalviewMutex.enter();
     482  Win32MemMapView *view = mapviews;
     483
     484  if(view == this) {
     485        mapviews = next;
     486  }
     487  else {
     488        while(view->next) {
     489                if(view->next == this)
     490                        break;
     491                view = view->next;
     492        }
     493        if(view->next) {
     494                view->next = next;
     495        }
     496        else    dprintf(("Win32MemMapView::~Win32MemMapView: map not found!! (%x)", this));
     497  }
     498  globalviewMutex.leave();
     499}
     500//******************************************************************************
     501//******************************************************************************
     502void Win32MemMapView::deleteView(Win32MemMap *map)
     503{
     504  globalviewMutex.enter();
     505  Win32MemMapView *view = mapviews;
     506
     507  if(view != NULL) {
     508        while(view) {
     509                if(view->getParentMap() == map)
     510                {
     511                        globalviewMutex.leave();
     512                        delete view;
     513                        return;
     514                }
     515                view = view->next;
     516        }
     517  }
     518  globalviewMutex.leave();
     519}
     520//******************************************************************************
     521//******************************************************************************
     522Win32MemMap *Win32MemMapView::findMapByView(ULONG address, ULONG *offset,
     523                                            ULONG accessType,
     524                                            Win32MemMapView **pView)
     525{
     526  globalviewMutex.enter();
     527  Win32MemMapView *view = mapviews;
     528
     529  *offset = 0;
     530
     531  if(view != NULL) {
     532        while(view && (ULONG)view->getViewAddr() <= address) {
     533                if((ULONG)view->getViewAddr() <= address &&
     534                   (ULONG)view->getViewAddr() + view->getSize() >= address &&
     535                   view->getAccessFlags() >= accessType)
     536                {
     537                        *offset = view->getOffset() + (address - (ULONG)view->getViewAddr());
     538                        goto success;
     539                }
     540                view = view->next;
     541        }
     542        //failure if we get here
     543        view = NULL;
     544  }
     545success:
     546  globalviewMutex.leave();
     547  if(pView) *pView = view;
     548  return (view) ? view->getParentMap() : NULL;
     549}
     550//******************************************************************************
     551//******************************************************************************
     552Win32MemMapView *Win32MemMapView::findView(LPVOID address)
     553{
     554  Win32MemMapView *view = mapviews;
     555
     556  if(view != NULL) {
     557        while(view) {
     558                if(view->getViewAddr() == address)
     559                {
     560                        break;
     561                }
     562                view = view->next;
     563        }
     564  }
     565  return view;
     566}
     567//******************************************************************************
     568//******************************************************************************
     569Win32MemMapView *Win32MemMapView::mapviews = NULL;
     570
  • trunk/src/kernel32/mmap.h

    r699 r712  
    1 /* $Id: mmap.h,v 1.8 1999-08-25 17:05:57 sandervl Exp $ */
     1/* $Id: mmap.h,v 1.9 1999-08-27 16:51:00 sandervl Exp $ */
    22
    33/*
     
    1919#endif
    2020
     21//commit 4 pages at once when the app accesses it
     22#define NRPAGES_TOCOMMIT        200
     23
     24#define MEMMAP_ACCESS_READ      1
     25#define MEMMAP_ACCESS_WRITE     2
     26#define MEMMAP_ACCESS_EXECUTE   4
     27
     28class Win32MemMapView;
     29
     30//******************************************************************************
     31//******************************************************************************
    2132class Win32MemMap
    2233{
     
    2637
    2738   BOOL   Init(HANDLE hMemMap);
    28    BOOL   flushView(LPVOID lpvBase, ULONG cbFlush);
     39   BOOL   flushView(ULONG offset, ULONG cbFlush);
    2940   LPVOID mapViewOfFile(ULONG size, ULONG offset, ULONG fdwAccess);
    30    BOOL   unmapViewOfFile();
     41   BOOL   unmapViewOfFile(Win32MemMapView *view);
    3142
    3243   HFILE  getMapHandle()                 { return hMemMap; };
    3344   LPSTR  getMemName()                   { return lpszMapName; };
    3445   DWORD  getProtFlags()                 { return mProtFlags; };
     46   LPVOID getMappingAddr()               { return pMapping; };
    3547
    3648   void   AddRef()                       { ++referenced; };
    3749   void   Release()                      { if(--referenced == 0) delete this; };
    3850
    39    BOOL   hasReadAccess();
    40    BOOL   hasWriteAccess();
    41    BOOL   hasExecuteAccess();
    42  
    43    BOOL   commitPage(LPVOID lpPageFaultAddr, ULONG nrpages, BOOL fWriteAccess);
     51   BOOL   commitPage(ULONG offset, BOOL fWriteAccess);
    4452
    4553static Win32MemMap *findMap(LPSTR lpszName);
     
    5664   LPSTR  lpszMapName;
    5765   void  *pMapping;
    58    BOOL   fMapped;
     66
     67   ULONG  nrMappings;
    5968
    6069   ULONG  referenced;
     
    6675          Win32MemMap *next;
    6776};
     77//******************************************************************************
     78//Memory mapped file View Class
     79//******************************************************************************
     80class Win32MemMapView
     81{
     82public:
     83   Win32MemMapView(Win32MemMap *map, ULONG offset, ULONG size, ULONG fdwAccess);
     84  ~Win32MemMapView();
     85
     86   DWORD  getAccessFlags()               { return mfAccess; };
     87   DWORD  getSize()                      { return mSize;    };
     88   LPVOID getViewAddr()                  { return pMapView; };
     89   ULONG  getOffset()                    { return mOffset;  };
     90
     91   BOOL   everythingOk()                 { return errorState == 0; };
     92
     93Win32MemMap *getParentMap()              { return mParentMap;};
     94
     95static void             deleteView(Win32MemMap *map);
     96static Win32MemMap     *findMapByView(ULONG address, ULONG *offset, ULONG accessType, Win32MemMapView **pView=NULL);
     97static Win32MemMapView *findView(LPVOID address);
     98
     99protected:
     100   ULONG  mSize, errorState;
     101   ULONG  mfAccess, mOffset;
     102   void  *pMapView;
     103
     104   Win32MemMap *mParentMap;
     105
     106private:
     107   static Win32MemMapView *mapviews;
     108          Win32MemMapView *next;
     109
     110   friend class Win32MemMap;
     111};
     112//******************************************************************************
     113//******************************************************************************
    68114
    69115#endif //__MMAP_H__
  • trunk/src/kernel32/oslibdos.cpp

    r707 r712  
    1 /* $Id: oslibdos.cpp,v 1.2 1999-08-26 15:05:14 sandervl Exp $ */
     1/* $Id: oslibdos.cpp,v 1.3 1999-08-27 16:51:00 sandervl Exp $ */
    22
    33/*
     
    2323#include "oslibdos.h"
    2424
     25APIRET APIENTRY DosAliasMem(PVOID pb, ULONG cb, PPVOID ppbAlias, ULONG fl);
     26
     27//******************************************************************************
     28//******************************************************************************
     29DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
     30{
     31  return DosAliasMem(pb, cb, ppbAlias, fl);
     32}
    2533//******************************************************************************
    2634//******************************************************************************
    2735DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags)
    2836{
    29 //  return DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
    30   return DosAllocMem(lplpMemAddr, size, flags);
     37  return DosAllocMem(lplpMemAddr, size, flags | flAllocMem);
    3138}
    3239//******************************************************************************
  • trunk/src/kernel32/oslibdos.h

    r707 r712  
    1 /* $Id: oslibdos.h,v 1.2 1999-08-26 15:05:14 sandervl Exp $ */
     1/* $Id: oslibdos.h,v 1.3 1999-08-27 16:51:00 sandervl Exp $ */
    22
    33/*
     
    1414
    1515
     16DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl);
    1617DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags);
    1718DWORD OSLibDosFreeMem(LPVOID lpMemAddr);
  • trunk/src/kernel32/virtual.cpp

    r708 r712  
    1 /* $Id: virtual.cpp,v 1.10 1999-08-26 17:56:26 sandervl Exp $ */
     1/* $Id: virtual.cpp,v 1.11 1999-08-27 16:51:01 sandervl Exp $ */
    22
    33/*
     
    149149{
    150150 Win32MemMap *map;
     151 DWORD offset;
    151152
    152153    if (!base)
     
    155156        return FALSE;
    156157    }
    157     map = Win32MemMap::findMap((ULONG)base);
     158    map = Win32MemMapView::findMapByView((ULONG)base, &offset, MEMMAP_ACCESS_READ);
    158159    if(map == NULL) {
    159160        SetLastError( ERROR_FILE_NOT_FOUND );
    160161        return FALSE;
    161162    }
    162     return map->flushView((LPVOID)base, cbFlush);
     163    return map->flushView(offset, cbFlush);
    163164}
    164165
     
    179180{
    180181 Win32MemMap *map;
     182 Win32MemMapView *view;
     183
     184 DWORD offset;
    181185
    182186    if (!addr)
     
    185189        return FALSE;
    186190    }
    187     map = Win32MemMap::findMap((ULONG)addr);
     191    map = Win32MemMapView::findMapByView((ULONG)addr, &offset, MEMMAP_ACCESS_READ, &view);
    188192    if(map == NULL) {
    189193        SetLastError( ERROR_FILE_NOT_FOUND );
    190194        return FALSE;
    191195    }
    192     return map->unmapViewOfFile();
     196    return map->unmapViewOfFile(view);
    193197}
    194198
     
    461465        return 0;
    462466  }
    463   cbRangeSize = cbLength;
     467 
     468  cbRangeSize = cbLength & ~0xFFF;
     469  if(cbLength & 0xFFF) {
     470        cbRangeSize += PAGE_SIZE;
     471  }
    464472  rc = OSLibDosQueryMem((LPVOID)lpvAddress, &cbRangeSize, &dAttr);
    465473  if(rc) {
  • trunk/src/kernel32/windll.cpp

    r705 r712  
    1 /* $Id: windll.cpp,v 1.16 1999-08-26 12:55:37 sandervl Exp $ */
     1/* $Id: windll.cpp,v 1.17 1999-08-27 16:51:01 sandervl Exp $ */
    22
    33/*
     
    3232#include "vmutex.h"
    3333#include "oslibmisc.h"
     34#include "oslibdos.h"
    3435
    3536VMutex dlllistmutex;   //protects linked lists of heaps
     
    165166 char   modname[CCHMAXPATH];
    166167 char  *syspath;
    167  FILE  *dllfile;
     168 HFILE  dllfile;
    168169 APIRET rc;
    169170 BOOL   fRet;
     
    175176                strcat(szFileName,".DLL");
    176177        }
    177         dllfile = fopen(szFileName, "r");
     178        dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
    178179        if(dllfile == NULL) {//search in libpath for dll
    179180                syspath = getenv("WIN32LIBPATH");
     
    187188                }
    188189        }
    189         else    fclose(dllfile);
     190        else    OSLibDosClose(dllfile);
    190191        if(isPEImage(szFileName) == TRUE) {
    191192                fRet = Win32Image::init(0);
  • trunk/src/kernel32/winimage.cpp

    r705 r712  
    1 /* $Id: winimage.cpp,v 1.17 1999-08-26 12:55:37 sandervl Exp $ */
     1/* $Id: winimage.cpp,v 1.18 1999-08-27 16:51:01 sandervl Exp $ */
    22
    33/*
     
    200200 IMAGE_TLS_DIRECTORY *tlsDir = NULL;
    201201 int    nSections, i;
     202 char   szFullPath[CCHMAXPATH] = "";
    202203
    203204  fImgMapping = VIRTUAL_MapFileA(szFileName, &win32file);
     
    207208        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    208209        goto failure;
     210  }
     211
     212  if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
     213        setFullPath(szFullPath);
    209214  }
    210215
     
    425430        }
    426431  }
    427 
    428   if(processImports((char *)win32file) == FALSE) {
    429         fout << "Failed to process imports!" << endl;
    430         goto failure;
    431   }
    432 
    433432  if(fh.Characteristics & IMAGE_FILE_DLL) {
    434433        if(processExports((char *)win32file) == FALSE) {
     
    437436        }
    438437  }
     438
     439  if(processImports((char *)win32file) == FALSE) {
     440        fout << "Failed to process imports!" << endl;
     441        goto failure;
     442  }
     443
    439444  IMAGE_SECTION_HEADER sh;
    440445  if(GetSectionHdrByName (win32file, &sh, ".rsrc")) {
     
    797802  apiaddr = WinDll->getApi(ordinal);
    798803  if(apiaddr == 0) {
    799     fout << "--->>> NOT FOUND!";
    800     *import = (ULONG)MissingApi;
     804        fout << "--->>> NOT FOUND!";
     805        *import = (ULONG)MissingApi;
    801806  }
    802807  else  *import = apiaddr;
     
    812817  apiaddr = WinDll->getApi(impname);
    813818  if(apiaddr == 0) {
    814     fout << "--->>> NOT FOUND!";
    815     *import = (ULONG)MissingApi;
     819        fout << "--->>> NOT FOUND!";
     820        *import = (ULONG)MissingApi;
    816821  }
    817822  else  *import = apiaddr;
  • trunk/src/kernel32/wprocess.cpp

    r705 r712  
    1 /* $Id: wprocess.cpp,v 1.29 1999-08-26 12:55:38 sandervl Exp $ */
     1/* $Id: wprocess.cpp,v 1.30 1999-08-27 16:51:01 sandervl Exp $ */
    22
    33/*
     
    234234        winexe->setTLSCallBackAddr(TlsCallbackAddr);
    235235
    236         char *modname = getenv("WIN32MODULE");
    237 
    238         if(modname != NULL)
    239         {
    240                 dprintf(("Set full path for exe to %s", modname));
    241                 winexe->setFullPath(modname);
    242         }
    243236        winexe->start();
    244237  }
Note: See TracChangeset for help on using the changeset viewer.