/** * 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; }
/** * 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; }
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; }