diff --git a/subsystems/win32/win32k/eng/mapping.c b/subsystems/win32/win32k/eng/mapping.c index 7e445d7c631..5cec5a8cad2 100644 --- a/subsystems/win32/win32k/eng/mapping.c +++ b/subsystems/win32/win32k/eng/mapping.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * PURPOSE: Functions for mapping files and sections * FILE: subsys/win32k/eng/device.c - * PROGRAMER: + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */ #include @@ -11,12 +11,314 @@ #define NDEBUG #include +// HACK!!! +#define MmMapViewInSessionSpace MmMapViewInSystemSpace +#define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace + +typedef struct _ENGSECTION +{ + PVOID pvSectionObject; + PVOID pvMappedBase; + SIZE_T cjViewSize; + ULONG ulTag; +} ENGSECTION, *PENGSECTION; + +typedef struct _FILEVIEW +{ + ULARGE_INTEGER LastWriteTime; + PVOID pvKView; + PVOID pvViewFD; + ULONG cjView; + PVOID pSection; +} FILEVIEW, *PFILEVIEW; + +typedef struct _FONTFILEVIEW +{ + FILEVIEW; + DWORD reserved[2]; + PWSTR pwszPath; + SIZE_T ulRegionSize; + ULONG cKRefCount; + ULONG cRefCountFD; + PVOID pvSpoolerBase; + DWORD dwSpoolerPid; +} FONTFILEVIEW, *PFONTFILEVIEW; + +enum +{ + FVF_SYSTEMROOT = 1, + FVF_READONLY = 2, + FVF_FONTFILE = 4, +}; + +HANDLE ghSystem32Directory; +HANDLE ghRootDirectory; + + +PVOID +NTAPI +EngCreateSection( + IN ULONG fl, + IN SIZE_T cjSize, + HANDLE hFile, + IN ULONG ulTag) +{ + NTSTATUS Status; + PENGSECTION pSection; + PVOID pvSectionObject; + LARGE_INTEGER liSize; + + /* Allocate a section object */ + pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU'); + if (!pSection) return NULL; + + liSize.QuadPart = cjSize; + Status = MmCreateSection(&pvSectionObject, + SECTION_ALL_ACCESS, + NULL, + &liSize, + PAGE_READWRITE, + SEC_COMMIT, + hFile, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create a section Status=0x%x\n", Status); + EngFreeMem(pSection); + return NULL; + } + + /* Set the fields of the section */ + pSection->ulTag = ulTag; + pSection->pvSectionObject = pvSectionObject; + pSection->pvMappedBase = NULL; + pSection->cjViewSize = cjSize; + + return pSection; +} + + +BOOL +APIENTRY +EngMapSection( + IN PVOID pvSection, + IN BOOL bMap, + IN HANDLE hProcess, + OUT PVOID* pvBaseAddress) +{ + NTSTATUS Status; + PENGSECTION pSection = pvSection; + PEPROCESS pepProcess; + + /* Get a pointer to the process */ + Status = ObReferenceObjectByHandle(hProcess, + PROCESS_VM_OPERATION, + NULL, + KernelMode, + (PVOID*)&pepProcess, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status); + return FALSE; + } + + if (bMap) + { + /* Make sure the section isn't already mapped */ + ASSERT(pSection->pvMappedBase == NULL); + + /* Map the section into the process address space */ + Status = MmMapViewOfSection(pSection->pvSectionObject, + pepProcess, + &pSection->pvMappedBase, + 0, + pSection->cjViewSize, + NULL, + &pSection->cjViewSize, + 0, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + } + } + else + { + /* Make sure the section is mapped */ + ASSERT(pSection->pvMappedBase); + + /* Unmap the section from the process address space */ + Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase); + if (NT_SUCCESS(Status)) + { + pSection->pvMappedBase = NULL; + } + else + { + DPRINT1("Failed to unmap a section @ &p Status=0x%x\n", + pSection->pvMappedBase, Status); + } + } + + /* Dereference the process */ + ObDereferenceObject(pepProcess); + + /* Set the new mapping base and return bool status */ + *pvBaseAddress = pSection->pvMappedBase; + return NT_SUCCESS(Status); +} + +BOOL +APIENTRY +EngFreeSectionMem( + IN PVOID pvSection OPTIONAL, + IN PVOID pvMappedBase OPTIONAL) +{ + NTSTATUS Status; + PENGSECTION pSection = pvSection; + BOOL bResult = TRUE; + + /* Did the caller give us a mapping base? */ + if (pvMappedBase) + { + Status = MmUnmapViewInSessionSpace(pvMappedBase); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status); + bResult = FALSE; + } + } + + /* Check if we should free the section as well */ + if (pSection) + { + /* Dereference the kernel section */ + ObDereferenceObject(pSection->pvSectionObject); + + /* Finally free the section memory itself */ + EngFreeMem(pSection); + } + + return bResult; +} + +PVOID +APIENTRY +EngAllocSectionMem( + OUT PVOID *ppvSection, + IN ULONG fl, + IN SIZE_T cjSize, + IN ULONG ulTag) +{ + NTSTATUS Status; + PENGSECTION pSection; + + /* Check parameter */ + if (cjSize == 0) return NULL; + + /* Allocate a section object */ + pSection = EngCreateSection(fl, cjSize, NULL, ulTag); + + /* Map the section in session space */ + Status = MmMapViewInSessionSpace(pSection->pvSectionObject, + &pSection->pvMappedBase, + &pSection->cjViewSize); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + *ppvSection = NULL; + EngFreeSectionMem(pSection, NULL); + return NULL; + } + + /* Set section pointer and return base address */ + *ppvSection = pSection; + return pSection->pvMappedBase; +} + + +PFILEVIEW +NTAPI +EngLoadModuleEx( + LPWSTR pwsz, + ULONG cjSizeOfModule, + FLONG fl) +{ + PFILEVIEW pFileView = NULL; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hRootDir; + UNICODE_STRING ustrFileName; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; + NTSTATUS Status; + + if (fl & FVF_FONTFILE) + { + pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG'); + } + else + { + pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg'); + } + + /* Check for success */ + if (!pFileView) return NULL; + + /* Check if the file is relative to system32 */ + if (fl & FVF_SYSTEMROOT) + { + hRootDir = ghSystem32Directory; + } + else + { + hRootDir = ghRootDirectory; + } + + /* Initialize unicode string and object attributes */ + RtlInitUnicodeString(&ustrFileName, pwsz); + InitializeObjectAttributes(&ObjectAttributes, + &ustrFileName, + OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, + hRootDir, + NULL); + + /* Now open the file */ + Status = ZwCreateFile(&hFile, + FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + /* Check for auto size */ + if (cjSizeOfModule == 0) + { + } + + /* Allocate a section object */ + pFileView->pSection = EngCreateSection(fl, cjSizeOfModule, hFile, '1234'); + + /* Close the file handle */ + ZwClose(hFile); + + pFileView->cjView = cjSizeOfModule; + + return pFileView; +} + HANDLE APIENTRY EngLoadModule(LPWSTR pwsz) { - UNIMPLEMENTED; - return NULL; + /* Forward to EngLoadModuleEx */ + return (HANDLE)EngLoadModuleEx(pwsz, 0, FVF_READONLY | FVF_SYSTEMROOT); } HANDLE @@ -25,9 +327,8 @@ EngLoadModuleForWrite( IN LPWSTR pwsz, IN ULONG cjSizeOfModule) { - // www.osr.com/ddk/graphics/gdifncs_98rr.htm - UNIMPLEMENTED; - return NULL; + /* Forward to EngLoadModuleEx */ + return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT); } PVOID @@ -36,17 +337,41 @@ EngMapModule( IN HANDLE h, OUT PULONG pulSize) { - // www.osr.com/ddk/graphics/gdifncs_9b1j.htm - UNIMPLEMENTED; - return NULL; + PFILEVIEW pFileView = (PFILEVIEW)h; + PENGSECTION pSection = pFileView->pSection; + NTSTATUS Status; + + /* Map the section in session space */ + Status = MmMapViewInSessionSpace(pSection->pvSectionObject, + &pSection->pvMappedBase, + &pSection->cjViewSize); + if (NT_SUCCESS(Status)) + { + *pulSize = pSection->cjViewSize; + } + else + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + *pulSize = 0; + EngFreeSectionMem(pSection, NULL); + return NULL; + } + + return pSection->pvMappedBase; } VOID APIENTRY -EngFreeModule (IN HANDLE h) +EngFreeModule(IN HANDLE h) { - // www.osr.com/ddk/graphics/gdifncs_9fzb.htm - UNIMPLEMENTED; + PFILEVIEW pFileView = (PFILEVIEW)h; + PENGSECTION pSection = pFileView->pSection; + + /* Free the section */ + EngFreeSectionMem(pSection, pSection->pvMappedBase); + + /* Free the file view memory */ + EngFreeMem(pFileView); } PVOID @@ -56,8 +381,28 @@ EngMapFile( IN ULONG cjSize, OUT ULONG_PTR *piFile) { - UNIMPLEMENTED; - return NULL; + HANDLE hModule; + PVOID pvBase; + + /* Load the file */ + hModule = EngLoadModuleEx(pwsz, 0, 0); + if (!hModule) + { + *piFile = 0; + return NULL; + } + + /* Map the file */ + pvBase = EngMapModule(hModule, &cjSize); + if (!pvBase) + { + EngFreeModule(hModule); + hModule = NULL; + } + + /* Set iFile and return mapped base */ + *piFile = (ULONG_PTR)hModule; + return pvBase; } BOOL @@ -65,8 +410,11 @@ APIENTRY EngUnmapFile( IN ULONG_PTR iFile) { - UNIMPLEMENTED; - return FALSE; + HANDLE hModule = (HANDLE)iFile; + + EngFreeModule(hModule); + + return TRUE; } @@ -110,36 +458,3 @@ EngUnmapFontFile( // www.osr.com/ddk/graphics/gdifncs_09wn.htm EngUnmapFontFileFD(iFile); } - - -BOOLEAN -APIENTRY -EngMapSection(IN PVOID Section, - IN BOOLEAN Map, - IN HANDLE Process, - IN PVOID* BaseAddress) -{ - UNIMPLEMENTED; - return FALSE; -} - -PVOID -APIENTRY -EngAllocSectionMem(IN PVOID SectionObject, - IN ULONG Flags, - IN SIZE_T MemSize, - IN ULONG Tag) -{ - UNIMPLEMENTED; - return NULL; -} - - -BOOLEAN -APIENTRY -EngFreeSectionMem(IN PVOID SectionObject OPTIONAL, - IN PVOID MappedBase) -{ - UNIMPLEMENTED; - return FALSE; -}