[WIN32SS:NTGDI] Allow calling NtGdiCreateHalftonePalette with a NULL hDC (#9217)

CORE-20231

Tests show this is allowed on Windows and even Wine. Also, official MS
Windows SDK headers indicate that the `CreateHalftonePalette()` `hDC`
parameter is optional, and so can be NULL.

Not allowing a NULL `hDC` caused compatibility issues, breaking applications
like Internet Explorer 8.0 and Microsoft Encarta.

Make `NtGdiCreateHalftonePalette()` accept a NULL `hDC`, fixing its crash
in this case, and only locking it when it's not NULL. Simplify also the
function execution path.

Co-authored-by: Simone Mario Lombardo <[email protected]>
This commit is contained in:
Mohammad Amin Mollazadeh
2026-07-02 20:19:33 +02:00
committed by Hermès BÉLUSCA - MAÏTO
co-authored by Simone Mario Lombardo
parent 3e78f9a735
commit 6d8a5fa0bb
+27 -18
View File
@@ -531,13 +531,7 @@ NtGdiCreateHalftonePalette(HDC hDC)
PPALETTE ppal;
PDC pdc;
HPALETTE hpal = NULL;
pdc = DC_LockDc(hDC);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
BOOL UseDefaultPalette = TRUE;
RtlZeroMemory(PalEntries, sizeof(PalEntries));
@@ -553,13 +547,33 @@ NtGdiCreateHalftonePalette(HDC hDC)
PalEntries[246 + i].peBlue = g_sysPalTemplate[10 + i].peBlue;
}
ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
if (ppal && (ppal->flFlags & PAL_INDEXED))
if (hDC)
{
/* FIXME: optimize the palette for the current palette */
UNIMPLEMENTED;
pdc = DC_LockDc(hDC);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
if (ppal)
{
if (ppal->flFlags & PAL_INDEXED)
{
UseDefaultPalette = FALSE;
/* FIXME: optimize the palette for the current palette */
UNIMPLEMENTED;
}
PALETTE_ShareUnlockPalette(ppal);
}
DC_UnlockDc(pdc);
}
else
if (UseDefaultPalette)
{
for (r = 0; r < 6; r++)
{
@@ -584,11 +598,6 @@ NtGdiCreateHalftonePalette(HDC hDC)
}
}
if (ppal)
PALETTE_ShareUnlockPalette(ppal);
DC_UnlockDc(pdc);
ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, 256, PalEntries, 0, 0, 0);
if (ppal)
{
@@ -778,7 +787,7 @@ IntGdiRealizePalette(HDC hDC)
ASSERT(ppalDC->flFlags & PAL_INDEXED);
DPRINT1("RealizePalette unimplemented for %s\n",
DPRINT1("RealizePalette unimplemented for %s\n",
(pdc->dctype == DCTYPE_MEMORY ? "memory managed DCs" : "device DCs"));
cleanup: