ReactOS  0.4.13-dev-249-gcba1a2f
usrheap.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for usrheap.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 _Function_class_ (RTL_HEAP_COMMIT_ROUTINE)
 
static PWIN32HEAP IntUserHeapCreate (IN PVOID SectionObject, IN PVOID *SystemMappedBase, IN ULONG HeapSize)
 
PWIN32HEAP UserCreateHeap (OUT PVOID *SectionObject, IN OUT PVOID *SystemBase, IN SIZE_T HeapSize)
 
NTSTATUS UnmapGlobalUserHeap (IN PEPROCESS Process)
 
NTSTATUS MapGlobalUserHeap (IN PEPROCESS Process, OUT PVOID *KernelMapping, OUT PVOID *UserMapping)
 

Variables

HANDLE GlobalUserHeap = NULL
 
PVOID GlobalUserHeapSection = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 22 of file usrheap.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( RTL_HEAP_COMMIT_ROUTINE  )

Definition at line 29 of file usrheap.c.

38 {
39  PPROCESSINFO W32Process;
41  PVOID UserBase = NULL;
43  SIZE_T Delta;
44  PVOID UserCommitAddress;
45 
46  W32Process = PsGetCurrentProcessWin32Process();
47 
48  if (W32Process != NULL)
49  {
50  /* Search for the mapping */
51  Mapping = &W32Process->HeapMappings;
52  while (Mapping != NULL)
53  {
54  if (Mapping->KernelMapping == Base)
55  {
56  UserBase = Mapping->UserMapping;
57  break;
58  }
59 
60  Mapping = Mapping->Next;
61  }
62 
63  ASSERT(UserBase != NULL);
64  }
65  else
66  {
67  SIZE_T ViewSize = 0;
69 
70  /* HACK: This needs to be handled during startup only... */
72 
73  /* Temporarily map it into user space */
74  Offset.QuadPart = 0;
77  &UserBase,
78  0,
79  0,
80  &Offset,
81  &ViewSize,
82  ViewUnmap,
84  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
85 
86  if (!NT_SUCCESS(Status))
87  return Status;
88  }
89 
90  /* Apply the commit address offset to the user base address */
91  Delta = (SIZE_T)((ULONG_PTR)(*CommitAddress) - (ULONG_PTR)Base);
92  UserCommitAddress = (PVOID)((ULONG_PTR)UserBase + Delta);
93 
94  /* Perform the actual commit */
95  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
96  &UserCommitAddress,
97  0,
98  CommitSize,
99  MEM_COMMIT,
101 
102  if (NT_SUCCESS(Status))
103  {
104  /* Determine the address to return */
105  Delta = (SIZE_T)((ULONG_PTR)UserCommitAddress - (ULONG_PTR)UserBase);
107  }
108 
109  if (W32Process == NULL)
110  {
112  UserBase);
113  }
114 
115  return Status;
116 }
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define MEM_COMMIT
Definition: nt_native.h:1313
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:4500
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:281
void * PVOID
Definition: retypes.h:9
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3051
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Inout_ PVOID * CommitAddress
Definition: rtltypes.h:574
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static ULONG Delta
Definition: xboxvideo.c:28
HANDLE GlobalUserHeap
Definition: usrheap.c:25
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define SEC_NO_CHANGE
Definition: mmtypes.h:94

◆ IntUserHeapCreate()

static PWIN32HEAP IntUserHeapCreate ( IN PVOID  SectionObject,
IN PVOID SystemMappedBase,
IN ULONG  HeapSize 
)
static

Definition at line 119 of file usrheap.c.

122 {
123  PVOID MappedView = NULL;
127  PVOID pHeap;
129 
130  Offset.QuadPart = 0;
131 
132  /* Commit the first page before creating the heap! */
135  &MappedView,
136  0,
137  0,
138  &Offset,
139  &ViewSize,
140  ViewUnmap,
142  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
143  if (!NT_SUCCESS(Status))
144  return NULL;
145 
146  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
147  &MappedView,
148  0,
149  &ViewSize,
150  MEM_COMMIT,
151  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
152 
154  MappedView);
155 
156  if (!NT_SUCCESS(Status))
157  return NULL;
158 
159  /* Create the heap, don't serialize in kmode! The caller is responsible
160  to synchronize the heap! */
161  Parameters.Length = sizeof(Parameters);
162  Parameters.InitialCommit = ViewSize;
163  Parameters.InitialReserve = (SIZE_T)HeapSize;
164  Parameters.CommitRoutine = IntUserHeapCommitRoutine;
165 
167  *SystemMappedBase,
168  (SIZE_T)HeapSize,
169  ViewSize,
170  NULL,
171  &Parameters);
172 
173  return pHeap;
174 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
LONG NTSTATUS
Definition: precomp.h:26
#define MEM_COMMIT
Definition: nt_native.h:1313
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:4500
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3051
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:871
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define SEC_NO_CHANGE
Definition: mmtypes.h:94

Referenced by UserCreateHeap().

◆ MapGlobalUserHeap()

NTSTATUS MapGlobalUserHeap ( IN PEPROCESS  Process,
OUT PVOID KernelMapping,
OUT PVOID UserMapping 
)

Definition at line 262 of file usrheap.c.

265 {
267  PPROCESSINFO W32Process;
268  PW32HEAP_USER_MAPPING HeapMapping;
269  PVOID UserBase = NULL;
270 
271  SIZE_T ViewSize = 0;
273 
274  TRACE_CH(UserProcess, "MapGlobalUserHeap called for process 0x%p\n", Process);
275 
276  W32Process = PsGetProcessWin32Process(Process);
277  if (W32Process == NULL)
278  {
279  ERR_CH(UserProcess, "MapGlobalUserHeap - We don't have a Win32 process!\n");
280  ASSERT(FALSE);
281  }
282 
283  TRACE_CH(UserProcess, "MapGlobalUserHeap - We got a Win32 process, find for existing global user heap mapping...\n");
284 
285  /* The first mapping entry must be the global user heap */
286  HeapMapping = &W32Process->HeapMappings;
287 
288  /* Find out if another thread already mapped the global user heap */
289  if (HeapMapping->KernelMapping == (PVOID)GlobalUserHeap)
290  {
291  HeapMapping->Count++;
292 
293  TRACE_CH(UserProcess, "MapGlobalUserHeap - A mapping was found, return it.\n");
294 
295  *KernelMapping = HeapMapping->KernelMapping;
296  *UserMapping = HeapMapping->UserMapping;
297 
298  return STATUS_SUCCESS;
299  }
300 
301  TRACE_CH(UserProcess, "MapGlobalUserHeap - No mapping was found, let's map...\n");
302 
303  /* We're the first, map the global heap into the process */
304  Offset.QuadPart = 0;
306  Process,
307  &UserBase,
308  0,
309  0,
310  &Offset,
311  &ViewSize,
312  ViewUnmap,
314  PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
315  if (!NT_SUCCESS(Status))
316  {
317  ERR_CH(UserProcess, "MapGlobalUserHeap - Failed to map the global heap! 0x%x\n", Status);
318  return Status;
319  }
320 
321  TRACE_CH(UserProcess, "MapGlobalUserHeap -- Mapped kernel global heap 0x%p to user space at 0x%p\n",
322  GlobalUserHeap, UserBase);
323 
324  /* Add the mapping */
325  HeapMapping->Next = NULL;
326  HeapMapping->KernelMapping = (PVOID)GlobalUserHeap;
327  HeapMapping->UserMapping = UserBase;
328  HeapMapping->Limit = ViewSize;
329  HeapMapping->Count = 1;
330 
331  *KernelMapping = HeapMapping->KernelMapping;
332  *UserMapping = HeapMapping->UserMapping;
333 
334  return STATUS_SUCCESS;
335 }
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
LONG NTSTATUS
Definition: precomp.h:26
static GENERIC_MAPPING UserMapping
Definition: samrpc.c:48
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:4500
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:281
void * PVOID
Definition: retypes.h:9
ULONG_PTR Limit
Definition: win32.h:197
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:107
HANDLE GlobalUserHeap
Definition: usrheap.c:25
#define ERR_CH(ch, fmt,...)
Definition: debug.h:104
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:194

Referenced by InitProcessCallback().

◆ UnmapGlobalUserHeap()

NTSTATUS UnmapGlobalUserHeap ( IN PEPROCESS  Process)

Definition at line 232 of file usrheap.c.

233 {
235  PPROCESSINFO W32Process;
236  PW32HEAP_USER_MAPPING HeapMapping;
237 
238  TRACE_CH(UserProcess, "IntUnmapDesktopView called for process 0x%p\n", Process);
239 
240  W32Process = PsGetProcessWin32Process(Process);
241  if (W32Process == NULL)
242  {
243  ERR_CH(UserProcess, "UnmapGlobalUserHeap - We don't have a Win32 process!\n");
244  ASSERT(FALSE);
245  }
246 
247  /* The first mapping entry must be the global user heap */
248  HeapMapping = &W32Process->HeapMappings;
249  ASSERT(HeapMapping->KernelMapping == (PVOID)GlobalUserHeap);
250 
251  /* Unmap if we're the last thread using the global user heap */
252  if (--HeapMapping->Count == 0)
253  {
254  TRACE_CH(UserProcess, "UnmapGlobalUserHeap - Unmapping\n");
256  }
257 
258  return Status;
259 }
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:281
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3051
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:107
HANDLE GlobalUserHeap
Definition: usrheap.c:25
#define ERR_CH(ch, fmt,...)
Definition: debug.h:104
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
return STATUS_SUCCESS
Definition: btrfs.c:2745

◆ UserCreateHeap()

PWIN32HEAP UserCreateHeap ( OUT PVOID SectionObject,
IN OUT PVOID SystemBase,
IN SIZE_T  HeapSize 
)

Definition at line 177 of file usrheap.c.

180 {
181  LARGE_INTEGER SizeHeap;
182  PWIN32HEAP pHeap = NULL;
184 
185  SizeHeap.QuadPart = HeapSize;
186 
187  /* Create the section and map it into session space */
190  NULL,
191  &SizeHeap,
192  PAGE_EXECUTE_READWRITE, /* Would prefer PAGE_READWRITE, but thanks to RTL heaps... */
193  SEC_RESERVE | 1,
194  NULL,
195  NULL);
196 
197  if (!NT_SUCCESS(Status))
198  {
200  return FALSE;
201  }
202 
204  SystemBase,
205  &HeapSize);
206  if (!NT_SUCCESS(Status))
207  {
209  *SectionObject = NULL;
210 
212  return FALSE;
213  }
214 
215  /* Create the heap */
217  SystemBase,
218  HeapSize);
219 
220  if (pHeap == NULL)
221  {
223  *SectionObject = NULL;
224 
226  }
227 
228  return pHeap;
229 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
struct _WIN32HEAP * PWIN32HEAP
Definition: usrheap.h:3
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define SEC_RESERVE
Definition: nt_native.h:1323
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI MmCreateSection(OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:4973
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
static PWIN32HEAP IntUserHeapCreate(IN PVOID SectionObject, IN PVOID *SystemMappedBase, IN ULONG HeapSize)
Definition: usrheap.c:119
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2991
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by DriverEntry(), and UserInitializeDesktop().

Variable Documentation

◆ GlobalUserHeap

◆ GlobalUserHeapSection

PVOID GlobalUserHeapSection = NULL

Definition at line 26 of file usrheap.c.

Referenced by _Function_class_(), DriverEntry(), and MapGlobalUserHeap().