Author: gadamopoulos
Date: Sat Oct 27 16:39:18 2012
New Revision: 57623
URL: 
http://svn.reactos.org/svn/reactos?rev=57623&view=rev
Log:
[win32k]
- Fix WARN macros
- Keep a list of the PROCESSINFO of all the running processes
- Count how many handles a process owns per type in PROCESSINFO
- Improve the debug output when we run out of user handles to show all handle counts per
process
Modified:
    trunk/reactos/win32ss/include/ntuser.h
    trunk/reactos/win32ss/user/ntuser/main.c
    trunk/reactos/win32ss/user/ntuser/ntuser.h
    trunk/reactos/win32ss/user/ntuser/object.c
    trunk/reactos/win32ss/user/ntuser/object.h
    trunk/reactos/win32ss/user/ntuser/win32.h
    trunk/reactos/win32ss/user/ntuser/win32kdebug.h
Modified: trunk/reactos/win32ss/include/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?r…
==============================================================================
--- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -56,7 +56,8 @@
   otHidData,
   otDeviceInfo,
   otTouchInput,
-  otGestureInfo
+  otGestureInfo,
+  USER_HANDLE_TYPE_COUNT
 } USER_OBJECT_TYPE;
 typedef enum _USERTHREADINFOCLASS
Modified: trunk/reactos/win32ss/user/ntuser/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/main.c…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -26,6 +26,7 @@
 SHORT gusLanguageID;
 PPROCESSINFO ppiScrnSaver;
+PPROCESSINFO gppiList = NULL;
 extern ULONG_PTR Win32kSSDT[];
 extern UCHAR Win32kSSPT[];
@@ -55,7 +56,7 @@
 Win32kProcessCallback(struct _EPROCESS *Process,
                       BOOLEAN Create)
 {
-    PPROCESSINFO ppiCurrent;
+    PPROCESSINFO ppiCurrent, *pppi;
     DECLARE_RETURN(NTSTATUS);
     ASSERT(Process->Peb);
@@ -160,6 +161,10 @@
         ASSERT(ppiCurrent->pPoolDcAttr);
         ASSERT(ppiCurrent->pPoolBrushAttr);
         ASSERT(ppiCurrent->pPoolRgnAttr);
+
+        /* Add the process to the global list */
+        ppiCurrent->ppiNext = gppiList;
+        gppiList = ppiCurrent;
     }
     else
     {
@@ -212,11 +217,25 @@
         if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;
+        pppi = &gppiList;
+        while (*pppi != NULL && *pppi != ppiCurrent)
+            pppi = &(*pppi)->ppiNext;
+
+        ASSERT(*pppi == ppiCurrent);
+
+        *pppi = ppiCurrent->ppiNext;
+
         TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
         /* Ftee the PROCESSINFO */
         PsSetProcessWin32Process(Process, NULL);
         ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
+#if DBG
+        if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
+        {
+            DbgUserDumpHandleTable();
+        }
+#endif
     }
     RETURN( STATUS_SUCCESS);
Modified: trunk/reactos/win32ss/user/ntuser/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntuser…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/ntuser.h [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -12,6 +12,7 @@
 extern BOOL gbInitialized;
 extern PSERVERINFO gpsi;
 extern PTHREADINFO gptiCurrent;
+extern PPROCESSINFO gppiList;
 extern PPROCESSINFO ppiScrnSaver;
 extern PPROCESSINFO gppiInputProvider;
Modified: trunk/reactos/win32ss/user/ntuser/object.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -12,6 +12,66 @@
 //int usedHandles=0;
 PUSER_HANDLE_TABLE gHandleTable = NULL;
+#if DBG
+
+void DbgUserDumpHandleTable()
+{
+    int HandleCounts[USER_HANDLE_TYPE_COUNT];
+    PPROCESSINFO ppiList;
+    int i;
+    PWCHAR TypeNames[] = {L"Free",L"Window",L"Menu",
L"CursorIcon", L"SMWP", L"Hook", L"ClipBoardData",
L"CallProc",
+                          L"Accel", L"DDEaccess",
L"DDEconv", L"DDExact", L"Monitor", L"KBDlayout",
L"KBDfile",
+                          L"Event", L"Timer",
L"InputContext", L"HidData", L"DeviceInfo",
L"TouchInput",L"GestureInfo"};
+
+    ERR("Total handles count: %d\n", gpsi->cHandleEntries);
+
+    memset(HandleCounts, 0, sizeof(HandleCounts));
+
+    /* First of all count the number of handles per tpe */
+    ppiList = gppiList;
+    while (ppiList)
+    {
+        ERR("Process %s (%d) handles count: %d\n\t",
ppiList->peProcess->ImageFileName, ppiList->peProcess->UniqueProcessId,
ppiList->UserHandleCount);
+
+        for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+        {
+            HandleCounts[i] += ppiList->DbgHandleCount[i];
+
+            DbgPrint("%S: %d, ", TypeNames[i], ppiList->DbgHandleCount[i]);
+            if (i % 6 == 0)
+                DbgPrint("\n\t");
+        }
+        DbgPrint("\n");
+
+        ppiList = ppiList->ppiNext;
+    }
+
+    /* Print total type counts */
+    ERR("Total handles of the running processes: \n\t");
+    for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+    {
+        DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
+        if (i % 6 == 0)
+            DbgPrint("\n\t");
+    }
+    DbgPrint("\n");
+
+    /* Now count the handle counts that are allocated from the handle table */
+    memset(HandleCounts, 0, sizeof(HandleCounts));
+    for (i = 0; i < gHandleTable->nb_handles; i++)
+         HandleCounts[gHandleTable->handles[i].type]++;
+
+    ERR("Total handles count allocated: \n\t");
+    for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+    {
+        DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
+        if (i % 6 == 0)
+            DbgPrint("\n\t");
+    }
+    DbgPrint("\n");
+}
+
+#endif
 PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
 {
@@ -51,55 +111,12 @@
    if (ht->nb_handles >= ht->allocated_handles)  /* Need to grow the array */
    {
-/**/
-      int i, iFree = 0, iWindow = 0, iMenu = 0, iCursorIcon = 0,
-          iHook = 0, iCallProc = 0, iAccel = 0, iMonitor = 0, iTimer = 0, iEvent = 0,
iSMWP = 0;
- /**/
-      ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n",
gpsi->cHandleEntries, ht->nb_handles);
-//#if 0
-      for(i = 0; i < ht->nb_handles; i++)
-      {
-         switch (ht->handles[i].type)
-         {
-           case otFree: // Should be zero.
-            iFree++;
-            break;
-           case otWindow:
-            iWindow++;
-            break;
-           case otMenu:
-            iMenu++;
-            break;
-           case otCursorIcon:
-            iCursorIcon++;
-            break;
-           case otHook:
-            iHook++;
-            break;
-           case otCallProc:
-            iCallProc++;
-            break;
-           case otAccel:
-            iAccel++;
-            break;
-           case otMonitor:
-            iMonitor++;
-            break;
-           case otTimer:
-            iTimer++;
-            break;
-           case otEvent:
-            iEvent++;
-            break;
-           case otSMWP:
-            iSMWP++;
-           default:
-            break;
-         }
-      }
-      ERR("Handle Count by Type:\n Free = %d Window = %d Menu = %d CursorIcon = %d
Hook = %d\n CallProc = %d Accel = %d Monitor = %d Timer = %d Event = %d SMWP = %d\n",
-      iFree, iWindow, iMenu, iCursorIcon, iHook, iCallProc, iAccel, iMonitor, iTimer,
iEvent, iSMWP );
-//#endif
+       ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n",
gpsi->cHandleEntries, ht->nb_handles);
+
+#if DBG
+       DbgUserDumpHandleTable();
+#endif
+
       return NULL;
 #if 0
       PUSER_HANDLE_ENTRY new_handles;
@@ -138,6 +155,11 @@
 {
    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
    void *ret;
+
+#if DBG
+   ppi->DbgHandleCount[entry->type]--;
+#endif
+
    ret = entry->ptr;
    entry->ptr  = ht->freelist;
    entry->type = 0;
@@ -339,6 +361,10 @@
       return NULL;
    }
+#if DBG
+   ppi->DbgHandleCount[type]++;
+#endif
+
    RtlZeroMemory(Object, size);
    switch (type)
Modified: trunk/reactos/win32ss/user/ntuser/object.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -39,6 +39,7 @@
 PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE, HANDLE, USER_OBJECT_TYPE);
 BOOL FASTCALL UserCreateHandleTable(VOID);
 BOOL FASTCALL UserObjectInDestroy(HANDLE);
+void DbgUserDumpHandleTable();
 static __inline VOID
 UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Modified: trunk/reactos/win32ss/user/ntuser/win32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -195,6 +195,7 @@
   PTHREADINFO ptiList;
   PTHREADINFO ptiMainThread;
   struct _DESKTOP* rpdeskStartup;
+  PPROCESSINFO ppiNext;
   PCLS pclsPrivateList;
   PCLS pclsPublicList;
   INT cThreads;
@@ -224,6 +225,7 @@
 #if DBG
   BYTE DbgChannelLevel[DbgChCount];
+  DWORD DbgHandleCount[USER_HANDLE_TYPE_COUNT];
 #endif
 } PROCESSINFO;
Modified: trunk/reactos/win32ss/user/ntuser/win32kdebug.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32k…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/win32kdebug.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/win32kdebug.h [iso-8859-1] Sat Oct 27 16:39:18 2012
@@ -125,7 +125,7 @@
     #define DBG_ENABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] |= level)
     #define DBG_DISABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] &=
~level)
-    #define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] &
level)
+    #define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) (((ppi)->DbgChannelLevel[ch] &
level) == level)
     #define DBG_PRINT(ppi,ch,level,fmt, ...)  do {                            \
     if((level == ERR_LEVEL) || (ppi && DBG_IS_CHANNEL_ENABLED(ppi,ch,level))) \