[GDI32][WIN32K:NTGDI]
authorThomas Faber <thomas.faber@reactos.org>
Wed, 22 Apr 2015 20:24:29 +0000 (20:24 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Wed, 22 Apr 2015 20:24:29 +0000 (20:24 +0000)
- 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

reactos/win32ss/gdi/gdi32/objects/font.c
reactos/win32ss/gdi/ntgdi/font.c

index 4225005..25cab29 100644 (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;
 }
 
 /*
index 825a280..2543e82 100644 (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);
-
-  src = SafeFileName.Buffer;
-  SafeFileName.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, SafeFileName.MaximumLength, TAG_STRING);
-  if(!SafeFileName.Buffer)
-  {
-    EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-    return 0;
-  }
+    /* cwc = Length + trailing zero. */
+    if (cwc <= 1 || cwc > UNICODE_STRING_MAX_CHARS)
+        return 0;
 
-  /* Prepend '\??\' */
-  RtlCopyMemory(SafeFileName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
+    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;
+    }
 
-  Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
-  if(!NT_SUCCESS(Status))
-  {
-    ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
-    SetLastNtError(Status);
-    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;
 
-  Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
+    SafeFileName.Buffer[SafeFileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+    Ret = IntGdiAddFontResource(&SafeFileName, fl);
 
-  ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
-  return Ret;
+    ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
+    return Ret;
 }
 
  /*