📄 mapfile.c
字号:
|| ((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 0x4BOOL 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#endifBOOL 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){ HANDLE hm;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -