mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[WIN32K]
- Fix DCE list entry handling CORE-8669 #resolve svn path=/trunk/; revision=64868
This commit is contained in:
parent
268d1c62fe
commit
7b84cd051b
|
@ -44,7 +44,7 @@ typedef struct tagDCE
|
|||
INIT_FUNCTION NTSTATUS NTAPI InitDCEImpl(VOID);
|
||||
PDCE FASTCALL DceAllocDCE(PWND Window, DCE_TYPE Type);
|
||||
HWND FASTCALL IntWindowFromDC(HDC hDc);
|
||||
PDCE FASTCALL DceFreeDCE(PDCE dce, BOOLEAN Force);
|
||||
void FASTCALL DceFreeDCE(PDCE dce, BOOLEAN Force);
|
||||
void FASTCALL DceEmptyCache(void);
|
||||
VOID FASTCALL DceResetActiveDCEs(PWND Window);
|
||||
void FASTCALL DceFreeClassDCE(HDC);
|
||||
|
|
|
@ -51,15 +51,16 @@ DCE*
|
|||
FASTCALL
|
||||
DceGetDceFromDC(HDC hdc)
|
||||
{
|
||||
LIST_ENTRY* Entry = LEDce.Flink;
|
||||
PLIST_ENTRY ListEntry;
|
||||
DCE* dce;
|
||||
|
||||
while (Entry != &LEDce)
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
dce = CONTAINING_RECORD(Entry, DCE, List);
|
||||
dce = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (dce->hDC == hdc)
|
||||
return dce;
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -247,7 +248,7 @@ noparent:
|
|||
|
||||
if (Dce->hrgnClip != NULL)
|
||||
RgnClip = REGION_LockRgn(Dce->hrgnClip);
|
||||
|
||||
|
||||
if (RgnClip)
|
||||
{
|
||||
IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_AND);
|
||||
|
@ -330,18 +331,16 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
|
|||
#if 0 // Need to research and fix before this is a "growing" issue.
|
||||
if (++DCECache > 32)
|
||||
{
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (!(pDCE->DCXFlags & DCX_DCEBUSY))
|
||||
{ /* Free the unused cache DCEs. */
|
||||
pDCE = DceFreeDCE(pDCE, TRUE);
|
||||
if (!pDCE) break;
|
||||
continue;
|
||||
DceFreeDCE(pDCE, TRUE);
|
||||
}
|
||||
}
|
||||
while (pLE != &LEDce );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -359,7 +358,7 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
BOOL bUpdateVisRgn = TRUE;
|
||||
HDC hDC = NULL;
|
||||
PPROCESSINFO ppi;
|
||||
PLIST_ENTRY pLE;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
if (NULL == Wnd)
|
||||
{
|
||||
|
@ -463,15 +462,11 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
DCE* DceEmpty = NULL;
|
||||
DCE* DceUnused = NULL;
|
||||
KeEnterCriticalRegion();
|
||||
pLE = LEDce.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
// The reason for this you may ask?
|
||||
// Well, it seems ReactOS calls GetDC without first creating a desktop DC window!
|
||||
// Need to test for null here. Not sure if this is a bug or a feature.
|
||||
// First time use hax, need to use DceAllocDCE during window display init.
|
||||
if (!Dce) break;
|
||||
Dce = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
//
|
||||
// The way I understand this, you can have more than one DC per window.
|
||||
// Only one Owned if one was requested and saved and one Cached.
|
||||
|
@ -490,10 +485,7 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
break;
|
||||
}
|
||||
}
|
||||
pLE = Dce->List.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
|
||||
|
@ -510,20 +502,19 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
else // If we are here, we are POWNED or having CLASS.
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
pLE = LEDce.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
{ // Check for Window handle than HDC match for CLASS.
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
Dce = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
// Check for Window handle than HDC match for CLASS.
|
||||
if (Dce->hwndCurrent == Wnd->head.h)
|
||||
{
|
||||
bUpdateVisRgn = FALSE;
|
||||
break;
|
||||
}
|
||||
if (Dce->hDC == hDC) break;
|
||||
pLE = Dce->List.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) &&
|
||||
|
@ -554,11 +545,8 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
* http://www.reactos.org/archives/public/ros-dev/2008-July/010498.html
|
||||
* http://www.reactos.org/archives/public/ros-dev/2008-July/010499.html
|
||||
*/
|
||||
if (pLE != &LEDce)
|
||||
{
|
||||
RemoveEntryList(&Dce->List);
|
||||
InsertHeadList(&LEDce, &Dce->List);
|
||||
}
|
||||
RemoveEntryList(&Dce->List);
|
||||
InsertHeadList(&LEDce, &Dce->List);
|
||||
|
||||
/* Introduced in rev 6691 and modified later. */
|
||||
if ( (Flags & DCX_INTERSECTUPDATE) && !ClipRegion )
|
||||
|
@ -637,17 +625,13 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
|||
/***********************************************************************
|
||||
* DceFreeDCE
|
||||
*/
|
||||
PDCE FASTCALL
|
||||
void FASTCALL
|
||||
DceFreeDCE(PDCE pdce, BOOLEAN Force)
|
||||
{
|
||||
DCE *ret;
|
||||
PLIST_ENTRY pLE;
|
||||
BOOL Hit = FALSE;
|
||||
|
||||
if (NULL == pdce) return NULL;
|
||||
|
||||
pLE = pdce->List.Flink;
|
||||
ret = CONTAINING_RECORD(pLE, DCE, List);
|
||||
ASSERT(pdce != NULL);
|
||||
if (NULL == pdce) return;
|
||||
|
||||
pdce->DCXFlags |= DCX_INDESTROY;
|
||||
|
||||
|
@ -683,18 +667,10 @@ DceFreeDCE(PDCE pdce, BOOLEAN Force)
|
|||
|
||||
RemoveEntryList(&pdce->List);
|
||||
|
||||
if (IsListEmpty(&pdce->List))
|
||||
{
|
||||
ERR("List is Empty! DCE! -> %p\n" , pdce);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExFreePoolWithTag(pdce, USERTAG_DCE);
|
||||
|
||||
DCECount--;
|
||||
TRACE("Freed DCE's! %d \n", DCECount);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -706,7 +682,7 @@ void FASTCALL
|
|||
DceFreeWindowDCE(PWND Window)
|
||||
{
|
||||
PDCE pDCE;
|
||||
PLIST_ENTRY pLE;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
if (DCECount <= 0)
|
||||
{
|
||||
|
@ -714,20 +690,11 @@ DceFreeWindowDCE(PWND Window)
|
|||
return;
|
||||
}
|
||||
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if (!pDCE)
|
||||
{
|
||||
ERR("FreeWindowDCE No DCE Pointer!\n");
|
||||
break;
|
||||
}
|
||||
if (IsListEmpty(&pDCE->List))
|
||||
{
|
||||
ERR("FreeWindowDCE List is Empty!!!!\n");
|
||||
break;
|
||||
}
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if ( pDCE->hwndCurrent == Window->head.h &&
|
||||
!(pDCE->DCXFlags & DCX_DCEEMPTY) )
|
||||
{
|
||||
|
@ -755,8 +722,7 @@ DceFreeWindowDCE(PWND Window)
|
|||
}
|
||||
else if (Window->pcls->style & CS_OWNDC) /* Owned DCE */
|
||||
{
|
||||
pDCE = DceFreeDCE(pDCE, FALSE);
|
||||
if (!pDCE) break;
|
||||
DceFreeDCE(pDCE, FALSE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -785,76 +751,61 @@ DceFreeWindowDCE(PWND Window)
|
|||
pDCE->pwndOrg = pDCE->pwndClip = NULL;
|
||||
}
|
||||
}
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
}
|
||||
|
||||
void FASTCALL
|
||||
DceFreeClassDCE(HDC hDC)
|
||||
{
|
||||
PDCE pDCE;
|
||||
PLIST_ENTRY pLE;
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if(!pDCE) break;
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (pDCE->hDC == hDC)
|
||||
{
|
||||
pDCE = DceFreeDCE(pDCE, TRUE); // Might have gone cheap!
|
||||
if (!pDCE) break;
|
||||
continue;
|
||||
DceFreeDCE(pDCE, TRUE); // Might have gone cheap!
|
||||
}
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
}
|
||||
|
||||
void FASTCALL
|
||||
DceFreeThreadDCE(PTHREADINFO pti)
|
||||
{
|
||||
PDCE pDCE;
|
||||
PLIST_ENTRY pLE;
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if(!pDCE) break;
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (pDCE->ptiOwner == pti)
|
||||
{
|
||||
if (pDCE->DCXFlags & DCX_CACHE)
|
||||
{
|
||||
pDCE = DceFreeDCE(pDCE, TRUE);
|
||||
if (!pDCE) break;
|
||||
continue;
|
||||
DceFreeDCE(pDCE, TRUE);
|
||||
}
|
||||
}
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
DceEmptyCache(VOID)
|
||||
{
|
||||
PDCE pDCE;
|
||||
PLIST_ENTRY pLE;
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if(!pDCE) break;
|
||||
pDCE = DceFreeDCE(pDCE, TRUE);
|
||||
if(!pDCE) break;
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
DceFreeDCE(pDCE, TRUE);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -865,19 +816,18 @@ DceResetActiveDCEs(PWND Window)
|
|||
PWND CurrentWindow;
|
||||
INT DeltaX;
|
||||
INT DeltaY;
|
||||
PLIST_ENTRY pLE;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
if (NULL == Window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pLE = LEDce.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if(!pDCE) break;
|
||||
if(pLE == &LEDce) break;
|
||||
pDCE = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (0 == (pDCE->DCXFlags & (DCX_DCEEMPTY|DCX_INDESTROY)))
|
||||
{
|
||||
if (Window->head.h == pDCE->hwndCurrent)
|
||||
|
@ -892,8 +842,6 @@ DceResetActiveDCEs(PWND Window)
|
|||
CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
|
||||
if (NULL == CurrentWindow)
|
||||
{
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -901,8 +849,6 @@ DceResetActiveDCEs(PWND Window)
|
|||
if (!GreIsHandleValid(pDCE->hDC) ||
|
||||
(dc = DC_LockDc(pDCE->hDC)) == NULL)
|
||||
{
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
continue;
|
||||
}
|
||||
if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow))
|
||||
|
@ -937,23 +883,21 @@ DceResetActiveDCEs(PWND Window)
|
|||
DceUpdateVisRgn(pDCE, CurrentWindow, pDCE->DCXFlags);
|
||||
IntGdiSetHookFlags(pDCE->hDC, DCHF_VALIDATEVISRGN);
|
||||
}
|
||||
pLE = pDCE->List.Flink;
|
||||
pDCE = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
}
|
||||
|
||||
HWND FASTCALL
|
||||
IntWindowFromDC(HDC hDc)
|
||||
{
|
||||
DCE *Dce;
|
||||
PLIST_ENTRY pLE;
|
||||
PLIST_ENTRY ListEntry;
|
||||
HWND Ret = NULL;
|
||||
|
||||
pLE = LEDce.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
Dce = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (Dce->hDC == hDc)
|
||||
{
|
||||
if (Dce->DCXFlags & DCX_INDESTROY)
|
||||
|
@ -962,10 +906,7 @@ IntWindowFromDC(HDC hDc)
|
|||
Ret = Dce->hwndCurrent;
|
||||
break;
|
||||
}
|
||||
pLE = Dce->List.Flink;
|
||||
Dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
@ -973,25 +914,22 @@ INT FASTCALL
|
|||
UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
|
||||
{
|
||||
PDCE dce;
|
||||
PLIST_ENTRY pLE;
|
||||
PLIST_ENTRY ListEntry;
|
||||
INT nRet = 0;
|
||||
BOOL Hit = FALSE;
|
||||
|
||||
TRACE("%p %p\n", Window, hDc);
|
||||
pLE = LEDce.Flink;
|
||||
dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
do
|
||||
ListEntry = LEDce.Flink;
|
||||
while (ListEntry != &LEDce)
|
||||
{
|
||||
if(!dce) break;
|
||||
dce = CONTAINING_RECORD(ListEntry, DCE, List);
|
||||
ListEntry = ListEntry->Flink;
|
||||
if (dce->hDC == hDc)
|
||||
{
|
||||
Hit = TRUE;
|
||||
break;
|
||||
}
|
||||
pLE = dce->List.Flink;
|
||||
dce = CONTAINING_RECORD(pLE, DCE, List);
|
||||
}
|
||||
while (pLE != &LEDce );
|
||||
|
||||
if ( Hit && (dce->DCXFlags & DCX_DCEBUSY))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue