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

📄 mapfile.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 5 页
字号:
        || ((dwOffsetLow + length) < dwOffsetLow)
        || ((dwOffsetLow + length) < length)) {
        KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
        goto exit;
    }

    
    //
    // Prepare CleanEvent
    //

    if (!(lpce = AllocMem(HEAP_CLEANEVENT))) {
        KSetLastError(pCurThread,ERROR_OUTOFMEMORY);
        goto exit;
    }

    IncRef(hMap,pCurProc);
    lpret = lpm->pBase + dwOffsetLow;
    lpce->base = lpret;
    lpce->size = (DWORD)pCurProc;
    lpce->ceptr = lpm->lpmlist;
    lpm->lpmlist = lpce;

exit:
    LeaveCriticalSection(&MapNameCS);

    DEBUGMSG(ZONE_ENTRY,(L"SC_MapViewOfFile exit: %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx -> %8.8lx\r\n",
                         hMap, fdwAccess, dwOffsetHigh, dwOffsetLow, cbMap, lpret));

    return lpret;
}


#define FMB_LEAVENAMECS 	0x1
#define FMB_DOFULLDISCARD 	0x2
#define FMB_NOWRITEOUT 		0x4


BOOL FlushMapBuffers(LPFSMAP lpm, DWORD dwOffset, DWORD dwLength, DWORD dwFlags)
{
    DWORD remain, page, end, dw1;
    BOOL res, retval = FALSE;
    HANDLE h;
    LPBYTE pb;
    ACCESSKEY ulOldKey;

    SWITCHKEY(ulOldKey,0xffffffff);


    //
    // Figure out where we're starting and stopping, page-aligned
    //

    if (!dwLength)
        dwLength = lpm->length;
    end = dwOffset+dwLength;
    dwOffset = PAGEALIGN_DOWN(dwOffset);
    end = PAGEALIGN_UP(end);
    if (end > lpm->length)
        end = lpm->length;
    if (end < dwOffset) {
        if (dwFlags & FMB_LEAVENAMECS)
            LeaveCriticalSection(&MapNameCS);
        return FALSE;
    }


    if (lpm->pDirty == (LPBYTE)1) {
        //
        // Old-style (non-transactionable) file system
        //

        h = lpm->hFile;
        pb = lpm->pBase;
        if (dwFlags & FMB_LEAVENAMECS)
            LeaveCriticalSection(&MapNameCS);
        SetFilePointer(h,dwOffset,0,FILE_BEGIN);
        if (!WriteFile(h,pb,end-dwOffset,&remain,0) || (remain != end-dwOffset)) {
            DEBUGMSG(ZONE_PAGING,(L"FMB 5\r\n"));
            DEBUGCHK(0);
            goto exit;
        }
        FlushFileBuffers(h);
        retval = TRUE;

    } else if (lpm->pDirty) {
        //
        // We have dirty memory to flush
        //

        EnterCriticalSection(&WriterCS);

        if (!(dwFlags & FMB_NOWRITEOUT)) {

            DEBUGMSG(ZONE_PAGING,(L"FMB 1\r\n"));
            EnterCriticalSection(&PagerCS);

            //
            // Now flush the pages in memory back to the file
            //

            for (page = dwOffset/PAGE_SIZE; (page+1)*PAGE_SIZE <= end; page++) {

                // Flush the page only if it is dirty
                if (lpm->pDirty[page/8] & (1<<(page%8))) {

                    lpm->bRestart = 1;
                    lpm->pDirty[page/8] &= ~(1<<(page%8));
                    res = VirtualProtect(lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,
                                         PAGE_READONLY, &dw1);
                    DEBUGCHK(res);
                    lpm->dwDirty--;
                    DEBUGCHK(!(lpm->dwDirty & 0x80000000));

                    LeaveCriticalSection(&PagerCS);

                    if (!WriteFileWithSeek(lpm->hFile, lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,
                                           &dw1, 0, page*PAGE_SIZE, 0) ||
                        (dw1 != PAGE_SIZE)) {
                        DEBUGMSG(ZONE_PAGING,(L"FMB 2\r\n"));
                        LeaveCriticalSection(&WriterCS);
                        if (dwFlags & FMB_LEAVENAMECS)
                            LeaveCriticalSection(&MapNameCS);
                        DEBUGCHK(0);
                        goto exit;
                    }

                    EnterCriticalSection(&PagerCS);
                }
            }

            // Flush the incomplete page at the end, if present
            remain = end - (page*PAGE_SIZE);
            if (remain && (lpm->pDirty[page/8] & (1<<(page%8)))) {

                DEBUGCHK(remain<=PAGE_SIZE);
                lpm->bRestart = 1;
                lpm->pDirty[page/8] &= ~(1<<(page%8));
                res = VirtualProtect(lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,
                                     PAGE_READONLY, &dw1);
                DEBUGCHK(res);
                lpm->dwDirty--;
                DEBUGCHK(!(lpm->dwDirty & 0x80000000));

                LeaveCriticalSection(&PagerCS);

                if (!WriteFileWithSeek(lpm->hFile, lpm->pBase+page*PAGE_SIZE, remain,
                                       &dw1, 0, page*PAGE_SIZE, 0)
                    || (dw1 != remain)) {
                    DEBUGMSG(ZONE_PAGING,(L"FMB 3\r\n"));
                    LeaveCriticalSection(&WriterCS);
                    if (dwFlags & FMB_LEAVENAMECS)
                        LeaveCriticalSection(&MapNameCS);
                    DEBUGCHK(0);
                    goto exit;
                }

            } else
                LeaveCriticalSection(&PagerCS);

            DEBUGMSG(ZONE_PAGING,(L"FMB 4\r\n"));

            // Flush the dirty blocks in the cache back to the file
            FlushFileBuffers(lpm->hFile);
        }

        if (dwFlags & FMB_DOFULLDISCARD)
            DecommitROPages(lpm->pBase,lpm->reslen);
        LeaveCriticalSection(&WriterCS);
        if (dwFlags & FMB_LEAVENAMECS)
            LeaveCriticalSection(&MapNameCS);

    } else {
        //
        // No dirty memory
        //

        if ((lpm->hFile != INVALID_HANDLE_VALUE) && (dwFlags & FMB_DOFULLDISCARD))
            FSMapMemFree(lpm->pBase,lpm->reslen,MEM_DECOMMIT);
        if (dwFlags & FMB_LEAVENAMECS)
            LeaveCriticalSection(&MapNameCS);
    }

    retval = TRUE;

exit:
    SETCURKEY(ulOldKey);
    return retval;
}


BOOL KernelCloseHandle(HANDLE hFile)
{
    CALLBACKINFO cbi;

    cbi.hProc = ProcArray[0].hProc;
    cbi.pfn = (FARPROC)CloseHandle;
    cbi.pvArg0 = hFile;

    return (BOOL)PerformCallBack4Int(&cbi);
}


void FreeMap(HANDLE hMap)
{
    CLEANEVENT *lpce;
    LPFSMAP lpm, lpm2;
    HANDLE hm;

    lpm = HandleToMap(hMap);
    DEBUGCHK(lpm);

    EnterCriticalSection(&MapCS);

    // Remove from the list of maps
    if (hMapList == hMap)
        hMapList = HandleToMap(hMap)->hNext;
    else {
        for (hm = hMapList; hm; hm = lpm2->hNext) {
            lpm2 = HandleToMap(hm);
            DEBUGCHK(lpm2);
            if (lpm2->hNext == hMap) {
                lpm2->hNext = lpm->hNext;
                break;
            }
        }
        DEBUGCHK(hm);
    }

    LeaveCriticalSection(&MapCS);

    // Flush all dirty pages back to the file
    if (lpm->bNoAutoFlush)
        FlushMapBuffersLogged(lpm, 0, lpm->length, FMB_LEAVENAMECS);
    else
        FlushMapBuffers(lpm, 0, lpm->length, FMB_LEAVENAMECS);

    if ((lpm->hFile != INVALID_HANDLE_VALUE) && !lpm->bNoAutoFlush)
        KernelCloseHandle(lpm->hFile);

    if (lpm->name)
        FreeName(lpm->name);

    while (lpm->lpmlist) {
        lpce = lpm->lpmlist->ceptr;
        FreeMem(lpm->lpmlist, HEAP_CLEANEVENT);
        lpm->lpmlist = lpce;
    }

    FSMapMemFree(lpm->pBase, lpm->reslen, MEM_DECOMMIT);
    FSMapMemFree(lpm->pBase, lpm->reslen, MEM_RELEASE);
    FreeMem(lpm, HEAP_FSMAP);
    FreeHandle(hMap);
}


HANDLE FindMap(LPBYTE pMem)
{
    HANDLE hm;
    LPFSMAP lpm;

    EnterCriticalSection(&MapCS);

    for (hm = hMapList; hm; hm = lpm->hNext) {
        lpm = HandleToMap(hm);
        DEBUGCHK(lpm);
        if ((lpm->pBase <= pMem) && (pMem < lpm->pBase + lpm->length))
            break;
    }

    LeaveCriticalSection(&MapCS);

    return hm;
}


BOOL SC_UnmapViewOfFile(LPVOID lpvAddr)
{
    BOOL retval = FALSE;
    HANDLE hm;
    BOOL bLeft = 0;
    LPFSMAP lpm;
    CLEANEVENT *lpce, *lpce2;

    DEBUGMSG(ZONE_ENTRY,(L"SC_UnmapViewOfFile entry: %8.8lx\r\n", lpvAddr));

    EnterCriticalSection(&MapNameCS);

    if (hm = FindMap(lpvAddr)) {

        lpm = HandleToMap(hm);
        lpce2 = NULL;

        if (lpce = lpm->lpmlist) {
            if ((lpce->base == lpvAddr) && (lpce->size == (DWORD)pCurProc))
                lpm->lpmlist = lpce->ceptr;
            else {
                do {
                    lpce2 = lpce;
                    lpce = lpce->ceptr;
                } while (lpce && ((lpce->base != lpvAddr)
                                  || (lpce->size != (DWORD)pCurProc)));

                if (lpce)
                    lpce2->ceptr = lpce->ceptr;
            }
        }

        if (lpce) {
            FreeMem(lpce, HEAP_CLEANEVENT);
            if (DecRef(hm, pCurProc, FALSE)) {
                FreeMap(hm);
                bLeft = 1;
            }
            retval = TRUE;
        } else
            KSetLastError(pCurThread, ERROR_INVALID_ADDRESS);

    } else
        KSetLastError(pCurThread, ERROR_INVALID_ADDRESS);

    if (!bLeft)
        LeaveCriticalSection(&MapNameCS);

    DEBUGMSG(ZONE_ENTRY,(L"SC_UnmapViewOfFile exit: %8.8lx -> %8.8lx\r\n",
                         lpvAddr, retval));

    return retval;
}


BOOL SC_FlushViewOfFile(LPCVOID lpBaseAddress, DWORD dwNumberOfBytesToFlush)
{
    BOOL retval = FALSE;
    LPFSMAP lpm;
    HANDLE hm;

    DEBUGMSG(ZONE_ENTRY,(L"SC_FlushViewOfFile entry: %8.8lx %8.8lx\r\n",
                         lpBaseAddress, dwNumberOfBytesToFlush));

    EnterCriticalSection(&MapNameCS);

    if (hm = FindMap((LPBYTE)lpBaseAddress)) {
        lpm = HandleToMap(hm);
        DEBUGCHK(lpm);
        if (lpm->bNoAutoFlush) {
            retval = FlushMapBuffersLogged(lpm, (LPBYTE)lpBaseAddress-lpm->pBase,
                                           dwNumberOfBytesToFlush, FMB_LEAVENAMECS);
        } else
            retval = FlushMapBuffers(lpm, (LPBYTE)lpBaseAddress-lpm->pBase,
                                     dwNumberOfBytesToFlush, FMB_LEAVENAMECS);
    } else
        LeaveCriticalSection(&MapNameCS);
    DEBUGMSG(ZONE_ENTRY,(L"SC_FlushViewOfFile exit: %8.8lx %8.8lx -> %8.8lx\r\n",
                         lpBaseAddress, dwNumberOfBytesToFlush, retval));
    return retval;
}

#if (PAGE_SIZE == 1024)
    #define MAYBE_LIMIT_MEMORY 32
    #define MAYBE_LIMIT_DIRTY 72
#else
    #define MAYBE_LIMIT_MEMORY 10
    #define MAYBE_LIMIT_DIRTY 18
#endif


BOOL SC_FlushViewOfFileMaybe(LPCVOID lpBaseAddress, DWORD dwNumberOfBytesToFlush)
{
    extern long PageOutTrigger;
    BOOL retval = FALSE;
    LPFSMAP lpm;
    HANDLE hm;

    DEBUGMSG(ZONE_ENTRY,(L"SC_FlushViewOfFileMaybe entry: %8.8lx %8.8lx\r\n",
                         lpBaseAddress, dwNumberOfBytesToFlush));

    EnterCriticalSection(&MapNameCS);

    if (hm = FindMap((LPBYTE)lpBaseAddress)) {

        lpm = HandleToMap(hm);
        DEBUGCHK(lpm);

        if ((PageFreeCount >= MAYBE_LIMIT_MEMORY + PageOutTrigger)
            && (lpm->dwDirty < MAYBE_LIMIT_DIRTY)) {
            LeaveCriticalSection(&MapNameCS);
            retval = TRUE;

        } else if (lpm->bNoAutoFlush) {
            retval = FlushMapBuffersLogged(lpm, (LPBYTE)lpBaseAddress-lpm->pBase,
                                           dwNumberOfBytesToFlush, FMB_LEAVENAMECS);

        } else {
            retval = FlushMapBuffers(lpm, (LPBYTE)lpBaseAddress-lpm->pBase,
                                     dwNumberOfBytesToFlush, FMB_LEAVENAMECS);
        }

    } else
        LeaveCriticalSection(&MapNameCS);

    DEBUGMSG(ZONE_ENTRY,(L"SC_FlushViewOfFileMaybe exit: %8.8lx %8.8lx -> %8.8lx\r\n",
                         lpBaseAddress, dwNumberOfBytesToFlush, retval));

    return retval;
}


int MappedPageIn(BOOL bWrite, DWORD addr)

⌨️ 快捷键说明

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