ReactOS  0.4.15-dev-3291-gea4c1a0
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)
31 static
33 NTAPI
34 IntUserHeapCommitRoutine(
35  _In_ PVOID Base,
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 }
117 
118 static PWIN32HEAP
120  IN PVOID *SystemMappedBase,
121  IN ULONG HeapSize)
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 
166  pHeap = RtlCreateHeap(
167 #if DBG /* Enable checks on debug builds */
169 #endif
171  *SystemMappedBase,
172  (SIZE_T)HeapSize,
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  {
213  *SectionObject = NULL;
214 
216  return FALSE;
217  }
218 
219  /* Create the heap */
221  SystemBase,
222  HeapSize);
223 
224  if (pHeap == NULL)
225  {
227  *SectionObject = NULL;
228 
230  }
231 
232  return pHeap;
233 }
234 
235 NTSTATUS
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 
265 NTSTATUS
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 */
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define IN
Definition: typedefs.h:39
#define _Inout_
Definition: ms_sal.h:378
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
struct _WIN32HEAP * PWIN32HEAP
Definition: usrheap.h:3
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
_Function_class_(RTL_HEAP_COMMIT_ROUTINE)
Definition: usrheap.c:29
#define HEAP_TAIL_CHECKING_ENABLED
Definition: nt_native.h:1697
#define MEM_COMMIT
Definition: nt_native.h:1313
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS MapGlobalUserHeap(IN PEPROCESS Process, OUT PVOID *KernelMapping, OUT PVOID *UserMapping)
Definition: usrheap.c:266
static GENERIC_MAPPING UserMapping
Definition: samrpc.c:48
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define SEC_RESERVE
Definition: nt_native.h:1323
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define _In_
Definition: ms_sal.h:308
#define _IRQL_requires_same_
Definition: driverspecs.h:232
#define DBG(x)
Definition: moztest.c:12
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:3906
W32HEAP_USER_MAPPING HeapMappings
Definition: win32.h:288
void * PVOID
Definition: retypes.h:9
NTSTATUS UnmapGlobalUserHeap(IN PEPROCESS Process)
Definition: usrheap.c:236
#define HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
ULONG_PTR Limit
Definition: win32.h:204
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3109
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Inout_ PVOID * CommitAddress
Definition: rtltypes.h:578
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:4509
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
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
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:108
static ULONG Delta
Definition: xboxvideo.c:33
HANDLE GlobalUserHeap
Definition: usrheap.c:25
#define NULL
Definition: types.h:112
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define ERR_CH(ch, fmt,...)
Definition: debug.h:105
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define OUT
Definition: typedefs.h:40
static PWIN32HEAP IntUserHeapCreate(IN PVOID SectionObject, IN PVOID *SystemMappedBase, IN ULONG HeapSize)
Definition: usrheap.c:119
_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
unsigned int ULONG
Definition: retypes.h:1
PWIN32HEAP UserCreateHeap(OUT PVOID *SectionObject, IN OUT PVOID *SystemBase, IN SIZE_T HeapSize)
Definition: usrheap.c:181
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:3046
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:201
LONGLONG QuadPart
Definition: typedefs.h:114