Ignore:
Timestamp:
Aug 25, 1999, 7:05:57 PM (26 years ago)
Author:
sandervl
Message:

Memory mapped file (writes) changes

File:
1 edited

Legend:

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

    r695 r699  
    1 /* $Id: mmap.cpp,v 1.12 1999-08-25 15:27:19 sandervl Exp $ */
     1/* $Id: mmap.cpp,v 1.13 1999-08-25 17:05:57 sandervl Exp $ */
    22
    33/*
     
    1010 *       dispatched to our exception handler until after the kernel mode
    1111 *       call returns (too late))
    12  *
    13  * NOTE: There's no easy way to determine which pages were modified. Temporary
    14  *       solution is to write all paged-in memory to disk.
    1512 *
    1613 * NOTE: Are apps allowed to change the protection flags of memory mapped pages?
     
    140137}
    141138//******************************************************************************
    142 //******************************************************************************
    143 BOOL Win32MemMap::commitPage(LPVOID lpPageFaultAddr, ULONG nrpages)
    144 {
     139//We determine whether a page has been modified by checking it's protection flags
     140//If the write flag is set, this means commitPage had to enable this due to a pagefault
     141//(all pages are readonly until the app tries to write to it)
     142//******************************************************************************
     143BOOL Win32MemMap::commitPage(LPVOID lpPageFaultAddr, ULONG nrpages, BOOL fWriteAccess)
     144{
     145 MEMORY_BASIC_INFORMATION memInfo;
    145146 DWORD pageAddr = (DWORD)lpPageFaultAddr & ~0xFFF;
    146147 DWORD oldProt, newProt, nrBytesRead, offset, size;
     
    151152  dprintf(("Win32MemMap::commitPage %x (faultaddr %x), nr of pages %d", pageAddr, lpPageFaultAddr, nrpages));
    152153  if(hMemFile != -1) {
    153         if(VirtualAlloc((LPVOID)pageAddr, nrpages*PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE) == FALSE) {
    154                 goto fail;
    155         }
    156         offset = pageAddr - (ULONG)pMapping;
    157         size   = nrpages*PAGE_SIZE;
    158         if(offset + size > mSize) {
    159                 size = mSize - offset;
    160         }
    161         if(SetFilePointer(hMemFile, offset, NULL, FILE_BEGIN) != offset) {
    162                 dprintf(("Win32MemMap::commitPage: SetFilePointer failed to set pos to %x", offset));
    163                 goto fail;
    164         }
    165         if(ReadFile(hMemFile, (LPSTR)pageAddr, size, &nrBytesRead, NULL) == FALSE) {
    166                 dprintf(("Win32MemMap::commitPage: ReadFile failed for %x", pageAddr));
    167                 goto fail;
    168         }
    169         if(nrBytesRead != size) {
    170                 dprintf(("Win32MemMap::commitPage: ReadFile didn't read all bytes for %x", pageAddr));
    171                 goto fail;
    172         }
    173         if(mProtFlags & PAGE_READONLY) {
     154        if(VirtualQuery((LPSTR)pageAddr, &memInfo, nrpages*PAGE_SIZE) == 0) {
     155                dprintf(("Win32MemMap::commitPage: VirtualQuery (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
     156                goto fail;
     157        }
     158        if(memInfo.State & MEM_COMMIT)
     159        {//if it's already committed, then the app tried to write to it
     160                if(!fWriteAccess) {
     161                        dprintf(("Win32MemMap::commitPage: Huh? Already committed and not trying to write (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
     162                        goto fail;
     163                }
     164                if(VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt) == FALSE) {
     165                        dprintf(("Win32MemMap::commitPage: Failed to set write flag on page (%x,%x) failed for %x", pageAddr, nrpages*PAGE_SIZE));
     166                        goto fail;
     167                }
     168        }
     169        else {
     170                if(VirtualAlloc((LPVOID)pageAddr, nrpages*PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE) == FALSE) {
     171                        goto fail;
     172                }
     173                offset = pageAddr - (ULONG)pMapping;
     174                size   = nrpages*PAGE_SIZE;
     175                if(offset + size > mSize) {
     176                        size = mSize - offset;
     177                }
     178                if(SetFilePointer(hMemFile, offset, NULL, FILE_BEGIN) != offset) {
     179                        dprintf(("Win32MemMap::commitPage: SetFilePointer failed to set pos to %x", offset));
     180                        goto fail;
     181                }
     182                if(ReadFile(hMemFile, (LPSTR)pageAddr, size, &nrBytesRead, NULL) == FALSE) {
     183                        dprintf(("Win32MemMap::commitPage: ReadFile failed for %x", pageAddr));
     184                        goto fail;
     185                }
     186                if(nrBytesRead != size) {
     187                        dprintf(("Win32MemMap::commitPage: ReadFile didn't read all bytes for %x", pageAddr));
     188                        goto fail;
     189                }
     190                if(mProtFlags & PAGE_READONLY) {
    174191//DosSetMem returns flags with EXECUTE bit set, even though the initial allocation is without this bit set!
    175192//Also returns access denied when trying to set it back to READONLY
    176                 VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt);
    177 //              if(VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt) == FALSE) {
    178 //                      goto fail;
    179 //              }
     193                        VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt);
     194//                      if(VirtualProtect((LPVOID)pageAddr, nrpages*PAGE_SIZE, newProt, &oldProt) == FALSE) {
     195//                              goto fail;
     196//                      }
     197                }
    180198        }
    181199  }
     
    256274}
    257275//******************************************************************************
    258 // NOTE: There's no easy way to determine which pages were modified. Temporary
    259 //       solution is to write all paged-in memory to disk.
     276//We determine whether a page has been modified by checking it's protection flags
     277//If the write flag is set, this means commitPage had to enable this due to a pagefault
     278//(all pages are readonly until the app tries to modify it)
     279//
    260280//TODO: Are apps allowed to change the protection flags of memory mapped pages?
    261281//      I'm assuming they aren't for now.
Note: See TracChangeset for help on using the changeset viewer.