[ros-diffs] [jimtabor] 26510: Apply Alex patch to dc.c NtGdiExtGetObject.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Thu Apr 26 05:25:42 CEST 2007


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/objects/dc.c?rev=26510&r1=26509&r2=26510&view=diff
==============================================================================
--- 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 )




More information about the Ros-diffs mailing list