You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
20 KiB
686 lines
20 KiB
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
|
|
|
Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
usergdi.h
|
|
|
|
Abstract:
|
|
|
|
This module contains private USER functions used by GDI.
|
|
All of these function are named Userxxx.
|
|
|
|
Author:
|
|
|
|
Chris Williams (chriswil) 25-May-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _USERGDI_ZWAPI_INC_
|
|
#define _USERGDI_ZWAPI_INC_
|
|
#include <zwapi.h>
|
|
#endif
|
|
|
|
extern PDRIVER_OBJECT gpWin32kDriverObject;
|
|
|
|
|
|
VOID
|
|
VideoPortCallout(
|
|
IN PVOID Params
|
|
);
|
|
|
|
BOOL FASTCALL
|
|
UserScreenAccessCheck(
|
|
VOID
|
|
);
|
|
|
|
HDC
|
|
UserGetDesktopDC(
|
|
ULONG type,
|
|
BOOL bAltType,
|
|
BOOL bValidate
|
|
);
|
|
|
|
BOOL
|
|
UserReleaseDC(
|
|
HDC hdc
|
|
);
|
|
|
|
HDEV
|
|
UserGetHDEV(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UserAssociateHwnd(
|
|
HWND hwnd,
|
|
PVOID pwo
|
|
);
|
|
|
|
HRGN
|
|
UserGetClientRgn(
|
|
HWND hwnd,
|
|
LPRECT lprc,
|
|
BOOL bWindowInsteadOfClient
|
|
);
|
|
|
|
BOOL
|
|
UserGetHwnd(
|
|
HDC hdc,
|
|
HWND *phwnd,
|
|
PVOID *ppwo,
|
|
BOOL bCheckStyle
|
|
);
|
|
|
|
VOID
|
|
UserEnterUserCritSec(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UserLeaveUserCritSec(
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
UserGetCurrentDesktopId(
|
|
DWORD* pdwDesktopId
|
|
);
|
|
|
|
VOID
|
|
UserRedrawDesktop(
|
|
VOID
|
|
);
|
|
|
|
UINT_PTR
|
|
UserSetTimer(
|
|
UINT dwElapse,
|
|
PVOID pTimerFunc
|
|
);
|
|
|
|
BOOL
|
|
UserVisrgnFromHwnd(
|
|
HRGN *phrgn,
|
|
HWND hwnd
|
|
);
|
|
|
|
VOID
|
|
UserKillTimer(
|
|
UINT_PTR nID
|
|
);
|
|
|
|
#if DBG
|
|
VOID
|
|
UserAssertUserCritSecIn(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UserAssertUserCritSecOut(
|
|
VOID
|
|
);
|
|
#endif
|
|
|
|
VOID
|
|
UserGetDisconnectDeviceResolutionHint(
|
|
PDEVMODEW
|
|
);
|
|
|
|
NTSTATUS
|
|
UserSessionSwitchEnterCrit(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UserSessionSwitchLeaveCrit(
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
UserIsUserCritSecIn(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
GetAppCompatFlags2(
|
|
WORD wVersion
|
|
);
|
|
|
|
BOOL
|
|
UserGetRedirectedWindowOrigin(
|
|
HDC hdc,
|
|
LPPOINT ppt
|
|
);
|
|
|
|
HBITMAP
|
|
UserGetRedirectionBitmap(
|
|
HWND hwnd
|
|
);
|
|
|
|
//
|
|
// User-mode printer driver kernel-to-client callback mechanism.
|
|
//
|
|
|
|
DWORD
|
|
ClientPrinterThunk(
|
|
PVOID pvIn,
|
|
ULONG cjIn,
|
|
PVOID pvOut,
|
|
ULONG cjOut
|
|
);
|
|
|
|
//
|
|
// Gdi fonts stuff
|
|
//
|
|
|
|
VOID
|
|
GdiMultiUserFontCleanup();
|
|
|
|
|
|
#define BEGIN_REENTERCRIT() \
|
|
{ \
|
|
BOOL fAlreadyHadCrit; \
|
|
\
|
|
/* \
|
|
* If we're not in the user crit then acquire it. \
|
|
*/ \
|
|
fAlreadyHadCrit = ExIsResourceAcquiredExclusiveLite(gpresUser); \
|
|
if (fAlreadyHadCrit == FALSE) { \
|
|
EnterCrit(); \
|
|
}
|
|
|
|
#define END_REENTERCRIT() \
|
|
if (fAlreadyHadCrit == FALSE) { \
|
|
LeaveCrit(); \
|
|
} \
|
|
}
|
|
|
|
|
|
/*
|
|
* Pool memory allocation functions used in win32k
|
|
*/
|
|
|
|
/*
|
|
* From ntos\inc\pool.h
|
|
*/
|
|
#define SESSION_POOL_MASK 32
|
|
|
|
#if DBG
|
|
#define TRACE_MAP_VIEWS
|
|
#define MAP_VIEW_STACK_TRACE
|
|
#else
|
|
#if defined(PRERELEASE) || defined(USER_INSTRUMENTATION)
|
|
#define TRACE_MAP_VIEWS
|
|
#define MAP_VIEW_STACK_TRACE
|
|
#endif
|
|
#endif
|
|
|
|
#define TAG_SECTION_SHARED 101
|
|
#define TAG_SECTION_DESKTOP 102
|
|
#define TAG_SECTION_GDI 103
|
|
#define TAG_SECTION_FONT 104
|
|
#define TAG_SECTION_REMOTEFONT 105
|
|
#define TAG_SECTION_CREATESECTION 106
|
|
#define TAG_SECTION_DIB 107
|
|
#define TAG_SECTION_HMGR 108
|
|
|
|
struct tagWin32MapView;
|
|
|
|
#define MAP_VIEW_STACK_TRACE_SIZE 6
|
|
|
|
typedef struct tagWin32Section {
|
|
struct tagWin32Section* pNext;
|
|
struct tagWin32Section* pPrev;
|
|
struct tagWin32MapView* pFirstView;
|
|
PVOID SectionObject;
|
|
LARGE_INTEGER SectionSize;
|
|
DWORD SectionTag;
|
|
#ifdef MAP_VIEW_STACK_TRACE
|
|
PVOID trace[MAP_VIEW_STACK_TRACE_SIZE];
|
|
#endif // MAP_VIEW_STACK_TRACE
|
|
} Win32Section, *PWin32Section;
|
|
|
|
typedef struct tagWin32MapView {
|
|
struct tagWin32MapView* pNext;
|
|
struct tagWin32MapView* pPrev;
|
|
PWin32Section pSection;
|
|
PVOID pViewBase;
|
|
SIZE_T ViewSize;
|
|
#ifdef MAP_VIEW_STACK_TRACE
|
|
PVOID trace[MAP_VIEW_STACK_TRACE_SIZE];
|
|
#endif // MAP_VIEW_STACK_TRACE
|
|
} Win32MapView, *PWin32MapView;
|
|
|
|
#ifndef TRACE_MAP_VIEWS
|
|
|
|
NTSTATUS __inline Win32CreateSection(
|
|
PVOID *SectionObject,
|
|
ACCESS_MASK DesiredAccess,
|
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
PLARGE_INTEGER InputMaximumSize,
|
|
ULONG SectionPageProtection,
|
|
ULONG AllocationAttributes,
|
|
HANDLE FileHandle,
|
|
PFILE_OBJECT FileObject,
|
|
DWORD SectionTag)
|
|
{
|
|
NTSTATUS Status;
|
|
Status = MmCreateSection(
|
|
SectionObject,
|
|
DesiredAccess,
|
|
ObjectAttributes,
|
|
InputMaximumSize,
|
|
SectionPageProtection,
|
|
AllocationAttributes,
|
|
FileHandle,
|
|
FileObject);
|
|
if (NT_SUCCESS(Status)) {
|
|
ObDeleteCapturedInsertInfo (*SectionObject);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS __inline ZwWin32CreateSection(
|
|
PVOID *SectionObject,
|
|
ACCESS_MASK DesiredAccess,
|
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
PLARGE_INTEGER InputMaximumSize,
|
|
ULONG SectionPageProtection,
|
|
ULONG AllocationAttributes,
|
|
HANDLE FileHandle,
|
|
PFILE_OBJECT FileObject,
|
|
DWORD SectionTag)
|
|
{
|
|
HANDLE SectionHandle;
|
|
NTSTATUS Status;
|
|
|
|
Status = ZwCreateSection(
|
|
&SectionHandle,
|
|
DesiredAccess,
|
|
ObjectAttributes,
|
|
InputMaximumSize,
|
|
SectionPageProtection,
|
|
AllocationAttributes,
|
|
FileHandle);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
Status = ObReferenceObjectByHandle(
|
|
SectionHandle,
|
|
DesiredAccess,
|
|
*(POBJECT_TYPE *)MmSectionObjectType,
|
|
KernelMode,
|
|
SectionObject,
|
|
NULL);
|
|
ZwClose(SectionHandle);
|
|
return Status;
|
|
|
|
}
|
|
|
|
NTSTATUS __inline Win32MapViewInSessionSpace(
|
|
PVOID Section,
|
|
PVOID *MappedBase,
|
|
PSIZE_T ViewSize)
|
|
{
|
|
return MmMapViewInSessionSpace(Section, MappedBase, ViewSize);
|
|
}
|
|
|
|
NTSTATUS __inline Win32UnmapViewInSessionSpace(
|
|
PVOID MappedBase)
|
|
{
|
|
return MmUnmapViewInSessionSpace(MappedBase);
|
|
}
|
|
|
|
VOID __inline Win32DestroySection(PVOID Section)
|
|
{
|
|
ObDereferenceObject(Section);
|
|
}
|
|
#else
|
|
|
|
NTSTATUS _Win32CreateSection(
|
|
PVOID* pSectionObject,
|
|
ACCESS_MASK DesiredAccess,
|
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
PLARGE_INTEGER pInputMaximumSize,
|
|
ULONG SectionPageProtection,
|
|
ULONG AllocationAttributes,
|
|
HANDLE FileHandle,
|
|
PFILE_OBJECT FileObject,
|
|
DWORD SectionTag);
|
|
|
|
NTSTATUS _ZwWin32CreateSection(
|
|
PVOID* pSectionObject,
|
|
ACCESS_MASK DesiredAccess,
|
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
PLARGE_INTEGER pInputMaximumSize,
|
|
ULONG SectionPageProtection,
|
|
ULONG AllocationAttributes,
|
|
HANDLE FileHandle,
|
|
PFILE_OBJECT FileObject,
|
|
DWORD SectionTag);
|
|
|
|
NTSTATUS _Win32MapViewInSessionSpace(
|
|
PVOID Section,
|
|
PVOID* pMappedBase,
|
|
PSIZE_T pViewSize);
|
|
|
|
NTSTATUS _Win32UnmapViewInSessionSpace(
|
|
PVOID MappedBase);
|
|
|
|
VOID _Win32DestroySection(
|
|
PVOID Section);
|
|
|
|
#define Win32CreateSection _Win32CreateSection
|
|
#define ZwWin32CreateSection _ZwWin32CreateSection
|
|
#define Win32MapViewInSessionSpace _Win32MapViewInSessionSpace
|
|
#define Win32UnmapViewInSessionSpace _Win32UnmapViewInSessionSpace
|
|
#define Win32DestroySection _Win32DestroySection
|
|
#endif // TRACE_MAP_VIEWS
|
|
|
|
#if DBG
|
|
#define POOL_INSTR
|
|
#define POOL_INSTR_API
|
|
#else
|
|
#define POOL_INSTR
|
|
#endif // DBG
|
|
|
|
/*++
|
|
|
|
How the registry controls pool instrumentation in win32k.sys:
|
|
--------------------------------------------------------------
|
|
|
|
If pool instrumentation is turned on (this can be done for free builds as
|
|
well as checked) then there are several levels of tracing controlled from
|
|
the registry under the following key:
|
|
|
|
HKLM\System\CurrentControlSet\Control\Session Manager\SubSystems\Pool
|
|
|
|
if this key doesn't exist default settings are used for each of the following key.
|
|
|
|
1. HeavyRemoteSession REG_DWORD
|
|
|
|
default: 1
|
|
if this is non zero or the key doesn't exist then pool tracing is on
|
|
for remote sessions of win32k.sys.
|
|
|
|
2. HeavyConsoleSession REG_DWORD
|
|
|
|
default: 0
|
|
if this is non zero then pool tracing is on for console sessions
|
|
of win32k.sys. it the key doesn't exist then pool tracing is off for
|
|
the main session.
|
|
|
|
3. StackTraces REG_DWORD
|
|
|
|
default:
|
|
- 1 for remote sessions
|
|
- 0 for the main session
|
|
|
|
if non zero then a stack trace record will be saved for every
|
|
pool allocation made.
|
|
|
|
4. KeepFailRecords REG_DWORD
|
|
|
|
default: 32
|
|
if non zero then win32k.sys will keep a list of the last x allocations
|
|
that failed (tag + stack trace). Use !dpa -f to dump the stack traces of
|
|
the failed allocations
|
|
|
|
4. UseTailString REG_DWORD
|
|
|
|
default: 0
|
|
if non zero for every pool allocation there will be a string attached
|
|
to the end of the allocation to catch some specific type of memory corruption.
|
|
|
|
5. KeepFreeRecords REG_DWORD
|
|
|
|
default: 0
|
|
not implemented yet. the number will specify how many free pointers will
|
|
be kept in a list so we can differentiate when we call ExFreePool between
|
|
a totally bogus value and a pointer that was already freed.
|
|
|
|
6. AllocationIndex REG_DWORD
|
|
7. AllocationsToFail REG_DWORD
|
|
|
|
If AllocationIndex is non zero then win32k counts the pool allocations
|
|
made and will start failing from allocation AllocationIndex a number
|
|
of AllocationsToFail allocations. This is useful during boot time when
|
|
a user mode test cannot call Win32PoolAllocationStats to fail pool allocations.
|
|
|
|
8. BreakForPoolLeaks REG_DWORD
|
|
|
|
default: 0
|
|
|
|
Breaks in the debugger (if started with /debug in boot.ini) if pool leaks
|
|
are detected in win32k.sys for remote sessions.
|
|
|
|
--*/
|
|
|
|
|
|
#ifdef POOL_INSTR
|
|
PVOID HeavyAllocPool(SIZE_T uBytes, ULONG iTag, DWORD dwFlags, EX_POOL_PRIORITY priority);
|
|
VOID HeavyFreePool(PVOID p);
|
|
|
|
#define Win32AllocPool(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, 0, (EX_POOL_PRIORITY)0)
|
|
|
|
#define Win32AllocPoolWithPriority(uBytes, iTag, priority) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_PRIORITY, priority)
|
|
|
|
#define Win32AllocPoolZInit(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_ZEROINIT, (EX_POOL_PRIORITY)0)
|
|
|
|
#define Win32AllocPoolZInitWithPriority(uBytes, iTag, priority) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_ZEROINIT | DAP_PRIORITY, priority)
|
|
|
|
#define Win32AllocPoolWithQuota(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA, (EX_POOL_PRIORITY)0)
|
|
|
|
#define Win32AllocPoolWithQuotaZInit(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA | DAP_ZEROINIT, (EX_POOL_PRIORITY)0)
|
|
|
|
#define Win32AllocPoolNonPaged(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL, (EX_POOL_PRIORITY)0);
|
|
|
|
#define Win32AllocPoolNonPagedWithPriority(uBytes, iTag, priority) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_PRIORITY, priority);
|
|
|
|
#define Win32AllocPoolWithQuotaNonPaged(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA | DAP_NONPAGEDPOOL, (EX_POOL_PRIORITY)0);
|
|
|
|
#define Win32AllocPoolNonPagedNS(uBytes, iTag) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_NONSESSION, (EX_POOL_PRIORITY)0);
|
|
|
|
#define Win32AllocPoolNonPagedNSWithPriority(uBytes, iTag, priority) \
|
|
HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_NONSESSION | DAP_PRIORITY, priority);
|
|
|
|
#define Win32FreePool HeavyFreePool
|
|
|
|
#else
|
|
PVOID __inline Win32AllocPool(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return ExAllocatePoolWithTag(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | PagedPool),
|
|
uBytes, uTag);
|
|
}
|
|
PVOID __inline Win32AllocPoolWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
|
|
{
|
|
return ExAllocatePoolWithTagPriority(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | PagedPool),
|
|
uBytes, uTag, priority);
|
|
}
|
|
PVOID __inline Win32AllocPoolWithQuota(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return ExAllocatePoolWithQuotaTag(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE),
|
|
uBytes, uTag);
|
|
}
|
|
PVOID __inline Win32AllocPoolNonPaged(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return ExAllocatePoolWithTag(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool),
|
|
uBytes, uTag);
|
|
}
|
|
PVOID __inline Win32AllocPoolNonPagedWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
|
|
{
|
|
return ExAllocatePoolWithTagPriority(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool),
|
|
uBytes, uTag, priority);
|
|
}
|
|
PVOID __inline Win32AllocPoolNonPagedNS(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return ExAllocatePoolWithTag(
|
|
(POOL_TYPE)NonPagedPool,
|
|
uBytes, uTag);
|
|
}
|
|
PVOID __inline Win32AllocPoolNonPagedNSWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
|
|
{
|
|
return ExAllocatePoolWithTagPriority(
|
|
(POOL_TYPE)NonPagedPool,
|
|
uBytes, uTag, priority);
|
|
}
|
|
PVOID __inline Win32AllocPoolWithQuotaNonPaged(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return ExAllocatePoolWithQuotaTag(
|
|
(POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool), uBytes, uTag);
|
|
}
|
|
|
|
PVOID Win32AllocPoolWithTagZInit(SIZE_T uBytes, ULONG uTag);
|
|
PVOID Win32AllocPoolWithTagZInitWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority);
|
|
PVOID Win32AllocPoolWithQuotaTagZInit(SIZE_T uBytes, ULONG uTag);
|
|
|
|
PVOID __inline Win32AllocPoolZInit(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return Win32AllocPoolWithTagZInit(uBytes, uTag);
|
|
}
|
|
PVOID __inline Win32AllocPoolZInitWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
|
|
{
|
|
return Win32AllocPoolWithTagZInitWithPriority(uBytes, uTag, priority);
|
|
}
|
|
|
|
PVOID __inline Win32AllocPoolWithQuotaZInit(SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return Win32AllocPoolWithQuotaTagZInit(uBytes, uTag);
|
|
}
|
|
|
|
#define Win32FreePool ExFreePool
|
|
|
|
#endif // POOL_INSTR
|
|
|
|
/*
|
|
* All the User* allocation functions are defined to be Win32*
|
|
*/
|
|
|
|
#define UserAllocPool Win32AllocPool
|
|
#define UserAllocPoolZInit Win32AllocPoolZInit
|
|
#define UserAllocPoolWithQuota Win32AllocPoolWithQuota
|
|
#define UserAllocPoolWithQuotaZInit Win32AllocPoolWithQuotaZInit
|
|
#define UserAllocPoolNonPaged Win32AllocPoolNonPaged
|
|
#define UserAllocPoolNonPagedNS Win32AllocPoolNonPagedNS
|
|
#define UserAllocPoolWithQuotaNonPaged Win32AllocPoolWithQuotaNonPaged
|
|
#define UserFreePool Win32FreePool
|
|
|
|
|
|
SIZE_T Win32QueryPoolSize(
|
|
PVOID p);
|
|
|
|
PVOID UserReAllocPoolWithTag(
|
|
PVOID pSrc,
|
|
SIZE_T uBytesSrc,
|
|
SIZE_T uBytes,
|
|
ULONG uTag);
|
|
|
|
PVOID UserReAllocPoolWithQuotaTag(
|
|
PVOID pSrc,
|
|
SIZE_T uBytesSrc,
|
|
SIZE_T uBytes,
|
|
ULONG uTag);
|
|
|
|
PVOID __inline UserReAllocPool(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return UserReAllocPoolWithTag(p, uBytesSrc, uBytes, uTag);
|
|
}
|
|
|
|
PVOID __inline UserReAllocPoolWithQuota(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
return UserReAllocPoolWithQuotaTag(p, uBytesSrc, uBytes, uTag);
|
|
}
|
|
|
|
/*
|
|
* Since the ReAllocPoolZInit functions are not yet used, they are
|
|
* made inline to save code space. Consider making them non-inline
|
|
* if they get a few uses.
|
|
*/
|
|
PVOID __inline UserReAllocPoolZInit(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
PVOID pv;
|
|
pv = UserReAllocPoolWithTag(p, uBytesSrc, uBytes, uTag);
|
|
if (pv && uBytes > uBytesSrc) {
|
|
RtlZeroMemory((BYTE *)pv + uBytesSrc, uBytes - uBytesSrc);
|
|
}
|
|
|
|
return pv;
|
|
}
|
|
|
|
PVOID __inline UserReAllocPoolWithQuotaZInit(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
|
|
{
|
|
PVOID pv;
|
|
pv = UserReAllocPoolWithQuotaTag(p, uBytesSrc, uBytes, uTag);
|
|
if (pv && uBytes > uBytesSrc) {
|
|
RtlZeroMemory((BYTE *)pv + uBytesSrc, uBytes - uBytesSrc);
|
|
}
|
|
|
|
return pv;
|
|
}
|
|
|
|
#define DAP_USEQUOTA 0x01
|
|
#define DAP_ZEROINIT 0x02
|
|
#define DAP_NONPAGEDPOOL 0x04
|
|
#define DAP_NONSESSION 0x08
|
|
#define DAP_PRIORITY 0x10
|
|
|
|
//!!!dbug -- there has to be a better one somewhere...
|
|
/*
|
|
* Memory manager (ExAllocate..., etc.) pool header size.
|
|
*/
|
|
#define MM_POOL_HEADER_SIZE 8
|
|
|
|
#define POOL_ALLOC_TRACE_SIZE 8
|
|
|
|
typedef struct tagWin32PoolHead {
|
|
SIZE_T size; // the size of the allocation (doesn't include
|
|
// this structure
|
|
struct tagWin32PoolHead* pPrev; // pointer to the previous allocation of this tag
|
|
struct tagWin32PoolHead* pNext; // pointer to the next allocation of this tag
|
|
PVOID* pTrace; // pointer to the stack trace
|
|
|
|
} Win32PoolHead, *PWin32PoolHead;
|
|
|
|
/*
|
|
* Memory barrier
|
|
* This macro ensures the pending write-back instructions retire before the next
|
|
* code, settles the multi-proc rare problems (see KeMemoryBarrier macros).
|
|
* RISC chips could reorder the retirement of the instructions, so when it's
|
|
* critical to ensure the order of the write operation, those macros should be
|
|
* used.
|
|
*/
|
|
#if defined(_X86_)
|
|
#define Win32MemoryBarrier()
|
|
#elif defined(_IA64_)
|
|
#if defined(NT_UP)
|
|
#define Win32MemoryBarrier()
|
|
#else
|
|
#define WIN32_MEMORY_BARRIER_REQUIRED
|
|
#define Win32MemoryBarrier() __mf()
|
|
#endif
|
|
#elif defined(_AMD64_)
|
|
#define Win32MemoryBarrier()
|
|
#else
|
|
#error unknown CPU type.
|
|
#endif
|
|
|