Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/Dialog.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/Dialog.cpp	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/Dialog.cpp	(revision 40214)
@@ -6,5 +6,5 @@
 /*
  *
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -19,4 +19,6 @@
 #include <windows.h>
 #include <stdio.h>      /* Needed for swprintf() */
+
+#include <VBox/VboxGuestLib.h>
 
 #include "Dialog.h"
@@ -92,5 +94,8 @@
 void hookDialogBoxes(PVOID pWinlogonFunctions, DWORD dwWlxVersion)
 {
-    Log(("VBoxGINA::hookDialogBoxes\n"));
+    if (!pWinlogonFunctions) /* Needed for testcase. */
+        return;
+
+    VBoxGINAVerbose(0, "VBoxGINA::hookDialogBoxes\n");
 
     /* this is version dependent */
@@ -134,5 +139,5 @@
         default:
         {
-            Log(("VBoxGINA::hookDialogBoxes: unrecognized version '%d', nothing hooked!\n", dwWlxVersion));
+            VBoxGINAVerbose(0, "VBoxGINA::hookDialogBoxes: unrecognized version '%d', nothing hooked!\n", dwWlxVersion);
             /* not good, don't do anything */
             break;
@@ -141,8 +146,19 @@
 }
 
-//
-// Redirected WlxLoggedOutSASDlgProc().
-//
-BOOL credentialsToUI(HWND hwndUserId, HWND hwndPassword, HWND hwndDomain)
+/**
+ * Enters credentials into the given text fields.
+ *
+ * @return  IPRT status code.
+ * @param   hwndDlg                 Handle of dialog to enter credentials into.
+ * @param   hwndUserId              Handle of username text field. Optional.
+ * @param   hwndPassword            Handle of password text field. Optional.
+ * @param   hwndDomain              Handle of domain text field. Optional.
+ * @param   pwszUser                Username to enter into username text field.
+ * @param   pwszPassword            Password to enter into password text field.
+ * @param   pwszDomain              Domain to enter into domain text field.
+ */
+int credentialsToUI(HWND hwndDlg,
+                    HWND hwndUserId, HWND hwndPassword, HWND hwndDomain,
+                    PCRTUTF16 pwszUser, PCRTUTF16 pwszPassword, PCRTUTF16 pwszDomain)
 {
     BOOL bIsFQDN = FALSE;
@@ -151,10 +167,10 @@
     {
         /* search the domain combo box for our required domain and select it */
-        Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Trying to find domain entry in combo box ...\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Trying to find domain entry in combo box ...\n");
         DWORD dwIndex = (DWORD) SendMessage(hwndDomain, CB_FINDSTRING,
-                                            0, (LPARAM)g_Domain);
+                                            0, (LPARAM)pwszDomain);
         if (dwIndex != CB_ERR)
         {
-            Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Found domain at combo box pos %ld\n", dwIndex));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Found domain at combo box pos %ld\n", dwIndex);
             SendMessage(hwndDomain, CB_SETCURSEL, (WPARAM) dwIndex, 0);
             EnableWindow(hwndDomain, FALSE);
@@ -162,5 +178,5 @@
         else
         {
-            Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain not found in combo box ...\n"));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain not found in combo box ...\n");
 
             /* If the domain value has a dot (.) in it, it is a FQDN (Fully Qualified Domain Name)
@@ -173,19 +189,19 @@
              *
              */
-            size_t l = wcslen(g_Domain);
+            size_t l = wcslen(pwszDomain);
             if (l > 255)
-                Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Warning! FQDN is too long (max 255 bytes), will be truncated!\n"));
-
-            if (wcslen(g_Username) > 0) /* We need a user name that we can use in caes of a FQDN */
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Warning! FQDN (domain) is too long (max 255 bytes), will be truncated!\n");
+
+            if (wcslen(pwszUser) > 0) /* We need a user name that we can use in caes of a FQDN */
             {
                 if (l > 16) /* Domain name is longer than 16 chars, cannot be a NetBIOS name anymore */
                 {
-                    Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (length)!\n"));
+                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (length)!\n");
                     bIsFQDN = TRUE;
                 }
                 else if (   l > 0
-                         && wcsstr(g_Domain, L".") != NULL) /* if we found a dot (.) in the domain name, this has to be a FQDN */
+                         && wcsstr(pwszDomain, L".") != NULL) /* if we found a dot (.) in the domain name, this has to be a FQDN */
                 {
-                    Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (dot)!\n"));
+                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (dot)!\n");
                     bIsFQDN = TRUE;
                 }
@@ -193,6 +209,6 @@
                 if (bIsFQDN)
                 {
-                    swprintf(szUserFQDN, sizeof(szUserFQDN) / sizeof(wchar_t), L"%s@%s", g_Username, g_Domain);
-                    Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: FQDN user name is now: %s!\n", szUserFQDN));
+                    swprintf(szUserFQDN, sizeof(szUserFQDN) / sizeof(wchar_t), L"%s@%s", pwszUser, pwszDomain);
+                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: FQDN user name is now: %s!\n", szUserFQDN);
                 }
             }
@@ -202,12 +218,89 @@
     {
         if (!bIsFQDN)
-            SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)g_Username);
+            SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)pwszUser);
         else
             SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)szUserFQDN);
     }
     if (hwndPassword)
-        SendMessage(hwndPassword, WM_SETTEXT, 0, (LPARAM)g_Password);
-
-    return TRUE;
+        SendMessage(hwndPassword, WM_SETTEXT, 0, (LPARAM)pwszPassword);
+
+    return VINF_SUCCESS; /** @todo */
+}
+
+/**
+ * Tries to retrieve credentials and enters them into the specified windows,
+ * optionally followed by a button press to confirm/abort the dialog.
+ *
+ * @return  IPRT status code.
+ * @param   hwndDlg                 Handle of dialog to enter credentials into.
+ * @param   hwndUserId              Handle of username text field. Optional.
+ * @param   hwndPassword            Handle of password text field. Optional.
+ * @param   hwndDomain              Handle of domain text field. Optional.
+ * @param   wButtonToPress          Button ID of dialog to press after successful
+ *                                  retrieval + storage. If set to 0 no button will
+ *                                  be pressed.
+ */
+int credentialsHandle(HWND hwndDlg,
+                      HWND hwndUserId, HWND hwndPassword, HWND hwndDomain,
+                      WORD wButtonToPress)
+{
+    int rc = VINF_SUCCESS;
+
+    if (!VBoxGINAHandleCurrentSession())
+        rc = VERR_NOT_FOUND;
+
+    if (RT_SUCCESS(rc))
+    {
+        rc = VbglR3CredentialsQueryAvailability();
+        if (RT_FAILURE(rc))
+        {
+            if (rc != VERR_NOT_FOUND)
+                VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: error querying for credentials, rc=%Rrc\n", rc);
+        }
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: credentials available\n");
+
+        /*
+         * Set status to "terminating" to let the host know this module now
+         * tries to receive and use passed credentials so that credentials from
+         * the host won't be sent twice.
+         */
+        VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminating);
+
+        PRTUTF16 pwszUser, pwszPassword, pwszDomain;
+        rc = VbglR3CredentialsRetrieveUtf16(&pwszUser, &pwszPassword, &pwszDomain);
+        if (RT_SUCCESS(rc))
+        {
+    #ifdef DEBUG
+            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=%ls, domain=%ls\n",
+                            pwszUser, pwszPassword, pwszDomain);
+    #else
+            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=XXX, domain=%ls\n",
+                            pwszUser, pwszDomain);
+    #endif
+            /* Fill in credentials to appropriate UI elements. */
+            rc = credentialsToUI(hwndDlg,
+                                 hwndUserId, hwndPassword, hwndDomain,
+                                 pwszUser, pwszPassword, pwszDomain);
+            if (RT_SUCCESS(rc))
+            {
+                /* Confirm/cancel the dialog by pressing the appropriate button. */
+                if (wButtonToPress)
+                {
+                    WPARAM wParam = MAKEWPARAM(wButtonToPress, BN_CLICKED);
+                    PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
+                }
+            }
+
+            VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain,
+                                          3 /* Passes */);
+        }
+    }
+
+    VBoxGINAVerbose(3, "VBoxGINA::credentialsHandle: returned with rc=%Rrc\n", rc);
+    return rc;
 }
 
@@ -220,5 +313,5 @@
     static HWND s_hwndUserId, s_hwndPassword, s_hwndDomain = 0;
 
-    /*Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc\n"));*/
+    /*VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc\n");*/
 
     //
@@ -234,5 +327,5 @@
         case WM_INITDIALOG:
         {
-            Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: got WM_INITDIALOG\n"));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: got WM_INITDIALOG\n");
 
             /* get the entry fields */
@@ -247,27 +340,14 @@
                 s_hwndDomain = GetDlgItem(hwndDlg, IDC_WLXLOGGEDOUTSAS_DOMAIN2);
 
-            Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: hwndUserId: %x, hwndPassword: %d, hwndDomain: %d\n",
-                 s_hwndUserId, s_hwndPassword, s_hwndDomain));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: hwndUserId: %x, hwndPassword: %d, hwndDomain: %d\n",
+                            s_hwndUserId, s_hwndPassword, s_hwndDomain);
 
             /* terminate the credentials poller thread, it's done is job */
-            credentialsPollerTerminate();
-
-            if (credentialsAvailable())
-            {
-                /* query the credentials from VBox */
-                if (credentialsRetrieve())
-                {
-                    /* fill in credentials to appropriate UI elements */
-                    credentialsToUI(s_hwndUserId, s_hwndPassword, s_hwndDomain);
-
-                    /* we got the credentials, null them out */
-                    credentialsReset();
-
-                    /* confirm the logon dialog, simulating the user pressing "OK" */
-                    WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
-                    PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
-                }
-            }
-            else
+            VBoxGINACredentialsPollerTerminate();
+
+            int rc = credentialsHandle(hwndDlg,
+                                       s_hwndUserId, s_hwndPassword, s_hwndDomain,
+                                       IDOK /* Button */);
+            if (RT_FAILURE(rc))
             {
                 /*
@@ -277,6 +357,6 @@
                 UINT_PTR uTimer = SetTimer(hwndDlg, IDT_LOGGEDONDLG_POLL, 200, NULL);
                 if (!uTimer)
-                    Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: failed creating timer! Last error: %ld\n",
-                         GetLastError()));
+                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: failed creating timer! Last error: %ld\n",
+                                    GetLastError());
             }
             break;
@@ -288,21 +368,11 @@
             if (wParam == IDT_LOGGEDONDLG_POLL)
             {
-                if (credentialsAvailable())
+                int rc = credentialsHandle(hwndDlg,
+                                           s_hwndUserId, s_hwndPassword, s_hwndDomain,
+                                           IDOK /* Button */);
+                if (RT_SUCCESS(rc))
                 {
-                    if (credentialsRetrieve())
-                    {
-                        /* fill in credentials to appropriate UI elements */
-                        credentialsToUI(s_hwndUserId, s_hwndPassword, s_hwndDomain);
-
-                        /* we got the credentials, null them out */
-                        credentialsReset();
-
-                        /* confirm the logon dialog, simulating the user pressing "OK" */
-                        WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
-                        PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
-
-                        /* we don't need the timer any longer */
-                        KillTimer(hwndDlg, IDT_LOGGEDONDLG_POLL);
-                    }
+                    /* we don't need the timer any longer */
+                    KillTimer(hwndDlg, IDT_LOGGEDONDLG_POLL);
                 }
             }
@@ -326,5 +396,5 @@
     static HWND s_hwndPassword = 0;
 
-    /*Log(("VBoxGINA::MyWlxLockedSASDlgProc\n"));*/
+    /*VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc\n");*/
 
     //
@@ -340,30 +410,17 @@
         case WM_INITDIALOG:
         {
-            Log(("VBoxGINA::MyWlxLockedSASDlgProc: got WM_INITDIALOG\n"));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: WM_INITDIALOG\n");
 
             /* get the entry fields */
             s_hwndPassword = GetDlgItem(hwndDlg, IDC_WKSTALOCKED_PASSWORD);
-            Log(("VBoxGINA::MyWlxLockedSASDlgProc: hwndPassword: %d\n", s_hwndPassword));
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: hwndPassword: %d\n", s_hwndPassword);
 
             /* terminate the credentials poller thread, it's done is job */
-            credentialsPollerTerminate();
-
-            if (credentialsAvailable())
-            {
-                /* query the credentials from VBox */
-                if (credentialsRetrieve())
-                {
-                    /* fill in credentials to appropriate UI elements */
-                    credentialsToUI(NULL /* User ID */, s_hwndPassword, NULL /* Domain */);
-
-                    /* we got the credentials, null them out */
-                    credentialsReset();
-
-                    /* confirm the logon dialog, simulating the user pressing "OK" */
-                    WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
-                    PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
-                }
-            }
-            else
+            VBoxGINACredentialsPollerTerminate();
+
+            int rc = credentialsHandle(hwndDlg,
+                                       NULL /* Username */, s_hwndPassword, NULL /* Domain */,
+                                       IDOK /* Button */);
+            if (RT_FAILURE(rc))
             {
                 /*
@@ -373,6 +430,6 @@
                 UINT_PTR uTimer = SetTimer(hwndDlg, IDT_LOCKEDDLG_POLL, 200, NULL);
                 if (!uTimer)
-                    Log(("VBoxGINA::MyWlxLockedSASDlgProc: failed creating timer! Last error: %ld\n",
-                         GetLastError()));
+                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: failed creating timer! Last error: %ld\n",
+                         GetLastError());
             }
             break;
@@ -384,21 +441,11 @@
             if (wParam == IDT_LOCKEDDLG_POLL)
             {
-                if (credentialsAvailable())
+                int rc = credentialsHandle(hwndDlg,
+                                           NULL /* Username */, s_hwndPassword, NULL /* Domain */,
+                                           IDOK /* Button */);
+                if (RT_SUCCESS(rc))
                 {
-                    if (credentialsRetrieve())
-                    {
-                        /* fill in credentials to appropriate UI elements */
-                        credentialsToUI(NULL /* User ID */, s_hwndPassword, NULL /* Domain */);
-
-                        /* we got the credentials, null them out */
-                        credentialsReset();
-
-                        /* confirm the logon dialog, simulating the user pressing "OK" */
-                        WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
-                        PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
-
-                        /* we don't need the timer any longer */
-                        KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
-                    }
+                    /* we don't need the timer any longer */
+                    KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
                 }
             }
@@ -407,6 +454,15 @@
 
         case WM_DESTROY:
+        {
+            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: WM_DESTROY\n");
+
+            /* Because this is the only point where we know within our module that the locked
+             * dialog has been closed by a valid unlock password we have to set the appropriate
+             * facility status here. */
+            VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
+
             KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
             break;
+        }
     }
     return bResult;
@@ -421,5 +477,7 @@
                                LPARAM  dwInitParam)
 {
-    Log(("VBoxGINA::MyWlxDialogBoxParam: lpszTemplate = %ls\n", lpszTemplate));
+    VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: lpszTemplate=%ls\n", lpszTemplate);
+
+    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Active);
 
     //
@@ -433,8 +491,12 @@
         switch ((DWORD) lpszTemplate)
         {
+            case IDD_WLXDIAPLAYSASNOTICE_DIALOG:
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: SAS notice dialog displayed; not handled\n");
+                break;
+
             case IDD_WLXLOGGEDOUTSAS_DIALOG:     /* Windows NT 4.0. */
             case IDD_WLXLOGGEDOUTSAS_DIALOG2:    /* Windows 2000 and up. */
             {
-                Log(("VBoxGINA::MyWlxDialogBoxParam: returning hooked LOGGED OUT dialog\n"));
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: returning hooked SAS logged out dialog\n");
                 g_pfnWlxLoggedOutSASDlgProc = dlgprc;
                 return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
@@ -442,8 +504,12 @@
             }
 
+            case IDD_SECURITY_DIALOG:
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: Security dialog displayed; not handled\n");
+                break;
+
             case IDD_WLXWKSTALOCKEDSAS_DIALOG:   /* Windows NT 4.0. */
             case IDD_WLXWKSTALOCKEDSAS_DIALOG2:  /* Windows 2000 and up. */
             {
-                Log(("VBoxGINA::MyWlxDialogBoxParam: returning hooked LOCKED dialog\n"));
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: returning hooked SAS locked dialog\n");
                 g_pfnWlxLockedSASDlgProc = dlgprc;
                 return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
@@ -454,16 +520,10 @@
 
             default:
-            {
-                char szBuf[1024];
-                sprintf(szBuf, "VBoxGINA::MyWlxDialogBoxParam: dialog %ld not handled\n", (DWORD)lpszTemplate);
-                Log((szBuf));
+                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: dialog %ld not handled\n", (DWORD)lpszTemplate);
                 break;
-            }
-        }
-    }
-
-    //
-    // The rest will not be redirected.
-    //
+        }
+    }
+
+    /* The rest will be redirected. */
     return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate,
                                   hwndOwner, dlgprc, dwInitParam);
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.cpp	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.cpp	(revision 40214)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -17,47 +17,44 @@
 
 #include <windows.h>
+
+#include <iprt/semaphore.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+
 #include "winwlx.h"
 #include "Helper.h"
 #include "VBoxGINA.h"
 
-#include <VBox/VBoxGuest.h>
-#include <VBox/VMMDev.h>
-#include <iprt/string.h>
-
-/* remote session handling */
-DWORD g_dwHandleRemoteSessions = 0;
-
-/* the credentials */
-wchar_t g_Username[VMMDEV_CREDENTIALS_SZ_SIZE];
-wchar_t g_Password[VMMDEV_CREDENTIALS_SZ_SIZE];
-wchar_t g_Domain[VMMDEV_CREDENTIALS_SZ_SIZE];
-
-
-HANDLE getVBoxDriver(void)
-{
-    static HANDLE sVBoxDriver = INVALID_HANDLE_VALUE;
-    if (sVBoxDriver == INVALID_HANDLE_VALUE)
-    {
-        sVBoxDriver = CreateFile(L"\\\\.\\VBoxGuest", /** @todo use define */
-                                 GENERIC_READ | GENERIC_WRITE,
-                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                 NULL,
-                                 OPEN_EXISTING,
-                                 FILE_ATTRIBUTE_NORMAL,
-                                 NULL);
-        if (sVBoxDriver == INVALID_HANDLE_VALUE)
-            Log(("VBoxGINA::sVBoxDriver: failed to open VBoxGuest driver, last error = %d\n", GetLastError()));
-    }
-    return sVBoxDriver;
-}
-
-/**
- * Detects whether our process is running in a remote session or not.
- *
- * @return  bool        true if running in a remote session, false if not.
- */
-bool isRemoteSession(void)
-{
-    return (0 != GetSystemMetrics(SM_REMOTESESSION)) ? true : false;
+#include <VBox/log.h>
+#include <VBox/VboxGuestLib.h>
+
+/** Flag indicating whether remote sessions (over MSRDP) should be
+ *  handled or not. Default is disabled. */
+static DWORD g_dwHandleRemoteSessions = 0;
+/** Verbosity flag for guest logging. */
+static DWORD g_dwVerbosity = 0;
+
+/**
+ * Displays a verbose message.
+ *
+ * @param   iLevel      Minimum log level required to display this message.
+ * @param   pszFormat   The message text.
+ * @param   ...         Format arguments.
+ */
+void VBoxGINAVerbose(DWORD dwLevel, const char *pszFormat, ...)
+{
+    if (dwLevel <= g_dwVerbosity)
+    {
+        va_list args;
+        va_start(args, pszFormat);
+        char *psz = NULL;
+        RTStrAPrintfV(&psz, pszFormat, args);
+        va_end(args);
+
+        AssertPtr(psz);
+        LogRel(("%s", psz));
+
+        RTStrFree(psz);
+    }
 }
 
@@ -65,7 +62,7 @@
  * Loads the global configuration from registry.
  *
- * @return  DWORD       Windows error code.
- */
-DWORD loadConfiguration(void)
+ * @return  IPRT status code.
+ */
+int VBoxGINALoadConfiguration(void)
 {
     HKEY hKey;
@@ -86,8 +83,28 @@
             g_dwHandleRemoteSessions = dwValue;
         }
+
+        dwRet = RegQueryValueEx(hKey, L"LoggingEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
+        if (   dwRet  == ERROR_SUCCESS
+            && dwType == REG_DWORD
+            && dwSize == sizeof(DWORD))
+        {
+            g_dwVerbosity = 1; /* Default logging level. */
+        }
+
+        if (g_dwVerbosity) /* Do we want logging at all? */
+        {
+            dwRet = RegQueryValueEx(hKey, L"LoggingLevel", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
+            if (   dwRet  == ERROR_SUCCESS
+                && dwType == REG_DWORD
+                && dwSize == sizeof(DWORD))
+            {
+                g_dwVerbosity = dwValue;
+            }
+        }
+
         RegCloseKey(hKey);
     }
     /* Do not report back an error here yet. */
-    return ERROR_SUCCESS;
+    return VINF_SUCCESS;
 }
 
@@ -97,13 +114,14 @@
  * @return  bool        true if we should handle this session, false if not.
  */
-bool handleCurrentSession(void)
+bool VBoxGINAHandleCurrentSession(void)
 {
     /* Load global configuration from registry. */
-    DWORD dwRet = loadConfiguration();
-    if (ERROR_SUCCESS != dwRet)
-        LogRel(("VBoxGINA::handleCurrentSession: Error loading global configuration, error=%ld\n", dwRet));
+    int rc = VBoxGINALoadConfiguration();
+    if (RT_FAILURE(rc))
+        VBoxGINAVerbose(0, "VBoxGINA::handleCurrentSession: Error loading global configuration, rc=%Rrc\n",
+                        rc);
 
     bool fHandle = false;
-    if (isRemoteSession())
+    if (VbglR3AutoLogonIsRemoteSession())
     {
         if (g_dwHandleRemoteSessions) /* Force remote session handling. */
@@ -113,94 +131,6 @@
         fHandle = true;
 
-    if (!fHandle)
-        LogRel(("VBoxGINA::handleCurrentSession: Handling of remote desktop sessions is disabled.\n"));
-
+    VBoxGINAVerbose(3, "VBoxGINA::handleCurrentSession: Handling current session=%RTbool\n", fHandle);
     return fHandle;
-}
-
-void credentialsReset(void)
-{
-    RT_ZERO(g_Username);
-    RT_ZERO(g_Password);
-    RT_ZERO(g_Domain);
-}
-
-bool credentialsAvailable(void)
-{
-    if (!handleCurrentSession())
-        return false;
-
-    HANDLE vboxDriver = getVBoxDriver();
-    if (vboxDriver ==  INVALID_HANDLE_VALUE)
-        return false;
-
-    /* query the VMMDev whether there are credentials */
-    VMMDevCredentials vmmreqCredentials = {0};
-    vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqCredentials, VMMDevReq_QueryCredentials);
-    vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_QUERYPRESENCE;
-    DWORD cbReturned;
-    if (!DeviceIoControl(vboxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(vmmreqCredentials)), &vmmreqCredentials, sizeof(vmmreqCredentials),
-                         &vmmreqCredentials, sizeof(vmmreqCredentials), &cbReturned, NULL))
-    {
-        Log(("VBoxGINA::credentialsAvailable: error doing IOCTL, last error: %d\n", GetLastError()));
-        return false;
-    }
-    bool fAvailable = ((vmmreqCredentials.u32Flags & VMMDEV_CREDENTIALS_PRESENT) != 0);
-    /*Log(("VBoxGINA::credentialsAvailable: fAvailable: %d\n", fAvailable));*/
-    return fAvailable;
-}
-
-bool credentialsRetrieve(void)
-{
-    if (!handleCurrentSession())
-        return false;
-
-    Log(("VBoxGINA::credentialsRetrieve\n"));
-
-    HANDLE vboxDriver = getVBoxDriver();
-    if (vboxDriver == INVALID_HANDLE_VALUE)
-        return false;
-
-    /* to be safe, reset the credentials */
-    credentialsReset();
-
-    /* query the credentials */
-    VMMDevCredentials vmmreqCredentials = {0};
-    vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqCredentials, VMMDevReq_QueryCredentials);
-    vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_READ;
-    vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_CLEAR;
-    DWORD cbReturned;
-    if (!DeviceIoControl(vboxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(vmmreqCredentials)), &vmmreqCredentials, sizeof(vmmreqCredentials),
-                         &vmmreqCredentials, sizeof(vmmreqCredentials), &cbReturned, NULL))
-    {
-        Log(("VBoxGINA::credentialsRetrieve: error doing IOCTL, last error: %d\n", GetLastError()));
-        return false;
-    }
-    /* convert from UTF-8 to UTF-16 and store in global variables */
-    PRTUTF16 ptr = NULL;
-    if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szUserName, &ptr)) && ptr)
-    {
-        wcscpy(g_Username, ptr);
-        RTUtf16Free(ptr);
-    }
-    ptr = NULL;
-    if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szPassword, &ptr)) && ptr)
-    {
-        wcscpy(g_Password, ptr);
-        RTUtf16Free(ptr);
-    }
-    ptr = NULL;
-    if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szDomain, &ptr)) && ptr)
-    {
-        wcscpy(g_Domain, ptr);
-        RTUtf16Free(ptr);
-    }
-    Log(("VBoxGINA::credentialsRetrieve: returning user '%s', password '%s', domain '%s'\n",
-         vmmreqCredentials.szUserName, vmmreqCredentials.szPassword, vmmreqCredentials.szDomain));
-
-    /* Let the release log know that we got something. */
-    LogRel(("VBoxGINA: Credentials from host retrieved\n"));
-
-    return true;
 }
 
@@ -208,5 +138,4 @@
 RTTHREAD gThreadPoller = NIL_RTTHREAD;
 
-
 /**
  * Poller thread. Checks periodically whether there are credentials.
@@ -214,11 +143,12 @@
 static DECLCALLBACK(int) credentialsPoller(RTTHREAD ThreadSelf, void *pvUser)
 {
-    Log(("VBoxGINA::credentialsPoller\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller\n");
 
     do
     {
-        if (credentialsAvailable())
-        {
-            Log(("VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n"));
+        int rc = VbglR3CredentialsQueryAvailability();
+        if (RT_SUCCESS(rc))
+        {
+            VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n");
             /* tell WinLogon to start the attestation process */
             pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
@@ -226,8 +156,17 @@
             return 0;
         }
+
+        if (   RT_FAILURE(rc)
+            && rc != VERR_NOT_FOUND)
+        {
+            static int s_cBitchedQueryAvail = 0;
+            if (s_cBitchedQueryAvail++ < 5)
+                VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: querying for credentials failed with rc=%Rrc\n", rc);
+        }
+
         /* wait a bit */
         if (RTThreadUserWait(ThreadSelf, 500) == VINF_SUCCESS)
         {
-            Log(("VBoxGINA::credentialsPoller: we were asked to terminate\n"));
+            VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: we were asked to terminate\n");
             /* we were asked to terminate, do that instantly! */
             return 0;
@@ -239,16 +178,16 @@
 }
 
-bool credentialsPollerCreate(void)
-{
-    if (!handleCurrentSession())
-        return false;
-
-    Log(("VBoxGINA::credentialsPollerCreate\n"));
+int VBoxGINACredentialsPollerCreate(void)
+{
+    if (!VBoxGINAHandleCurrentSession())
+        return VINF_SUCCESS;
+
+    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate\n");
 
     /* don't create more than one of them */
     if (gThreadPoller != NIL_RTTHREAD)
     {
-        Log(("VBoxGINA::credentialsPollerCreate: thread already running, returning!\n"));
-        return false;
+        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: thread already running, returning!\n");
+        return VINF_SUCCESS;
     }
 
@@ -257,39 +196,49 @@
                             RTTHREADFLAGS_WAITABLE, "creds");
     if (RT_FAILURE(rc))
-    {
-        Log(("VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc));
-        return false;
-    }
-    return true;
-}
-
-bool credentialsPollerTerminate(void)
-{
-    Log(("VBoxGINA::credentialsPollerTerminate\n"));
-
+        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc);
+
+    return rc;
+}
+
+int VBoxGINACredentialsPollerTerminate(void)
+{
     if (gThreadPoller == NIL_RTTHREAD)
-    {
-        Log(("VBoxGINA::credentialsPollerTerminate: either thread or exit sem is NULL!\n"));
-        return false;
-    }
+        return VINF_SUCCESS;
+
+    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate\n");
+
     /* post termination event semaphore */
     int rc = RTThreadUserSignal(gThreadPoller);
     if (RT_SUCCESS(rc))
     {
-        Log(("VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n"));
-        /* wait until the thread has terminated */
+        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n");
         rc = RTThreadWait(gThreadPoller, RT_INDEFINITE_WAIT, NULL);
-        Log(("VBoxGINA::credentialsPollerTermiante: thread has (probably) terminated (rc = %Rrc)\n", rc));
     }
     else
-    {
-        /* failed to signal the thread - very unlikely - so no point in waiting long. */
-        Log(("VBoxGINA::credentialsPollerTermiante: failed to signal semaphore, rc = %Rrc\n", rc));
-        rc = RTThreadWait(gThreadPoller, 100, NULL);
-        Log(("VBoxGINA::credentialsPollerTermiante: thread has terminated? wait rc = %Rrc\n", rc));
-    }
-    /* now cleanup */
-    gThreadPoller = NIL_RTTHREAD;
-    return true;
-}
-
+        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: thread has terminated? wait rc = %Rrc\n",     rc);
+
+    if (RT_SUCCESS(rc))
+    {
+        gThreadPoller = NIL_RTTHREAD;
+    }
+
+    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: returned with rc=%Rrc)\n", rc);
+    return rc;
+}
+
+/**
+ * Reports VBoxGINA's status to the host (treated as a guest facility).
+ *
+ * @return  IPRT status code.
+ * @param   enmStatus               Status to report to the host.
+ */
+int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus)
+{
+    VBoxGINAVerbose(0, "VBoxGINA: reporting status %d\n", enmStatus);
+
+    int rc = VbglR3AutoLogonReportStatus(enmStatus);
+    if (RT_FAILURE(rc))
+        VBoxGINAVerbose(0, "VBoxGINA: failed to report status %d, rc=%Rrc\n", enmStatus, rc);
+    return rc;
+}
+
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.h	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.h	(revision 40214)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -18,20 +18,15 @@
 #define ___H_GINAHELPER
 
-#include <iprt/thread.h>
-#include <iprt/semaphore.h>
+#include <VBox/VBoxGuestLib.h>
 
-/* the credentials */
-extern wchar_t g_Username[];
-extern wchar_t g_Password[];
-extern wchar_t g_Domain[];
+void VBoxGINAVerbose(DWORD dwLevel, const char *pszFormat, ...);
 
-DWORD loadConfiguration();
-bool handleCurrentSession(void);
+int  VBoxGINALoadConfiguration();
+bool VBoxGINAHandleCurrentSession(void);
 
-void credentialsReset(void);
-bool credentialsAvailable(void);
-bool credentialsRetrieve(void);
-bool credentialsPollerCreate(void);
-bool credentialsPollerTerminate(void);
+int VBoxGINACredentialsPollerCreate(void);
+int VBoxGINACredentialsPollerTerminate(void);
+
+int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus);
 
 #endif /* !___H_GINAHELPER */
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/Makefile.kmk	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/Makefile.kmk	(revision 40214)
@@ -5,5 +5,5 @@
 
 #
-# Copyright (C) 2006-2011 Oracle Corporation
+# Copyright (C) 2006-2012 Oracle Corporation
 #
 # This file is part of VirtualBox Open Source Edition (OSE), as
@@ -22,7 +22,4 @@
 VBoxGINA_TEMPLATE = VBOXGUESTR3DLL
 VBoxGINA_DEFS     = UNICODE VBGL_VBOXGUEST VBOX_WITH_HGCM
-ifdef DEBUG_andy
- VBoxGINA_DEFS   += LOG_ENABLED
-endif
 VBoxGINA_SOURCES  = \
 	VBoxGINA.cpp \
@@ -35,4 +32,7 @@
 	$(VBOX_LIB_VBGL_R3)
 
+# Include testcase(s).
+include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+
 include	$(KBUILD_PATH)/subfooter.kmk
 
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.cpp	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.cpp	(revision 40214)
@@ -3,5 +3,5 @@
  * VBoxGINA -- Windows Logon DLL for VirtualBox
  *
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -17,9 +17,14 @@
 #include <stdlib.h>
 #include <windows.h>
+
+#include <iprt/buildconfig.h>
+#include <iprt/initterm.h>
+
+#include <VBox/VBoxGuestLib.h>
+
 #include "winwlx.h"
 #include "VBoxGINA.h"
 #include "Helper.h"
 #include "Dialog.h"
-#include <VBox/VBoxGuestLib.h>
 
 /*
@@ -78,7 +83,12 @@
         case DLL_PROCESS_ATTACH:
         {
-            RTR3InitDll(0);
+            RTR3InitDll(0 /* Flags */);
             VbglR3Init();
-            LogRel(("VBoxGINA: DLL loaded.\n"));
+
+            VBoxGINALoadConfiguration();
+
+            VBoxGINAVerbose(0, "VBoxGINA: v%s r%s (%s %s) loaded\n",
+                            RTBldCfgVersion(), RTBldCfgRevisionStr(),
+                            __DATE__, __TIME__);
 
             DisableThreadLibraryCalls(hInstance);
@@ -89,5 +99,5 @@
         case DLL_PROCESS_DETACH:
         {
-            LogRel(("VBoxGINA: DLL unloaded.\n"));
+            VBoxGINAVerbose(0, "VBoxGINA: Unloaded\n");
             VbglR3Term();
             /// @todo RTR3Term();
@@ -107,15 +117,10 @@
     HINSTANCE hDll;
 
-#ifdef DEBUG_andy
-    /* Enable full log output. */
-    RTLogGroupSettings(0, "+autologon.e.l.f.l2.l3");
-#endif
-
-    Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion);
 
     /* Load the standard Microsoft GINA DLL. */
     if (!(hDll = LoadLibrary(TEXT("MSGINA.DLL"))))
     {
-        Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! Last error=%ld\n", GetLastError()));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed loading MSGINA! Last error=%ld\n", GetLastError());
         return FALSE;
     }
@@ -127,5 +132,5 @@
     if (!GWlxNegotiate)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n");
         return FALSE;
     }
@@ -133,5 +138,5 @@
     if (!GWlxInitialize)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n");
         return FALSE;
     }
@@ -140,5 +145,5 @@
     if (!GWlxDisplaySASNotice)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n");
         return FALSE;
     }
@@ -147,5 +152,5 @@
     if (!GWlxLoggedOutSAS)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n");
         return FALSE;
     }
@@ -154,5 +159,5 @@
     if (!GWlxActivateUserShell)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n");
         return FALSE;
     }
@@ -161,5 +166,5 @@
     if (!GWlxLoggedOnSAS)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n");
         return FALSE;
     }
@@ -168,5 +173,5 @@
     if (!GWlxDisplayLockedNotice)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n");
         return FALSE;
     }
@@ -174,5 +179,5 @@
     if (!GWlxIsLockOk)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n");
         return FALSE;
     }
@@ -181,5 +186,5 @@
     if (!GWlxWkstaLockedSAS)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n");
         return FALSE;
     }
@@ -187,5 +192,5 @@
     if (!GWlxIsLogoffOk)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n");
         return FALSE;
     }
@@ -193,5 +198,5 @@
     if (!GWlxLogoff)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n");
         return FALSE;
     }
@@ -199,5 +204,5 @@
     if (!GWlxShutdown)
     {
-        Log(("VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n");
         return FALSE;
     }
@@ -215,17 +220,17 @@
     GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)GetProcAddress(hDll, "WlxReconnectNotify");
     GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)GetProcAddress(hDll, "WlxDisconnectNotify");
-    Log(("VBoxGINA::WlxNegotiate: optional function pointers:\n"
-             "  WlxStartApplication: %p\n"
-             "  WlxScreenSaverNotify: %p\n"
-             "  WlxNetworkProviderLoad: %p\n"
-             "  WlxDisplayStatusMessage: %p\n"
-             "  WlxGetStatusMessage: %p\n"
-             "  WlxRemoveStatusMessage: %p\n"
-             "  WlxGetConsoleSwitchCredentials: %p\n"
-             "  WlxReconnectNotify: %p\n"
-             "  WlxDisconnectNotify: %p\n",
-             GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
-             GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
-             GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: optional function pointers:\n"
+                    "  WlxStartApplication: %p\n"
+                    "  WlxScreenSaverNotify: %p\n"
+                    "  WlxNetworkProviderLoad: %p\n"
+                    "  WlxDisplayStatusMessage: %p\n"
+                    "  WlxGetStatusMessage: %p\n"
+                    "  WlxRemoveStatusMessage: %p\n"
+                    "  WlxGetConsoleSwitchCredentials: %p\n"
+                    "  WlxReconnectNotify: %p\n"
+                    "  WlxDisconnectNotify: %p\n",
+                    GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
+                    GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
+                    GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify);
 
     wlxVersion = dwWinlogonVersion;
@@ -242,5 +247,5 @@
                           PVOID pWinlogonFunctions, PVOID *pWlxContext)
 {
-    Log(("VBoxGINA::WlxInitialize\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxInitialize\n");
 
     /* Store Winlogon function table */
@@ -250,4 +255,6 @@
     hGinaWlx = hWlx;
 
+    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Init);
+
     /* Hook the dialogs */
     hookDialogBoxes(pWlxFuncs, wlxVersion);
@@ -260,10 +267,11 @@
 VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxDisplaySASNotice\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice\n");
 
     /* Check if there are credentials for us, if so simulate C-A-D */
-    if (credentialsAvailable())
-    {
-        Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
+    int rc = VbglR3CredentialsQueryAvailability();
+    if (RT_SUCCESS(rc))
+    {
+        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n");
         /* Wutomatic C-A-D */
         pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
@@ -271,7 +279,7 @@
     else
     {
-        Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n");
         /* start the credentials poller thread */
-        credentialsPollerCreate();
+        VBoxGINACredentialsPollerCreate();
         /* Forward call to MSGINA. */
         GWlxDisplaySASNotice(pWlxContext);
@@ -284,9 +292,10 @@
                            PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
 {
-    Log(("VBoxGINA::WlxLoggedOutSAS\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOutSAS\n");
 
     /* When performing a direct logon without C-A-D, our poller might not be running */
-    if (!credentialsAvailable())
-        credentialsPollerCreate();
+    int rc = VbglR3CredentialsQueryAvailability();
+    if (RT_FAILURE(rc))
+        VBoxGINACredentialsPollerCreate();
 
     int iRet;
@@ -310,8 +319,17 @@
 
 
+/**
+ * WinLogon calls this function following a successful logon to request that the GINA activate the user's shell program.
+ */
 BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
                                  PWSTR pszMprLogonScript, PVOID pEnvironment)
 {
-    Log(("VBoxGINA::WlxActivateUserShell\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxActivateUserShell\n");
+
+    /*
+     * Report status "terminated" to the host -- this means that a user
+     * got logged in (either manually or automatically using the provided credentials).
+     */
+    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
 
     /* Forward call to MSGINA. */
@@ -322,5 +340,5 @@
 int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
 {
-    Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: dwSasType=%ld\n", dwSasType);
 
     /*
@@ -331,5 +349,5 @@
 
     /* Forward call to MSGINA. */
-    Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n");
     return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
 }
@@ -337,10 +355,11 @@
 VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxDisplayLockedNotice\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice\n");
 
     /* Check if there are credentials for us, if so simulate C-A-D */
-    if (credentialsAvailable())
-    {
-        Log(("VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n"));
+    int rc = VbglR3CredentialsQueryAvailability();
+    if (RT_SUCCESS(rc))
+    {
+        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n");
         /* Automatic C-A-D */
         pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
@@ -348,7 +367,7 @@
     else
     {
-        Log(("VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n"));
+        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n");
         /* start the credentials poller thread */
-        credentialsPollerCreate();
+        VBoxGINACredentialsPollerCreate();
         /* Forward call to MSGINA. */
         GWlxDisplayLockedNotice(pWlxContext);
@@ -357,18 +376,23 @@
 
 
+/*
+ * Winlogon calls this function before it attempts to lock the workstation.
+ */
 BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxIsLockOk\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxIsLockOk\n");
     /* Forward call to MSGINA. */
     return GWlxIsLockOk(pWlxContext);
 }
 
+
 int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
 {
-    Log(("VBoxGINA::WlxWkstaLockedSAS\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxWkstaLockedSAS, dwSasType=%ld\n", dwSasType);
 
     /* When performing a direct logon without C-A-D, our poller might not be running */
-    if (!credentialsAvailable())
-        credentialsPollerCreate();
+    int rc = VbglR3CredentialsQueryAvailability();
+    if (RT_FAILURE(rc))
+        VBoxGINACredentialsPollerCreate();
 
     /* Forward call to MSGINA. */
@@ -376,25 +400,23 @@
 }
 
+
 BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxIsLogoffOk\n"));
-
-    BOOL bSuccess = GWlxIsLogoffOk(pWlxContext);
-    if (bSuccess)
-    {
-        //
-        // if it's ok to logoff, finish with the stored credentials
-        // and scrub the buffers
-        //
-        credentialsReset();
-
-    }
-    return bSuccess;
-}
-
-
+    VBoxGINAVerbose(0, "VBoxGINA::WlxIsLogoffOk\n");
+
+    return GWlxIsLogoffOk(pWlxContext);
+}
+
+
+/*
+ * Winlogon calls this function to notify the GINA of a logoff operation on this
+ * workstation. This allows the GINA to perform any logoff operations that may be required.
+ */
 VOID WINAPI WlxLogoff(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxLogoff\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxLogoff\n");
+
+    /* No need to report the "active" status to the host here -- this will be done
+     * when VBoxGINA gets the chance to hook the dialogs (again). */
 
     /* Forward call to MSGINA. */
@@ -403,7 +425,19 @@
 
 
+/*
+ * Winlogon calls this function just before shutting down.
+ * This allows the GINA to perform any necessary shutdown tasks.
+ * Will be called *after* WlxLogoff!
+ */
 VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
 {
-    Log(("VBoxGINA::WlxShutdown\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxShutdown\n");
+
+    /*
+     * Report status "inactive" to the host -- this means the
+     * auto-logon feature won't be active anymore at this point
+     * (until it maybe gets loaded again after a reboot).
+     */
+    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Inactive);
 
     /* Forward call to MSGINA. */
@@ -417,5 +451,5 @@
 BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
 {
-    Log(("VBoxGINA::WlxScreenSaverNotify\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxScreenSaverNotify\n");
 
     /* Forward to MSGINA if present. */
@@ -431,6 +465,6 @@
                                 PVOID pEnvironment, PWSTR pszCmdLine)
 {
-    Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
-         pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
+                    pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
 
     /* Forward to MSGINA if present. */
@@ -446,5 +480,5 @@
 BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
 {
-    Log(("VBoxGINA::WlxNetworkProviderLoad\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxNetworkProviderLoad\n");
 
     /* Forward to MSGINA if present. */
@@ -458,5 +492,5 @@
                                     PWSTR pTitle, PWSTR pMessage)
 {
-    Log(("VBoxGINA::WlxDisplayStatusMessage\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayStatusMessage\n");
 
     /* Forward to MSGINA if present. */
@@ -470,5 +504,5 @@
                                 PWSTR pMessage, DWORD dwBufferSize)
 {
-    Log(("VBoxGINA::WlxGetStatusMessage\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxGetStatusMessage\n");
 
     /* Forward to MSGINA if present. */
@@ -481,5 +515,5 @@
 BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxRemoveStatusMessage\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxRemoveStatusMessage\n");
 
     /* Forward to MSGINA if present. */
@@ -495,5 +529,5 @@
 BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
 {
-    Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxGetConsoleSwitchCredentials\n");
 
     /* Forward call to MSGINA if present */
@@ -506,5 +540,5 @@
 VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxReconnectNotify\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxReconnectNotify\n");
 
     /* Forward to MSGINA if present. */
@@ -516,5 +550,5 @@
 VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
 {
-    Log(("VBoxGINA::WlxDisconnectNotify\n"));
+    VBoxGINAVerbose(0, "VBoxGINA::WlxDisconnectNotify\n");
 
     /* Forward to MSGINA if present. */
@@ -523,2 +557,39 @@
 }
 
+
+DWORD WINAPI VBoxGINADebug(void)
+{
+#ifdef DEBUG
+    DWORD dwVersion;
+    BOOL fRes = WlxNegotiate(WLX_VERSION_1_4, &dwVersion);
+    if (!fRes)
+        return 1;
+
+    void* pWlxContext = NULL;
+    WLX_DISPATCH_VERSION_1_4 wlxDispatch;
+    ZeroMemory(&wlxDispatch, sizeof(WLX_DISPATCH_VERSION_1_4));
+
+    fRes = WlxInitialize(0, 0,
+                         NULL /* Reserved */,
+                         NULL /* Winlogon functions */,
+                         &pWlxContext);
+    if (!fRes)
+        return 2;
+
+    WlxDisplaySASNotice(pWlxContext);
+
+    char szSID[MAX_PATH];
+    LUID luidAuth;
+    DWORD dwOpts;
+    WLX_MPR_NOTIFY_INFO wlxNotifyInfo;
+    void* pvProfile;
+    HANDLE hToken;
+    int iRes = WlxLoggedOutSAS(pWlxContext, WLX_SAS_TYPE_CTRL_ALT_DEL,
+                               &luidAuth, szSID,
+                               &dwOpts, &hToken, &wlxNotifyInfo, &pvProfile);
+    return iRes;
+#else
+    return 0;
+#endif
+}
+
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.def
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.def	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.def	(revision 40214)
@@ -3,5 +3,5 @@
 ; * VBoxGINA -- Windows Logon DLL for VirtualBox
 ; *
-; Copyright (C) 2006-2007 Oracle Corporation
+; Copyright (C) 2006-2012 Oracle Corporation
 ;
 ; This file is part of VirtualBox Open Source Edition (OSE), as
@@ -42,2 +42,4 @@
 	WlxReconnectNotify
 	WlxDisconnectNotify
+    ; Debug
+    VBoxGINADebug
Index: trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.h	(revision 40136)
+++ trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.h	(revision 40214)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -15,11 +15,6 @@
  */
 
-#ifndef ___H_VBOXGINA
-#define ___H_VBOXGINA
-
-#include <iprt/initterm.h>
-
-#define LOG_GROUP LOG_GROUP_AUTOLOGON
-#include <VBox/log.h>
+#ifndef __VBOXGINA_H__
+#define __VBOXGINA_H__
 
 /** Handle to Winlogon service */
@@ -59,4 +54,4 @@
 /** @}  */
 
-#endif /* !___H_VBOXGINA */
+#endif /* !__VBOXGINA_H__ */
 
