Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp	(revision 44163)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp	(revision 44164)
@@ -96,4 +96,26 @@
 
 #ifndef TARGET_NT4
+
+static bool vboxServiceVMInfoSession0Separation(void)
+{
+    /** @todo Only do this once. Later. */
+    OSVERSIONINFOEX OSInfoEx;
+    RT_ZERO(OSInfoEx);
+    OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+    if (   !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
+        || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT)
+    {
+        /* Platform other than NT (e.g. Win9x) not supported. */
+        return false;
+    }
+
+    if (   OSInfoEx.dwMajorVersion >= 6
+        && OSInfoEx.dwMinorVersion >= 0)
+    {
+        return true;
+    }
+
+    return false;
+}
 
 /**
@@ -459,5 +481,5 @@
 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession,
                                                  PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs,
-                                                 PULONG puSession)
+                                                 PULONG puTerminalSession)
 {
     if (!pSession)
@@ -507,12 +529,10 @@
 
     if (g_cVerbosity)
-        VBoxServiceVerbose(3, "Session %u has %u processes total\n",
-                           pSessionData->Session, cNumProcs);
+        VBoxServiceVerbose(3, "Session has %u processes total\n", cNumProcs);
     else
-        VBoxServiceVerbose(3, "Session %u has at least one process\n",
-                           pSessionData->Session);
-
-    if (puSession)
-        *puSession = pSessionData->Session;
+        VBoxServiceVerbose(3, "Session has at least one process\n");
+
+    if (puTerminalSession)
+        *puTerminalSession = pSessionData->Session;
 
     LsaFreeReturnBuffer(pSessionData);
@@ -596,4 +616,17 @@
                        pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart,
                        pSessionData->LogonType);
+
+    if (vboxServiceVMInfoSession0Separation())
+    {
+        /* Starting at Windows Vista user sessions begin with session 1, so
+         * ignore (stale) session 0 users. */
+        if (   pSessionData->Session == 0
+        /* Also check the logon time. */
+            || pSessionData->LogonTime.QuadPart == 0)
+        {
+            LsaFreeReturnBuffer(pSessionData);
+            return false;
+        }
+    }
 
     /*
@@ -732,5 +765,5 @@
 int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
 {
-    AssertPtrReturn(ppszUserList && *ppszUserList, VERR_INVALID_POINTER);
+    AssertPtrReturn(ppszUserList, VERR_INVALID_POINTER);
     AssertPtrReturn(pcUsersInList, VERR_INVALID_POINTER);
 
@@ -739,9 +772,6 @@
 
 #ifdef DEBUG
-    if (!s_uGuestPropClientID)
-    {
-        int rc2 = VbglR3GuestPropConnect(&s_uGuestPropClientID);
-        AssertRC(rc2);
-    }
+    int rc2 = VbglR3GuestPropConnect(&s_uGuestPropClientID);
+    AssertRC(rc2);
 #endif
 
@@ -804,10 +834,15 @@
 
                     /* Retrieve assigned processes of current session. */
-                    ULONG ulSession;
-                    uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs, &ulSession);
+                    uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs,
+                                                                                     NULL /* Terminal session ID */);
                     /* Don't return here when current session does not have assigned processes
                      * anymore -- in that case we have to search through the unique users list below
                      * and see if got a stale user/session entry. */
 
+#ifdef DEBUG
+                    char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath,  sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32", i);
+                    VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath,
+                                          "%RU32: cSessionProcs=%RU32 (%RU32 total)", s_uIter, cSessionProcs, cProcs);
+#endif
                     bool fFoundUser = false;
                     for (ULONG a = 0; a < cUniqueUsers; a++)
@@ -823,8 +858,8 @@
                              * Only respect the highest session for the current user.
                              */
-                            if (ulSession > pCurUser->ulSession)
+                            if (i > pCurUser->ulSession)
                             {
                                 VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last session=%RU32)\n",
-                                                   pCurUser->wszUser, cSessionProcs, ulSession);
+                                                   pCurUser->wszUser, cSessionProcs, i);
 
                                 if (!cSessionProcs)
@@ -832,17 +867,17 @@
                                                        pCurUser->wszUser,
                                                        pCurUser->ulNumProcs, cSessionProcs,
-                                                       pCurUser->ulSession, ulSession);
+                                                       pCurUser->ulSession, i);
 
                                 pCurUser->ulNumProcs = cSessionProcs;
-                                pCurUser->ulSession  = ulSession;
+                                pCurUser->ulSession  = i;
                             }
                             /* There can be multiple session objects using the same session ID for the
                              * current user -- so when we got the same session again just add the found
                              * processes to it. */
-                            else if (   pCurUser->ulSession == ulSession
+                            else if (   pCurUser->ulSession == i
                                      && cSessionProcs)
                             {
                                 VBoxServiceVerbose(4, "Adding %u processes to user=%ls (session=%RU32)\n",
-                                                   cSessionProcs, pCurUser->wszUser, ulSession);
+                                                   cSessionProcs, pCurUser->wszUser, i);
 
                                 pCurUser->ulNumProcs += cSessionProcs;
@@ -857,9 +892,9 @@
                     {
                         VBoxServiceVerbose(4, "Adding new user=%ls (session=%RU32) with %u processes\n",
-                                           UserInfo.wszUser, ulSession, cSessionProcs);
+                                           UserInfo.wszUser, i, cSessionProcs);
 
                         memcpy(&pUserInfo[cUniqueUsers], &UserInfo, sizeof(VBOXSERVICEVMINFOUSER));
                         pUserInfo[cUniqueUsers].ulNumProcs = cSessionProcs;
-                        pUserInfo[cUniqueUsers].ulSession  = ulSession;
+                        pUserInfo[cUniqueUsers].ulSession  = i;
                         cUniqueUsers++;
                         Assert(cUniqueUsers <= cSessions);
@@ -885,5 +920,12 @@
                                       s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulSession, pUserInfo[i].ulNumProcs);
 #endif
-                if (pUserInfo[i].ulNumProcs)
+                bool fAddUser = true;
+                if (   pUserInfo[i].ulNumProcs
+                       /* If we have session 0 separation, add the user regardless of the
+                        * attached processes. */
+                    || vboxServiceVMInfoSession0Separation())
+                    fAddUser = true;
+
+                if (fAddUser)
                 {
                     VBoxServiceVerbose(3, "User %ls has %ld processes (session %u)\n",
