⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapfile.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    LPVOID  pMem = 0, pMemPage = 0;
    BOOL    retval, fPageUsed = TRUE;
    WORD    idxPgMem = INVALID_PG_INDEX;

    DEBUGCHK (PagerCS.OwnerThread == hCurThread);
    
    DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE,
             (L"MappedPageInHelper: Taking fault at 0x%08x (%s)\r\n", addr, bWrite ? L"write" : L"read"));

    // cannot write to RO file
    if (bWrite && (INVALID_HANDLE_VALUE != lpm->hFile) && !lpm->pDirty) {
        DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE, (L"MappedPageInHelper:  Failed - Write on Read Only file\r\n"));
        return PAGEIN_FAILURE;
    }

    // check if the memory is already paged-in by others.
    if ((retval = MMQueryState (addr, bWrite)) != PAGEIN_RETRY) {
        return retval;
    }

    // memory back'd file -- simply commit and return
    if (INVALID_HANDLE_VALUE == lpm->hFile) {

        if (!(pMem = VirtualAlloc((LPVOID)addr, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE))) {
            DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE, (L"MappedPageInHelper: PageIn failed COMMITING (%8.8lx)\r\n", addr));
            return PAGEIN_FAILURE;
        }
        PagedInCount++;
        return PAGEIN_SUCCESS;

    }

    //
    // allocate memory for paging
    //
    if (!lpm->pDirty) {
        // RO page, try to get it from paging pool
        pMemPage = GetPagingPage (&lpm->pgqueue, 0, 0, &idxPgMem);
    }
            
    if (!pMemPage) {
        // no paging pool, get a page from secure slot for paging
        if (pMem = VirtualAlloc ((LPVOID)ProcArray[0].dwVMBase, 0x10000, MEM_RESERVE, PAGE_NOACCESS)) {
            pMemPage = VirtualAlloc ((LPVOID)((DWORD)pMem + (addr & 0xffff)), PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
        }
            
        if (!pMemPage) {
            DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE, (L"MappedPageInHelper: PageIn failed on VirtualAlloc\r\n"));
            // it's debatable whether we return PAGEIN_RETRY or PAGEIN_FAILURE when memory allocation failed.
            // for now we're returning PAGEIN_RETRY
        }
    }

    if (pMemPage) {

        lpm->bRestart = 0;

        LeaveCriticalSection(&PagerCS);

        // page in the memory mapped file
        retval = MappedPageInPage (lpm, bWrite, addr, pMemPage);

        EnterCriticalSection(&PagerCS);

        if (PAGEIN_SUCCESS == retval) {

            if (!lpm->bRestart
                && ((retval = MMQueryState (addr, bWrite)) == PAGEIN_RETRY)) {

	            OEMCacheRangeFlush (pMemPage, PAGE_SIZE, CACHE_SYNC_WRITEBACK);
                if (VirtualCopy ((LPVOID)addr, pMemPage, PAGE_SIZE, bWrite ? PAGE_READWRITE : PAGE_READONLY)) {
                    // note: if VirtualCopy Failed, we will return PAGEIN_RETRY since it might be someone
                    //       else paged in the page for us
                    retval = PAGEIN_SUCCESS;
                    PagedInCount++;
                }
                
            } else {
                // if we get here, the page we allocated for paging isn't used. Make sure we return it to
                // the paging pool's free list.
                fPageUsed = FALSE;
            }

        }

        
    }

    if (INVALID_PG_INDEX != idxPgMem) {
        // if we're using paging pool, add the page to the memory mapped file's queue when succeeded,
        // or return it to free list when failed
        if ((PAGEIN_SUCCESS == retval) && fPageUsed) {
            AddPageToQueue (&lpm->pgqueue, idxPgMem, addr, lpm);
        } else {
            AddPageToFreeList (idxPgMem);
        }
    } else {
        if (pMemPage && !VirtualFree(pMemPage, PAGE_SIZE, MEM_DECOMMIT)) {
            DEBUGMSG(1, (L"MappedPageInHelper: VirtualFree 1 failed during PageIn!\r\n"));
        }

        if (pMem && !VirtualFree(pMem, 0, MEM_RELEASE)) {
            DEBUGMSG(1, (L"MappedPageInHelper: VirtualFree 2 failed during PageIn!\r\n"));
        }

    }
    DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE,
             (L"MappedPageInHelper: PageIn exit, 0x%08x (%d) -> %u\r\n", addr, bWrite, retval));

    return retval;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int MappedPageIn (BOOL bWrite, DWORD addr)
{
    int     retval;
    HANDLE  hm;
    LPFSMAP lpm;
    ACCESSKEY ulOldKey;

    addr = PAGEALIGN_DOWN(addr);

    if (!(hm = FindMap((LPBYTE)addr))) {
        DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE,
                 (L"MMFILE: PageIn failed on FindMap 0x%08x (%d)\r\n", addr, bWrite));
        return PAGEIN_FAILURE;
    }

    if (!(lpm = HandleToMap(hm))) {
        DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE, (L"MMFILE: PageIn failed on bad hMap\r\n"));
        DEBUGCHK(0);
        return PAGEIN_FAILURE;
    }
    DEBUGCHK(!(lpm->bDirectROM)); // Should never have to page in ROM maps

    EnterCriticalSection(&PagerCS);
    SWITCHKEY(ulOldKey, 0xffffffff);

    retval = MappedPageInHelper (lpm, bWrite, addr);
    if ((PAGEIN_SUCCESS == retval) && bWrite && lpm->pDirty) {

        DWORD page = (addr - (DWORD)lpm->pBase + PAGE_SIZE - 1)/PAGE_SIZE;

        DEBUGMSG(lpm->pDirty[DIRTY_INDEX(page)] & DIRTY_MASK(page),
                 (TEXT("MappedPageIn: Pagein dirtying already-dirty page %u of map 0x%08x!\r\n"),
                  page, lpm));
        lpm->pDirty[DIRTY_INDEX(page)] |= DIRTY_MASK(page);
        lpm->dwDirty++;

    }
    
    SETCURKEY(ulOldKey);
    LeaveCriticalSection(&PagerCS);
    return retval;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
PageOutFile(void)
{
    HANDLE hMap;
    LPFSMAP lpm;
    
    EnterCriticalSection(&MapNameCS);
    DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE,
             (L"MMFILE: PageOut starting free count: %d\r\n", PageFreeCount));
    
    for (hMap = hMapList; hMap; hMap = lpm->hNext) {
        lpm = HandleToMap(hMap);
        if (lpm) {
            if (lpm->pDirty != (LPBYTE)1) {
                FlushMapBuffers(lpm, 0, lpm->length,
                                FMB_DOFULLDISCARD | (lpm->bNoAutoFlush ? FMB_NOWRITEOUT : 0));
            }
        } else {
            // No way to signal an error -- just continue
            DEBUGCHK(0);
            break;
        }
    }
    
    DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE,
             (L"MMFILE: PageOut ending free count: %d\r\n", PageFreeCount));
    LeaveCriticalSection(&MapNameCS);
}


CLEANEVENT *pCFMCleanup;




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
TryCloseMappedHandle(
    HANDLE h
    )
{
    BOOL retval;
    CLEANEVENT *pce, *pce2;

    EnterCriticalSection(&MapNameCS);

    pce = pCFMCleanup;
    if (pce) {
        if ((pce->size == (DWORD)pCurProc) && (pce->base == h)) {
            pCFMCleanup = pce->ceptr;
            FreeMem(pce, HEAP_CLEANEVENT);
            retval = KernelCloseHandle(h);
            LeaveCriticalSection(&MapNameCS);
            return retval;
        }

        while (pce->ceptr) {
            if ((pce->ceptr->size == (DWORD)pCurProc) && (pce->ceptr->base == h)) {
                pce2 = pce->ceptr;
                pce->ceptr = pce2->ceptr;
                FreeMem(pce2, HEAP_CLEANEVENT);
                retval = KernelCloseHandle(h);
                LeaveCriticalSection(&MapNameCS);
                return retval;
            }

            pce = pce->ceptr;
        }
    }

    LeaveCriticalSection(&MapNameCS);

    KSetLastError(pCurThread, ERROR_INVALID_HANDLE);

    return FALSE;
}




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
CloseMappedFileHandles()
{
    HANDLE  hm;
    LPFSMAP lpm;
    CLEANEVENT *pce, *pce2;

    CloseHugeMemoryAreas(0);

    EnterCriticalSection(&MapNameCS);
    pce = pCFMCleanup;
    while (pce && (pce->size == (DWORD)pCurProc)) {
        pCFMCleanup = pce->ceptr;
        KernelCloseHandle(pce->base);
        FreeMem(pce, HEAP_CLEANEVENT);
        pce = pCFMCleanup;
    }

    if (pce) {
        while (pce->ceptr) {
            if (pce->ceptr->size == (DWORD)pCurProc) {
                pce2 = pce->ceptr;
                pce->ceptr = pce2->ceptr;
                KernelCloseHandle(pce2->base);
                FreeMem(pce2, HEAP_CLEANEVENT);
            } else
                pce = pce->ceptr;
        }
    }

    EnterCriticalSection(&MapCS);
    for (hm = hMapList; hm; hm = lpm->hNext) {

        lpm = HandleToMap(hm);
        if (lpm) {
            
            while ((pce = lpm->lpmlist) && (pce->size == (DWORD)pCurProc)) {
                lpm->lpmlist = pce->ceptr;
                FreeMem(pce, HEAP_CLEANEVENT);
            }
    
            if (lpm->lpmlist) {
                pce2 = lpm->lpmlist;
                pce = pce2->ceptr;
                while (pce) {
                    if (pce->size == (DWORD)pCurProc) {
                        pce2->ceptr = pce->ceptr;
                        FreeMem(pce, HEAP_CLEANEVENT);
                        pce = pce2->ceptr;
                    } else {
                        pce2 = pce;
                        pce = pce->ceptr;
                    }           
                }
            }
        
        } else {
            // No way to signal an error -- just continue
            DEBUGCHK(0);
            break;
        }
    }

    LeaveCriticalSection(&MapCS);
    LeaveCriticalSection(&MapNameCS);
}   



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
HANDLE 
SC_CreateFileForMapping(
    LPCTSTR lpFileName, 
    DWORD   dwDesiredAccess, 
    DWORD   dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,                                
    DWORD   dwCreationDisposition, 
    DWORD   dwFlagsAndAttributes,                               
    HANDLE  hTemplateFile
    )
{
    HANDLE  hFile;
    CALLBACKINFO cbi;
    CLEANEVENT *pce;
    DWORD   dwFlags;

    // Make sure the caller has access to this file
    if ((SC_CeGetCallerTrust() != OEM_CERTIFY_TRUST) 
        && (IsSystemFile(lpFileName) || (dwFlagsAndAttributes & FILE_ATTRIBUTE_SYSTEM))
        && (!g_fSysFileReadable || (dwDesiredAccess & GENERIC_WRITE))) {
        ERRORMSG(1, (TEXT("CreateFileForMapping failed due to insufficient trust\r\n")));
        KSetLastError(pCurThread, ERROR_ACCESS_DENIED);
        return INVALID_HANDLE_VALUE;
    }

    pce = AllocMem(HEAP_CLEANEVENT);
    if (!pce) {
        KSetLastError(pCurThread, ERROR_NOT_ENOUGH_MEMORY);
        return INVALID_HANDLE_VALUE;
    }

    // Prepare to create the file
    cbi.hProc = ProcArray[0].hProc;
    cbi.pfn = (FARPROC)CreateFile;
    cbi.pvArg0 = MapPtr(lpFileName);

    if (dwShareMode & FILE_SHARE_WRITE_OVERRIDE) {
        dwFlags = FILE_SHARE_WRITE | FILE_SHARE_READ;
    } else {
        dwFlags = (dwDesiredAccess == GENERIC_READ) ? FILE_SHARE_READ : 0;
    }

    // Create the file
    hFile = (HANDLE)PerformCallBack(&cbi, dwDesiredAccess, dwFlags, lpSecurityAttributes,
                                    dwCreationDisposition,
                                    dwFlagsAndAttributes | FILE_FLAG_WRITE_THROUGH,
                                    hTemplateFile);
    if (hFile != INVALID_HANDLE_VALUE) {
        // Add to mapper cleanup list
        EnterCriticalSection(&MapNameCS);
        pce->base = hFile;
        pce->size = (DWORD)pCurProc;
        pce->ceptr = pCFMCleanup;
        pCFMCleanup = pce;
        LeaveCriticalSection(&MapNameCS);
    } else
        FreeMem(pce, HEAP_CLEANEVENT);

    return hFile;
}



//------------------------------------------------------------------------------
// flProtect can only combine PAGE_READONLY, PAGE_READWRITE, and SEC_COMMIT
// lpsa ignored
//------------------------------------------------------------------------------
HANDLE 
SC_CreateFileMapping(
    HANDLE  hFile, 
    LPSECURITY_ATTRIBUTES lpsa,
    DWORD   flProtect, 
    DWORD   dwMaxSizeHigh,
    DWORD   dwMaxSizeLow, 
    LPCTSTR lpName
    )
{
    HANDLE  hMap = 0;
    LPFSMAP lpm = 0;
    BYTE    testbyte;
    BOOL    bPage = TRUE;
    DWORD   len, dwFileLen, dwMapLen;
    LPBYTE  pData = 0;
    BOOL    bNoAutoFlush;
    BOOL    bDirectROM = FALSE;
    BY_HANDLE_FILE_INFORMATION info;

    DEBUGMSG(ZONE_ENTRY, (L"SC_CreateFileMapping entry: %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx\r\n",
                          hFile, lpsa, flProtect, dwMaxSizeHigh, dwMaxSizeLow, lpName));

    SetNKCallOut (pCurThread);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -