262 lines
6.4 KiB
C++
262 lines
6.4 KiB
C++
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
#include <netcfgx.h>
|
||
|
#include <devguid.h>
|
||
|
|
||
|
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<void**>(&pINetCfg));
|
||
|
|
||
|
if (S_OK == hr) {
|
||
|
INetCfgLock * pnclock = NULL;
|
||
|
|
||
|
if (fAcquireWriteLock) {
|
||
|
// Get the locking interface
|
||
|
hr = pINetCfg->QueryInterface(IID_INetCfgLock,
|
||
|
reinterpret_cast<LPVOID *>(&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<LPVOID *>(&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;
|
||
|
}
|