BOOL CNetConnectionPropertyUi::GetINetCfgComponent(INetCfg *pNCfg, INetCfgComponent ** pOut) { LPWSTR pName; HRESULT hr; INetCfgComponent * pNCg; ULONG Fetched; IEnumNetCfgComponent * pEnumCfg; hr = pNCfg->EnumComponents(&GUID_DEVCLASS_NET, &pEnumCfg); if (FAILED(hr)) { return FALSE; } while (pEnumCfg->Next(1, &pNCg, &Fetched) == S_OK) { hr = pNCg->GetDisplayName(&pName); if (SUCCEEDED(hr)) { if (!_wcsicmp(pName, pProperties->pszwDeviceName)) { *pOut = pNCg; pEnumCfg->Release(); return TRUE; } CoTaskMemFree(pName); } pNCg->Release(); } pEnumCfg->Release(); return FALSE; }
//+--------------------------------------------------------------------------- // // Function: HrUninstallNetComponent // // Purpose: Uninstall the specified component. // // Arguments: // pnc [in] pointer to INetCfg object // szComponentId [in] component to uninstall // // Returns: S_OK or NETCFG_S_REBOOT on success, otherwise an error code // // Notes: // HRESULT HrUninstallNetComponent(IN INetCfg* pnc, IN PCWSTR szComponentId) { HRESULT hr=S_OK; OBO_TOKEN OboToken; INetCfgComponent* pncc; GUID guidClass; INetCfgClass* pncClass; INetCfgClassSetup* pncClassSetup; // OBO_TOKEN specifies the entity on whose behalf this // component is being uninstalld // set it to OBO_USER so that szComponentId will be uninstalld // On-Behalf-Of "user" ZeroMemory (&OboToken, sizeof(OboToken)); OboToken.Type = OBO_USER; // see if the component is really installed hr = pnc->FindComponent(szComponentId, &pncc); if (S_OK == hr) { // yes, it is installed. obtain INetCfgClassSetup and DeInstall hr = pncc->GetClassGuid(&guidClass); if (S_OK == hr) { hr = pnc->QueryNetCfgClass(&guidClass, IID_INetCfgClass, (void**)&pncClass); if (SUCCEEDED(hr)) { hr = pncClass->QueryInterface(IID_INetCfgClassSetup, (void**)&pncClassSetup); if (SUCCEEDED(hr)) { hr = pncClassSetup->DeInstall (pncc, &OboToken, NULL); ReleaseObj (pncClassSetup); } ReleaseObj(pncClass); } } ReleaseObj(pncc); } return hr; }
static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingInterface *pIf, OUT bool *pbShouldBind) { INetCfgComponent * pAdapterComponent; HRESULT hr = pIf->GetLowerComponent(&pAdapterComponent); if (hr == S_OK) { hr = vboxNetFltWinNotifyShouldBind(pAdapterComponent, pbShouldBind); pAdapterComponent->Release(); } else { NonStandardAssertBreakpoint(); } return hr; }
VOID CNetConnectionPropertyUi::ShowNetworkComponentProperties(HWND hwndDlg) { LVITEMW lvItem; HWND hDlgCtrl; UINT Index, Count; HRESULT hr; INetCfgComponent *pNCfgComp; PNET_ITEM pItem; hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMPONENTSLIST); Count = ListView_GetItemCount(hDlgCtrl); if (!Count) return; ZeroMemory(&lvItem, sizeof(LVITEMW)); lvItem.mask = LVIF_PARAM | LVIF_STATE; lvItem.stateMask = (UINT)-1; for (Index = 0; Index < Count; Index++) { lvItem.iItem = Index; if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { if (lvItem.state & LVIS_SELECTED) break; } } if (!(lvItem.state & LVIS_SELECTED)) { return; } pItem = (PNET_ITEM)lvItem.lParam; pNCfgComp = (INetCfgComponent*)pItem->pNCfgComp; hr = pNCfgComp->RaisePropertyUi(GetParent(hwndDlg), NCRP_QUERY_PROPERTY_UI, (INetConnectionConnectUi*)this); if (SUCCEEDED(hr)) { hr = pNCfgComp->RaisePropertyUi(GetParent(hwndDlg), NCRP_SHOW_PROPERTY_UI, (INetConnectionConnectUi*)this); } }
DWORD UninstallDriver() { TRACE_ENTER("UninstallDriver"); //_tprintf( _T("Uninstalling %s...\n"), NDISPROT_FRIENDLY_NAME ); // int nResult = MessageBox(NULL, _T("Uninstalling Driver..."), NDISPROT_FRIENDLY_NAME, MB_OKCANCEL | MB_ICONINFORMATION); // // if (nResult != IDOK) // { // return 0; // } INetCfg* pnc; INetCfgComponent* pncc; INetCfgClass* pncClass; INetCfgClassSetup* pncClassSetup; LPTSTR lpszApp; GUID guidClass; OBO_TOKEN obo; HRESULT hr; hr = HrGetINetCfg(TRUE, APP_NAME, &pnc, &lpszApp); if (hr == S_OK) { // // Get a reference to the network component to uninstall. // hr = pnc->FindComponent(NDISLWF_SERVICE_PNP_DEVICE_ID, &pncc); if (hr == S_OK) { // // Get the class GUID. // hr = pncc->GetClassGuid(&guidClass); if (hr == S_OK) { // // Get a reference to component's class. // hr = pnc->QueryNetCfgClass(&guidClass, IID_INetCfgClass, (PVOID *)&pncClass); if (hr == S_OK) { // // Get the setup interface. // hr = pncClass->QueryInterface(IID_INetCfgClassSetup, (LPVOID *)&pncClassSetup); if (hr == S_OK) { // // Uninstall the component. // ZeroMemory(&obo, sizeof(OBO_TOKEN)); obo.Type = OBO_USER; hr = pncClassSetup->DeInstall(pncc, &obo, NULL); if ((hr == S_OK) || (hr == NETCFG_S_REBOOT)) { hr = pnc->Apply(); if ((hr != S_OK) && (hr != NETCFG_S_REBOOT)) { ErrMsg(hr, L"Couldn't apply the changes after" L" uninstalling %s.", NDISLWF_SERVICE_PNP_DEVICE_ID); } else { TRACE_EXIT("UninstallDriver"); return 1; } } else { ErrMsg(hr, L"Failed to uninstall %s.", NDISLWF_SERVICE_PNP_DEVICE_ID); } ReleaseRef(pncClassSetup); } else { ErrMsg(hr, L"Couldn't get an interface to setup class."); } ReleaseRef(pncClass); } else { ErrMsg(hr, L"Couldn't get a pointer to class interface " L"of %s.", NDISLWF_SERVICE_PNP_DEVICE_ID); } } else { ErrMsg(hr, L"Couldn't get the class guid of %s.", NDISLWF_SERVICE_PNP_DEVICE_ID); } ReleaseRef(pncc); } else { ErrMsg(hr, L"Couldn't get an interface pointer to %s.", NDISLWF_SERVICE_PNP_DEVICE_ID); } HrReleaseINetCfg(pnc, TRUE); } else { if ((hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp) { ErrMsg(hr, L"%s currently holds the lock, try later.", lpszApp); CoTaskMemFree(lpszApp); } else { ErrMsg(hr, L"Couldn't get the notify object interface."); } } TRACE_EXIT("UninstallDriver"); return 0; }
bool ChangeNicBindingOrder() { HRESULT hr = S_OK; INetCfg *pNetCfg = NULL; INetCfgBindingPath *pNetCfgPath; INetCfgComponent *pNetCfgComponent = NULL; INetCfgComponentBindings *pNetCfgBinding = NULL; INetCfgLock *pNetCfgLock = NULL; IEnumNetCfgBindingPath *pEnumNetCfgBindingPath = NULL; PWSTR szLockedBy; if (!SUCCEEDED(CoInitialize(NULL))) { return false; } if (S_OK != CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pNetCfg)) { return false; } if (!SUCCEEDED(pNetCfg->QueryInterface(IID_INetCfgLock, (LPVOID *)&pNetCfgLock))) { return false; } static const ULONG c_cmsTimeout = 5000; static const WCHAR c_szSampleNetcfgApp[] = L"TapRebinder (TapRebinder.exe)"; if (!SUCCEEDED(pNetCfgLock->AcquireWriteLock(c_cmsTimeout, c_szSampleNetcfgApp, &szLockedBy))) { wprintf(L"Could not lock INetcfg, it is already locked by '%s'", szLockedBy); return false; } if (!SUCCEEDED(pNetCfg->Initialize(NULL))) { if (pNetCfgLock) { pNetCfgLock->ReleaseWriteLock(); } ReleaseObj(pNetCfgLock); return false; } ReleaseObj(pNetCfgLock); if (S_OK != pNetCfg->FindComponent(L"ms_tcpip", &pNetCfgComponent)) { return false; } if (S_OK != pNetCfgComponent->QueryInterface(IID_INetCfgComponentBindings, (LPVOID *)&pNetCfgBinding)) { return false; } if (S_OK != pNetCfgBinding->EnumBindingPaths(EBP_BELOW, &pEnumNetCfgBindingPath)) { return false; } while (S_OK == hr) { hr = pEnumNetCfgBindingPath->Next(1, &pNetCfgPath, NULL); LPWSTR pszwPathToken; pNetCfgPath->GetPathToken(&pszwPathToken); if (wcscmp(pszwPathToken, wDeviceInstanceId) == 0) { wprintf(L" Moving adapter to the first position: %s.\n", pszwPathToken); pNetCfgBinding->MoveBefore(pNetCfgPath, NULL); pNetCfg->Apply(); CoTaskMemFree(pszwPathToken); ReleaseObj(pNetCfgPath); break; } CoTaskMemFree(pszwPathToken); ReleaseObj(pNetCfgPath); } ReleaseObj(pEnumNetCfgBindingPath); ReleaseObj(pNetCfgBinding); ReleaseObj(pNetCfgComponent); ReleaseINetCfg(TRUE, pNetCfg); return true; }
HRESULT HrFindInstance (INetCfg *pnc, GUID &guidInstance, INetCfgComponent **ppnccMiniport) { IEnumNetCfgComponent *pencc; INetCfgComponent *pncc; GUID guid; WCHAR szGuid[MAX_PATH+1]; ULONG ulCount; BOOL found; HRESULT hr; TraceMsg( L"-->HrFindInstance.\n" ); hr = pnc->EnumComponents( &GUID_DEVCLASS_NET, &pencc ); if ( hr == S_OK ) { StringFromGUID2( guidInstance, szGuid, MAX_PATH+1 ); TraceMsg( L" Looking for component with InstanceGuid %s\n", szGuid ); hr = pencc->Next( 1, &pncc, &ulCount ); for ( found=FALSE; (hr == S_OK) && (found == FALSE); ) { hr = pncc->GetInstanceGuid( &guid ); if ( hr == S_OK ) { StringFromGUID2( guid, szGuid, MAX_PATH+1 ); TraceMsg( L" Found component with InstanceGuid %s\n", szGuid ); found = IsEqualGUID( guid, guidInstance ); if ( found == FALSE ) { ReleaseObj( pncc ); hr = pencc->Next( 1, &pncc, &ulCount ); } else { *ppnccMiniport = pncc; } } } ReleaseObj( pencc ); } else { TraceMsg( L" EnumComponents failed(HRESULT = %x).\n", hr ); } TraceMsg( L"<--HrFindInstance(HRESULT = %x).\n", hr ); return hr; }
//+--------------------------------------------------------------------------- // // Function: HrShowBindingPath // // Purpose: Display components of a binding path in the format: // foo -> bar -> adapter // // Arguments: // pncbp [in] pointer to INetCfgBindingPath object // // Returns: S_OK on success, otherwise an error code // // Notes: // HRESULT HrShowBindingPath(IN INetCfgBindingPath* pncbp) { HRESULT hr=S_OK; INetCfgBindingInterface* pncbi; INetCfgComponent* pncc = NULL; BOOL fFirstInterface=TRUE; PWSTR szComponentId; while (SUCCEEDED(hr) && (S_OK == (hr = HrGetNextBindingInterface(pncbp, &pncbi)))) { // for the first (top) interface we need to get the upper as well as // the lower component. for other interfaces we need to get // only the lower component. if (fFirstInterface) { fFirstInterface = FALSE; hr = pncbi->GetUpperComponent(&pncc); if (SUCCEEDED(hr)) { // get id so that we can display it // // for readability of the output, we have used the GetId // function. For non net class components, this // does not pose a problem. In case of net class components, // there may be more than one net adapters of the same type // in which case, GetId will return the same string. This will // make it impossible to distinguish between two binding // paths that end in two distinct identical cards. In such case, // it may be better to use the GetInstanceGuid function because // it will return unique GUID for each instance of an adapter. // hr = pncc->GetId(&szComponentId); ReleaseObj(pncc); if (SUCCEEDED(hr)) { LogPrintf(szComponentId); CoTaskMemFree(szComponentId); } } } if (SUCCEEDED(hr)) { hr = pncbi->GetLowerComponent(&pncc); if (SUCCEEDED(hr)) { hr = pncc->GetId(&szComponentId); if (SUCCEEDED(hr)) { LogPrintf(_T(" -> %s"), szComponentId); CoTaskMemFree(szComponentId); } ReleaseObj(pncc); } } ReleaseObj(pncbi); } LogPrintf(_T("\n")); if (hr == S_FALSE) { hr = S_OK; } return hr; }
//+--------------------------------------------------------------------------- // // Function: HrShowNetComponents // // Purpose: Display the list of installed components of the // specified class. // // Arguments: // pnc [in] pointer to INetCfg object // pguidClass [in] pointer to class GUID // // Returns: S_OK on success, otherwise an error code // // Notes: // HRESULT HrShowNetComponents(IN INetCfg* pnc, IN const GUID* pguidClass) { HRESULT hr=S_OK; PWSTR szInfId; PWSTR szDisplayName; DWORD dwcc; INetCfgComponent* pncc; INetCfgClass* pncclass; IEnumNetCfgComponent* pencc; ULONG celtFetched; hr = pnc->QueryNetCfgClass(pguidClass, IID_INetCfgClass, (void**)&pncclass); if (SUCCEEDED(hr)) { // get IEnumNetCfgComponent so that we can enumerate hr = pncclass->EnumComponents(&pencc); ReleaseObj(pncclass); while (SUCCEEDED(hr) && (S_OK == (hr = pencc->Next(1, &pncc, &celtFetched)))) { if (pguidClass == &GUID_DEVCLASS_NET) { // we are interested only in physical netcards // hr = pncc->GetCharacteristics(&dwcc); if (FAILED(hr) || !(dwcc & NCF_PHYSICAL)) { hr = S_OK; ReleaseObj(pncc); continue; } } hr = pncc->GetId(&szInfId); if (S_OK == hr) { hr = pncc->GetDisplayName(&szDisplayName); if (SUCCEEDED(hr)) { LogPrintf(_T("%-26s %s\n"), szInfId, szDisplayName); CoTaskMemFree(szDisplayName); } CoTaskMemFree(szInfId); } // we dont want to stop enumeration just because 1 component // failed either GetId or GetDisplayName, therefore reset hr to S_OK hr = S_OK; ReleaseObj(pncc); } ReleaseObj(pencc); } if (S_FALSE == hr) { hr = S_OK; } return hr; }
// Install the NDIS protocol driver bool UninstallNdisProtocolDriver(wchar_t *id, UINT lock_timeout) { bool ret = false; HRESULT hr; INetCfg *pNetCfg; // Validate arguments if (id == NULL) { return false; } hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void **)&pNetCfg); if (SUCCEEDED(hr)) { INetCfgLock *pLock; hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock); if (SUCCEEDED(hr)) { LPWSTR locked_by; hr = pLock->AcquireWriteLock(lock_timeout, L"SoftEther VPN", &locked_by); if (SUCCEEDED(hr)) { hr = pNetCfg->Initialize(NULL); if (SUCCEEDED(hr)) { INetCfgComponent *pncc = NULL; hr = pNetCfg->FindComponent(id, &pncc); if (pncc == NULL || hr == S_FALSE) { hr = E_FAIL; } if (SUCCEEDED(hr)) { INetCfgClass *pncClass; hr = pNetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NETTRANS, IID_INetCfgClass, (void **)&pncClass); if (SUCCEEDED(hr)) { INetCfgClassSetup *pncClassSetup; hr = pncClass->QueryInterface(IID_INetCfgClassSetup, (void **)&pncClassSetup); if (SUCCEEDED(hr)) { OBO_TOKEN obo; wchar_t *c = NULL; Zero(&obo, sizeof(obo)); obo.Type = OBO_USER; hr = pncClassSetup->DeInstall(pncc, &obo, &c); if (SUCCEEDED(hr)) { hr = pNetCfg->Apply(); if (SUCCEEDED(hr)) { ret = true; } else { WHERE; Debug("0x%x\n", hr); } } else { WHERE; Debug("0x%x\n", hr); } pncClassSetup->Release(); } else { WHERE; } pncClass->Release(); } else { WHERE; } pncc->Release(); } else { WHERE; } } else { WHERE; } pLock->ReleaseWriteLock(); } else { WHERE; } pLock->Release(); } pNetCfg->Release(); } else { WHERE; } return ret; }
HRESULT CMuxVirtualMiniport::Install (VOID) { INetCfgClass *pncClass; INetCfgClassSetup *pncClassSetup; INetCfgComponent *pnccMiniport; HRESULT hr; LPWSTR *pmszwRefs=NULL; OBO_TOKEN *pOboToken=NULL; DWORD dwSetupFlags=0; LPCWSTR pszwAnswerFile=NULL; LPCWSTR pszwAnswerSections=NULL; TraceMsg( L"-->CMuxVirtualMiniport::Install.\n" ); hr = m_pnc->QueryNetCfgClass( &GUID_DEVCLASS_NET, IID_INetCfgClass, (void **)&pncClass ); if ( hr == S_OK ) { hr = pncClass->QueryInterface( IID_INetCfgClassSetup, (void **)&pncClassSetup ); if ( hr == S_OK ) { hr = pncClassSetup->Install( c_szMuxMiniport, pOboToken, dwSetupFlags, 0, pszwAnswerFile, pszwAnswerSections, &pnccMiniport ); if ( hr == S_OK ) { hr = pnccMiniport->GetInstanceGuid( &m_guidMiniport ); if ( hr != S_OK ) { TraceMsg( L" Failed to get the instance guid, uninstalling " L" the miniport.\n" ); pncClassSetup->DeInstall( pnccMiniport, pOboToken, pmszwRefs ); } ReleaseObj( pnccMiniport ); } else { TraceMsg( L" Failed to install the miniport.\n" ); } ReleaseObj( pncClassSetup ); } else { TraceMsg( L" QueryInterface failed.\n" ); } ReleaseObj( pncClass ); } else { TraceMsg( L" QueryNetCfgClass failed.\n" ); } TraceMsg( L"<--CMuxVirtualMiniport::Install(HRESULT = %x).\n", hr ); return hr; }
HRESULT HrUninstallNetComponent( IN INetCfg* pnc, IN LPCTSTR szComponentId ) { INetCfgComponent *pncc = NULL; INetCfgClass *pncClass = NULL; INetCfgClassSetup *pncClassSetup = NULL; OBO_TOKEN OboToken; GUID guidClass; HRESULT hr = S_OK; // // OBO_TOKEN specifies on whose behalf this // component is being installed. // Set it to OBO_USER so that szComponentId will be installed // on behalf of the user. // ZeroMemory(&OboToken, sizeof(OboToken)); OboToken.Type = OBO_USER; // // Get the component's reference. // hr = pnc->FindComponent(szComponentId, &pncc); if (S_OK == hr) { // // Get the component's class GUID. // hr = pncc->GetClassGuid(&guidClass); if (hr == S_OK) { // // Get component's class reference. // hr = pnc->QueryNetCfgClass(&guidClass, IID_INetCfgClass, (void**)&pncClass); if (hr == S_OK) { // // Get Setup reference. // hr = pncClass->QueryInterface(IID_INetCfgClassSetup, (void**)&pncClassSetup); if (hr == S_OK) { hr = pncClassSetup->DeInstall(pncc, &OboToken, NULL); if (hr == S_OK) { // // Apply the changes // hr = pnc->Apply(); } ReleaseRef(pncClassSetup); } ReleaseRef(pncClass); } } ReleaseRef(pncc); } return hr; }
HRESULT CMuxPhysicalAdapter::ApplyPnpChanges( INetCfgPnpReconfigCallback *pfCallback, ConfigAction eApplyAction) { CMuxVirtualMiniport *pMiniport = NULL; GUID guidMiniport; DWORD dwMiniportCount; DWORD i; HRESULT hr; #ifdef CUSTOM_EVENTS LPWSTR lpDevice; WCHAR szMiniportGuid[MAX_PATH+1]; DWORD dwBytes; INetCfgComponent *pncc; LPWSTR lpszBindName; PNOTIFY_CUSTOM_EVENT lppnpEvent; #endif UNREFERENCED_PARAMETER(eApplyAction); TraceMsg( L"-->CMuxPhysicalAdapter::ApplyPnpChanges.\n" ); #ifdef CUSTOM_EVENTS // // Find the instance of the adapter to get its bindname. // hr = HrFindInstance( m_pnc, m_guidAdapter, &pncc ); if ( hr == S_OK ) { hr = pncc->GetBindName( &lpszBindName ); if ( hr != S_OK ) { TraceMsg( L" GetBindName failed.(HRESULT = %x). PnP changes will not " L"be applied and the driver will not be notified.\n", hr ); } ReleaseObj( pncc ); } else { TraceMsg( L" PnP changes will not " L"be applied and the driver will not be notified.\n", hr ); } #endif dwMiniportCount = m_MiniportsToAdd.ListCount(); TraceMsg( L" Applying PnP changes to %d new miniports.\n", dwMiniportCount ); for (i=0; i < dwMiniportCount; ++i) { pMiniport = NULL; m_MiniportsToAdd.Remove( &pMiniport ); pMiniport->GetMiniportGUID( &guidMiniport ); m_MiniportList.Insert( pMiniport, guidMiniport ); // // Do miniport specific Pnp Changes when they are added. // hr = pMiniport->ApplyPnpChanges( pfCallback, eActAdd ); if( hr != S_OK) { // you may do something } #ifdef CUSTOM_EVENTS // // Notify the driver that one or more virtual miniports have been added. // StringFromGUID2( guidMiniport, szMiniportGuid, MAX_PATH+1 ); lpDevice = AddDevicePrefix( szMiniportGuid ); if ( lpDevice ) { dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) + ((wcslen(lpDevice) + 1) * sizeof(WCHAR)); lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes ); if ( lppnpEvent ) { lppnpEvent->uSignature = NOTIFY_SIGNATURE; lppnpEvent->uEvent = MUX_CUSTOM_EVENT; wcscpy( lppnpEvent->szMiniport, lpDevice ); hr = pfCallback->SendPnpReconfig( NCRL_NDIS, c_szMuxService, lpszBindName, (PVOID)lppnpEvent, dwBytes ); TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned " L"%#x.\n", hr ); if ( hr != S_OK ) { TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n", i ); } free( lppnpEvent ); } free( lpDevice ); } #endif } dwMiniportCount = m_MiniportsToRemove.ListCount(); TraceMsg( L" Applying PnP changes to %d removed miniports.\n", dwMiniportCount ); for (i=0; i < dwMiniportCount; ++i) { pMiniport = NULL; m_MiniportsToRemove.Remove( &pMiniport ); pMiniport->GetMiniportGUID( &guidMiniport ); // // Do miniport specific Pnp Changes when they are uninstalled. // hr = pMiniport->ApplyPnpChanges( pfCallback, eActRemove ); if( hr != S_OK) { // you may do something } delete pMiniport; #ifdef CUSTOM_EVENTS // // Notify the driver that one or more virtual miniports have been // uninstalled. // // We can't notify the driver in case the adapter or the protocol is // being uninstalled because the binding handle doesn't exist. // if ( eApplyAction != eActRemove ) { StringFromGUID2( guidMiniport, szMiniportGuid, MAX_PATH+1 ); lpDevice = AddDevicePrefix( szMiniportGuid ); if ( lpDevice ) { dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) + ((wcslen(lpDevice) + 1) * sizeof(WCHAR)); lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes ); if ( lppnpEvent ) { lppnpEvent->uSignature = NOTIFY_SIGNATURE; lppnpEvent->uEvent = MUX_CUSTOM_EVENT; wcscpy( lppnpEvent->szMiniport, lpDevice ); hr = pfCallback->SendPnpReconfig( NCRL_NDIS, c_szMuxService, lpszBindName, (PVOID)lppnpEvent, dwBytes ); TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned " L"%#x.\n", hr ); if ( hr != S_OK ) { TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n", i ); } free( lppnpEvent ); } free( lpDevice ); } } #endif } #ifdef CUSTOM_EVENTS CoTaskMemFree( lpszBindName ); #endif TraceMsg( L"<--CMuxPhysicalAdapter::ApplyPnpChanges(HRESULT = %x).\n", S_OK ); return S_OK; }