VirtualBox

Ignore:
Timestamp:
Sep 12, 2011 1:21:04 PM (13 years ago)
Author:
vboxsync
Message:

VBoxUsbLib-win.cpp: Drop the scary exit(0) bits, fixed a copy&past hwnd bug, and made sure the init thread gets signalled on class registration failure. Used common sense and corrected the driver version check. Cleanups.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp

    r38714 r38715  
    11/* $Id$ */
    22/** @file
    3  * VBox USB R3 Driver Interface library
     3 * VBox USB ring-3 Driver Interface library, Windows.
    44 */
     5
    56/*
    67 * Copyright (C) 2011 Oracle Corporation
     
    1415 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1516 */
     17
     18/*******************************************************************************
     19*   Header Files                                                               *
     20*******************************************************************************/
    1621#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
    1722#include <windows.h>
     
    4348#endif
    4449
    45 typedef struct _USB_INTERFACE_DESCRIPTOR2 {
     50/*******************************************************************************
     51*   Structures and Typedefs                                                    *
     52*******************************************************************************/
     53typedef struct _USB_INTERFACE_DESCRIPTOR2
     54{
    4655    UCHAR  bLength;
    4756    UCHAR  bDescriptorType;
     
    6978} VBOXUSBGLOBALSTATE, *PVBOXUSBGLOBALSTATE;
    7079
    71 static VBOXUSBGLOBALSTATE g_VBoxUsbGlobal;
    72 
    7380typedef struct VBOXUSB_STRING_DR_ENTRY
    7481{
     
    7986} VBOXUSB_STRING_DR_ENTRY, *PVBOXUSB_STRING_DR_ENTRY;
    8087
    81 /* this represents VBoxUsb device instance */
     88/**
     89 * This represents VBoxUsb device instance
     90 */
    8291typedef struct VBOXUSB_DEV
    8392{
    8493    struct VBOXUSB_DEV *pNext;
    85     char    szName[512];
    86     char    szDriverRegName[512];
     94    char                szName[512];
     95    char                szDriverRegName[512];
    8796} VBOXUSB_DEV, *PVBOXUSB_DEV;
     97
     98
     99/*******************************************************************************
     100*   Global Variables                                                           *
     101*******************************************************************************/
     102static VBOXUSBGLOBALSTATE g_VBoxUsbGlobal;
     103
    88104
    89105int usbLibVuDeviceValidate(PVBOXUSB_DEV pVuDev)
     
    11621178#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
    11631179
    1164 static VOID CALLBACK usbLibTimerCallback(
    1165         __in  PVOID lpParameter,
    1166         __in  BOOLEAN TimerOrWaitFired
    1167       )
     1180static VOID CALLBACK usbLibTimerCallback(__in PVOID lpParameter, __in BOOLEAN TimerOrWaitFired)
    11681181{
    11691182    SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
     
    12271240}
    12281241
     1242/** @todo r=bird: Use an IPRT thread? */
    12291243static DWORD WINAPI usbLibMsgThreadProc(__in LPVOID lpParameter)
    12301244{
    12311245    static LPCSTR   s_szVBoxUsbWndClassName = "VBoxUsbLibClass";
    1232      HWND           hwnd      = 0;
    1233      HINSTANCE      hInstance = (HINSTANCE)GetModuleHandle(NULL);
    1234      bool           bExit     = false;
    1235 
    1236      /* Register the Window Class. */
    1237      WNDCLASS wc;
    1238      wc.style         = 0;
    1239      wc.lpfnWndProc   = usbLibWndProc;
    1240      wc.cbClsExtra    = 0;
    1241      wc.cbWndExtra    = sizeof(void *);
    1242      wc.hInstance     = hInstance;
    1243      wc.hIcon         = NULL;
    1244      wc.hCursor       = NULL;
    1245      wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    1246      wc.lpszMenuName  = NULL;
    1247      wc.lpszClassName = s_szVBoxUsbWndClassName;
    1248 
    1249      ATOM atomWindowClass = RegisterClass(&wc);
    1250 
    1251      if (atomWindowClass != 0)
    1252      {
    1253          /* Create the window. */
    1254          g_VBoxUsbGlobal.hWnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
    1255                                                s_szVBoxUsbWndClassName, s_szVBoxUsbWndClassName,
    1256                                                WS_POPUPWINDOW,
    1257                                                -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
    1258          SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
    1259 
    1260          if (g_VBoxUsbGlobal.hWnd)
    1261          {
    1262              SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
    1263                           SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
    1264 
    1265              MSG msg;
    1266              while (GetMessage(&msg, NULL, 0, 0))
    1267              {
    1268                  TranslateMessage(&msg);
    1269                  DispatchMessage(&msg);
    1270              }
    1271 
    1272              DestroyWindow(hwnd);
    1273 
    1274              bExit = true;
    1275          }
    1276 
    1277          UnregisterClass(s_szVBoxUsbWndClassName, hInstance);
    1278      }
    1279 
    1280      /** @todo r=bird: Please explain why the USB library needs
    1281       *        this exit(0) hack! */
    1282      if (bExit)
    1283      {
    1284          /* no need any accuracy here, in anyway the DHCP server usually gets terminated with TerminateProcess */
    1285          exit(0);
    1286      }
    1287 
    1288      return 0;
    1289 }
    1290 #endif
     1246    const HINSTANCE hInstance               = (HINSTANCE)GetModuleHandle(NULL);
     1247
     1248    Assert(g_VBoxUsbGlobal.hWnd == NULL);
     1249    g_VBoxUsbGlobal.hWnd = NULL;
     1250
     1251    /*
     1252     * Register the Window Class and the hitten window create.
     1253     */
     1254    WNDCLASS wc;
     1255    wc.style         = 0;
     1256    wc.lpfnWndProc   = usbLibWndProc;
     1257    wc.cbClsExtra    = 0;
     1258    wc.cbWndExtra    = sizeof(void *);
     1259    wc.hInstance     = hInstance;
     1260    wc.hIcon         = NULL;
     1261    wc.hCursor       = NULL;
     1262    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
     1263    wc.lpszMenuName  = NULL;
     1264    wc.lpszClassName = s_szVBoxUsbWndClassName;
     1265    ATOM atomWindowClass = RegisterClass(&wc);
     1266    if (atomWindowClass != 0)
     1267        g_VBoxUsbGlobal.hWnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
     1268                                              s_szVBoxUsbWndClassName, s_szVBoxUsbWndClassName,
     1269                                              WS_POPUPWINDOW,
     1270                                              -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
     1271    else
     1272        AssertMsgFailed(("RegisterClass failed, last error %u\n", GetLastError()));
     1273
     1274    /*
     1275     * Signal the creator thread.
     1276     */
     1277    ASMCompilerBarrier();
     1278    SetEvent(g_VBoxUsbGlobal.hNotifyEvent);
     1279
     1280    if (g_VBoxUsbGlobal.hWnd)
     1281    {
     1282        /* Make sure it's really hidden. */
     1283        SetWindowPos(g_VBoxUsbGlobal.hWnd, HWND_TOPMOST, -200, -200, 0, 0,
     1284                     SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
     1285
     1286        /*
     1287         * The message pump.
     1288         */
     1289        MSG msg;
     1290        while (GetMessage(&msg, NULL, 0, 0))
     1291        {
     1292            TranslateMessage(&msg);
     1293            DispatchMessage(&msg);
     1294        }
     1295
     1296        /*
     1297         * Clean up.
     1298         */
     1299        DestroyWindow(g_VBoxUsbGlobal.hWnd);
     1300    }
     1301
     1302    if (atomWindowClass != NULL)
     1303        UnregisterClass(s_szVBoxUsbWndClassName, hInstance);
     1304
     1305    return 0;
     1306}
     1307
     1308#endif /* VBOX_USB_USE_DEVICE_NOTIFICATION */
    12911309
    12921310/**
     
    13011319    Log(("usbproxy: usbLibInit\n"));
    13021320
    1303     memset(&g_VBoxUsbGlobal, 0, sizeof (g_VBoxUsbGlobal));
    1304 
     1321    RT_ZERO(g_VBoxUsbGlobal);
    13051322    g_VBoxUsbGlobal.hMonitor = INVALID_HANDLE_VALUE;
    13061323
     1324    /*
     1325     * Create the notification and interrupt event before opening the device.
     1326     */
    13071327    g_VBoxUsbGlobal.hNotifyEvent = CreateEvent(NULL,  /* LPSECURITY_ATTRIBUTES lpEventAttributes */
    13081328                                               FALSE, /* BOOL bManualReset */
     
    13211341        if (g_VBoxUsbGlobal.hInterruptEvent)
    13221342        {
    1323             g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    1324                                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
     1343            /*
     1344             * Open the USB monitor device, starting if needed.
     1345             */
     1346            g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME,
     1347                                                  GENERIC_READ | GENERIC_WRITE,
     1348                                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
     1349                                                  NULL,
     1350                                                  OPEN_EXISTING,
     1351                                                  FILE_ATTRIBUTE_SYSTEM,
     1352                                                  NULL);
    13251353
    13261354            if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
     
    13291357                if (hr == S_OK)
    13301358                {
    1331                     g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
    1332                                            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
     1359                    g_VBoxUsbGlobal.hMonitor = CreateFile(USBMON_DEVICE_NAME,
     1360                                                          GENERIC_READ | GENERIC_WRITE,
     1361                                                          FILE_SHARE_READ | FILE_SHARE_WRITE,
     1362                                                          NULL,
     1363                                                          OPEN_EXISTING,
     1364                                                          FILE_ATTRIBUTE_SYSTEM,
     1365                                                          NULL);
    13331366                    if (g_VBoxUsbGlobal.hMonitor == INVALID_HANDLE_VALUE)
    13341367                    {
     
    13421375            if (g_VBoxUsbGlobal.hMonitor != INVALID_HANDLE_VALUE)
    13431376            {
    1344                 USBSUP_VERSION Version = {0};
    1345                 DWORD cbReturned = 0;
    1346 
    1347                 if (DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_GET_VERSION, NULL, 0, &Version, sizeof (Version), &cbReturned, NULL))
     1377                /*
     1378                 * Check the USB monitor version.
     1379                 * 
     1380                 * Drivers are backwards compatible within the same major
     1381                 * number.  We consider the minor version number this library
     1382                 * is compiled with to be the minimum required by the driver.
     1383                 * This is by reasoning that the library uses the full feature
     1384                 * set of the driver it's written for.
     1385                 */
     1386                USBSUP_VERSION  Version = {0};
     1387                DWORD           cbReturned = 0;
     1388                if (DeviceIoControl(g_VBoxUsbGlobal.hMonitor, SUPUSBFLT_IOCTL_GET_VERSION,
     1389                                    NULL, 0,
     1390                                    &Version, sizeof (Version),
     1391                                    &cbReturned, NULL))
    13481392                {
    1349                     /** @todo r=bird: Explain why we accept any mismatching major
    1350                      *        version as long as the minor version is less or equal!
    1351                      *        It does not make sense to me... */
    13521393                    if (   Version.u32Major == USBMON_MAJOR_VERSION
    1353                         || Version.u32Minor <= USBMON_MINOR_VERSION)
     1394                        && Version.u32Minor >= USBMON_MINOR_VERSION)
    13541395                    {
    13551396#ifndef VBOX_USB_USE_DEVICE_NOTIFICATION
     1397                        /*
     1398                         * Tell the monitor driver which event object to use
     1399                         * for notifications.
     1400                         */
    13561401                        USBSUP_SET_NOTIFY_EVENT SetEvent = {0};
    13571402                        Assert(g_VBoxUsbGlobal.hNotifyEvent);
     
    13631408                        {
    13641409                            rc = SetEvent.u.rc;
    1365                             AssertRC(rc);
    13661410                            if (RT_SUCCESS(rc))
    13671411                            {
     
    13711415                                return VINF_SUCCESS;
    13721416                            }
    1373                             AssertMsgFailed(("SetEvent failed, rc (%d)\n", rc));
     1417
     1418                            AssertMsgFailed(("SetEvent failed, %Rrc (%d)\n", rc, rc));
    13741419                        }
    13751420                        else
     
    13801425                        }
    13811426#else
     1427                        /*
     1428                         * ??? Please explain this....
     1429                         */
    13821430                        g_VBoxUsbGlobal.hTimerQueue = CreateTimerQueue();
    13831431                        if (g_VBoxUsbGlobal.hTimerQueue)
     
    14321480                    else
    14331481                    {
    1434                         LogRel((__FUNCTION__": Monitor driver version mismatch!!\n"));
     1482                        LogRel((__FUNCTION__": USB Monitor driver version mismatch! driver=%u.%u library=%u.%u\n",
     1483                                Version.u32Major, Version.u32Minor, USBMON_MAJOR_VERSION, USBMON_MINOR_VERSION));
    14351484#ifdef VBOX_WITH_ANNOYING_USB_ASSERTIONS
    14361485                        AssertFailed();
     
    15031552#ifdef VBOX_USB_USE_DEVICE_NOTIFICATION
    15041553    bRc = PostMessage(g_VBoxUsbGlobal.hWnd, WM_QUIT, 0, 0);
    1505     if (!bRc)
    1506     {
    1507         DWORD winEr = GetLastError();
    1508         AssertMsgFailed(("PostMessage for hWnd failed winEr(%d)\n", winEr));
    1509     }
     1554    AssertMsg(bRc, ("PostMessage for hWnd failed winEr(%d)\n", GetLastError()));
    15101555
    15111556    if (g_VBoxUsbGlobal.hThread != NULL)
     
    15461591    return VINF_SUCCESS;
    15471592}
     1593
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