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

📄 mapfile.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
// decommitted already.  pBase and len must be page aligned for DECOMMIT.  pBase must be
// SUB_MAPPER_INCR aligned and len must be page aligned for RELEASE
//------------------------------------------------------------------------------
BOOL 
FSMapMemFree(
    LPBYTE pBase,
    DWORD  len,
    DWORD  flags
    )
{
    BOOL   res, retval = FALSE;
    LPBYTE pCurr = pBase;
    DWORD  curr, trav, currbytes, bytesleft = len;

    DEBUGCHK((DWORD)pCurr == PAGEALIGN_UP((DWORD)pCurr));
    DEBUGCHK(bytesleft == PAGEALIGN_UP(bytesleft));

    EnterCriticalSection(&VAcs);

    if (flags == MEM_DECOMMIT) {

        while (bytesleft) {
            currbytes = ((DWORD)(pCurr + MAPPER_INCR) & ~(MAPPER_INCR-1)) - (DWORD)pCurr;
            if (currbytes > bytesleft)
                currbytes = bytesleft;

            DEBUGCHK((DWORD)pCurr == ((DWORD)pCurr & ~(PAGE_SIZE-1)));
            DEBUGCHK(currbytes == PAGEALIGN_UP(currbytes));

            res = VirtualFree(pCurr, currbytes, MEM_DECOMMIT);
            DEBUGCHK(res);

            pCurr += currbytes;
            bytesleft -= currbytes;
        }

        retval = TRUE;

    } else if (flags == MEM_RELEASE) {

                do {
            curr = ((DWORD)pCurr - FIRST_MAPPER_ADDRESS) / MAPPER_INCR;
            trav = ((DWORD)pCurr / SUB_MAPPER_INCR) & (32-1);  // & (32-1) is faster than % 32
            DEBUGCHK(rbSubRes[curr] & (1 << trav));
            if (!(rbSubRes[curr] &= ~(1 << trav))) {
                rbRes &= ~(1 << curr);
                DeleteMapperSection(FIRST_MAPPER_ADDRESS + (MAPPER_INCR * curr));
            }

            pCurr += SUB_MAPPER_INCR;

        } while (pCurr < pBase + len);

        retval = TRUE;
    }

    LeaveCriticalSection(&VAcs);

    return retval;
}



//------------------------------------------------------------------------------
// pBase and len must be page-aligned
//------------------------------------------------------------------------------
BOOL 
FSMapMemCommit(
    LPBYTE pBase,
    DWORD  len,
    DWORD  access
    )
{
    BOOL   retval = FALSE;
    LPBYTE pFree, pCurr = pBase;
    DWORD  currbytes, bytesleft = len;

    DEBUGCHK((DWORD)pCurr == PAGEALIGN_UP((DWORD)pCurr));
    DEBUGCHK(bytesleft == PAGEALIGN_UP(bytesleft));

    EnterCriticalSection(&VAcs);

    while (bytesleft) {

        currbytes = (((DWORD)pCurr + MAPPER_INCR) & ~(MAPPER_INCR-1)) - (DWORD)pCurr;
        if (currbytes > bytesleft)
            currbytes = bytesleft;
        DEBUGCHK(currbytes == PAGEALIGN_UP(currbytes));

        if (!VirtualAlloc(pCurr, currbytes, MEM_COMMIT, access)) {
            pFree = pBase;
            bytesleft = len;

            while (pFree != pCurr) {
                currbytes = (((DWORD)pCurr + MAPPER_INCR) & ~(MAPPER_INCR-1)) - (DWORD)pCurr;
                if (currbytes > bytesleft)
                    currbytes = bytesleft;

                VirtualFree(pFree, currbytes, MEM_DECOMMIT);

                pFree += currbytes;
                bytesleft -= currbytes;
            }

            goto exit;
        }

        pCurr += currbytes;
        bytesleft -= currbytes;
    }

    retval = TRUE;

exit:
    LeaveCriticalSection(&VAcs);

    return retval;
}



//------------------------------------------------------------------------------
// Provides r/w view if request r/o view of r/w map
//------------------------------------------------------------------------------
LPVOID 
SC_MapViewOfFile(
    HANDLE  hMap,
    DWORD   fdwAccess,
    DWORD   dwOffsetHigh,
    DWORD   dwOffsetLow,
    DWORD   cbMap
    )
{
    LPFSMAP lpm;
    LPVOID  lpret = 0;
    DWORD   length;
    CLEANEVENT *lpce;

    DEBUGMSG(ZONE_ENTRY || ZONE_MAPFILE,
             (L"SC_MapViewOfFile entry: %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx\r\n",
              hMap, fdwAccess, dwOffsetHigh, dwOffsetLow, cbMap));

    EnterCriticalSection(&MapNameCS);


    //
    // Check args
    //

    lpm = HandleToMapPerm(hMap);
    if (!lpm) {
        KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
        goto exit;
    }

    length = (cbMap ? cbMap : lpm->length - dwOffsetLow);

    if ((fdwAccess == FILE_MAP_ALL_ACCESS)
        || (fdwAccess == (FILE_MAP_WRITE | FILE_MAP_READ)))
        fdwAccess = FILE_MAP_WRITE;

    if (dwOffsetHigh
        || ((fdwAccess == FILE_MAP_WRITE)
            && (lpm->hFile != INVALID_HANDLE_VALUE)
            && !lpm->pDirty)
        || (fdwAccess & ~(FILE_MAP_READ | FILE_MAP_WRITE))
        || ((dwOffsetLow + length) > lpm->length)
        || ((dwOffsetLow + length) < dwOffsetLow)
        || ((dwOffsetLow + length) < length)) {
        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
        goto exit;
    }

    
    //
    // Prepare CleanEvent
    //

    lpce = AllocMem(HEAP_CLEANEVENT);
    if (!lpce) {
        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 || ZONE_MAPFILE,
             (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;

    // No pages to flush on ROM maps
    if (lpm->bDirectROM) {
        if (dwFlags & FMB_LEAVENAMECS)
            LeaveCriticalSection(&MapNameCS);
        return TRUE;
    }

    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);
        goto exit;
    }


    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 (!FSWriteFile(h, pb, end - dwOffset, &remain) || (remain != end - dwOffset)) {
            DEBUGMSG(ZONE_PAGING || ZONE_MAPFILE, (L"MMFILE: FlushMap failed on write 1\r\n"));
            DEBUGCHK(0);
            goto exit;
        }
        FlushFileBuffers(h);
        retval = TRUE;

    } else if (lpm->pDirty) {
        //
        // The file is read/write -- we may have dirty pages to flush
        //

        EnterCriticalSection(&WriterCS);

        if (!(dwFlags & FMB_NOWRITEOUT)) {

            DEBUGMSG(ZONE_MAPFILE, (L"MMFILE: FlushMap\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[DIRTY_INDEX(page)] & DIRTY_MASK(page)) {

                    res = VirtualProtect(lpm->pBase + page*PAGE_SIZE, PAGE_SIZE,
                                         PAGE_READONLY, &dw1);
                    DEBUGCHK(res);

                    LeaveCriticalSection(&PagerCS);

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

                    EnterCriticalSection(&PagerCS);
                    
                    lpm->bRestart = 1;
                    lpm->pDirty[DIRTY_INDEX(page)] &= ~DIRTY_MASK(page);
                    lpm->dwDirty--;
                    DEBUGCHK(!(lpm->dwDirty & 0x80000000));
                }
            }

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

                DEBUGCHK(remain <= PAGE_SIZE);
                res = VirtualProtect(lpm->pBase + page*PAGE_SIZE, PAGE_SIZE,
                                     PAGE_READONLY, &dw1);
                DEBUGCHK(res);

                LeaveCriticalSection(&PagerCS);

                if (!WriteFileWithSeek(lpm->hFile, lpm->pBase + page*PAGE_SIZE, remain,
                                       &dw1, 0, page*PAGE_SIZE, 0)
                    || (dw1 != remain)) {
                    DEBUGMSG(ZONE_MAPFILE, (L"MMFILE: FlushMap failed on write 3\r\n"));
                    LeaveCriticalSection(&WriterCS);
                    if (dwFlags & FMB_LEAVENAMECS)
                        LeaveCriticalSection(&MapNameCS);
                    DEBUGCHK(0);
                    goto exit;
                }
                
                EnterCriticalSection(&PagerCS);
                
                lpm->bRestart = 1;
                lpm->pDirty[DIRTY_INDEX(page)] &= ~DIRTY_MASK(page);
                lpm->dwDirty--;
                DEBUGCHK(!(lpm->dwDirty & 0x80000000));
            }
            
            LeaveCriticalSection(&PagerCS);

            DEBUGMSG(ZONE_MAPFILE, (L"MMFILE: FlushMap succeeded\r\n"));

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

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

    } else {
        //
        // The file is read-only (no dirty pages to flush)
        //
        DEBUGCHK (!lpm->bDirectROM);

        if ((lpm->hFile != INVALID_HANDLE_VALUE) && (dwFlags & FMB_DOFULLDISCARD)) {
            FSMapMemFree(lpm->pBase, lpm->reslen, MEM_DECOMMIT);
            FreeAllPagesFromQ (&lpm->pgqueue);
        }
        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);
}




//------------------------------------------------------------------------------

⌨️ 快捷键说明

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