Author: tkreuzer
Date: Tue Nov 4 20:37:54 2014
New Revision: 65253
URL: http://svn.reactos.org/svn/reactos?rev=65253&view=rev
Log:
[NTOSKRNL]
Fix the fix to ObSetSecurityDescriptorInfo. To understand the change: it is not only style change! The old code modified SecurityDescriptor, which must always stay the same in the loop!
Modified:
branches/kernel-fun/reactos/ntoskrnl/ob/obsecure.c
Modified: branches/kernel-fun/reactos/ntoskrnl/ob/obsecure.c
URL: http://svn.reactos.org/svn/reactos/branches/kernel-fun/reactos/ntoskrnl/ob/…
==============================================================================
--- branches/kernel-fun/reactos/ntoskrnl/ob/obsecure.c [iso-8859-1] (original)
+++ branches/kernel-fun/reactos/ntoskrnl/ob/obsecure.c [iso-8859-1] Tue Nov 4 20:37:54 2014
@@ -131,27 +131,26 @@
/* Get the object header */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
-
- /* Reference the old descriptor */
- OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
- NewDescriptor = OldDescriptor;
-
- /* Set the SD information */
- Status = SeSetSecurityDescriptorInfo(Object,
- SecurityInformation,
- SecurityDescriptor,
- &NewDescriptor,
- PoolType,
- GenericMapping);
- if (!NT_SUCCESS(Status))
- {
- /* We failed, dereference the old one */
- if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
- return Status;
- }
-
while (TRUE)
{
+ /* Reference the old descriptor */
+ OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
+ NewDescriptor = OldDescriptor;
+
+ /* Set the SD information */
+ Status = SeSetSecurityDescriptorInfo(Object,
+ SecurityInformation,
+ SecurityDescriptor,
+ &NewDescriptor,
+ PoolType,
+ GenericMapping);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, dereference the old one */
+ if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
+ break;
+ }
+
/* Now add this to the cache */
Status = ObLogSecurityDescriptor(NewDescriptor,
&CachedDescriptor,
@@ -174,18 +173,15 @@
CachedDescriptor,
OldDescriptor);
- /* Get the security descriptor */
- SecurityDescriptor = ExGetObjectFastReference(OldValue);
- Count = ExGetCountFastReference(OldValue);
-
/* Make sure the swap worked */
- if (SecurityDescriptor == OldDescriptor)
+ if (ExGetObjectFastReference(OldValue) == OldDescriptor)
{
/* Flush waiters */
ObpAcquireObjectLock(ObjectHeader);
ObpReleaseObjectLock(ObjectHeader);
/* And dereference the old one */
+ Count = ExGetCountFastReference(OldValue);
ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
break;
}
Author: tkreuzer
Date: Tue Nov 4 20:20:45 2014
New Revision: 65252
URL: http://svn.reactos.org/svn/reactos?rev=65252&view=rev
Log:
[WIN32K]
- Fix completely broken REGION_CropAndOffsetRegion
- Make sure iType is correctly set in NtGdiGetRegionData
Modified:
trunk/reactos/win32ss/gdi/ntgdi/region.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] Tue Nov 4 20:20:45 2014
@@ -577,7 +577,7 @@
pReg->rdh.iType = RDH_RECTANGLES;
}
-// FIXME: This seems to be wrong
+// FIXME: This function needs review and testing
/***********************************************************************
* REGION_CropAndOffsetRegion
*/
@@ -649,82 +649,106 @@
else // Region box and clipping rect appear to intersect
{
PRECTL lpr, rpr;
- ULONG i, j, clipa, clipb;
- INT left = rgnSrc->rdh.rcBound.right + off->x;
- INT right = rgnSrc->rdh.rcBound.left + off->x;
-
- for (clipa = 0; (rgnSrc->Buffer + clipa)->bottom <= rect->top; clipa++)
- // Region and rect intersect so we stop before clipa > rgnSrc->rdh.nCount
- ; // skip bands above the clipping rectangle
-
+ ULONG i, j, clipa, clipb, nRgnSize;
+ INT left = MAXLONG;
+ INT right = MINLONG;
+ INT top = MAXLONG;
+ INT bottom = MINLONG;
+
+ /* Skip all rects that are completely above our intersect rect */
+ for (clipa = 0; clipa < rgnSrc->rdh.nCount; clipa++)
+ {
+ /* bottom is exclusive, so break when we go above it */
+ if (rgnSrc->Buffer[clipa].bottom > rect->top) break;
+ }
+
+ /* Bail out, if there is nothing left */
+ if (clipa == rgnSrc->rdh.nCount) goto empty;
+
+ /* Find the last rect that is still within the intersect rect (exclusive) */
for (clipb = clipa; clipb < rgnSrc->rdh.nCount; clipb++)
- if ((rgnSrc->Buffer + clipb)->top >= rect->bottom)
- break; // and below it
+ {
+ /* bottom is exclusive, so stop, when we start at that y pos */
+ if (rgnSrc->Buffer[clipb].top >= rect->bottom) break;
+ }
+
+ /* Bail out, if there is nothing left */
+ if (clipb == clipa) goto empty;
// clipa - index of the first rect in the first intersecting band
- // clipb - index of the last rect in the last intersecting band
-
- if ((rgnDst != rgnSrc) && (rgnDst->rdh.nCount < (i = (clipb - clipa))))
+ // clipb - index of the last rect in the last intersecting band plus 1
+
+ /* Check if the buffer in the dest region is large enough,
+ otherwise allocate a new one */
+ nRgnSize = (clipb - clipa) * sizeof(RECT);
+ if ((rgnDst != rgnSrc) && (rgnDst->rdh.nRgnSize < nRgnSize))
{
PRECTL temp;
- temp = ExAllocatePoolWithTag(PagedPool, i * sizeof(RECT), TAG_REGION);
+ temp = ExAllocatePoolWithTag(PagedPool, nRgnSize, TAG_REGION);
if (!temp)
return ERROR;
- if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
- ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // free the old buffer
+ /* Free the old buffer */
+ if (rgnDst->Buffer && (rgnDst->Buffer != &rgnDst->rdh.rcBound))
+ ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION);
+
rgnDst->Buffer = temp;
- rgnDst->rdh.nCount = i;
- rgnDst->rdh.nRgnSize = i * sizeof(RECT);
- }
-
+ rgnDst->rdh.nCount = 0;
+ rgnDst->rdh.nRgnSize = nRgnSize;
+ rgnDst->rdh.iType = RDH_RECTANGLES;
+ }
+
+ /* Loop all rects within the intersect rect from the y perspective */
for (i = clipa, j = 0; i < clipb ; i++)
{
// i - src index, j - dst index, j is always <= i for obvious reasons
- lpr = rgnSrc->Buffer + i;
-
- if (lpr->left < rect->right && lpr->right > rect->left)
+ lpr = &rgnSrc->Buffer[i];
+
+ /* Make sure the source rect is not retarded */
+ ASSERT(lpr->bottom > rect->top);
+ ASSERT(lpr->right > rect->left);
+
+ /* We already checked above, this should hold true */
+ ASSERT(lpr->bottom > rect->top);
+ ASSERT(lpr->top < rect->bottom);
+
+ /* Check if this rect is really inside the intersect rect */
+ if ((lpr->left < rect->right) && (lpr->right > rect->left))
{
- rpr = rgnDst->Buffer + j;
-
- rpr->top = lpr->top + off->y;
- rpr->bottom = lpr->bottom + off->y;
- rpr->left = ((lpr->left > rect->left) ? lpr->left : rect->left) + off->x;
- rpr->right = ((lpr->right < rect->right) ? lpr->right : rect->right) + off->x;
-
+ rpr = &rgnDst->Buffer[j];
+
+ /* Crop the rect with the intersect rect and add offset */
+ rpr->top = max(lpr->top, rect->top) + off->y;
+ rpr->bottom = min(lpr->bottom, rect->bottom) + off->y;
+ rpr->left = max(lpr->left, rect->left) + off->x;
+ rpr->right = min(lpr->right, rect->right) + off->y;
+
+ /* Make sure the resulting rect is not retarded */
+ ASSERT(lpr->bottom > rect->top);
+ ASSERT(lpr->right > rect->left);
+
+ /* Track new bounds */
if (rpr->left < left) left = rpr->left;
if (rpr->right > right) right = rpr->right;
-
+ if (rpr->top < top) top = rpr->top;
+ if (rpr->bottom > bottom) bottom = rpr->bottom;
+
+ /* Next target rect */
j++;
}
}
if (j == 0) goto empty;
+ /* Update the bounds rect */
rgnDst->rdh.rcBound.left = left;
rgnDst->rdh.rcBound.right = right;
-
- left = rect->top + off->y;
- right = rect->bottom + off->y;
-
- rgnDst->rdh.nCount = j--;
- for (i = 0; i <= j; i++) // Fixup top band
- if ((rgnDst->Buffer + i)->top < left)
- (rgnDst->Buffer + i)->top = left;
- else
- break;
-
- for (i = j; i > 0; i--) // Fixup bottom band
- if ((rgnDst->Buffer + i)->bottom > right)
- (rgnDst->Buffer + i)->bottom = right;
- else
- break;
-
- rgnDst->rdh.rcBound.top = (rgnDst->Buffer)->top;
- rgnDst->rdh.rcBound.bottom = (rgnDst->Buffer + j)->bottom;
-
- rgnDst->rdh.iType = RDH_RECTANGLES;
+ rgnDst->rdh.rcBound.top = top;
+ rgnDst->rdh.rcBound.bottom = bottom;
+
+ /* Set new rect count */
+ rgnDst->rdh.nCount = j;
}
return REGION_Complexity(rgnDst);
@@ -732,15 +756,9 @@
empty:
if (!rgnDst->Buffer)
{
- rgnDst->Buffer = ExAllocatePoolWithTag(PagedPool, RGN_DEFAULT_RECTS * sizeof(RECT), TAG_REGION);
- if (rgnDst->Buffer)
- {
- rgnDst->rdh.nCount = RGN_DEFAULT_RECTS;
- rgnDst->rdh.nRgnSize = RGN_DEFAULT_RECTS * sizeof(RECT);
- }
- else
- return ERROR;
- }
+ rgnDst->Buffer = &rgnDst->rdh.rcBound;
+ }
+
EMPTY_REGION(rgnDst);
return NULLREGION;
}
@@ -4004,6 +4022,7 @@
ProbeForWrite(lpRgnData, cjSize, sizeof(ULONG));
RtlCopyMemory(lpRgnData, &prgn->rdh, sizeof(RGNDATAHEADER));
RtlCopyMemory(lpRgnData->Buffer, prgn->Buffer, cjRects);
+ lpRgnData->rdh.iType = RDH_RECTANGLES;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{