ReactOS 0.4.15-dev-8236-g99f0937
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;
44 PVOID UserCommitAddress;
45
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,
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,
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}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2750
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_NO_CHANGE
Definition: mmtypes.h:95
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewUnmap
Definition: nt_native.h:1279
#define MEM_COMMIT
Definition: nt_native.h:1313
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
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:3996
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:290
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
HANDLE GlobalUserHeap
Definition: usrheap.c:25
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
static ULONG Delta
Definition: xboxvideo.c:33
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Inout_ PVOID * CommitAddress
Definition: rtltypes.h:597

◆ 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,
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
166 pHeap = RtlCreateHeap(
167#if DBG /* Enable checks on debug builds */
169#endif
171 *SystemMappedBase,
173 ViewSize,
174 NULL,
175 &Parameters);
176
177 return pHeap;
178}
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define DBG(x)
Definition: moztest.c:12
#define HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
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 HEAP_TAIL_CHECKING_ENABLED
Definition: nt_native.h:1697
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)

Referenced by UserCreateHeap().

◆ MapGlobalUserHeap()

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

Definition at line 266 of file usrheap.c.

269{
271 PPROCESSINFO W32Process;
272 PW32HEAP_USER_MAPPING HeapMapping;
273 PVOID UserBase = NULL;
274
275 SIZE_T ViewSize = 0;
277
278 TRACE_CH(UserProcess, "MapGlobalUserHeap called for process 0x%p\n", Process);
279
280 W32Process = PsGetProcessWin32Process(Process);
281 if (W32Process == NULL)
282 {
283 ERR_CH(UserProcess, "MapGlobalUserHeap - We don't have a Win32 process!\n");
284 ASSERT(FALSE);
285 }
286
287 TRACE_CH(UserProcess, "MapGlobalUserHeap - We got a Win32 process, find for existing global user heap mapping...\n");
288
289 /* The first mapping entry must be the global user heap */
290 HeapMapping = &W32Process->HeapMappings;
291
292 /* Find out if another thread already mapped the global user heap */
293 if (HeapMapping->KernelMapping == (PVOID)GlobalUserHeap)
294 {
295 HeapMapping->Count++;
296
297 TRACE_CH(UserProcess, "MapGlobalUserHeap - A mapping was found, return it.\n");
298
299 *KernelMapping = HeapMapping->KernelMapping;
300 *UserMapping = HeapMapping->UserMapping;
301
302 return STATUS_SUCCESS;
303 }
304
305 TRACE_CH(UserProcess, "MapGlobalUserHeap - No mapping was found, let's map...\n");
306
307 /* We're the first, map the global heap into the process */
308 Offset.QuadPart = 0;
310 Process,
311 &UserBase,
312 0,
313 0,
314 &Offset,
315 &ViewSize,
316 ViewUnmap,
318 PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
319 if (!NT_SUCCESS(Status))
320 {
321 ERR_CH(UserProcess, "MapGlobalUserHeap - Failed to map the global heap! 0x%x\n", Status);
322 return Status;
323 }
324
325 TRACE_CH(UserProcess, "MapGlobalUserHeap -- Mapped kernel global heap 0x%p to user space at 0x%p\n",
326 GlobalUserHeap, UserBase);
327
328 /* Add the mapping */
329 HeapMapping->Next = NULL;
330 HeapMapping->KernelMapping = (PVOID)GlobalUserHeap;
331 HeapMapping->UserMapping = UserBase;
332 HeapMapping->Limit = ViewSize;
333 HeapMapping->Count = 1;
334
335 *KernelMapping = HeapMapping->KernelMapping;
336 *UserMapping = HeapMapping->UserMapping;
337
338 return STATUS_SUCCESS;
339}
#define ERR_CH(ch, fmt,...)
Definition: debug.h:108
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:111
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
static GENERIC_MAPPING UserMapping
Definition: samrpc.c:48
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:198
ULONG_PTR Limit
Definition: win32.h:201

Referenced by InitProcessCallback().

◆ UnmapGlobalUserHeap()

NTSTATUS UnmapGlobalUserHeap ( IN PEPROCESS  Process)

Definition at line 236 of file usrheap.c.

237{
239 PPROCESSINFO W32Process;
240 PW32HEAP_USER_MAPPING HeapMapping;
241
242 TRACE_CH(UserProcess, "IntUnmapDesktopView called for process 0x%p\n", Process);
243
244 W32Process = PsGetProcessWin32Process(Process);
245 if (W32Process == NULL)
246 {
247 ERR_CH(UserProcess, "UnmapGlobalUserHeap - We don't have a Win32 process!\n");
248 ASSERT(FALSE);
249 }
250
251 /* The first mapping entry must be the global user heap */
252 HeapMapping = &W32Process->HeapMappings;
253 ASSERT(HeapMapping->KernelMapping == (PVOID)GlobalUserHeap);
254
255 /* Unmap if we're the last thread using the global user heap */
256 if (--HeapMapping->Count == 0)
257 {
258 TRACE_CH(UserProcess, "UnmapGlobalUserHeap - Unmapping\n");
260 }
261
262 return Status;
263}

◆ UserCreateHeap()

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

Definition at line 181 of file usrheap.c.

184{
185 LARGE_INTEGER SizeHeap;
186 PWIN32HEAP pHeap = NULL;
188
189 SizeHeap.QuadPart = HeapSize;
190
191 /* Create the section and map it into session space */
194 NULL,
195 &SizeHeap,
196 PAGE_EXECUTE_READWRITE, /* Would prefer PAGE_READWRITE, but thanks to RTL heaps... */
197 SEC_RESERVE | 1,
198 NULL,
199 NULL);
200
201 if (!NT_SUCCESS(Status))
202 {
204 return FALSE;
205 }
206
208 SystemBase,
209 &HeapSize);
210 if (!NT_SUCCESS(Status))
211 {
214
216 return FALSE;
217 }
218
219 /* Create the heap */
221 SystemBase,
222 HeapSize);
223
224 if (pHeap == NULL)
225 {
228
230 }
231
232 return pHeap;
233}
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2687
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define SEC_RESERVE
Definition: nt_native.h:1323
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
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:4620
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
static PWIN32HEAP IntUserHeapCreate(IN PVOID SectionObject, IN PVOID *SystemMappedBase, IN ULONG HeapSize)
Definition: usrheap.c:119
struct _WIN32HEAP * PWIN32HEAP
Definition: usrheap.h:3
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
#define ObDereferenceObject
Definition: obfuncs.h:203

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().