ReactOS 0.4.15-dev-7889-g76290a6
mapping.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Functions for mapping files and sections
5 * FILE: win32ss/gdi/eng/mapping.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9#include <win32k.h>
10
11#define NDEBUG
12#include <debug.h>
13
16
22 _In_ ULONG cjOffset,
23 _Out_ PHANDLE phSecure)
24{
25 LARGE_INTEGER liSectionOffset;
26 PVOID pvBaseAddress;
28
29 /* Check if the size is ok (for 64 bit) */
30 if (cjSize > ULONG_MAX)
31 {
32 DPRINT1("chSize out of range: 0x%Id\n", cjSize);
33 return NULL;
34 }
35
36 /* Align the offset at allocation granularity and compensate for the size */
37 liSectionOffset.QuadPart = cjOffset & ~(MM_ALLOCATION_GRANULARITY - 1);
38 cjSize += cjOffset & (MM_ALLOCATION_GRANULARITY - 1);
39
40 /* Map the section */
41 Status = ZwMapViewOfSection(hSection,
43 &pvBaseAddress,
44 0,
45 cjSize,
46 &liSectionOffset,
47 &cjSize,
49 0,
51 if (!NT_SUCCESS(Status))
52 {
53 DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
54 return NULL;
55 }
56
57 /* Secure the section memory */
58 *phSecure = EngSecureMem(pvBaseAddress, (ULONG)cjSize);
59 if (!*phSecure)
60 {
61 ZwUnmapViewOfSection(NtCurrentProcess(), pvBaseAddress);
62 return NULL;
63 }
64
65 /* Return the address where the requested data starts */
66 return (PUCHAR)pvBaseAddress + (cjOffset & (MM_ALLOCATION_GRANULARITY - 1));
67}
68
69VOID
72 _In_ PVOID pvBits,
73 _In_ ULONG cjOffset,
74 _In_ HANDLE hSecure)
75{
77
78 /* Unsecure the memory */
79 EngUnsecureMem(hSecure);
80
81 /* Calculate the real start of the section view */
82 pvBits = (PUCHAR)pvBits - (cjOffset & (MM_ALLOCATION_GRANULARITY - 1));
83
84 /* Unmap the section view */
87}
88
95{
97 PENGSECTION pSection;
98 PVOID pvSectionObject;
99 LARGE_INTEGER liSize;
100
101 /* Allocate a section object */
102 pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU');
103 if (!pSection) return NULL;
104
105 liSize.QuadPart = cjSize;
106 Status = MmCreateSection(&pvSectionObject,
108 NULL,
109 &liSize,
112 NULL,
113 NULL);
114 if (!NT_SUCCESS(Status))
115 {
116 DPRINT1("Failed to create a section Status=0x%x\n", Status);
117 EngFreeMem(pSection);
118 return NULL;
119 }
120
121 /* Set the fields of the section */
122 pSection->ulTag = ulTag;
123 pSection->pvSectionObject = pvSectionObject;
124 pSection->pvMappedBase = NULL;
125 pSection->cjViewSize = cjSize;
126
127 return pSection;
128}
129
130PVOID
131NTAPI
133 _In_ ULONG fl,
136{
138 PENGSECTION pSection;
139 PVOID pvSectionObject;
140 LARGE_INTEGER liSize;
141
142 /* Allocate a section object */
143 pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU');
144 if (!pSection) return NULL;
145
146 liSize.QuadPart = cjSize;
147 Status = MmCreateSection(&pvSectionObject,
149 NULL,
150 &liSize,
152 SEC_COMMIT | 1,
153 NULL,
154 NULL);
155 if (!NT_SUCCESS(Status))
156 {
157 DPRINT1("Failed to create a section Status=0x%x\n", Status);
158 EngFreeMem(pSection);
159 return NULL;
160 }
161
162 /* Set the fields of the section */
163 pSection->ulTag = ulTag;
164 pSection->pvSectionObject = pvSectionObject;
165 pSection->pvMappedBase = NULL;
166 pSection->cjViewSize = cjSize;
167
168 return pSection;
169}
170
172BOOL
174EngMapSection(
175 _In_ PVOID pvSection,
176 _In_ BOOL bMap,
178 _When_(bMap, _Outptr_) PVOID* pvBaseAddress)
179{
181 PENGSECTION pSection = pvSection;
182 PEPROCESS pepProcess;
183
184 /* Get a pointer to the process */
187 NULL,
189 (PVOID*)&pepProcess,
190 NULL);
191 if (!NT_SUCCESS(Status))
192 {
193 DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status);
194 return FALSE;
195 }
196
197 if (bMap)
198 {
199 /* Make sure the section isn't already mapped */
200 ASSERT(pSection->pvMappedBase == NULL);
201
202 /* Map the section into the process address space */
204 pepProcess,
205 &pSection->pvMappedBase,
206 0,
207 pSection->cjViewSize,
208 NULL,
209 &pSection->cjViewSize,
210 ViewUnmap,
211 0,
213 if (!NT_SUCCESS(Status))
214 {
215 DPRINT1("Failed to map a section Status=0x%x\n", Status);
216 }
217 }
218 else
219 {
220 /* Make sure the section is mapped */
221 ASSERT(pSection->pvMappedBase);
222
223 /* Unmap the section from the process address space */
224 Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase);
225 if (NT_SUCCESS(Status))
226 {
227 pSection->pvMappedBase = NULL;
228 }
229 else
230 {
231 DPRINT1("Failed to unmap a section @ %p Status=0x%x\n",
232 pSection->pvMappedBase, Status);
233 }
234 }
235
236 /* Dereference the process */
237 ObDereferenceObject(pepProcess);
238
239 /* Set the new mapping base and return bool status */
240 *pvBaseAddress = pSection->pvMappedBase;
241 return NT_SUCCESS(Status);
242}
243
244BOOL
247 _In_opt_ PVOID pvSection,
248 _In_opt_ PVOID pvMappedBase)
249{
251 PENGSECTION pSection = pvSection;
252 BOOL bResult = TRUE;
253
254 /* Did the caller give us a mapping base? */
255 if (pvMappedBase)
256 {
257 Status = MmUnmapViewInSessionSpace(pvMappedBase);
258 if (!NT_SUCCESS(Status))
259 {
260 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
261 bResult = FALSE;
262 }
263 }
264
265 /* Check if we should free the section as well */
266 if (pSection)
267 {
268 /* Dereference the kernel section */
270
271 /* Finally free the section memory itself */
272 EngFreeMem(pSection);
273 }
274
275 return bResult;
276}
277
282PVOID
284EngAllocSectionMem(
285 _Outptr_ PVOID *ppvSection,
286 _In_ ULONG fl,
289{
291 PENGSECTION pSection;
292
293 /* Check parameter */
294 if (cjSize == 0) return NULL;
295
296 /* Allocate a section object */
297 pSection = EngCreateSectionHack(fl, cjSize, ulTag);
298 if (!pSection)
299 {
300 *ppvSection = NULL;
301 return NULL;
302 }
303
304 /* Map the section in session space */
306 &pSection->pvMappedBase,
307 &pSection->cjViewSize);
308 if (!NT_SUCCESS(Status))
309 {
310 DPRINT1("Failed to map a section Status=0x%x\n", Status);
311 *ppvSection = NULL;
312 EngFreeSectionMem(pSection, NULL);
313 return NULL;
314 }
315
316 if (fl & FL_ZERO_MEMORY)
317 {
319 }
320
321 /* Set section pointer and return base address */
322 *ppvSection = pSection;
323 return pSection->pvMappedBase;
324}
325
328NTAPI
330 _In_z_ LPWSTR pwsz,
331 _In_ ULONG cjSizeOfModule,
332 _In_ FLONG fl)
333{
334 PFILEVIEW pFileView = NULL;
336 HANDLE hRootDir;
337 UNICODE_STRING ustrFileName;
342 LARGE_INTEGER liSize;
343
344 if (fl & FVF_FONTFILE)
345 {
346 pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG');
347 }
348 else
349 {
350 pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg');
351 }
352
353 /* Check for success */
354 if (!pFileView) return NULL;
355
356 /* Check if the file is relative to system32 */
357 if (fl & FVF_SYSTEMROOT)
358 {
359 hRootDir = ghSystem32Directory;
360 }
361 else
362 {
363 hRootDir = ghRootDirectory;
364 }
365
366 /* Initialize unicode string and object attributes */
367 RtlInitUnicodeString(&ustrFileName, pwsz);
369 &ustrFileName,
371 hRootDir,
372 NULL);
373
374 /* Now open the file */
375 Status = ZwCreateFile(&hFile,
379 NULL,
381 0,
382 FILE_OPEN,
384 NULL,
385 0);
386 if (!NT_SUCCESS(Status))
387 {
388 DPRINT1("Failed to open file, hFile=%p, Status=0x%x\n", hFile, Status);
389 EngFreeMem(pFileView);
390 return NULL;
391 }
392
393 Status = ZwQueryInformationFile(hFile,
398 if (NT_SUCCESS(Status))
399 {
400 pFileView->LastWriteTime = FileInformation.LastWriteTime;
401 }
402
403 /* Create a section from the file */
404 liSize.QuadPart = cjSizeOfModule;
405 Status = MmCreateSection(&pFileView->pSection,
407 NULL,
408 &liSize,
411 hFile,
412 NULL);
413
414 /* Close the file handle */
415 ZwClose(hFile);
416
417 if (!NT_SUCCESS(Status))
418 {
419 DPRINT1("Failed to create a section Status=0x%x\n", Status);
420 EngFreeMem(pFileView);
421 return NULL;
422 }
423
424
425 pFileView->pvKView = NULL;
426 pFileView->pvViewFD = NULL;
427 pFileView->cjView = 0;
428
429 return pFileView;
430}
431
432HANDLE
435 _In_ LPWSTR pwsz)
436{
437 /* Forward to EngLoadModuleEx */
439}
440
441HANDLE
444 _In_ LPWSTR pwsz,
445 _In_ ULONG cjSizeOfModule)
446{
447 /* Forward to EngLoadModuleEx */
448 return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT);
449}
450
452_Success_(return!=NULL)
454PVOID
456EngMapModule(
457 _In_ HANDLE h,
459{
460 PFILEVIEW pFileView = (PFILEVIEW)h;
462
463 pFileView->cjView = 0;
464
465 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
467 &pFileView->pvKView,
468 &pFileView->cjView);
469 if (!NT_SUCCESS(Status))
470 {
471 DPRINT1("Failed to map a section Status=0x%x\n", Status);
472 *pulSize = 0;
473 return NULL;
474 }
475
476 *pulSize = (ULONG)pFileView->cjView;
477 return pFileView->pvKView;
478}
479
480VOID
484{
485 PFILEVIEW pFileView = (PFILEVIEW)h;
487
488 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
490 if (!NT_SUCCESS(Status))
491 {
492 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
493 ASSERT(FALSE);
494 }
495
496 /* Dereference the section */
497 ObDereferenceObject(pFileView->pSection);
498
499 /* Free the file view memory */
500 EngFreeMem(pFileView);
501}
502
503_Success_(return != 0)
505PVOID
507EngMapFile(
508 _In_ LPWSTR pwsz,
511{
513 PVOID pvBase;
514
515 /* Load the file */
516 hModule = EngLoadModuleEx(pwsz, 0, 0);
517 if (!hModule)
518 {
519 *piFile = 0;
520 return NULL;
521 }
522
523 /* Map the file */
524 pvBase = EngMapModule(hModule, &cjSize);
525 if (!pvBase)
526 {
528 hModule = NULL;
529 }
530
531 /* Set iFile and return mapped base */
533 return pvBase;
534}
535
536BOOL
540{
542
544
545 return TRUE;
546}
547
549_Success_(return!=FALSE)
550BOOL
552EngMapFontFileFD(
556{
557 // www.osr.com/ddk/graphics/gdifncs_0co7.htm
559 return FALSE;
560}
561
562VOID
566{
567 // http://www.osr.com/ddk/graphics/gdifncs_6wbr.htm
569}
570
571__drv_preferredFunction("EngMapFontFileFD", "Obsolete")
574BOOL
576EngMapFontFile(
580{
581 // www.osr.com/ddk/graphics/gdifncs_3up3.htm
582 return EngMapFontFileFD(iFile, ppjBuf, pcjBuf);
583}
584
585VOID
589{
590 // www.osr.com/ddk/graphics/gdifncs_09wn.htm
592}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:3128
NTSTATUS NTAPI MmUnmapViewInSessionSpace(IN PVOID MappedBase)
Definition: section.c:3089
NTSTATUS NTAPI MmMapViewInSessionSpace(IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:3054
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
return
Definition: dirsup.c:529
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define APIENTRY
Definition: api.h:79
HMODULE hModule
Definition: animate.c:44
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ULONG_PTR
Definition: config.h:101
#define __drv_preferredFunction(func, why)
Definition: driverspecs.h:311
#define __drv_allocatesMem(kind)
Definition: driverspecs.h:257
unsigned int BOOL
Definition: ntddk_ex.h:94
@ FileBasicInformation
Definition: from_kernel.h:65
#define FILE_OPEN
Definition: from_kernel.h:54
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define ULONG_MAX
Definition: limits.h:44
#define PROCESS_VM_OPERATION
Definition: pstypes.h:160
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ BOOL bMap
Definition: mapping.h:70
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
@ FVF_READONLY
Definition: mapping.h:39
@ FVF_FONTFILE
Definition: mapping.h:40
@ FVF_SYSTEMROOT
Definition: mapping.h:38
struct _FILEVIEW * PFILEVIEW
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Outptr_result_bytebuffer_(size)
Definition: ms_sal.h:472
#define _Success_(expr)
Definition: ms_sal.h:259
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _In_z_
Definition: ms_sal.h:313
#define _Check_return_
Definition: ms_sal.h:557
#define _Outptr_
Definition: ms_sal.h:427
#define _Post_invalid_
Definition: ms_sal.h:695
#define _At_(target, annos)
Definition: ms_sal.h:244
#define _Out_
Definition: ms_sal.h:345
#define _When_(expr, annos)
Definition: ms_sal.h:254
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define _Post_writable_byte_size_(size)
Definition: ms_sal.h:652
_In_ HANDLE hFile
Definition: mswsock.h:90
#define KernelMode
Definition: asm.h:34
#define MM_ALLOCATION_GRANULARITY
Definition: mmtypes.h:36
#define SEC_COMMIT
Definition: mmtypes.h:100
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_READ_DATA
Definition: nt_native.h:628
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewUnmap
Definition: nt_native.h:1279
@ ViewShare
Definition: nt_native.h:1278
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
unsigned long FLONG
Definition: ntbasedef.h:366
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define EngFreeMem
Definition: polytest.cpp:56
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4447
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
ULONG ulTag
Definition: mapping.h:7
PVOID pvSectionObject
Definition: mapping.h:4
PVOID pvMappedBase
Definition: mapping.h:5
SIZE_T cjViewSize
Definition: mapping.h:6
PVOID pvKView
Definition: mapping.h:13
LARGE_INTEGER LastWriteTime
Definition: mapping.h:12
PVOID pvViewFD
Definition: mapping.h:14
PVOID pSection
Definition: mapping.h:16
SIZE_T cjView
Definition: mapping.h:15
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
PVOID NTAPI EngCreateSectionHack(_In_ ULONG fl, _In_ SIZE_T cjSize, _In_ ULONG ulTag)
Definition: mapping.c:132
HANDLE APIENTRY EngLoadModule(_In_ LPWSTR pwsz)
Definition: mapping.c:434
HANDLE APIENTRY EngLoadModuleForWrite(_In_ LPWSTR pwsz, _In_ ULONG cjSizeOfModule)
Definition: mapping.c:443
VOID NTAPI EngUnmapSectionView(_In_ PVOID pvBits, _In_ ULONG cjOffset, _In_ HANDLE hSecure)
Definition: mapping.c:71
HANDLE ghRootDirectory
Definition: mapping.c:15
PVOID NTAPI EngCreateSection(_In_ ULONG fl, _In_ SIZE_T cjSize, _In_ ULONG ulTag)
Definition: mapping.c:91
VOID APIENTRY EngUnmapFontFileFD(_In_ ULONG_PTR iFile)
Definition: mapping.c:564
VOID APIENTRY EngFreeModule(_In_ _Post_invalid_ HANDLE h)
Definition: mapping.c:482
BOOL APIENTRY EngUnmapFile(_In_ ULONG_PTR iFile)
Definition: mapping.c:538
BOOL APIENTRY EngFreeSectionMem(_In_opt_ PVOID pvSection, _In_opt_ PVOID pvMappedBase)
Definition: mapping.c:246
PVOID NTAPI EngMapSectionView(_In_ HANDLE hSection, _In_ SIZE_T cjSize, _In_ ULONG cjOffset, _Out_ PHANDLE phSecure)
Definition: mapping.c:19
HANDLE ghSystem32Directory
Definition: mapping.c:14
_Check_return_ PFILEVIEW NTAPI EngLoadModuleEx(_In_z_ LPWSTR pwsz, _In_ ULONG cjSizeOfModule, _In_ FLONG fl)
Definition: mapping.c:329
VOID APIENTRY EngUnmapFontFile(_In_ ULONG_PTR iFile)
Definition: mapping.c:587
_In_ FLONG fl
Definition: winddi.h:1279
_In_ ULONG _In_ ULONG ulTag
Definition: winddi.h:3942
_Check_return_ _Outptr_result_bytebuffer_ pcjBuf PULONG * ppjBuf
Definition: winddi.h:2109
_Check_return_ _Out_ PULONG pulSize
Definition: winddi.h:2120
_Check_return_ _Outptr_result_bytebuffer_ pcjBuf PULONG _Out_ ULONG * pcjBuf
Definition: winddi.h:2110
ENGAPI HANDLE APIENTRY EngSecureMem(_In_reads_bytes_(cjLength) PVOID Address, _In_ ULONG cjLength)
_In_ ULONG cjSize
Definition: winddi.h:3634
_In_ ULONG_PTR iFile
Definition: winddi.h:3835
ENGAPI VOID APIENTRY EngUnsecureMem(_In_ HANDLE hSecure)
_In_ ULONG_PTR * piFile
Definition: winddi.h:3720
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17
WCHAR * LPWSTR
Definition: xmlstorage.h:184