VBoxNetCfg.cpp revision 91000cbe6d6b2158c32ffe4b4bce4890f82fd1ad
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith * VBoxNetCfg.cpp - Network Configuration API.
f8dd5569a14fbf6cf9e64bf54ff0df1752dd33b4Luke Smith * Copyright (C) 2011-2012 Oracle Corporation
98181742b1bd0b4f3d0b25c1abdae58b0506405cJenny Donnelly * This file is part of VirtualBox Open Source Edition (OSE), as
98181742b1bd0b4f3d0b25c1abdae58b0506405cJenny Donnelly * available from http://www.virtualbox.org. This file is free software;
f8dd5569a14fbf6cf9e64bf54ff0df1752dd33b4Luke Smith * you can redistribute it and/or modify it under the terms of the GNU
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith * General Public License (GPL) as published by the Free Software
b997a309ae6157688d370ccbdb9cffe508d8b87cLuke Smith * Foundation, in version 2 as it comes in the "COPYING" file of the
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith#ifndef Assert /** @todo r=bird: where would this be defined? */
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith//# ifdef DEBUG
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith//# define Assert(_expr) assert(_expr)
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith//# define Assert(_expr) do{ }while (0)
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith#define DbgLog /** @todo r=bird: What does this do? */
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith#define VBOX_NETCFG_LOCK_TIME_OUT 5000 /** @todo r=bird: What does this do? */
27788c46ca93d36657566e988e31ed66ec81c227Luke Smithstatic HRESULT vboxNetCfgWinINetCfgLock(IN INetCfg *pNetCfg,
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock);
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith NonStandardLogFlow(("QueryInterface failed, hr (0x%x)\n", hr));
27788c46ca93d36657566e988e31ed66ec81c227Luke Smith hr = pLock->AcquireWriteLock(cmsTimeout, pszwClientDescription, ppszwClientDescription);
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith NonStandardLogFlow(("AcquireWriteLock failed, hr (0x%x)\n", hr));
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smithstatic HRESULT vboxNetCfgWinINetCfgUnlock(IN INetCfg *pNetCfg)
fc898f11f7bdfeda4964ea9d2d1d1ad770a9fdbdLuke Smith HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock);
f8dd5569a14fbf6cf9e64bf54ff0df1752dd33b4Luke Smith NonStandardLogFlow(("QueryInterface failed, hr (0x%x)\n", hr));
f8dd5569a14fbf6cf9e64bf54ff0df1752dd33b4Luke Smith NonStandardLogFlow(("ReleaseWriteLock failed, hr (0x%x)\n", hr));
return hr;
HRESULT hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNetCfg);
return hr;
if (fGetWriteLock)
return S_OK;
return hr;
return S_OK;
if (fHasWriteLock)
return hr;
return hr;
if (uComponentStatus == 0)
return hr;
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;
return hr;
static HRESULT vboxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
if (!cFilesProcessed)
} while (cFilesProcessed--);
return hr;
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallComponent(IN INetCfg *pNetCfg, IN INetCfgComponent *pComponent)
return hr;
return hr;
if (pSetup)
return hr;
typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNetCfg, IN INetCfgComponent *pNetCfgComponent, PVOID pContext);
if (pNetCfgComponent)
if (pContext)
if (!fResult)
return hr;
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf);
static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
pDev,
KEY_READ);
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiOpenDevRegKey failed with error %ld\n",
GetLastError()));
//NonStandardLogFlow(("VBoxNetCfgWinRenameConnection(%S,%S) => 0x%x\n", pWCfgGuidString, TempName, hr_tmp));
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: Failed to get friendly name for device \"%S\"\n",
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: Querying instance ID failed with %d\n",
ret));
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiGetDeviceInstallParams failed with %ld\n",
GetLastError()));
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed with %ld\n",
GetLastError()));
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetSelectedDevice failed with %ld\n",
GetLastError()));
NonStandardLogFlow(("vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetClassInstallParams failed with %ld\n",
GetLastError()));
return TRUE;
typedef struct VBOXNECTFGWINPROPCHANGE
static BOOL vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext)
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: Unexpected prop change type: %d\n", pPc->enmPcType));
return FALSE;
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: SetupDiGetDeviceInstallParams failed with %ld\n",
GetLastError()));
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed with %ld\n",
GetLastError()));
return TRUE;
typedef BOOL (*VBOXNETCFGWIN_NETENUM_CALLBACK) (HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext);
dwDevID++;
if (pBuffer)
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed with %ld\n", winEr));
if (!pBuffer)
cbRequired));
NonStandardLogFlow(("VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed with %ld\n",
winEr));
if (pBuffer)
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;
if (pfnRoutine)
class ComStrongRef
class NoAddRefRelease : public I
#if !defined (VBOX_WITH_XPCOM)
void setNull()
release();
p = NULL;
bool isNull() const
return (p == NULL);
bool operator! () const { return isNull(); }
template <class OC>
NoAddRefRelease <C> *operator-> () const
return (NoAddRefRelease <C> *) p;
if (pp)
return S_OK;
return E_INVALIDARG;
C **asOutParam()
setNull();
void addref()
void release()
if (that_p)
release();
p = that_p;
template <class OI>
template <class OC>
template <class OI>
if (that_p)
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,
if (pEnumerator)
NonStandardLogFlow(("netIfWinFindAdapterClassById: IEnumWbemClassObject::Next -> hr=0x%x pclsObj=%p uReturn=%u 42=%u\n",
return S_OK;
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)
*pIpv4 = 0;
*pMaskv4 = 0;
for (LONG i = 0;
*pIpv4 = 0;
*pMaskv4 = 0;
*pIpv4 = 0;
*pMaskv4 = 0;
return hr;
static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound)
*pFound = false;
for (LONG k = 0;
for (LONG i = 0;
*pFound = true;
return hr;
static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound)
ULONG i;
*pFound = false;
&& !(*pFound)
return hr;
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
return hr;
return hr;
return hr;
if (cArgs)
pArgs[i], 0);
return hr;
if (pIpArray)
aIndex[0] = i;
return hr;
if (pIpArray)
aIndex[0] = 0;
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());
switch (winEr)
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;
if (ClassName)
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
switch (winEr)
return hr;
return hr;
return hr;
if (ClassName)
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
switch (winEr)
return hr;
if (ClassName)
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
if (winEr == 0)
hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
if (winEr == 0)
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)
return hr;
static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
if (aIPV6DefaultGateway)
static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
return rc;
if (bIsHostOnly)
return hr;
if (bIsHostOnly)
return hr;
static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, PFNVBOXNETCFG_IPSETTINGS_CALLBACK pfnCallback, PVOID pContext)
case AF_INET:
fIPFound = true;
sizeof(ip));
case AF_INET:
if (!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */
fMaskFound = true;
typedef struct _IPPROBE_CONTEXT
bool bConflict;
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(OUT PULONG pNetIp, OUT PULONG pNetMask)
if (!pAddresses)
if (!pAddresses)
*pNetIp = 0;
*pNetMask = 0;
if (*pNetIp == 0)
if (pAddresses)
return hr;
return hr;
NULL);
return hr;
return hr;
NULL);
return hr;
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)
bool bFoundIface = false;
bFoundIface = true;
} while (!bFoundIface);
} while (!bFoundIface);
return TRUE;
switch (Notification)
case SPFILENOTIFY_TARGETNEWER:
return TRUE;
/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */
return E_INVALIDARG;
&pidl);
if (pShellFolder)
return hr;
return NULL;
return E_FAIL;
return E_FAIL;
return E_FAIL;
return status;
return S_OK;
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface(IN const GUID *pGUID, OUT BSTR *pErrMsg)
if (!length)
wszGuid);
if (hkeyConnection)
if (hkeyNetwork)
while (TRUE)
if (!ok)
index++;
NULL,
NULL,
&size);
if (!ok)
index++;
NULL,
size,
NULL);
if (!ok)
index++;
index++;
if (deviceHwid)
if (found)
index++;
GetLastError()));
if (!ok)
GetLastError()));
if (!ok)
GetLastError()));
return hrc;
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUpdateHostOnlyNetworkInterface(LPCWSTR pcsxwInf, BOOL *pbRebootRequired)
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
GetLastError()));
if (!fResult)
GetLastError()));
if (!fResult)
GetLastError()));
if (!fResult)
GetLastError()));
if (pInfPath)
if (fResult)
memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0]));
if (bIsInfPathFile)
if (!fResult)
if (!fResult)
GetLastError()));
while (TRUE)
if (!ret)
index++;
sizeof (detailBuf),
NULL))
TCHAR * t;
index ++;
if (!found)
if (!fResult)
GetLastError()));
if (!fResult)
err));
if (!fResult)
GetLastError()));
if (fResult)
if (!fResult)
if (!fResult)
GetLastError()));
if (fResult)
if (!fResult)
GetLastError()));
if (!fResult)
GetLastError()));
if (!fResult)
GetLastError()));
if (!fResult)
GetLastError()));
KEY_READ);
err));
err));
if (destroyList)
if (lppszName)
if (!*lppszName)
if (pGuid)
&lpszApp);
pGuid);
pGuid);
pGuid);
return hrc;