1
/* $Id: NetIf-win.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
3
* Main - NetIfList, Windows implementation.
7
* Copyright (C) 2008-2010 Oracle Corporation
9
* This file is part of VirtualBox Open Source Edition (OSE), as
10
* available from http://www.virtualbox.org. This file is free software;
11
* you can redistribute it and/or modify it under the terms of the GNU
12
* General Public License (GPL) as published by the Free Software
13
* Foundation, in version 2 as it comes in the "COPYING" file of the
14
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
/*******************************************************************************
22
*******************************************************************************/
23
#define LOG_GROUP LOG_GROUP_MAIN
34
#ifdef VBOX_WITH_NETFLT
35
#include "VBox/WinNetConfig.h"
42
#include "HostNetworkInterfaceImpl.h"
43
#include "ProgressImpl.h"
44
#include "VirtualBoxImpl.h"
47
#ifdef VBOX_WITH_NETFLT
62
#define VBOX_APP_NAME L"VirtualBox"
64
static int getDefaultInterfaceIndex()
66
PMIB_IPFORWARDTABLE pIpTable;
67
DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
68
DWORD dwRC = NO_ERROR;
71
pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
72
if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
75
pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
79
dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
82
for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
83
if (pIpTable->table[i].dwForwardDest == 0)
85
iIndex = pIpTable->table[i].dwForwardIfIndex;
93
static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
96
int rc = VINF_SUCCESS;
98
* Most of the hosts probably have less than 10 adapters,
99
* so we'll mostly succeed from the first attempt.
101
ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
102
PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
104
return VERR_NO_MEMORY;
105
dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
106
if (dwRc == ERROR_BUFFER_OVERFLOW)
108
/* Impressive! More than 10 adapters! Get more memory and try again. */
109
RTMemFree(pAddresses);
110
pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
112
return VERR_NO_MEMORY;
113
dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
115
if (dwRc == NO_ERROR)
117
PIP_ADAPTER_ADDRESSES pAdapter;
118
for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
120
char *pszUuid = RTStrDup(pAdapter->AdapterName);
121
size_t len = strlen(pszUuid) - 1;
122
if (pszUuid[0] == '{' && pszUuid[len] == '}')
125
if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
127
bool fIPFound, fIPv6Found;
128
PIP_ADAPTER_UNICAST_ADDRESS pAddr;
129
fIPFound = fIPv6Found = false;
130
for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
132
switch (pAddr->Address.lpSockaddr->sa_family)
138
memcpy(&pInfo->IPAddress,
139
&((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
140
sizeof(pInfo->IPAddress));
147
memcpy(&pInfo->IPv6Address,
148
((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
149
sizeof(pInfo->IPv6Address));
154
PIP_ADAPTER_PREFIX pPrefix;
155
fIPFound = fIPv6Found = false;
156
for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
158
switch (pPrefix->Address.lpSockaddr->sa_family)
163
if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
166
ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
169
Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
170
pPrefix->PrefixLength));
176
if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
179
ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
182
Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
183
pPrefix->PrefixLength));
188
if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
189
Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
191
memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
192
pInfo->enmMediumType = NETIF_T_ETHERNET;
193
pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
194
pInfo->bIsDefault = (pAdapter->IfIndex == iDefault);
202
ADAPTER_SETTINGS Settings;
203
HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
208
pInfo->IPAddress.u = Settings.ip;
209
pInfo->IPNetMask.u = Settings.mask;
211
pInfo->bDhcpEnabled = Settings.bDhcp;
215
pInfo->bDhcpEnabled = false;
218
RTMemFree(pAddresses);
223
/* svc helper func */
225
struct StaticIpConfig
231
struct StaticIpV6Config
234
ULONG IPV6NetMaskLength;
237
struct NetworkInterfaceHelperClientData
239
SVCHlpMsg::Code msgCode;
240
/* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
242
ComObjPtr<HostNetworkInterface> iface;
243
ComObjPtr<VirtualBox> vBox;
244
/* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
249
StaticIpConfig StaticIP;
250
StaticIpV6Config StaticIPV6;
256
static HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
258
void *aUser, int *aVrc)
261
LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
262
aClient, aProgress, aUser));
264
AssertReturn( (aClient == NULL && aProgress == NULL && aVrc == NULL)
265
|| (aClient != NULL && aProgress != NULL && aVrc != NULL),
267
AssertReturn(aUser, E_POINTER);
269
std::auto_ptr<NetworkInterfaceHelperClientData>
270
d(static_cast<NetworkInterfaceHelperClientData *>(aUser));
274
/* "cleanup only" mode, just return (it will free aUser) */
279
int vrc = VINF_SUCCESS;
283
case SVCHlpMsg::CreateHostOnlyNetworkInterface:
285
LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
286
LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
288
/* write message and parameters */
289
vrc = aClient->write(d->msgCode);
290
if (RT_FAILURE(vrc)) break;
291
// vrc = aClient->write(Utf8Str(d->name));
292
// if (RT_FAILURE(vrc)) break;
294
/* wait for a reply */
295
bool endLoop = false;
298
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
300
vrc = aClient->read(reply);
301
if (RT_FAILURE(vrc)) break;
305
case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
310
vrc = aClient->read(name);
311
if (RT_FAILURE(vrc)) break;
312
vrc = aClient->read(guid);
313
if (RT_FAILURE(vrc)) break;
315
LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
317
/* initialize the object returned to the caller by
318
* CreateHostOnlyNetworkInterface() */
319
rc = d->iface->init(Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
322
rc = d->iface->setVirtualBox(d->vBox);
325
rc = d->iface->updateConfig();
331
case SVCHlpMsg::Error:
333
/* read the error message */
335
vrc = aClient->read(errMsg);
336
if (RT_FAILURE(vrc)) break;
338
rc = E_FAIL;//TODO: setError(E_FAIL, errMsg);
345
rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
346
//"Invalid message code %d (%08lX)\n",
355
case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
357
LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
358
LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
360
/* write message and parameters */
361
vrc = aClient->write(d->msgCode);
362
if (RT_FAILURE(vrc)) break;
363
vrc = aClient->write(d->guid);
364
if (RT_FAILURE(vrc)) break;
366
/* wait for a reply */
367
bool endLoop = false;
370
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
372
vrc = aClient->read(reply);
373
if (RT_FAILURE(vrc)) break;
384
case SVCHlpMsg::Error:
386
/* read the error message */
388
vrc = aClient->read(errMsg);
389
if (RT_FAILURE(vrc)) break;
391
rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
398
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
399
//"Invalid message code %d (%08lX)\n",
408
case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
410
LogFlowFunc(("EnableDynamicIpConfig:\n"));
411
LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
413
/* write message and parameters */
414
vrc = aClient->write(d->msgCode);
415
if (RT_FAILURE(vrc)) break;
416
vrc = aClient->write(d->guid);
417
if (RT_FAILURE(vrc)) break;
419
/* wait for a reply */
420
bool endLoop = false;
423
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
425
vrc = aClient->read(reply);
426
if (RT_FAILURE(vrc)) break;
433
rc = d->iface->updateConfig();
437
case SVCHlpMsg::Error:
439
/* read the error message */
441
vrc = aClient->read(errMsg);
442
if (RT_FAILURE(vrc)) break;
444
rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
451
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
452
//"Invalid message code %d (%08lX)\n",
461
case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
463
LogFlowFunc(("EnableStaticIpConfig:\n"));
464
LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
466
/* write message and parameters */
467
vrc = aClient->write(d->msgCode);
468
if (RT_FAILURE(vrc)) break;
469
vrc = aClient->write(d->guid);
470
if (RT_FAILURE(vrc)) break;
471
vrc = aClient->write(d->u.StaticIP.IPAddress);
472
if (RT_FAILURE(vrc)) break;
473
vrc = aClient->write(d->u.StaticIP.IPNetMask);
474
if (RT_FAILURE(vrc)) break;
476
/* wait for a reply */
477
bool endLoop = false;
480
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
482
vrc = aClient->read(reply);
483
if (RT_FAILURE(vrc)) break;
490
rc = d->iface->updateConfig();
494
case SVCHlpMsg::Error:
496
/* read the error message */
498
vrc = aClient->read(errMsg);
499
if (RT_FAILURE(vrc)) break;
501
rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
508
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
509
//"Invalid message code %d (%08lX)\n",
518
case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
520
LogFlowFunc(("EnableStaticIpConfigV6:\n"));
521
LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
523
/* write message and parameters */
524
vrc = aClient->write(d->msgCode);
525
if (RT_FAILURE(vrc)) break;
526
vrc = aClient->write(d->guid);
527
if (RT_FAILURE(vrc)) break;
528
vrc = aClient->write(Utf8Str(d->u.StaticIPV6.IPV6Address));
529
if (RT_FAILURE(vrc)) break;
530
vrc = aClient->write(d->u.StaticIPV6.IPV6NetMaskLength);
531
if (RT_FAILURE(vrc)) break;
533
/* wait for a reply */
534
bool endLoop = false;
537
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
539
vrc = aClient->read(reply);
540
if (RT_FAILURE(vrc)) break;
547
rc = d->iface->updateConfig();
551
case SVCHlpMsg::Error:
553
/* read the error message */
555
vrc = aClient->read(errMsg);
556
if (RT_FAILURE(vrc)) break;
558
rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
565
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
566
//"Invalid message code %d (%08lX)\n",
575
case SVCHlpMsg::DhcpRediscover: /* see usage in code */
577
LogFlowFunc(("DhcpRediscover:\n"));
578
LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
580
/* write message and parameters */
581
vrc = aClient->write(d->msgCode);
582
if (RT_FAILURE(vrc)) break;
583
vrc = aClient->write(d->guid);
584
if (RT_FAILURE(vrc)) break;
586
/* wait for a reply */
587
bool endLoop = false;
590
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
592
vrc = aClient->read(reply);
593
if (RT_FAILURE(vrc)) break;
600
rc = d->iface->updateConfig();
604
case SVCHlpMsg::Error:
606
/* read the error message */
608
vrc = aClient->read(errMsg);
609
if (RT_FAILURE(vrc)) break;
611
rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
618
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
619
//"Invalid message code %d (%08lX)\n",
629
rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
630
// "Invalid message code %d (%08lX)\n",
631
// d->msgCode, d->msgCode),
638
LogFlowFunc(("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
644
int netIfNetworkInterfaceHelperServer(SVCHlpClient *aClient,
645
SVCHlpMsg::Code aMsgCode)
648
LogFlowFunc(("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
650
AssertReturn(aClient, VERR_INVALID_POINTER);
652
int vrc = VINF_SUCCESS;
657
case SVCHlpMsg::CreateHostOnlyNetworkInterface:
659
LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
662
// vrc = aClient->read(name);
663
// if (RT_FAILURE(vrc)) break;
670
hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), name.asOutParam(), bstrErr.asOutParam());
675
hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
678
/* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
679
* i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter */
681
hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
684
/* write success followed by GUID */
685
vrc = aClient->write(SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
686
if (RT_FAILURE(vrc)) break;
687
vrc = aClient->write(Utf8Str(name));
688
if (RT_FAILURE(vrc)) break;
689
vrc = aClient->write(guid);
690
if (RT_FAILURE(vrc)) break;
694
vrc = VERR_GENERAL_FAILURE;
695
errMsg = Utf8Str(bstrErr);
696
/* write failure followed by error message */
697
if (errMsg.isEmpty())
698
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
699
vrc = aClient->write(SVCHlpMsg::Error);
700
if (RT_FAILURE(vrc)) break;
701
vrc = aClient->write(errMsg);
702
if (RT_FAILURE(vrc)) break;
707
case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
709
LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
714
vrc = aClient->read(guid);
715
if (RT_FAILURE(vrc)) break;
718
hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
722
/* write parameter-less success */
723
vrc = aClient->write(SVCHlpMsg::OK);
724
if (RT_FAILURE(vrc)) break;
728
vrc = VERR_GENERAL_FAILURE;
729
errMsg = Utf8Str(bstrErr);
730
/* write failure followed by error message */
731
if (errMsg.isEmpty())
732
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
733
vrc = aClient->write(SVCHlpMsg::Error);
734
if (RT_FAILURE(vrc)) break;
735
vrc = aClient->write(errMsg);
736
if (RT_FAILURE(vrc)) break;
741
case SVCHlpMsg::EnableStaticIpConfigV6:
743
LogFlowFunc(("EnableStaticIpConfigV6:\n"));
748
vrc = aClient->read(guid);
749
if (RT_FAILURE(vrc)) break;
750
vrc = aClient->read(ipV6);
751
if (RT_FAILURE(vrc)) break;
752
vrc = aClient->read(maskLengthV6);
753
if (RT_FAILURE(vrc)) break;
756
vrc = VERR_NOT_IMPLEMENTED;
760
/* write success followed by GUID */
761
vrc = aClient->write(SVCHlpMsg::OK);
762
if (RT_FAILURE(vrc)) break;
766
/* write failure followed by error message */
767
if (errMsg.isEmpty())
768
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
769
vrc = aClient->write(SVCHlpMsg::Error);
770
if (RT_FAILURE(vrc)) break;
771
vrc = aClient->write(errMsg);
772
if (RT_FAILURE(vrc)) break;
777
case SVCHlpMsg::EnableStaticIpConfig:
779
LogFlowFunc(("EnableStaticIpConfig:\n"));
783
vrc = aClient->read(guid);
784
if (RT_FAILURE(vrc)) break;
785
vrc = aClient->read(ip);
786
if (RT_FAILURE(vrc)) break;
787
vrc = aClient->read(mask);
788
if (RT_FAILURE(vrc)) break;
791
hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
795
/* write success followed by GUID */
796
vrc = aClient->write(SVCHlpMsg::OK);
797
if (RT_FAILURE(vrc)) break;
801
vrc = VERR_GENERAL_FAILURE;
802
/* write failure followed by error message */
803
if (errMsg.isEmpty())
804
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
805
vrc = aClient->write(SVCHlpMsg::Error);
806
if (RT_FAILURE(vrc)) break;
807
vrc = aClient->write(errMsg);
808
if (RT_FAILURE(vrc)) break;
813
case SVCHlpMsg::EnableDynamicIpConfig:
815
LogFlowFunc(("EnableDynamicIpConfig:\n"));
818
vrc = aClient->read(guid);
819
if (RT_FAILURE(vrc)) break;
822
hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
826
/* write success followed by GUID */
827
vrc = aClient->write(SVCHlpMsg::OK);
828
if (RT_FAILURE(vrc)) break;
832
vrc = VERR_GENERAL_FAILURE;
833
/* write failure followed by error message */
834
if (errMsg.isEmpty())
835
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
836
vrc = aClient->write(SVCHlpMsg::Error);
837
if (RT_FAILURE(vrc)) break;
838
vrc = aClient->write(errMsg);
839
if (RT_FAILURE(vrc)) break;
844
case SVCHlpMsg::DhcpRediscover:
846
LogFlowFunc(("DhcpRediscover:\n"));
849
vrc = aClient->read(guid);
850
if (RT_FAILURE(vrc)) break;
853
hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
857
/* write success followed by GUID */
858
vrc = aClient->write(SVCHlpMsg::OK);
859
if (RT_FAILURE(vrc)) break;
863
vrc = VERR_GENERAL_FAILURE;
864
/* write failure followed by error message */
865
if (errMsg.isEmpty())
866
errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
867
vrc = aClient->write(SVCHlpMsg::Error);
868
if (RT_FAILURE(vrc)) break;
869
vrc = aClient->write(errMsg);
870
if (RT_FAILURE(vrc)) break;
876
AssertMsgFailedBreakStmt(
877
("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
878
VERR_GENERAL_FAILURE);
881
LogFlowFunc(("vrc=%Rrc\n", vrc));
886
/** @todo REMOVE. OBSOLETE NOW. */
888
* Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
889
* later OSes) and it has the UAC (User Account Control) feature enabled.
891
static BOOL IsUACEnabled()
895
OSVERSIONINFOEX info;
896
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
897
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
898
rc = GetVersionEx((OSVERSIONINFO *) &info);
899
AssertReturn(rc != 0, FALSE);
901
LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
902
info.dwMajorVersion, info.dwMinorVersion));
904
/* we are interested only in Vista (and newer versions...). In all
905
* earlier versions UAC is not present. */
906
if (info.dwMajorVersion < 6)
909
/* the default EnableLUA value is 1 (Enabled) */
910
DWORD dwEnableLUA = 1;
913
rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
914
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
915
0, KEY_QUERY_VALUE, &hKey);
917
Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
918
if (rc == ERROR_SUCCESS)
921
DWORD cbEnableLUA = sizeof(dwEnableLUA);
922
rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
923
(LPBYTE) &dwEnableLUA, &cbEnableLUA);
927
Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
930
LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
932
return dwEnableLUA == 1;
937
static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
938
INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
939
int iDefaultInterface)
944
int rc = VERR_GENERAL_FAILURE;
946
hr = pncc->GetDisplayName(&lpszName);
952
hr = pncc->GetInstanceGuid(&IfGuid);
957
memset(&Info, 0, sizeof(Info));
958
Info.Uuid = *(Guid(IfGuid).raw());
959
rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
962
Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
964
/* create a new object and add it to the list */
965
ComObjPtr<HostNetworkInterface> iface;
966
iface.createObject();
967
/* remove the curly bracket at the end */
968
if (SUCCEEDED(iface->init(name, enmType, &Info)))
971
pPist->push_front(iface);
973
pPist->push_back(iface);
981
CoTaskMemFree(lpszName);
987
#endif /* VBOX_WITH_NETFLT */
990
static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
992
#ifndef VBOX_WITH_NETFLT
993
/* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
994
return VERR_NOT_IMPLEMENTED;
995
#else /* # if defined VBOX_WITH_NETFLT */
997
INetCfgComponent *pMpNcc;
998
LPWSTR lpszApp = NULL;
1000
IEnumNetCfgComponent *pEnumComponent;
1002
/* we are using the INetCfg API for getting the list of miniports */
1003
hr = VBoxNetCfgWinQueryINetCfg(FALSE,
1010
hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
1013
while ((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
1015
ULONG uComponentStatus;
1016
hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1019
if (uComponentStatus == 0)
1022
hr = pMpNcc->GetId(&pId);
1026
if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1028
vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
1034
VBoxNetCfgWinReleaseRef(pMpNcc);
1036
Assert(hr == S_OK || hr == S_FALSE);
1038
VBoxNetCfgWinReleaseRef(pEnumComponent);
1042
LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1045
VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1049
CoTaskMemFree(lpszApp);
1051
#endif /* # if defined VBOX_WITH_NETFLT */
1052
return VINF_SUCCESS;
1055
int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1057
#ifndef VBOX_WITH_NETFLT
1058
return VERR_NOT_IMPLEMENTED;
1061
HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1065
hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1069
memset(pInfo, 0, sizeof(NETIFINFO));
1071
pInfo->Uuid = *(guid.raw());
1073
return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
1076
return VERR_GENERAL_FAILURE;
1080
int NetIfGetConfigByName(PNETIFINFO)
1082
return VERR_NOT_IMPLEMENTED;
1085
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
1086
IHostNetworkInterface **aHostNetworkInterface,
1087
IProgress **aProgress)
1089
#ifndef VBOX_WITH_NETFLT
1090
return VERR_NOT_IMPLEMENTED;
1092
/* create a progress object */
1093
ComObjPtr<Progress> progress;
1094
progress.createObject();
1097
HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1100
rc = progress->init(pVBox, host,
1101
Bstr(_T("Creating host only network interface")).raw(),
1102
FALSE /* aCancelable */);
1105
if (FAILED(rc)) return rc;
1106
progress.queryInterfaceTo(aProgress);
1108
/* create a new uninitialized host interface object */
1109
ComObjPtr<HostNetworkInterface> iface;
1110
iface.createObject();
1111
iface.queryInterfaceTo(aHostNetworkInterface);
1113
/* create the networkInterfaceHelperClient() argument */
1114
std::auto_ptr<NetworkInterfaceHelperClientData>
1115
d(new NetworkInterfaceHelperClientData());
1116
AssertReturn(d.get(), E_OUTOFMEMORY);
1118
d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1123
rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1124
netIfNetworkInterfaceHelperClient,
1125
static_cast<void *>(d.get()),
1130
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1136
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1140
int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, IN_GUID aId,
1141
IProgress **aProgress)
1143
#ifndef VBOX_WITH_NETFLT
1144
return VERR_NOT_IMPLEMENTED;
1146
/* create a progress object */
1147
ComObjPtr<Progress> progress;
1148
progress.createObject();
1150
HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1153
rc = progress->init(pVBox, host,
1154
Bstr(_T("Removing host network interface")).raw(),
1155
FALSE /* aCancelable */);
1158
if (FAILED(rc)) return rc;
1159
progress.queryInterfaceTo(aProgress);
1161
/* create the networkInterfaceHelperClient() argument */
1162
std::auto_ptr<NetworkInterfaceHelperClientData>
1163
d(new NetworkInterfaceHelperClientData());
1164
AssertReturn(d.get(), E_OUTOFMEMORY);
1166
d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1169
rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1170
netIfNetworkInterfaceHelperClient,
1171
static_cast<void *>(d.get()),
1176
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1182
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1186
int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1188
#ifndef VBOX_WITH_NETFLT
1189
return VERR_NOT_IMPLEMENTED;
1193
rc = pIf->COMGETTER(Id)(guid.asOutParam());
1196
// ComPtr<VirtualBox> vBox;
1197
// rc = pIf->getVirtualBox(vBox.asOutParam());
1198
// if (SUCCEEDED(rc))
1200
/* create a progress object */
1201
ComObjPtr<Progress> progress;
1202
progress.createObject();
1203
// ComPtr<IHost> host;
1204
// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1205
// if (SUCCEEDED(rc))
1207
rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1208
Bstr("Enabling Dynamic Ip Configuration").raw(),
1209
FALSE /* aCancelable */);
1212
if (FAILED(rc)) return rc;
1213
// progress.queryInterfaceTo(aProgress);
1215
/* create the networkInterfaceHelperClient() argument */
1216
std::auto_ptr<NetworkInterfaceHelperClientData>
1217
d(new NetworkInterfaceHelperClientData());
1218
AssertReturn(d.get(), E_OUTOFMEMORY);
1220
d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1221
d->guid = Guid(guid);
1223
d->u.StaticIP.IPAddress = ip;
1224
d->u.StaticIP.IPNetMask = mask;
1226
rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1227
netIfNetworkInterfaceHelperClient,
1228
static_cast<void *>(d.get()),
1233
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1236
progress->WaitForCompletion(-1);
1243
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1247
int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1249
#ifndef VBOX_WITH_NETFLT
1250
return VERR_NOT_IMPLEMENTED;
1254
rc = pIf->COMGETTER(Id)(guid.asOutParam());
1257
// ComPtr<VirtualBox> vBox;
1258
// rc = pIf->getVirtualBox(vBox.asOutParam());
1259
// if (SUCCEEDED(rc))
1261
/* create a progress object */
1262
ComObjPtr<Progress> progress;
1263
progress.createObject();
1264
// ComPtr<IHost> host;
1265
// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1266
// if (SUCCEEDED(rc))
1268
rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1269
Bstr("Enabling Dynamic Ip Configuration").raw(),
1270
FALSE /* aCancelable */);
1273
if (FAILED(rc)) return rc;
1274
// progress.queryInterfaceTo(aProgress);
1276
/* create the networkInterfaceHelperClient() argument */
1277
std::auto_ptr<NetworkInterfaceHelperClientData>
1278
d(new NetworkInterfaceHelperClientData());
1279
AssertReturn(d.get(), E_OUTOFMEMORY);
1281
d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1284
d->u.StaticIPV6.IPV6Address = aIPV6Address;
1285
d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1287
rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1288
netIfNetworkInterfaceHelperClient,
1289
static_cast<void *>(d.get()),
1294
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1297
progress->WaitForCompletion(-1);
1304
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1308
int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1310
#ifndef VBOX_WITH_NETFLT
1311
return VERR_NOT_IMPLEMENTED;
1315
rc = pIf->COMGETTER(Id)(guid.asOutParam());
1318
// ComPtr<VirtualBox> vBox;
1319
// rc = pIf->getVirtualBox(vBox.asOutParam());
1320
// if (SUCCEEDED(rc))
1322
/* create a progress object */
1323
ComObjPtr<Progress> progress;
1324
progress.createObject();
1325
// ComPtr<IHost> host;
1326
// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1327
// if (SUCCEEDED(rc))
1329
rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1330
Bstr("Enabling Dynamic Ip Configuration").raw(),
1331
FALSE /* aCancelable */);
1334
if (FAILED(rc)) return rc;
1335
// progress.queryInterfaceTo(aProgress);
1337
/* create the networkInterfaceHelperClient() argument */
1338
std::auto_ptr<NetworkInterfaceHelperClientData>
1339
d(new NetworkInterfaceHelperClientData());
1340
AssertReturn(d.get(), E_OUTOFMEMORY);
1342
d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1346
rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1347
netIfNetworkInterfaceHelperClient,
1348
static_cast<void *>(d.get()),
1353
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1356
progress->WaitForCompletion(-1);
1363
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1367
int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1369
#ifndef VBOX_WITH_NETFLT
1370
return VERR_NOT_IMPLEMENTED;
1374
rc = pIf->COMGETTER(Id)(guid.asOutParam());
1377
// ComPtr<VirtualBox> vBox;
1378
// rc = pIf->getVirtualBox(vBox.asOutParam());
1379
// if (SUCCEEDED(rc))
1381
/* create a progress object */
1382
ComObjPtr<Progress> progress;
1383
progress.createObject();
1384
// ComPtr<IHost> host;
1385
// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1386
// if (SUCCEEDED(rc))
1388
rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1389
Bstr("Enabling Dynamic Ip Configuration").raw(),
1390
FALSE /* aCancelable */);
1393
if (FAILED(rc)) return rc;
1394
// progress.queryInterfaceTo(aProgress);
1396
/* create the networkInterfaceHelperClient() argument */
1397
std::auto_ptr<NetworkInterfaceHelperClientData>
1398
d(new NetworkInterfaceHelperClientData());
1399
AssertReturn(d.get(), E_OUTOFMEMORY);
1401
d->msgCode = SVCHlpMsg::DhcpRediscover;
1405
rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1406
netIfNetworkInterfaceHelperClient,
1407
static_cast<void *>(d.get()),
1412
/* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1415
progress->WaitForCompletion(-1);
1422
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1426
int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1428
#ifndef VBOX_WITH_NETFLT
1429
return VERR_NOT_IMPLEMENTED;
1430
#else /* # if defined VBOX_WITH_NETFLT */
1432
INetCfgComponent *pMpNcc;
1433
INetCfgComponent *pTcpIpNcc;
1436
IEnumNetCfgBindingPath *pEnumBp;
1437
INetCfgBindingPath *pBp;
1438
IEnumNetCfgBindingInterface *pEnumBi;
1439
INetCfgBindingInterface *pBi;
1440
int iDefault = getDefaultInterfaceIndex();
1442
/* we are using the INetCfg API for getting the list of miniports */
1443
hr = VBoxNetCfgWinQueryINetCfg(FALSE,
1450
# ifdef VBOX_NETFLT_ONDEMAND_BIND
1451
/* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
1452
hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
1454
/* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
1455
hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
1456
# ifndef VBOX_WITH_HARDENING
1459
/* TODO: try to install the netflt from here */
1467
hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
1471
hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
1472
Assert(hr == S_OK || hr == S_FALSE);
1475
/* S_OK == enabled, S_FALSE == disabled */
1476
if (pBp->IsEnabled() == S_OK)
1478
hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
1482
hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
1486
hr = pBi->GetLowerComponent( &pMpNcc );
1490
ULONG uComponentStatus;
1491
hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1494
if (uComponentStatus == 0)
1496
vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
1499
VBoxNetCfgWinReleaseRef( pMpNcc );
1501
VBoxNetCfgWinReleaseRef(pBi);
1503
hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
1505
VBoxNetCfgWinReleaseRef(pEnumBi);
1508
VBoxNetCfgWinReleaseRef(pBp);
1510
hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
1512
VBoxNetCfgWinReleaseRef(pEnumBp);
1514
VBoxNetCfgWinReleaseRef(pTcpIpNcc);
1518
LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1521
VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1524
netIfListHostAdapters(list);
1526
return VINF_SUCCESS;
1527
#endif /* # if defined VBOX_WITH_NETFLT */