windows-nt/Source/XPSP1/NT/net/tcpip/tpipv6/ipv6mon/installipv6.cpp
2020-09-26 16:20:57 +08:00

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