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

📄 mapfile.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 5 页
字号:
        // Clear the restore flag        FlushStruct.dwRestoreFlags = RESTORE_FLAG_NONE;        if (!WriteFileWithSeek(lpm->hFile, &FlushStruct.dwRestoreFlags,                               sizeof(DWORD), &bread, 0,                               offsetof(fslog_t,dwRestoreFlags), 0)            || (bread != sizeof(DWORD))) {            ERRORMSG(1,(L"Failed to clear flags on ValidateFile!\r\n"));                                                        return FALSE;        }        FlushFileBuffers(lpm->hFile);    }    return TRUE;}#define FMBL_FLUSH_SKIP_LIMIT   (PAGES_PER_BLOCK*2)BOOL FlushMapBuffersLogged(LPFSMAP lpm, DWORD dwOffset, DWORD dwLength, DWORD dwFlags){    DWORD remain, page, end, dw1, count;    BOOL 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        //        ERRORMSG(1,(L"FlushMapBuffersLogged being used on old-style " \                    L"(non-transactionable) file system!\r\n"));        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) {        //        // The file is read/write -- we may have dirty pages to flush        //        EnterCriticalSection(&WriterCS);        if (!(dwFlags & FMB_NOWRITEOUT)) {            DWORD dwFilePos, dwMemPos;                        // This struct is used to communicate with ValidateFile.            // Only dwRestoreStart (which we do not modify) is used by any            // other part of the file system.            struct {                DWORD dwRestoreFlags;                DWORD dwRestoreStart;                DWORD dwRestoreSize;            } FlushStruct;            // Track pages that are skipped            DWORD dwSkippedPage[FMBL_FLUSH_SKIP_LIMIT];  // List of page nums            WORD wSkippedPages = 0;                      // Count of pages            WORD wNextSkip;                              // Used to iterate list            count = 0;            //            // Read and update restore data            //            DEBUGMSG(ZONE_PAGING, (L"FMB 1\r\n"));            if (!ReadFileWithSeek(lpm->hFile,&FlushStruct.dwRestoreStart, sizeof(DWORD),                                  &dw1, 0, offsetof(fslog_t,dwRestoreStart), 0)                || (dw1 != sizeof(DWORD))) {                // We can exit here because nothing has been changed.                RETAILMSG(1,(L"Read 0 failed on attempt at logged flush!\r\n"));                LeaveCriticalSection(&WriterCS);                if (dwFlags & FMB_LEAVENAMECS)                    LeaveCriticalSection(&MapNameCS);                                // debugchk because this shouldn't happen                DEBUGCHK(0);                                goto exit;            }            dwFilePos = FlushStruct.dwRestoreStart;            FlushStruct.dwRestoreFlags = RESTORE_FLAG_UNFLUSHED;            FlushStruct.dwRestoreSize = PAGE_SIZE;            if (!WriteFileWithSeek(lpm->hFile, &FlushStruct, sizeof(FlushStruct),                                   &dw1, 0, offsetof(fslog_t,dwRestoreFlags), 0)                || (dw1 != sizeof(FlushStruct))) {                // We can exit here because nothing has been changed.                RETAILMSG(1,(L"Write 0 failed on attempt at logged flush!\r\n"));                LeaveCriticalSection(&WriterCS);                if (dwFlags & FMB_LEAVENAMECS)                    LeaveCriticalSection(&MapNameCS);                goto exit;            }            //            // Now flush the pages in memory back to the file.  We write the            // new pages to the end of the file for safety, and only copy them            // into their rightful places when we are done, inside ValidateFile.            // We cannot clear the dirty flags until all pages are successfully            // flushed, so we only update their dirty flags at the end.            //            // Flush the dirty blocks in the cache back to the file            FlushFileBuffers(lpm->hFile);            EnterCriticalSection(&PagerCS);                        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))) {                    // If it's the first page, make sure the restore data is correct.                    if (!page)                        memcpy(lpm->pBase + offsetof(fslog_t,dwRestoreFlags),                               &FlushStruct, sizeof(FlushStruct));                                        if (VirtualProtect(lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,                                       PAGE_READONLY, &dw1)) {                        LeaveCriticalSection(&PagerCS);                        // Write the page's location to the start of the page                        dwMemPos = page*PAGE_SIZE;                        if (!WriteFileWithSeek(lpm->hFile, &dwMemPos, sizeof(DWORD),                                               &dw1, 0, dwFilePos, 0)                            || (dw1 != sizeof(DWORD))) {                            // We can exit here because nothing has really changed.                            RETAILMSG(1, (L"Write 1 failed on attempt at logged flush!\r\n"));                            goto exitUnlock;                        }                        // Now write the page of data                        dwFilePos += sizeof(DWORD);                        if (!WriteFileWithSeek(lpm->hFile, lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,                                               &dw1, 0, dwFilePos, 0)                            || (dw1 != PAGE_SIZE)) {                            // We can exit here because nothing has really changed.                            RETAILMSG(1,(L"Write 2 failed on attempt at logged flush!\r\n"));                            goto exitUnlock;                        }                        dwFilePos += PAGE_SIZE;                        count++;                        EnterCriticalSection(&PagerCS);                                        } else {                        // Failed the VirtualProtect - skip the page                        if (wSkippedPages < FMBL_FLUSH_SKIP_LIMIT) {                            dwSkippedPage[wSkippedPages] = page;                            wSkippedPages++;                        } else {                            // Reached our limit; this shouldn't happen                            RETAILMSG(1, (TEXT("Logged flush failures exceeded limit! (file 0x%08x)\r\n"),                                          lpm->hFile));                            DEBUGCHK(0);                        }                    }                }            }            // 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);                // If it's the first page, make sure the restore data is correct.                if (!page)                    memcpy(lpm->pBase + offsetof(fslog_t,dwRestoreFlags),                            &FlushStruct, sizeof(FlushStruct));                if (VirtualProtect(lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,                                    PAGE_READONLY, &dw1)) {                    LeaveCriticalSection(&PagerCS);                    // Write the page's location to the start of the page                    dwMemPos = page*PAGE_SIZE;                    if (!WriteFileWithSeek(lpm->hFile, &dwMemPos, sizeof(DWORD),                                           &dw1, 0, dwFilePos, 0)                        || (dw1 != sizeof(DWORD))) {                        // We can exit here because nothing has really changed.                        RETAILMSG(1, (L"Write 3 failed on attempt at logged flush!\r\n"));                        goto exitUnlock;                    }                    // Now write the page of data                    dwFilePos += sizeof(DWORD);                    if (!WriteFileWithSeek(lpm->hFile, lpm->pBase+page*PAGE_SIZE, PAGE_SIZE,                                           &dw1, 0, dwFilePos, 0)                        || (dw1 != PAGE_SIZE)) {                        // We can exit here because nothing has really changed.                        RETAILMSG(1, (L"Write 4 failed on attempt at logged flush!\r\n"));                        goto exitUnlock;                    }                    dwFilePos += PAGE_SIZE;                    count++;                                } else {                    // Failed the VirtualProtect - skip the page                    if (wSkippedPages < FMBL_FLUSH_SKIP_LIMIT) {                        dwSkippedPage[wSkippedPages] = page;                        wSkippedPages++;                    } else {                        // Reached our limit; this shouldn't happen                        RETAILMSG(1, (TEXT("Logged flush failures exceeded limit! (file 0x%08x)\r\n"),                                      lpm->hFile));                        DEBUGCHK(0);                    }                                        LeaveCriticalSection(&PagerCS);                }            } else                LeaveCriticalSection(&PagerCS);            // Flush the dirty blocks in the cache back to the file            FlushFileBuffers(lpm->hFile);            //            // Update restore data again            //            FlushStruct.dwRestoreFlags = RESTORE_FLAG_FLUSHED;            FlushStruct.dwRestoreSize |= count<<16;            if (!WriteFileWithSeek(lpm->hFile, &FlushStruct, sizeof(FlushStruct),                                   &dw1, 0, offsetof(fslog_t,dwRestoreFlags), 0)                || (dw1 != sizeof(FlushStruct))) {                // We can exit here because nothing has really changed.                RETAILMSG(1,(L"Write 5 failed on attempt at logged flush!\r\n"));                goto exitUnlock;            }            // Flush the dirty blocks in the cache back to the file            FlushFileBuffers(lpm->hFile);            DEBUGMSG(ZONE_PAGING, (L"FMB 4\r\n"));                        // Commit the flush.            if (!ValidateFile(lpm)) {                // We cannot validate the file, so we must fail the flush!                goto exitUnlock;            }                            //            // Now that everything is totally done, we can mark the blocks            // as clean.            //                        DEBUGMSG(wSkippedPages, (TEXT("FlushMapBuffersLogged: skipped %u pages\r\n"), wSkippedPages));            if (wSkippedPages > 0) {                wNextSkip = 0;            } else {                wNextSkip = FMBL_FLUSH_SKIP_LIMIT;            }            EnterCriticalSection(&PagerCS);            for (page = dwOffset/PAGE_SIZE; (page+1)*PAGE_SIZE <= end; page++) {                if (lpm->pDirty[page/8] & (1<<(page%8))) {                    if ((wNextSkip < wSkippedPages)                        && (dwSkippedPage[wNextSkip] == page)) {                        // The page was skipped -- leave it marked dirty                        wNextSkip++;                    } else {                        // Mark as clean                        lpm->bRestart = 1;                        lpm->pDirty[page/8] &= ~(1<<(page%8));                        lpm->dwDirty--;                        DEBUGCHK(!(lpm->dwDirty & 0x80000000));                    }                }            }            remain = end - (page*PAGE_SIZE);            if (remain && (lpm->pDirty[page/8] & (1<<(page%8)))) {                if ((wNextSkip < wSkippedPages)                    && (dwSkippedPage[wNextSkip] == page)) {                    // The page was skipped -- leave it marked dirty                    wNextSkip++;                } else {                    // Mark as clean                    lpm->bRestart = 1;                    lpm->pDirty[page/8] &= ~(1<<(page%8));                    lpm->dwDirty--;                    DEBUGCHK(!(lpm->dwDirty & 0x80000000));                }            }            DEBUGCHK((wNextSkip == wSkippedPages) || (wNextSkip == FMBL_FLUSH_SKIP_LIMIT));            DEBUGCHK(!(lpm->dwDirty) || (wSkippedPages > 0));            LeaveCriticalSection(&PagerCS);        }        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)        //        if ((lpm->hFile != INVALID_HANDLE_VALUE) && (dwFlags & FMB_DOFULLDISCARD))            FSMapMemFree(lpm->pBase, lpm->reslen, MEM_DECOMMIT);        if (dwFlags & FMB_LEAVENAMECS)            LeaveCriticalSection(&MapNameCS);    }    // Successful return    retval = TRUE;    goto exit;exitUnlock:    // If an error occurred after some pages were VirtualProtected, we must    // go back and unlock them.        // File must be read/write    DEBUGCHK(lpm->pDirty > (LPBYTE)1);            RETAILMSG(1, (TEXT("FlushMapBuffersLogged: Unlocking protected pages\r\n")));        EnterCriticalSection(&PagerCS);    // Here we assume that all dirty pages should be read/write...    for (page = dwOffset/PAGE_SIZE; (page+1)*PAGE_SIZE <= end; page++) {        if ((lpm->pDirty[page/8] & (1<<(page%8)))            && !VirtualProtect(lpm->pBase + page*PAGE_SIZE, PAGE_SIZE,                               PAGE_READWRITE, &dw1)) {            // Is it possible to fail a call to VirtualProtect?            DEBUGCHK(0);        }    }    remain = end - (page*PAGE_SIZE);    if (remain && (lpm->pDirty[page/8] & (1<<(page%8)))        && !VirtualProtect(lpm->pBase + page*PAGE_SIZE, PAGE_SIZE,                           PAGE_READWRITE, &dw1)) {        // Is it possible to fail a call to VirtualProtect?        DEBUGCHK(0);    }        LeaveCriticalSection(&PagerCS);        // Flush the dirty blocks in the cache back to the file    FlushFileBuffers(lpm->hFile);    LeaveCriticalSection(&WriterCS);    if (dwFlags & FMB_LEAVENAMECS)        LeaveCriticalSection(&MapNameCS);exit:    SETCURKEY(ulOldKey);    return retval;}

⌨️ 快捷键说明

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