VirtualBox

Changeset 40214 in vbox


Ignore:
Timestamp:
Feb 22, 2012 2:36:09 PM (13 years ago)
Author:
vboxsync
Message:

VBoxGINA: Added support for auto-logon facility, added guest log support, misc. refactoring, added basic testcase.

Location:
trunk/src/VBox/Additions/WINNT/VBoxGINA
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/Dialog.cpp

    r36258 r40214  
    66/*
    77 *
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#include <windows.h>
    2020#include <stdio.h>      /* Needed for swprintf() */
     21
     22#include <VBox/VboxGuestLib.h>
    2123
    2224#include "Dialog.h"
     
    9294void hookDialogBoxes(PVOID pWinlogonFunctions, DWORD dwWlxVersion)
    9395{
    94     Log(("VBoxGINA::hookDialogBoxes\n"));
     96    if (!pWinlogonFunctions) /* Needed for testcase. */
     97        return;
     98
     99    VBoxGINAVerbose(0, "VBoxGINA::hookDialogBoxes\n");
    95100
    96101    /* this is version dependent */
     
    134139        default:
    135140        {
    136             Log(("VBoxGINA::hookDialogBoxes: unrecognized version '%d', nothing hooked!\n", dwWlxVersion));
     141            VBoxGINAVerbose(0, "VBoxGINA::hookDialogBoxes: unrecognized version '%d', nothing hooked!\n", dwWlxVersion);
    137142            /* not good, don't do anything */
    138143            break;
     
    141146}
    142147
    143 //
    144 // Redirected WlxLoggedOutSASDlgProc().
    145 //
    146 BOOL credentialsToUI(HWND hwndUserId, HWND hwndPassword, HWND hwndDomain)
     148/**
     149 * Enters credentials into the given text fields.
     150 *
     151 * @return  IPRT status code.
     152 * @param   hwndDlg                 Handle of dialog to enter credentials into.
     153 * @param   hwndUserId              Handle of username text field. Optional.
     154 * @param   hwndPassword            Handle of password text field. Optional.
     155 * @param   hwndDomain              Handle of domain text field. Optional.
     156 * @param   pwszUser                Username to enter into username text field.
     157 * @param   pwszPassword            Password to enter into password text field.
     158 * @param   pwszDomain              Domain to enter into domain text field.
     159 */
     160int credentialsToUI(HWND hwndDlg,
     161                    HWND hwndUserId, HWND hwndPassword, HWND hwndDomain,
     162                    PCRTUTF16 pwszUser, PCRTUTF16 pwszPassword, PCRTUTF16 pwszDomain)
    147163{
    148164    BOOL bIsFQDN = FALSE;
     
    151167    {
    152168        /* search the domain combo box for our required domain and select it */
    153         Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Trying to find domain entry in combo box ...\n"));
     169        VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Trying to find domain entry in combo box ...\n");
    154170        DWORD dwIndex = (DWORD) SendMessage(hwndDomain, CB_FINDSTRING,
    155                                             0, (LPARAM)g_Domain);
     171                                            0, (LPARAM)pwszDomain);
    156172        if (dwIndex != CB_ERR)
    157173        {
    158             Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Found domain at combo box pos %ld\n", dwIndex));
     174            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Found domain at combo box pos %ld\n", dwIndex);
    159175            SendMessage(hwndDomain, CB_SETCURSEL, (WPARAM) dwIndex, 0);
    160176            EnableWindow(hwndDomain, FALSE);
     
    162178        else
    163179        {
    164             Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain not found in combo box ...\n"));
     180            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain not found in combo box ...\n");
    165181
    166182            /* If the domain value has a dot (.) in it, it is a FQDN (Fully Qualified Domain Name)
     
    173189             *
    174190             */
    175             size_t l = wcslen(g_Domain);
     191            size_t l = wcslen(pwszDomain);
    176192            if (l > 255)
    177                 Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Warning! FQDN is too long (max 255 bytes), will be truncated!\n"));
    178 
    179             if (wcslen(g_Username) > 0) /* We need a user name that we can use in caes of a FQDN */
     193                VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Warning! FQDN (domain) is too long (max 255 bytes), will be truncated!\n");
     194
     195            if (wcslen(pwszUser) > 0) /* We need a user name that we can use in caes of a FQDN */
    180196            {
    181197                if (l > 16) /* Domain name is longer than 16 chars, cannot be a NetBIOS name anymore */
    182198                {
    183                     Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (length)!\n"));
     199                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (length)!\n");
    184200                    bIsFQDN = TRUE;
    185201                }
    186202                else if (   l > 0
    187                          && wcsstr(g_Domain, L".") != NULL) /* if we found a dot (.) in the domain name, this has to be a FQDN */
     203                         && wcsstr(pwszDomain, L".") != NULL) /* if we found a dot (.) in the domain name, this has to be a FQDN */
    188204                {
    189                     Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (dot)!\n"));
     205                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: Domain seems to be a FQDN (dot)!\n");
    190206                    bIsFQDN = TRUE;
    191207                }
     
    193209                if (bIsFQDN)
    194210                {
    195                     swprintf(szUserFQDN, sizeof(szUserFQDN) / sizeof(wchar_t), L"%s@%s", g_Username, g_Domain);
    196                     Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: FQDN user name is now: %s!\n", szUserFQDN));
     211                    swprintf(szUserFQDN, sizeof(szUserFQDN) / sizeof(wchar_t), L"%s@%s", pwszUser, pwszDomain);
     212                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: FQDN user name is now: %s!\n", szUserFQDN);
    197213                }
    198214            }
     
    202218    {
    203219        if (!bIsFQDN)
    204             SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)g_Username);
     220            SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)pwszUser);
    205221        else
    206222            SendMessage(hwndUserId, WM_SETTEXT, 0, (LPARAM)szUserFQDN);
    207223    }
    208224    if (hwndPassword)
    209         SendMessage(hwndPassword, WM_SETTEXT, 0, (LPARAM)g_Password);
    210 
    211     return TRUE;
     225        SendMessage(hwndPassword, WM_SETTEXT, 0, (LPARAM)pwszPassword);
     226
     227    return VINF_SUCCESS; /** @todo */
     228}
     229
     230/**
     231 * Tries to retrieve credentials and enters them into the specified windows,
     232 * optionally followed by a button press to confirm/abort the dialog.
     233 *
     234 * @return  IPRT status code.
     235 * @param   hwndDlg                 Handle of dialog to enter credentials into.
     236 * @param   hwndUserId              Handle of username text field. Optional.
     237 * @param   hwndPassword            Handle of password text field. Optional.
     238 * @param   hwndDomain              Handle of domain text field. Optional.
     239 * @param   wButtonToPress          Button ID of dialog to press after successful
     240 *                                  retrieval + storage. If set to 0 no button will
     241 *                                  be pressed.
     242 */
     243int credentialsHandle(HWND hwndDlg,
     244                      HWND hwndUserId, HWND hwndPassword, HWND hwndDomain,
     245                      WORD wButtonToPress)
     246{
     247    int rc = VINF_SUCCESS;
     248
     249    if (!VBoxGINAHandleCurrentSession())
     250        rc = VERR_NOT_FOUND;
     251
     252    if (RT_SUCCESS(rc))
     253    {
     254        rc = VbglR3CredentialsQueryAvailability();
     255        if (RT_FAILURE(rc))
     256        {
     257            if (rc != VERR_NOT_FOUND)
     258                VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: error querying for credentials, rc=%Rrc\n", rc);
     259        }
     260    }
     261
     262    if (RT_SUCCESS(rc))
     263    {
     264        VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: credentials available\n");
     265
     266        /*
     267         * Set status to "terminating" to let the host know this module now
     268         * tries to receive and use passed credentials so that credentials from
     269         * the host won't be sent twice.
     270         */
     271        VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminating);
     272
     273        PRTUTF16 pwszUser, pwszPassword, pwszDomain;
     274        rc = VbglR3CredentialsRetrieveUtf16(&pwszUser, &pwszPassword, &pwszDomain);
     275        if (RT_SUCCESS(rc))
     276        {
     277    #ifdef DEBUG
     278            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=%ls, domain=%ls\n",
     279                            pwszUser, pwszPassword, pwszDomain);
     280    #else
     281            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=XXX, domain=%ls\n",
     282                            pwszUser, pwszDomain);
     283    #endif
     284            /* Fill in credentials to appropriate UI elements. */
     285            rc = credentialsToUI(hwndDlg,
     286                                 hwndUserId, hwndPassword, hwndDomain,
     287                                 pwszUser, pwszPassword, pwszDomain);
     288            if (RT_SUCCESS(rc))
     289            {
     290                /* Confirm/cancel the dialog by pressing the appropriate button. */
     291                if (wButtonToPress)
     292                {
     293                    WPARAM wParam = MAKEWPARAM(wButtonToPress, BN_CLICKED);
     294                    PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
     295                }
     296            }
     297
     298            VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain,
     299                                          3 /* Passes */);
     300        }
     301    }
     302
     303    VBoxGINAVerbose(3, "VBoxGINA::credentialsHandle: returned with rc=%Rrc\n", rc);
     304    return rc;
    212305}
    213306
     
    220313    static HWND s_hwndUserId, s_hwndPassword, s_hwndDomain = 0;
    221314
    222     /*Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc\n"));*/
     315    /*VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc\n");*/
    223316
    224317    //
     
    234327        case WM_INITDIALOG:
    235328        {
    236             Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: got WM_INITDIALOG\n"));
     329            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: got WM_INITDIALOG\n");
    237330
    238331            /* get the entry fields */
     
    247340                s_hwndDomain = GetDlgItem(hwndDlg, IDC_WLXLOGGEDOUTSAS_DOMAIN2);
    248341
    249             Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: hwndUserId: %x, hwndPassword: %d, hwndDomain: %d\n",
    250                  s_hwndUserId, s_hwndPassword, s_hwndDomain));
     342            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: hwndUserId: %x, hwndPassword: %d, hwndDomain: %d\n",
     343                            s_hwndUserId, s_hwndPassword, s_hwndDomain);
    251344
    252345            /* terminate the credentials poller thread, it's done is job */
    253             credentialsPollerTerminate();
    254 
    255             if (credentialsAvailable())
    256             {
    257                 /* query the credentials from VBox */
    258                 if (credentialsRetrieve())
    259                 {
    260                     /* fill in credentials to appropriate UI elements */
    261                     credentialsToUI(s_hwndUserId, s_hwndPassword, s_hwndDomain);
    262 
    263                     /* we got the credentials, null them out */
    264                     credentialsReset();
    265 
    266                     /* confirm the logon dialog, simulating the user pressing "OK" */
    267                     WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
    268                     PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
    269                 }
    270             }
    271             else
     346            VBoxGINACredentialsPollerTerminate();
     347
     348            int rc = credentialsHandle(hwndDlg,
     349                                       s_hwndUserId, s_hwndPassword, s_hwndDomain,
     350                                       IDOK /* Button */);
     351            if (RT_FAILURE(rc))
    272352            {
    273353                /*
     
    277357                UINT_PTR uTimer = SetTimer(hwndDlg, IDT_LOGGEDONDLG_POLL, 200, NULL);
    278358                if (!uTimer)
    279                     Log(("VBoxGINA::MyWlxLoggedOutSASDlgProc: failed creating timer! Last error: %ld\n",
    280                          GetLastError()));
     359                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLoggedOutSASDlgProc: failed creating timer! Last error: %ld\n",
     360                                    GetLastError());
    281361            }
    282362            break;
     
    288368            if (wParam == IDT_LOGGEDONDLG_POLL)
    289369            {
    290                 if (credentialsAvailable())
     370                int rc = credentialsHandle(hwndDlg,
     371                                           s_hwndUserId, s_hwndPassword, s_hwndDomain,
     372                                           IDOK /* Button */);
     373                if (RT_SUCCESS(rc))
    291374                {
    292                     if (credentialsRetrieve())
    293                     {
    294                         /* fill in credentials to appropriate UI elements */
    295                         credentialsToUI(s_hwndUserId, s_hwndPassword, s_hwndDomain);
    296 
    297                         /* we got the credentials, null them out */
    298                         credentialsReset();
    299 
    300                         /* confirm the logon dialog, simulating the user pressing "OK" */
    301                         WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
    302                         PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
    303 
    304                         /* we don't need the timer any longer */
    305                         KillTimer(hwndDlg, IDT_LOGGEDONDLG_POLL);
    306                     }
     375                    /* we don't need the timer any longer */
     376                    KillTimer(hwndDlg, IDT_LOGGEDONDLG_POLL);
    307377                }
    308378            }
     
    326396    static HWND s_hwndPassword = 0;
    327397
    328     /*Log(("VBoxGINA::MyWlxLockedSASDlgProc\n"));*/
     398    /*VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc\n");*/
    329399
    330400    //
     
    340410        case WM_INITDIALOG:
    341411        {
    342             Log(("VBoxGINA::MyWlxLockedSASDlgProc: got WM_INITDIALOG\n"));
     412            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: WM_INITDIALOG\n");
    343413
    344414            /* get the entry fields */
    345415            s_hwndPassword = GetDlgItem(hwndDlg, IDC_WKSTALOCKED_PASSWORD);
    346             Log(("VBoxGINA::MyWlxLockedSASDlgProc: hwndPassword: %d\n", s_hwndPassword));
     416            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: hwndPassword: %d\n", s_hwndPassword);
    347417
    348418            /* terminate the credentials poller thread, it's done is job */
    349             credentialsPollerTerminate();
    350 
    351             if (credentialsAvailable())
    352             {
    353                 /* query the credentials from VBox */
    354                 if (credentialsRetrieve())
    355                 {
    356                     /* fill in credentials to appropriate UI elements */
    357                     credentialsToUI(NULL /* User ID */, s_hwndPassword, NULL /* Domain */);
    358 
    359                     /* we got the credentials, null them out */
    360                     credentialsReset();
    361 
    362                     /* confirm the logon dialog, simulating the user pressing "OK" */
    363                     WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
    364                     PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
    365                 }
    366             }
    367             else
     419            VBoxGINACredentialsPollerTerminate();
     420
     421            int rc = credentialsHandle(hwndDlg,
     422                                       NULL /* Username */, s_hwndPassword, NULL /* Domain */,
     423                                       IDOK /* Button */);
     424            if (RT_FAILURE(rc))
    368425            {
    369426                /*
     
    373430                UINT_PTR uTimer = SetTimer(hwndDlg, IDT_LOCKEDDLG_POLL, 200, NULL);
    374431                if (!uTimer)
    375                     Log(("VBoxGINA::MyWlxLockedSASDlgProc: failed creating timer! Last error: %ld\n",
    376                          GetLastError()));
     432                    VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: failed creating timer! Last error: %ld\n",
     433                         GetLastError());
    377434            }
    378435            break;
     
    384441            if (wParam == IDT_LOCKEDDLG_POLL)
    385442            {
    386                 if (credentialsAvailable())
     443                int rc = credentialsHandle(hwndDlg,
     444                                           NULL /* Username */, s_hwndPassword, NULL /* Domain */,
     445                                           IDOK /* Button */);
     446                if (RT_SUCCESS(rc))
    387447                {
    388                     if (credentialsRetrieve())
    389                     {
    390                         /* fill in credentials to appropriate UI elements */
    391                         credentialsToUI(NULL /* User ID */, s_hwndPassword, NULL /* Domain */);
    392 
    393                         /* we got the credentials, null them out */
    394                         credentialsReset();
    395 
    396                         /* confirm the logon dialog, simulating the user pressing "OK" */
    397                         WPARAM wParam = MAKEWPARAM(IDOK, BN_CLICKED);
    398                         PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
    399 
    400                         /* we don't need the timer any longer */
    401                         KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
    402                     }
     448                    /* we don't need the timer any longer */
     449                    KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
    403450                }
    404451            }
     
    407454
    408455        case WM_DESTROY:
     456        {
     457            VBoxGINAVerbose(0, "VBoxGINA::MyWlxLockedSASDlgProc: WM_DESTROY\n");
     458
     459            /* Because this is the only point where we know within our module that the locked
     460             * dialog has been closed by a valid unlock password we have to set the appropriate
     461             * facility status here. */
     462            VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
     463
    409464            KillTimer(hwndDlg, IDT_LOCKEDDLG_POLL);
    410465            break;
     466        }
    411467    }
    412468    return bResult;
     
    421477                               LPARAM  dwInitParam)
    422478{
    423     Log(("VBoxGINA::MyWlxDialogBoxParam: lpszTemplate = %ls\n", lpszTemplate));
     479    VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: lpszTemplate=%ls\n", lpszTemplate);
     480
     481    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Active);
    424482
    425483    //
     
    433491        switch ((DWORD) lpszTemplate)
    434492        {
     493            case IDD_WLXDIAPLAYSASNOTICE_DIALOG:
     494                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: SAS notice dialog displayed; not handled\n");
     495                break;
     496
    435497            case IDD_WLXLOGGEDOUTSAS_DIALOG:     /* Windows NT 4.0. */
    436498            case IDD_WLXLOGGEDOUTSAS_DIALOG2:    /* Windows 2000 and up. */
    437499            {
    438                 Log(("VBoxGINA::MyWlxDialogBoxParam: returning hooked LOGGED OUT dialog\n"));
     500                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: returning hooked SAS logged out dialog\n");
    439501                g_pfnWlxLoggedOutSASDlgProc = dlgprc;
    440502                return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
     
    442504            }
    443505
     506            case IDD_SECURITY_DIALOG:
     507                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: Security dialog displayed; not handled\n");
     508                break;
     509
    444510            case IDD_WLXWKSTALOCKEDSAS_DIALOG:   /* Windows NT 4.0. */
    445511            case IDD_WLXWKSTALOCKEDSAS_DIALOG2:  /* Windows 2000 and up. */
    446512            {
    447                 Log(("VBoxGINA::MyWlxDialogBoxParam: returning hooked LOCKED dialog\n"));
     513                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: returning hooked SAS locked dialog\n");
    448514                g_pfnWlxLockedSASDlgProc = dlgprc;
    449515                return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
     
    454520
    455521            default:
    456             {
    457                 char szBuf[1024];
    458                 sprintf(szBuf, "VBoxGINA::MyWlxDialogBoxParam: dialog %ld not handled\n", (DWORD)lpszTemplate);
    459                 Log((szBuf));
     522                VBoxGINAVerbose(0, "VBoxGINA::MyWlxDialogBoxParam: dialog %ld not handled\n", (DWORD)lpszTemplate);
    460523                break;
    461             }
    462         }
    463     }
    464 
    465     //
    466     // The rest will not be redirected.
    467     //
     524        }
     525    }
     526
     527    /* The rest will be redirected. */
    468528    return g_pfnWlxDialogBoxParam(hWlx, hInst, lpszTemplate,
    469529                                  hwndOwner, dlgprc, dwInitParam);
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.cpp

    r39759 r40214  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717
    1818#include <windows.h>
     19
     20#include <iprt/semaphore.h>
     21#include <iprt/string.h>
     22#include <iprt/thread.h>
     23
    1924#include "winwlx.h"
    2025#include "Helper.h"
    2126#include "VBoxGINA.h"
    2227
    23 #include <VBox/VBoxGuest.h>
    24 #include <VBox/VMMDev.h>
    25 #include <iprt/string.h>
    26 
    27 /* remote session handling */
    28 DWORD g_dwHandleRemoteSessions = 0;
    29 
    30 /* the credentials */
    31 wchar_t g_Username[VMMDEV_CREDENTIALS_SZ_SIZE];
    32 wchar_t g_Password[VMMDEV_CREDENTIALS_SZ_SIZE];
    33 wchar_t g_Domain[VMMDEV_CREDENTIALS_SZ_SIZE];
    34 
    35 
    36 HANDLE getVBoxDriver(void)
    37 {
    38     static HANDLE sVBoxDriver = INVALID_HANDLE_VALUE;
    39     if (sVBoxDriver == INVALID_HANDLE_VALUE)
    40     {
    41         sVBoxDriver = CreateFile(L"\\\\.\\VBoxGuest", /** @todo use define */
    42                                  GENERIC_READ | GENERIC_WRITE,
    43                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
    44                                  NULL,
    45                                  OPEN_EXISTING,
    46                                  FILE_ATTRIBUTE_NORMAL,
    47                                  NULL);
    48         if (sVBoxDriver == INVALID_HANDLE_VALUE)
    49             Log(("VBoxGINA::sVBoxDriver: failed to open VBoxGuest driver, last error = %d\n", GetLastError()));
    50     }
    51     return sVBoxDriver;
    52 }
    53 
    54 /**
    55  * Detects whether our process is running in a remote session or not.
    56  *
    57  * @return  bool        true if running in a remote session, false if not.
    58  */
    59 bool isRemoteSession(void)
    60 {
    61     return (0 != GetSystemMetrics(SM_REMOTESESSION)) ? true : false;
     28#include <VBox/log.h>
     29#include <VBox/VboxGuestLib.h>
     30
     31/** Flag indicating whether remote sessions (over MSRDP) should be
     32 *  handled or not. Default is disabled. */
     33static DWORD g_dwHandleRemoteSessions = 0;
     34/** Verbosity flag for guest logging. */
     35static DWORD g_dwVerbosity = 0;
     36
     37/**
     38 * Displays a verbose message.
     39 *
     40 * @param   iLevel      Minimum log level required to display this message.
     41 * @param   pszFormat   The message text.
     42 * @param   ...         Format arguments.
     43 */
     44void VBoxGINAVerbose(DWORD dwLevel, const char *pszFormat, ...)
     45{
     46    if (dwLevel <= g_dwVerbosity)
     47    {
     48        va_list args;
     49        va_start(args, pszFormat);
     50        char *psz = NULL;
     51        RTStrAPrintfV(&psz, pszFormat, args);
     52        va_end(args);
     53
     54        AssertPtr(psz);
     55        LogRel(("%s", psz));
     56
     57        RTStrFree(psz);
     58    }
    6259}
    6360
     
    6562 * Loads the global configuration from registry.
    6663 *
    67  * @return  DWORD       Windows error code.
    68  */
    69 DWORD loadConfiguration(void)
     64 * @return  IPRT status code.
     65 */
     66int VBoxGINALoadConfiguration(void)
    7067{
    7168    HKEY hKey;
     
    8683            g_dwHandleRemoteSessions = dwValue;
    8784        }
     85
     86        dwRet = RegQueryValueEx(hKey, L"LoggingEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
     87        if (   dwRet  == ERROR_SUCCESS
     88            && dwType == REG_DWORD
     89            && dwSize == sizeof(DWORD))
     90        {
     91            g_dwVerbosity = 1; /* Default logging level. */
     92        }
     93
     94        if (g_dwVerbosity) /* Do we want logging at all? */
     95        {
     96            dwRet = RegQueryValueEx(hKey, L"LoggingLevel", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
     97            if (   dwRet  == ERROR_SUCCESS
     98                && dwType == REG_DWORD
     99                && dwSize == sizeof(DWORD))
     100            {
     101                g_dwVerbosity = dwValue;
     102            }
     103        }
     104
    88105        RegCloseKey(hKey);
    89106    }
    90107    /* Do not report back an error here yet. */
    91     return ERROR_SUCCESS;
     108    return VINF_SUCCESS;
    92109}
    93110
     
    97114 * @return  bool        true if we should handle this session, false if not.
    98115 */
    99 bool handleCurrentSession(void)
     116bool VBoxGINAHandleCurrentSession(void)
    100117{
    101118    /* Load global configuration from registry. */
    102     DWORD dwRet = loadConfiguration();
    103     if (ERROR_SUCCESS != dwRet)
    104         LogRel(("VBoxGINA::handleCurrentSession: Error loading global configuration, error=%ld\n", dwRet));
     119    int rc = VBoxGINALoadConfiguration();
     120    if (RT_FAILURE(rc))
     121        VBoxGINAVerbose(0, "VBoxGINA::handleCurrentSession: Error loading global configuration, rc=%Rrc\n",
     122                        rc);
    105123
    106124    bool fHandle = false;
    107     if (isRemoteSession())
     125    if (VbglR3AutoLogonIsRemoteSession())
    108126    {
    109127        if (g_dwHandleRemoteSessions) /* Force remote session handling. */
     
    113131        fHandle = true;
    114132
    115     if (!fHandle)
    116         LogRel(("VBoxGINA::handleCurrentSession: Handling of remote desktop sessions is disabled.\n"));
    117 
     133    VBoxGINAVerbose(3, "VBoxGINA::handleCurrentSession: Handling current session=%RTbool\n", fHandle);
    118134    return fHandle;
    119 }
    120 
    121 void credentialsReset(void)
    122 {
    123     RT_ZERO(g_Username);
    124     RT_ZERO(g_Password);
    125     RT_ZERO(g_Domain);
    126 }
    127 
    128 bool credentialsAvailable(void)
    129 {
    130     if (!handleCurrentSession())
    131         return false;
    132 
    133     HANDLE vboxDriver = getVBoxDriver();
    134     if (vboxDriver ==  INVALID_HANDLE_VALUE)
    135         return false;
    136 
    137     /* query the VMMDev whether there are credentials */
    138     VMMDevCredentials vmmreqCredentials = {0};
    139     vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqCredentials, VMMDevReq_QueryCredentials);
    140     vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_QUERYPRESENCE;
    141     DWORD cbReturned;
    142     if (!DeviceIoControl(vboxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(vmmreqCredentials)), &vmmreqCredentials, sizeof(vmmreqCredentials),
    143                          &vmmreqCredentials, sizeof(vmmreqCredentials), &cbReturned, NULL))
    144     {
    145         Log(("VBoxGINA::credentialsAvailable: error doing IOCTL, last error: %d\n", GetLastError()));
    146         return false;
    147     }
    148     bool fAvailable = ((vmmreqCredentials.u32Flags & VMMDEV_CREDENTIALS_PRESENT) != 0);
    149     /*Log(("VBoxGINA::credentialsAvailable: fAvailable: %d\n", fAvailable));*/
    150     return fAvailable;
    151 }
    152 
    153 bool credentialsRetrieve(void)
    154 {
    155     if (!handleCurrentSession())
    156         return false;
    157 
    158     Log(("VBoxGINA::credentialsRetrieve\n"));
    159 
    160     HANDLE vboxDriver = getVBoxDriver();
    161     if (vboxDriver == INVALID_HANDLE_VALUE)
    162         return false;
    163 
    164     /* to be safe, reset the credentials */
    165     credentialsReset();
    166 
    167     /* query the credentials */
    168     VMMDevCredentials vmmreqCredentials = {0};
    169     vmmdevInitRequest((VMMDevRequestHeader*)&vmmreqCredentials, VMMDevReq_QueryCredentials);
    170     vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_READ;
    171     vmmreqCredentials.u32Flags |= VMMDEV_CREDENTIALS_CLEAR;
    172     DWORD cbReturned;
    173     if (!DeviceIoControl(vboxDriver, VBOXGUEST_IOCTL_VMMREQUEST(sizeof(vmmreqCredentials)), &vmmreqCredentials, sizeof(vmmreqCredentials),
    174                          &vmmreqCredentials, sizeof(vmmreqCredentials), &cbReturned, NULL))
    175     {
    176         Log(("VBoxGINA::credentialsRetrieve: error doing IOCTL, last error: %d\n", GetLastError()));
    177         return false;
    178     }
    179     /* convert from UTF-8 to UTF-16 and store in global variables */
    180     PRTUTF16 ptr = NULL;
    181     if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szUserName, &ptr)) && ptr)
    182     {
    183         wcscpy(g_Username, ptr);
    184         RTUtf16Free(ptr);
    185     }
    186     ptr = NULL;
    187     if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szPassword, &ptr)) && ptr)
    188     {
    189         wcscpy(g_Password, ptr);
    190         RTUtf16Free(ptr);
    191     }
    192     ptr = NULL;
    193     if (RT_SUCCESS(RTStrToUtf16(vmmreqCredentials.szDomain, &ptr)) && ptr)
    194     {
    195         wcscpy(g_Domain, ptr);
    196         RTUtf16Free(ptr);
    197     }
    198     Log(("VBoxGINA::credentialsRetrieve: returning user '%s', password '%s', domain '%s'\n",
    199          vmmreqCredentials.szUserName, vmmreqCredentials.szPassword, vmmreqCredentials.szDomain));
    200 
    201     /* Let the release log know that we got something. */
    202     LogRel(("VBoxGINA: Credentials from host retrieved\n"));
    203 
    204     return true;
    205135}
    206136
     
    208138RTTHREAD gThreadPoller = NIL_RTTHREAD;
    209139
    210 
    211140/**
    212141 * Poller thread. Checks periodically whether there are credentials.
     
    214143static DECLCALLBACK(int) credentialsPoller(RTTHREAD ThreadSelf, void *pvUser)
    215144{
    216     Log(("VBoxGINA::credentialsPoller\n"));
     145    VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller\n");
    217146
    218147    do
    219148    {
    220         if (credentialsAvailable())
    221         {
    222             Log(("VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n"));
     149        int rc = VbglR3CredentialsQueryAvailability();
     150        if (RT_SUCCESS(rc))
     151        {
     152            VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n");
    223153            /* tell WinLogon to start the attestation process */
    224154            pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
     
    226156            return 0;
    227157        }
     158
     159        if (   RT_FAILURE(rc)
     160            && rc != VERR_NOT_FOUND)
     161        {
     162            static int s_cBitchedQueryAvail = 0;
     163            if (s_cBitchedQueryAvail++ < 5)
     164                VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: querying for credentials failed with rc=%Rrc\n", rc);
     165        }
     166
    228167        /* wait a bit */
    229168        if (RTThreadUserWait(ThreadSelf, 500) == VINF_SUCCESS)
    230169        {
    231             Log(("VBoxGINA::credentialsPoller: we were asked to terminate\n"));
     170            VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: we were asked to terminate\n");
    232171            /* we were asked to terminate, do that instantly! */
    233172            return 0;
     
    239178}
    240179
    241 bool credentialsPollerCreate(void)
    242 {
    243     if (!handleCurrentSession())
    244         return false;
    245 
    246     Log(("VBoxGINA::credentialsPollerCreate\n"));
     180int VBoxGINACredentialsPollerCreate(void)
     181{
     182    if (!VBoxGINAHandleCurrentSession())
     183        return VINF_SUCCESS;
     184
     185    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate\n");
    247186
    248187    /* don't create more than one of them */
    249188    if (gThreadPoller != NIL_RTTHREAD)
    250189    {
    251         Log(("VBoxGINA::credentialsPollerCreate: thread already running, returning!\n"));
    252         return false;
     190        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: thread already running, returning!\n");
     191        return VINF_SUCCESS;
    253192    }
    254193
     
    257196                            RTTHREADFLAGS_WAITABLE, "creds");
    258197    if (RT_FAILURE(rc))
    259     {
    260         Log(("VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc));
    261         return false;
    262     }
    263     return true;
    264 }
    265 
    266 bool credentialsPollerTerminate(void)
    267 {
    268     Log(("VBoxGINA::credentialsPollerTerminate\n"));
    269 
     198        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc);
     199
     200    return rc;
     201}
     202
     203int VBoxGINACredentialsPollerTerminate(void)
     204{
    270205    if (gThreadPoller == NIL_RTTHREAD)
    271     {
    272         Log(("VBoxGINA::credentialsPollerTerminate: either thread or exit sem is NULL!\n"));
    273         return false;
    274     }
     206        return VINF_SUCCESS;
     207
     208    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate\n");
     209
    275210    /* post termination event semaphore */
    276211    int rc = RTThreadUserSignal(gThreadPoller);
    277212    if (RT_SUCCESS(rc))
    278213    {
    279         Log(("VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n"));
    280         /* wait until the thread has terminated */
     214        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n");
    281215        rc = RTThreadWait(gThreadPoller, RT_INDEFINITE_WAIT, NULL);
    282         Log(("VBoxGINA::credentialsPollerTermiante: thread has (probably) terminated (rc = %Rrc)\n", rc));
    283216    }
    284217    else
    285     {
    286         /* failed to signal the thread - very unlikely - so no point in waiting long. */
    287         Log(("VBoxGINA::credentialsPollerTermiante: failed to signal semaphore, rc = %Rrc\n", rc));
    288         rc = RTThreadWait(gThreadPoller, 100, NULL);
    289         Log(("VBoxGINA::credentialsPollerTermiante: thread has terminated? wait rc = %Rrc\n", rc));
    290     }
    291     /* now cleanup */
    292     gThreadPoller = NIL_RTTHREAD;
    293     return true;
    294 }
    295 
     218        VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: thread has terminated? wait rc = %Rrc\n",     rc);
     219
     220    if (RT_SUCCESS(rc))
     221    {
     222        gThreadPoller = NIL_RTTHREAD;
     223    }
     224
     225    VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: returned with rc=%Rrc)\n", rc);
     226    return rc;
     227}
     228
     229/**
     230 * Reports VBoxGINA's status to the host (treated as a guest facility).
     231 *
     232 * @return  IPRT status code.
     233 * @param   enmStatus               Status to report to the host.
     234 */
     235int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus)
     236{
     237    VBoxGINAVerbose(0, "VBoxGINA: reporting status %d\n", enmStatus);
     238
     239    int rc = VbglR3AutoLogonReportStatus(enmStatus);
     240    if (RT_FAILURE(rc))
     241        VBoxGINAVerbose(0, "VBoxGINA: failed to report status %d, rc=%Rrc\n", enmStatus, rc);
     242    return rc;
     243}
     244
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/Helper.h

    r36446 r40214  
    44
    55/*
    6  * Copyright (C) 2006-2011 Oracle Corporation
     6 * Copyright (C) 2006-2012 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1818#define ___H_GINAHELPER
    1919
    20 #include <iprt/thread.h>
    21 #include <iprt/semaphore.h>
     20#include <VBox/VBoxGuestLib.h>
    2221
    23 /* the credentials */
    24 extern wchar_t g_Username[];
    25 extern wchar_t g_Password[];
    26 extern wchar_t g_Domain[];
     22void VBoxGINAVerbose(DWORD dwLevel, const char *pszFormat, ...);
    2723
    28 DWORD loadConfiguration();
    29 bool handleCurrentSession(void);
     24int  VBoxGINALoadConfiguration();
     25bool VBoxGINAHandleCurrentSession(void);
    3026
    31 void credentialsReset(void);
    32 bool credentialsAvailable(void);
    33 bool credentialsRetrieve(void);
    34 bool credentialsPollerCreate(void);
    35 bool credentialsPollerTerminate(void);
     27int VBoxGINACredentialsPollerCreate(void);
     28int VBoxGINACredentialsPollerTerminate(void);
     29
     30int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus);
    3631
    3732#endif /* !___H_GINAHELPER */
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/Makefile.kmk

    r38310 r40214  
    55
    66#
    7 # Copyright (C) 2006-2011 Oracle Corporation
     7# Copyright (C) 2006-2012 Oracle Corporation
    88#
    99# This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222VBoxGINA_TEMPLATE = VBOXGUESTR3DLL
    2323VBoxGINA_DEFS     = UNICODE VBGL_VBOXGUEST VBOX_WITH_HGCM
    24 ifdef DEBUG_andy
    25  VBoxGINA_DEFS   += LOG_ENABLED
    26 endif
    2724VBoxGINA_SOURCES  = \
    2825        VBoxGINA.cpp \
     
    3532        $(VBOX_LIB_VBGL_R3)
    3633
     34# Include testcase(s).
     35include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
     36
    3737include $(KBUILD_PATH)/subfooter.kmk
    3838
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.cpp

    r38646 r40214  
    33 * VBoxGINA -- Windows Logon DLL for VirtualBox
    44 *
    5  * Copyright (C) 2006-2011 Oracle Corporation
     5 * Copyright (C) 2006-2012 Oracle Corporation
    66 *
    77 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717#include <stdlib.h>
    1818#include <windows.h>
     19
     20#include <iprt/buildconfig.h>
     21#include <iprt/initterm.h>
     22
     23#include <VBox/VBoxGuestLib.h>
     24
    1925#include "winwlx.h"
    2026#include "VBoxGINA.h"
    2127#include "Helper.h"
    2228#include "Dialog.h"
    23 #include <VBox/VBoxGuestLib.h>
    2429
    2530/*
     
    7883        case DLL_PROCESS_ATTACH:
    7984        {
    80             RTR3InitDll(0);
     85            RTR3InitDll(0 /* Flags */);
    8186            VbglR3Init();
    82             LogRel(("VBoxGINA: DLL loaded.\n"));
     87
     88            VBoxGINALoadConfiguration();
     89
     90            VBoxGINAVerbose(0, "VBoxGINA: v%s r%s (%s %s) loaded\n",
     91                            RTBldCfgVersion(), RTBldCfgRevisionStr(),
     92                            __DATE__, __TIME__);
    8393
    8494            DisableThreadLibraryCalls(hInstance);
     
    8999        case DLL_PROCESS_DETACH:
    90100        {
    91             LogRel(("VBoxGINA: DLL unloaded.\n"));
     101            VBoxGINAVerbose(0, "VBoxGINA: Unloaded\n");
    92102            VbglR3Term();
    93103            /// @todo RTR3Term();
     
    107117    HINSTANCE hDll;
    108118
    109 #ifdef DEBUG_andy
    110     /* Enable full log output. */
    111     RTLogGroupSettings(0, "+autologon.e.l.f.l2.l3");
    112 #endif
    113 
    114     Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion));
     119    VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion);
    115120
    116121    /* Load the standard Microsoft GINA DLL. */
    117122    if (!(hDll = LoadLibrary(TEXT("MSGINA.DLL"))))
    118123    {
    119         Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! Last error=%ld\n", GetLastError()));
     124        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed loading MSGINA! Last error=%ld\n", GetLastError());
    120125        return FALSE;
    121126    }
     
    127132    if (!GWlxNegotiate)
    128133    {
    129         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
     134        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n");
    130135        return FALSE;
    131136    }
     
    133138    if (!GWlxInitialize)
    134139    {
    135         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
     140        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n");
    136141        return FALSE;
    137142    }
     
    140145    if (!GWlxDisplaySASNotice)
    141146    {
    142         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
     147        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n");
    143148        return FALSE;
    144149    }
     
    147152    if (!GWlxLoggedOutSAS)
    148153    {
    149         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
     154        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n");
    150155        return FALSE;
    151156    }
     
    154159    if (!GWlxActivateUserShell)
    155160    {
    156         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
     161        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n");
    157162        return FALSE;
    158163    }
     
    161166    if (!GWlxLoggedOnSAS)
    162167    {
    163         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
     168        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n");
    164169        return FALSE;
    165170    }
     
    168173    if (!GWlxDisplayLockedNotice)
    169174    {
    170         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
     175        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n");
    171176        return FALSE;
    172177    }
     
    174179    if (!GWlxIsLockOk)
    175180    {
    176         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
     181        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n");
    177182        return FALSE;
    178183    }
     
    181186    if (!GWlxWkstaLockedSAS)
    182187    {
    183         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
     188        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n");
    184189        return FALSE;
    185190    }
     
    187192    if (!GWlxIsLogoffOk)
    188193    {
    189         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
     194        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n");
    190195        return FALSE;
    191196    }
     
    193198    if (!GWlxLogoff)
    194199    {
    195         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
     200        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n");
    196201        return FALSE;
    197202    }
     
    199204    if (!GWlxShutdown)
    200205    {
    201         Log(("VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n"));
     206        VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n");
    202207        return FALSE;
    203208    }
     
    215220    GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)GetProcAddress(hDll, "WlxReconnectNotify");
    216221    GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)GetProcAddress(hDll, "WlxDisconnectNotify");
    217     Log(("VBoxGINA::WlxNegotiate: optional function pointers:\n"
    218              "  WlxStartApplication: %p\n"
    219              "  WlxScreenSaverNotify: %p\n"
    220              "  WlxNetworkProviderLoad: %p\n"
    221              "  WlxDisplayStatusMessage: %p\n"
    222              "  WlxGetStatusMessage: %p\n"
    223              "  WlxRemoveStatusMessage: %p\n"
    224              "  WlxGetConsoleSwitchCredentials: %p\n"
    225              "  WlxReconnectNotify: %p\n"
    226              "  WlxDisconnectNotify: %p\n",
    227              GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
    228              GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
    229              GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify));
     222    VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: optional function pointers:\n"
     223                    "  WlxStartApplication: %p\n"
     224                    "  WlxScreenSaverNotify: %p\n"
     225                    "  WlxNetworkProviderLoad: %p\n"
     226                    "  WlxDisplayStatusMessage: %p\n"
     227                    "  WlxGetStatusMessage: %p\n"
     228                    "  WlxRemoveStatusMessage: %p\n"
     229                    "  WlxGetConsoleSwitchCredentials: %p\n"
     230                    "  WlxReconnectNotify: %p\n"
     231                    "  WlxDisconnectNotify: %p\n",
     232                    GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
     233                    GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
     234                    GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify);
    230235
    231236    wlxVersion = dwWinlogonVersion;
     
    242247                          PVOID pWinlogonFunctions, PVOID *pWlxContext)
    243248{
    244     Log(("VBoxGINA::WlxInitialize\n"));
     249    VBoxGINAVerbose(0, "VBoxGINA::WlxInitialize\n");
    245250
    246251    /* Store Winlogon function table */
     
    250255    hGinaWlx = hWlx;
    251256
     257    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Init);
     258
    252259    /* Hook the dialogs */
    253260    hookDialogBoxes(pWlxFuncs, wlxVersion);
     
    260267VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
    261268{
    262     Log(("VBoxGINA::WlxDisplaySASNotice\n"));
     269    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice\n");
    263270
    264271    /* Check if there are credentials for us, if so simulate C-A-D */
    265     if (credentialsAvailable())
    266     {
    267         Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
     272    int rc = VbglR3CredentialsQueryAvailability();
     273    if (RT_SUCCESS(rc))
     274    {
     275        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n");
    268276        /* Wutomatic C-A-D */
    269277        pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
     
    271279    else
    272280    {
    273         Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
     281        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n");
    274282        /* start the credentials poller thread */
    275         credentialsPollerCreate();
     283        VBoxGINACredentialsPollerCreate();
    276284        /* Forward call to MSGINA. */
    277285        GWlxDisplaySASNotice(pWlxContext);
     
    284292                           PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
    285293{
    286     Log(("VBoxGINA::WlxLoggedOutSAS\n"));
     294    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOutSAS\n");
    287295
    288296    /* When performing a direct logon without C-A-D, our poller might not be running */
    289     if (!credentialsAvailable())
    290         credentialsPollerCreate();
     297    int rc = VbglR3CredentialsQueryAvailability();
     298    if (RT_FAILURE(rc))
     299        VBoxGINACredentialsPollerCreate();
    291300
    292301    int iRet;
     
    310319
    311320
     321/**
     322 * WinLogon calls this function following a successful logon to request that the GINA activate the user's shell program.
     323 */
    312324BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
    313325                                 PWSTR pszMprLogonScript, PVOID pEnvironment)
    314326{
    315     Log(("VBoxGINA::WlxActivateUserShell\n"));
     327    VBoxGINAVerbose(0, "VBoxGINA::WlxActivateUserShell\n");
     328
     329    /*
     330     * Report status "terminated" to the host -- this means that a user
     331     * got logged in (either manually or automatically using the provided credentials).
     332     */
     333    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
    316334
    317335    /* Forward call to MSGINA. */
     
    322340int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
    323341{
    324     Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
     342    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: dwSasType=%ld\n", dwSasType);
    325343
    326344    /*
     
    331349
    332350    /* Forward call to MSGINA. */
    333     Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
     351    VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n");
    334352    return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
    335353}
     
    337355VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
    338356{
    339     Log(("VBoxGINA::WlxDisplayLockedNotice\n"));
     357    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice\n");
    340358
    341359    /* Check if there are credentials for us, if so simulate C-A-D */
    342     if (credentialsAvailable())
    343     {
    344         Log(("VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n"));
     360    int rc = VbglR3CredentialsQueryAvailability();
     361    if (RT_SUCCESS(rc))
     362    {
     363        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n");
    345364        /* Automatic C-A-D */
    346365        pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
     
    348367    else
    349368    {
    350         Log(("VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n"));
     369        VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n");
    351370        /* start the credentials poller thread */
    352         credentialsPollerCreate();
     371        VBoxGINACredentialsPollerCreate();
    353372        /* Forward call to MSGINA. */
    354373        GWlxDisplayLockedNotice(pWlxContext);
     
    357376
    358377
     378/*
     379 * Winlogon calls this function before it attempts to lock the workstation.
     380 */
    359381BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
    360382{
    361     Log(("VBoxGINA::WlxIsLockOk\n"));
     383    VBoxGINAVerbose(0, "VBoxGINA::WlxIsLockOk\n");
    362384    /* Forward call to MSGINA. */
    363385    return GWlxIsLockOk(pWlxContext);
    364386}
    365387
     388
    366389int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
    367390{
    368     Log(("VBoxGINA::WlxWkstaLockedSAS\n"));
     391    VBoxGINAVerbose(0, "VBoxGINA::WlxWkstaLockedSAS, dwSasType=%ld\n", dwSasType);
    369392
    370393    /* When performing a direct logon without C-A-D, our poller might not be running */
    371     if (!credentialsAvailable())
    372         credentialsPollerCreate();
     394    int rc = VbglR3CredentialsQueryAvailability();
     395    if (RT_FAILURE(rc))
     396        VBoxGINACredentialsPollerCreate();
    373397
    374398    /* Forward call to MSGINA. */
     
    376400}
    377401
     402
    378403BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
    379404{
    380     Log(("VBoxGINA::WlxIsLogoffOk\n"));
    381 
    382     BOOL bSuccess = GWlxIsLogoffOk(pWlxContext);
    383     if (bSuccess)
    384     {
    385         //
    386         // if it's ok to logoff, finish with the stored credentials
    387         // and scrub the buffers
    388         //
    389         credentialsReset();
    390 
    391     }
    392     return bSuccess;
    393 }
    394 
    395 
     405    VBoxGINAVerbose(0, "VBoxGINA::WlxIsLogoffOk\n");
     406
     407    return GWlxIsLogoffOk(pWlxContext);
     408}
     409
     410
     411/*
     412 * Winlogon calls this function to notify the GINA of a logoff operation on this
     413 * workstation. This allows the GINA to perform any logoff operations that may be required.
     414 */
    396415VOID WINAPI WlxLogoff(PVOID pWlxContext)
    397416{
    398     Log(("VBoxGINA::WlxLogoff\n"));
     417    VBoxGINAVerbose(0, "VBoxGINA::WlxLogoff\n");
     418
     419    /* No need to report the "active" status to the host here -- this will be done
     420     * when VBoxGINA gets the chance to hook the dialogs (again). */
    399421
    400422    /* Forward call to MSGINA. */
     
    403425
    404426
     427/*
     428 * Winlogon calls this function just before shutting down.
     429 * This allows the GINA to perform any necessary shutdown tasks.
     430 * Will be called *after* WlxLogoff!
     431 */
    405432VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
    406433{
    407     Log(("VBoxGINA::WlxShutdown\n"));
     434    VBoxGINAVerbose(0, "VBoxGINA::WlxShutdown\n");
     435
     436    /*
     437     * Report status "inactive" to the host -- this means the
     438     * auto-logon feature won't be active anymore at this point
     439     * (until it maybe gets loaded again after a reboot).
     440     */
     441    VBoxGINAReportStatus(VBoxGuestFacilityStatus_Inactive);
    408442
    409443    /* Forward call to MSGINA. */
     
    417451BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
    418452{
    419     Log(("VBoxGINA::WlxScreenSaverNotify\n"));
     453    VBoxGINAVerbose(0, "VBoxGINA::WlxScreenSaverNotify\n");
    420454
    421455    /* Forward to MSGINA if present. */
     
    431465                                PVOID pEnvironment, PWSTR pszCmdLine)
    432466{
    433     Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
    434          pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
     467    VBoxGINAVerbose(0, "VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
     468                    pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
    435469
    436470    /* Forward to MSGINA if present. */
     
    446480BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
    447481{
    448     Log(("VBoxGINA::WlxNetworkProviderLoad\n"));
     482    VBoxGINAVerbose(0, "VBoxGINA::WlxNetworkProviderLoad\n");
    449483
    450484    /* Forward to MSGINA if present. */
     
    458492                                    PWSTR pTitle, PWSTR pMessage)
    459493{
    460     Log(("VBoxGINA::WlxDisplayStatusMessage\n"));
     494    VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayStatusMessage\n");
    461495
    462496    /* Forward to MSGINA if present. */
     
    470504                                PWSTR pMessage, DWORD dwBufferSize)
    471505{
    472     Log(("VBoxGINA::WlxGetStatusMessage\n"));
     506    VBoxGINAVerbose(0, "VBoxGINA::WlxGetStatusMessage\n");
    473507
    474508    /* Forward to MSGINA if present. */
     
    481515BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
    482516{
    483     Log(("VBoxGINA::WlxRemoveStatusMessage\n"));
     517    VBoxGINAVerbose(0, "VBoxGINA::WlxRemoveStatusMessage\n");
    484518
    485519    /* Forward to MSGINA if present. */
     
    495529BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
    496530{
    497     Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
     531    VBoxGINAVerbose(0, "VBoxGINA::WlxGetConsoleSwitchCredentials\n");
    498532
    499533    /* Forward call to MSGINA if present */
     
    506540VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
    507541{
    508     Log(("VBoxGINA::WlxReconnectNotify\n"));
     542    VBoxGINAVerbose(0, "VBoxGINA::WlxReconnectNotify\n");
    509543
    510544    /* Forward to MSGINA if present. */
     
    516550VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
    517551{
    518     Log(("VBoxGINA::WlxDisconnectNotify\n"));
     552    VBoxGINAVerbose(0, "VBoxGINA::WlxDisconnectNotify\n");
    519553
    520554    /* Forward to MSGINA if present. */
     
    523557}
    524558
     559
     560DWORD WINAPI VBoxGINADebug(void)
     561{
     562#ifdef DEBUG
     563    DWORD dwVersion;
     564    BOOL fRes = WlxNegotiate(WLX_VERSION_1_4, &dwVersion);
     565    if (!fRes)
     566        return 1;
     567
     568    void* pWlxContext = NULL;
     569    WLX_DISPATCH_VERSION_1_4 wlxDispatch;
     570    ZeroMemory(&wlxDispatch, sizeof(WLX_DISPATCH_VERSION_1_4));
     571
     572    fRes = WlxInitialize(0, 0,
     573                         NULL /* Reserved */,
     574                         NULL /* Winlogon functions */,
     575                         &pWlxContext);
     576    if (!fRes)
     577        return 2;
     578
     579    WlxDisplaySASNotice(pWlxContext);
     580
     581    char szSID[MAX_PATH];
     582    LUID luidAuth;
     583    DWORD dwOpts;
     584    WLX_MPR_NOTIFY_INFO wlxNotifyInfo;
     585    void* pvProfile;
     586    HANDLE hToken;
     587    int iRes = WlxLoggedOutSAS(pWlxContext, WLX_SAS_TYPE_CTRL_ALT_DEL,
     588                               &luidAuth, szSID,
     589                               &dwOpts, &hToken, &wlxNotifyInfo, &pvProfile);
     590    return iRes;
     591#else
     592    return 0;
     593#endif
     594}
     595
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.def

    r28800 r40214  
    33; * VBoxGINA -- Windows Logon DLL for VirtualBox
    44; *
    5 ; Copyright (C) 2006-2007 Oracle Corporation
     5; Copyright (C) 2006-2012 Oracle Corporation
    66;
    77; This file is part of VirtualBox Open Source Edition (OSE), as
     
    4242        WlxReconnectNotify
    4343        WlxDisconnectNotify
     44    ; Debug
     45    VBoxGINADebug
  • trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.h

    r38310 r40214  
    44
    55/*
    6  * Copyright (C) 2006-2011 Oracle Corporation
     6 * Copyright (C) 2006-2012 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1515 */
    1616
    17 #ifndef ___H_VBOXGINA
    18 #define ___H_VBOXGINA
    19 
    20 #include <iprt/initterm.h>
    21 
    22 #define LOG_GROUP LOG_GROUP_AUTOLOGON
    23 #include <VBox/log.h>
     17#ifndef __VBOXGINA_H__
     18#define __VBOXGINA_H__
    2419
    2520/** Handle to Winlogon service */
     
    5954/** @}  */
    6055
    61 #endif /* !___H_VBOXGINA */
     56#endif /* !__VBOXGINA_H__ */
    6257
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette