ReactOS 0.4.15-dev-8127-g6338913
usrheap.c
Go to the documentation of this file.
1/*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <win32k.h>
21
22#define NDEBUG
23#include <debug.h>
24
27
28
29_Function_class_(RTL_HEAP_COMMIT_ROUTINE)
31static
34IntUserHeapCommitRoutine(
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}
117
118static PWIN32HEAP
120 IN PVOID *SystemMappedBase,
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}
179
182 IN OUT PVOID *SystemBase,
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}
234
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}
264
267 OUT PVOID* KernelMapping,
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}
340
341/* EOF */
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2687
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:2750
LONG NTSTATUS
Definition: precomp.h:26
#define ERR_CH(ch, fmt,...)
Definition: debug.h:108
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:111
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define ULONG_PTR
Definition: config.h:101
#define _IRQL_requires_same_
Definition: driverspecs.h:232
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
#define DBG(x)
Definition: moztest.c:12
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
_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 HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define SEC_RESERVE
Definition: nt_native.h:1323
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 NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewUnmap
Definition: nt_native.h:1279
#define MEM_COMMIT
Definition: nt_native.h:1313
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
static GENERIC_MAPPING UserMapping
Definition: samrpc.c:48
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
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_SUCCESS
Definition: shellext.h:65
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:290
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:198
ULONG_PTR Limit
Definition: win32.h:201
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
NTSTATUS UnmapGlobalUserHeap(IN PEPROCESS Process)
Definition: usrheap.c:236
PWIN32HEAP UserCreateHeap(OUT PVOID *SectionObject, IN OUT PVOID *SystemBase, IN SIZE_T HeapSize)
Definition: usrheap.c:181
NTSTATUS MapGlobalUserHeap(IN PEPROCESS Process, OUT PVOID *KernelMapping, OUT PVOID *UserMapping)
Definition: usrheap.c:266
HANDLE GlobalUserHeap
Definition: usrheap.c:25
static PWIN32HEAP IntUserHeapCreate(IN PVOID SectionObject, IN PVOID *SystemMappedBase, IN ULONG HeapSize)
Definition: usrheap.c:119
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
struct _WIN32HEAP * PWIN32HEAP
Definition: usrheap.h:3
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
static ULONG Delta
Definition: xboxvideo.c:33
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Inout_ PVOID * CommitAddress
Definition: rtltypes.h:584