/**
 * performs the Idc initialization
 * we separate the globals initialization to globals "base" initialization which is actually
 * "general" globals initialization except for Idc not being initialized, and idc initialization.
 * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
 * thus it's not possible to make idc initialization from the driver startup routine for it.
 *
 * @returns VBox status code.
 * @param   pGlobals    Pointer to the globals. */
DECLHIDDEN(int) vboxNetAdpInitIdc(PVBOXNETADPGLOBALS pGlobals)
{
    int rc;
    /*
     * Establish a connection to SUPDRV and register our component factory.
     */
    rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
    if (RT_SUCCESS(rc))
    {
        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
        if (RT_SUCCESS(rc))
        {
#if 1 /** @todo REMOVE ME! */
            PVBOXNETADP pTmp;
            rc = vboxNetAdpCreate(&pGlobals->TrunkFactory, &pTmp);
            if (RT_FAILURE(rc))
                Log(("Failed to create vboxnet0, rc=%Rrc.\n", rc));
#endif
            Log(("VBoxNetAdp: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
            return rc;
        }

        /* bail out. */
        LogRel(("VBoxNetAdp: Failed to register component factory, rc=%Rrc\n", rc));
        SUPR0IdcClose(&pGlobals->SupDrvIDC);
    }

    return rc;
}
/**
 * tries to deinitialize Idc
 * we separate the globals settings "base" which is actually
 * "general" globals settings except for Idc, and idc.
 * This is needed for windows filter driver, which gets loaded prior to VBoxDrv,
 * thus it's not possible to make idc initialization from the driver startup routine for it,
 * though the "base is still needed for the driver to functions".
 * @param pGlobals
 * @return VINF_SUCCESS on success, VERR_WRONG_ORDER if we're busy.
 */
DECLHIDDEN(int) vboxNetAdpTryDeleteIdc(PVBOXNETADPGLOBALS pGlobals)
{
    int rc;

    Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);

    /*
     * Check before trying to deregister the factory.
     */
    if (!vboxNetAdpCanUnload(pGlobals))
        return VERR_WRONG_ORDER;

    /*
     * Disconnect from SUPDRV and check that nobody raced us,
     * reconnect if that should happen.
     */
    rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
    AssertRC(rc);
    if (!vboxNetAdpCanUnload(pGlobals))
    {
        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
        AssertRC(rc);
        return VERR_WRONG_ORDER;
    }

    SUPR0IdcClose(&pGlobals->SupDrvIDC);

    return rc;
}
Example #3
0
/**
 * Try to close the IDC connection to SUPDRV if established.
 *
 * @returns VBox status code.
 * @retval  VINF_SUCCESS on success.
 * @retval  VERR_WRONG_ORDER if we're busy.
 *
 * @param   pGlobals        Pointer to the globals.
 */
DECLHIDDEN(int) vboxPciDeleteIdc(PVBOXRAWPCIGLOBALS pGlobals)
{
    int rc;

    Assert(pGlobals->hFastMtx != NIL_RTSEMFASTMUTEX);

    /*
     * Check before trying to deregister the factory.
     */
    if (!vboxPciCanUnload(pGlobals))
        return VERR_WRONG_ORDER;

    if (!pGlobals->fIDCOpen)
        rc = VINF_SUCCESS;
    else
    {
        /*
         * Disconnect from SUPDRV.
         */
        rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
        AssertRC(rc);
        SUPR0IdcClose(&pGlobals->SupDrvIDC);
        pGlobals->fIDCOpen = false;
    }

    return rc;
}
Example #4
0
static int vboxPciInitIdc(PVBOXRAWPCIGLOBALS pGlobals)
{
    int rc;
    Assert(!pGlobals->fIDCOpen);

    /*
     * Establish a connection to SUPDRV and register our component factory.
     */
    rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL);
    if (RT_SUCCESS(rc))
    {
        rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory);
        if (RT_SUCCESS(rc))
        {
            pGlobals->fIDCOpen = true;
            Log(("VBoxRawPci: pSession=%p\n", SUPR0IdcGetSession(&pGlobals->SupDrvIDC)));
            return rc;
        }

        /* bail out. */
        LogRel(("VBoxRawPci: Failed to register component factory, rc=%Rrc\n", rc));
        SUPR0IdcClose(&pGlobals->SupDrvIDC);
    }

    return rc;
}
/**
 * Opens the IDC interface of the support driver.
 *
 * This will perform basic version negotiations and fail if the
 * minimum requirements aren't met.
 *
 * @returns VBox status code.
 * @param   pHandle             The handle structure (output).
 * @param   uReqVersion         The requested version. Pass 0 for default.
 * @param   uMinVersion         The minimum required version. Pass 0 for default.
 * @param   puSessionVersion    Where to store the session version. Optional.
 * @param   puDriverVersion     Where to store the session version. Optional.
 * @param   puDriverRevision    Where to store the SVN revision of the driver. Optional.
 */
SUPR0DECL(int) SUPR0IdcOpen(PSUPDRVIDCHANDLE pHandle, uint32_t uReqVersion, uint32_t uMinVersion,
                            uint32_t *puSessionVersion, uint32_t *puDriverVersion, uint32_t *puDriverRevision)
{
    unsigned uDefaultMinVersion;
    SUPDRVIDCREQCONNECT Req;
    int rc;

    /*
     * Validate and set failure return values.
     */
    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
    pHandle->s.pSession = NULL;

    AssertPtrNullReturn(puSessionVersion, VERR_INVALID_POINTER);
    if (puSessionVersion)
        *puSessionVersion = 0;

    AssertPtrNullReturn(puDriverVersion, VERR_INVALID_POINTER);
    if (puDriverVersion)
        *puDriverVersion = 0;

    AssertPtrNullReturn(puDriverRevision, VERR_INVALID_POINTER);
    if (puDriverRevision)
        *puDriverRevision = 0;

    AssertReturn(!uMinVersion || (uMinVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);
    AssertReturn(!uReqVersion || (uReqVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);

    /*
     * Handle default version input and enforce minimum requirements made
     * by this library.
     *
     * The clients will pass defaults (0), and only in the case that some
     * special API feature was just added will they set an actual version.
     * So, this is the place where can easily enforce a minimum IDC version
     * on bugs and similar. It corresponds a bit to what SUPR3Init is
     * responsible for.
     */
    uDefaultMinVersion = SUPDRV_IDC_VERSION & UINT32_C(0xffff0000);
    if (!uMinVersion || uMinVersion < uDefaultMinVersion)
        uMinVersion = uDefaultMinVersion;
    if (!uReqVersion || uReqVersion < uDefaultMinVersion)
        uReqVersion = uDefaultMinVersion;

    /*
     * Setup the connect request packet and call the OS specific function.
     */
    Req.Hdr.cb = sizeof(Req);
    Req.Hdr.rc = VERR_WRONG_ORDER;
    Req.Hdr.pSession = NULL;
    Req.u.In.u32MagicCookie = SUPDRVIDCREQ_CONNECT_MAGIC_COOKIE;
    Req.u.In.uMinVersion = uMinVersion;
    Req.u.In.uReqVersion = uReqVersion;
    rc = supR0IdcNativeOpen(pHandle, &Req);
    if (RT_SUCCESS(rc))
    {
        pHandle->s.pSession = Req.u.Out.pSession;
        if (puSessionVersion)
            *puSessionVersion = Req.u.Out.uSessionVersion;
        if (puDriverVersion)
            *puDriverVersion = Req.u.Out.uDriverVersion;
        if (puDriverRevision)
            *puDriverRevision = Req.u.Out.uDriverRevision;

        /*
         * We don't really trust anyone, make sure the returned
         * session and version values actually makes sense.
         */
        if (    VALID_PTR(Req.u.Out.pSession)
            &&  Req.u.Out.uSessionVersion >= uMinVersion
            &&  (Req.u.Out.uSessionVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)))
        {
            ASMAtomicCmpXchgPtr(&g_pMainHandle, pHandle, NULL);
            return rc;
        }

        AssertMsgFailed(("pSession=%p uSessionVersion=0x%x (r%u)\n", Req.u.Out.pSession, Req.u.Out.uSessionVersion, Req.u.Out.uDriverRevision));
        rc = VERR_VERSION_MISMATCH;
        SUPR0IdcClose(pHandle);
    }

    return rc;
}