From c77aba633cc4b31c911c02ae2de92e19f2568bf8 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 6 Jun 2007 11:00:53 +0000 Subject: [PATCH] - IntGdiAddFontResource: Add the filename to the font entry - implement NtGdiGetFontResourceInfoInternalW and add it to the syscall table svn path=/trunk/; revision=27022 --- .../subsystems/win32/win32k/include/text.h | 2 + .../subsystems/win32/win32k/objects/text.c | 250 +++++++++++++++++- reactos/tools/nci/w32ksvc.db | 2 +- 3 files changed, 251 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/text.h b/reactos/subsystems/win32/win32k/include/text.h index a0e676c80ec..315dbf53a70 100644 --- a/reactos/subsystems/win32/win32k/include/text.h +++ b/reactos/subsystems/win32/win32k/include/text.h @@ -1,6 +1,8 @@ #ifndef _WIN32K_TEXT_H #define _WIN32K_TEXT_H +#define TAG_FINF TAG('F', 'I', 'N', 'F') + /* GDI logical font object */ typedef struct { diff --git a/reactos/subsystems/win32/win32k/objects/text.c b/reactos/subsystems/win32/win32k/objects/text.c index 215257e652c..e11668de799 100644 --- a/reactos/subsystems/win32/win32k/objects/text.c +++ b/reactos/subsystems/win32/win32k/objects/text.c @@ -285,7 +285,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) PSECTION_OBJECT SectionObject; ULONG ViewSize = 0; FT_Fixed XScale, YScale; - + UNICODE_STRING FileNameCopy; /* Open the font file */ @@ -361,7 +361,8 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) return 0; } - /* FontGDI->Filename = FileName; perform strcpy */ + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, FileName, &FileNameCopy); + FontGDI->Filename = FileNameCopy.Buffer; FontGDI->face = Face; /* FIXME: Complete text metrics */ @@ -4159,4 +4160,249 @@ NtGdiGetSetTextCharExtra( HDC hDC, INT CharExtra, BOOL Set) return (Ret); } +static BOOL FASTCALL +IntGetFullFileName( + POBJECT_NAME_INFORMATION NameInfo, + ULONG Size, + PUNICODE_STRING FileName) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hFile; + IO_STATUS_BLOCK IoStatusBlock; + ULONG Desired; + + InitializeObjectAttributes(&ObjectAttributes, + FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = ZwOpenFile( + &hFile, + 0, //FILE_READ_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0); + + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenFile() failed (Status = 0x%lx)\n", Status); + return FALSE; + } + + Status = ZwQueryObject(hFile, ObjectNameInformation, NameInfo, Size, &Desired); + ZwClose(hFile); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryObject() failed (Status = %lx)\n", Status); + return FALSE; + } + + return TRUE; +} + +static BOOL FASTCALL +IntGdiGetFontResourceInfo( + IN PUNICODE_STRING FileName, + OUT void *pBuffer, + OUT DWORD *pdwBytes, + IN DWORD dwType) +{ + UNICODE_STRING EntryFileName; + POBJECT_NAME_INFORMATION NameInfo1, NameInfo2; + PLIST_ENTRY ListEntry; + PFONT_ENTRY FontEntry; + FONTFAMILYINFO Info; + ULONG Size; + BOOL bFound = FALSE; + + /* Create buffer for full path name */ + Size = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR); + NameInfo1 = ExAllocatePoolWithTag(PagedPool, Size, TAG_FINF); + if (!NameInfo1) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* Get the full path name */ + if (!IntGetFullFileName(NameInfo1, Size, FileName)) + { + ExFreePool(NameInfo1); + return FALSE; + } + + /* Create a buffer for the entries' names */ + NameInfo2 = ExAllocatePoolWithTag(PagedPool, Size, TAG_FINF); + if (!NameInfo2) + { + ExFreePool(NameInfo1); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* Try to find the pathname in the global font list */ + IntLockGlobalFonts; + for (ListEntry = FontListHead.Flink; + ListEntry != &FontListHead; + ListEntry = ListEntry->Flink) + { + FontEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY, ListEntry); + if (FontEntry->Font->Filename != NULL) + { + RtlInitUnicodeString(&EntryFileName , FontEntry->Font->Filename); + if (IntGetFullFileName(NameInfo2, Size, &EntryFileName)) + { + if (RtlEqualUnicodeString(&NameInfo1->Name, &NameInfo2->Name, FALSE)) + { + /* found */ + FontFamilyFillInfo(&Info, FontEntry->FaceName.Buffer, FontEntry->Font); + bFound = TRUE; + break; + } + } + } + } + IntUnLockGlobalFonts; + + /* Free the buffers */ + ExFreePool(NameInfo1); + ExFreePool(NameInfo2); + + if (!bFound && dwType != 5) + { + /* Font could not be found in system table + dwType == 5 will still handle this */ + return FALSE; + } + + switch(dwType) + { + case 0: /* FIXME: returns 1 or 2, don't know what this is atm */ + *(DWORD*)pBuffer = 1; + *pdwBytes = sizeof(DWORD); + break; + + case 1: /* Copy the full font name */ + Size = wcslen(Info.EnumLogFontEx.elfFullName) + 1; + Size = min(Size , LF_FULLFACESIZE) * sizeof(WCHAR); + memcpy(pBuffer, Info.EnumLogFontEx.elfFullName, Size); + // FIXME: Do we have to zeroterminate? + *pdwBytes = Size; + break; + + case 2: /* Copy a LOGFONTW structure */ + memcpy(pBuffer, &Info.EnumLogFontEx.elfLogFont, sizeof(LOGFONTW)); + *pdwBytes = sizeof(LOGFONTW); + break; + + case 3: /* FIXME: What exactly is copied here? */ + *(DWORD*)pBuffer = 1; + *pdwBytes = sizeof(DWORD*); + break; + + case 5: /* Looks like a BOOL that is copied, TRUE, if the font was not found */ + *(BOOL*)pBuffer = !bFound; + *pdwBytes = sizeof(BOOL); + break; + + default: + return FALSE; + } + + return TRUE; +} + +W32KAPI BOOL APIENTRY +NtGdiGetFontResourceInfoInternalW( + IN LPWSTR pwszFiles, + IN ULONG cwc, + IN ULONG cFiles, + IN UINT cjIn, + OUT LPDWORD pdwBytes, + OUT LPVOID pvBuf, + IN DWORD dwType) +{ + NTSTATUS Status = STATUS_SUCCESS; + DWORD dwBytes; + UNICODE_STRING SafeFileNames; + BOOL bRet = FALSE; + + union + { + LOGFONTW logfontw; + WCHAR FullName[LF_FULLFACESIZE]; + } Buffer; + + /* FIXME: handle cFiles > 0 */ + + /* Check for valid dwType values + dwType == 4 seems to be handled by gdi32 only */ + if (dwType == 4 || dwType > 5) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* Check buffers and copy pwszFiles */ + _SEH_TRY + { + ProbeForRead(pwszFiles, cwc * sizeof(WCHAR), 1); + bRet = RtlCreateUnicodeString(&SafeFileNames, pwszFiles); + ProbeForWrite(pdwBytes, sizeof(DWORD), 1); + ProbeForWrite(pvBuf, cjIn, 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END + + if(!bRet) + { + /* Could not create the unicode string, so return instantly */ + return FALSE; + } + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + /* Free the string for the filename */ + RtlFreeUnicodeString(&SafeFileNames); + return FALSE; + } + + bRet = IntGdiGetFontResourceInfo(&SafeFileNames, &Buffer, &dwBytes, dwType); + + /* Check if succeeded and the buffer is big enough */ + if (bRet && cjIn >= dwBytes) + { + /* Copy the data back to caller */ + _SEH_TRY + { + /* Buffers are already probed */ + RtlCopyMemory(pvBuf, &Buffer, dwBytes); + *pdwBytes = dwBytes; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + bRet = FALSE; + } + } + + /* Free the string for the filename */ + RtlFreeUnicodeString(&SafeFileNames); + + return bRet; +} + /* EOF */ diff --git a/reactos/tools/nci/w32ksvc.db b/reactos/tools/nci/w32ksvc.db index 291c24f75f9..755c042ba02 100644 --- a/reactos/tools/nci/w32ksvc.db +++ b/reactos/tools/nci/w32ksvc.db @@ -121,7 +121,7 @@ NtGdiGetEnhMetaFilePixelFormat 3 NtGdiGetFontData 5 NtGdiGetFontFamilyInfo 4 NtGdiGetFontLanguageInfo 1 -#NtGdiGetFontResourceInfo ? +NtGdiGetFontResourceInfoInternalW 7 NtGdiGetGlyphOutline 8 #NtGdiGetGlyphOutlineWow ? NtGdiGetGraphicsMode 1