Apply Alex patch to dc.c NtGdiExtGetObject.

svn path=/trunk/; revision=26510
This commit is contained in:
James Tabor 2007-04-26 03:25:42 +00:00
parent 5610a60b73
commit cd5a11a313

View file

@ -1753,9 +1753,11 @@ NtGdiGetDeviceCaps(HDC hDC,
DC_GET_VAL( INT, NtGdiGetMapMode, w.MapMode ) DC_GET_VAL( INT, NtGdiGetMapMode, w.MapMode )
DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode ) DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode )
INT
INT FASTCALL FASTCALL
IntGdiGetObject(HANDLE Handle, INT cbCount, LPVOID lpBuffer) IntGdiGetObject(IN HANDLE Handle,
IN INT cbCount,
IN LPVOID lpBuffer)
{ {
PVOID pGdiObject; PVOID pGdiObject;
INT Result = 0; INT Result = 0;
@ -1808,71 +1810,102 @@ IntGdiGetObject(HANDLE Handle, INT cbCount, LPVOID lpBuffer)
return Result; return Result;
} }
INT STDCALL INT
NtGdiExtGetObjectW(HANDLE hGdiObj, INT cbCount, LPVOID lpUnsafeBuf) NTAPI
NtGdiExtGetObjectW(IN HANDLE hGdiObj,
IN INT cbCount,
OUT LPVOID lpBuffer)
{ {
LPVOID lpSafeBuf; INT iRetCount = 0;
NTSTATUS Status = STATUS_SUCCESS; INT iObjectType;
INT RetCount = 0; INT cbRealCount = cbCount;
union
/* From Wine: GetObject does not SetLastError() on a null object */
if (!hGdiObj)
{ {
return 0; BITMAP bmpObject;
DIBSECTION disObject;
LOGPEN lgpObject;
LOGBRUSH lgbObject;
LOGFONTW lgfObject;
EXTLOGFONTW elgfObject;
} Object;
//
// Get the object type
//
iObjectType = GDIOBJ_GetObjectType(hGdiObj);
//
// Check if the given size is too large
//
if (cbCount > sizeof(Object))
{
//
// Normalize to the largest supported object size
//
DPRINT1("cbCount too big!\n");
cbCount = sizeof(Object);
} }
if (!lpUnsafeBuf) //
// Check if this is a brush
//
if (iObjectType == GDI_OBJECT_TYPE_BRUSH)
{ {
return IntGdiGetObject(hGdiObj, 0, NULL); //
// Windows GDI Hack: Manually correct the size
//
cbCount = sizeof(LOGBRUSH);
} }
if (!cbCount) //
// Now do the actual call
//
iRetCount = IntGdiGetObject(hGdiObj, cbCount, lpBuffer ? &Object : NULL);
//
// Check if this is a brush
//
if (iObjectType == GDI_OBJECT_TYPE_BRUSH)
{ {
return 0; //
// Fixup the size to account for our previous fixup
//
cbCount = min(cbCount, cbRealCount);
} }
RetCount = IntGdiGetObject(hGdiObj, cbCount, NULL); //
if (!RetCount) // Make sure we have a buffer and a return size
{ //
return 0; if ((iRetCount) && (lpBuffer))
}
if ((UINT)cbCount > RetCount)
{
cbCount = RetCount;
}
lpSafeBuf = ExAllocatePoolWithTag(PagedPool, RetCount, TAG_GDIOBJ);
if(!lpSafeBuf)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
RetCount = IntGdiGetObject(hGdiObj, cbCount, lpSafeBuf);
if (RetCount)
{ {
//
// Enter SEH for buffer transfer
//
_SEH_TRY _SEH_TRY
{ {
ProbeForWrite(lpUnsafeBuf, cbCount, 1); //
RtlCopyMemory(lpUnsafeBuf, lpSafeBuf, cbCount); // Probe the buffer and copy it
//
ProbeForWrite(lpBuffer, min(cbCount, cbRealCount), sizeof(WORD));
RtlCopyMemory(lpBuffer, &Object, min(cbCount, cbRealCount));
} }
_SEH_HANDLE _SEH_HANDLE
{ {
Status = _SEH_GetExceptionCode(); //
// Clear the return value.
// Do *NOT* set last error here!
//
iRetCount = 0;
} }
_SEH_END; _SEH_END;
} }
ExFreePool(lpSafeBuf); //
// Return the count
if(!NT_SUCCESS(Status)) //
{ return iRetCount;
SetLastNtError(Status);
return 0;
}
return RetCount;
} }
DC_GET_VAL( INT, NtGdiGetRelAbs, w.relAbsMode ) DC_GET_VAL( INT, NtGdiGetRelAbs, w.relAbsMode )
DC_GET_VAL( INT, NtGdiGetROP2, w.ROPmode ) DC_GET_VAL( INT, NtGdiGetROP2, w.ROPmode )
DC_GET_VAL( INT, NtGdiGetStretchBltMode, w.stretchBltMode ) DC_GET_VAL( INT, NtGdiGetStretchBltMode, w.stretchBltMode )