VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter) { VM_ASSERT_EMT(pVM); AssertPtrReturn(pFilter, VERR_INVALID_POINTER); AssertPtrReturn(pFilter->pBwGroupR3, VERR_INVALID_POINTER); PUVM pUVM = pVM->pUVM; PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper; int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc); if (RT_SUCCESS(rc)) { pdmNsFilterUnlink(pFilter); PPDMNSBWGROUP pBwGroup = NULL; pBwGroup = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, NULL, PPDMNSBWGROUP); if (pBwGroup) pdmNsBwGroupUnref(pBwGroup); int rc2 = RTCritSectLeave(&pShaper->cs); AssertRC(rc2); } return rc; }
/** * Detach network filter driver from bandwidth group. * * @returns VBox status code. * @param pUVM The user mode VM handle. * @param pDrvIns The driver instance. * @param pFilter Pointer to the filter we detach. */ VMMR3_INT_DECL(int) PDMR3NsDetach(PUVM pUVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter) { RT_NOREF_PV(pDrvIns); VM_ASSERT_EMT(pUVM->pVM); AssertPtrReturn(pFilter, VERR_INVALID_POINTER); /* Now, return quietly if the filter isn't attached since driver/device destructors are called on constructor failure. */ if (!pFilter->pBwGroupR3) return VINF_SUCCESS; AssertPtrReturn(pFilter->pBwGroupR3, VERR_INVALID_POINTER); PPDMNETSHAPER pShaper = pUVM->pdm.s.pNetShaper; LOCK_NETSHAPER_RETURN(pShaper); pdmNsFilterUnlink(pFilter); PPDMNSBWGROUP pBwGroup = ASMAtomicXchgPtrT(&pFilter->pBwGroupR3, NULL, PPDMNSBWGROUP); if (pBwGroup) pdmNsBwGroupUnref(pBwGroup); UNLOCK_NETSHAPER(pShaper); return VINF_SUCCESS; }