[NTGDI] Minimal pass of fixing ExtEscape (#8536)

* [WIN32SS] Minimal pass of fixing ExtEscape
Resolves issues with the AMD/ATI GPU Driver and the Intel OpenGL ICD when used in fullscreen mode.

Co-authored-by: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
This commit is contained in:
Justin Miller
2026-01-20 09:56:03 -08:00
committed by GitHub
parent 49f633517f
commit 108db5b356

View File

@@ -94,6 +94,13 @@ NtGdiExtEscape(
PPDEVOBJ ppdev;
PSURFACE psurf;
/* Validate input parameters */
if ((InSize < 0) || (OutSize < 0) || (UnsafeInData == NULL && InSize != 0))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
if (hDC == NULL)
{
if (pDriver)
@@ -135,10 +142,13 @@ NtGdiExtEscape(
ppdev = pDC->ppdev;
PDEVOBJ_vReference(ppdev);
EngAcquireSemaphore(ppdev->hsemDevLock);
/* Check if we have a surface */
psurf = pDC->dclevel.pSurface;
if (!psurf)
{
EngReleaseSemaphore(ppdev->hsemDevLock);
DC_UnlockDc(pDC);
PDEVOBJ_vRelease(ppdev);
return 0;
@@ -156,81 +166,52 @@ NtGdiExtEscape(
goto Exit;
}
if ( InSize && UnsafeInData )
{
if (InSize)
{
SafeInData = ExAllocatePoolWithTag(PagedPool, InSize, GDITAG_TEMP);
_SEH2_TRY
{
ProbeForRead(UnsafeInData,
InSize,
1);
if (SafeInData == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Exit;
}
else
{
ProbeForRead(UnsafeInData, InSize, 1);
RtlCopyMemory(SafeInData, UnsafeInData, InSize);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
Result = -1;
goto Exit;
}
SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, GDITAG_TEMP );
if ( !SafeInData )
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
Result = -1;
goto Exit;
}
_SEH2_TRY
{
/* Pointers were already probed! */
RtlCopyMemory(SafeInData,
UnsafeInData,
InSize);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if ( !NT_SUCCESS(Status) )
{
Status = _SEH2_GetExceptionCode();
SetLastNtError(Status);
Result = -1;
goto Exit;
}
_SEH2_END;
}
if ( OutSize && UnsafeOutData )
if (OutSize)
{
_SEH2_TRY
if (UnsafeOutData != NULL)
{
ProbeForWrite(UnsafeOutData,
OutSize,
1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
Result = -1;
goto Exit;
_SEH2_TRY
{
ProbeForWrite(UnsafeOutData, OutSize, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
SetLastNtError(Status);
goto Exit;
}
_SEH2_END;
}
SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, GDITAG_TEMP );
if ( !SafeOutData )
SafeOutData = ExAllocatePoolZero(PagedPool, OutSize, GDITAG_TEMP);
if (SafeOutData == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
Result = -1;
goto Exit;
}
}
@@ -242,44 +223,37 @@ NtGdiExtEscape(
InSize,
SafeInData,
OutSize,
SafeOutData );
SafeOutData);
if (OutSize != 0 && UnsafeOutData != NULL && SafeOutData != NULL)
{
_SEH2_TRY
{
RtlCopyMemory(UnsafeOutData, SafeOutData, OutSize);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
SetLastNtError(Status);
Result = -1;
}
_SEH2_END;
}
Exit:
if (hDC == NULL)
{
EngReleaseSemaphore(ppdev->hsemDevLock);
}
SURFACE_ShareUnlockSurface(psurf);
EngReleaseSemaphore(ppdev->hsemDevLock);
PDEVOBJ_vRelease(ppdev);
if ( SafeInData )
if (SafeInData != NULL)
{
ExFreePoolWithTag ( SafeInData ,GDITAG_TEMP );
ExFreePoolWithTag(SafeInData, GDITAG_TEMP);
}
if ( SafeOutData )
if (SafeOutData != NULL)
{
if (Result > 0)
{
_SEH2_TRY
{
/* Pointers were already probed! */
RtlCopyMemory(UnsafeOutData, SafeOutData, OutSize);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if ( !NT_SUCCESS(Status) )
{
SetLastNtError(Status);
Result = -1;
}
}
ExFreePoolWithTag ( SafeOutData, GDITAG_TEMP );
ExFreePoolWithTag(SafeOutData, GDITAG_TEMP);
}
return Result;