📄 mapfile.c
字号:
LPFSMAP lpm; DWORD bread, len, len2, page; LPVOID pMem = 0, pMem2 = 0; BOOL bWritable, retval = 2; MEMORY_BASIC_INFORMATION mbi; ACCESSKEY ulOldKey; SWITCHKEY(ulOldKey,0xffffffff); addr = PAGEALIGN_DOWN(addr); EnterCriticalSection(&PagerCS); DEBUGMSG(ZONE_PAGING,(L"Taking Mapped PI fault: %8.8lx (%d)\r\n", addr, bWrite)); VirtualQuery((LPVOID)addr, &mbi, sizeof(mbi)); if (mbi.State == MEM_COMMIT) { if ((mbi.Protect == PAGE_READWRITE) || (mbi.Protect == PAGE_EXECUTE_READWRITE) || (!bWrite && ((mbi.Protect == PAGE_READONLY) || (mbi.Protect == PAGE_EXECUTE_READ)))) { DEBUGMSG(ZONE_PAGING,(L"LPI: %8.8lx (%d) -> %d (1)\r\n", addr, bWrite, retval)); LeaveCriticalSection(&PagerCS); return 1; } } if (!(hm = FindMap((LPBYTE)addr))) { DEBUGMSG(ZONE_PAGING,(L"LPI: %8.8lx (%d) -> 0 (4)\r\n",addr,bWrite)); LeaveCriticalSection(&PagerCS); return 0; } lpm = HandleToMap(hm); DEBUGCHK(lpm); bWritable = ((lpm->hFile == INVALID_HANDLE_VALUE) || lpm->pDirty); if (lpm->hFile == INVALID_HANDLE_VALUE) { if (!(pMem = VirtualAlloc((LPVOID)addr, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE))) { DEBUGMSG(ZONE_PAGING, (L" MPI: VA0 Failed!\r\n")); goto exit; } PagedInCount++; retval = 1; } else if (bWritable || !bWrite) { if (mbi.State == MEM_COMMIT) { if (!VirtualProtect((LPVOID)addr, PAGE_SIZE, PAGE_READWRITE, &bread)) { DEBUGMSG(ZONE_PAGING, (L" MPI: VP1 Failed!\r\n")); goto exit; } } else { if (!(pMem = VirtualAlloc((LPVOID)ProcArray[0].dwVMBase, 0x10000, MEM_RESERVE, PAGE_NOACCESS))) { DEBUGMSG(ZONE_PAGING, (L" MPI: VA1 Failed!\r\n")); goto exit; } pMem2 = (LPVOID)((DWORD)pMem + (addr&0xffff)); if (!VirtualAlloc(pMem2, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE)) { DEBUGMSG(ZONE_PAGING, (L" MPI: VA2 Failed!\r\n")); goto exit; } len = addr - (DWORD)lpm->pBase; lpm->bRestart = 0; LeaveCriticalSection(&PagerCS); // flush any logged mapfiles if too many pages are dirty if (bWrite && lpm->bNoAutoFlush && (lpm->dwDirty >= MAYBE_LIMIT_DIRTY - 1)) { FlushMapBuffersLogged(lpm, 0, 0, 0); retval = 3; goto exitnoleave; } len2 = ((DWORD)lpm->pBase + lpm->filelen - addr < PAGE_SIZE ? (DWORD)lpm->pBase + lpm->filelen - addr : PAGE_SIZE); if (!ReadFileWithSeek(lpm->hFile, pMem2, len2, &bread, 0, len, 0) || (bread != len2)) { DEBUGMSG(ZONE_PAGING,(L" MPI: SFP Failed!\r\n")); retval = 3; goto exitnoleave; } EnterCriticalSection(&PagerCS); if (lpm->bRestart) { retval = 1; DEBUGMSG(ZONE_PAGING,(L"LPI: %8.8lx (%d) -> %d (restart)\r\n", addr, bWrite, retval)); goto exit; } VirtualQuery((LPVOID)addr, &mbi, sizeof(mbi)); if (mbi.State == MEM_COMMIT) { if ((mbi.Protect == PAGE_READWRITE) || (mbi.Protect == PAGE_EXECUTE_READWRITE) || (!bWrite && ((mbi.Protect == PAGE_READONLY) || (mbi.Protect == PAGE_EXECUTE_READ)))) retval = 1; else retval = 0; DEBUGMSG(ZONE_PAGING,(L"LPI: %8.8lx (%d) -> %d (1)\r\n", addr, bWrite, retval)); goto exit; } if (!VirtualCopy((LPVOID)addr, pMem2, PAGE_SIZE, bWrite ? PAGE_READWRITE : PAGE_READONLY)) { DEBUGMSG(ZONE_PAGING,(L" MPI: VC Failed!\r\n")); goto exit; } PagedInCount++; } if (bWrite) { page = (addr - (DWORD)lpm->pBase + PAGE_SIZE - 1)/PAGE_SIZE; lpm->pDirty[page/8] |= (1<<(page%8)); lpm->dwDirty++; } retval = 1; } else retval = 0;exit: LeaveCriticalSection(&PagerCS);exitnoleave: DEBUGMSG(ZONE_PAGING,(L"MappedPageIn exit: %8.8lx %8.8lx -> %8.8lx\r\n", bWrite, addr, retval)); if (pMem2) if (!VirtualFree(pMem2,PAGE_SIZE,MEM_DECOMMIT)) DEBUGMSG(ZONE_PAGING,(L" MapPage in failure in VF1!\r\n")); if (pMem) if (!VirtualFree(pMem,0,MEM_RELEASE)) DEBUGMSG(ZONE_PAGING,(L" MapPage in failure in VF2!\r\n")); SETCURKEY(ulOldKey); return retval;}void PageOutFile(void){ HANDLE hMap; LPFSMAP lpm; EnterCriticalSection(&MapNameCS); DEBUGMSG(ZONE_PAGING,(L"MPO: Starting free count: %d\r\n",PageFreeCount)); for (hMap = hMapList; hMap; hMap = lpm->hNext) { lpm = HandleToMap(hMap); DEBUGCHK(lpm); if (lpm->pDirty != (LPBYTE)1) FlushMapBuffers(lpm, 0, lpm->length, FMB_DOFULLDISCARD | (lpm->bNoAutoFlush ? FMB_NOWRITEOUT : 0)); } DEBUGMSG(ZONE_PAGING,(L"MPO: Ending page 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); DEBUGCHK(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; } } } } 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; 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 ignoredHANDLE 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 = 1; DWORD len, realfilelen, reallen; PHDATA phd; LPBYTE pData = 0; BOOL bNoAutoFlush; 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)); bNoAutoFlush = (flProtect & PAGE_INTERNALDBMAPPING) ? 1 : 0; flProtect &= ~(SEC_COMMIT|PAGE_INTERNALDBMAPPING); // Remove from mapper cleanup list, if present if ((hFile != INVALID_HANDLE_VALUE) && !bNoAutoFlush) { CLEANEVENT *pce, *pce2; EnterCriticalSection(&MapNameCS); if (pce = pCFMCleanup) { if (pce->base == hFile) { pCFMCleanup = pce->ceptr; FreeMem(pce, HEAP_CLEANEVENT); } else { while (pce->ceptr && (pce->ceptr->base != hFile)) pce = pce->ceptr; if (pce2 = pce->ceptr) { pce->ceptr = pce2->ceptr; FreeMem(pce2, HEAP_CLEANEVENT); } } } LeaveCriticalSection(&MapNameCS); } // Reject if the file is empty (??) if ((hFile != INVALID_HANDLE_VALUE) && ((realfilelen = SetFilePointer(hFile, 0, 0, FILE_END)) == 0xffffffff)) { KernelCloseHandle(hFile); KSetLastError(pCurThread, ERROR_INVALID_PARAMETER); return 0; } // Determine the size the map should have if ((hFile == INVALID_HANDLE_VALUE) || dwMaxSizeLow) reallen = dwMaxSizeLow; else reallen = realfilelen; if (reallen & 0x80000000) { KernelCloseHandle(hFile); KSetLastError(pCurThread, ERROR_INVALID_PARAMETER); return 0; } // Clip the file to the new size, if necessary if ((hFile != INVALID_HANDLE_VALUE) && (realfilelen < reallen)) { if (!bNoAutoFlush && ((SetFilePointer(hFile, reallen, 0, FILE_BEGIN) != reallen) || !SetEndOfFile(hFile))) { KernelCloseHandle(hFile); KSetLastError(pCurThread, ERROR_ACCESS_DENIED); return 0; } realfilelen = reallen; } // // Make sure the mapping doesn't already exist // EnterCriticalSection(&MapNameCS); if (lpName) { // Check name if ((len = strlenW(lpName)) > MAX_PATH - 1) { KSetLastError(pCurThread, ERROR_INVALID_PARAMETER); goto errexit; } EnterCriticalSection(&MapCS); for (hMap = hMapList; hMap; hMap = lpm->hNext) { lpm = HandleToMap(hMap);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -