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/subsyst…
==============================================================================
--- 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/subsyst…
==============================================================================
--- 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;