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)
14 HANDLE ghSystem32Directory
;
15 HANDLE ghRootDirectory
;
23 _Out_ PHANDLE phSecure
)
25 LARGE_INTEGER liSectionOffset
;
29 /* Check if the size is ok (for 64 bit) */
30 if (cjSize
> ULONG_MAX
)
32 DPRINT1("chSize out of range: 0x%Id\n", cjSize
);
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);
41 Status
= ZwMapViewOfSection(hSection
,
51 if (!NT_SUCCESS(Status
))
53 DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status
);
57 /* Secure the section memory */
58 *phSecure
= EngSecureMem(pvBaseAddress
, (ULONG
)cjSize
);
61 ZwUnmapViewOfSection(NtCurrentProcess(), pvBaseAddress
);
65 /* Return the address where the requested data starts */
66 return (PUCHAR
)pvBaseAddress
+ (cjOffset
& (MM_ALLOCATION_GRANULARITY
- 1));
78 /* Unsecure the memory */
79 EngUnsecureMem(hSecure
);
81 /* Calculate the real start of the section view */
82 pvBits
= (PUCHAR
)pvBits
- (cjOffset
& (MM_ALLOCATION_GRANULARITY
- 1));
84 /* Unmap the section view */
85 Status
= MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits
);
86 ASSERT(NT_SUCCESS(Status
));
98 PVOID pvSectionObject
;
101 /* Allocate a section object */
102 pSection
= EngAllocMem(0, sizeof(ENGSECTION
), 'stsU');
103 if (!pSection
) return NULL
;
105 liSize
.QuadPart
= cjSize
;
106 Status
= MmCreateSection(&pvSectionObject
,
114 if (!NT_SUCCESS(Status
))
116 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
117 EngFreeMem(pSection
);
121 /* Set the fields of the section */
122 pSection
->ulTag
= ulTag
;
123 pSection
->pvSectionObject
= pvSectionObject
;
124 pSection
->pvMappedBase
= NULL
;
125 pSection
->cjViewSize
= cjSize
;
132 EngCreateSectionHack(
138 PENGSECTION pSection
;
139 PVOID pvSectionObject
;
140 LARGE_INTEGER liSize
;
142 /* Allocate a section object */
143 pSection
= EngAllocMem(0, sizeof(ENGSECTION
), 'stsU');
144 if (!pSection
) return NULL
;
146 liSize
.QuadPart
= cjSize
;
147 Status
= MmCreateSection(&pvSectionObject
,
155 if (!NT_SUCCESS(Status
))
157 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
158 EngFreeMem(pSection
);
162 /* Set the fields of the section */
163 pSection
->ulTag
= ulTag
;
164 pSection
->pvSectionObject
= pvSectionObject
;
165 pSection
->pvMappedBase
= NULL
;
166 pSection
->cjViewSize
= cjSize
;
171 _Success_(return!=FALSE
)
175 _In_ PVOID pvSection
,
177 _In_ HANDLE hProcess
,
178 _When_(bMap
, _Outptr_
) PVOID
* pvBaseAddress
)
181 PENGSECTION pSection
= pvSection
;
182 PEPROCESS pepProcess
;
184 /* Get a pointer to the process */
185 Status
= ObReferenceObjectByHandle(hProcess
,
186 PROCESS_VM_OPERATION
,
191 if (!NT_SUCCESS(Status
))
193 DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess
, Status
);
199 /* Make sure the section isn't already mapped */
200 ASSERT(pSection
->pvMappedBase
== NULL
);
202 /* Map the section into the process address space */
203 Status
= MmMapViewOfSection(pSection
->pvSectionObject
,
205 &pSection
->pvMappedBase
,
207 pSection
->cjViewSize
,
209 &pSection
->cjViewSize
,
213 if (!NT_SUCCESS(Status
))
215 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
220 /* Make sure the section is mapped */
221 ASSERT(pSection
->pvMappedBase
);
223 /* Unmap the section from the process address space */
224 Status
= MmUnmapViewOfSection(pepProcess
, pSection
->pvMappedBase
);
225 if (NT_SUCCESS(Status
))
227 pSection
->pvMappedBase
= NULL
;
231 DPRINT1("Failed to unmap a section @ %p Status=0x%x\n",
232 pSection
->pvMappedBase
, Status
);
236 /* Dereference the process */
237 ObDereferenceObject(pepProcess
);
239 /* Set the new mapping base and return bool status */
240 *pvBaseAddress
= pSection
->pvMappedBase
;
241 return NT_SUCCESS(Status
);
247 _In_opt_ PVOID pvSection
,
248 _In_opt_ PVOID pvMappedBase
)
251 PENGSECTION pSection
= pvSection
;
254 /* Did the caller give us a mapping base? */
257 Status
= MmUnmapViewInSessionSpace(pvMappedBase
);
258 if (!NT_SUCCESS(Status
))
260 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status
);
265 /* Check if we should free the section as well */
268 /* Dereference the kernel section */
269 ObDereferenceObject(pSection
->pvSectionObject
);
271 /* Finally free the section memory itself */
272 EngFreeMem(pSection
);
279 _Success_(return!=NULL
)
280 __drv_allocatesMem(Mem
)
281 _Post_writable_byte_size_(cjSize
)
285 _Outptr_ PVOID
*ppvSection
,
291 PENGSECTION pSection
;
293 /* Check parameter */
294 if (cjSize
== 0) return NULL
;
296 /* Allocate a section object */
297 pSection
= EngCreateSectionHack(fl
, cjSize
, ulTag
);
304 /* Map the section in session space */
305 Status
= MmMapViewInSessionSpace(pSection
->pvSectionObject
,
306 &pSection
->pvMappedBase
,
307 &pSection
->cjViewSize
);
308 if (!NT_SUCCESS(Status
))
310 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
312 EngFreeSectionMem(pSection
, NULL
);
316 if (fl
& FL_ZERO_MEMORY
)
318 RtlZeroMemory(pSection
->pvMappedBase
, cjSize
);
321 /* Set section pointer and return base address */
322 *ppvSection
= pSection
;
323 return pSection
->pvMappedBase
;
331 _In_ ULONG cjSizeOfModule
,
334 PFILEVIEW pFileView
= NULL
;
335 OBJECT_ATTRIBUTES ObjectAttributes
;
337 UNICODE_STRING ustrFileName
;
338 IO_STATUS_BLOCK IoStatusBlock
;
339 FILE_BASIC_INFORMATION FileInformation
;
342 LARGE_INTEGER liSize
;
344 if (fl
& FVF_FONTFILE
)
346 pFileView
= EngAllocMem(0, sizeof(FONTFILEVIEW
), 'vffG');
350 pFileView
= EngAllocMem(0, sizeof(FILEVIEW
), 'liFg');
353 /* Check for success */
354 if (!pFileView
) return NULL
;
356 /* Check if the file is relative to system32 */
357 if (fl
& FVF_SYSTEMROOT
)
359 hRootDir
= ghSystem32Directory
;
363 hRootDir
= ghRootDirectory
;
366 /* Initialize unicode string and object attributes */
367 RtlInitUnicodeString(&ustrFileName
, pwsz
);
368 InitializeObjectAttributes(&ObjectAttributes
,
370 OBJ_CASE_INSENSITIVE
|OBJ_KERNEL_HANDLE
,
374 /* Now open the file */
375 Status
= ZwCreateFile(&hFile
,
380 FILE_ATTRIBUTE_NORMAL
,
383 FILE_NON_DIRECTORY_FILE
,
386 if (!NT_SUCCESS(Status
))
388 DPRINT1("Failed to open file, hFile=%p, Status=0x%x\n", hFile
, Status
);
389 EngFreeMem(pFileView
);
393 Status
= ZwQueryInformationFile(hFile
,
396 sizeof(FILE_BASIC_INFORMATION
),
397 FileBasicInformation
);
398 if (NT_SUCCESS(Status
))
400 pFileView
->LastWriteTime
= FileInformation
.LastWriteTime
;
403 /* Create a section from the file */
404 liSize
.QuadPart
= cjSizeOfModule
;
405 Status
= MmCreateSection(&pFileView
->pSection
,
409 fl
& FVF_READONLY
? PAGE_EXECUTE_READ
: PAGE_EXECUTE_READWRITE
,
414 /* Close the file handle */
417 if (!NT_SUCCESS(Status
))
419 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
420 EngFreeMem(pFileView
);
425 pFileView
->pvKView
= NULL
;
426 pFileView
->pvViewFD
= NULL
;
427 pFileView
->cjView
= 0;
437 /* Forward to EngLoadModuleEx */
438 return (HANDLE
)EngLoadModuleEx(pwsz
, 0, FVF_READONLY
| FVF_SYSTEMROOT
);
443 EngLoadModuleForWrite(
445 _In_ ULONG cjSizeOfModule
)
447 /* Forward to EngLoadModuleEx */
448 return (HANDLE
)EngLoadModuleEx(pwsz
, cjSizeOfModule
, FVF_SYSTEMROOT
);
452 _Success_(return!=NULL
)
453 _Post_writable_byte_size_(*pulSize
)
458 _Out_ PULONG pulSize
)
460 PFILEVIEW pFileView
= (PFILEVIEW
)h
;
463 pFileView
->cjView
= 0;
465 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
466 Status
= MmMapViewInSystemSpace(pFileView
->pSection
,
469 if (!NT_SUCCESS(Status
))
471 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
476 *pulSize
= (ULONG
)pFileView
->cjView
;
477 return pFileView
->pvKView
;
483 _In_ _Post_invalid_ HANDLE h
)
485 PFILEVIEW pFileView
= (PFILEVIEW
)h
;
488 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
489 Status
= MmUnmapViewInSystemSpace(pFileView
->pvKView
);
490 if (!NT_SUCCESS(Status
))
492 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status
);
496 /* Dereference the section */
497 ObDereferenceObject(pFileView
->pSection
);
499 /* Free the file view memory */
500 EngFreeMem(pFileView
);
503 _Success_(return != 0)
504 _When_(cjSize
!= 0, _At_(return, _Out_writes_bytes_(cjSize
)))
510 _Out_ ULONG_PTR
*piFile
)
516 hModule
= EngLoadModuleEx(pwsz
, 0, 0);
524 pvBase
= EngMapModule(hModule
, &cjSize
);
527 EngFreeModule(hModule
);
531 /* Set iFile and return mapped base */
532 *piFile
= (ULONG_PTR
)hModule
;
539 _In_ ULONG_PTR iFile
)
541 HANDLE hModule
= (HANDLE
)iFile
;
543 EngFreeModule(hModule
);
549 _Success_(return!=FALSE
)
553 _In_ ULONG_PTR iFile
,
554 _Outptr_result_bytebuffer_(*pcjBuf
) PULONG
*ppjBuf
,
557 // www.osr.com/ddk/graphics/gdifncs_0co7.htm
565 _In_ ULONG_PTR iFile
)
567 // http://www.osr.com/ddk/graphics/gdifncs_6wbr.htm
571 __drv_preferredFunction("EngMapFontFileFD", "Obsolete")
573 _Success_(return!=FALSE
)
577 _In_ ULONG_PTR iFile
,
578 _Outptr_result_bytebuffer_(*pcjBuf
) PULONG
*ppjBuf
,
581 // www.osr.com/ddk/graphics/gdifncs_3up3.htm
582 return EngMapFontFileFD(iFile
, ppjBuf
, pcjBuf
);
588 _In_ ULONG_PTR iFile
)
590 // www.osr.com/ddk/graphics/gdifncs_09wn.htm
591 EngUnmapFontFileFD(iFile
);