ReactOS  0.4.13-dev-249-gcba1a2f
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 
167  *SystemMappedBase,
168  (SIZE_T)HeapSize,
169  ViewSize,
170  NULL,
171  &Parameters);
172 
173  return pHeap;
174 }
175 
178  IN OUT PVOID *SystemBase,
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 }
230 
231 NTSTATUS
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 }
260 
261 NTSTATUS
263  OUT PVOID* KernelMapping,
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 }
336 
337 /* EOF */
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define _IRQL_requires_same_
Definition: no_sal2.h:652
#define IN
Definition: typedefs.h:38
#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:2327
_Function_class_(RTL_HEAP_COMMIT_ROUTINE)
Definition: usrheap.c:29
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define MEM_COMMIT
Definition: nt_native.h:1313
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS MapGlobalUserHeap(IN PEPROCESS Process, OUT PVOID *KernelMapping, OUT PVOID *UserMapping)
Definition: usrheap.c:262
static GENERIC_MAPPING UserMapping
Definition: samrpc.c:48
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define SEC_RESERVE
Definition: nt_native.h:1323
#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
NTSTATUS UnmapGlobalUserHeap(IN PEPROCESS Process)
Definition: usrheap.c:232
#define NtCurrentProcess()
Definition: nt_native.h:1657
ULONG_PTR Limit
Definition: win32.h:197
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
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
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
#define _Inout_
Definition: no_sal2.h:244
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_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
PVOID GlobalUserHeapSection
Definition: usrheap.c:26
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:107
static ULONG Delta
Definition: xboxvideo.c:28
HANDLE GlobalUserHeap
Definition: usrheap.c:25
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#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
#define OUT
Definition: typedefs.h:39
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:177
#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
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:2991
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define SEC_NO_CHANGE
Definition: mmtypes.h:94
struct _W32HEAP_USER_MAPPING * Next
Definition: win32.h:194
LONGLONG QuadPart
Definition: typedefs.h:112