[ros-diffs] [jimtabor] 45293: [Win32k] - Add back removed window dce support routine. Fixed list handling and implemented thread cleanup for dces.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Thu Jan 28 02:00:09 CET 2010


Author: jimtabor
Date: Thu Jan 28 02:00:09 2010
New Revision: 45293

URL: http://svn.reactos.org/svn/reactos?rev=45293&view=rev
Log:
[Win32k]
- Add back removed window dce support routine. Fixed list handling and implemented thread cleanup for dces.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/dce.h
    trunk/reactos/subsystems/win32/win32k/main/dllmain.c
    trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
    trunk/reactos/subsystems/win32/win32k/ntuser/vis.c
    trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
    trunk/reactos/subsystems/win32/win32k/ntuser/window.c

Modified: trunk/reactos/subsystems/win32/win32k/include/dce.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/dce.h?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/dce.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/dce.h [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -61,5 +61,7 @@
 VOID FASTCALL DceResetActiveDCEs(PWINDOW_OBJECT Window);
 void FASTCALL DceFreeClassDCE(HDC);
 HWND FASTCALL UserGethWnd(HDC,PWNDOBJ*);
+void FASTCALL DceFreeWindowDCE(PWINDOW_OBJECT);
+void FASTCALL DceFreeThreadDCE(PTHREADINFO);
 
 #endif /* _WIN32K_DCE_H */

Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/main/dllmain.c?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -288,6 +288,7 @@
       DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
 
       Win32Thread->TIF_flags |= TIF_INCLEANUP;
+      DceFreeThreadDCE(Win32Thread);
       HOOK_DestroyThreadHooks(Thread);
       UnregisterThreadHotKeys(Thread);
       /* what if this co_ func crash in umode? what will clean us up then? */

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/painting.c?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/painting.c [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -1111,8 +1111,6 @@
    END_CLEANUP;
 }
 
-
-
 static
 INT FASTCALL
 UserScrollDC(HDC hDC, INT dx, INT dy, const RECTL *prcScroll,
@@ -1207,9 +1205,6 @@
 
    return Result;
 }
-
-
-
 
 /*
  * NtUserScrollDC
@@ -1217,10 +1212,15 @@
  * Status
  *    @implemented
  */
-
 BOOL APIENTRY
-NtUserScrollDC(HDC hDC, INT dx, INT dy, const RECT *prcUnsafeScroll,
-               const RECT *prcUnsafeClip, HRGN hrgnUpdate, LPRECT prcUnsafeUpdate)
+NtUserScrollDC(
+   HDC hDC,
+   INT dx,
+   INT dy,
+   const RECT *prcUnsafeScroll,
+   const RECT *prcUnsafeClip,
+   HRGN hrgnUpdate,
+   LPRECT prcUnsafeUpdate)
 {
    DECLARE_RETURN(DWORD);
    RECTL rcScroll, rcClip, rcUpdate;
@@ -1258,10 +1258,13 @@
       RETURN(FALSE);
    }
 
-   Result = UserScrollDC(hDC, dx, dy,
-                         prcUnsafeScroll? &rcScroll : 0,
-                         prcUnsafeClip? &rcClip : 0, hrgnUpdate,
-                         prcUnsafeUpdate? &rcUpdate : NULL);
+   Result = UserScrollDC( hDC,
+                          dx,
+                          dy,
+                          prcUnsafeScroll? &rcScroll : 0,
+                          prcUnsafeClip? &rcClip : 0,
+                          hrgnUpdate,
+                          prcUnsafeUpdate? &rcUpdate : NULL);
    if(Result == ERROR)
    {
    	  /* FIXME: Only if hRgnUpdate is invalid we should SetLastError(ERROR_INVALID_HANDLE) */
@@ -1303,8 +1306,15 @@
  */
 
 DWORD APIENTRY
-NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *prcUnsafeScroll,
-                     const RECT *prcUnsafeClip, HRGN hrgnUpdate, LPRECT prcUnsafeUpdate, UINT flags)
+NtUserScrollWindowEx(
+   HWND hWnd,
+   INT dx,
+   INT dy,
+   const RECT *prcUnsafeScroll,
+   const RECT *prcUnsafeClip,
+   HRGN hrgnUpdate,
+   LPRECT prcUnsafeUpdate,
+   UINT flags)
 {
    RECTL rcScroll, rcClip, rcCaret, rcUpdate;
    INT Result;
@@ -1378,7 +1388,14 @@
    rcCaret = rcScroll;
    hwndCaret = co_IntFixCaret(Window, &rcCaret, flags);
 
-   Result = UserScrollDC(hDC, dx, dy, &rcScroll, &rcClip, hrgnOwn, prcUnsafeUpdate? &rcUpdate : NULL);
+   Result = UserScrollDC( hDC,
+                          dx,
+                          dy,
+                         &rcScroll,
+                         &rcClip,
+                          hrgnOwn,
+                          prcUnsafeUpdate? &rcUpdate : NULL);
+
    UserReleaseDC(Window, hDC, FALSE);
 
    /*

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/vis.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/vis.c?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/vis.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/vis.c [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -47,6 +47,8 @@
       return NULL;
    }
 
+   VisRgn = NULL;
+
    if (ClientArea)
    {
       VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcClient);
@@ -71,13 +73,14 @@
            CurrentWindow->state & WINDOWSTATUS_DESTROYED )
       {
          DPRINT1("ATM the Current Window or Parent is dead!\n");
+         if (VisRgn) REGION_FreeRgnByHandle(VisRgn);
          return NULL;
       }
 
       CurrentWnd = CurrentWindow->Wnd;
       if (!CurrentWnd || !(CurrentWnd->style & WS_VISIBLE))
       {
-         REGION_FreeRgnByHandle(VisRgn);
+         if (VisRgn) REGION_FreeRgnByHandle(VisRgn);
          return NULL;
       }
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/windc.c?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -19,9 +19,10 @@
 /* GLOBALS *******************************************************************/
 
 /* NOTE - I think we should store this per window station (including gdi objects) */
-
-static PDCE FirstDce = NULL;
-//static INT DCECount = 0; // Count of DCE in system.
+/* Answer: No, use the DCE pMonitor to compare with! */
+
+static LIST_ENTRY LEDce;
+static INT DCECount = 0; // Count of DCE in system.
 
 #define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
                               DCX_NORESETATTRS | DCX_LOCKWINDOWUPDATE | \
@@ -51,6 +52,7 @@
       defaultDCstate->pdcattr = &defaultDCstate->dcattr;
       DC_vCopyState(dc, defaultDCstate, TRUE);
       DC_UnlockDc( dc );
+      InitializeListHead(&LEDce);
   }
   return hDC;
 }
@@ -90,7 +92,8 @@
       ExFreePoolWithTag(pDce, TAG_PDCE);
       return NULL;
   }
-
+  DCECount++;
+  DPRINT("Alloc DCE's! %d\n",DCECount);
   pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
   pDce->pwndOrg  = Wnd;
   pDce->pwndClip = Wnd;
@@ -99,15 +102,7 @@
   pDce->hrgnSavedVis = NULL;
   pDce->ppiOwner = NULL;
 
-  KeEnterCriticalRegion();
-  if (FirstDce == NULL)
-  {
-     FirstDce = pDce;
-     InitializeListHead(&FirstDce->List);
-  }
-  else
-     InsertTailList(&FirstDce->List, &pDce->List);
-  KeLeaveCriticalRegion();
+  InsertTailList(&LEDce, &pDce->List);
 
   DCU_SetDcUndeletable(pDce->hDC);
 
@@ -204,7 +199,6 @@
    }
 
    /* restore previous visible region */
-
    if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
          ((dce->DCXFlags & DCX_CACHE) || EndPaint))
    {
@@ -213,30 +207,48 @@
 
    if (dce->DCXFlags & DCX_CACHE)
    {
-     if (!(dce->DCXFlags & DCX_NORESETATTRS))
-     {
-       /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
-       IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
-
-       // Clean the DC
-       if (!IntGdiCleanDC(dce->hDC)) return 0;
-
-       if (dce->DCXFlags & DCX_DCEDIRTY)
-       {
-         /* don't keep around invalidated entries
-          * because SetDCState() disables hVisRgn updates
-          * by removing dirty bit. */
-         dce->hwndCurrent = 0;
-         dce->DCXFlags &= DCX_CACHE;
-         dce->DCXFlags |= DCX_DCEEMPTY;
-       }
-     }
-     dce->DCXFlags &= ~DCX_DCEBUSY;
-     DPRINT("Exit!!!!! DCX_CACHE!!!!!!   hDC-> %x \n", dce->hDC);
-     if (!IntGdiSetDCOwnerEx( dce->hDC, GDI_OBJ_HMGR_NONE, FALSE))
-        return 0;
-     dce->ptiOwner = NULL; // Reset ownership.
-     dce->ppiOwner = NULL;
+      if (!(dce->DCXFlags & DCX_NORESETATTRS))
+      {
+         /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
+         IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
+
+         // Clean the DC
+         if (!IntGdiCleanDC(dce->hDC)) return 0;
+
+         if (dce->DCXFlags & DCX_DCEDIRTY)
+         {
+           /* don't keep around invalidated entries
+            * because SetDCState() disables hVisRgn updates
+            * by removing dirty bit. */
+           dce->hwndCurrent = 0;
+           dce->DCXFlags &= DCX_CACHE;
+           dce->DCXFlags |= DCX_DCEEMPTY;
+         }
+      }
+      dce->DCXFlags &= ~DCX_DCEBUSY;
+      DPRINT("Exit!!!!! DCX_CACHE!!!!!!   hDC-> %x \n", dce->hDC);
+      if (!IntGdiSetDCOwnerEx( dce->hDC, GDI_OBJ_HMGR_NONE, FALSE))
+         return 0;
+      dce->ptiOwner = NULL; // Reset ownership.
+      dce->ppiOwner = NULL;
+
+#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
+         {
+            if (!(pDCE->DCXFlags & DCX_DCEBUSY))
+            {  /* Free the unused cache DCEs. */
+               pDCE = DceFreeDCE(pDCE, TRUE);
+               if (!pDCE) break;
+               continue;
+            }
+         }
+         while (pLE != &LEDce );
+      }
+#endif      
    }
    return 1; // Released!
 }
@@ -335,6 +347,7 @@
    PWND Wnd = NULL;
    HDC hDC = NULL;
    PPROCESSINFO ppi;
+   PLIST_ENTRY pLE;
 
    if (NULL == Window)
    {
@@ -445,7 +458,8 @@
       DCE* DceEmpty = NULL;
       DCE* DceUnused = NULL;
       KeEnterCriticalRegion();
-      Dce = FirstDce;
+      pLE = LEDce.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
       do
       {
 // The reason for this you may ask?
@@ -471,8 +485,10 @@
                break;
             }
          }
-        Dce = (PDCE)Dce->List.Flink;
-      } while (Dce != FirstDce);
+         pLE = Dce->List.Flink;
+         Dce = CONTAINING_RECORD(pLE, DCE, List);
+      }
+      while (pLE != &LEDce);
       KeLeaveCriticalRegion();
 
       Dce = (DceEmpty == NULL) ? DceUnused : DceEmpty;
@@ -488,14 +504,17 @@
    else // If we are here, we are POWNED or having CLASS.
    {
       KeEnterCriticalRegion();
-      Dce = FirstDce;
+      pLE = LEDce.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
       do
       {   // Check for Window handle than HDC match for CLASS.
           if ((Dce->hwndCurrent == Window->hSelf) ||
               (Dce->hDC == hDC))
              break;
-          Dce = (PDCE)Dce->List.Flink;
-      } while (Dce != FirstDce);
+          pLE = Dce->List.Flink;
+          Dce = CONTAINING_RECORD(pLE, DCE, List);
+      }
+      while (pLE != &LEDce);
       KeLeaveCriticalRegion();
 
       if ( (Flags & (DCX_INTERSECTRGN|DCX_EXCLUDERGN)) &&
@@ -526,11 +545,10 @@
         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 ((Dce != FirstDce))
+   if (pLE != &LEDce)
    {
       RemoveEntryList(&Dce->List);
-      InsertHeadList(&FirstDce->List, &Dce->List);
-      FirstDce = Dce;
+      InsertHeadList(&LEDce, &Dce->List);
    }
 
    /* Introduced in rev 6691 and modified later. */
@@ -595,15 +613,13 @@
 DceFreeDCE(PDCE pdce, BOOLEAN Force)
 {
   DCE *ret;
+  PLIST_ENTRY pLE;
   BOOL Hit = FALSE;
 
   if (NULL == pdce) return NULL;
 
-  ret = (PDCE) pdce->List.Flink;
-
-#if 0 /* FIXME */
-  SetDCHook(pdce->hDC, NULL, 0L);
-#endif
+  pLE = pdce->List.Flink;
+  ret = CONTAINING_RECORD(pLE, DCE, List);
 
   if (Force && !GDIOBJ_OwnedByCurrentProcess(pdce->hDC))
   {
@@ -625,6 +641,7 @@
   if (pdce->hrgnClip && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
   {
       REGION_FreeRgnByHandle(pdce->hrgnClip);
+      pdce->hrgnClip = NULL;
   }
 
   RemoveEntryList(&pdce->List);
@@ -632,47 +649,158 @@
   if (IsListEmpty(&pdce->List))
   {
       DPRINT1("List is Empty! DCE! -> %x\n" , pdce);
-      FirstDce = NULL;
-      ret = NULL;
+      return NULL;
   }
 
   ExFreePoolWithTag(pdce, TAG_PDCE);
 
+  DCECount--;
+  DPRINT("Freed DCE's! %d \n", DCECount);
+
   return ret;
+}
+
+/***********************************************************************
+ *           DceFreeWindowDCE
+ *
+ * Remove owned DCE and reset unreleased cache DCEs.
+ */
+void FASTCALL
+DceFreeWindowDCE(PWINDOW_OBJECT Window)
+{
+  PDCE pDCE;
+  PLIST_ENTRY pLE;
+
+  if (DCECount <= 0)
+  {
+     DPRINT1("No Entry!\n");
+     return;
+  }
+
+  pLE = LEDce.Flink;
+  pDCE = CONTAINING_RECORD(pLE, DCE, List);
+  do
+  {
+     if (!pDCE) break;
+     if (IsListEmpty(&pDCE->List)) break;
+     if (pDCE->hwndCurrent == Window->hSelf)
+     {
+        if (!(pDCE->DCXFlags & DCX_CACHE)) /* owned or Class DCE*/
+        {
+           if (Window->Wnd->pcls->style & CS_CLASSDC) /* Test Class first */
+           {
+              if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class DCE*/
+                 DceDeleteClipRgn(pDCE);
+              // Update and reset Vis Rgn and clear the dirty bit.
+              // Should release VisRgn than reset it to default.
+              DceUpdateVisRgn(pDCE, Window, pDCE->DCXFlags);
+              pDCE->DCXFlags = DCX_DCEEMPTY|DCX_CACHE;
+              pDCE->hwndCurrent = 0;
+
+              DPRINT("POWNED DCE going Cheap!! DCX_CACHE!! hDC-> %x \n", pDCE->hDC);
+              if (!IntGdiSetDCOwnerEx( pDCE->hDC, GDI_OBJ_HMGR_NONE, FALSE))
+                  return;
+              /* Do not change owner so thread can clean up! */
+           }
+           else if (Window->Wnd->pcls->style & CS_OWNDC) /* owned DCE*/
+           {
+              pDCE = DceFreeDCE(pDCE, FALSE);
+              if (!pDCE) break;
+              continue;
+           }
+           else
+           {
+              ASSERT(FALSE);
+           }
+        }
+        else
+        {
+           if (pDCE->DCXFlags & DCX_DCEBUSY) /* shared cache DCE */
+           {
+              /* FIXME: AFAICS we are doing the right thing here so
+               * this should be a DPRINT. But this is best left as an ERR
+               * because the 'application error' is likely to come from
+               * another part of Wine (i.e. it's our fault after all).
+               * We should change this to DPRINT when ReactOS is more stable
+               * (for 1.0?).
+               */
+              DPRINT1("[%p] GetDC() without ReleaseDC()!\n", Window->hSelf);
+              DceReleaseDC(pDCE, FALSE);
+           }
+           pDCE->DCXFlags |= DCX_DCEEMPTY;
+           pDCE->hwndCurrent = 0;
+        }
+     }
+     pLE = pDCE->List.Flink;
+     pDCE = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce);
 }
 
 void FASTCALL
 DceFreeClassDCE(HDC hDC)
 {
-   PDCE pDCE = FirstDce;
-   KeEnterCriticalRegion();
+   PDCE pDCE;
+   PLIST_ENTRY pLE;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+
    do
    {
        if(!pDCE) break;
        if (pDCE->hDC == hDC)
        {
-          pDCE = DceFreeDCE(pDCE, FALSE);
-          if(!pDCE) break;
+          pDCE = DceFreeDCE(pDCE, TRUE); // Might have gone cheap!
+          if (!pDCE) break;
           continue;
        }
-       pDCE = (PDCE)pDCE->List.Flink;
-   } while (pDCE != FirstDce);
-   KeLeaveCriticalRegion();
+       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);
+
+   do
+   {
+       if(!pDCE) break;
+       if (pDCE->ptiOwner == pti)
+       {
+          if (pDCE->DCXFlags & DCX_CACHE)
+          {
+             pDCE = DceFreeDCE(pDCE, TRUE);
+             if (!pDCE) break;
+             continue;
+          }
+       }
+       pLE = pDCE->List.Flink;
+       pDCE = CONTAINING_RECORD(pLE, DCE, List);
+   }
+   while (pLE != &LEDce);
 }
 
 VOID FASTCALL
 DceEmptyCache(VOID)
 {
-   PDCE pDCE = FirstDce;
-   KeEnterCriticalRegion();
+   PDCE pDCE;
+   PLIST_ENTRY pLE;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
+
    do
    {
       if(!pDCE) break;
       pDCE = DceFreeDCE(pDCE, TRUE);
       if(!pDCE) break;
-   } while (pDCE != FirstDce);
-   KeLeaveCriticalRegion();
-   FirstDce = NULL;
+   }
+   while (pLE != &LEDce);
 }
 
 VOID FASTCALL
@@ -683,16 +811,19 @@
    PWINDOW_OBJECT CurrentWindow;
    INT DeltaX;
    INT DeltaY;
+   PLIST_ENTRY pLE;
 
    if (NULL == Window)
    {
       return;
    }
-   pDCE = FirstDce;
+   pLE = LEDce.Flink;
+   pDCE = CONTAINING_RECORD(pLE, DCE, List);
    if(!pDCE) return; // Another null test!
    do
    {
       if(!pDCE) break;
+      if(pLE == &LEDce) break;
       if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
       {
          if (Window->hSelf == pDCE->hwndCurrent)
@@ -704,7 +835,8 @@
             CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
             if (NULL == CurrentWindow)
             {
-               pDCE = (PDCE) pDCE->List.Flink;
+               pLE = pDCE->List.Flink;
+               pDCE = CONTAINING_RECORD(pLE, DCE, List);
                continue;
             }
          }
@@ -712,7 +844,8 @@
          if (!GDIOBJ_ValidateHandle(pDCE->hDC, GDI_OBJECT_TYPE_DC) ||
              (dc = DC_LockDc(pDCE->hDC)) == NULL)
          {
-            pDCE = (PDCE) pDCE->List.Flink;
+            pLE = pDCE->List.Flink;
+            pDCE = CONTAINING_RECORD(pLE, DCE, List);
             continue;
          }
          if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow))
@@ -751,17 +884,21 @@
 //            UserDerefObject(CurrentWindow);
          }
       }
-      pDCE =(PDCE) pDCE->List.Flink;
-   } while (pDCE != FirstDce);
+      pLE = pDCE->List.Flink;
+      pDCE = CONTAINING_RECORD(pLE, DCE, List);
+   }
+   while (pLE != &LEDce);
 }
 
 HWND FASTCALL
 IntWindowFromDC(HDC hDc)
 {
   DCE *Dce;
+  PLIST_ENTRY pLE;
   HWND Ret = NULL;
-  KeEnterCriticalRegion();
-  Dce = FirstDce;
+
+  pLE = LEDce.Flink;
+  Dce = CONTAINING_RECORD(pLE, DCE, List);
   do
   {
       if(Dce->hDC == hDc)
@@ -769,9 +906,10 @@
          Ret = Dce->hwndCurrent;
          break;
       }
-      Dce = (PDCE)Dce->List.Flink;
-  } while (Dce != FirstDce);
-  KeLeaveCriticalRegion();
+      pLE = Dce->List.Flink;
+      Dce = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce);
   return Ret;
 }
 
@@ -779,12 +917,13 @@
 UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
 {
   PDCE dce;
+  PLIST_ENTRY pLE;
   INT nRet = 0;
   BOOL Hit = FALSE;
 
   DPRINT("%p %p\n", Window, hDc);
-  dce = FirstDce;
-  KeEnterCriticalRegion();
+  pLE = LEDce.Flink;
+  dce = CONTAINING_RECORD(pLE, DCE, List);
   do
   {
      if(!dce) break;
@@ -793,11 +932,10 @@
         Hit = TRUE;
         break;
      }
-
-     dce = (PDCE) dce->List.Flink;
-  }
-  while (dce != FirstDce );
-  KeLeaveCriticalRegion();
+     pLE = dce->List.Flink;
+     dce = CONTAINING_RECORD(pLE, DCE, List);
+  }
+  while (pLE != &LEDce );
 
   if ( Hit && (dce->DCXFlags & DCX_DCEBUSY))
   {

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/window.c?rev=45293&r1=45292&r2=45293&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Thu Jan 28 02:00:09 2010
@@ -478,6 +478,7 @@
       Window->SystemMenu = (HMENU)0;
    }
 
+   DceFreeWindowDCE(Window);    /* Always do this to catch orphaned DCs */
 #if 0 /* FIXME */
 
    WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);




More information about the Ros-diffs mailing list