summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/win/NetIf-win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-server/win/NetIf-win.cpp')
-rw-r--r--src/VBox/Main/src-server/win/NetIf-win.cpp1528
1 files changed, 1528 insertions, 0 deletions
diff --git a/src/VBox/Main/src-server/win/NetIf-win.cpp b/src/VBox/Main/src-server/win/NetIf-win.cpp
new file mode 100644
index 000000000..0225818ad
--- /dev/null
+++ b/src/VBox/Main/src-server/win/NetIf-win.cpp
@@ -0,0 +1,1528 @@
+/* $Id: NetIf-win.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
+/** @file
+ * Main - NetIfList, Windows implementation.
+ */
+
+/*
+ * Copyright (C) 2008-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * 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.
+ */
+
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_MAIN
+
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <list>
+
+#define _WIN32_DCOM
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#ifdef VBOX_WITH_NETFLT
+#include "VBox/WinNetConfig.h"
+#include "devguid.h"
+#endif
+
+#include <iphlpapi.h>
+
+#include "Logging.h"
+#include "HostNetworkInterfaceImpl.h"
+#include "ProgressImpl.h"
+#include "VirtualBoxImpl.h"
+#include "netif.h"
+
+#ifdef VBOX_WITH_NETFLT
+#include <Wbemidl.h>
+#include <comdef.h>
+
+#include "svchlp.h"
+
+#include <shellapi.h>
+#define INITGUID
+#include <guiddef.h>
+#include <devguid.h>
+#include <objbase.h>
+#include <setupapi.h>
+#include <shlobj.h>
+#include <cfgmgr32.h>
+
+#define VBOX_APP_NAME L"VirtualBox"
+
+static int getDefaultInterfaceIndex()
+{
+ PMIB_IPFORWARDTABLE pIpTable;
+ DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
+ DWORD dwRC = NO_ERROR;
+ int iIndex = -1;
+
+ pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
+ if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
+ {
+ RTMemFree(pIpTable);
+ pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
+ if (!pIpTable)
+ return -1;
+ }
+ dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
+ if (dwRC == NO_ERROR)
+ {
+ for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
+ if (pIpTable->table[i].dwForwardDest == 0)
+ {
+ iIndex = pIpTable->table[i].dwForwardIfIndex;
+ break;
+ }
+ }
+ RTMemFree(pIpTable);
+ return iIndex;
+}
+
+static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
+{
+ DWORD dwRc;
+ int rc = VINF_SUCCESS;
+ /*
+ * Most of the hosts probably have less than 10 adapters,
+ * so we'll mostly succeed from the first attempt.
+ */
+ ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
+ PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
+ if (!pAddresses)
+ return VERR_NO_MEMORY;
+ dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
+ if (dwRc == ERROR_BUFFER_OVERFLOW)
+ {
+ /* Impressive! More than 10 adapters! Get more memory and try again. */
+ RTMemFree(pAddresses);
+ pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
+ if (!pAddresses)
+ return VERR_NO_MEMORY;
+ dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
+ }
+ if (dwRc == NO_ERROR)
+ {
+ PIP_ADAPTER_ADDRESSES pAdapter;
+ for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
+ {
+ char *pszUuid = RTStrDup(pAdapter->AdapterName);
+ size_t len = strlen(pszUuid) - 1;
+ if (pszUuid[0] == '{' && pszUuid[len] == '}')
+ {
+ pszUuid[len] = 0;
+ if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
+ {
+ bool fIPFound, fIPv6Found;
+ PIP_ADAPTER_UNICAST_ADDRESS pAddr;
+ fIPFound = fIPv6Found = false;
+ for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
+ {
+ switch (pAddr->Address.lpSockaddr->sa_family)
+ {
+ case AF_INET:
+ if (!fIPFound)
+ {
+ fIPFound = true;
+ memcpy(&pInfo->IPAddress,
+ &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
+ sizeof(pInfo->IPAddress));
+ }
+ break;
+ case AF_INET6:
+ if (!fIPv6Found)
+ {
+ fIPv6Found = true;
+ memcpy(&pInfo->IPv6Address,
+ ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
+ sizeof(pInfo->IPv6Address));
+ }
+ break;
+ }
+ }
+ PIP_ADAPTER_PREFIX pPrefix;
+ fIPFound = fIPv6Found = false;
+ for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
+ {
+ switch (pPrefix->Address.lpSockaddr->sa_family)
+ {
+ case AF_INET:
+ if (!fIPFound)
+ {
+ if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
+ {
+ fIPFound = true;
+ ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
+ }
+ else
+ Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
+ pPrefix->PrefixLength));
+ }
+ break;
+ case AF_INET6:
+ if (!fIPv6Found)
+ {
+ if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
+ {
+ fIPv6Found = true;
+ ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
+ }
+ else
+ Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
+ pPrefix->PrefixLength));
+ }
+ break;
+ }
+ }
+ if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
+ Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
+ else
+ memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
+ pInfo->enmMediumType = NETIF_T_ETHERNET;
+ pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
+ pInfo->bIsDefault = (pAdapter->IfIndex == iDefault);
+ RTStrFree(pszUuid);
+ break;
+ }
+ }
+ RTStrFree(pszUuid);
+ }
+
+ ADAPTER_SETTINGS Settings;
+ HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
+ if (hr == S_OK)
+ {
+ if (Settings.ip)
+ {
+ pInfo->IPAddress.u = Settings.ip;
+ pInfo->IPNetMask.u = Settings.mask;
+ }
+ pInfo->bDhcpEnabled = Settings.bDhcp;
+ }
+ else
+ {
+ pInfo->bDhcpEnabled = false;
+ }
+ }
+ RTMemFree(pAddresses);
+
+ return VINF_SUCCESS;
+}
+
+/* svc helper func */
+
+struct StaticIpConfig
+{
+ ULONG IPAddress;
+ ULONG IPNetMask;
+};
+
+struct StaticIpV6Config
+{
+ BSTR IPV6Address;
+ ULONG IPV6NetMaskLength;
+};
+
+struct NetworkInterfaceHelperClientData
+{
+ SVCHlpMsg::Code msgCode;
+ /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
+ Bstr name;
+ ComObjPtr<HostNetworkInterface> iface;
+ ComObjPtr<VirtualBox> vBox;
+ /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
+ Guid guid;
+
+ union
+ {
+ StaticIpConfig StaticIP;
+ StaticIpV6Config StaticIPV6;
+ } u;
+
+
+};
+
+static HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
+ Progress *aProgress,
+ void *aUser, int *aVrc)
+{
+ LogFlowFuncEnter();
+ LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
+ aClient, aProgress, aUser));
+
+ AssertReturn( (aClient == NULL && aProgress == NULL && aVrc == NULL)
+ || (aClient != NULL && aProgress != NULL && aVrc != NULL),
+ E_POINTER);
+ AssertReturn(aUser, E_POINTER);
+
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(static_cast<NetworkInterfaceHelperClientData *>(aUser));
+
+ if (aClient == NULL)
+ {
+ /* "cleanup only" mode, just return (it will free aUser) */
+ return S_OK;
+ }
+
+ HRESULT rc = S_OK;
+ int vrc = VINF_SUCCESS;
+
+ switch (d->msgCode)
+ {
+ case SVCHlpMsg::CreateHostOnlyNetworkInterface:
+ {
+ LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
+ LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+// vrc = aClient->write(Utf8Str(d->name));
+// if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
+ {
+ /* read the GUID */
+ Guid guid;
+ Utf8Str name;
+ vrc = aClient->read(name);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+
+ LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
+
+ /* initialize the object returned to the caller by
+ * CreateHostOnlyNetworkInterface() */
+ rc = d->iface->init(Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
+ if (SUCCEEDED(rc))
+ {
+ rc = d->iface->setVirtualBox(d->vBox);
+ if (SUCCEEDED(rc))
+ {
+ rc = d->iface->updateConfig();
+ }
+ }
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL;//TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
+ {
+ LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
+ LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->guid);
+ if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::OK:
+ {
+ /* no parameters */
+ rc = S_OK;
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
+ {
+ LogFlowFunc(("EnableDynamicIpConfig:\n"));
+ LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->guid);
+ if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::OK:
+ {
+ /* no parameters */
+ rc = d->iface->updateConfig();
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
+ {
+ LogFlowFunc(("EnableStaticIpConfig:\n"));
+ LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->guid);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->u.StaticIP.IPAddress);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->u.StaticIP.IPNetMask);
+ if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::OK:
+ {
+ /* no parameters */
+ rc = d->iface->updateConfig();
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
+ {
+ LogFlowFunc(("EnableStaticIpConfigV6:\n"));
+ LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->guid);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(Utf8Str(d->u.StaticIPV6.IPV6Address));
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->u.StaticIPV6.IPV6NetMaskLength);
+ if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::OK:
+ {
+ /* no parameters */
+ rc = d->iface->updateConfig();
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ case SVCHlpMsg::DhcpRediscover: /* see usage in code */
+ {
+ LogFlowFunc(("DhcpRediscover:\n"));
+ LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
+
+ /* write message and parameters */
+ vrc = aClient->write(d->msgCode);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(d->guid);
+ if (RT_FAILURE(vrc)) break;
+
+ /* wait for a reply */
+ bool endLoop = false;
+ while (!endLoop)
+ {
+ SVCHlpMsg::Code reply = SVCHlpMsg::Null;
+
+ vrc = aClient->read(reply);
+ if (RT_FAILURE(vrc)) break;
+
+ switch (reply)
+ {
+ case SVCHlpMsg::OK:
+ {
+ /* no parameters */
+ rc = d->iface->updateConfig();
+ endLoop = true;
+ break;
+ }
+ case SVCHlpMsg::Error:
+ {
+ /* read the error message */
+ Utf8Str errMsg;
+ vrc = aClient->read(errMsg);
+ if (RT_FAILURE(vrc)) break;
+
+ rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
+ endLoop = true;
+ break;
+ }
+ default:
+ {
+ endLoop = true;
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+ //"Invalid message code %d (%08lX)\n",
+ //reply, reply),
+ //rc = E_FAIL);
+ }
+ }
+ }
+
+ break;
+ }
+ default:
+ rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
+// "Invalid message code %d (%08lX)\n",
+// d->msgCode, d->msgCode),
+// rc = E_FAIL);
+ }
+
+ if (aVrc)
+ *aVrc = vrc;
+
+ LogFlowFunc(("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
+ LogFlowFuncLeave();
+ return rc;
+}
+
+
+int netIfNetworkInterfaceHelperServer(SVCHlpClient *aClient,
+ SVCHlpMsg::Code aMsgCode)
+{
+ LogFlowFuncEnter();
+ LogFlowFunc(("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
+
+ AssertReturn(aClient, VERR_INVALID_POINTER);
+
+ int vrc = VINF_SUCCESS;
+ HRESULT hrc;
+
+ switch (aMsgCode)
+ {
+ case SVCHlpMsg::CreateHostOnlyNetworkInterface:
+ {
+ LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
+
+// Utf8Str name;
+// vrc = aClient->read(name);
+// if (RT_FAILURE(vrc)) break;
+
+ Guid guid;
+ Utf8Str errMsg;
+ Bstr name;
+ Bstr bstrErr;
+
+ hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), name.asOutParam(), bstrErr.asOutParam());
+
+ if (hrc == S_OK)
+ {
+ ULONG ip, mask;
+ hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
+ if (hrc == S_OK)
+ {
+ /* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
+ * i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter */
+ ip = ip | (1 << 24);
+ hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
+ }
+
+ /* write success followed by GUID */
+ vrc = aClient->write(SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(Utf8Str(name));
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(guid);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ vrc = VERR_GENERAL_FAILURE;
+ errMsg = Utf8Str(bstrErr);
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
+ {
+ LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
+
+ Guid guid;
+ Bstr bstrErr;
+
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+
+ Utf8Str errMsg;
+ hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
+
+ if (hrc == S_OK)
+ {
+ /* write parameter-less success */
+ vrc = aClient->write(SVCHlpMsg::OK);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ vrc = VERR_GENERAL_FAILURE;
+ errMsg = Utf8Str(bstrErr);
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableStaticIpConfigV6:
+ {
+ LogFlowFunc(("EnableStaticIpConfigV6:\n"));
+
+ Guid guid;
+ Utf8Str ipV6;
+ ULONG maskLengthV6;
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->read(ipV6);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->read(maskLengthV6);
+ if (RT_FAILURE(vrc)) break;
+
+ Utf8Str errMsg;
+ vrc = VERR_NOT_IMPLEMENTED;
+
+ if (RT_SUCCESS(vrc))
+ {
+ /* write success followed by GUID */
+ vrc = aClient->write(SVCHlpMsg::OK);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableStaticIpConfig:
+ {
+ LogFlowFunc(("EnableStaticIpConfig:\n"));
+
+ Guid guid;
+ ULONG ip, mask;
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->read(ip);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->read(mask);
+ if (RT_FAILURE(vrc)) break;
+
+ Utf8Str errMsg;
+ hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
+
+ if (hrc == S_OK)
+ {
+ /* write success followed by GUID */
+ vrc = aClient->write(SVCHlpMsg::OK);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ vrc = VERR_GENERAL_FAILURE;
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ case SVCHlpMsg::EnableDynamicIpConfig:
+ {
+ LogFlowFunc(("EnableDynamicIpConfig:\n"));
+
+ Guid guid;
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+
+ Utf8Str errMsg;
+ hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
+
+ if (hrc == S_OK)
+ {
+ /* write success followed by GUID */
+ vrc = aClient->write(SVCHlpMsg::OK);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ vrc = VERR_GENERAL_FAILURE;
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ case SVCHlpMsg::DhcpRediscover:
+ {
+ LogFlowFunc(("DhcpRediscover:\n"));
+
+ Guid guid;
+ vrc = aClient->read(guid);
+ if (RT_FAILURE(vrc)) break;
+
+ Utf8Str errMsg;
+ hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
+
+ if (hrc == S_OK)
+ {
+ /* write success followed by GUID */
+ vrc = aClient->write(SVCHlpMsg::OK);
+ if (RT_FAILURE(vrc)) break;
+ }
+ else
+ {
+ vrc = VERR_GENERAL_FAILURE;
+ /* write failure followed by error message */
+ if (errMsg.isEmpty())
+ errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
+ vrc = aClient->write(SVCHlpMsg::Error);
+ if (RT_FAILURE(vrc)) break;
+ vrc = aClient->write(errMsg);
+ if (RT_FAILURE(vrc)) break;
+ }
+
+ break;
+ }
+ default:
+ AssertMsgFailedBreakStmt(
+ ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
+ VERR_GENERAL_FAILURE);
+ }
+
+ LogFlowFunc(("vrc=%Rrc\n", vrc));
+ LogFlowFuncLeave();
+ return vrc;
+}
+
+/** @todo REMOVE. OBSOLETE NOW. */
+/**
+ * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
+ * later OSes) and it has the UAC (User Account Control) feature enabled.
+ */
+static BOOL IsUACEnabled()
+{
+ LONG rc = 0;
+
+ OSVERSIONINFOEX info;
+ ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
+ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ rc = GetVersionEx((OSVERSIONINFO *) &info);
+ AssertReturn(rc != 0, FALSE);
+
+ LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
+ info.dwMajorVersion, info.dwMinorVersion));
+
+ /* we are interested only in Vista (and newer versions...). In all
+ * earlier versions UAC is not present. */
+ if (info.dwMajorVersion < 6)
+ return FALSE;
+
+ /* the default EnableLUA value is 1 (Enabled) */
+ DWORD dwEnableLUA = 1;
+
+ HKEY hKey;
+ rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
+ 0, KEY_QUERY_VALUE, &hKey);
+
+ Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
+ if (rc == ERROR_SUCCESS)
+ {
+
+ DWORD cbEnableLUA = sizeof(dwEnableLUA);
+ rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
+ (LPBYTE) &dwEnableLUA, &cbEnableLUA);
+
+ RegCloseKey(hKey);
+
+ Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
+ }
+
+ LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
+
+ return dwEnableLUA == 1;
+}
+
+/* end */
+
+static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
+ INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
+ int iDefaultInterface)
+{
+ LPWSTR lpszName;
+ GUID IfGuid;
+ HRESULT hr;
+ int rc = VERR_GENERAL_FAILURE;
+
+ hr = pncc->GetDisplayName(&lpszName);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ Bstr name(lpszName);
+
+ hr = pncc->GetInstanceGuid(&IfGuid);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ NETIFINFO Info;
+ memset(&Info, 0, sizeof(Info));
+ Info.Uuid = *(Guid(IfGuid).raw());
+ rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
+ if (RT_FAILURE(rc))
+ {
+ Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
+ }
+ /* create a new object and add it to the list */
+ ComObjPtr<HostNetworkInterface> iface;
+ iface.createObject();
+ /* remove the curly bracket at the end */
+ if (SUCCEEDED(iface->init(name, enmType, &Info)))
+ {
+ if (Info.bIsDefault)
+ pPist->push_front(iface);
+ else
+ pPist->push_back(iface);
+ rc = VINF_SUCCESS;
+ }
+ else
+ {
+ Assert(0);
+ }
+ }
+ CoTaskMemFree(lpszName);
+ }
+
+ return rc;
+}
+
+#endif /* VBOX_WITH_NETFLT */
+
+
+static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
+{
+#ifndef VBOX_WITH_NETFLT
+ /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
+ return VERR_NOT_IMPLEMENTED;
+#else /* # if defined VBOX_WITH_NETFLT */
+ INetCfg *pNc;
+ INetCfgComponent *pMpNcc;
+ LPWSTR lpszApp = NULL;
+ HRESULT hr;
+ IEnumNetCfgComponent *pEnumComponent;
+
+ /* we are using the INetCfg API for getting the list of miniports */
+ hr = VBoxNetCfgWinQueryINetCfg(FALSE,
+ VBOX_APP_NAME,
+ &pNc,
+ &lpszApp);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
+ if (hr == S_OK)
+ {
+ while ((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
+ {
+ ULONG uComponentStatus;
+ hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
+ if (hr == S_OK)
+ {
+ if (uComponentStatus == 0)
+ {
+ LPWSTR pId;
+ hr = pMpNcc->GetId(&pId);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
+ {
+ vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
+ }
+ CoTaskMemFree(pId);
+ }
+ }
+ }
+ VBoxNetCfgWinReleaseRef(pMpNcc);
+ }
+ Assert(hr == S_OK || hr == S_FALSE);
+
+ VBoxNetCfgWinReleaseRef(pEnumComponent);
+ }
+ else
+ {
+ LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
+ }
+
+ VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
+ }
+ else if (lpszApp)
+ {
+ CoTaskMemFree(lpszApp);
+ }
+#endif /* # if defined VBOX_WITH_NETFLT */
+ return VINF_SUCCESS;
+}
+
+int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ Bstr name;
+ HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
+ if (hr == S_OK)
+ {
+ Bstr IfGuid;
+ hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ memset(pInfo, 0, sizeof(NETIFINFO));
+ Guid guid(IfGuid);
+ pInfo->Uuid = *(guid.raw());
+
+ return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
+ }
+ }
+ return VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfGetConfigByName(PNETIFINFO)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
+int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
+ IHostNetworkInterface **aHostNetworkInterface,
+ IProgress **aProgress)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+
+ ComPtr<IHost> host;
+ HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+ rc = progress->init(pVBox, host,
+ Bstr(_T("Creating host only network interface")).raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+ progress.queryInterfaceTo(aProgress);
+
+ /* create a new uninitialized host interface object */
+ ComObjPtr<HostNetworkInterface> iface;
+ iface.createObject();
+ iface.queryInterfaceTo(aHostNetworkInterface);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
+// d->name = aName;
+ d->iface = iface;
+ d->vBox = pVBox;
+
+ rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, IN_GUID aId,
+ IProgress **aProgress)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+ ComPtr<IHost> host;
+ HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+ rc = progress->init(pVBox, host,
+ Bstr(_T("Removing host network interface")).raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+ progress.queryInterfaceTo(aProgress);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
+ d->guid = aId;
+
+ rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ HRESULT rc;
+ Bstr guid;
+ rc = pIf->COMGETTER(Id)(guid.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+// ComPtr<VirtualBox> vBox;
+// rc = pIf->getVirtualBox(vBox.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+// ComPtr<IHost> host;
+// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
+ Bstr("Enabling Dynamic Ip Configuration").raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+// progress.queryInterfaceTo(aProgress);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
+ d->guid = Guid(guid);
+ d->iface = pIf;
+ d->u.StaticIP.IPAddress = ip;
+ d->u.StaticIP.IPNetMask = mask;
+
+ rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+
+ progress->WaitForCompletion(-1);
+ }
+ }
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ HRESULT rc;
+ Bstr guid;
+ rc = pIf->COMGETTER(Id)(guid.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+// ComPtr<VirtualBox> vBox;
+// rc = pIf->getVirtualBox(vBox.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+// ComPtr<IHost> host;
+// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
+ Bstr("Enabling Dynamic Ip Configuration").raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+// progress.queryInterfaceTo(aProgress);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
+ d->guid = guid;
+ d->iface = pIf;
+ d->u.StaticIPV6.IPV6Address = aIPV6Address;
+ d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
+
+ rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+
+ progress->WaitForCompletion(-1);
+ }
+ }
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ HRESULT rc;
+ Bstr guid;
+ rc = pIf->COMGETTER(Id)(guid.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+// ComPtr<VirtualBox> vBox;
+// rc = pIf->getVirtualBox(vBox.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+// ComPtr<IHost> host;
+// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
+ Bstr("Enabling Dynamic Ip Configuration").raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+// progress.queryInterfaceTo(aProgress);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
+ d->guid = guid;
+ d->iface = pIf;
+
+ rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+
+ progress->WaitForCompletion(-1);
+ }
+ }
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else
+ HRESULT rc;
+ Bstr guid;
+ rc = pIf->COMGETTER(Id)(guid.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+// ComPtr<VirtualBox> vBox;
+// rc = pIf->getVirtualBox(vBox.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ /* create a progress object */
+ ComObjPtr<Progress> progress;
+ progress.createObject();
+// ComPtr<IHost> host;
+// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
+// if (SUCCEEDED(rc))
+ {
+ rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
+ Bstr("Enabling Dynamic Ip Configuration").raw(),
+ FALSE /* aCancelable */);
+ if (SUCCEEDED(rc))
+ {
+ if (FAILED(rc)) return rc;
+// progress.queryInterfaceTo(aProgress);
+
+ /* create the networkInterfaceHelperClient() argument */
+ std::auto_ptr<NetworkInterfaceHelperClientData>
+ d(new NetworkInterfaceHelperClientData());
+ AssertReturn(d.get(), E_OUTOFMEMORY);
+
+ d->msgCode = SVCHlpMsg::DhcpRediscover;
+ d->guid = guid;
+ d->iface = pIf;
+
+ rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
+ netIfNetworkInterfaceHelperClient,
+ static_cast<void *>(d.get()),
+ progress);
+
+ if (SUCCEEDED(rc))
+ {
+ /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
+ d.release();
+
+ progress->WaitForCompletion(-1);
+ }
+ }
+ }
+ }
+ }
+
+ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
+#endif
+}
+
+int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
+{
+#ifndef VBOX_WITH_NETFLT
+ return VERR_NOT_IMPLEMENTED;
+#else /* # if defined VBOX_WITH_NETFLT */
+ INetCfg *pNc;
+ INetCfgComponent *pMpNcc;
+ INetCfgComponent *pTcpIpNcc;
+ LPWSTR lpszApp;
+ HRESULT hr;
+ IEnumNetCfgBindingPath *pEnumBp;
+ INetCfgBindingPath *pBp;
+ IEnumNetCfgBindingInterface *pEnumBi;
+ INetCfgBindingInterface *pBi;
+ int iDefault = getDefaultInterfaceIndex();
+
+ /* we are using the INetCfg API for getting the list of miniports */
+ hr = VBoxNetCfgWinQueryINetCfg(FALSE,
+ VBOX_APP_NAME,
+ &pNc,
+ &lpszApp);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+# ifdef VBOX_NETFLT_ONDEMAND_BIND
+ /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
+ hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
+# else
+ /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
+ hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
+# ifndef VBOX_WITH_HARDENING
+ if (hr != S_OK)
+ {
+ /* TODO: try to install the netflt from here */
+ }
+# endif
+
+# endif
+
+ if (hr == S_OK)
+ {
+ hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
+ Assert(hr == S_OK || hr == S_FALSE);
+ while (hr == S_OK)
+ {
+ /* S_OK == enabled, S_FALSE == disabled */
+ if (pBp->IsEnabled() == S_OK)
+ {
+ hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
+ Assert(hr == S_OK);
+ if ( hr == S_OK )
+ {
+ hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
+ Assert(hr == S_OK);
+ while (hr == S_OK)
+ {
+ hr = pBi->GetLowerComponent( &pMpNcc );
+ Assert(hr == S_OK);
+ if (hr == S_OK)
+ {
+ ULONG uComponentStatus;
+ hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
+ if (hr == S_OK)
+ {
+ if (uComponentStatus == 0)
+ {
+ vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
+ }
+ }
+ VBoxNetCfgWinReleaseRef( pMpNcc );
+ }
+ VBoxNetCfgWinReleaseRef(pBi);
+
+ hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
+ }
+ VBoxNetCfgWinReleaseRef(pEnumBi);
+ }
+ }
+ VBoxNetCfgWinReleaseRef(pBp);
+
+ hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
+ }
+ VBoxNetCfgWinReleaseRef(pEnumBp);
+ }
+ VBoxNetCfgWinReleaseRef(pTcpIpNcc);
+ }
+ else
+ {
+ LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
+ }
+
+ VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
+ }
+
+ netIfListHostAdapters(list);
+
+ return VINF_SUCCESS;
+#endif /* # if defined VBOX_WITH_NETFLT */
+}