Index: /trunk/src/VBox/Devices/Input/UsbMouse.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/UsbMouse.cpp	(revision 46729)
+++ /trunk/src/VBox/Devices/Input/UsbMouse.cpp	(revision 46730)
@@ -120,6 +120,6 @@
 typedef struct USBHID
 {
-    /** Pointer back to the PDM USB Device instance structure. */
-    PPDMUSBINS          pUsbIns;
+    /** USB device instance number. */
+    uint32_t            iInstance;
     /** Critical section protecting the device state. */
     RTCRITSECT          CritSect;
@@ -634,5 +634,5 @@
 static int usbHidCompleteStall(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb, const char *pszWhy)
 {
-    Log(("usbHidCompleteStall/#%u: pUrb=%p:%s: %s\n", pThis->pUsbIns->iInstance, pUrb, pUrb->pszDesc, pszWhy));
+    Log(("usbHidCompleteStall/#%u: pUrb=%p:%s: %s\n", pThis->iInstance, pUrb, pUrb->pszDesc, pszWhy));
 
     pUrb->enmStatus = VUSBSTATUS_STALL;
@@ -657,5 +657,5 @@
 static int usbHidCompleteOk(PUSBHID pThis, PVUSBURB pUrb, size_t cbData)
 {
-    Log(("usbHidCompleteOk/#%u: pUrb=%p:%s cbData=%#zx\n", pThis->pUsbIns->iInstance, pUrb, pUrb->pszDesc, cbData));
+    Log(("usbHidCompleteOk/#%u: pUrb=%p:%s cbData=%#zx\n", pThis->iInstance, pUrb, pUrb->pszDesc, cbData));
 
     pUrb->enmStatus = VUSBSTATUS_OK;
@@ -859,12 +859,7 @@
 }
 
-/**
- * @copydoc PDMUSBREG::pfnUrbReap
- */
-static DECLCALLBACK(PVUSBURB) usbHidUrbReap(PPDMUSBINS pUsbIns, RTMSINTERVAL cMillies)
-{
-    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidUrbReap/#%u: cMillies=%u\n", pUsbIns->iInstance, cMillies));
-
+
+static PVUSBURB usbHidUrbReapCore(PUSBHID pThis, RTMSINTERVAL cMillies)
+{
     RTCritSectEnter(&pThis->CritSect);
 
@@ -887,5 +882,5 @@
 
     if (pUrb)
-        Log(("usbHidUrbReap/#%u: pUrb=%p:%s\n", pUsbIns->iInstance, pUrb, pUrb->pszDesc));
+        Log(("usbHidUrbReap/#%u: pUrb=%p:%s\n", pThis->iInstance, pUrb, pUrb->pszDesc));
     return pUrb;
 }
@@ -893,10 +888,17 @@
 
 /**
- * @copydoc PDMUSBREG::pfnUrbCancel
- */
-static DECLCALLBACK(int) usbHidUrbCancel(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
+ * @copydoc PDMUSBREG::pfnUrbReap
+ */
+static DECLCALLBACK(PVUSBURB) usbHidUrbReap(PPDMUSBINS pUsbIns,
+                                            RTMSINTERVAL cMillies)
 {
     PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidUrbCancel/#%u: pUrb=%p:%s\n", pUsbIns->iInstance, pUrb, pUrb->pszDesc));
+    LogFlow(("usbHidUrbReap/#%u: cMillies=%u\n", pThis->iInstance, cMillies));
+    return usbHidUrbReapCore(pThis, cMillies);
+}
+
+
+static int usbHidUrbCancelCore(PUSBHID pThis, PVUSBURB pUrb)
+{
     RTCritSectEnter(&pThis->CritSect);
 
@@ -911,4 +913,15 @@
 }
 
+
+/**
+ * @copydoc PDMUSBREG::pfnUrbCancel
+ */
+static DECLCALLBACK(int) usbHidUrbCancel(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
+{
+    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
+    LogFlow(("usbHidUrbCancel/#%u: pUrb=%p:%s\n", pThis->iInstance, pUrb,
+             pUrb->pszDesc));
+    return usbHidUrbCancelCore(pThis, pUrb);
+}
 
 /**
@@ -1149,11 +1162,6 @@
 
 
-/**
- * @copydoc PDMUSBREG::pfnUrbQueue
- */
-static DECLCALLBACK(int) usbHidQueue(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
-{
-    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidQueue/#%u: pUrb=%p:%s EndPt=%#x\n", pUsbIns->iInstance, pUrb, pUrb->pszDesc, pUrb->EndPt));
+static int usbHidQueueCore(PUSBHID pThis, PVUSBURB pUrb)
+{
     RTCritSectEnter(&pThis->CritSect);
 
@@ -1186,11 +1194,17 @@
 
 /**
- * @copydoc PDMUSBREG::pfnUsbClearHaltedEndpoint
- */
-static DECLCALLBACK(int) usbHidUsbClearHaltedEndpoint(PPDMUSBINS pUsbIns, unsigned uEndpoint)
+ * @copydoc PDMUSBREG::pfnUrbQueue
+ */
+static DECLCALLBACK(int) usbHidQueue(PPDMUSBINS pUsbIns, PVUSBURB pUrb)
 {
     PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidUsbClearHaltedEndpoint/#%u: uEndpoint=%#x\n", pUsbIns->iInstance, uEndpoint));
-
+    LogFlow(("usbHidQueue/#%u: pUrb=%p:%s EndPt=%#x\n", pUsbIns->iInstance,
+             pUrb, pUrb->pszDesc, pUrb->EndPt));
+    return usbHidQueueCore(pThis, pUrb);
+}
+
+
+static int usbHidUsbClearHaltedEndpointCore(PUSBHID pThis, unsigned uEndpoint)
+{
     if ((uEndpoint & ~0x80) < RT_ELEMENTS(pThis->aEps))
     {
@@ -1205,9 +1219,25 @@
 
 /**
+ * @copydoc PDMUSBREG::pfnUsbClearHaltedEndpoint
+ */
+static DECLCALLBACK(int) usbHidUsbClearHaltedEndpoint(PPDMUSBINS pUsbIns,
+                                                      unsigned uEndpoint)
+{
+    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
+    LogFlow(("usbHidUsbClearHaltedEndpoint/#%u: uEndpoint=%#x\n",
+             pUsbIns->iInstance, uEndpoint));
+    return usbHidUsbClearHaltedEndpointCore(pThis, uEndpoint);
+}
+
+
+/**
  * @copydoc PDMUSBREG::pfnUsbSetInterface
  */
-static DECLCALLBACK(int) usbHidUsbSetInterface(PPDMUSBINS pUsbIns, uint8_t bInterfaceNumber, uint8_t bAlternateSetting)
-{
-    LogFlow(("usbHidUsbSetInterface/#%u: bInterfaceNumber=%u bAlternateSetting=%u\n", pUsbIns->iInstance, bInterfaceNumber, bAlternateSetting));
+static DECLCALLBACK(int) usbHidUsbSetInterface(PPDMUSBINS pUsbIns,
+                                               uint8_t bInterfaceNumber,
+                                               uint8_t bAlternateSetting)
+{
+    LogFlow(("usbHidUsbSetInterface/#%u: bInterfaceNumber=%u bAlternateSetting=%u\n",
+             pUsbIns->iInstance, bInterfaceNumber, bAlternateSetting));
     Assert(bAlternateSetting == 0);
     return VINF_SUCCESS;
@@ -1215,12 +1245,10 @@
 
 
-/**
- * @copydoc PDMUSBREG::pfnUsbSetConfiguration
- */
-static DECLCALLBACK(int) usbHidUsbSetConfiguration(PPDMUSBINS pUsbIns, uint8_t bConfigurationValue,
-                                                   const void *pvOldCfgDesc, const void *pvOldIfState, const void *pvNewCfgDesc)
-{
-    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidUsbSetConfiguration/#%u: bConfigurationValue=%u\n", pUsbIns->iInstance, bConfigurationValue));
+static int usbHidUsbSetConfigurationCore(PUSBHID pThis,
+                                         uint8_t bConfigurationValue,
+                                         const void *pvOldCfgDesc,
+                                         const void *pvOldIfState,
+                                         const void *pvNewCfgDesc)
+{
     Assert(bConfigurationValue == 1);
     RTCritSectEnter(&pThis->CritSect);
@@ -1230,5 +1258,6 @@
      */
     if (pThis->bConfigurationValue == bConfigurationValue)
-        usbHidResetWorker(pThis, NULL, true /*fSetConfig*/); /** @todo figure out the exact difference */
+        usbHidResetWorker(pThis, NULL, true /*fSetConfig*/);
+        /** @todo figure out the exact difference */
     pThis->bConfigurationValue = bConfigurationValue;
 
@@ -1245,10 +1274,26 @@
 
 /**
+ * @copydoc PDMUSBREG::pfnUsbSetConfiguration
+ */
+static DECLCALLBACK(int) usbHidUsbSetConfiguration(PPDMUSBINS pUsbIns,
+                                                   uint8_t bConfigurationValue,
+                                                   const void *pvOldCfgDesc,
+                                                   const void *pvOldIfState,
+                                                   const void *pvNewCfgDesc)
+{
+    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
+    LogFlow(("usbHidUsbSetConfiguration/#%u: bConfigurationValue=%u\n",
+             pUsbIns->iInstance, bConfigurationValue));
+    return usbHidUsbSetConfigurationCore(pThis, bConfigurationValue,
+                                         pvOldCfgDesc, pvOldIfState,
+                                         pvNewCfgDesc);
+}
+
+
+/**
  * @copydoc PDMUSBREG::pfnUsbGetDescriptorCache
  */
-static DECLCALLBACK(PCPDMUSBDESCCACHE) usbHidUsbGetDescriptorCache(PPDMUSBINS pUsbIns)
-{
-    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidUsbGetDescriptorCache/#%u:\n", pUsbIns->iInstance));
+static PCPDMUSBDESCCACHE usbHidUsbGetDescriptorCacheCore(PUSBHID pThis)
+{
     if (pThis->isAbsolute) {
         return &g_UsbHidTDescCache;
@@ -1260,4 +1305,27 @@
 
 /**
+ * @copydoc PDMUSBREG::pfnUsbGetDescriptorCache
+ */
+static DECLCALLBACK(PCPDMUSBDESCCACHE) usbHidUsbGetDescriptorCache(PPDMUSBINS
+                                                                        pUsbIns)
+{
+    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
+    LogFlow(("usbHidUsbGetDescriptorCache/#%u:\n", pUsbIns->iInstance));
+    return usbHidUsbGetDescriptorCacheCore(pThis);
+}
+
+
+static DECLCALLBACK(int) usbHidUsbResetCore(PUSBHID pThis)
+{
+    RTCritSectEnter(&pThis->CritSect);
+
+    int rc = usbHidResetWorker(pThis, NULL, false /*fSetConfig*/);
+
+    RTCritSectLeave(&pThis->CritSect);
+    return rc;
+}
+
+
+/**
  * @copydoc PDMUSBREG::pfnUsbReset
  */
@@ -1266,21 +1334,10 @@
     PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
     LogFlow(("usbHidUsbReset/#%u:\n", pUsbIns->iInstance));
-    RTCritSectEnter(&pThis->CritSect);
-
-    int rc = usbHidResetWorker(pThis, NULL, false /*fSetConfig*/);
-
-    RTCritSectLeave(&pThis->CritSect);
-    return rc;
-}
-
-
-/**
- * @copydoc PDMUSBREG::pfnDestruct
- */
-static void usbHidDestruct(PPDMUSBINS pUsbIns)
-{
-    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    LogFlow(("usbHidDestruct/#%u:\n", pUsbIns->iInstance));
-
+    return usbHidUsbResetCore(pThis);
+}
+
+
+static void usbHidDestructCore(PUSBHID pThis)
+{
     if (RTCritSectIsInitialized(&pThis->CritSect))
     {
@@ -1299,16 +1356,22 @@
 
 /**
- * @copydoc PDMUSBREG::pfnConstruct
- */
-static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance, PCFGMNODE pCfg, PCFGMNODE pCfgGlobal)
+ * @copydoc PDMUSBREG::pfnDestruct
+ */
+static DECLCALLBACK(void) usbHidDestruct(PPDMUSBINS pUsbIns)
 {
     PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
-    Log(("usbHidConstruct/#%u:\n", iInstance));
-
+    LogFlow(("usbHidDestruct/#%u:\n", pUsbIns->iInstance));
+    usbHidDestructCore(pThis);
+}
+
+
+static int usbHidConstructCore(PUSBHID pThis, int iInstance, bool isAbsolute,
+                               uint8_t u8CoordShift)
+{
     /*
      * Perform the basic structure initialization first so the destructor
      * will not misbehave.
      */
-    pThis->pUsbIns                                  = pUsbIns;
+    pThis->iInstance                                = iInstance;
     pThis->hEvtDoneQueue                            = NIL_RTSEMEVENT;
     usbHidQueueInit(&pThis->ToHostQueue);
@@ -1321,32 +1384,67 @@
     AssertRCReturn(rc, rc);
 
+    pThis->isAbsolute = isAbsolute;
+    pThis->u8CoordShift = u8CoordShift;
+
+    pThis->Lun0.IBase.pfnQueryInterface = usbHidMouseQueryInterface;
+    pThis->Lun0.IPort.pfnPutEvent       = usbHidMousePutEvent;
+    pThis->Lun0.IPort.pfnPutEventAbs    = usbHidMousePutEventAbs;
+
+    return VINF_SUCCESS;
+}
+
+
+static void usbHidConstructFinish(PUSBHID pThis, PPDMIMOUSECONNECTOR pDrv)
+{
+    pThis->Lun0.pDrv = pDrv;
+}
+
+
+/**
+ * @copydoc PDMUSBREG::pfnConstruct
+ */
+static DECLCALLBACK(int) usbHidConstruct(PPDMUSBINS pUsbIns, int iInstance,
+                                         PCFGMNODE pCfg, PCFGMNODE pCfgGlobal)
+{
+    PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID);
+    bool isAbsolute;
+    uint8_t u8CoordShift;
+    PPDMIMOUSECONNECTOR pDrv;
+    Log(("usbHidConstruct/#%u:\n", iInstance));
+
     /*
      * Validate and read the configuration.
      */
-    rc = CFGMR3ValidateConfig(pCfg, "/", "Absolute|CoordShift", "Config", "UsbHid", iInstance);
+    int rc = CFGMR3ValidateConfig(pCfg, "/", "Absolute|CoordShift", "Config",
+                                  "UsbHid", iInstance);
     if (RT_FAILURE(rc))
         return rc;
-    rc = CFGMR3QueryBoolDef(pCfg, "Absolute", &pThis->isAbsolute, false);
+    rc = CFGMR3QueryBoolDef(pCfg, "Absolute", &isAbsolute, false);
     if (RT_FAILURE(rc))
-        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to query settings"));
-
-    pThis->Lun0.IBase.pfnQueryInterface = usbHidMouseQueryInterface;
-    pThis->Lun0.IPort.pfnPutEvent       = usbHidMousePutEvent;
-    pThis->Lun0.IPort.pfnPutEventAbs    = usbHidMousePutEventAbs;
+        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS,
+                                   N_("HID failed to query settings"));
+
+    rc = CFGMR3QueryU8Def(pCfg, "CoordShift", &u8CoordShift, 1);
+    if (RT_FAILURE(rc))
+        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS,
+                                   N_("HID failed to query shift factor"));
+
+    rc = usbHidConstructCore(pThis, iInstance, isAbsolute, u8CoordShift);
 
     /*
      * Attach the mouse driver.
      */
-    rc = PDMUsbHlpDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase, &pThis->Lun0.pDrvBase, "Mouse Port");
+    rc = PDMUsbHlpDriverAttach(pUsbIns, 0 /*iLun*/, &pThis->Lun0.IBase,
+                               &pThis->Lun0.pDrvBase, "Mouse Port");
     if (RT_FAILURE(rc))
-        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to attach mouse driver"));
-
-    pThis->Lun0.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pDrvBase, PDMIMOUSECONNECTOR);
-    if (!pThis->Lun0.pDrv)
-        return PDMUsbHlpVMSetError(pUsbIns, VERR_PDM_MISSING_INTERFACE, RT_SRC_POS, N_("HID failed to query mouse interface"));
-
-    rc = CFGMR3QueryU8Def(pCfg, "CoordShift", &pThis->u8CoordShift, 1);
-    if (RT_FAILURE(rc))
-        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to query shift factor"));
+        return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS,
+                                   N_("HID failed to attach mouse driver"));
+
+    pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pDrvBase, PDMIMOUSECONNECTOR);
+    if (!pDrv)
+        return PDMUsbHlpVMSetError(pUsbIns, VERR_PDM_MISSING_INTERFACE,
+                                   RT_SRC_POS,
+                                   N_("HID failed to query mouse interface"));
+    usbHidConstructFinish(pThis, pDrv);
 
     return VINF_SUCCESS;
