2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Functions for mapping files and sections
5 * FILE: subsys/win32k/eng/device.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
));
99 PVOID pvSectionObject
;
100 LARGE_INTEGER liSize
;
102 /* Allocate a section object */
103 pSection
= EngAllocMem(0, sizeof(ENGSECTION
), 'stsU');
104 if (!pSection
) return NULL
;
106 liSize
.QuadPart
= cjSize
;
107 Status
= MmCreateSection(&pvSectionObject
,
115 if (!NT_SUCCESS(Status
))
117 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
118 EngFreeMem(pSection
);
122 /* Set the fields of the section */
123 pSection
->ulTag
= ulTag
;
124 pSection
->pvSectionObject
= pvSectionObject
;
125 pSection
->pvMappedBase
= NULL
;
126 pSection
->cjViewSize
= cjSize
;
133 EngCreateSectionHack(
139 PENGSECTION pSection
;
140 PVOID pvSectionObject
;
141 LARGE_INTEGER liSize
;
143 /* Allocate a section object */
144 pSection
= EngAllocMem(0, sizeof(ENGSECTION
), 'stsU');
145 if (!pSection
) return NULL
;
147 liSize
.QuadPart
= cjSize
;
148 Status
= MmCreateSection(&pvSectionObject
,
156 if (!NT_SUCCESS(Status
))
158 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
159 EngFreeMem(pSection
);
163 /* Set the fields of the section */
164 pSection
->ulTag
= ulTag
;
165 pSection
->pvSectionObject
= pvSectionObject
;
166 pSection
->pvMappedBase
= NULL
;
167 pSection
->cjViewSize
= cjSize
;
180 OUT PVOID
* pvBaseAddress
)
183 PENGSECTION pSection
= pvSection
;
184 PEPROCESS pepProcess
;
186 /* Get a pointer to the process */
187 Status
= ObReferenceObjectByHandle(hProcess
,
188 PROCESS_VM_OPERATION
,
193 if (!NT_SUCCESS(Status
))
195 DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess
, Status
);
201 /* Make sure the section isn't already mapped */
202 ASSERT(pSection
->pvMappedBase
== NULL
);
204 /* Map the section into the process address space */
205 Status
= MmMapViewOfSection(pSection
->pvSectionObject
,
207 &pSection
->pvMappedBase
,
209 pSection
->cjViewSize
,
211 &pSection
->cjViewSize
,
215 if (!NT_SUCCESS(Status
))
217 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
222 /* Make sure the section is mapped */
223 ASSERT(pSection
->pvMappedBase
);
225 /* Unmap the section from the process address space */
226 Status
= MmUnmapViewOfSection(pepProcess
, pSection
->pvMappedBase
);
227 if (NT_SUCCESS(Status
))
229 pSection
->pvMappedBase
= NULL
;
233 DPRINT1("Failed to unmap a section @ %p Status=0x%x\n",
234 pSection
->pvMappedBase
, Status
);
238 /* Dereference the process */
239 ObDereferenceObject(pepProcess
);
241 /* Set the new mapping base and return bool status */
242 *pvBaseAddress
= pSection
->pvMappedBase
;
243 return NT_SUCCESS(Status
);
249 IN PVOID pvSection OPTIONAL
,
250 IN PVOID pvMappedBase OPTIONAL
)
253 PENGSECTION pSection
= pvSection
;
256 /* Did the caller give us a mapping base? */
259 Status
= MmUnmapViewInSessionSpace(pvMappedBase
);
260 if (!NT_SUCCESS(Status
))
262 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status
);
267 /* Check if we should free the section as well */
270 /* Dereference the kernel section */
271 ObDereferenceObject(pSection
->pvSectionObject
);
273 /* Finally free the section memory itself */
274 EngFreeMem(pSection
);
283 OUT PVOID
*ppvSection
,
289 PENGSECTION pSection
;
291 /* Check parameter */
292 if (cjSize
== 0) return NULL
;
294 /* Allocate a section object */
295 pSection
= EngCreateSectionHack(fl
, cjSize
, ulTag
);
302 /* Map the section in session space */
303 Status
= MmMapViewInSessionSpace(pSection
->pvSectionObject
,
304 &pSection
->pvMappedBase
,
305 &pSection
->cjViewSize
);
306 if (!NT_SUCCESS(Status
))
308 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
310 EngFreeSectionMem(pSection
, NULL
);
314 if (fl
& FL_ZERO_MEMORY
)
316 RtlZeroMemory(pSection
->pvMappedBase
, cjSize
);
319 /* Set section pointer and return base address */
320 *ppvSection
= pSection
;
321 return pSection
->pvMappedBase
;
329 ULONG cjSizeOfModule
,
332 PFILEVIEW pFileView
= NULL
;
333 OBJECT_ATTRIBUTES ObjectAttributes
;
335 UNICODE_STRING ustrFileName
;
336 IO_STATUS_BLOCK IoStatusBlock
;
337 FILE_BASIC_INFORMATION FileInformation
;
340 LARGE_INTEGER liSize
;
342 if (fl
& FVF_FONTFILE
)
344 pFileView
= EngAllocMem(0, sizeof(FONTFILEVIEW
), 'vffG');
348 pFileView
= EngAllocMem(0, sizeof(FILEVIEW
), 'liFg');
351 /* Check for success */
352 if (!pFileView
) return NULL
;
354 /* Check if the file is relative to system32 */
355 if (fl
& FVF_SYSTEMROOT
)
357 hRootDir
= ghSystem32Directory
;
361 hRootDir
= ghRootDirectory
;
364 /* Initialize unicode string and object attributes */
365 RtlInitUnicodeString(&ustrFileName
, pwsz
);
366 InitializeObjectAttributes(&ObjectAttributes
,
368 OBJ_CASE_INSENSITIVE
|OBJ_KERNEL_HANDLE
,
372 /* Now open the file */
373 Status
= ZwCreateFile(&hFile
,
378 FILE_ATTRIBUTE_NORMAL
,
381 FILE_NON_DIRECTORY_FILE
,
385 Status
= ZwQueryInformationFile(hFile
,
388 sizeof(FILE_BASIC_INFORMATION
),
389 FileBasicInformation
);
390 if (NT_SUCCESS(Status
))
392 pFileView
->LastWriteTime
= FileInformation
.LastWriteTime
;
395 /* Create a section from the file */
396 liSize
.QuadPart
= cjSizeOfModule
;
397 Status
= MmCreateSection(&pFileView
->pSection
,
401 fl
& FVF_READONLY
? PAGE_EXECUTE_READ
: PAGE_EXECUTE_READWRITE
,
406 /* Close the file handle */
409 if (!NT_SUCCESS(Status
))
411 DPRINT1("Failed to create a section Status=0x%x\n", Status
);
412 EngFreeMem(pFileView
);
417 pFileView
->pvKView
= NULL
;
418 pFileView
->pvViewFD
= NULL
;
419 pFileView
->cjView
= 0;
429 /* Forward to EngLoadModuleEx */
430 return (HANDLE
)EngLoadModuleEx(pwsz
, 0, FVF_READONLY
| FVF_SYSTEMROOT
);
435 EngLoadModuleForWrite(
437 _In_ ULONG cjSizeOfModule
)
439 /* Forward to EngLoadModuleEx */
440 return (HANDLE
)EngLoadModuleEx(pwsz
, cjSizeOfModule
, FVF_SYSTEMROOT
);
447 _Out_ PULONG pulSize
)
449 PFILEVIEW pFileView
= (PFILEVIEW
)h
;
452 pFileView
->cjView
= 0;
454 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
455 Status
= MmMapViewInSystemSpace(pFileView
->pSection
,
458 if (!NT_SUCCESS(Status
))
460 DPRINT1("Failed to map a section Status=0x%x\n", Status
);
465 *pulSize
= (ULONG
)pFileView
->cjView
;
466 return pFileView
->pvKView
;
474 PFILEVIEW pFileView
= (PFILEVIEW
)h
;
477 /* FIXME: Use system space because ARM3 doesn't support executable sections yet */
478 Status
= MmUnmapViewInSystemSpace(pFileView
->pvKView
);
479 if (!NT_SUCCESS(Status
))
481 DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status
);
485 /* Dereference the section */
486 ObDereferenceObject(pFileView
->pSection
);
488 /* Free the file view memory */
489 EngFreeMem(pFileView
);
492 _Success_(return != 0)
493 _When_(cjSize
!= 0, _At_(return, _Out_writes_bytes_(cjSize
)))
499 _Out_ ULONG_PTR
*piFile
)
505 hModule
= EngLoadModuleEx(pwsz
, 0, 0);
513 pvBase
= EngMapModule(hModule
, &cjSize
);
516 EngFreeModule(hModule
);
520 /* Set iFile and return mapped base */
521 *piFile
= (ULONG_PTR
)hModule
;
528 _In_ ULONG_PTR iFile
)
530 HANDLE hModule
= (HANDLE
)iFile
;
532 EngFreeModule(hModule
);
541 _In_ ULONG_PTR iFile
,
542 _Outptr_result_bytebuffer_(*pcjBuf
) PULONG
*ppjBuf
,
545 // www.osr.com/ddk/graphics/gdifncs_0co7.htm
553 _In_ ULONG_PTR iFile
)
555 // http://www.osr.com/ddk/graphics/gdifncs_6wbr.htm
562 _In_ ULONG_PTR iFile
,
563 _Outptr_result_bytebuffer_(*pcjBuf
) PULONG
*ppjBuf
,
566 // www.osr.com/ddk/graphics/gdifncs_3up3.htm
567 return EngMapFontFileFD(iFile
, ppjBuf
, pcjBuf
);
573 _In_ ULONG_PTR iFile
)
575 // www.osr.com/ddk/graphics/gdifncs_09wn.htm
576 EngUnmapFontFileFD(iFile
);