[WIN32K]
authorThomas Faber <thomas.faber@reactos.org>
Tue, 21 Oct 2014 14:28:16 +0000 (14:28 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Tue, 21 Oct 2014 14:28:16 +0000 (14:28 +0000)
- Fix DCE list entry handling
CORE-8669 #resolve

svn path=/trunk/; revision=64868

reactos/win32ss/user/ntuser/dce.h
reactos/win32ss/user/ntuser/windc.c

index 5c7e932..882385c 100644 (file)
@@ -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);
index b7d3fc3..afee0f3 100644 (file)
@@ -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))
   {