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