Windows2003-3790/windows/appcompat/shims/layer/emulateheap_support.c
2020-09-30 16:53:55 +02:00

239 lines
7.1 KiB
C

#include "EmulateHeap_kernel32.h"
HANDLE hheapKernel = 0;
PDB pdbCur;
PDB *ppdbCur = &pdbCur;
PDB **pppdbCur = &ppdbCur;
/***SN PageCommit - commit physical pages to a specified linear address
*
* The entire target region must have been reserved by a single previous
* call to PageReserve.
*
* If PC_LOCKED, PC_LOCKEDIFDP, or PC_FIXED are passed into PageCommit,
* then all of the pages in the specified range must currently uncommitted.
* If none of those flags are specified, then any existing
* committed pages in the range will be unaffected by this call and an
* error will not be returned. However, even though it is allowed,
* calling PageCommit on a range containing already committed memory
* should be avoided because it is waste of time.
*
* ENTRY: page - base virtual page number to start commit at
* npages - number of pages to commit
* hpd - handle to pager descriptor (returned from PagerRegister)
* or one of these special value:
* PD_ZEROINIT - swappable zero-initialized
* PD_NOINIT - swappable uninitialized
* PD_FIXED - fixed uninitialized (must also pass in
* PC_FIXED flag)
* PD_FIXEDZERO - fixed zero-initialized (must also pass
* in PC_FIXED flag)
* pagerdata - a single dword to be stored with the page(s) for
* use by the pager. If one of the special pagers
* listed above is used for the "hpd" parameter, then
* this parameter is reserved and should be zero.
* flags - PC_FIXED - page are created permanently locked
* PC_LOCKED - pages are created present and locked
* PC_LOCKEDIFDP - page are locked if swapping is via DOS
* PC_STATIC - allow commit in AR_STATIC object
* PC_USER - make the pages ring 3 accessible
* PC_WRITEABLE - make the pages writeable
* PC_INCR - increment "pagerdata" once for each page. If
* one of the special pagers listed above is used
* for the "hpd" parameter, then this flags
* should not be specified.
* PC_PRESENT - make the pages present as they are committed
* (not needed with PC_FIXED or PC_LOCKED)
* PC_DIRTY - mark the pages as dirty as they are committed
* (ignored if PC_PRESENT, PC_FIXED or PC_LOCKED
* isn't specified)
* EXIT: non-zero if success, 0 if failure
*/
ULONG EXTERNAL
PageCommit(ULONG page, ULONG npages, ULONG hpd, ULONG pagerdata, ULONG flags)
{
return (ULONG_PTR) VirtualAlloc((LPVOID)(page * PAGESIZE), npages * PAGESIZE, MEM_COMMIT, PAGE_READWRITE);
}
/***SN PageDecommit - decommit physical pages from a specific address
*
* The pages must be within an address range previously allocated
* by a single call to PageReserve. Though it is not an error to
* call PageDecommit on a range including pages which are already
* decommitted, such behavoir is discouraged because it is a waste of time.
*
* ENTRY: page - virtual page number of first page to decommit
* npages - number of pages to decommit
* flags - PC_STATIC - allow decommit in AR_STATIC object
* EXIT: non-zero if success, else 0 if failure
*/
ULONG EXTERNAL
PageDecommit(ULONG page, ULONG npages, ULONG flags)
{
// PREFAST - This generates a PREFAST error asking us to use the MEM_RELEASE flag
// We do not want that and hence this error can be ignored.
return (ULONG) VirtualFree((LPVOID)(page * PAGESIZE), npages * PAGESIZE, MEM_DECOMMIT);
}
/***SN PageReserve - allocate linear address space in the current context
*
* The address range allocated by PageReserve is not backed by any
* physical memory. PageCommit, PageCommitPhys, or PageCommitContig
* should be called before actually touching a reserved region.
*
* Optionally, page permission flags (PC_WRITEABLE and PC_USER) may be
* passed into this service. The flags are not acted on in any way
* (because uncommitted memory is always inaccessible) but they are stored
* internally by the memory manager. The PageQuery service returns these
* permissions in the mbi_AllocationProtect field of its information
* structure.
*
* ENTRY: page - requested base address of object (virtual page number)
* or a special value:
* PR_PRIVATE - anywhere in current ring 3 private region
* PR_SHARED - anywhere in the ring 3 shared region
* PR_SYSTEM - anywhere in the system region
* npages - number of pages to reserve
* flags - PR_FIXED - so PageReAllocate will not move object
* PR_STATIC - don't allow commits, decommits or frees
* unless *_STATIC flag is passed in
* PR_4MEG - returned address must be 4mb aligned
* (this flag is ignored if a specific address
* is requested by the "page" parameter)
* PC_WRITEABLE, PC_USER - optional, see above
*
* EXIT: linear address of allocated object or -1 if error
*/
ULONG EXTERNAL
PageReserve(ULONG page, ULONG npages, ULONG flags)
{
ULONG uRet;
if ((page == PR_PRIVATE) ||
(page == PR_SHARED) ||
(page == PR_SYSTEM))
{
page = 0;
}
uRet = (ULONG) VirtualAlloc((LPVOID)(page * PAGESIZE), npages * PAGESIZE, MEM_RESERVE, PAGE_READWRITE);
if (!uRet)
{
uRet = -1;
}
return uRet;
}
/***SO PageFree - De-reserved and de-commit an entire memory object
*
* ENTRY: laddr - linear address (handle) of base of object to free
* flags - PR_STATIC - allow freeing of AR_STATIC object
* EXIT: non-0 if success, 0 if failure
*
*/
ULONG EXTERNAL
_PageFree(ULONG laddr, ULONG flags)
{
return VirtualFree((LPVOID) laddr, 0, MEM_RELEASE);
}
KERNENTRY
HouseCleanLogicallyDeadHandles(VOID)
{
return 0;
}
CRITICAL_SECTION *
NewCrst()
{
CRITICAL_SECTION *lpcs = (CRITICAL_SECTION *) VirtualAlloc(0, sizeof(CRITICAL_SECTION), MEM_COMMIT, PAGE_READWRITE);
if (lpcs)
{
InitializeCriticalSection(lpcs);
}
return lpcs;
}
VOID
DisposeCrst(CRITICAL_SECTION *lpcs)
{
if (lpcs)
{
DeleteCriticalSection(lpcs);
VirtualFree(lpcs, 0, MEM_RELEASE);
}
}
DWORD KERNENTRY
GetAppCompatFlags(VOID)
{
return 0;
}
VOID APIENTRY
MakeCriticalSectionGlobal(LPCRITICAL_SECTION lpcsCriticalSection)
{
}
BOOL KERNENTRY
ReadProcessMemoryFromPDB(
PPDB ppdb,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead
)
{
return ReadProcessMemory(
GetCurrentProcess(),
lpBaseAddress,
lpBuffer,
nSize,
lpNumberOfBytesRead);
}
BOOL WINAPI
vHeapFree(
HANDLE hHeap,
DWORD dwFlags,
LPVOID lpMem
)
{
return HeapFree((HHEAP)hHeap, dwFlags, (LPSTR) lpMem);
}
BOOL
_HeapInit()
{
ZeroMemory(&pdbCur, sizeof(PDB));
pdbCur.hheapLocal = _HeapCreate(HEAP_SHARED, 0, 0);
hheapKernel = pdbCur.hheapLocal;
return (BOOL)(pdbCur.hheapLocal);
}
HANDLE
_GetProcessHeap(void)
{
return GetCurrentPdb()->hheapLocal;
}
BOOL
_IsOurHeap(HANDLE hHeap)
{
if (!IsBadReadPtr(hHeap, sizeof(HANDLE)))
{
return ((struct heapinfo_s *) hHeap)->hi_signature == HI_SIGNATURE;
}
else
{
return FALSE;
}
}