https://git.reactos.org/?p=reactos.git;a=commitdiff;h=811faed421a798659af3c…
commit 811faed421a798659af3cb3f09369af84fc4edf0
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Apr 11 11:46:52 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Apr 11 11:46:52 2019 +0900
[GDI32][NTGDI][SETUP] Fix font enumeration part 2 (#1492)
Eliminate some bugs about font enumeration. CORE-15755
- Add "Microsoft Sans Serif" font substitution.
- Fix and improve the treatment of the nominal font names.
- Split IntGetFontFamilyInfo function from NtGdiGetFontFamilyInfo.
- Add DoFontSystemUnittest function for font system unittest to GDI32.
- Call DoFontSystemUnittest function at CreateFontIndirectW first call.
---
base/setup/lib/muifonts.h | 10 +++
boot/bootdata/livecd.inf | 1 +
win32ss/gdi/gdi32/objects/font.c | 140 +++++++++++++++++++++++------
win32ss/gdi/ntgdi/freetype.c | 186 +++++++++++++++++++++++++--------------
win32ss/include/ntgdibad.h | 7 +-
5 files changed, 250 insertions(+), 94 deletions(-)
diff --git a/base/setup/lib/muifonts.h b/base/setup/lib/muifonts.h
index 72292afc466..826d512bdc1 100644
--- a/base/setup/lib/muifonts.h
+++ b/base/setup/lib/muifonts.h
@@ -11,6 +11,7 @@ MUI_SUBFONT LatinFonts[] =
{ L"Helv", L"Tahoma" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Tahoma" },
{ L"MS Sans Serif", L"Tahoma" },
{ L"MS Shell Dlg", L"Tahoma" },
{ L"MS Shell Dlg 2", L"Tahoma" },
@@ -37,6 +38,7 @@ MUI_SUBFONT CyrillicFonts[] =
{ L"Helv", L"Tahoma" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Tahoma" },
{ L"MS Sans Serif", L"Tahoma" },
{ L"MS Shell Dlg", L"Tahoma" },
{ L"MS Shell Dlg 2", L"Tahoma" },
@@ -63,6 +65,7 @@ MUI_SUBFONT GreekFonts[] =
{ L"Helv", L"DejaVu Sans" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"DejaVu Sans" },
{ L"MS Sans Serif", L"DejaVu Sans" },
{ L"MS Shell Dlg", L"DejaVu Sans" },
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
@@ -89,6 +92,7 @@ MUI_SUBFONT HebrewFonts[] =
{ L"Helv", L"Tahoma" },
{ L"Helvetica", L"Tahoma" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Tahoma" },
{ L"MS Sans Serif", L"Tahoma" },
{ L"MS Shell Dlg", L"Tahoma" },
{ L"MS Shell Dlg 2", L"Tahoma" },
@@ -121,6 +125,7 @@ MUI_SUBFONT ChineseSimplifiedFonts[] =
{ L"Helv", L"Droid Sans Fallback" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Droid Sans Fallback" },
{ L"MS Sans Serif", L"Droid Sans Fallback" },
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
@@ -163,6 +168,7 @@ MUI_SUBFONT ChineseTraditionalFonts[] =
{ L"Helv", L"Droid Sans Fallback" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Droid Sans Fallback" },
{ L"MS Sans Serif", L"Droid Sans Fallback" },
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
@@ -206,6 +212,7 @@ MUI_SUBFONT JapaneseFonts[] =
{ L"Helv", L"Droid Sans Fallback" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Droid Sans Fallback" },
{ L"MS Sans Serif", L"Droid Sans Fallback" },
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
@@ -250,6 +257,7 @@ MUI_SUBFONT KoreanFonts[] =
{ L"Helv", L"Droid Sans Fallback" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"Droid Sans Fallback" },
{ L"MS Sans Serif", L"Droid Sans Fallback" },
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
@@ -293,6 +301,7 @@ MUI_SUBFONT UnicodeFonts[] =
{ L"Helv", L"DejaVu Sans" },
{ L"Helvetica", L"DejaVu Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"DejaVu Sans" },
{ L"MS Sans Serif", L"DejaVu Sans" },
{ L"MS Shell Dlg", L"DejaVu Sans" },
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
@@ -320,6 +329,7 @@ MUI_SUBFONT HindiFonts[] =
{ L"Helv", L"Tahoma" },
{ L"Helvetica", L"Liberation Sans" },
{ L"Lucida Console", L"DejaVu Sans Mono" },
+ { L"Microsoft Sans Serif", L"FreeSans" },
{ L"MS Sans Serif", L"FreeSans" },
{ L"MS Shell Dlg", L"FreeSans" },
{ L"MS Shell Dlg 2", L"FreeSans" },
diff --git a/boot/bootdata/livecd.inf b/boot/bootdata/livecd.inf
index fda2356a978..dd44f0ed533 100644
--- a/boot/bootdata/livecd.inf
+++ b/boot/bootdata/livecd.inf
@@ -50,6 +50,7 @@ HKLM,"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontSubstitutes","Fixedsys",0
HKLM,"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontSubstitutes","Helv",0x00000000,"Tahoma"
HKLM,"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontSubstitutes","Helvetica",0x00000000,"Liberation
Sans"
HKLM,"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontSubstitutes","Lucida Console",0x00000000,"DejaVu
Sans Mono"
+HKLM,"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontSubstitutes","Microsoft Sans
Serif",0x00000000,"Tahoma"
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS
Sans Serif",0x00000000,"Tahoma"
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS
Shell Dlg",0x00000000,"Tahoma"
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS
Shell Dlg 2",0x00000000,"Tahoma"
diff --git a/win32ss/gdi/gdi32/objects/font.c b/win32ss/gdi/gdi32/objects/font.c
index 2f187b0edbc..e20c0702fb9 100644
--- a/win32ss/gdi/gdi32/objects/font.c
+++ b/win32ss/gdi/gdi32/objects/font.c
@@ -218,6 +218,13 @@ IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
int cmp = _wcsicmp(plf1->lfFaceName, plf2->lfFaceName);
if (cmp)
return cmp;
+ if (dwCompareFlags & IFFCX_CHARSET)
+ {
+ if (plf1->lfCharSet < plf2->lfCharSet)
+ return -1;
+ if (plf1->lfCharSet > plf2->lfCharSet)
+ return 1;
+ }
if (dwCompareFlags & IFFCX_STYLE)
{
WeightDiff1 = labs(plf1->lfWeight - FW_NORMAL);
@@ -231,13 +238,6 @@ IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
if (plf1->lfItalic > plf2->lfItalic)
return 1;
}
- if (dwCompareFlags & IFFCX_CHARSET)
- {
- if (plf1->lfCharSet < plf2->lfCharSet)
- return -1;
- if (plf1->lfCharSet > plf2->lfCharSet)
- return 1;
- }
return 0;
}
@@ -267,7 +267,7 @@ IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
first = InfoList;
last = &InfoList[nCount];
- // std::unique(first, last, IntFontFamilyCompareEx);
+ /* std::unique(first, last, IntFontFamilyCompareEx); */
if (first == last)
return 0;
@@ -285,60 +285,70 @@ IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
}
static int FASTCALL
-IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
+IntEnumFontFamilies(HDC Dc, const LOGFONTW *LogFont, PVOID EnumProc, LPARAM lParam,
DWORD dwFlags)
{
int FontFamilyCount;
- int FontFamilySize;
PFONTFAMILYINFO Info;
int Ret = 1;
int i;
ENUMLOGFONTEXA EnumLogFontExA;
NEWTEXTMETRICEXA NewTextMetricExA;
LOGFONTW lfW;
+ LONG DataSize, InfoCount;
- Info = RtlAllocateHeap(GetProcessHeap(), 0,
- INITIAL_FAMILY_COUNT * sizeof(FONTFAMILYINFO));
- if (NULL == Info)
+ DataSize = INITIAL_FAMILY_COUNT * sizeof(FONTFAMILYINFO);
+ Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
+ if (Info == NULL)
{
return 1;
}
+ /* Initialize the LOGFONT structure */
+ ZeroMemory(&lfW, sizeof(lfW));
if (!LogFont)
{
lfW.lfCharSet = DEFAULT_CHARSET;
- lfW.lfPitchAndFamily = 0;
- lfW.lfFaceName[0] = 0;
- LogFont = &lfW;
+ }
+ else
+ {
+ lfW.lfCharSet = LogFont->lfCharSet;
+ lfW.lfPitchAndFamily = LogFont->lfPitchAndFamily;
+ StringCbCopyW(lfW.lfFaceName, sizeof(lfW.lfFaceName), LogFont->lfFaceName);
}
- FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, LogFont, Info, INITIAL_FAMILY_COUNT);
+ /* Retrieve the font information */
+ InfoCount = INITIAL_FAMILY_COUNT;
+ FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, &lfW, Info, &InfoCount);
if (FontFamilyCount < 0)
{
RtlFreeHeap(GetProcessHeap(), 0, Info);
return 1;
}
- if (INITIAL_FAMILY_COUNT < FontFamilyCount)
+
+ /* Resize the buffer if the buffer is too small */
+ if (INITIAL_FAMILY_COUNT < InfoCount)
{
- FontFamilySize = FontFamilyCount;
RtlFreeHeap(GetProcessHeap(), 0, Info);
- Info = RtlAllocateHeap(GetProcessHeap(), 0,
- FontFamilyCount * sizeof(FONTFAMILYINFO));
- if (NULL == Info)
+ DataSize = InfoCount * sizeof(FONTFAMILYINFO);
+ Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
+ if (Info == NULL)
{
return 1;
}
- FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, LogFont, Info, FontFamilySize);
- if (FontFamilyCount < 0 || FontFamilySize < FontFamilyCount)
+ FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, &lfW, Info, &InfoCount);
+ if (FontFamilyCount < 0 || FontFamilyCount < InfoCount)
{
RtlFreeHeap(GetProcessHeap(), 0, Info);
return 1;
}
}
+ /* Sort and remove redundant information */
qsort(Info, FontFamilyCount, sizeof(*Info), IntFontFamilyCompare);
- FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, LogFont, dwFlags);
+ FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, &lfW, dwFlags);
+ /* call the callback */
for (i = 0; i < FontFamilyCount; i++)
{
if (dwFlags & IEFF_UNICODE)
@@ -1693,6 +1703,78 @@ CreateFontIndirectA(
}
+#if DBG
+VOID DumpFamilyInfo(const FONTFAMILYINFO *Info, LONG Count)
+{
+ LONG i;
+ const LOGFONTW *plf;
+
+ DPRINT1("---\n");
+ DPRINT1("Count: %d\n", Count);
+ for (i = 0; i < Count; ++i)
+ {
+ plf = &Info[i].EnumLogFontEx.elfLogFont;
+ DPRINT1("%d: '%S',%u,'%S', %ld:%ld, %ld, %d, %d\n", i,
+ plf->lfFaceName, plf->lfCharSet, Info[i].EnumLogFontEx.elfFullName,
+ plf->lfHeight, plf->lfWidth, plf->lfWeight, plf->lfItalic,
plf->lfPitchAndFamily);
+ }
+}
+
+VOID DoFontSystemUnittest(VOID)
+{
+ LOGFONTW LogFont;
+ FONTFAMILYINFO Info[4];
+ UNICODE_STRING Str1, Str2;
+ LONG ret, InfoCount;
+
+ //DumpFontInfo(TRUE);
+
+ /* L"" DEFAULT_CHARSET */
+ RtlZeroMemory(&LogFont, sizeof(LogFont));
+ LogFont.lfCharSet = DEFAULT_CHARSET;
+ InfoCount = RTL_NUMBER_OF(Info);
+ ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
+ DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
+ DumpFamilyInfo(Info, ret);
+ ASSERT(ret == RTL_NUMBER_OF(Info));
+ ASSERT(InfoCount > 32);
+
+ /* L"Microsoft Sans Serif" ANSI_CHARSET */
+ RtlZeroMemory(&LogFont, sizeof(LogFont));
+ LogFont.lfCharSet = ANSI_CHARSET;
+ StringCbCopyW(LogFont.lfFaceName, sizeof(LogFont.lfFaceName), L"Microsoft Sans
Serif");
+ InfoCount = RTL_NUMBER_OF(Info);
+ ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
+ DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
+ DumpFamilyInfo(Info, ret);
+ ASSERT(ret != -1);
+ ASSERT(InfoCount > 0);
+ ASSERT(InfoCount < 16);
+
+ RtlInitUnicodeString(&Str1, Info[0].EnumLogFontEx.elfLogFont.lfFaceName);
+ RtlInitUnicodeString(&Str2, L"Microsoft Sans Serif");
+ ret = RtlCompareUnicodeString(&Str1, &Str2, TRUE);
+ ASSERT(ret == 0);
+
+ RtlInitUnicodeString(&Str1, Info[0].EnumLogFontEx.elfFullName);
+ RtlInitUnicodeString(&Str2, L"Tahoma");
+ ret = RtlCompareUnicodeString(&Str1, &Str2, TRUE);
+ ASSERT(ret == 0);
+
+ /* L"Non-Existent" DEFAULT_CHARSET */
+ RtlZeroMemory(&LogFont, sizeof(LogFont));
+ LogFont.lfCharSet = ANSI_CHARSET;
+ StringCbCopyW(LogFont.lfFaceName, sizeof(LogFont.lfFaceName),
L"Non-Existent");
+ InfoCount = RTL_NUMBER_OF(Info);
+ ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
+ DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
+ DumpFamilyInfo(Info, ret);
+ ASSERT(ret == 0);
+ ASSERT(InfoCount == 0);
+}
+#endif
+
+/* EOF */
/*
* @implemented
*/
@@ -1702,6 +1784,14 @@ CreateFontIndirectW(
CONST LOGFONTW *lplf
)
{
+#if DBG
+ static BOOL bDidTest = FALSE;
+ if (!bDidTest)
+ {
+ DoFontSystemUnittest();
+ bDidTest = TRUE;
+ }
+#endif
if (lplf)
{
ENUMLOGFONTEXDVW Logfont;
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c
index a5f93e92c8f..298c1fa12ca 100644
--- a/win32ss/gdi/ntgdi/freetype.c
+++ b/win32ss/gdi/ntgdi/freetype.c
@@ -2675,18 +2675,18 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
}
static BOOLEAN FASTCALL
-GetFontFamilyInfoForList(LPLOGFONTW LogFont,
+GetFontFamilyInfoForList(const LOGFONTW *LogFont,
PFONTFAMILYINFO Info,
LPCWSTR NominalName,
- DWORD *pCount,
- DWORD MaxCount,
+ LONG *pCount,
+ LONG MaxCount,
PLIST_ENTRY Head)
{
PLIST_ENTRY Entry;
PFONT_ENTRY CurrentEntry;
FONTGDI *FontGDI;
FONTFAMILYINFO InfoEntry;
- DWORD Count = *pCount;
+ LONG Count = *pCount;
for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
{
@@ -2697,29 +2697,15 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
if (LogFont->lfCharSet != DEFAULT_CHARSET &&
LogFont->lfCharSet != FontGDI->CharSet)
{
- continue;
- }
-
- if (LogFont->lfFaceName[0] == UNICODE_NULL)
- {
- if (Count < MaxCount)
- {
- FontFamilyFillInfo(&Info[Count], NominalName, NULL, FontGDI);
- }
- Count++;
- continue;
+ continue; /* charset mismatch */
}
- FontFamilyFillInfo(&InfoEntry, NominalName, NULL, FontGDI);
+ /* get one info entry */
+ FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI);
- if (NominalName)
- {
- RtlStringCchCopyW(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
-
RTL_NUMBER_OF(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
- NominalName);
- }
- else
+ if (LogFont->lfFaceName[0] != UNICODE_NULL)
{
+ /* check name */
if (_wcsnicmp(LogFont->lfFaceName,
InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
@@ -2731,7 +2717,16 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
}
}
- if (Count < MaxCount)
+ if (NominalName)
+ {
+ /* store the nominal name */
+ RtlStringCbCopyW(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
+ sizeof(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
+ NominalName);
+ }
+
+ /* store one entry to Info */
+ if (0 <= Count && Count < MaxCount)
{
RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
}
@@ -2744,10 +2739,10 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
}
static BOOLEAN FASTCALL
-GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
+GetFontFamilyInfoForSubstitutes(const LOGFONTW *LogFont,
PFONTFAMILYINFO Info,
- DWORD *pCount,
- DWORD MaxCount)
+ LONG *pCount,
+ LONG MaxCount)
{
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
PFONTSUBST_ENTRY pCurrentEntry;
@@ -2762,6 +2757,7 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
if (LogFont->lfFaceName[0] != UNICODE_NULL)
{
+ /* check name */
if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
continue; /* mismatch */
}
@@ -2771,18 +2767,22 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
pCurrentEntry->CharSets[FONTSUBST_FROM] ==
pCurrentEntry->CharSets[FONTSUBST_TO])
{
+ /* identical mapping */
continue;
}
+ /* substitute and get the real name */
IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
SubstituteFontRecurse(&lf);
if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet !=
lf.lfCharSet)
continue;
+ /* search in global fonts */
IntLockGlobalFonts();
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
&g_FontListHead);
IntUnLockGlobalFonts();
+ /* search in private fonts */
IntLockProcessPrivateFonts(Win32Process);
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
&Win32Process->PrivateFontListHead);
@@ -5407,70 +5407,126 @@ ftGdiGetKerningPairs( PFONTGDI Font,
// Functions needing sorting.
//
///////////////////////////////////////////////////////////////////////////
-int APIENTRY
+
+LONG FASTCALL
+IntGetFontFamilyInfo(HDC Dc,
+ const LOGFONTW *SafeLogFont,
+ PFONTFAMILYINFO SafeInfo,
+ LONG InfoCount)
+{
+ LONG AvailCount = 0;
+ PPROCESSINFO Win32Process;
+
+ /* Enumerate font families in the global list */
+ IntLockGlobalFonts();
+ if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
+ InfoCount, &g_FontListHead))
+ {
+ IntUnLockGlobalFonts();
+ return -1;
+ }
+ IntUnLockGlobalFonts();
+
+ /* Enumerate font families in the process local list */
+ Win32Process = PsGetCurrentProcessWin32Process();
+ IntLockProcessPrivateFonts(Win32Process);
+ if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
InfoCount,
+ &Win32Process->PrivateFontListHead))
+ {
+ IntUnLockProcessPrivateFonts(Win32Process);
+ return -1;
+ }
+ IntUnLockProcessPrivateFonts(Win32Process);
+
+ /* Enumerate font families in the registry */
+ if (!GetFontFamilyInfoForSubstitutes(SafeLogFont, SafeInfo, &AvailCount,
InfoCount))
+ {
+ return -1;
+ }
+
+ return AvailCount;
+}
+
+LONG NTAPI
NtGdiGetFontFamilyInfo(HDC Dc,
- LPLOGFONTW UnsafeLogFont,
+ const LOGFONTW *UnsafeLogFont,
PFONTFAMILYINFO UnsafeInfo,
- DWORD Size)
+ LPLONG UnsafeInfoCount)
{
NTSTATUS Status;
LOGFONTW LogFont;
PFONTFAMILYINFO Info;
- DWORD Count;
- PPROCESSINFO Win32Process;
+ LONG GotCount, AvailCount, DataSize, SafeInfoCount;
- /* Make a safe copy */
- Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
- if (! NT_SUCCESS(Status))
+ if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
- /* Allocate space for a safe copy */
- Info = ExAllocatePoolWithTag(PagedPool, Size * sizeof(FONTFAMILYINFO), GDITAG_TEXT);
- if (NULL == Info)
+ Status = MmCopyFromCaller(&SafeInfoCount, UnsafeInfoCount,
sizeof(SafeInfoCount));
+ if (!NT_SUCCESS(Status))
{
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
-
- /* Enumerate font families in the global list */
- IntLockGlobalFonts();
- Count = 0;
- if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
&g_FontListHead) )
+ GotCount = 0;
+ Status = MmCopyToCaller(UnsafeInfoCount, &GotCount, sizeof(*UnsafeInfoCount));
+ if (!NT_SUCCESS(Status))
{
- IntUnLockGlobalFonts();
- ExFreePoolWithTag(Info, GDITAG_TEXT);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
- IntUnLockGlobalFonts();
-
- /* Enumerate font families in the process local list */
- Win32Process = PsGetCurrentProcessWin32Process();
- IntLockProcessPrivateFonts(Win32Process);
- if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
- &Win32Process->PrivateFontListHead))
+ Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
+ if (!NT_SUCCESS(Status))
{
- IntUnLockProcessPrivateFonts(Win32Process);
- ExFreePoolWithTag(Info, GDITAG_TEXT);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ if (SafeInfoCount <= 0)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
- IntUnLockProcessPrivateFonts(Win32Process);
- /* Enumerate font families in the registry */
- if (! GetFontFamilyInfoForSubstitutes(&LogFont, Info, &Count, Size))
+ /* Allocate space for a safe copy */
+ DataSize = SafeInfoCount * sizeof(FONTFAMILYINFO);
+ if (DataSize <= 0)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ Info = ExAllocatePoolWithTag(PagedPool, DataSize, GDITAG_TEXT);
+ if (Info == NULL)
{
- ExFreePoolWithTag(Info, GDITAG_TEXT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return -1;
}
+ /* Retrieve the information */
+ AvailCount = IntGetFontFamilyInfo(Dc, &LogFont, Info, SafeInfoCount);
+ GotCount = min(AvailCount, SafeInfoCount);
+ SafeInfoCount = AvailCount;
+
/* Return data to caller */
- if (0 != Count)
+ if (GotCount > 0)
{
- Status = MmCopyToCaller(UnsafeInfo, Info,
- (Count < Size ? Count : Size) *
sizeof(FONTFAMILYINFO));
- if (! NT_SUCCESS(Status))
+ DataSize = GotCount * sizeof(FONTFAMILYINFO);
+ if (DataSize <= 0)
+ {
+ ExFreePoolWithTag(Info, GDITAG_TEXT);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ Status = MmCopyToCaller(UnsafeInfo, Info, DataSize);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Info, GDITAG_TEXT);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ Status = MmCopyToCaller(UnsafeInfoCount, &SafeInfoCount,
sizeof(*UnsafeInfoCount));
+ if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(Info, GDITAG_TEXT);
EngSetLastError(ERROR_INVALID_PARAMETER);
@@ -5480,7 +5536,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
ExFreePoolWithTag(Info, GDITAG_TEXT);
- return Count;
+ return GotCount;
}
FORCEINLINE
@@ -6618,7 +6674,7 @@ NtGdiGetCharABCWidthsW(
if(Safepwch)
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
- if (! NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
diff --git a/win32ss/include/ntgdibad.h b/win32ss/include/ntgdibad.h
index ba8588f2f96..58d644e68e9 100644
--- a/win32ss/include/ntgdibad.h
+++ b/win32ss/include/ntgdibad.h
@@ -50,14 +50,13 @@ typedef struct tagFONTFAMILYINFO
} FONTFAMILYINFO, *PFONTFAMILYINFO;
/* Should be using NtGdiEnumFontChunk */
-INT
+LONG
NTAPI
NtGdiGetFontFamilyInfo(
HDC Dc,
- LPLOGFONTW LogFont,
+ const LOGFONTW *LogFont,
PFONTFAMILYINFO Info,
- DWORD Size
-);
+ LPLONG UnsafeInfoCount);
/* Use NtGdiGetDCPoint with GdiGetViewPortExt */
BOOL APIENTRY NtGdiGetViewportExtEx(HDC hDC, LPSIZE viewportExt);