/**
 * Stop all service threads and free the device chain.
 */
void USBProxyBackendSolaris::uninit()
{
    LogFlowThisFunc(("destruct\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    /*
     * Terminate the USB library
     */
    if (mUSBLibInitialized)
    {
        USBLibTerm();
        mUSBLibInitialized = false;
    }

    if (mNotifyEventSem != NIL_RTSEMEVENT)
    {
        RTSemEventDestroy(mNotifyEventSem);
        mNotifyEventSem = NIL_RTSEMEVENT;
    }
}
/**
 * Initializes the object (called right after construction).
 *
 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
 */
HRESULT USBProxyServiceWindows::init(void)
{
    /*
     * Create the semaphore (considered fatal).
     */
    mhEventInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
    AssertReturn(mhEventInterrupt != INVALID_HANDLE_VALUE, E_FAIL);

    /*
     * Initialize the USB lib and stuff.
     */
    int rc = USBLibInit();
    if (RT_SUCCESS(rc))
    {
        /*
         * Start the poller thread.
         */
        rc = start();
        if (RT_SUCCESS(rc))
        {
            LogFlowThisFunc(("returns successfully\n"));
            return S_OK;
        }

        USBLibTerm();
    }

    CloseHandle(mhEventInterrupt);
    mhEventInterrupt = INVALID_HANDLE_VALUE;

    LogFlowThisFunc(("returns failure!!! (rc=%Rrc)\n", rc));
    mLastError = rc;
    return S_OK;
}
/**
 * Stop all service threads and free the device chain.
 */
USBProxyServiceWindows::~USBProxyServiceWindows()
{
    LogFlowThisFunc(("\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    if (mhEventInterrupt != INVALID_HANDLE_VALUE)
        CloseHandle(mhEventInterrupt);
    mhEventInterrupt = INVALID_HANDLE_VALUE;

    /*
     * Terminate the library...
     */
    int rc = USBLibTerm();
    AssertRC(rc);
}
Beispiel #4
0
/**
 * Stop all service threads and free the device chain.
 */
USBProxyServiceDarwin::~USBProxyServiceDarwin()
{
    LogFlowThisFunc(("\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
    /*
     * Terminate the USB library - it'll
     */
    if (mUSBLibInitialized)
    {
        USBLibTerm();
        mUSBLibInitialized = false;
    }
#endif
}
/**
 * Close the USB device.
 *
 * @param   pProxyDev   The device instance.
 */
static DECLCALLBACK(void) usbProxySolarisClose(PUSBPROXYDEV pProxyDev)
{
    LogFlow((USBPROXY ":usbProxySolarisClose: pProxyDev=%p\n", pProxyDev));

    PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);

    /* Close the device (do not re-enumerate). */
    VBOXUSBREQ_CLOSE_DEVICE CloseReq;
    CloseReq.ResetLevel = VBOXUSB_RESET_LEVEL_CLOSE;
    usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));

    pProxyDev->fDetached = true;
    usbProxySolarisCloseFile(pDevSol);

    /*
     * Now we can close it and free all the resources.
     */
    RTCritSectDelete(&pDevSol->CritSect);

    PUSBPROXYURBSOL pUrbSol = NULL;
    while ((pUrbSol = pDevSol->pInFlightHead) != NULL)
    {
        pDevSol->pInFlightHead = pUrbSol->pNext;
        RTMemFree(pUrbSol);
    }

    while ((pUrbSol = pDevSol->pFreeHead) != NULL)
    {
        pDevSol->pFreeHead = pUrbSol->pNext;
        RTMemFree(pUrbSol);
    }

    RTPipeClose(pDevSol->hPipeWakeupR);
    RTPipeClose(pDevSol->hPipeWakeupW);

    RTStrFree(pDevSol->pszDevicePath);
    pDevSol->pszDevicePath = NULL;

    USBLibTerm();
}
/**
 * Stop all service threads and free the device chain.
 */
USBProxyServiceSolaris::~USBProxyServiceSolaris()
{
    LogFlowThisFunc(("destruct\n"));

    /*
     * Stop the service.
     */
    if (isActive())
        stop();

    /*
     * Terminate the USB library
     */
    if (mUSBLibInitialized)
    {
        USBLibTerm();
        mUSBLibInitialized = false;
    }

    RTSemEventDestroy(mNotifyEventSem);
    mNotifyEventSem = NULL;
}
/**
 * Opens the USB device.
 *
 * @returns VBox status code.
 * @param   pProxyDev       The device instance.
 * @param   pszAddress      The unique device identifier.
 *                          The format of this string is "VendorId:ProducIt:Release:StaticPath".
 * @param   pvBackend       Backend specific pointer, unused for the solaris backend.
 */
static DECLCALLBACK(int) usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
{
    PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);

    LogFlowFunc((USBPROXY ":usbProxySolarisOpen pProxyDev=%p pszAddress=%s pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));

    /*
     * Initialize our USB R3 lib.
     */
    int rc = USBLibInit();
    if (RT_SUCCESS(rc))
    {
        /*
         * Allocate and initialize the solaris backend data.
         */
        AssertCompile(PATH_MAX >= MAXPATHLEN);
        char szDeviceIdent[PATH_MAX+48];
        rc = RTStrPrintf(szDeviceIdent, sizeof(szDeviceIdent), "%s", pszAddress);
        if (RT_SUCCESS(rc))
        {
            rc = RTCritSectInit(&pDevSol->CritSect);
            if (RT_SUCCESS(rc))
            {
                /*
                 * Create wakeup pipe.
                 */
                rc = RTPipeCreate(&pDevSol->hPipeWakeupR, &pDevSol->hPipeWakeupW, 0);
                if (RT_SUCCESS(rc))
                {
                    int Instance;
                    char *pszDevicePath = NULL;
                    rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
                    if (RT_SUCCESS(rc))
                    {
                        pDevSol->pszDevicePath = pszDevicePath;

                        /*
                         * Open the client driver.
                         */
                        RTFILE hFile;
                        rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
                        if (RT_SUCCESS(rc))
                        {
                            pDevSol->hFile = hFile;
                            pDevSol->pProxyDev = pProxyDev;

                            /*
                             * Verify client driver version.
                             */
                            VBOXUSBREQ_GET_VERSION GetVersionReq;
                            bzero(&GetVersionReq, sizeof(GetVersionReq));
                            rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
                            if (RT_SUCCESS(rc))
                            {
                                if (   GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
                                    && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
                                {
                                    /*
                                     * Try & get the current cached config from Solaris.
                                     */
                                    usbProxySolarisGetActiveConfig(pDevSol);
                                    return VINF_SUCCESS;
                                }
                                else
                                {
                                    LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
                                            GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
                                    rc = VERR_VERSION_MISMATCH;
                                }
                            }
                            else
                                LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));

                            RTFileClose(pDevSol->hFile);
                            pDevSol->hFile = NIL_RTFILE;
                            pDevSol->pProxyDev = NULL;
                        }
                        else
                            LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));

                        RTStrFree(pDevSol->pszDevicePath);
                        pDevSol->pszDevicePath = NULL;
                    }
                    else
                    {
                        LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
                        if (rc == VERR_NOT_FOUND)
                            rc = VERR_OPEN_FAILED;
                    }
                    RTPipeClose(pDevSol->hPipeWakeupR);
                    RTPipeClose(pDevSol->hPipeWakeupW);
                }

                RTCritSectDelete(&pDevSol->CritSect);
            }
            else
                LogRel((USBPROXY ":RTCritSectInit failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
        }
        else
            LogRel((USBPROXY ":RTStrAPrintf failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
    }
    else
        LogRel((USBPROXY ":USBLibInit failed. rc=%Rrc\n", rc));

    USBLibTerm();
    return rc;
}