diff --git a/win32ss/gdi/ntgdi/region.c b/win32ss/gdi/ntgdi/region.c
index 79712182c7..057f753ab3 100644
--- a/win32ss/gdi/ntgdi/region.c
+++ b/win32ss/gdi/ntgdi/region.c
@@ -402,8 +402,8 @@ typedef struct _SCANLINE_LISTBLOCK
  *
  *************************************************************************/
 
-#define LARGE_COORDINATE  0x7fffffff /* FIXME */
-#define SMALL_COORDINATE  0x80000000
+#define LARGE_COORDINATE  INT_MAX
+#define SMALL_COORDINATE  INT_MIN
 
 static
 BOOL
@@ -509,8 +509,8 @@ REGION_bAddRect(
     return TRUE;
 }
 
-typedef VOID (FASTCALL *overlapProcp)(PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT);
-typedef VOID (FASTCALL *nonOverlapProcp)(PREGION, PRECT, PRECT, INT, INT);
+typedef BOOL (FASTCALL *overlapProcp)(PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT);
+typedef BOOL (FASTCALL *nonOverlapProcp)(PREGION, PRECT, PRECT, INT, INT);
 
 // Number of points to buffer before sending them off to scanlines() :  Must be an even number
 #define NUMPTSTOBUFFER 200
@@ -947,7 +947,7 @@ REGION_Coalesce(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_RegionOp(
     PREGION newReg, /* Place to store result */
@@ -1001,7 +1001,7 @@ REGION_RegionOp(
     if (newReg->Buffer == NULL)
     {
         newReg->rdh.nRgnSize = 0;
-        return;
+        return FALSE;
     }
 
     /* Initialize ybot and ytop.
@@ -1062,7 +1062,7 @@ REGION_RegionOp(
 
             if ((top != bot) && (nonOverlap1Func != NULL))
             {
-                (*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot);
+                if (!(*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot)) return FALSE;
             }
 
             ytop = r2->top;
@@ -1074,7 +1074,7 @@ REGION_RegionOp(
 
             if ((top != bot) && (nonOverlap2Func != NULL))
             {
-                (*nonOverlap2Func)(newReg, r2, r2BandEnd, top, bot);
+                if (!(*nonOverlap2Func)(newReg, r2, r2BandEnd, top, bot) ) return FALSE; 
             }
 
             ytop = r1->top;
@@ -1099,7 +1099,7 @@ REGION_RegionOp(
         curBand = newReg->rdh.nCount;
         if (ybot > ytop)
         {
-            (*overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
+            if (!(*overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot)) return FALSE;
         }
 
         if (newReg->rdh.nCount != curBand)
@@ -1134,11 +1134,12 @@ REGION_RegionOp(
                     r1BandEnd++;
                 }
 
-                (*nonOverlap1Func)(newReg,
+                if (!(*nonOverlap1Func)(newReg,
                                    r1,
                                    r1BandEnd,
                                    max(r1->top,ybot),
-                                   r1->bottom);
+                                   r1->bottom))
+                    return FALSE;
                 r1 = r1BandEnd;
             }
             while (r1 != r1End);
@@ -1154,11 +1155,12 @@ REGION_RegionOp(
                 r2BandEnd++;
             }
 
-            (*nonOverlap2Func)(newReg,
+            if (!(*nonOverlap2Func)(newReg,
                                r2,
                                r2BandEnd,
                                max(r2->top,ybot),
-                               r2->bottom);
+                               r2->bottom))
+                return FALSE;
             r2 = r2BandEnd;
         }
         while (r2 != r2End);
@@ -1216,7 +1218,7 @@ REGION_RegionOp(
 
     if (oldRects != &newReg->rdh.rcBound)
         ExFreePoolWithTag(oldRects, TAG_REGION);
-    return;
+    return TRUE;
 }
 
 /***********************************************************************
@@ -1235,7 +1237,7 @@ REGION_RegionOp(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_IntersectO(
     PREGION pReg,
@@ -1262,7 +1264,7 @@ REGION_IntersectO(
         {
             if (!REGION_bAddRect(pReg, left, top, right, bottom))
             {
-                return;
+                return FALSE;
             }
         }
 
@@ -1284,14 +1286,14 @@ REGION_IntersectO(
         }
     }
 
-    return;
+    return TRUE;
 }
 
 /***********************************************************************
  * REGION_IntersectRegion
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_IntersectRegion(
     PREGION newReg,
@@ -1307,12 +1309,13 @@ REGION_IntersectRegion(
     }
     else
     {
-        REGION_RegionOp(newReg,
+        if (!REGION_RegionOp(newReg,
                         reg1,
                         reg2,
                         REGION_IntersectO,
                         NULL,
-                        NULL);
+                        NULL))
+            return FALSE;
     }
 
     /* Can't alter newReg's extents before we call miRegionOp because
@@ -1321,6 +1324,7 @@ REGION_IntersectRegion(
      * way there's no checking against rectangles that will be nuked
      * due to coalescing, so we have to examine fewer rectangles. */
     REGION_SetExtents(newReg);
+    return TRUE;
 }
 
 /***********************************************************************
@@ -1341,7 +1345,7 @@ REGION_IntersectRegion(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_UnionNonO(
     PREGION pReg,
@@ -1354,7 +1358,7 @@ REGION_UnionNonO(
     {
         if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
         {
-            return;
+            return FALSE;
         }
 
         do
@@ -1365,7 +1369,7 @@ REGION_UnionNonO(
         while (r != rEnd);
     }
 
-    return;
+    return TRUE;
 }
 
 static __inline
@@ -1411,7 +1415,7 @@ REGION_bMergeRect(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_UnionO (
     PREGION pReg,
@@ -1426,12 +1430,12 @@ REGION_UnionO (
     {
         if (r1->left < r2->left)
         {
-            REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
+            if (!REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom)) return FALSE;
             r1++;
         }
         else
         {
-            REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
+            if (!REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom)) return FALSE;
             r2++;
         }
     }
@@ -1440,7 +1444,7 @@ REGION_UnionO (
     {
         do
         {
-            REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
+            if (!REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom)) return FALSE;
             r1++;
         }
         while (r1 != r1End);
@@ -1449,25 +1453,27 @@ REGION_UnionO (
     {
         while (r2 != r2End)
         {
-            REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
+            if (!REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom)) return FALSE;
             r2++;
         }
     }
 
-    return;
+    return TRUE;
 }
 
 /***********************************************************************
  * REGION_UnionRegion
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_UnionRegion(
     PREGION newReg,
     PREGION reg1,
     PREGION reg2)
 {
+    BOOL ret = TRUE;
+
     /* Checks all the simple cases
      * Region 1 and 2 are the same or region 1 is empty */
     if ((reg1 == reg2) || (reg1->rdh.nCount == 0) ||
@@ -1476,10 +1482,10 @@ REGION_UnionRegion(
     {
         if (newReg != reg2)
         {
-            REGION_CopyRegion(newReg, reg2);
+            ret = REGION_CopyRegion(newReg, reg2);
         }
 
-        return;
+        return ret;
     }
 
     /* If nothing to union (region 2 empty) */
@@ -1489,10 +1495,10 @@ REGION_UnionRegion(
     {
         if (newReg != reg1)
         {
-            REGION_CopyRegion(newReg, reg1);
+            ret = REGION_CopyRegion(newReg, reg1);
         }
 
-        return;
+        return ret;
     }
 
     /* Region 1 completely subsumes region 2 */
@@ -1504,10 +1510,10 @@ REGION_UnionRegion(
     {
         if (newReg != reg1)
         {
-            REGION_CopyRegion(newReg, reg1);
+            ret = REGION_CopyRegion(newReg, reg1);
         }
 
-        return;
+        return ret;
     }
 
     /* Region 2 completely subsumes region 1 */
@@ -1519,23 +1525,25 @@ REGION_UnionRegion(
     {
         if (newReg != reg2)
         {
-            REGION_CopyRegion(newReg, reg2);
+            ret = REGION_CopyRegion(newReg, reg2);
         }
 
-        return;
+        return ret;
     }
 
-    REGION_RegionOp(newReg,
+    if ((ret = REGION_RegionOp(newReg,
                     reg1,
                     reg2,
                     REGION_UnionO,
                     REGION_UnionNonO,
-                    REGION_UnionNonO);
-
+                    REGION_UnionNonO)))
+    {
     newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
     newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
     newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
     newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -1554,7 +1562,7 @@ REGION_UnionRegion(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_SubtractNonO1(
     PREGION pReg,
@@ -1567,7 +1575,7 @@ REGION_SubtractNonO1(
     {
         if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
         {
-            return;
+            return FALSE;
         }
 
         do
@@ -1578,7 +1586,7 @@ REGION_SubtractNonO1(
         while (r != rEnd);
     }
 
-    return;
+    return TRUE;
 }
 
 
@@ -1594,7 +1602,7 @@ REGION_SubtractNonO1(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_SubtractO(
     PREGION pReg,
@@ -1641,7 +1649,7 @@ REGION_SubtractO(
              * part of minuend to region and skip to next subtrahend. */
             if (!REGION_bAddRect(pReg, left, top, r2->left, bottom))
             {
-                return;
+                return FALSE;
             }
 
             left = r2->right;
@@ -1665,7 +1673,7 @@ REGION_SubtractO(
             {
                 if (!REGION_bAddRect(pReg, left, top, r1->right, bottom))
                 {
-                    return;
+                    return FALSE;
                 }
             }
 
@@ -1680,7 +1688,7 @@ REGION_SubtractO(
     {
         if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (r1End - r1)))
         {
-            return;
+            return FALSE;
         }
 
         /* Add remaining minuend rectangles to region. */
@@ -1696,7 +1704,7 @@ REGION_SubtractO(
         while (r1 != r1End);
     }
 
-    return;
+    return TRUE;
 }
 
 /*!
@@ -1711,7 +1719,7 @@ REGION_SubtractO(
  *
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_SubtractRegion(
     PREGION regD,
@@ -1723,16 +1731,16 @@ REGION_SubtractRegion(
         (regS->rdh.nCount == 0) ||
         (EXTENTCHECK(&regM->rdh.rcBound, &regS->rdh.rcBound) == 0))
     {
-        REGION_CopyRegion(regD, regM);
-        return;
+        return REGION_CopyRegion(regD, regM);
     }
 
-    REGION_RegionOp(regD,
+    if (!REGION_RegionOp(regD,
                     regM,
                     regS,
                     REGION_SubtractO,
                     REGION_SubtractNonO1,
-                    NULL);
+                    NULL))
+        return FALSE;
 
     /* Can't alter newReg's extents before we call miRegionOp because
      * it might be one of the source regions and miRegionOp depends
@@ -1740,13 +1748,14 @@ REGION_SubtractRegion(
      * way there's no checking against rectangles that will be nuked
      * due to coalescing, so we have to examine fewer rectangles. */
     REGION_SetExtents(regD);
+    return TRUE;
 }
 
 /***********************************************************************
  * REGION_XorRegion
  */
 static
-VOID
+BOOL
 FASTCALL
 REGION_XorRegion(
     PREGION dr,
@@ -1755,12 +1764,13 @@ REGION_XorRegion(
 {
     HRGN htra, htrb;
     PREGION tra, trb;
+    BOOL ret;
 
     // FIXME: Don't use a handle
     tra = REGION_AllocRgnWithHandle(sra->rdh.nCount + 1);
     if (tra == NULL)
     {
-        return;
+        return FALSE;
     }
     htra = tra->BaseObject.hHmgr;
 
@@ -1770,19 +1780,19 @@ REGION_XorRegion(
     {
         REGION_UnlockRgn(tra);
         GreDeleteObject(htra);
-        return;
+        return FALSE;
     }
     htrb = trb->BaseObject.hHmgr;
 
-    REGION_SubtractRegion(tra, sra, srb);
-    REGION_SubtractRegion(trb, srb, sra);
-    REGION_UnionRegion(dr, tra, trb);
+    ret = REGION_SubtractRegion(tra, sra, srb) &&
+          REGION_SubtractRegion(trb, srb, sra) &&
+          REGION_UnionRegion(dr, tra, trb);
     REGION_UnlockRgn(tra);
     REGION_UnlockRgn(trb);
 
     GreDeleteObject(htra);
     GreDeleteObject(htrb);
-    return;
+    return ret;
 }
 
 
@@ -1821,6 +1831,27 @@ REGION_SubtractRectFromRgn(
     return REGION_Complexity(prgnDest);
 }
 
+BOOL
+FASTCALL
+REGION_bCopy(
+    PREGION dst,
+    PREGION src)
+{
+    if ( !dst || !src ) return FALSE;
+    return REGION_CopyRegion( dst, src);
+}
+
+BOOL
+FASTCALL
+REGION_bIntersectRegion(
+    PREGION newReg,
+    PREGION reg1,
+    PREGION reg2)
+{
+    if ( !newReg || !reg1 || !reg2 ) return FALSE;
+    return REGION_IntersectRegion( newReg, reg1, reg2);
+}
+
 static
 BOOL
 REGION_bMakeSimpleFrameRgn(
@@ -2469,6 +2500,7 @@ IntGdiCombineRgn(
     PREGION prgnSrc2,
     INT iCombineMode)
 {
+    BOOL Ret = TRUE;
 
     if (prgnDest == NULL)
     {
@@ -2500,20 +2532,20 @@ IntGdiCombineRgn(
     switch (iCombineMode)
     {
         case RGN_AND:
-            REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
+            Ret = REGION_IntersectRegion(prgnDest, prgnSrc1, prgnSrc2);
             break;
         case RGN_OR:
-            REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
+            Ret = REGION_UnionRegion(prgnDest, prgnSrc1, prgnSrc2);
             break;
         case RGN_XOR:
-            REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
+            Ret = REGION_XorRegion(prgnDest, prgnSrc1, prgnSrc2);
             break;
         case RGN_DIFF:
-            REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
+            Ret = REGION_SubtractRegion(prgnDest, prgnSrc1, prgnSrc2);
             break;
     }
 
-    return REGION_Complexity(prgnDest);
+    return Ret ? REGION_Complexity(prgnDest) : ERROR;
 }
 
 INT
@@ -3600,8 +3632,9 @@ NtGdiCreateRoundRectRgn(
 {
     PREGION obj;
     HRGN hrgn;
-    INT asq, bsq, d, xd, yd;
-    RECTL rect;
+    int a, b, i, x, y;
+    INT64 asq, bsq, dx, dy, err;
+    RECT *rects;
 
     /* Make the dimensions sensible */
     if (left > right)
@@ -3618,95 +3651,75 @@ NtGdiCreateRoundRectRgn(
         bottom = tmp;
     }
 
-    ellipse_width = abs(ellipse_width);
-    ellipse_height = abs(ellipse_height);
+    /* the region is for the rectangle interior, but only at right and bottom for some reason */
+    right--;
+    bottom--;
 
-    /* Check parameters */
-    if (ellipse_width > right-left)
-        ellipse_width = right-left;
-    if (ellipse_height > bottom-top)
-        ellipse_height = bottom-top;
+    ellipse_width = min( right - left, abs( ellipse_width ));
+    ellipse_height = min( bottom - top, abs( ellipse_height ));
 
     /* Check if we can do a normal rectangle instead */
+
     if ((ellipse_width < 2) || (ellipse_height < 2))
         return NtGdiCreateRectRgn(left, top, right, bottom);
 
-    /* Create region */
-    d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64;
-    obj = REGION_AllocUserRgnWithHandle(d);
+    obj = REGION_AllocUserRgnWithHandle( ellipse_height );
     if (obj == NULL)
         return 0;
 
     hrgn = obj->BaseObject.hHmgr;
 
-    /* Ellipse algorithm, based on an article by K. Porter
-       in DDJ Graphics Programming Column, 8/89 */
-    asq = ellipse_width * ellipse_width / 4;        /* a^2 */
-    bsq = ellipse_height * ellipse_height / 4;      /* b^2 */
-    d = bsq - asq * ellipse_height / 2 + asq / 4;   /* b^2 - a^2b + a^2/4 */
-    xd = 0;
-    yd = asq * ellipse_height;                      /* 2a^2b */
+    obj->rdh.rcBound.left   = left;
+    obj->rdh.rcBound.top    = top;
+    obj->rdh.rcBound.right  = right;
+    obj->rdh.rcBound.bottom = bottom;
+    rects = obj->Buffer;
 
-    rect.left   = left + ellipse_width / 2;
-    rect.right  = right - ellipse_width / 2;
+    /* based on an algorithm by Alois Zingl */
 
-    /* Loop to draw first half of quadrant */
-    while (xd < yd)
-    {
-        /* If nearest pixel is toward the center */
-        if (d > 0)
-        {
-            /* Move toward center */
-            rect.top = top++;
-            rect.bottom = rect.top + 1;
-            REGION_UnionRectWithRgn(obj, &rect);
-            rect.top = --bottom;
-            rect.bottom = rect.top + 1;
-            REGION_UnionRectWithRgn(obj, &rect);
-            yd -= 2*asq;
-            d  -= yd;
-        }
+    a = ellipse_width - 1;
+    b = ellipse_height - 1;
+    asq = (INT64)8 * a * a;
+    bsq = (INT64)8 * b * b;
+    dx  = (INT64)4 * b * b * (1 - a);
+    dy  = (INT64)4 * a * a * (1 + (b % 2));
+    err = dx + dy + a * a * (b % 2);
 
-        /* Next horiz point */
-        rect.left--;
-        rect.right++;
-        xd += 2*bsq;
-        d  += bsq + xd;
-    }
+    x = 0;
+    y = ellipse_height / 2;
 
-    /* Loop to draw second half of quadrant */
-    d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
-    while (yd >= 0)
-    {
-        /* next vertical point */
-        rect.top = top++;
-        rect.bottom = rect.top + 1;
-        REGION_UnionRectWithRgn(obj, &rect);
-        rect.top = --bottom;
-        rect.bottom = rect.top + 1;
-        REGION_UnionRectWithRgn(obj, &rect);
+    rects[y].left = left;
+    rects[y].right = right;
 
-        /* If nearest pixel is outside ellipse */
-        if (d < 0)
+    while (x <= ellipse_width / 2)
+    {
+        INT64 e2 = 2 * err;
+        if (e2 >= dx)
         {
-            /* Move away from center */
-            rect.left--;
-            rect.right++;
-            xd += 2*bsq;
-            d  += xd;
+            x++;
+            err += dx += bsq;
+        }
+        if (e2 <= dy)
+        {
+            y++;
+            err += dy += asq;
+            rects[y].left = left + x;
+            rects[y].right = right - x;
         }
-
-        yd -= 2*asq;
-        d  += asq - yd;
     }
-
-    /* Add the inside rectangle */
-    if (top <= bottom)
+    for (i = 0; i < ellipse_height / 2; i++)
+    {
+        rects[i].left = rects[b - i].left;
+        rects[i].right = rects[b - i].right;
+        rects[i].top = top + i;
+        rects[i].bottom = rects[i].top + 1;
+    }
+    for (; i < ellipse_height; i++)
     {
-        rect.top = top;
-        rect.bottom = bottom;
-        REGION_UnionRectWithRgn(obj, &rect);
+        rects[i].top = bottom - ellipse_height + i;
+        rects[i].bottom = rects[i].top + 1;
     }
+    rects[ellipse_height / 2].top = top + ellipse_height / 2;  /* extend to top of rectangle */
 
     REGION_UnlockRgn(obj);
     return hrgn;
