[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

svn path=/trunk/; revision=67353
This commit is contained in:
Thomas Faber 2015-04-22 20:24:29 +00:00
parent 0d91854d88
commit a6840dcddd
2 changed files with 74 additions and 32 deletions

View file

@ -10,6 +10,7 @@
#include <precomp.h>
#include <math.h>
#include <strsafe.h>
#define NDEBUG
#include <debug.h>
@ -2181,7 +2182,7 @@ NewEnumFontFamiliesExW(
}
/*
* @unimplemented
* @implemented
*/
int
WINAPI
@ -2190,7 +2191,45 @@ GdiAddFontResourceW(
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;
}
/*

View file

@ -427,48 +427,51 @@ RealizeFontInit(HFONT hFont)
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;
UNICODE_STRING SafeFileName;
INT Ret;
/* FIXME: Protect with SEH? */
RtlInitUnicodeString(&SafeFileName, pwszFiles);
DBG_UNREFERENCED_PARAMETER(cFiles);
DBG_UNREFERENCED_PARAMETER(dwPidTid);
DBG_UNREFERENCED_PARAMETER(pdv);
/* Reserve for prepending '\??\' */
SafeFileName.Length += 4 * sizeof(WCHAR);
SafeFileName.MaximumLength += 4 * sizeof(WCHAR);
/* cwc = Length + trailing zero. */
if (cwc <= 1 || cwc > UNICODE_STRING_MAX_CHARS)
return 0;
src = SafeFileName.Buffer;
SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING);
if(!SafeFileName.Buffer)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
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;
}
/* Prepend '\??\' */
RtlCopyMemory(SafeFileName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
_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);
Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
if(!NT_SUCCESS(Status))
{
ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
SetLastNtError(Status);
return 0;
}
Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
return Ret;
return Ret;
}
/*