📄 mapfile.c
字号:
/* * NK Kernel loader code * * Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved. * * Module Name: * * mapfile.c * * Abstract: * * This file implements the NK kernel mapped file routines * */#include "kernel.h"DWORD rbRes;DWORD rbSubRes[NUM_MAPPER_SECTIONS];extern CRITICAL_SECTION VAcs, PagerCS, MapCS, MapNameCS, WriterCS;HANDLE hMapList;BOOL SC_MapCloseHandle(HANDLE hMap);BOOL ValidateFile(LPFSMAP lpm);BOOL FlushMapBuffersLogged(LPFSMAP lpm, DWORD dwOffset, DWORD dwLength, DWORD dwFlags);const PFNVOID MapMthds[] = { (PFNVOID)SC_MapCloseHandle, (PFNVOID)0, (PFNVOID)SC_MapViewOfFile,};const CINFO cinfMap = { "FMAP", DISPATCH_KERNEL_PSL, HT_FSMAP, sizeof(MapMthds)/sizeof(MapMthds[0]), MapMthds};#define SUB_MAPPER_INCR (MAPPER_INCR/32)#define MapBits(n) ((n) == 0x1f ? 0xffffffff : (1<<((n)+1))-1)// Restore flags used for map buffer logged flush#define RESTORE_FLAG_NONE 0#define RESTORE_FLAG_UNFLUSHED 1#define RESTORE_FLAG_FLUSHED 2// reserves a memory region of length lenLPVOID FSMapMemReserve(DWORD len){ DWORD secs; DWORD first, curr, trav; LPVOID retval = 0; DEBUGCHK(len); EnterCriticalSection(&VAcs); if (len >= MAPPER_INCR) { secs = (len + MAPPER_INCR - 1)/MAPPER_INCR; first = 0; for (curr = 0; curr <= NUM_MAPPER_SECTIONS - secs; curr++) { if (rbRes & (1<<curr)) first = curr+1; else if (curr - first + 1 == secs) break; } if (curr > NUM_MAPPER_SECTIONS - secs) goto exit; for (trav = first; trav <= curr; trav++) { if (!CreateMapperSection(FIRST_MAPPER_ADDRESS+(MAPPER_INCR*trav))) { while (trav-- != first) { DeleteMapperSection(FIRST_MAPPER_ADDRESS+(MAPPER_INCR*trav)); rbRes &= ~(1<<trav); } goto exit; } rbRes |= (1<<trav); rbSubRes[trav] = (trav == curr ? MapBits(((len - 1)%MAPPER_INCR)/SUB_MAPPER_INCR) : (DWORD)-1); } retval = (LPVOID)(FIRST_MAPPER_ADDRESS + (MAPPER_INCR*first)); } else { secs = (len + SUB_MAPPER_INCR - 1) / SUB_MAPPER_INCR; for (curr = 0; curr < NUM_MAPPER_SECTIONS; curr++) { if (rbRes & (1<<curr)) { first = 0; for (trav = 0; trav <= 32-secs; trav++) { if (rbSubRes[curr] & (1<<trav)) first = trav+1; else if (trav - first == secs) break; } if (trav <= 32-secs) break; } } if (curr == NUM_MAPPER_SECTIONS) { for (curr = 0; curr < NUM_MAPPER_SECTIONS; curr++) { if (!(rbRes & (1<<curr))) { if (!CreateMapperSection(FIRST_MAPPER_ADDRESS + (MAPPER_INCR*curr))) goto exit; rbRes |= (1<<curr); rbSubRes[curr] = MapBits(((len-1)/SUB_MAPPER_INCR)); retval = (LPVOID)(FIRST_MAPPER_ADDRESS + (MAPPER_INCR*curr)); break; } } } else { rbSubRes[curr] |= (MapBits(((len-1)/SUB_MAPPER_INCR)) << first); retval = (LPVOID)(FIRST_MAPPER_ADDRESS + (MAPPER_INCR*curr) + (SUB_MAPPER_INCR*first)); } } exit: LeaveCriticalSection(&VAcs); return retval;}CLEANEVENT *pHugeCleanList;LPVOID HugeVirtualReserve(DWORD dwSize){ LPCLEANEVENT lpce; LPVOID pMem; dwSize = PAGEALIGN_UP(dwSize); if (!(lpce = AllocMem(HEAP_CLEANEVENT))) { KSetLastError(pCurThread, ERROR_OUTOFMEMORY); return 0; } if (!(pMem = FSMapMemReserve(dwSize))) { FreeMem(lpce, HEAP_CLEANEVENT); KSetLastError(pCurThread, ERROR_OUTOFMEMORY); return 0; } lpce->base = pMem; lpce->op = dwSize; lpce->size = (DWORD)pCurProc; EnterCriticalSection(&MapNameCS); lpce->ceptr = pHugeCleanList; pHugeCleanList = lpce; LeaveCriticalSection(&MapNameCS); return pMem;}BOOL FSMapMemFree(LPBYTE pBase, DWORD len, DWORD flags);BOOL CloseHugeMemoryAreas(LPVOID pMem){ LPCLEANEVENT pce, pce2; EnterCriticalSection(&MapNameCS); pce = pHugeCleanList; while (pce && (pce->size == (DWORD)pCurProc) && (!pMem || (pMem == pce->base))) { pHugeCleanList = pce->ceptr; VirtualFree(pce->base, pce->op, MEM_DECOMMIT); FSMapMemFree(pce->base, pce->op, MEM_RELEASE); FreeMem(pce, HEAP_CLEANEVENT); pce = pHugeCleanList; if (pMem) { LeaveCriticalSection(&MapNameCS); return TRUE; } } if (pce) { while (pce->ceptr) { if ((pce->ceptr->size == (DWORD)pCurProc) && (!pMem || (pMem == pce->ceptr->base))) { pce2 = pce->ceptr; pce->ceptr = pce2->ceptr; VirtualFree(pce2->base, pce2->op, MEM_DECOMMIT); FSMapMemFree(pce2->base, pce2->op, MEM_RELEASE); FreeMem(pce2, HEAP_CLEANEVENT); if (pMem) { LeaveCriticalSection(&MapNameCS); return TRUE; } } else pce = pce->ceptr; } } LeaveCriticalSection(&MapNameCS); return FALSE;}BOOL HugeVirtualRelease(LPVOID pMem){ if (!CloseHugeMemoryAreas(pMem)) { KSetLastError(pCurThread, ERROR_INVALID_PARAMETER); return FALSE; } return TRUE;}void DecommitROPages(LPBYTE pBase, DWORD len){ MEMORY_BASIC_INFORMATION mbi; EnterCriticalSection(&VAcs); while (len) { if (!VirtualQuery(pBase, &mbi, sizeof(mbi))) { DEBUGCHK(0); break; } if ((mbi.State == MEM_COMMIT) && (mbi.Protect == PAGE_READONLY)) VirtualFree(pBase, mbi.RegionSize, MEM_DECOMMIT); pBase += mbi.RegionSize; if (len < mbi.RegionSize) break; len -= mbi.RegionSize; } LeaveCriticalSection(&VAcs);}// Decommits or releases a MapMemReserve'd chunk of memory. Length must be passed in.// Flags must be MEM_DECOMMIT *or* MEM_RELEASE, and to RELEASE the range must be// 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 RELEASEBOOL 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; 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-alignedBOOL 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 mapLPVOID SC_MapViewOfFile(HANDLE hMap, DWORD fdwAccess, DWORD dwOffsetHigh, DWORD dwOffsetLow, DWORD cbMap){ LPFSMAP lpm; LPVOID lpret = 0; DWORD length; CLEANEVENT *lpce; DEBUGMSG(ZONE_ENTRY,(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 // if (!(lpm = (bAllKMode ? HandleToMapPerm(hMap) : HandleToMap(hMap)))) { 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -