Commit in reactos on MAIN
lib/gdi32/misc/stubs.c+1-171.61 -> 1.62
lib/gdi32/objects/region.c+22-21.14 -> 1.15
subsys/win32k/objects/region.c+154-91.53 -> 1.54
+177-28
3 modified files
safe parameter handling for PolyPolygonRgn() and PolygonRgn(). The actual region calculation for both functions is not yet implemented though!

reactos/lib/gdi32/misc
stubs.c 1.61 -> 1.62
diff -u -r1.61 -r1.62
--- stubs.c	15 May 2004 08:52:25 -0000	1.61
+++ stubs.c	18 May 2004 13:57:41 -0000	1.62
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.61 2004/05/15 08:52:25 navaraf Exp $
+/* $Id: stubs.c,v 1.62 2004/05/18 13:57:41 weiden Exp $
  *
  * reactos/lib/gdi32/misc/stubs.c
  *
@@ -1091,22 +1091,6 @@
 	return FALSE;
 }
 
-
-/*
- * @unimplemented
- */
-HRGN
-STDCALL
-CreatePolygonRgn(
-	CONST POINT	*a0,
-	int		a1,
-	int		a2
-	)
-{
-	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return 0;
-}
-
 /*
  * @unimplemented
  */

reactos/lib/gdi32/objects
region.c 1.14 -> 1.15
diff -u -r1.14 -r1.15
--- region.c	25 Apr 2004 14:46:54 -0000	1.14
+++ region.c	18 May 2004 13:57:41 -0000	1.15
@@ -85,8 +85,27 @@
 	int		fnPolyFillMode
 	)
 {
-  return NtGdiCreatePolyPolygonRgn ( (CONST PPOINT)lppt,
-    (CONST PINT)lpPolyCounts, nCount, fnPolyFillMode );
+  return NtGdiCreatePolyPolygonRgn((CONST PPOINT)lppt,
+                                   (CONST PINT)lpPolyCounts,
+				   nCount,
+				   fnPolyFillMode);
+}
+
+
+/*
+ * @implemented
+ */
+HRGN
+STDCALL
+CreatePolygonRgn(
+	CONST POINT	*lppt,
+	int		cPoints,
+	int		fnPolyFillMode
+	)
+{
+  return NtGdiCreatePolygonRgn((CONST PPOINT)lppt,
+                               cPoints,
+			       fnPolyFillMode);
 }
 
 
@@ -312,3 +331,4 @@
 {
   return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight);
 }
+

reactos/subsys/win32k/objects
region.c 1.53 -> 1.54
diff -u -r1.53 -r1.54
--- region.c	16 May 2004 09:51:27 -0000	1.53
+++ region.c	18 May 2004 13:57:41 -0000	1.54
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: region.c,v 1.53 2004/05/16 09:51:27 weiden Exp $ */
+/* $Id: region.c,v 1.54 2004/05/18 13:57:41 weiden Exp $ */
 #include <w32k.h>
 #include <win32k/float.h>
 
@@ -1692,23 +1692,168 @@
                                  SafeRect.right - SafeRect.left, SafeRect.bottom - SafeRect.top);
 }
 
+HRGN FASTCALL
+IntCreatePolyPolgonRgn(PPOINT pt,
+                       PINT PolyCounts,
+		       INT Count,
+                       INT PolyFillMode)
+{
+  return (HRGN)0;
+}
+
 HRGN
 STDCALL
 NtGdiCreatePolygonRgn(CONST PPOINT  pt,
-                           INT  Count,
-                           INT  PolyFillMode)
+                      INT  Count,
+                      INT  PolyFillMode)
 {
-  UNIMPLEMENTED;
+   POINT *SafePoints;
+   NTSTATUS Status;
+   HRGN hRgn;
+   
+   
+   if (pt == NULL || Count == 0 ||
+       (PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
+   {
+      /* Windows doesn't set a last error here */
+      return (HRGN)0;
+   }
+   
+   if (Count == 1)
+   {
+      /* can't create a region with only one point! */
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return (HRGN)0;
+   }
+   
+   if (Count == 2)
+   {
+      /* Windows creates an empty region! */
+      ROSRGNDATA *rgn;
+      
+      if(!(hRgn = RGNDATA_AllocRgn(1)))
+      {
+	 return (HRGN)0;
+      }
+      if(!(rgn = RGNDATA_LockRgn(hRgn)))
+      {
+        NtGdiDeleteObject(hRgn);
+	return (HRGN)0;
+      }
+      
+      EMPTY_REGION(rgn);
+      
+      RGNDATA_UnlockRgn(hRgn);
+      return hRgn;
+   }
+   
+   if (!(SafePoints = ExAllocatePool(PagedPool, Count * sizeof(POINT))))
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return (HRGN)0;
+   }
+   
+   Status = MmCopyFromCaller(SafePoints, pt, Count * sizeof(POINT));
+   if (!NT_SUCCESS(Status))
+   {
+      ExFreePool(SafePoints);
+      SetLastNtError(Status);
+      return (HRGN)0;
+   }
+   
+   hRgn = IntCreatePolyPolgonRgn(SafePoints, &Count, 1, PolyFillMode);
+   
+   ExFreePool(SafePoints);
+   return hRgn;
 }
 
 HRGN
 STDCALL
 NtGdiCreatePolyPolygonRgn(CONST PPOINT  pt,
-                               CONST PINT  PolyCounts,
-                               INT  Count,
-                               INT  PolyFillMode)
-{
-  UNIMPLEMENTED;
+                          CONST PINT  PolyCounts,
+                          INT  Count,
+                          INT  PolyFillMode)
+{
+   POINT *Safept;
+   INT *SafePolyCounts;
+   INT nPoints, nEmpty, nInvalid, i;
+   HRGN hRgn;
+   NTSTATUS Status;
+   
+   if (pt == NULL || PolyCounts == NULL || Count == 0 ||
+       (PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
+   {
+      /* Windows doesn't set a last error here */
+      return (HRGN)0;
+   }
+   
+   if (!(SafePolyCounts = ExAllocatePool(PagedPool, Count * sizeof(INT))))
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return (HRGN)0;
+   }
+   
+   Status = MmCopyFromCaller(SafePolyCounts, PolyCounts, Count * sizeof(INT));
+   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 = ExAllocatePool(PagedPool, nPoints * sizeof(POINT))))
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return (HRGN)0;
+   }
+   
+   Status = MmCopyFromCaller(Safept, pt, nPoints * sizeof(POINT));
+   if (!NT_SUCCESS(Status))
+   {
+      ExFreePool(Safept);
+      ExFreePool(SafePolyCounts);
+      SetLastNtError(Status);
+      return (HRGN)0;
+   }
+   
+   /* now we're ready to calculate the region safely */
+   hRgn = IntCreatePolyPolgonRgn(Safept, SafePolyCounts, Count, PolyFillMode);
+   
+   ExFreePool(Safept);
+   ExFreePool(SafePolyCounts);
+   return hRgn;
 }
 
 HRGN STDCALL
CVSspam 0.2.8