Implement ExtCreateRegion.
Modified: trunk/reactos/include/win32k/region.h
Modified: trunk/reactos/lib/gdi32/gdi32.def
Modified: trunk/reactos/subsys/win32k/objects/region.c

Modified: trunk/reactos/include/win32k/region.h
--- trunk/reactos/include/win32k/region.h	2005-01-02 18:00:31 UTC (rev 12729)
+++ trunk/reactos/include/win32k/region.h	2005-01-02 18:04:59 UTC (rev 12730)
@@ -79,9 +79,9 @@
 
 HRGN
 STDCALL
-NtGdiExtCreateRegion(CONST PXFORM  Xform,
-                          DWORD  Count,
-                          CONST PROSRGNDATA  RgnData);
+NtGdiExtCreateRegion(CONST XFORM *Xform,
+                          DWORD Count,
+                          CONST RGNDATA *RgnData);
 
 BOOL
 STDCALL

Modified: trunk/reactos/lib/gdi32/gdi32.def
--- trunk/reactos/lib/gdi32/gdi32.def	2005-01-02 18:00:31 UTC (rev 12729)
+++ trunk/reactos/lib/gdi32/gdi32.def	2005-01-02 18:04:59 UTC (rev 12730)
@@ -1,4 +1,4 @@
-; $Id: gdi32.def,v 1.13 2004/12/30 02:32:23 navaraf Exp $
+; $Id$
 ;
 ; gdi32.def
 ;
@@ -168,7 +168,7 @@
 EudcUnloadLinkW@8
 ExcludeClipRect@20=NtGdiExcludeClipRect@20
 ExtCreatePen@20=NtGdiExtCreatePen@20
-ExtCreateRegion@12
+ExtCreateRegion@12=NtGdiExtCreateRegion@12
 ExtEscape@24=NtGdiExtEscape@24
 ExtFloodFill@20=NtGdiExtFloodFill@20
 ExtSelectClipRgn@12=NtGdiExtSelectClipRgn@12

Modified: trunk/reactos/subsys/win32k/objects/region.c
--- trunk/reactos/subsys/win32k/objects/region.c	2005-01-02 18:00:31 UTC (rev 12729)
+++ trunk/reactos/subsys/win32k/objects/region.c	2005-01-02 18:04:59 UTC (rev 12730)
@@ -113,7 +113,7 @@
  * the y-x-banding that's so nice to have...
  */
 
-/* $Id: region.c,v 1.64 2004/12/12 01:40:38 weiden Exp $ */
+/* $Id$ */
 #include <w32k.h>
 #include <win32k/float.h>
 
@@ -2224,12 +2224,57 @@
 
 HRGN
 STDCALL
-NtGdiExtCreateRegion(CONST PXFORM  Xform,
-                          DWORD  Count,
-                          CONST PROSRGNDATA  RgnData)
+NtGdiExtCreateRegion(CONST XFORM *Xform,
+                          DWORD Count,
+                          CONST RGNDATA *RgnData)
 {
-  UNIMPLEMENTED;
-  return 0;
+   HRGN hRgn;
+   RGNDATA SafeRgnData;
+   PROSRGNDATA Region;
+   NTSTATUS Status;
+
+   if (Count < FIELD_OFFSET(RGNDATA, Buffer))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+   }
+
+   Status = MmCopyFromCaller(&SafeRgnData, RgnData, min(Count, sizeof(RGNDATA)));
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+   }
+
+   hRgn = RGNDATA_AllocRgn(SafeRgnData.rdh.nCount);
+   if (hRgn == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+   
+   Region = RGNDATA_LockRgn(hRgn);
+   if (Region == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+   }
+
+   RtlCopyMemory(&Region->rdh, &SafeRgnData, FIELD_OFFSET(RGNDATA, Buffer));
+
+   Status = MmCopyFromCaller(Region->Buffer, RgnData->Buffer,
+                             Count - FIELD_OFFSET(RGNDATA, Buffer));
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      RGNDATA_UnlockRgn(hRgn);
+      NtGdiDeleteObject(hRgn);
+      return NULL;
+   }
+   
+   RGNDATA_UnlockRgn(hRgn);
+
+   return hRgn;
 }
 
 BOOL