Author: jimtabor
Date: Thu Apr 26 07:25:42 2007
New Revision: 26510
URL:
http://svn.reactos.org/svn/reactos?rev=26510&view=rev
Log:
Apply Alex patch to dc.c NtGdiExtGetObject.
Modified:
trunk/reactos/subsystems/win32/win32k/objects/dc.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dc.c Thu Apr 26 07:25:42 2007
@@ -1753,9 +1753,11 @@
DC_GET_VAL( INT, NtGdiGetMapMode, w.MapMode )
DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode )
-
-INT FASTCALL
-IntGdiGetObject(HANDLE Handle, INT cbCount, LPVOID lpBuffer)
+INT
+FASTCALL
+IntGdiGetObject(IN HANDLE Handle,
+ IN INT cbCount,
+ IN LPVOID lpBuffer)
{
PVOID pGdiObject;
INT Result = 0;
@@ -1808,70 +1810,101 @@
return Result;
}
-INT STDCALL
-NtGdiExtGetObjectW(HANDLE hGdiObj, INT cbCount, LPVOID lpUnsafeBuf)
-{
- LPVOID lpSafeBuf;
- NTSTATUS Status = STATUS_SUCCESS;
- INT RetCount = 0;
-
- /* From Wine: GetObject does not SetLastError() on a null object */
- if (!hGdiObj)
- {
- return 0;
- }
-
- if (!lpUnsafeBuf)
- {
- return IntGdiGetObject(hGdiObj, 0, NULL);
- }
-
- if (!cbCount)
- {
- return 0;
- }
-
- RetCount = IntGdiGetObject(hGdiObj, cbCount, NULL);
- if (!RetCount)
- {
- return 0;
- }
- 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)
- {
- _SEH_TRY
- {
- ProbeForWrite(lpUnsafeBuf, cbCount, 1);
- RtlCopyMemory(lpUnsafeBuf, lpSafeBuf, cbCount);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
-
- ExFreePool(lpSafeBuf);
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return 0;
- }
-
- return RetCount;
-}
-
+INT
+NTAPI
+NtGdiExtGetObjectW(IN HANDLE hGdiObj,
+ IN INT cbCount,
+ OUT LPVOID lpBuffer)
+{
+ INT iRetCount = 0;
+ INT iObjectType;
+ INT cbRealCount = cbCount;
+ union
+ {
+ 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);
+ }
+
+ //
+ // Check if this is a brush
+ //
+ if (iObjectType == GDI_OBJECT_TYPE_BRUSH)
+ {
+ //
+ // Windows GDI Hack: Manually correct the size
+ //
+ cbCount = sizeof(LOGBRUSH);
+ }
+
+ //
+ // Now do the actual call
+ //
+ iRetCount = IntGdiGetObject(hGdiObj, cbCount, lpBuffer ? &Object : NULL);
+
+ //
+ // Check if this is a brush
+ //
+ if (iObjectType == GDI_OBJECT_TYPE_BRUSH)
+ {
+ //
+ // Fixup the size to account for our previous fixup
+ //
+ cbCount = min(cbCount, cbRealCount);
+ }
+
+ //
+ // Make sure we have a buffer and a return size
+ //
+ if ((iRetCount) && (lpBuffer))
+ {
+ //
+ // Enter SEH for buffer transfer
+ //
+ _SEH_TRY
+ {
+ //
+ // Probe the buffer and copy it
+ //
+ ProbeForWrite(lpBuffer, min(cbCount, cbRealCount), sizeof(WORD));
+ RtlCopyMemory(lpBuffer, &Object, min(cbCount, cbRealCount));
+ }
+ _SEH_HANDLE
+ {
+ //
+ // Clear the return value.
+ // Do *NOT* set last error here!
+ //
+ iRetCount = 0;
+ }
+ _SEH_END;
+ }
+
+ //
+ // Return the count
+ //
+ return iRetCount;
+}
DC_GET_VAL( INT, NtGdiGetRelAbs, w.relAbsMode )
DC_GET_VAL( INT, NtGdiGetROP2, w.ROPmode )