NetIf-win.cpp revision 79207ebc7bef44216ecdbe520de76317c713ada6
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync/* $Id$ */
2291faee92ebb5cc9722cd3f22e499900a5a411fvboxsync/** @file
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * Main - NetIfList, Windows implementation.
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync */
2291faee92ebb5cc9722cd3f22e499900a5a411fvboxsync
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync/*
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * Copyright (C) 2008-2012 Oracle Corporation
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync *
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * available from http://www.virtualbox.org. This file is free software;
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * General Public License (GPL) as published by the Free Software
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync */
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync/*******************************************************************************
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync* Header Files *
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync*******************************************************************************/
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync#define LOG_GROUP LOG_GROUP_MAIN
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync
ef1c003b45b1550236f47a2da7eea2e25f224b41vboxsync#include <iprt/asm.h>
ef1c003b45b1550236f47a2da7eea2e25f224b41vboxsync#include <iprt/err.h>
ef1c003b45b1550236f47a2da7eea2e25f224b41vboxsync#include <list>
ef1c003b45b1550236f47a2da7eea2e25f224b41vboxsync
0486df2e670fa5d25ca947fd92b19dd54229692dvboxsync#define _WIN32_DCOM
0486df2e670fa5d25ca947fd92b19dd54229692dvboxsync#include <winsock2.h>
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync#include <ws2tcpip.h>
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include <windows.h>
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#ifdef VBOX_WITH_NETFLT
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync# include "VBox/VBoxNetCfg-win.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync# include "devguid.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#endif
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include <iphlpapi.h>
6cf17994e7631a6e8711c17848689c2064d5ccacvboxsync
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include "Logging.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include "HostNetworkInterfaceImpl.h"
6cf17994e7631a6e8711c17848689c2064d5ccacvboxsync#include "ProgressImpl.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include "VirtualBoxImpl.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include "netif.h"
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#ifdef VBOX_WITH_NETFLT
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include <Wbemidl.h>
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync#include <comdef.h>
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync#include "svchlp.h"
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync#include <shellapi.h>
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync#define INITGUID
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync#include <guiddef.h>
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync#include <devguid.h>
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync#include <objbase.h>
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync#include <setupapi.h>
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync#include <shlobj.h>
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync#include <cfgmgr32.h>
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync#define VBOX_APP_NAME L"VirtualBox"
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsyncstatic int getDefaultInterfaceIndex()
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync{
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync PMIB_IPFORWARDTABLE pIpTable;
b459362b1c9b5ce5e6bf4ceb32ffe1294c08be07vboxsync DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
b459362b1c9b5ce5e6bf4ceb32ffe1294c08be07vboxsync DWORD dwRC = NO_ERROR;
b459362b1c9b5ce5e6bf4ceb32ffe1294c08be07vboxsync int iIndex = -1;
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
b459362b1c9b5ce5e6bf4ceb32ffe1294c08be07vboxsync if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync {
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync RTMemFree(pIpTable);
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync if (!pIpTable)
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync return -1;
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync }
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync if (dwRC == NO_ERROR)
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync {
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync if (pIpTable->table[i].dwForwardDest == 0)
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync {
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync iIndex = pIpTable->table[i].dwForwardIfIndex;
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync break;
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync }
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync }
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync RTMemFree(pIpTable);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync return iIndex;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync}
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync
41e3b5da61b49017cb647f2f32a231c524fc370avboxsyncstatic int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
41e3b5da61b49017cb647f2f32a231c524fc370avboxsync{
41e3b5da61b49017cb647f2f32a231c524fc370avboxsync DWORD dwRc;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync int rc = VINF_SUCCESS;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync /*
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync * Most of the hosts probably have less than 10 adapters,
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync * so we'll mostly succeed from the first attempt.
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync */
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync if (!pAddresses)
cfd41a3683178a30bac4417128b4673806653797vboxsync return VERR_NO_MEMORY;
cfd41a3683178a30bac4417128b4673806653797vboxsync dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync if (dwRc == ERROR_BUFFER_OVERFLOW)
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync {
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync /* Impressive! More than 10 adapters! Get more memory and try again. */
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync RTMemFree(pAddresses);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (!pAddresses)
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync return VERR_NO_MEMORY;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (dwRc == NO_ERROR)
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync {
613c0d015cbaef93be47fc03f0708744c5c24f79vboxsync PIP_ADAPTER_ADDRESSES pAdapter;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync {
cefc5f2411cee3fe8071f6f99ed23a90f46b29f6vboxsync char *pszUuid = RTStrDup(pAdapter->AdapterName);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync size_t len = strlen(pszUuid) - 1;
907ba2c9b3d1821f95be17115ecad9fe8a2cae02vboxsync if (pszUuid[0] == '{' && pszUuid[len] == '}')
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pszUuid[len] = 0;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync bool fIPFound, fIPv6Found;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync PIP_ADAPTER_UNICAST_ADDRESS pAddr;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync fIPFound = fIPv6Found = false;
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
f6cc81e94c29cc9b39b896cf32ecfe0501b4a1e5vboxsync {
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync switch (pAddr->Address.lpSockaddr->sa_family)
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync {
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync case AF_INET:
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync if (!fIPFound)
efbdd9fc22305720d20be7cc37b4f45f43146b09vboxsync {
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync fIPFound = true;
9c59bcefe2993070fafaf0d6cee9673f48479128vboxsync memcpy(&pInfo->IPAddress,
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync sizeof(pInfo->IPAddress));
9c59bcefe2993070fafaf0d6cee9673f48479128vboxsync }
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync break;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync case AF_INET6:
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (!fIPv6Found)
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync fIPv6Found = true;
9c59bcefe2993070fafaf0d6cee9673f48479128vboxsync memcpy(&pInfo->IPv6Address,
9c59bcefe2993070fafaf0d6cee9673f48479128vboxsync ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync sizeof(pInfo->IPv6Address));
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
8f7119688865a134053bd580972655ce2b8954b3vboxsync break;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync PIP_ADAPTER_PREFIX pPrefix;
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync fIPFound = fIPv6Found = false;
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync {
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync switch (pPrefix->Address.lpSockaddr->sa_family)
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync {
a2f6500ea77004e215d6fc8fcdab25b1d4d1ad3dvboxsync case AF_INET:
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (!fIPFound)
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
8f7119688865a134053bd580972655ce2b8954b3vboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync fIPFound = true;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync }
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync else
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pPrefix->PrefixLength));
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
45eeaa1736817a425d69d35b3aa5f0dc38a7f7efvboxsync break;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync case AF_INET6:
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync if (!fIPv6Found)
8f7119688865a134053bd580972655ce2b8954b3vboxsync {
62e5c2cfabb91397405d7bfe7908ec2b3a483831vboxsync if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
62e5c2cfabb91397405d7bfe7908ec2b3a483831vboxsync {
8f7119688865a134053bd580972655ce2b8954b3vboxsync fIPv6Found = true;
8f7119688865a134053bd580972655ce2b8954b3vboxsync ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync }
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync else
8f7119688865a134053bd580972655ce2b8954b3vboxsync Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync pPrefix->PrefixLength));
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync }
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync break;
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync }
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync }
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync else
8f7119688865a134053bd580972655ce2b8954b3vboxsync memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
8f7119688865a134053bd580972655ce2b8954b3vboxsync pInfo->enmMediumType = NETIF_T_ETHERNET;
8f7119688865a134053bd580972655ce2b8954b3vboxsync pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync pInfo->bIsDefault = (pAdapter->IfIndex == iDefault);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync RTStrFree(pszUuid);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync break;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync }
8f7119688865a134053bd580972655ce2b8954b3vboxsync RTStrFree(pszUuid);
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync ADAPTER_SETTINGS Settings;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync if (hr == S_OK)
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync {
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync if (Settings.ip)
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync {
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync pInfo->IPAddress.u = Settings.ip;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync pInfo->IPNetMask.u = Settings.mask;
8f7119688865a134053bd580972655ce2b8954b3vboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync pInfo->bDhcpEnabled = Settings.bDhcp;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync else
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync {
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync pInfo->bDhcpEnabled = false;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync }
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync RTMemFree(pAddresses);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync return VINF_SUCCESS;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync}
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync/* svc helper func */
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsyncstruct StaticIpConfig
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync{
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync ULONG IPAddress;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync ULONG IPNetMask;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync};
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsyncstruct StaticIpV6Config
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync{
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync BSTR IPV6Address;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync ULONG IPV6NetMaskLength;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync};
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsyncstruct NetworkInterfaceHelperClientData
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync{
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync SVCHlpMsg::Code msgCode;
933606e7609b250f207a2f97112f8388f88998c1vboxsync /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
8f7119688865a134053bd580972655ce2b8954b3vboxsync Bstr name;
933606e7609b250f207a2f97112f8388f88998c1vboxsync ComObjPtr<HostNetworkInterface> iface;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync ComObjPtr<VirtualBox> vBox;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync Guid guid;
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync union
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync StaticIpConfig StaticIP;
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync StaticIpV6Config StaticIPV6;
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync } u;
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync};
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsyncstatic HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync Progress *aProgress,
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync void *aUser, int *aVrc)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync{
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync LogFlowFuncEnter();
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync aClient, aProgress, aUser));
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync AssertReturn( (aClient == NULL && aProgress == NULL && aVrc == NULL)
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync || (aClient != NULL && aProgress != NULL && aVrc != NULL),
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync E_POINTER);
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync AssertReturn(aUser, E_POINTER);
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync std::auto_ptr<NetworkInterfaceHelperClientData>
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync d(static_cast<NetworkInterfaceHelperClientData *>(aUser));
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync if (aClient == NULL)
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync /* "cleanup only" mode, just return (it will free aUser) */
e12a6ea07ddb7a02b3575e78b24960e13f42bf4cvboxsync return S_OK;
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync }
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync HRESULT rc = S_OK;
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync int vrc = VINF_SUCCESS;
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync switch (d->msgCode)
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync {
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync {
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync /* write message and parameters */
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync vrc = aClient->write(d->msgCode);
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync if (RT_FAILURE(vrc)) break;
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync// vrc = aClient->write(Utf8Str(d->name));
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync// if (RT_FAILURE(vrc)) break;
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync /* wait for a reply */
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync bool endLoop = false;
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync while (!endLoop)
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync {
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync SVCHlpMsg::Code reply = SVCHlpMsg::Null;
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync vrc = aClient->read(reply);
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync if (RT_FAILURE(vrc)) break;
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync switch (reply)
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync {
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync {
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync /* read the GUID */
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync Guid guid;
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync Utf8Str name;
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync vrc = aClient->read(name);
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync if (RT_FAILURE(vrc)) break;
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync vrc = aClient->read(guid);
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync if (RT_FAILURE(vrc)) break;
e12a6ea07ddb7a02b3575e78b24960e13f42bf4cvboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync /* initialize the object returned to the caller by
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync * CreateHostOnlyNetworkInterface() */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync rc = d->iface->init(Bstr(name), Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (SUCCEEDED(rc))
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync rc = d->iface->i_setVirtualBox(d->vBox);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync if (SUCCEEDED(rc))
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync {
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync rc = d->iface->updateConfig();
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync }
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync }
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync endLoop = true;
e27467c77543dda00047807bdd69b62f1cd50feevboxsync break;
e27467c77543dda00047807bdd69b62f1cd50feevboxsync }
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync case SVCHlpMsg::Error:
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync {
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /* read the error message */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync Utf8Str errMsg;
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync vrc = aClient->read(errMsg);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync if (RT_FAILURE(vrc)) break;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync
9a1578b66f9e563cf99c75ffa881db476f477e3avboxsync rc = E_FAIL;//TODO: setError(E_FAIL, errMsg);
8f7119688865a134053bd580972655ce2b8954b3vboxsync endLoop = true;
8f7119688865a134053bd580972655ce2b8954b3vboxsync break;
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync }
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync default:
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync {
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync endLoop = true;
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync //"Invalid message code %d (%08lX)\n",
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync //reply, reply),
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync //rc = E_FAIL);
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync }
8f7119688865a134053bd580972655ce2b8954b3vboxsync }
8f7119688865a134053bd580972655ce2b8954b3vboxsync }
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync break;
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync }
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync {
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync
8f7119688865a134053bd580972655ce2b8954b3vboxsync /* write message and parameters */
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync vrc = aClient->write(d->msgCode);
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync if (RT_FAILURE(vrc)) break;
8f7119688865a134053bd580972655ce2b8954b3vboxsync vrc = aClient->write(d->guid);
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync if (RT_FAILURE(vrc)) break;
8f7119688865a134053bd580972655ce2b8954b3vboxsync
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync /* wait for a reply */
8f7119688865a134053bd580972655ce2b8954b3vboxsync bool endLoop = false;
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync while (!endLoop)
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync {
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync SVCHlpMsg::Code reply = SVCHlpMsg::Null;
bc8ea11359bbfdee1aa1a32821d263292d4a8feevboxsync
9b5e4e8f5c00e8cd2289a73d173c96e551c79397vboxsync vrc = aClient->read(reply);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync if (RT_FAILURE(vrc)) break;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync switch (reply)
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync {
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync case SVCHlpMsg::OK:
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync {
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync /* no parameters */
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync rc = S_OK;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync endLoop = true;
d95b7fbc09277b5375b98812fa76b08c6ce8535cvboxsync break;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync }
d95b7fbc09277b5375b98812fa76b08c6ce8535cvboxsync case SVCHlpMsg::Error:
d95b7fbc09277b5375b98812fa76b08c6ce8535cvboxsync {
d95b7fbc09277b5375b98812fa76b08c6ce8535cvboxsync /* read the error message */
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync Utf8Str errMsg;
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync vrc = aClient->read(errMsg);
97674677e4f2aeae576c39f966568dd664ba7979vboxsync if (RT_FAILURE(vrc)) break;
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync endLoop = true;
72f66530e1bf87aa6894a5f55f1b4d36caa5761fvboxsync break;
97674677e4f2aeae576c39f966568dd664ba7979vboxsync }
97674677e4f2aeae576c39f966568dd664ba7979vboxsync default:
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync {
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;
RT_ZERO(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(&pNc, FALSE,
VBOX_APP_NAME,
10000,
&lpszApp);
Assert(hr == S_OK);
if (hr == S_OK)
{
hr = pNc->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent);
if (hr == S_OK)
{
while ((hr = pEnumComponent->Next(1, &pMpNcc, NULL)) == 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);
}
}
}
pMpNcc->Release();
}
Assert(hr == S_OK || hr == S_FALSE);
pEnumComponent->Release();
}
else
{
LogRel((__FUNCTION__": EnumComponents 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;
}
/**
* Obtain the current state of the interface.
*
* @returns VBox status code.
*
* @param pcszIfName Interface name.
* @param penmState Where to store the retrieved state.
*/
int NetIfGetState(const char *pcszIfName, NETIFSTATUS *penmState)
{
return VERR_NOT_IMPLEMENTED;
}
/**
* Retrieve the physical link speed in megabits per second. If the interface is
* not up or otherwise unavailable the zero speed is returned.
*
* @returns VBox status code.
*
* @param pcszIfName Interface name.
* @param puMbits Where to store the link speed.
*/
int NetIfGetLinkSpeed(const char * /*pcszIfName*/, uint32_t * /*puMbits*/)
{
return VERR_NOT_IMPLEMENTED;
}
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
IHostNetworkInterface **aHostNetworkInterface,
IProgress **aProgress,
const char *pcszName)
{
#ifndef VBOX_WITH_NETFLT
return VERR_NOT_IMPLEMENTED;
#else
/* create a progress object */
ComObjPtr<Progress> progress;
progress.createObject();
ComPtr<IHost> host;
HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
if (SUCCEEDED(rc))
{
rc = progress->init(pVirtualBox, 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 = pVirtualBox;
rc = pVirtualBox->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 *pVirtualBox, 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 = pVirtualBox->COMGETTER(Host)(host.asOutParam());
if (SUCCEEDED(rc))
{
rc = progress->init(pVirtualBox, 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 = pVirtualBox->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(&pNc, FALSE,
VBOX_APP_NAME,
10000,
&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)
{
INetCfgComponentBindings *pBindings;
hr = pTcpIpNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindings);
Assert(hr == S_OK);
if (hr == S_OK)
{
hr = pBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp);
Assert(hr == S_OK);
if (hr == S_OK)
{
hr = pEnumBp->Reset();
Assert(hr == S_OK);
if (hr == S_OK)
{
while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
{
/* S_OK == enabled, S_FALSE == disabled */
if (pBp->IsEnabled() == S_OK)
{
hr = pBp->EnumBindingInterfaces(&pEnumBi);
Assert(hr == S_OK);
if (hr == S_OK)
{
hr = pEnumBi->Reset();
Assert(hr == S_OK);
if (hr == S_OK)
{
while ((hr = pEnumBi->Next(1, &pBi, NULL)) == 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);
}
}
pMpNcc->Release();
}
pBi->Release();
}
Assert(hr == S_OK || hr == S_FALSE);
}
pEnumBi->Release();
}
}
pBp->Release();
}
Assert(hr == S_OK || hr == S_FALSE);
}
pEnumBp->Release();
}
pBindings->Release();
}
pTcpIpNcc->Release();
}
else
{
LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)\n", hr));
}
VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
}
netIfListHostAdapters(list);
return VINF_SUCCESS;
#endif /* # if defined VBOX_WITH_NETFLT */
}