Ignore:
Timestamp:
Jun 18, 2009, 11:53:26 AM (16 years ago)
Author:
ydario
Message:

Kernel32 updates.

File:
1 edited

Legend:

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

    r10369 r21302  
    106106        if(mfAccess & MEMMAP_ACCESS_COPYONWRITE)
    107107        {
     108            //A copy on write view is a private copy of the memory map
     109            //The pages reflect the state of the original map until they are
     110            //modified.
     111            //We use guard pages to track access to the COW view.
     112            pMapView = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE|PAGE_GUARD);
     113            if(pMapView == NULL) {
     114                dprintf(("VirtualAlloc FAILED"));
    108115            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    109116            errorState = 1;
    110117            return;
     118        }
    111119        }
    112120        else
     
    118126        }
    119127    }
     128    //Allocate bitmap for all pages of a COW view to track which pages are
     129    //shared and which are private (copy on write -> private page)
     130    if(fdwAccess == FILE_MAP_COPY)
     131    {
     132        DWORD nrPages = mSize >> PAGE_SHIFT;
     133        if(mSize & 0xFFF)
     134           nrPages++;
     135
     136        int sizebitmap = nrPages/8 + 1;
     137
     138        pCOWBitmap = (char *)malloc(sizebitmap);
     139        if(pCOWBitmap) {
     140            memset(pCOWBitmap, 0, sizebitmap);
     141        }
     142        else DebugInt3();
     143    }
    120144
    121145    dprintf(("Win32MemMapView::Win32MemMapView: created %x (alias for %x), size %d", pMapView, viewaddr, size));
     
    245269//       PAGEVIEW_READONLY      -> set page flags to readonly
    246270//       PAGEVIEW_VIEW          -> set page flags to view default
     271//       PAGEVIEW_GUARD         -> set page flags of COW view to GUARD
    247272//
    248273// Returns:
     
    264289        ( (flags == PAGEVIEW_GUARD) && !(mfAccess & MEMMAP_ACCESS_COPYONWRITE) ) )
    265290    {
     291        //PAGEVIEW_GUARD only applies to COW views
    266292        //PAGEVIEW_VIEW/READONLY does not apply to COW views
    267293        return TRUE;
     
    289315            accessAttr |= PAG_WRITE;
    290316        }
    291     }
    292 
     317        if(flags == PAGEVIEW_GUARD) {
     318            accessAttr |= PAG_GUARD;
     319        }
     320    }
     321
     322    if(flags == PAGEVIEW_GUARD || (mfAccess & MEMMAP_ACCESS_COPYONWRITE))
    293323    {
     324        DWORD startpage = (offset - mOffset) >> PAGE_SHIFT;
     325        DWORD nrPages = size >> PAGE_SHIFT;
     326        if(size & 0xFFF)
     327           nrPages++;
     328
     329        //COW views need special treatment. If we are told to change any flags
     330        //of the COW pages, then only the shared pages must be changed.
     331        //So check each page if it is still shared.
     332        for(int i=startpage;i<startpage+nrPages;i++)
     333    {
     334            if(!isCOWPage(i))
     335            {//page is still shared, so set the guard flag
     336                rc = OSLibDosSetMem((char *)pMapView+(offset - mOffset), PAGE_SIZE, accessAttr);
     337                if(rc) {
     338                    dprintf(("Win32MemMapView::changePageFlags: OSLibDosSetMem %x %x %x failed with %d", (char *)pMapView+(offset - mOffset), size, accessAttr, rc));
     339                    return FALSE;
     340                }
     341            }
     342            offset += PAGE_SIZE;
     343        }
     344    }
     345    else {
    294346        rc = OSLibDosSetMem((char *)pMapView+(offset - mOffset), size, accessAttr);
    295347        if(rc) {
Note: See TracChangeset for help on using the changeset viewer.