#include "precomp.h" #pragma hdrstop #include #include HRESULT HrCreateINetCfg ( IN BOOL fAcquireWriteLock, OUT INetCfg** ppINetCfg) { HRESULT hr; INetCfg* pINetCfg; // Get the INetCfg interface. // hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD, IID_INetCfg, reinterpret_cast(&pINetCfg)); if (S_OK == hr) { INetCfgLock * pnclock = NULL; if (fAcquireWriteLock) { // Get the locking interface hr = pINetCfg->QueryInterface(IID_INetCfgLock, reinterpret_cast(&pnclock)); if (SUCCEEDED(hr)) { LPWSTR pwszLockHolder; // Attempt to lock the INetCfg for read/write hr = pnclock->AcquireWriteLock(100, L"InstallIPv6", &pwszLockHolder); if (S_FALSE == hr) { // Couldn't acquire the lock hr = NETCFG_E_NO_WRITE_LOCK; DisplayMessage(g_hModule, EMSG_NO_WRITE_LOCK, pwszLockHolder); } if (pwszLockHolder) { CoTaskMemFree(pwszLockHolder); } } } if (S_OK == hr) { hr = pINetCfg->Initialize (NULL); if (S_OK == hr) { *ppINetCfg = pINetCfg; pINetCfg->AddRef(); } else { if (pnclock) { pnclock->ReleaseWriteLock(); } } } if (pnclock) { pnclock->Release(); } //Transfer ownership to caller. pINetCfg->Release(); } return hr; } DWORD pAddOrRemoveIpv6(BOOL fAddIpv6) { HRESULT hr; INetCfg* pINetCfg; DWORD dwErr = NO_ERROR; hr = HrCreateINetCfg (TRUE, &pINetCfg); if (S_OK == hr) { INetCfgClassSetup* pSetup; // Get the setup interface used for installing // and uninstalling components. // hr = pINetCfg->QueryNetCfgClass ( &GUID_DEVCLASS_NETTRANS, IID_INetCfgClassSetup, (VOID**)&pSetup); if (S_OK == hr) { OBO_TOKEN OboToken; INetCfgComponent* pIComp; ZeroMemory (&OboToken, sizeof(OboToken)); OboToken.Type = OBO_USER; if (fAddIpv6) { hr = pSetup->Install ( L"MS_TCPIP6", &OboToken, 0, 0, NULL, NULL, &pIComp); if (pIComp) { pIComp->Release(); } } else { // Need to remove the component. // Find it first. // hr = pINetCfg->FindComponent ( L"MS_TCPIP6", &pIComp); if (S_OK == hr) { hr = pSetup->DeInstall ( pIComp, &OboToken, NULL); pIComp->Release(); } else { DisplayMessage(g_hModule, EMSG_PROTO_NOT_INSTALLED); dwErr = ERROR_SUPPRESS_OUTPUT; } } if (SUCCEEDED(hr)) { if (NETCFG_S_REBOOT == hr) { hr = S_OK; DisplayMessage(g_hModule, EMSG_REBOOT_NEEDED); dwErr = ERROR_SUPPRESS_OUTPUT; } else { dwErr = ERROR_OKAY; } } else { if (NETCFG_E_NEED_REBOOT == hr) { DisplayMessage(g_hModule, EMSG_REBOOT_NEEDED); dwErr = ERROR_SUPPRESS_OUTPUT; } else { dwErr = hr; } } pSetup->Release(); } hr = pINetCfg->Uninitialize(); if (SUCCEEDED(hr)) { INetCfgLock *pnclock; // Get the locking interface hr = pINetCfg->QueryInterface(IID_INetCfgLock, reinterpret_cast(&pnclock)); if (SUCCEEDED(hr)) { // Attempt to lock the INetCfg for read/write hr = pnclock->ReleaseWriteLock(); pnclock->Release(); } } pINetCfg->Release(); } else if (NETCFG_E_NO_WRITE_LOCK == hr) { // Message has already been printed dwErr = ERROR_SUPPRESS_OUTPUT; } else if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr) { dwErr = ERROR_ACCESS_DENIED; } else { dwErr = hr; } return dwErr; } EXTERN_C DWORD IsIpv6Installed( BOOL *bInstalled) { HRESULT hr = S_OK; BOOL fInitCom = TRUE; BOOL fPresent = FALSE; DWORD dwErr = NO_ERROR; // Initialize COM. // hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ); if (RPC_E_CHANGED_MODE == hr) { // If we changed mode, then we won't uninitialize COM when we are done. // hr = S_OK; fInitCom = FALSE; } if (SUCCEEDED(hr)) { HRESULT hr; INetCfg* pINetCfg; hr = HrCreateINetCfg (FALSE, &pINetCfg); if (S_OK == hr) { fPresent = (S_OK == pINetCfg->FindComponent(L"MS_TCPIP6", NULL)); pINetCfg->Uninitialize(); pINetCfg->Release(); } else { dwErr = hr; } if (fInitCom) { CoUninitialize(); } } else { dwErr = hr; } *bInstalled = fPresent; return dwErr; } EXTERN_C DWORD AddOrRemoveIpv6 ( IN BOOL fAddIpv6) { HRESULT hr = S_OK; BOOL fInitCom = TRUE; DWORD dwErr = NO_ERROR; // Initialize COM. // hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ); if (RPC_E_CHANGED_MODE == hr) { // If we changed mode, then we won't uninitialize COM when we are done. // hr = S_OK; fInitCom = FALSE; } if (SUCCEEDED(hr)) { dwErr = pAddOrRemoveIpv6(fAddIpv6); if (fInitCom) { CoUninitialize(); } } else { dwErr = hr; } return dwErr; }