Author: jimtabor
Date: Wed Jun 4 11:07:47 2008
New Revision: 33855
URL: http://svn.reactos.org/svn/reactos?rev=33855&view=rev
Log:
Prevent a crash if the list is empty and check for zero. If (List is Empty! DCE!) is called before the crash, this means we have a thread that is not finished running before shutdown. There is a proper way for handling this
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c [iso-8859-1] Wed Jun 4 11:07:47 2008
@@ -632,6 +632,7 @@
KeEnterCriticalRegion();
do
{
+ if (!pDCE) break;
if (pDCE->hwndCurrent == Window->hSelf)
{
if (!(pDCE->DCXFlags & DCX_CACHE)) /* owned or Class DCE*/
@@ -651,6 +652,7 @@
Window->Wnd->Style & CS_OWNDC) /* owned DCE*/
{
pDCE = DceFreeDCE(pDCE, FALSE);
+ if (!pDCE) break;
Window->Dce = NULL;
continue;
}
Author: jimtabor
Date: Wed Jun 4 01:10:49 2008
New Revision: 33849
URL: http://svn.reactos.org/svn/reactos?rev=33849&view=rev
Log:
No need to do it twice.
Modified:
trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Wed Jun 4 01:10:49 2008
@@ -1506,8 +1506,6 @@
// Set this Brush to inaccessible mode and to an Owner of NONE.
// if (OwnerMask == GDI_OBJ_HMGR_NONE) Owner = OwnerMask;
- // Deny user access to User Data.
- pEntry->UserData = NULL; // This hBR is inaccessible!
if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, Owner))
return FALSE;
Author: jimtabor
Date: Wed Jun 4 00:43:11 2008
New Revision: 33847
URL: http://svn.reactos.org/svn/reactos?rev=33847&view=rev
Log:
Implement IntGdiSetBrushOwner and IntGdiAllocObjAttr.
Modified:
trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Wed Jun 4 00:43:11 2008
@@ -1422,11 +1422,107 @@
/** PUBLIC FUNCTIONS **********************************************************/
+/*
+ Since Brush/Pen and Region objects are sharable,,, we can just use
+ UserHeapAlloc to allocate the small attribute objects.
+
+ Example Allocating:
+
+ // Save Kernel Space Pointer
+ (PGDIBRUSHOBJ)->pBrushAttr = IntGdiAllocObjAttr(GDIObjType_BRUSH_TYPE);
+
+ // Kernel Space to User Space Pointer
+ (PGDI_TABLE_ENTRY)->UserData = UserHeapAddressToUser(pBrushAttr);
+
+ Example Freeing:
+
+ (PGDI_TABLE_ENTRY)->UserData = NULL; // Zero the user ptr.
+ UserHeapFree((PGDIBRUSHOBJ)->pBrushAttr); // Free from kernel ptr.
+ (PGDIBRUSHOBJ)->pBrushAttr = NULL;
+
+ Notes:
+ Testing with DC_ATTR works but has drawing difficulties. This could be due
+ to a bug in user share heap allocation and deallocation. The test did not
+ include additional deallocations until the DC was freed. So it was always
+ allocated to the DC. Space between allocations was not even and at less
+ than sizeof(DC_ATTR).
+
+ */
+PVOID
+FASTCALL
+IntGdiAllocObjAttr(GDIOBJTYPE Type)
+{
+ PVOID pMemAttr = NULL;
+
+ switch( Type )
+ {
+ case GDIObjType_DC_TYPE:
+ pMemAttr = UserHeapAlloc(sizeof(DC_ATTR));
+ if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(DC_ATTR));
+ break;
+ case GDIObjType_RGN_TYPE:
+ pMemAttr = UserHeapAlloc(sizeof(RGN_ATTR));
+ if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(RGN_ATTR));
+ break;
+ case GDIObjType_BRUSH_TYPE:
+ pMemAttr = UserHeapAlloc(sizeof(BRUSH_ATTR));
+ if (pMemAttr) RtlZeroMemory(pMemAttr, sizeof(BRUSH_ATTR));
+ break;
+ default:
+ break;
+ }
+ return pMemAttr;
+}
+
+
BOOL
FASTCALL
IntGdiSetBrushOwner(PGDIBRUSHOBJ pbr, DWORD OwnerMask)
{
- // Inc/Dec share locks and process counts.
+ HBRUSH hBR;
+ PEPROCESS Owner = NULL;
+ PGDI_TABLE_ENTRY pEntry = NULL;
+
+ if (!pbr) return FALSE;
+
+ hBR = pbr->BaseObject.hHmgr;
+
+ if (!hBR || (GDI_HANDLE_GET_TYPE(hBR) != GDI_OBJECT_TYPE_BRUSH))
+ return FALSE;
+ else
+ {
+ INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hBR);
+ pEntry = &GdiHandleTable->Entries[Index];
+ }
+
+ if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL)
+ {
+ GDIOBJ_ShareUnlockObjByPtr((POBJ)pbr);
+ return TRUE;
+ }
+
+ if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
+ {
+ // Set this Brush to inaccessible mode and to an Owner of NONE.
+// if (OwnerMask == GDI_OBJ_HMGR_NONE) Owner = OwnerMask;
+
+ // Deny user access to User Data.
+ pEntry->UserData = NULL; // This hBR is inaccessible!
+ if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, Owner))
+ return FALSE;
+
+ // Deny user access to User Data.
+ pEntry->UserData = NULL; // This hBR is inaccessible!
+ }
+
+ if (OwnerMask == GDI_OBJ_HMGR_POWNED)
+ {
+ if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, PsGetCurrentProcess() ))
+ return FALSE;
+
+ // Allow user access to User Data.
+ pEntry->UserData = pbr->pBrushAttr;
+ }
return TRUE;
}