Author: tkreuzer Date: Sat May 28 15:57:47 2011 New Revision: 51975
URL: http://svn.reactos.org/svn/reactos?rev=51975&view=rev Log: [WIN32K] - Refactor EngLoadModuleEx, add the loaded module to a global list, don't map files multiple times, increase reference instead. - Implement EngMapFontFileFD and EngUnmapFontFileFD
Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/mapping.c branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/mapping.h
Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/mapping.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsyste... ============================================================================== --- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/mapping.c [iso-8859-1] (original) +++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/mapping.c [iso-8859-1] Sat May 28 15:57:47 2011 @@ -12,7 +12,8 @@ #include <debug.h>
HANDLE ghSystem32Directory; -HANDLE ghRootDirectory; +HSEMAPHORE ghsemModuleList; +LIST_ENTRY gleModulelist = {&gleModulelist, &gleModulelist};
PVOID NTAPI @@ -221,21 +222,29 @@ UNICODE_STRING ustrFileName; IO_STATUS_BLOCK IoStatusBlock; FILE_BASIC_INFORMATION FileInformation; - POBJECT_NAME_INFORMATION pNameInfo; - HANDLE hFile; + HANDLE hFile = NULL; NTSTATUS Status; LARGE_INTEGER liSize; - ULONG cjInfo, cjDesired; - - /* Check if the file is relative to system32 */ - if (fl & FVF_SYSTEMROOT) - { - hRootDir = ghSystem32Directory; - } - else - { - hRootDir = ghRootDirectory; - } + PLIST_ENTRY ple; + ULONG cjSize; + + /* Acquire module list lock */ + EngAcquireSemaphore(ghsemModuleList); + + /* Loop the list of loaded modules */ + for (ple = gleModulelist.Flink; ple != &gleModulelist; ple = ple->Flink) + { + pFileView = CONTAINING_RECORD(ple, FILEVIEW, leLink); + if (_wcsnicmp(pFileView->pwszPath, pwsz, MAX_PATH) == 0) + { + /* Increment reference count and leave */ + pFileView->cRefs++; + goto cleanup; + } + } + + /* Use system32 root dir or absolute path */ + hRootDir = fl & FVF_SYSTEMROOT ? ghSystem32Directory : NULL;
/* Initialize unicode string and object attributes */ RtlInitUnicodeString(&ustrFileName, pwsz); @@ -258,15 +267,18 @@ NULL, 0);
+ if (!NT_SUCCESS(Status)) + { + pFileView = NULL; + goto cleanup; + } + /* Check if this is a font file */ if (fl & FVF_FONTFILE) { - /* Query name information length */ - Status = ZwQueryObject(hFile, ObjectNameInformation, NULL, 0, &cjInfo); - if (Status != STATUS_INFO_LENGTH_MISMATCH) goto cleanup; - /* Allocate a FONTFILEVIEW structure */ - pffv = EngAllocMem(0, sizeof(FONTFILEVIEW) + cjInfo, 'vffG'); + cjSize = sizeof(FONTFILEVIEW) + ustrFileName.Length + sizeof(WCHAR); + pffv = EngAllocMem(0, cjSize, 'vffG'); pFileView = (PFILEVIEW)pffv; if (!pffv) { @@ -274,17 +286,8 @@ goto cleanup; }
- /* Query name information */ - pNameInfo = (POBJECT_NAME_INFORMATION)(pffv + 1); - Status = ZwQueryObject(hFile, - ObjectNameInformation, - pNameInfo, - cjInfo, - &cjDesired); - if (!NT_SUCCESS(Status)) goto cleanup; - /* Initialize extended fields */ - pffv->pwszPath = pNameInfo->Name.Buffer; + pffv->pwszPath = (PWSTR)&pffv[1]; pffv->ulRegionSize = 0; pffv->cKRefCount = 0; pffv->cRefCountFD = 0; @@ -294,29 +297,34 @@ else { /* Allocate a FILEVIEW structure */ - pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg'); + cjSize = sizeof(FILEVIEW) + ustrFileName.Length + sizeof(WCHAR); + pFileView = EngAllocMem(0, cjSize, 'liFg'); if (!pFileView) { Status = STATUS_NO_MEMORY; goto cleanup; } + + pFileView->pwszPath = (PWSTR)&pFileView[1]; }
/* Initialize the structure */ + pFileView->cRefs = 1; pFileView->pvKView = NULL; pFileView->pvViewFD = NULL; pFileView->cjView = 0;
+ /* Copy the file name */ + wcscpy(pFileView->pwszPath, pwsz); + /* Query the last write time */ + FileInformation.LastWriteTime.QuadPart = 0; Status = ZwQueryInformationFile(hFile, &IoStatusBlock, &FileInformation, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); - if (NT_SUCCESS(Status)) - { - pFileView->LastWriteTime = FileInformation.LastWriteTime; - } + pFileView->LastWriteTime = FileInformation.LastWriteTime;
/* Create a section from the file */ liSize.QuadPart = cjSizeOfModule; @@ -329,16 +337,22 @@ hFile, NULL);
+ if (!NT_SUCCESS(Status)) + { + EngFreeMem(pFileView); + pFileView = NULL; + goto cleanup; + } + + /* Insert the structure into the list */ + InsertTailList(&gleModulelist, &pFileView->leLink); + cleanup: /* Close the file handle */ - ZwClose(hFile); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create a section Status=0x%x\n", Status); - EngFreeMem(pFileView); - return NULL; - } + if (hFile) ZwClose(hFile); + + /* Release module list lock */ + EngReleaseSemaphore(ghsemModuleList);
return pFileView; } @@ -394,19 +408,36 @@ PFILEVIEW pFileView = (PFILEVIEW)h; NTSTATUS Status;
- /* Unmap the section */ - Status = MmUnmapViewInSessionSpace(pFileView->pvKView); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status); - ASSERT(FALSE); - } - - /* Dereference the section */ - ObDereferenceObject(pFileView->pSection); - - /* Free the file view memory */ - EngFreeMem(pFileView); + /* Acquire module list lock */ + EngAcquireSemaphore(ghsemModuleList); + + /* Decrement reference count and check if its 0 */ + if (--pFileView->cRefs == 0) + { + /* Check if the section was mapped */ + if (pFileView->pvKView) + { + /* Unmap the section */ + Status = MmUnmapViewInSessionSpace(pFileView->pvKView); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status); + ASSERT(FALSE); + } + } + + /* Dereference the section */ + ObDereferenceObject(pFileView->pSection); + + /* Remove the entry from the list */ + RemoveEntryList(&pFileView->leLink); + + /* Free the file view memory */ + EngFreeMem(pFileView); + } + + /* Release module list lock */ + EngReleaseSemaphore(ghsemModuleList); }
PVOID @@ -460,9 +491,28 @@ OUT PULONG *ppjBuf, OUT ULONG *pcjBuf) { - // www.osr.com/ddk/graphics/gdifncs_0co7.htm - UNIMPLEMENTED; - return FALSE; + PFONTFILEVIEW pffv = (PFONTFILEVIEW)iFile; + NTSTATUS Status = STATUS_SUCCESS; + + // should be exclusively accessing this file! + + /* Increment reference count and check if its the 1st */ + if (++pffv->cRefCountFD == 1) + { + /* Map the file into the address space of CSRSS */ + Status = MmMapViewOfSection(pffv->pSection, + gpepCSRSS, + &pffv->pvViewFD, + 0, + 0, + NULL, + &pffv->cjView, + ViewUnmap, + 0, + PAGE_READONLY); + } + + return NT_SUCCESS(Status); }
VOID @@ -470,8 +520,17 @@ EngUnmapFontFileFD( IN ULONG_PTR iFile) { - // http://www.osr.com/ddk/graphics/gdifncs_6wbr.htm - UNIMPLEMENTED; + PFONTFILEVIEW pffv = (PFONTFILEVIEW)iFile; + NTSTATUS Status = STATUS_SUCCESS; + + // should be exclusively accessing this file! + + /* Decrement reference count and check if we reached 0 */ + if (--pffv->cRefCountFD == 0) + { + /* Unmap the file from the address space of CSRSS */ + Status = MmUnmapViewOfSection(gpepCSRSS, pffv->pvViewFD); + } }
BOOL
Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/mapping.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsyste... ============================================================================== --- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/mapping.h [iso-8859-1] (original) +++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/include/mapping.h [iso-8859-1] Sat May 28 15:57:47 2011 @@ -2,6 +2,8 @@ // HACK!!! #define MmMapViewInSessionSpace MmMapViewInSystemSpace #define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace + +extern PEPROCESS gpepCSRSS;
typedef struct _ENGSECTION { @@ -13,6 +15,9 @@
typedef struct _FILEVIEW { + LIST_ENTRY leLink; + PWSTR pwszPath; + ULONG cRefs; LARGE_INTEGER LastWriteTime; PVOID pvKView; PVOID pvViewFD; @@ -23,8 +28,6 @@ typedef struct _FONTFILEVIEW { FILEVIEW; - DWORD reserved[2]; - PWSTR pwszPath; SIZE_T ulRegionSize; ULONG cKRefCount; ULONG cRefCountFD;