Author: tfaber Date: Wed Apr 22 20:24:29 2015 New Revision: 67353
URL: http://svn.reactos.org/svn/reactos?rev=67353&view=rev Log: [GDI32][WIN32K:NTGDI] - Correctly handle relative paths passed to AddFontResource*. - Fix the user->kernel interface between GdiAddFontResourceW and NtGdiAddFontResourceW Patch by Víctor Martínez Calvo. CORE-9079
Modified: trunk/reactos/win32ss/gdi/gdi32/objects/font.c trunk/reactos/win32ss/gdi/ntgdi/font.c
Modified: trunk/reactos/win32ss/gdi/gdi32/objects/font.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/gdi32/objects/f... ============================================================================== --- trunk/reactos/win32ss/gdi/gdi32/objects/font.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/gdi32/objects/font.c [iso-8859-1] Wed Apr 22 20:24:29 2015 @@ -10,6 +10,7 @@ #include <precomp.h>
#include <math.h> +#include <strsafe.h>
#define NDEBUG #include <debug.h> @@ -2181,7 +2182,7 @@ }
/* - * @unimplemented + * @implemented */ int WINAPI @@ -2190,7 +2191,45 @@ FLONG fl, DESIGNVECTOR *pdv) { - return NtGdiAddFontResourceW((PWSTR)lpszFilename, 0, 0, fl, 0, pdv); + INT Ret; + WCHAR lpszBuffer[MAX_PATH]; + WCHAR lpszAbsPath[MAX_PATH]; + UNICODE_STRING NtAbsPath; + + /* FIXME: We don't support multiple files passed in lpszFilename + * as L"abcxxxxx.pfm|abcxxxxx.pfb" + */ + + /* Does the file exist in CurrentDirectory or in the Absolute Path passed? */ + GetCurrentDirectoryW(MAX_PATH, lpszBuffer); + + if (!SearchPathW(lpszBuffer, lpszFilename, NULL, MAX_PATH, lpszAbsPath, NULL)) + { + /* Nope. Then let's check Fonts folder */ + GetWindowsDirectoryW(lpszBuffer, MAX_PATH); + StringCbCatW(lpszBuffer, sizeof(lpszBuffer), L"\Fonts"); + + if (!SearchPathW(lpszBuffer, lpszFilename, NULL, MAX_PATH, lpszAbsPath, NULL)) + { + DPRINT1("Font not found. The Buffer is: %ls, the FileName is: %S", lpszBuffer, lpszFilename); + return 0; + } + } + + /* We found the font file so: */ + if (!RtlDosPathNameToNtPathName_U(lpszAbsPath, &NtAbsPath, NULL, NULL)) + { + DPRINT1("Can't convert Path! Path: %ls\n", lpszAbsPath); + return 0; + } + + /* The Nt call expects a null-terminator included in cwc param. */ + ASSERT(NtAbsPath.Buffer[NtAbsPath.Length / sizeof(WCHAR)] == UNICODE_NULL); + Ret = NtGdiAddFontResourceW(NtAbsPath.Buffer, NtAbsPath.Length / sizeof(WCHAR) + 1, 1, fl, 0, pdv); + + RtlFreeUnicodeString(&NtAbsPath); + + return Ret; }
/*
Modified: trunk/reactos/win32ss/gdi/ntgdi/font.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/font.c?re... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/font.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/font.c [iso-8859-1] Wed Apr 22 20:24:29 2015 @@ -427,48 +427,51 @@ INT APIENTRY NtGdiAddFontResourceW( - IN WCHAR *pwszFiles, + IN WCHAR *pwcFiles, IN ULONG cwc, IN ULONG cFiles, IN FLONG fl, IN DWORD dwPidTid, IN OPTIONAL DESIGNVECTOR *pdv) { - UNICODE_STRING SafeFileName; - PWSTR src; - NTSTATUS Status; - int Ret; - - /* FIXME: Protect with SEH? */ - RtlInitUnicodeString(&SafeFileName, pwszFiles); - - /* Reserve for prepending '??' */ - SafeFileName.Length += 4 * sizeof(WCHAR); - SafeFileName.MaximumLength += 4 * sizeof(WCHAR); - - src = SafeFileName.Buffer; - SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING); - if(!SafeFileName.Buffer) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - /* Prepend '??' */ - RtlCopyMemory(SafeFileName.Buffer, L"\??\", 4 * sizeof(WCHAR)); - - Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR))); - if(!NT_SUCCESS(Status)) - { + UNICODE_STRING SafeFileName; + INT Ret; + + DBG_UNREFERENCED_PARAMETER(cFiles); + DBG_UNREFERENCED_PARAMETER(dwPidTid); + DBG_UNREFERENCED_PARAMETER(pdv); + + /* cwc = Length + trailing zero. */ + if (cwc <= 1 || cwc > UNICODE_STRING_MAX_CHARS) + return 0; + + SafeFileName.MaximumLength = cwc * sizeof(WCHAR); + SafeFileName.Length = SafeFileName.MaximumLength - sizeof(UNICODE_NULL); + SafeFileName.Buffer = ExAllocatePoolWithTag(PagedPool, + SafeFileName.MaximumLength, + TAG_STRING); + if (!SafeFileName.Buffer) + { + return 0; + } + + _SEH2_TRY + { + ProbeForRead(pwcFiles, cwc * sizeof(WCHAR), sizeof(WCHAR)); + RtlCopyMemory(SafeFileName.Buffer, pwcFiles, SafeFileName.Length); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING); + _SEH2_YIELD(return 0); + } + _SEH2_END; + + SafeFileName.Buffer[SafeFileName.Length / sizeof(WCHAR)] = UNICODE_NULL; + Ret = IntGdiAddFontResource(&SafeFileName, fl); + ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING); - SetLastNtError(Status); - return 0; - } - - Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl); - - ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING); - return Ret; + return Ret; }
/*