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

305 lines
7.5 KiB
C++

#include <stdio.h>
#include <netcfgx.h>
#include <devguid.h>
//
// Localization library and MessageIds.
//
#include <nls.h>
#include "localmsg.h"
EXTERN_C void ausage(void);
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;
NlsPutMsg(STDOUT, IPV6_MESSAGE_0);
// printf("The write lock could not be acquired.\n");
NlsPutMsg(STDOUT, IPV6_MESSAGE_1, pwszLockHolder);
// printf("You must close %ls first.\n", 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;
}
VOID
pAddOrRemoveIpv6(BOOL fAddIpv6)
{
HRESULT hr;
INetCfg* pINetCfg;
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) {
NlsPutMsg(STDOUT, IPV6_MESSAGE_2);
// printf("Installing...\n");
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) {
NlsPutMsg(STDOUT, IPV6_MESSAGE_3);
// printf("Uninstalling...\n");
hr = pSetup->DeInstall (
pIComp,
&OboToken,
NULL);
pIComp->Release();
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_4);
// printf("Microsoft IPv6 Developer Edition is not installed.\n");
}
}
if (SUCCEEDED(hr)) {
if (NETCFG_S_REBOOT == hr) {
hr = S_OK;
NlsPutMsg(STDOUT, IPV6_MESSAGE_5);
// printf("A reboot is required to complete this action.\n");
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_6);
// printf("Succeeded.\n");
}
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_7);
// printf("Failed to complete the action.\n");
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) {
hr = S_OK;
NlsPutMsg(STDOUT, IPV6_MESSAGE_8);
// printf("The INF file for Microsoft IPv6 Developer Edition could not be found.\n");
}
else if (NETCFG_E_NEED_REBOOT == hr) {
NlsPutMsg(STDOUT, IPV6_MESSAGE_9);
// printf("A reboot is required before any further changes can be made.\n");
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_10, hr);
// printf("Error 0x%08x\n", 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
}
else if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr) {
ausage();
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_11, hr);
// printf("Problem 0x%08x occurred.\n", hr);
}
}
EXTERN_C
BOOL
IsIpv6Installed()
{
HRESULT hr = S_OK;
BOOL fInitCom = TRUE;
BOOL fPresent = FALSE;
// 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 {
NlsPutMsg(STDOUT, IPV6_MESSAGE_12, hr);
// printf("Problem 0x%08x occurred while accessing network configuration.\n", hr);
exit(1);
}
if (fInitCom) {
CoUninitialize();
}
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_13, hr);
// printf("Problem 0x%08x initializing COM library\n", hr);
}
return fPresent;
}
EXTERN_C
void
AddOrRemoveIpv6 (
IN BOOL fAddIpv6)
{
HRESULT hr = S_OK;
BOOL fInitCom = TRUE;
// 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)) {
pAddOrRemoveIpv6(fAddIpv6);
if (fInitCom) {
CoUninitialize();
}
}
else {
NlsPutMsg(STDOUT, IPV6_MESSAGE_13, hr);
// printf("Problem 0x%08x initializing COM library\n", hr);
}
}