- If dc is window owned and not class owned do not set class if null pdce. Added debug prints to locate reentrancy issues due to a race condition.
- Add more checks to find dead windows.

svn path=/trunk/; revision=45671
This commit is contained in:
James Tabor
2010-02-23 15:42:08 +00:00
parent e09b719f49
commit 2afc207a55
5 changed files with 41 additions and 17 deletions
@@ -48,6 +48,7 @@ typedef struct tagDCE
#define DCX_DCPOWNED 0x00008000
#define DCX_NOCLIPCHILDREN 0x00080000
#define DCX_NORECOMPUTE 0x00100000
#define DCX_INDESTROY 0x00400000
BOOL FASTCALL DCE_Cleanup(PDCE pDce);
PDCE FASTCALL DceAllocDCE(PWINDOW_OBJECT Window, DCE_TYPE Type);
@@ -238,7 +238,7 @@ BOOL UserSetCursorPos( INT x, INT y)
* User32 macro NtUserShowCursor */
int UserShowCursor(BOOL bShow)
{
PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo();;
PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo();
HDC hdcScreen;
if (!(hdcScreen = IntGetScreenDC()))
+4 -2
View File
@@ -92,7 +92,9 @@ VIS_ComputeVisibleRegion(
(PreviousWnd == Wnd && ClipSiblings))
{
CurrentSibling = CurrentWindow->spwndChild;
while (CurrentSibling != NULL && CurrentSibling != PreviousWindow)
while ( CurrentSibling != NULL &&
CurrentSibling != PreviousWindow &&
CurrentSibling->Wnd )
{
CurrentSiblingWnd = CurrentSibling->Wnd;
if ((CurrentSiblingWnd->style & WS_VISIBLE) &&
@@ -121,7 +123,7 @@ VIS_ComputeVisibleRegion(
if (ClipChildren)
{
CurrentWindow = Window->spwndChild;
while (CurrentWindow)
while (CurrentWindow && CurrentWindow->Wnd)
{
CurrentWnd = CurrentWindow->Wnd;
if ((CurrentWnd->style & WS_VISIBLE) &&
+34 -11
View File
@@ -181,7 +181,7 @@ DceDeleteClipRgn(DCE* Dce)
}
else if (Dce->hrgnClip != NULL)
{
REGION_FreeRgnByHandle(Dce->hrgnClip);
GDIOBJ_FreeObjByHandle(Dce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
}
Dce->hrgnClip = NULL;
@@ -193,7 +193,7 @@ DceDeleteClipRgn(DCE* Dce)
static INT FASTCALL
DceReleaseDC(DCE* dce, BOOL EndPaint)
{
if (DCX_DCEBUSY != (dce->DCXFlags & (DCX_DCEEMPTY | DCX_DCEBUSY)))
if (DCX_DCEBUSY != (dce->DCXFlags & (DCX_INDESTROY | DCX_DCEEMPTY | DCX_DCEBUSY)))
{
return 0;
}
@@ -573,6 +573,12 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
}
else if (ClipRegion != NULL)
{
if (Dce->hrgnClip != NULL)
{
DPRINT1("Should not be called!!\n");
GDIOBJ_FreeObjByHandle(Dce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
Dce->hrgnClip = NULL;
}
Dce->hrgnClip = ClipRegion;
}
@@ -621,6 +627,8 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
pLE = pdce->List.Flink;
ret = CONTAINING_RECORD(pLE, DCE, List);
pdce->DCXFlags |= DCX_INDESTROY;
if (Force && !GDIOBJ_OwnedByCurrentProcess(pdce->hDC))
{
DPRINT("Change ownership for DCE! -> %x\n" , pdce);
@@ -638,9 +646,9 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
if (!Hit) IntGdiDeleteDC(pdce->hDC, TRUE);
if (pdce->hrgnClip && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
if (pdce->hrgnClip && !(pdce->DCXFlags & DCX_KEEPCLIPRGN))
{
REGION_FreeRgnByHandle(pdce->hrgnClip);
GDIOBJ_FreeObjByHandle(pdce->hrgnClip, GDI_OBJECT_TYPE_REGION|GDI_OBJECT_TYPE_SILENT);
pdce->hrgnClip = NULL;
}
@@ -673,7 +681,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
if (DCECount <= 0)
{
DPRINT1("No Entry!\n");
DPRINT1("FreeWindowDCE No Entry! %d\n",DCECount);
return;
}
@@ -681,8 +689,16 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
pDCE = CONTAINING_RECORD(pLE, DCE, List);
do
{
if (!pDCE) break;
if (IsListEmpty(&pDCE->List)) break;
if (!pDCE)
{
DPRINT1("FreeWindowDCE No DCE Pointer!\n");
break;
}
if (IsListEmpty(&pDCE->List))
{
DPRINT1("FreeWindowDCE List is Empty!!!!\n");
break;
}
if ( pDCE->hwndCurrent == Window->hSelf &&
!(pDCE->DCXFlags & DCX_DCEEMPTY) )
{
@@ -700,7 +716,10 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
DPRINT("POWNED DCE going Cheap!! DCX_CACHE!! hDC-> %x \n", pDCE->hDC);
if (!IntGdiSetDCOwnerEx( pDCE->hDC, GDI_OBJ_HMGR_NONE, FALSE))
return;
{
DPRINT1("Fail Owner Switch hDC-> %x \n", pDCE->hDC);
break;
}
/* Do not change owner so thread can clean up! */
}
else if (Window->Wnd->pcls->style & CS_OWNDC) /* owned DCE*/
@@ -711,6 +730,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
}
else
{
DPRINT1("Not POWNED or CLASSDC hwndCurrent -> %x \n", pDCE->hwndCurrent);
ASSERT(FALSE);
}
}
@@ -825,7 +845,7 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
{
if(!pDCE) break;
if(pLE == &LEDce) break;
if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
if (0 == (pDCE->DCXFlags & (DCX_DCEEMPTY|DCX_INDESTROY)))
{
if (Window->hSelf == pDCE->hwndCurrent)
{
@@ -902,9 +922,12 @@ IntWindowFromDC(HDC hDc)
Dce = CONTAINING_RECORD(pLE, DCE, List);
do
{
if(Dce->hDC == hDc)
if (Dce->hDC == hDc)
{
Ret = Dce->hwndCurrent;
if (Dce->DCXFlags & DCX_INDESTROY)
Ret = NULL;
else
Ret = Dce->hwndCurrent;
break;
}
pLE = Dce->List.Flink;
@@ -2057,9 +2057,7 @@ AllocErr:
}
else if ( Wnd->pcls->style & CS_OWNDC)
{ /* Allocate a DCE for this window. */
PDCE pDce = DceAllocDCE(Window, DCE_WINDOW_DC);
if (!Wnd->pcls->pdce)
Wnd->pcls->pdce = pDce;
DceAllocDCE(Window, DCE_WINDOW_DC);
}
Pos.x = x;