[ros-diffs] [tkreuzer] 36686: - rewrite NtGdiPolyPolyDraw, optimizing it and making it more windows compatible - Make PolyCounts ULONGs, not DWORDS or INTs. - Remove GdiCreatePolyPolygonRgn and use IntCreatePolyPolygonRgn instead to get rid of code-duplication. - IntGdiPolygon: rename UnsafePoints to Points

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Oct 8 01:02:42 CEST 2008


Author: tkreuzer
Date: Tue Oct  7 18:02:41 2008
New Revision: 36686

URL: http://svn.reactos.org/svn/reactos?rev=36686&view=rev
Log:
- rewrite NtGdiPolyPolyDraw, optimizing it and making it more windows compatible
- Make PolyCounts ULONGs, not DWORDS or INTs.
- Remove GdiCreatePolyPolygonRgn and use IntCreatePolyPolygonRgn instead to get rid of code-duplication.
- IntGdiPolygon: rename UnsafePoints to Points

Modified:
    trunk/reactos/subsystems/win32/win32k/include/intgdi.h
    trunk/reactos/subsystems/win32/win32k/include/region.h
    trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
    trunk/reactos/subsystems/win32/win32k/objects/line.c
    trunk/reactos/subsystems/win32/win32k/objects/path.c
    trunk/reactos/subsystems/win32/win32k/objects/region.c

Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/intgdi.h?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -93,7 +93,7 @@
 BOOL FASTCALL
 IntGdiPolyPolyline(DC      *dc,
                    LPPOINT pt,
-                   LPDWORD PolyPoints,
+                   PULONG PolyPoints,
                    DWORD   Count);
 
 BOOL FASTCALL
@@ -125,7 +125,7 @@
 BOOL FASTCALL
 IntGdiPolyPolygon(DC      *dc,
                   LPPOINT Points,
-                  LPINT   PolyCounts,
+                  PULONG  PolyCounts,
                   int     Count);
 
 BOOL FASTCALL IntGdiGradientFill(DC *dc,

Modified: trunk/reactos/subsystems/win32/win32k/include/region.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/region.h?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/region.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/region.h [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -43,7 +43,7 @@
 
 INT STDCALL IntGdiGetRgnBox(HRGN, LPRECT);
 BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN );
-HRGN FASTCALL GdiCreatePolyPolygonRgn(CONST PPOINT, CONST PINT, INT, INT );
+HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT);
 
 INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT);
 INT FASTCALL REGION_Complexity(PROSRGNDATA);

Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/fillshap.c?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -51,7 +51,7 @@
 
 BOOL FASTCALL
 IntGdiPolygon(PDC    dc,
-              PPOINT UnsafePoints,
+              PPOINT Points,
               int    Count)
 {
     BITMAPOBJ *BitmapObj;
@@ -64,7 +64,7 @@
 
     ASSERT(dc); // caller's responsibility to pass a valid dc
 
-    if ( NULL == UnsafePoints || Count < 2 )
+    if (!Points || Count < 2 )
     {
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         return FALSE;
@@ -74,25 +74,25 @@
     if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
 
     /* Convert to screen coordinates */
-    IntLPtoDP(dc, UnsafePoints, Count);
+    IntLPtoDP(dc, Points, Count);
     for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
     {
-        UnsafePoints[CurrentPoint].x += dc->ptlDCOrig.x;
-        UnsafePoints[CurrentPoint].y += dc->ptlDCOrig.y;
+        Points[CurrentPoint].x += dc->ptlDCOrig.x;
+        Points[CurrentPoint].y += dc->ptlDCOrig.y;
     }
     // No need to have path here.
     {
-        DestRect.left   = UnsafePoints[0].x;
-        DestRect.right  = UnsafePoints[0].x;
-        DestRect.top    = UnsafePoints[0].y;
-        DestRect.bottom = UnsafePoints[0].y;
+        DestRect.left   = Points[0].x;
+        DestRect.right  = Points[0].x;
+        DestRect.top    = Points[0].y;
+        DestRect.bottom = Points[0].y;
 
         for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
         {
-            DestRect.left     = min(DestRect.left, UnsafePoints[CurrentPoint].x);
-            DestRect.right    = max(DestRect.right, UnsafePoints[CurrentPoint].x);
-            DestRect.top      = min(DestRect.top, UnsafePoints[CurrentPoint].y);
-            DestRect.bottom   = max(DestRect.bottom, UnsafePoints[CurrentPoint].y);
+            DestRect.left     = min(DestRect.left, Points[CurrentPoint].x);
+            DestRect.right    = max(DestRect.right, Points[CurrentPoint].x);
+            DestRect.top      = min(DestRect.top, Points[CurrentPoint].y);
+            DestRect.bottom   = max(DestRect.bottom, Points[CurrentPoint].y);
         }
 
         /* Special locking order to avoid lock-ups */
@@ -106,7 +106,7 @@
         if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
         {
             IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
-            ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), UnsafePoints, Count, DestRect );
+            ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), Points, Count, DestRect );
         }
         if (FillBrushObj)
             BRUSHOBJ_UnlockBrush(FillBrushObj);
@@ -122,16 +122,16 @@
             {
 
 // DPRINT1("Polygon Making line from (%d,%d) to (%d,%d)\n",
-//                                 UnsafePoints[0].x, UnsafePoints[0].y,
-//                                 UnsafePoints[1].x, UnsafePoints[1].y );
+//                                 Points[0].x, Points[0].y,
+//                                 Points[1].x, Points[1].y );
 
                 ret = IntEngLineTo(&BitmapObj->SurfObj,
                                    dc->CombinedClip,
                                    &PenBrushInst.BrushObject,
-                                   UnsafePoints[i].x,          /* From */
-                                   UnsafePoints[i].y,
-                                   UnsafePoints[i+1].x,          /* To */
-                                   UnsafePoints[i+1].y,
+                                   Points[i].x,          /* From */
+                                   Points[i].y,
+                                   Points[i+1].x,          /* To */
+                                   Points[i+1].y,
                                    &DestRect,
                                    ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
                 if (!ret) break;
@@ -142,10 +142,10 @@
                 ret = IntEngLineTo(&BitmapObj->SurfObj,
                                    dc->CombinedClip,
                                    &PenBrushInst.BrushObject,
-                                   UnsafePoints[Count-1].x, /* From */
-                                   UnsafePoints[Count-1].y,
-                                   UnsafePoints[0].x,       /* To */
-                                   UnsafePoints[0].y,
+                                   Points[Count-1].x, /* From */
+                                   Points[Count-1].y,
+                                   Points[0].x,       /* To */
+                                   Points[0].y,
                                    &DestRect,
                                    ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
             }
@@ -161,11 +161,11 @@
 BOOL FASTCALL
 IntGdiPolyPolygon(DC      *dc,
                   LPPOINT Points,
-                  LPINT   PolyCounts,
+                  PULONG  PolyCounts,
                   int     Count)
 {
     if (PATH_IsPathOpen(dc->DcLevel))
-        return PATH_PolyPolygon ( dc, Points, PolyCounts, Count);
+        return PATH_PolyPolygon ( dc, Points, (PINT)PolyCounts, Count);
 
     while (--Count >=0)
     {
@@ -336,185 +336,152 @@
 ULONG_PTR
 STDCALL
 NtGdiPolyPolyDraw( IN HDC hDC,
-                   IN PPOINT Points,
-                   IN PULONG PolyCounts,
+                   IN PPOINT UnsafePoints,
+                   IN PULONG UnsafeCounts,
                    IN ULONG Count,
                    IN INT iFunc )
 {
     DC *dc;
-    LPPOINT Safept;
-    LPINT SafePolyPoints;
+    PVOID pTemp;
+    LPPOINT SafePoints;
+    PULONG SafeCounts;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOL Ret = TRUE;
-    INT nPoints, nEmpty, nInvalid, i;
-
-    if (iFunc == GdiPolyPolyRgn)
-    {
-        return (ULONG_PTR) GdiCreatePolyPolygonRgn((CONST PPOINT)  Points,
-                (CONST PINT)  PolyCounts,
-                Count,
-                (INT) hDC);
-    }
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (dc->DC_Type == DC_TYPE_INFO)
-    {
-        DC_UnlockDc(dc);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
-
-    if (Count > 0)
-    {
-        _SEH_TRY
-        {
-            ProbeForRead(Points,
-                         Count * sizeof(POINT),
-                         1);
-            ProbeForRead(PolyCounts,
-                         Count * sizeof(INT),
-                         1);
-        }
-        _SEH_HANDLE
-        {
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if (!NT_SUCCESS(Status))
-        {
-            DC_UnlockDc(dc);
-            SetLastNtError(Status);
-            return FALSE;
-        }
-
-        SafePolyPoints = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_SHAPE);
-        if (!SafePolyPoints)
-        {
-            DC_UnlockDc(dc);
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-
-        _SEH_TRY
-        {
-            /* pointers already probed! */
-            RtlCopyMemory(SafePolyPoints,
-                          PolyCounts,
-                          Count * sizeof(INT));
-        }
-        _SEH_HANDLE
-        {
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if (!NT_SUCCESS(Status))
-        {
-            DC_UnlockDc(dc);
-            ExFreePool(SafePolyPoints);
-            SetLastNtError(Status);
-            return FALSE;
-        }
-        /* validate poligons */
-        nPoints = 0;
-        nEmpty = 0;
-        nInvalid = 0;
+    INT nPoints = 0, nMaxPoints = 0, nInvalid = 0, i;
+
+    if (!UnsafePoints || !UnsafeCounts ||
+        Count == 0 || iFunc == 0 || iFunc > GdiPolyPolyRgn)
+    {
+        /* Windows doesn't set last error */
+        return FALSE;
+    }
+
+    _SEH_TRY
+    {
+        ProbeForRead(UnsafePoints, Count * sizeof(POINT), 1);
+        ProbeForRead(UnsafeCounts, Count * sizeof(ULONG), 1);
+
+        /* Count points and validate poligons */
         for (i = 0; i < Count; i++)
         {
-            if (SafePolyPoints[i] == 0)
-            {
-                nEmpty++;
-            }
-            if (SafePolyPoints[i] == 1)
+            if (UnsafeCounts[i] < 2)
             {
                 nInvalid++;
             }
-            nPoints += SafePolyPoints[i];
+            nPoints += UnsafeCounts[i];
+            nMaxPoints = max(nMaxPoints, UnsafeCounts[i]);
         }
-
-        if (nEmpty == Count)
-        {
-            /* if all polygon counts are zero, return without setting a last error code. */
-            ExFreePool(SafePolyPoints);
-            return FALSE;
-        }
-        if (nInvalid != 0)
-        {
-            /* if at least one poly count is 1, fail */
-            ExFreePool(SafePolyPoints);
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
-            return FALSE;
-        }
-
-        Safept = ExAllocatePoolWithTag(PagedPool, nPoints * sizeof(POINT), TAG_SHAPE);
-        if (!Safept)
-        {
-            DC_UnlockDc(dc);
-            ExFreePool(SafePolyPoints);
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-
-        _SEH_TRY
-        {
-            /* pointers already probed! */
-            RtlCopyMemory(Safept,
-                          Points,
-                          nPoints * sizeof(POINT));
-        }
-        _SEH_HANDLE
-        {
-            Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if (!NT_SUCCESS(Status))
-        {
-            DC_UnlockDc(dc);
-            ExFreePool(SafePolyPoints);
-            ExFreePool(Safept);
-            SetLastNtError(Status);
-            return FALSE;
-        }
-    }
-    else
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* Windows doesn't set last error */
+        return FALSE;
+    }
+
+    if (nPoints == 0 || nPoints < nMaxPoints)
+    {
+        /* If all polygon counts are zero, or we have overflow,
+           return without setting a last error code. */
+        return FALSE;
+    }
+
+    if (nInvalid != 0)
+    {
+        /* If at least one poly count is 0 or 1, fail */
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Allocate one buffer for both counts and points */
+    pTemp = ExAllocatePoolWithTag(PagedPool,
+                                  Count * sizeof(ULONG) + nPoints * sizeof(POINT),
+                                  TAG_SHAPE);
+    if (!pTemp)
+    {
+        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    SafeCounts = pTemp;
+    SafePoints = (PVOID)(SafeCounts + Count);
+
+    _SEH_TRY
+    {
+        /* Pointers already probed! */
+        RtlCopyMemory(SafeCounts, UnsafeCounts, Count * sizeof(ULONG));
+        RtlCopyMemory(SafePoints, UnsafePoints, nPoints * sizeof(POINT));
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+        ExFreePool(pTemp);
+        return FALSE;
+    }
+
+    /* Special handling for GdiPolyPolyRgn */
+    if (iFunc == GdiPolyPolyRgn)
+    {
+        HRGN hRgn;
+        hRgn = IntCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, (INT_PTR)hDC);
+        ExFreePool(pTemp);
+        return (ULONG_PTR)hRgn;
+    }
+
+    dc = DC_LockDc(hDC);
+    if (!dc)
+    {
+        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        ExFreePool(pTemp);
+        return FALSE;
+    }
+
+    if (dc->DC_Type == DC_TYPE_INFO)
     {
         DC_UnlockDc(dc);
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
+        ExFreePool(pTemp);
+        /* Yes, Windows really returns TRUE in this case */
+        return TRUE;
+    }
+
+    /* Perform the actual work */
     switch (iFunc)
     {
         case GdiPolyPolygon:
-            Ret = IntGdiPolyPolygon(dc, Safept, SafePolyPoints, Count);
+            Ret = IntGdiPolyPolygon(dc, SafePoints, SafeCounts, Count);
             break;
         case GdiPolyPolyLine:
-            Ret = IntGdiPolyPolyline(dc, Safept, (LPDWORD) SafePolyPoints, Count);
+            Ret = IntGdiPolyPolyline(dc, SafePoints, SafeCounts, Count);
             break;
         case GdiPolyBezier:
-            Ret = IntGdiPolyBezier(dc, Safept, *PolyCounts);
+            Ret = IntGdiPolyBezier(dc, SafePoints, *SafeCounts);
             break;
         case GdiPolyLineTo:
-            Ret = IntGdiPolylineTo(dc, Safept, *PolyCounts);
+            Ret = IntGdiPolylineTo(dc, SafePoints, *SafeCounts);
             break;
         case GdiPolyBezierTo:
-            Ret = IntGdiPolyBezierTo(dc, Safept, *PolyCounts);
+            Ret = IntGdiPolyBezierTo(dc, SafePoints, *SafeCounts);
             break;
         default:
             SetLastWin32Error(ERROR_INVALID_PARAMETER);
             Ret = FALSE;
     }
-    ExFreePool(SafePolyPoints);
-    ExFreePool(Safept);
+
+    /* Cleanup and return */
     DC_UnlockDc(dc);
-
-    return (ULONG_PTR) Ret;
+    ExFreePool(pTemp);
+
+    return (ULONG_PTR)Ret;
 }
 
 

Modified: trunk/reactos/subsystems/win32/win32k/objects/line.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/line.c?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -350,12 +350,12 @@
 BOOL FASTCALL
 IntGdiPolyPolyline(DC      *dc,
                    LPPOINT pt,
-                   LPDWORD PolyPoints,
+                   PULONG  PolyPoints,
                    DWORD   Count)
 {
     int i;
     LPPOINT pts;
-    LPDWORD pc;
+    PULONG pc;
     BOOL ret = FALSE; // default to failure
     pts = pt;
     pc = PolyPoints;

Modified: trunk/reactos/subsystems/win32/win32k/objects/path.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/path.c?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -1028,7 +1028,6 @@
 }
 
 
-HRGN FASTCALL IntCreatePolyPolygonRgn(POINT *Pts, INT *Count, INT nbpolygons,INT mode);
 /* PATH_PathToRegion
  *
  * Creates a region from the specified path using the specified polygon
@@ -1042,7 +1041,7 @@
 PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
 {
   int    numStrokes, iStroke, i;
-  INT  *pNumPointsInStroke;
+  PULONG  pNumPointsInStroke;
   HRGN hrgn = 0;
 
   ASSERT(pPath!=NULL);
@@ -1060,7 +1059,7 @@
       numStrokes++;
 
   /* Allocate memory for number-of-points-in-stroke array */
-  pNumPointsInStroke=(int *)ExAllocatePoolWithTag(PagedPool, sizeof(int) * numStrokes, TAG_PATH);
+  pNumPointsInStroke = ExAllocatePoolWithTag(PagedPool, sizeof(ULONG) * numStrokes, TAG_PATH);
   if(!pNumPointsInStroke)
   {
     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);

Modified: trunk/reactos/subsystems/win32/win32k/objects/region.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/region.c?rev=36686&r1=36685&r2=36686&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] Tue Oct  7 18:02:41 2008
@@ -3560,7 +3560,7 @@
  */
 static void FASTCALL
 REGION_CreateETandAET(
-    const INT *Count,
+    const ULONG *Count,
     INT nbpolygons,
     const POINT *pts,
     EdgeTable *ET,
@@ -3657,7 +3657,7 @@
 HRGN FASTCALL
 IntCreatePolyPolygonRgn(
     POINT *Pts,
-    INT *Count,
+    PULONG Count,
     INT nbpolygons,
     INT mode
 )
@@ -3680,6 +3680,8 @@
     POINTBLOCK *tmpPtBlock;
     int numFullPtBlocks = 0;
     INT poly, total;
+
+    if (mode == 0 || mode > 2) return 0;
 
     if (!(region = REGION_AllocRgnWithHandle(nbpolygons)))
         return 0;
@@ -3851,139 +3853,4 @@
     return hrgn;
 }
 
-
-HRGN
-FASTCALL
-GdiCreatePolyPolygonRgn(
-    CONST PPOINT pt,
-    CONST PINT  PolyCounts,
-    INT  Count,
-    INT  PolyFillMode
-)
-{
-    POINT *Safept;
-    INT *SafePolyCounts;
-    INT nPoints, nEmpty, nInvalid, i;
-    HRGN hRgn;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (pt == NULL || PolyCounts == NULL || Count == 0 ||
-            (PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
-    {
-        /* Windows doesn't set a last error here */
-        return (HRGN)0;
-    }
-
-    _SEH_TRY
-    {
-        ProbeForRead(PolyCounts, Count * sizeof(INT), 1);
-        /* just probe one point for now, we don't know the length of the array yet */
-        ProbeForRead(pt, sizeof(POINT), 1);
-    }
-    _SEH_HANDLE
-    {
-        Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastNtError(Status);
-        return (HRGN)0;
-    }
-
-    if (!(SafePolyCounts = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_REGION)))
-    {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-        return (HRGN)0;
-    }
-
-    _SEH_TRY
-    {
-        /* pointers were already probed! */
-        RtlCopyMemory(SafePolyCounts,
-        PolyCounts,
-        Count * sizeof(INT));
-    }
-    _SEH_HANDLE
-    {
-        Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePool(SafePolyCounts);
-        SetLastNtError(Status);
-        return (HRGN)0;
-    }
-
-    /* validate poligons */
-    nPoints = 0;
-    nEmpty = 0;
-    nInvalid = 0;
-    for (i = 0; i < Count; i++)
-    {
-        if (SafePolyCounts[i] == 0)
-        {
-            nEmpty++;
-        }
-        if (SafePolyCounts[i] == 1)
-        {
-            nInvalid++;
-        }
-        nPoints += SafePolyCounts[i];
-    }
-
-    if (nEmpty == Count)
-    {
-        /* if all polygon counts are zero, return without setting a last error code. */
-        ExFreePool(SafePolyCounts);
-        return (HRGN)0;
-    }
-    if (nInvalid != 0)
-    {
-        /* if at least one poly count is 1, fail */
-        ExFreePool(SafePolyCounts);
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        return (HRGN)0;
-    }
-
-    /* copy points */
-    if (!(Safept = ExAllocatePoolWithTag(PagedPool, nPoints * sizeof(POINT), TAG_REGION)))
-    {
-        ExFreePool(SafePolyCounts);
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-        return (HRGN)0;
-    }
-
-    _SEH_TRY
-    {
-        ProbeForRead(pt, nPoints * sizeof(POINT), 1);
-        /* pointers were already probed! */
-        RtlCopyMemory(Safept,
-                      pt,
-                      nPoints * sizeof(POINT));
-    }
-    _SEH_HANDLE
-    {
-        Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePool(Safept);
-        ExFreePool(SafePolyCounts);
-        SetLastNtError(Status);
-        return (HRGN)0;
-    }
-
-    /* now we're ready to calculate the region safely */
-    hRgn = IntCreatePolyPolygonRgn(Safept, SafePolyCounts, Count, PolyFillMode);
-
-    ExFreePool(Safept);
-    ExFreePool(SafePolyCounts);
-    return hRgn;
-}
-
 /* EOF */



More information about the Ros-diffs mailing list