Ignore:
Timestamp:
Apr 2, 2003, 1:03:33 PM (22 years ago)
Author:
sandervl
Message:

PF: Corrected HFILE definition as it is in Wine and in Win2k

File:
1 edited

Legend:

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

    r9946 r9971  
    1 /* $Id: mmap.cpp,v 1.64 2003-03-27 14:13:10 sandervl Exp $ */
     1/* $Id: mmap.cpp,v 1.65 2003-04-02 11:03:31 sandervl Exp $ */
    22
    33/*
     
    7373//******************************************************************************
    7474//******************************************************************************
    75 Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
     75Win32MemMap::Win32MemMap(HANDLE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
    7676               : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0),
    7777                 image(0), pWriteBitmap(NULL)
     
    307307  if(image) {
    308308      return image->commitPage(pageAddr, fWriteAccess);
     309  }
     310
     311  if(fWriteAccess && (mProtFlags & PAGE_WRITECOPY))
     312  {//this is a COW map, call commitGuardPage to handle write faults
     313      return commitGuardPage(ulFaultAddr, offset, fWriteAccess);
    309314  }
    310315
     
    407412                dprintf(("Mark %d page(s) starting at %x as dirty", nrPages, pageAddr));
    408413                markDirtyPages(startPage, nrPages);
     414
     415                //Write access means that the next time the corresponding COW page
     416                //is touched, we need to reload it. So set the GUARD flags.
     417                updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_GUARD);
    409418            }
    410419        }
     
    429438            //Now change all the aliased pages according to their view protection flags
    430439            updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_VIEW);
     440
     441            //Write access means that the next time the corresponding COW page
     442            //is touched, we need to reload it. So set the GUARD flags.
     443            updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_GUARD);
    431444        }
    432445        faultsize -= memInfo.RegionSize;
     
    443456// Win32MemMap::commitGuardPage
    444457//
    445 // Handle a guard page exception
     458// Handle a guard page exception for a copy-on-write view (one page only)
    446459//
    447460// Parameters:
     
    468481   //align at page boundary
    469482   ulOffset &= ~0xFFF;
     483
     484   //commit a single page in the original mapping (pretend read access)
     485   ret = commitPage(ulFaultAddr, ulOffset, FALSE, 1);
     486   if(ret == FALSE) {
     487       DebugInt3();
     488       goto fail;
     489   }
     490   //clear PAGE_GUARD flag, since this page must now be made accessible
     491   dwNewProt = mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY);
     492   if(dwNewProt & PAGE_WRITECOPY) {
     493       dwNewProt |= PAGE_GUARD;
     494   }
     495   dwNewProt &= ~PAGE_GUARD;
     496   if(VirtualProtect((LPVOID)pageAddr, PAGE_SIZE, dwNewProt, &dwOldProt) == FALSE) {
     497       dprintf(("Win32MemMap::commitGuardPage: VirtualProtect %x 0x1000 %x failed!!", pageAddr, dwNewProt));
     498       goto fail;
     499   }
     500   //copy the data from the original mapping to the COW page
     501   memcpy((LPVOID)pageAddr, (char *)pMapping+ulOffset, PAGE_SIZE);
     502
     503   if(fWriteAccess)
     504   {//copy on write; mark pages as private
     505        DWORD startpage = (ulOffset) >> PAGE_SHIFT;
     506
     507        dprintf(("Win32MemMap::commitGuardPage: write access -> mark page as private"));
     508
     509        Win32MemMapView *view = Win32MemMapView::findView(ulFaultAddr);
     510        if(view)
     511        {
     512            view->markCOWPages(startpage, 1);
     513        }
     514        else DebugInt3(); //oh, oh
     515   }
     516   else
     517   {//read access; must set the map + all views to READONLY to track write access
     518
     519       dprintf(("Win32MemMap::commitGuardPage: read access -> set page as READONLY in map + all views"));
     520
     521       //first the memory map page
     522       if(VirtualProtect((LPVOID)pageAddr, PAGE_SIZE, PAGE_READONLY, &dwOldProt) == FALSE) {
     523           dprintf(("Win32MemMap::commitGuardPage: VirtualProtect %x 0x1000 %x failed!!", pageAddr, dwNewProt));
     524           goto fail;
     525       }
     526       //now for any views that exist
     527       updateViewPages(ulOffset, PAGE_SIZE, PAGEVIEW_READONLY);
     528   }
    470529
    471530   return TRUE;
     
    485544//       PAGEVIEW_READONLY      -> set page flags to readonly
    486545//       PAGEVIEW_VIEW          -> set page flags to view default
     546//       PAGEVIEW_GUARD         -> set page flags of COW view to GUARD
    487547//
    488548// Returns:
     
    535595        dprintf(("ERROR: Win32MemMap::invalidatePages: VirtualFree failed!!"));
    536596    }
    537     return TRUE;
     597    //invalidate all shared COW pages too by setting the GUARD flag
     598    //(which forces a resync the next time the app touches them)
     599    return updateViewPages(offset, size, PAGEVIEW_GUARD);
    538600}
    539601//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.