VBoxNetCfg.cpp revision 6db5dfa0985f898dd0497d98716b6d0335a9dde4
/* $Id$ */
/** @file
* VBoxNetCfg.cpp - Network Configuration API.
*/
/*
* Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "VBox/VBoxNetCfg-win.h"
#include "VBox/VBoxDrvCfg-win.h"
#define _WIN32_DCOM
#include <iphlpapi.h>
#include <devguid.h>
#include <stdio.h>
#include <regstr.h>
#include <shlobj.h>
#include <cfgmgr32.h>
#include <tchar.h>
#include <objbase.h>
#include <crtdbg.h>
#include <stdlib.h>
#include <string.h>
#include <Wbemidl.h>
#include <comdef.h>
#ifndef Assert /** @todo r=bird: where would this be defined? */
//# ifdef DEBUG
//# define Assert(_expr) assert(_expr)
//# else
//# define Assert(_expr) do{ }while (0)
//# endif
#endif
#define NonStandardLog DoLogging
#define NonStandardLogFlow(x) DoLogging x
#define DbgLog /** @todo r=bird: What does this do? */
{
{
return hr;
}
{
NonStandardLogFlow(("Write lock busy\n"));
}
{
}
return hr;
}
{
{
return hr;
}
return hr;
}
{
HRESULT hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNetCfg);
{
return hr;
}
if (fGetWriteLock)
{
{
}
}
{
{
return S_OK;
}
else
}
return hr;
}
{
if (!pNetCfg) /* If network config has been released already, just bail out. */
{
NonStandardLogFlow(("Warning: No network config given but write lock is set to TRUE\n"));
return S_OK;
}
{
/* Try to release the write lock below. */
}
if (fHasWriteLock)
{
}
return hr;
}
{
{
return hr;
}
{
{
if (uComponentStatus == 0)
{
{
{
/* found the needed device */
break;
}
}
else
}
}
}
return hr;
}
{
{
{
NonStandardLogFlow(("Component not found\n"));
}
{
}
}
else
return hr;
}
static HRESULT vboxNetCfgWinQueryInstaller(IN INetCfg *pNetCfg, IN const GUID *pguidClass, INetCfgClassSetup **ppSetup)
{
return hr;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
{
{
return hr;
}
0, /* IN DWORD dwSetupFlags */
0, /* IN DWORD dwUpgradeFromBuildNo */
NULL, /* IN LPCWSTR pszwAnswerFile */
NULL, /* IN LPCWSTR pszwAnswerSections */
{
/* ignore the apply failure */
}
else
return hr;
}
static HRESULT vboxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
{
UINT cFilesProcessed = 0;
{
{
break;
}
}
{
}
{
NonStandardLogFlow(("Installation failed, rolling back installation set ...\n"));
do
{
/* Keep going. */
if (!cFilesProcessed)
break;
} while (cFilesProcessed--);
NonStandardLogFlow(("Rollback complete\n"));
}
return hr;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallComponent(IN INetCfg *pNetCfg, IN INetCfgComponent *pComponent)
{
{
return hr;
}
{
return hr;
}
{
}
else
if (pSetup)
return hr;
}
typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNetCfg, IN INetCfgComponent *pNetCfgComponent, PVOID pContext);
{
{
do
{
{
// ULONG uComponentStatus;
// hr = pNcc->GetDeviceStatus(&uComponentStatus);
// if (SUCCEEDED(hr))
if (pNetCfgComponent)
{
if (pContext)
}
if (!fResult)
break;
}
else
{
{
}
else
break;
}
} while (true);
}
return hr;
}
/*
* Forward declarations of functions used in vboxNetCfgWinRemoveAllNetDevicesOfIdCallback.
*/
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf);
static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
{
{
{
/* Figure out NetCfgInstanceId. */
pDev,
0,
KEY_READ);
if (hKey == INVALID_HANDLE_VALUE)
{
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiOpenDevRegKey failed with error %ld\n",
GetLastError()));
}
else
{
if (ret == ERROR_SUCCESS)
{
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: Processing device ID \"%S\"\n",
/* Figure out device name. */
SPDRP_FRIENDLYNAME, /* IN DWORD Property,*/
NULL, /* OUT PDWORD PropertyRegDataType, OPTIONAL*/
sizeof(wszDevName), /* IN DWORD PropertyBufferSize,*/
NULL /* OUT PDWORD RequiredSize OPTIONAL*/))
{
/*
* Rename the connection before removing the device. This will
* hopefully prevent an error when we will be attempting
* to rename a newly created connection (see @bugref{6740}).
*/
//NonStandardLogFlow(("VBoxNetCfgWinRenameConnection(%S,%S) => 0x%x\n", pWCfgGuidString, TempName, hr_tmp));
}
else
{
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: Failed to get friendly name for device \"%S\"\n",
}
}
else
{
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: Querying instance ID failed with %d\n",
ret));
}
}
{
{
{
NonStandardLog(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: A reboot is required\n"));
}
}
else
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiGetDeviceInstallParams failed with %ld\n",
GetLastError()));
}
else
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed with %ld\n",
GetLastError()));
}
else
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetSelectedDevice failed with %ld\n",
GetLastError()));
}
else
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetClassInstallParams failed with %ld\n",
GetLastError()));
/* Continue enumeration. */
return TRUE;
}
typedef struct VBOXNECTFGWINPROPCHANGE
{
static BOOL vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
{
{
break;
break;
default:
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: Unexpected prop change type: %d\n", pPc->enmPcType));
return FALSE;
}
{
{
{
{
{
NonStandardLog(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: A reboot is required\n"));
}
}
else
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: SetupDiGetDeviceInstallParams failed with %ld\n",
GetLastError()));
}
else
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed with %ld\n",
GetLastError()));
}
else
}
else
/* Continue enumeration. */
return TRUE;
}
typedef BOOL (*VBOXNETCFGWIN_NETENUM_CALLBACK) (HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext);
{
NULL, /* IN PCTSTR Enumerator, OPTIONAL */
NULL, /* IN HWND hwndParent, OPTIONAL */
DIGCF_PRESENT, /* IN DWORD Flags,*/
NULL, /* IN HDEVINFO DeviceInfoSet, OPTIONAL */
NULL, /* IN PCTSTR MachineName, OPTIONAL */
NULL /* IN PVOID Reserved */);
if (hDevInfo != INVALID_HANDLE_VALUE)
{
for (;;)
{
{
winEr = GetLastError();
if (winEr == ERROR_NO_MORE_ITEMS)
break;
}
dwDevId++;
if (pBuffer)
DWORD cbRequired = 0;
SPDRP_HARDWAREID, /* IN DWORD Property */
NULL, /* OUT PDWORD PropertyRegDataType OPTIONAL */
pBuffer, /* OUT PBYTE PropertyBuffer */
cbBuffer, /* IN DWORD PropertyBufferSize */
&cbRequired /* OUT PDWORD RequiredSize OPTIONAL */))
{
winEr = GetLastError();
if (winEr != ERROR_INSUFFICIENT_BUFFER)
{
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed with %ld\n", winEr));
break;
}
if (!pBuffer)
{
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: Out of memory allocating %ld bytes\n",
cbRequired));
break;
}
SPDRP_HARDWAREID, /* IN DWORD Property */
NULL, /* OUT PDWORD PropertyRegDataType, OPTIONAL */
pBuffer, /* OUT PBYTE PropertyBuffer */
cbBuffer, /* IN DWORD PropertyBufferSize */
&cbRequired /* OUT PDWORD RequiredSize OPTIONAL */))
{
winEr = GetLastError();
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed with %ld\n",
winEr));
break;
}
}
{
{
break;
}
}
}
if (pBuffer)
}
else
{
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: SetupDiGetClassDevsExW failed with %ld\n", winEr));
}
return hr;
}
{
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinPropChangeAllNetDevicesOfId(IN LPCWSTR lpszPnPId, VBOXNECTFGWINPROPCHANGE_TYPE enmPcType)
{
HRESULT hr = VBoxNetCfgWinEnumNetDevices(lpszPnPId, vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback, &Pc);
{
return hr;
}
{
}
return S_OK;
}
/*
* logging
*/
{
if (pfnRoutine)
{
char szBuffer[4096] = {0};
}
}
{
}
/*
* IP configuration API
*/
/* network settings config */
/**
* Strong referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>.
*/
template <class C>
class ComStrongRef
{
protected:
};
/**
* Base template for smart COM pointers. Not intended to be used directly.
*/
class ComPtrBase : protected RefOps <C>
{
public:
/* special template to disable AddRef()/Release() */
template <class I>
class NoAddRefRelease : public I
{
private:
#if !defined (VBOX_WITH_XPCOM)
#else /* !defined (VBOX_WITH_XPCOM) */
#endif /* !defined (VBOX_WITH_XPCOM) */
};
protected:
ComPtrBase () : p (NULL) {}
~ComPtrBase() { release(); }
{
safe_assign (that.p);
return *this;
}
ComPtrBase &operator= (C *that_p)
{
return *this;
}
public:
void setNull()
{
release();
p = NULL;
}
bool isNull() const
{
return (p == NULL);
}
bool operator! () const { return isNull(); }
template <class I>
{
return ComPtrEquals (p, aThat);
}
template <class OC>
{
}
/** Intended to pass instances as in parameters to interface methods */
operator C* () const { return p; }
/**
* Dereferences the instance (redirects the -> operator to the managed
* pointer).
*/
NoAddRefRelease <C> *operator-> () const
{
AssertMsg (p, ("Managed pointer must not be null\n"));
return (NoAddRefRelease <C> *) p;
}
template <class I>
{
if (pp)
{
if (p)
{
}
else
{
return S_OK;
}
}
return E_INVALIDARG;
}
/** Intended to pass instances as out parameters to interface methods */
C **asOutParam()
{
setNull();
return &p;
}
private:
void addref()
{
if (p)
}
void release()
{
if (p)
}
void safe_assign (C *that_p)
{
/* be aware of self-assignment */
if (that_p)
release();
p = that_p;
}
C *p;
};
/**
* Smart COM pointer wrapper that automatically manages refcounting of
* interface pointers.
*
* @param I COM interface class
*/
{
public:
{
return *this;
}
template <class OI>
/* specialization for I */
template <class OC>
template <class OI>
{
if (that_p)
else
return *this;
}
/* specialization for I */
{
return *this;
}
template <class OC>
{
}
};
static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const GUID * pGuid, IWbemClassObject **pAdapterConfig)
{
if (length)
{
swprintf(wszQuery, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"%s\"", wszGuid);
hr = pSvc->ExecQuery(bstr_t("WQL"), bstr_t(wszQuery), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnumerator);
{
if (pEnumerator)
{
NonStandardLogFlow(("netIfWinFindAdapterClassById: IEnumWbemClassObject::Next -> hr=0x%x pclsObj=%p uReturn=%u 42=%u\n",
{
{
pEnumerator->Release();
return S_OK;
}
}
pEnumerator->Release();
}
else
{
NonStandardLogFlow(("ExecQuery returned no enumerator\n"));
}
}
else
}
else
{
}
return hr;
}
{
HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0 /*lFlags*/, &vtServiceName, NULL /*pvtType*/, NULL /*plFlavor*/);
{
}
return hr;
}
static HRESULT netIfWinGetIpSettings(IWbemClassObject * pAdapterConfig, ULONG *pIpv4, ULONG *pMaskv4)
{
VariantInit(&vtIp);
*pIpv4 = 0;
*pMaskv4 = 0;
{
{
{
{
if (pIpArray && pMaskArray)
{
for (LONG i = 0;
i++)
{
if (Ipv4 != INADDR_NONE)
{
break;
}
}
}
}
else
{
*pIpv4 = 0;
*pMaskv4 = 0;
}
}
}
else
{
*pIpv4 = 0;
*pMaskv4 = 0;
}
VariantClear(&vtIp);
}
return hr;
}
static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound)
{
VariantInit(&vtIp);
*pFound = false;
{
{
if (pIpArray && pMaskArray)
{
for (LONG k = 0;
k++)
{
for (LONG i = 0;
i++)
{
{
*pFound = true;
break;
}
}
}
}
}
VariantClear(&vtIp);
}
return hr;
}
static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound)
{
/* on Vista we need to wait for the address to get applied */
/* wait for the address to appear in the list */
ULONG i;
*pFound = false;
for (i = 0;
&& !(*pFound)
&& i < sec2Wait/6;
i++)
{
Sleep(6000);
}
return hr;
}
{
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
{
NULL, /* [in] const BSTR strUser */
NULL, /* [in] const BSTR strPassword */
0, /* [in] const BSTR strLocale */
NULL, /* [in] LONG lSecurityFlags */
0, /* [in] const BSTR strAuthority */
0, /* [in] IWbemContext* pCtx */
&pSvc /* [out] IWbemServices** ppNamespace */);
{
RPC_C_AUTHN_WINNT, /* DWORD dwAuthnSvc */
RPC_C_AUTHZ_NONE, /* DWORD dwAuthzSvc */
NULL, /* WCHAR * pServerPrincName */
RPC_C_AUTHN_LEVEL_CALL, /* DWORD dwAuthnLevel */
RPC_C_IMP_LEVEL_IMPERSONATE, /* DWORD dwImpLevel */
NULL, /* RPC_AUTH_IDENTITY_HANDLE pAuthInfo */
EOAC_NONE /* DWORD dwCapabilities */
);
{
/* do not need it any more */
return hr;
}
else
}
else
}
else
return hr;
}
{
{
}
else
return hr;
}
)
{
if (cArgs)
{
{
{
{
pArgs[i], 0);
break;
}
}
}
}
{
{
}
}
return hr;
}
{
if (pIpArray)
{
{
long aIndex[1];
aIndex[0] = i;
{
break;
}
}
{
}
}
else
return hr;
}
{
if (pIpArray)
{
long aIndex[1];
aIndex[0] = 0;
{
}
{
}
}
else
return hr;
}
{
{
}
return hr;
}
{
{
}
return hr;
}
static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask)
{
if (ClassName)
{
{
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam());
{
&varReturnValue, NULL, 0);
{
// Assert(varReturnValue.vt == VT_UINT);
switch (winEr)
{
case 0:
{
// bool bFound;
// HRESULT tmpHr = netIfWinWaitIpSettings(pSvc, pGuid, pIp->parray, pMask->parray, 180, &bFound);
}
break;
default:
break;
}
}
}
}
}
else
return hr;
}
static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp)
{
{
{
}
}
return hr;
}
static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, BSTR Ip, BSTR Mask)
{
{
{
}
}
return hr;
}
/* win API allows to set gw metrics as well, we are not setting them */
{
if (ClassName)
{
{
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
{
{
// Assert(varReturnValue.vt == VT_UINT);
switch (winEr)
{
case 0:
break;
default:
break;
}
}
}
}
}
else
return hr;
}
/* win API allows to set gw metrics as well, we are not setting them */
{
{
}
return hr;
}
/* win API allows to set gw metrics as well, we are not setting them */
{
{
VariantClear(&vGw);
}
return hr;
}
{
if (ClassName)
{
{
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
{
&varReturnValue, NULL, 0);
{
// Assert(varReturnValue.vt == VT_UINT);
switch (winEr)
{
case 0:
break;
default:
break;
}
}
}
}
}
else
return hr;
}
{
if (ClassName)
{
{
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
{
{
// Assert(varReturnValue.vt == VT_UINT);
if (winEr == 0)
{
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
{
{
// Assert(varReturnValue.vt == VT_UINT);
if (winEr == 0)
else
}
}
}
else
}
}
}
}
else
return hr;
}
{
return hr;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(IN const GUID * pGuid, OUT PADAPTER_SETTINGS pSettings)
{
{
{
}
}
return hr;
}
{
{
{
}
}
return hr;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(IN const GUID *pGuid, IN ULONG ip, IN ULONG mask)
{
{
{
{
if (bIsHostOnly)
{
{
{
#if 0
#endif
{
}
}
}
}
else
{
}
}
}
}
return hr;
}
#if 0
static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
{
{
{
{
{
if (aIPV6DefaultGateway)
{
}
{
// hr = netIfWinUpdateConfig(pIf);
}
}
}
}
}
}
static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
{
if (RT_SUCCESS(rc))
{
}
return rc;
}
#endif
{
{
{
{
if (bIsHostOnly)
{
{
{
// hr = netIfWinUpdateConfig(pIf);
}
}
}
else
{
}
}
}
}
return hr;
}
{
{
{
{
if (bIsHostOnly)
{
{
{
//hr = netIfWinUpdateConfig(pIf);
}
}
}
else
{
}
}
}
}
return hr;
}
static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, PFNVBOXNETCFG_IPSETTINGS_CALLBACK pfnCallback, PVOID pContext)
{
{
{
do
{
bool fIPFound, fMaskFound;
fIPFound = fMaskFound = false;
{
{
case AF_INET:
fIPFound = true;
sizeof(ip));
break;
// case AF_INET6:
// break;
}
}
{
{
case AF_INET:
if (!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */
break; /* the address values can contain illegal values */
fMaskFound = true;
break;
// case AF_INET6:
// break;
}
}
if (!fIPFound || !fMaskFound)
break;
return;
} while (true);
}
}
}
typedef struct _IPPROBE_CONTEXT
{
bool bConflict;
{
{
return false;
}
return true;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(OUT PULONG pNetIp, OUT PULONG pNetMask)
{
/*
* Most of the hosts probably have less than 10 adapters,
* so we'll mostly succeed from the first attempt.
*/
if (!pAddresses)
if (dwRc == ERROR_BUFFER_OVERFLOW)
{
/* Impressive! More than 10 adapters! Get more memory and try again. */
if (!pAddresses)
}
{
srand(GetTickCount());
*pNetIp = 0;
*pNetMask = 0;
for (int i = 0; i < 255; i++)
{
{
break;
}
}
if (*pNetIp == 0)
}
else
if (pAddresses)
{
}
return hr;
}
/*
*/
#define VBOXNETCFGWIN_NETFLT_ID L"sun_VBoxNetFlt"
#define VBOXNETCFGWIN_NETFLT_MP_ID L"sun_VBoxNetFltmp"
{
{
NonStandardLog("NetFlt is installed currently, uninstalling ...\n");
}
{
NonStandardLog("NetFlt is not installed currently\n");
}
else
{
}
return hr;
}
{
return vboxNetCfgWinNetFltUninstall(pNc, 0);
}
{
{
NonStandardLog("NetFlt will be installed ...\n");
NULL);
}
return hr;
}
/*
* Use the same id as does the old implementation for NDIS 5
* #define VBOXNETCFGWIN_NETLWF_ID L"oracle_VBoxNetLwf"
*/
#define VBOXNETCFGWIN_NETLWF_ID L"sun_VBoxNetFlt"
{
{
NonStandardLog("NetLwf is installed currently, uninstalling ...\n");
}
{
NonStandardLog("NetLwf is not installed currently\n");
}
else
{
}
return hr;
}
{
return vboxNetCfgWinNetLwfUninstall(pNc, 0);
}
{
{
NonStandardLog("NetLwf will be installed ...\n");
1,
NULL);
}
return hr;
}
#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network"
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf)
{
if (pSuffix)
{
}
{
return E_FAIL;
}
if (pSuffix)
{
}
return S_OK;
}
static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority(IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext)
{
/* Get component's binding. */
{
/* Get binding path enumerator reference. */
{
bool bFoundIface = false;
do
{
{
{
do
{
{
{
{
{
bFoundIface = true;
}
}
pNetCfgCompo->Release();
}
else
}
else
{
else
break;
}
} while (!bFoundIface);
}
else
}
else
{
else
break;
}
} while (!bFoundIface);
}
else
}
else
return TRUE;
}
)
{
switch (Notification)
{
case SPFILENOTIFY_TARGETNEWER:
return TRUE;
}
}
/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */
/*
Copyright 2004 by the Massachusetts Institute of Technology
All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the Massachusetts
Institute of Technology (M.I.T.) not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
*/
/**
* Use the IShellFolder API to rename the connection.
*/
{
/* This is the GUID for the network connections folder. It is constant.
* {7007ACC7-3202-11D1-AAD2-00805FC1270E} */
const GUID CLSID_NetworkConnections = {
0x7007ACC7, 0x3202, 0x11D1, {
0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
}
};
/* Build the display name in the form "::{GUID}". */
return E_INVALIDARG;
/* Create an instance of the network connections folder. */
reinterpret_cast<LPVOID *>(&pShellFolder));
/* Parse the display name. */
{
}
{
&pidl);
}
if (pShellFolder)
pShellFolder->Release();
return hr;
}
/**
* Loads a system DLL.
*
* @returns Module handle or NULL
* @param pszName The DLL name.
*/
{
return NULL;
return LoadLibraryA(szPath);
}
{
/* First try the IShellFolder interface, which was unimplemented
* for the network connections folder before XP. */
{
/** @todo that code doesn't seem to work! */
/* The IShellFolder interface is not implemented on this platform.
* Try the (undocumented) HrRenameConnection API in the netshell
* library. */
return E_FAIL;
return E_FAIL;
"HrRenameConnection");
if (RenameConnectionFunc == NULL)
{
return E_FAIL;
}
}
return status;
return S_OK;
}
#define SetErrBreak(strAndArgs) \
if (1) { \
break; \
} else do {} while (0)
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface(IN const GUID *pGUID, OUT BSTR *pErrMsg)
{
do
{
/* We have to find the device instance ID through a registry search */
HKEY hkeyNetwork = 0;
HKEY hkeyConnection = 0;
do
{
if (!length)
SetErrBreak(("Failed to create a Guid string"));
L"SYSTEM\\CurrentControlSet\\Control\\Network\\"
L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s",
wszGuid);
KEY_READ, &hkeyNetwork);
SetErrBreak (("Host interface network is not found in registry (%S) [1]",
SetErrBreak (("Host interface network is not found in registry (%S) [2]",
SetErrBreak (("Host interface network is not found in registry (%S) [3]",
}
while (0);
if (hkeyConnection)
if (hkeyNetwork)
break;
/*
* Now we are going to enumerate all network devices and
* wait until we encounter the right device instance ID
*/
do
{
/* initialize the structure size */
/* copy the net class GUID */
/* return a device info set contains all installed devices of the Net class */
if (hDeviceInfo == INVALID_HANDLE_VALUE)
/* enumerate the driver info list */
while (TRUE)
{
if (!ok)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
else
{
index++;
continue;
}
}
/* try to get the hardware ID registry property */
NULL,
NULL,
0,
&size);
if (!ok)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
index++;
continue;
}
NULL,
size,
NULL);
if (!ok)
{
free (deviceHwid);
deviceHwid = NULL;
index++;
continue;
}
}
else
{
/* something is wrong. This shouldn't have worked with a NULL buffer */
index++;
continue;
}
for (TCHAR *t = deviceHwid;
t += _tcslen (t) + 1)
{
{
/* get the device instance ID */
{
/* compare to what we determined before */
{
break;
}
}
}
}
if (deviceHwid)
{
free (deviceHwid);
deviceHwid = NULL;
}
if (found)
break;
index++;
}
SetErrBreak (("Host Interface Network driver not found (0x%08X)",
GetLastError()));
if (!ok)
SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
GetLastError()));
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
GetLastError()));
}
while (0);
/* clean up the device info set */
if (hDeviceInfo != INVALID_HANDLE_VALUE)
break;
}
while (0);
return hrc;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUpdateHostOnlyNetworkInterface(LPCWSTR pcsxwInf, BOOL *pbRebootRequired, LPCWSTR pcsxwId)
{
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
{
do
{
/* for our purposes, 2k buffer is more
* than enough to obtain the hardware ID
* of the VBoxNetAdp driver. */
/* initialize the structure size */
/* copy the net class GUID */
/* create an empty device info set associated with the net class GUID */
if (hDeviceInfo == INVALID_HANDLE_VALUE)
SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
GetLastError()));
/* get the class name from GUID */
if (!fResult)
SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
GetLastError()));
/* create a device info element and add the new device instance
* key to registry */
if (!fResult)
SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
GetLastError()));
/* select the newly created device info to be the currently
selected member */
if (!fResult)
SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
GetLastError()));
if (pInfPath)
{
/* get the device install parameters and disable filecopy */
if (fResult)
{
{
memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0]));
if (bIsInfPathFile)
{
}
if (!fResult)
{
break;
}
}
else
{
NonStandardLogFlow(("SetupDiSetDeviceInstallParams faileed: INF path is too long\n"));
break;
}
}
else
{
}
}
/* build a list of class drivers */
if (!fResult)
SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
GetLastError()));
destroyList = TRUE;
/* enumerate the driver info list */
while (TRUE)
{
/* if the function failed and GetLastError() returned
* ERROR_NO_MORE_ITEMS, then we have reached the end of the
* list. Otherwise there was something wrong with this
* particular driver. */
if (!ret)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
else
{
index++;
continue;
}
}
/* if we successfully find the hardware ID and it turns out to
* be the one for the loopback driver, then we are done. */
sizeof (detailBuf),
NULL))
{
TCHAR * t;
/* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
* whole list and see if there is a match somewhere. */
t = pDriverInfoDetail->HardwareID;
{
break;
t += _tcslen(t) + 1;
}
{
break;
}
}
index ++;
}
if (!found)
SetErrBreak(("Could not find Host Interface Networking driver! Please reinstall"));
/* set the loopback driver to be the currently selected */
if (!fResult)
SetErrBreak(("SetupDiSetSelectedDriver failed (0x%08X)",
GetLastError()));
/* register the phantom device to prepare for install */
if (!fResult)
{
SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
err));
}
/* registered, but remove if errors occur in the following code */
registered = TRUE;
/* ask the installer if we can install the device */
if (!fResult)
{
if (GetLastError() != ERROR_DI_DO_DEFAULT)
SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
GetLastError()));
/* that's fine */
}
/* get the device install parameters and disable filecopy */
if (fResult)
{
{
if (!fResult)
{
}
}
else
{
}
}
else
{
}
/* install the files first */
if (!fResult)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
GetLastError()));
/* get the device install parameters and disable filecopy */
if (fResult)
{
if (!fResult)
SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
GetLastError()));
}
/*
* Register any device-specific co-installers for this device,
*/
if (!fResult)
SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
GetLastError()));
/*
* install any installer-specified interfaces.
* and then do the real install
*/
if (!fResult)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
GetLastError()));
if (!fResult)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
GetLastError()));
/* Figure out NetCfgInstanceId */
0,
KEY_READ);
if (hkey == INVALID_HANDLE_VALUE)
cbSize = sizeof(pWCfgGuidString);
RegCloseKey (hkey);
SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/
NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
NULL /*OUT PDWORD RequiredSize OPTIONAL*/))
{
int err = GetLastError();
if (err != ERROR_INVALID_DATA)
{
SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
err));
}
SPDRP_DEVICEDESC, /* IN DWORD Property,*/
NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
NULL /*OUT PDWORD RequiredSize OPTIONAL*/
))
{
err = GetLastError();
SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
err));
}
}
}
while (0);
/*
* cleanup
*/
if (hDeviceInfo != INVALID_HANDLE_VALUE)
{
/* an error has occurred, but the device is registered, we must remove it */
if (ret != 0 && registered)
/* destroy the driver info list */
if (destroyList)
/* clean up the device info set */
}
/* return the network connection GUID on success */
{
if (lppszName)
{
if (!*lppszName)
{
NonStandardLogFlow(("SysAllocString failed\n"));
}
}
if (pGuid)
{
}
30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */
/* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */
&lpszApp);
{
pGuid);
{
pGuid);
pGuid);
}
{
}
else
}
{
}
else
}
return hrc;
}