VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/win/NetIf-win.cpp@ 59117

Last change on this file since 59117 was 59087, checked in by vboxsync, 9 years ago

bugref:7179. auto_ptr was removed from the files VirtualBoxImpl.cpp and NetIf-win.cpp. The operations with network interface on Windows OS were affected.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.2 KB
Line 
1/* $Id: NetIf-win.cpp 59087 2015-12-11 11:04:51Z vboxsync $ */
2/** @file
3 * Main - NetIfList, Windows implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2012 Oracle Corporation
8 *
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.
16 */
17
18
19
20/*********************************************************************************************************************************
21* Header Files *
22*********************************************************************************************************************************/
23#define LOG_GROUP LOG_GROUP_MAIN
24
25#define NETIF_WITHOUT_NETCFG
26
27#include <iprt/asm.h>
28#include <iprt/err.h>
29#include <list>
30
31#define _WIN32_DCOM
32#include <winsock2.h>
33#include <ws2tcpip.h>
34#include <windows.h>
35
36#ifdef VBOX_WITH_NETFLT
37# include "VBox/VBoxNetCfg-win.h"
38# include "devguid.h"
39#endif
40
41#include <iphlpapi.h>
42
43#include "Logging.h"
44#include "HostNetworkInterfaceImpl.h"
45#include "ProgressImpl.h"
46#include "VirtualBoxImpl.h"
47#include "netif.h"
48#include "ThreadTask.h"
49
50#ifdef VBOX_WITH_NETFLT
51#include <Wbemidl.h>
52#include <comdef.h>
53
54#include "svchlp.h"
55
56#include <shellapi.h>
57#define INITGUID
58#include <guiddef.h>
59#include <devguid.h>
60#include <objbase.h>
61#include <setupapi.h>
62#include <shlobj.h>
63#include <cfgmgr32.h>
64
65#define VBOX_APP_NAME L"VirtualBox"
66
67static int getDefaultInterfaceIndex()
68{
69 PMIB_IPFORWARDTABLE pIpTable;
70 DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
71 DWORD dwRC = NO_ERROR;
72 int iIndex = -1;
73
74 pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
75 if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
76 {
77 RTMemFree(pIpTable);
78 pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
79 if (!pIpTable)
80 return -1;
81 }
82 dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
83 if (dwRC == NO_ERROR)
84 {
85 for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
86 if (pIpTable->table[i].dwForwardDest == 0)
87 {
88 iIndex = pIpTable->table[i].dwForwardIfIndex;
89 break;
90 }
91 }
92 RTMemFree(pIpTable);
93 return iIndex;
94}
95
96static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
97{
98 DWORD dwRc;
99 int rc = VINF_SUCCESS;
100 /*
101 * Most of the hosts probably have less than 10 adapters,
102 * so we'll mostly succeed from the first attempt.
103 */
104 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
105 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
106 if (!pAddresses)
107 return VERR_NO_MEMORY;
108 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
109 if (dwRc == ERROR_BUFFER_OVERFLOW)
110 {
111 /* Impressive! More than 10 adapters! Get more memory and try again. */
112 RTMemFree(pAddresses);
113 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
114 if (!pAddresses)
115 return VERR_NO_MEMORY;
116 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
117 }
118 if (dwRc == NO_ERROR)
119 {
120 PIP_ADAPTER_ADDRESSES pAdapter;
121 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
122 {
123 char *pszUuid = RTStrDup(pAdapter->AdapterName);
124 size_t len = strlen(pszUuid) - 1;
125 if (pszUuid[0] == '{' && pszUuid[len] == '}')
126 {
127 pszUuid[len] = 0;
128 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
129 {
130 bool fIPFound, fIPv6Found;
131 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
132 fIPFound = fIPv6Found = false;
133 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
134 {
135 switch (pAddr->Address.lpSockaddr->sa_family)
136 {
137 case AF_INET:
138 if (!fIPFound)
139 {
140 fIPFound = true;
141 memcpy(&pInfo->IPAddress,
142 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
143 sizeof(pInfo->IPAddress));
144 }
145 break;
146 case AF_INET6:
147 if (!fIPv6Found)
148 {
149 fIPv6Found = true;
150 memcpy(&pInfo->IPv6Address,
151 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
152 sizeof(pInfo->IPv6Address));
153 }
154 break;
155 }
156 }
157 PIP_ADAPTER_PREFIX pPrefix;
158 fIPFound = fIPv6Found = false;
159 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
160 {
161 switch (pPrefix->Address.lpSockaddr->sa_family)
162 {
163 case AF_INET:
164 if (!fIPFound)
165 {
166 if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
167 {
168 fIPFound = true;
169 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
170 }
171 else
172 Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
173 pPrefix->PrefixLength));
174 }
175 break;
176 case AF_INET6:
177 if (!fIPv6Found)
178 {
179 if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
180 {
181 fIPv6Found = true;
182 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
183 }
184 else
185 Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
186 pPrefix->PrefixLength));
187 }
188 break;
189 }
190 }
191 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
192 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
193 else
194 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
195 pInfo->enmMediumType = NETIF_T_ETHERNET;
196 pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
197 pInfo->bIsDefault = (pAdapter->IfIndex == iDefault);
198 RTStrFree(pszUuid);
199 break;
200 }
201 }
202 RTStrFree(pszUuid);
203 }
204
205 ADAPTER_SETTINGS Settings;
206 HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
207 if (hr == S_OK)
208 {
209 if (Settings.ip)
210 {
211 pInfo->IPAddress.u = Settings.ip;
212 pInfo->IPNetMask.u = Settings.mask;
213 }
214 pInfo->bDhcpEnabled = Settings.bDhcp;
215 }
216 else
217 {
218 pInfo->bDhcpEnabled = false;
219 }
220 }
221 RTMemFree(pAddresses);
222
223 return VINF_SUCCESS;
224}
225
226/* svc helper func */
227
228struct StaticIpConfig
229{
230 ULONG IPAddress;
231 ULONG IPNetMask;
232};
233
234struct StaticIpV6Config
235{
236 BSTR IPV6Address;
237 ULONG IPV6NetMaskLength;
238};
239
240class NetworkInterfaceHelperClientData : public ThreadVoidData
241{
242public:
243 NetworkInterfaceHelperClientData(){};
244 ~NetworkInterfaceHelperClientData(){};
245
246 SVCHlpMsg::Code msgCode;
247 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
248 Bstr name;
249 ComObjPtr<HostNetworkInterface> iface;
250 ComObjPtr<VirtualBox> vBox;
251 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
252 Guid guid;
253
254 union
255 {
256 StaticIpConfig StaticIP;
257 StaticIpV6Config StaticIPV6;
258 } u;
259
260};
261
262static HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
263 Progress *aProgress,
264 void *aUser, int *aVrc)
265{
266 LogFlowFuncEnter();
267 LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
268 aClient, aProgress, aUser));
269
270 AssertReturn( (aClient == NULL && aProgress == NULL && aVrc == NULL)
271 || (aClient != NULL && aProgress != NULL && aVrc != NULL),
272 E_POINTER);
273 AssertReturn(aUser, E_POINTER);
274
275 NetworkInterfaceHelperClientData* d = static_cast<NetworkInterfaceHelperClientData *>(aUser);
276
277 if (aClient == NULL)
278 {
279 /* "cleanup only" mode, just return (it will free aUser) */
280 return S_OK;
281 }
282
283 HRESULT rc = S_OK;
284 int vrc = VINF_SUCCESS;
285
286 switch (d->msgCode)
287 {
288 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
289 {
290 LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
291 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
292
293 /* write message and parameters */
294 vrc = aClient->write(d->msgCode);
295 if (RT_FAILURE(vrc)) break;
296// vrc = aClient->write(Utf8Str(d->name));
297// if (RT_FAILURE(vrc)) break;
298
299 /* wait for a reply */
300 bool endLoop = false;
301 while (!endLoop)
302 {
303 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
304
305 vrc = aClient->read(reply);
306 if (RT_FAILURE(vrc)) break;
307
308 switch (reply)
309 {
310 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
311 {
312 /* read the GUID */
313 Guid guid;
314 Utf8Str name;
315 vrc = aClient->read(name);
316 if (RT_FAILURE(vrc)) break;
317 vrc = aClient->read(guid);
318 if (RT_FAILURE(vrc)) break;
319
320 LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
321
322 /* initialize the object returned to the caller by
323 * CreateHostOnlyNetworkInterface() */
324 rc = d->iface->init(Bstr(name), Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
325 if (SUCCEEDED(rc))
326 {
327 rc = d->iface->i_setVirtualBox(d->vBox);
328 if (SUCCEEDED(rc))
329 {
330 rc = d->iface->updateConfig();
331 }
332 }
333 endLoop = true;
334 break;
335 }
336 case SVCHlpMsg::Error:
337 {
338 /* read the error message */
339 Utf8Str errMsg;
340 vrc = aClient->read(errMsg);
341 if (RT_FAILURE(vrc)) break;
342
343 rc = E_FAIL;
344 d->iface->setError(E_FAIL, errMsg.c_str());
345 endLoop = true;
346 break;
347 }
348 default:
349 {
350 endLoop = true;
351 rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
352 //"Invalid message code %d (%08lX)\n",
353 //reply, reply),
354 //rc = E_FAIL);
355 }
356 }
357 }
358
359 break;
360 }
361 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
362 {
363 LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
364 LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
365
366 /* write message and parameters */
367 vrc = aClient->write(d->msgCode);
368 if (RT_FAILURE(vrc)) break;
369 vrc = aClient->write(d->guid);
370 if (RT_FAILURE(vrc)) break;
371
372 /* wait for a reply */
373 bool endLoop = false;
374 while (!endLoop)
375 {
376 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
377
378 vrc = aClient->read(reply);
379 if (RT_FAILURE(vrc)) break;
380
381 switch (reply)
382 {
383 case SVCHlpMsg::OK:
384 {
385 /* no parameters */
386 rc = S_OK;
387 endLoop = true;
388 break;
389 }
390 case SVCHlpMsg::Error:
391 {
392 /* read the error message */
393 Utf8Str errMsg;
394 vrc = aClient->read(errMsg);
395 if (RT_FAILURE(vrc)) break;
396
397 rc = E_FAIL;
398 d->iface->setError(E_FAIL, errMsg.c_str());
399 endLoop = true;
400 break;
401 }
402 default:
403 {
404 endLoop = true;
405 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
406 //"Invalid message code %d (%08lX)\n",
407 //reply, reply),
408 //rc = E_FAIL);
409 }
410 }
411 }
412
413 break;
414 }
415 case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
416 {
417 LogFlowFunc(("EnableDynamicIpConfig:\n"));
418 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
419
420 /* write message and parameters */
421 vrc = aClient->write(d->msgCode);
422 if (RT_FAILURE(vrc)) break;
423 vrc = aClient->write(d->guid);
424 if (RT_FAILURE(vrc)) break;
425
426 /* wait for a reply */
427 bool endLoop = false;
428 while (!endLoop)
429 {
430 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
431
432 vrc = aClient->read(reply);
433 if (RT_FAILURE(vrc)) break;
434
435 switch (reply)
436 {
437 case SVCHlpMsg::OK:
438 {
439 /* no parameters */
440 rc = d->iface->updateConfig();
441 endLoop = true;
442 break;
443 }
444 case SVCHlpMsg::Error:
445 {
446 /* read the error message */
447 Utf8Str errMsg;
448 vrc = aClient->read(errMsg);
449 if (RT_FAILURE(vrc)) break;
450
451 rc = E_FAIL;
452 d->iface->setError(E_FAIL, errMsg.c_str());
453 endLoop = true;
454 break;
455 }
456 default:
457 {
458 endLoop = true;
459 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
460 //"Invalid message code %d (%08lX)\n",
461 //reply, reply),
462 //rc = E_FAIL);
463 }
464 }
465 }
466
467 break;
468 }
469 case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
470 {
471 LogFlowFunc(("EnableStaticIpConfig:\n"));
472 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
473
474 /* write message and parameters */
475 vrc = aClient->write(d->msgCode);
476 if (RT_FAILURE(vrc)) break;
477 vrc = aClient->write(d->guid);
478 if (RT_FAILURE(vrc)) break;
479 vrc = aClient->write(d->u.StaticIP.IPAddress);
480 if (RT_FAILURE(vrc)) break;
481 vrc = aClient->write(d->u.StaticIP.IPNetMask);
482 if (RT_FAILURE(vrc)) break;
483
484 /* wait for a reply */
485 bool endLoop = false;
486 while (!endLoop)
487 {
488 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
489
490 vrc = aClient->read(reply);
491 if (RT_FAILURE(vrc)) break;
492
493 switch (reply)
494 {
495 case SVCHlpMsg::OK:
496 {
497 /* no parameters */
498 rc = d->iface->updateConfig();
499 endLoop = true;
500 break;
501 }
502 case SVCHlpMsg::Error:
503 {
504 /* read the error message */
505 Utf8Str errMsg;
506 vrc = aClient->read(errMsg);
507 if (RT_FAILURE(vrc)) break;
508
509 rc = E_FAIL;
510 d->iface->setError(E_FAIL, errMsg.c_str());
511 endLoop = true;
512 break;
513 }
514 default:
515 {
516 endLoop = true;
517 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
518 //"Invalid message code %d (%08lX)\n",
519 //reply, reply),
520 //rc = E_FAIL);
521 }
522 }
523 }
524
525 break;
526 }
527 case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
528 {
529 LogFlowFunc(("EnableStaticIpConfigV6:\n"));
530 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
531
532 /* write message and parameters */
533 vrc = aClient->write(d->msgCode);
534 if (RT_FAILURE(vrc)) break;
535 vrc = aClient->write(d->guid);
536 if (RT_FAILURE(vrc)) break;
537 vrc = aClient->write(Utf8Str(d->u.StaticIPV6.IPV6Address));
538 if (RT_FAILURE(vrc)) break;
539 vrc = aClient->write(d->u.StaticIPV6.IPV6NetMaskLength);
540 if (RT_FAILURE(vrc)) break;
541
542 /* wait for a reply */
543 bool endLoop = false;
544 while (!endLoop)
545 {
546 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
547
548 vrc = aClient->read(reply);
549 if (RT_FAILURE(vrc)) break;
550
551 switch (reply)
552 {
553 case SVCHlpMsg::OK:
554 {
555 /* no parameters */
556 rc = d->iface->updateConfig();
557 endLoop = true;
558 break;
559 }
560 case SVCHlpMsg::Error:
561 {
562 /* read the error message */
563 Utf8Str errMsg;
564 vrc = aClient->read(errMsg);
565 if (RT_FAILURE(vrc)) break;
566
567 rc = E_FAIL;
568 d->iface->setError(E_FAIL, errMsg.c_str());
569 endLoop = true;
570 break;
571 }
572 default:
573 {
574 endLoop = true;
575 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
576 //"Invalid message code %d (%08lX)\n",
577 //reply, reply),
578 //rc = E_FAIL);
579 }
580 }
581 }
582
583 break;
584 }
585 case SVCHlpMsg::DhcpRediscover: /* see usage in code */
586 {
587 LogFlowFunc(("DhcpRediscover:\n"));
588 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
589
590 /* write message and parameters */
591 vrc = aClient->write(d->msgCode);
592 if (RT_FAILURE(vrc)) break;
593 vrc = aClient->write(d->guid);
594 if (RT_FAILURE(vrc)) break;
595
596 /* wait for a reply */
597 bool endLoop = false;
598 while (!endLoop)
599 {
600 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
601
602 vrc = aClient->read(reply);
603 if (RT_FAILURE(vrc)) break;
604
605 switch (reply)
606 {
607 case SVCHlpMsg::OK:
608 {
609 /* no parameters */
610 rc = d->iface->updateConfig();
611 endLoop = true;
612 break;
613 }
614 case SVCHlpMsg::Error:
615 {
616 /* read the error message */
617 Utf8Str errMsg;
618 vrc = aClient->read(errMsg);
619 if (RT_FAILURE(vrc)) break;
620
621 rc = E_FAIL;
622 d->iface->setError(E_FAIL, errMsg.c_str());
623 endLoop = true;
624 break;
625 }
626 default:
627 {
628 endLoop = true;
629 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
630 //"Invalid message code %d (%08lX)\n",
631 //reply, reply),
632 //rc = E_FAIL);
633 }
634 }
635 }
636
637 break;
638 }
639 default:
640 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
641// "Invalid message code %d (%08lX)\n",
642// d->msgCode, d->msgCode),
643// rc = E_FAIL);
644 }
645
646 if (aVrc)
647 *aVrc = vrc;
648
649 LogFlowFunc(("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
650 LogFlowFuncLeave();
651 return rc;
652}
653
654
655int netIfNetworkInterfaceHelperServer(SVCHlpClient *aClient,
656 SVCHlpMsg::Code aMsgCode)
657{
658 LogFlowFuncEnter();
659 LogFlowFunc(("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
660
661 AssertReturn(aClient, VERR_INVALID_POINTER);
662
663 int vrc = VINF_SUCCESS;
664 HRESULT hrc;
665
666 switch (aMsgCode)
667 {
668 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
669 {
670 LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
671
672// Utf8Str name;
673// vrc = aClient->read(name);
674// if (RT_FAILURE(vrc)) break;
675
676 Guid guid;
677 Utf8Str errMsg;
678 Bstr name;
679 Bstr bstrErr;
680
681#ifdef VBOXNETCFG_DELAYEDRENAME
682 Bstr devId;
683 hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), devId.asOutParam(),
684 bstrErr.asOutParam());
685#else /* !VBOXNETCFG_DELAYEDRENAME */
686 hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), name.asOutParam(),
687 bstrErr.asOutParam());
688#endif /* !VBOXNETCFG_DELAYEDRENAME */
689
690 if (hrc == S_OK)
691 {
692 ULONG ip, mask;
693 hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
694 if (hrc == S_OK)
695 {
696 /* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
697 * i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter */
698 ip = ip | (1 << 24);
699 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
700 if (hrc != S_OK)
701 LogRel(("VBoxNetCfgWinEnableStaticIpConfig failed (0x%x)\n", hrc));
702 }
703 else
704 LogRel(("VBoxNetCfgWinGenHostOnlyNetworkNetworkIp failed (0x%x)\n", hrc));
705#ifdef VBOXNETCFG_DELAYEDRENAME
706 hrc = VBoxNetCfgWinRenameHostOnlyConnection((const GUID*)guid.raw(), devId.raw(), name.asOutParam());
707 if (hrc != S_OK)
708 LogRel(("VBoxNetCfgWinRenameHostOnlyConnection failed, error = 0x%x", hrc));
709#endif /* VBOXNETCFG_DELAYEDRENAME */
710 /* write success followed by GUID */
711 vrc = aClient->write(SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
712 if (RT_FAILURE(vrc)) break;
713 vrc = aClient->write(Utf8Str(name));
714 if (RT_FAILURE(vrc)) break;
715 vrc = aClient->write(guid);
716 if (RT_FAILURE(vrc)) break;
717 }
718 else
719 {
720 vrc = VERR_GENERAL_FAILURE;
721 errMsg = Utf8Str(bstrErr);
722 /* write failure followed by error message */
723 if (errMsg.isEmpty())
724 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
725 vrc = aClient->write(SVCHlpMsg::Error);
726 if (RT_FAILURE(vrc)) break;
727 vrc = aClient->write(errMsg);
728 if (RT_FAILURE(vrc)) break;
729 }
730
731 break;
732 }
733 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
734 {
735 LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
736
737 Guid guid;
738 Bstr bstrErr;
739
740 vrc = aClient->read(guid);
741 if (RT_FAILURE(vrc)) break;
742
743 Utf8Str errMsg;
744 hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
745
746 if (hrc == S_OK)
747 {
748 /* write parameter-less success */
749 vrc = aClient->write(SVCHlpMsg::OK);
750 if (RT_FAILURE(vrc)) break;
751 }
752 else
753 {
754 vrc = VERR_GENERAL_FAILURE;
755 errMsg = Utf8Str(bstrErr);
756 /* write failure followed by error message */
757 if (errMsg.isEmpty())
758 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
759 vrc = aClient->write(SVCHlpMsg::Error);
760 if (RT_FAILURE(vrc)) break;
761 vrc = aClient->write(errMsg);
762 if (RT_FAILURE(vrc)) break;
763 }
764
765 break;
766 }
767 case SVCHlpMsg::EnableStaticIpConfigV6:
768 {
769 LogFlowFunc(("EnableStaticIpConfigV6:\n"));
770
771 Guid guid;
772 Utf8Str ipV6;
773 ULONG maskLengthV6;
774 vrc = aClient->read(guid);
775 if (RT_FAILURE(vrc)) break;
776 vrc = aClient->read(ipV6);
777 if (RT_FAILURE(vrc)) break;
778 vrc = aClient->read(maskLengthV6);
779 if (RT_FAILURE(vrc)) break;
780
781 Utf8Str errMsg;
782 vrc = VERR_NOT_IMPLEMENTED;
783
784 if (RT_SUCCESS(vrc))
785 {
786 /* write success followed by GUID */
787 vrc = aClient->write(SVCHlpMsg::OK);
788 if (RT_FAILURE(vrc)) break;
789 }
790 else
791 {
792 /* write failure followed by error message */
793 if (errMsg.isEmpty())
794 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
795 vrc = aClient->write(SVCHlpMsg::Error);
796 if (RT_FAILURE(vrc)) break;
797 vrc = aClient->write(errMsg);
798 if (RT_FAILURE(vrc)) break;
799 }
800
801 break;
802 }
803 case SVCHlpMsg::EnableStaticIpConfig:
804 {
805 LogFlowFunc(("EnableStaticIpConfig:\n"));
806
807 Guid guid;
808 ULONG ip, mask;
809 vrc = aClient->read(guid);
810 if (RT_FAILURE(vrc)) break;
811 vrc = aClient->read(ip);
812 if (RT_FAILURE(vrc)) break;
813 vrc = aClient->read(mask);
814 if (RT_FAILURE(vrc)) break;
815
816 Utf8Str errMsg;
817 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
818
819 if (hrc == S_OK)
820 {
821 /* write success followed by GUID */
822 vrc = aClient->write(SVCHlpMsg::OK);
823 if (RT_FAILURE(vrc)) break;
824 }
825 else
826 {
827 vrc = VERR_GENERAL_FAILURE;
828 /* write failure followed by error message */
829 if (errMsg.isEmpty())
830 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
831 vrc = aClient->write(SVCHlpMsg::Error);
832 if (RT_FAILURE(vrc)) break;
833 vrc = aClient->write(errMsg);
834 if (RT_FAILURE(vrc)) break;
835 }
836
837 break;
838 }
839 case SVCHlpMsg::EnableDynamicIpConfig:
840 {
841 LogFlowFunc(("EnableDynamicIpConfig:\n"));
842
843 Guid guid;
844 vrc = aClient->read(guid);
845 if (RT_FAILURE(vrc)) break;
846
847 Utf8Str errMsg;
848 hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
849
850 if (hrc == S_OK)
851 {
852 /* write success followed by GUID */
853 vrc = aClient->write(SVCHlpMsg::OK);
854 if (RT_FAILURE(vrc)) break;
855 }
856 else
857 {
858 vrc = VERR_GENERAL_FAILURE;
859 /* write failure followed by error message */
860 if (errMsg.isEmpty())
861 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
862 vrc = aClient->write(SVCHlpMsg::Error);
863 if (RT_FAILURE(vrc)) break;
864 vrc = aClient->write(errMsg);
865 if (RT_FAILURE(vrc)) break;
866 }
867
868 break;
869 }
870 case SVCHlpMsg::DhcpRediscover:
871 {
872 LogFlowFunc(("DhcpRediscover:\n"));
873
874 Guid guid;
875 vrc = aClient->read(guid);
876 if (RT_FAILURE(vrc)) break;
877
878 Utf8Str errMsg;
879 hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
880
881 if (hrc == S_OK)
882 {
883 /* write success followed by GUID */
884 vrc = aClient->write(SVCHlpMsg::OK);
885 if (RT_FAILURE(vrc)) break;
886 }
887 else
888 {
889 vrc = VERR_GENERAL_FAILURE;
890 /* write failure followed by error message */
891 if (errMsg.isEmpty())
892 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
893 vrc = aClient->write(SVCHlpMsg::Error);
894 if (RT_FAILURE(vrc)) break;
895 vrc = aClient->write(errMsg);
896 if (RT_FAILURE(vrc)) break;
897 }
898
899 break;
900 }
901 default:
902 AssertMsgFailedBreakStmt(
903 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
904 VERR_GENERAL_FAILURE);
905 }
906
907 LogFlowFunc(("vrc=%Rrc\n", vrc));
908 LogFlowFuncLeave();
909 return vrc;
910}
911
912/** @todo REMOVE. OBSOLETE NOW. */
913/**
914 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
915 * later OSes) and it has the UAC (User Account Control) feature enabled.
916 */
917static BOOL IsUACEnabled()
918{
919 LONG rc = 0;
920
921 OSVERSIONINFOEX info;
922 ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
923 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
924 rc = GetVersionEx((OSVERSIONINFO *) &info);
925 AssertReturn(rc != 0, FALSE);
926
927 LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
928 info.dwMajorVersion, info.dwMinorVersion));
929
930 /* we are interested only in Vista (and newer versions...). In all
931 * earlier versions UAC is not present. */
932 if (info.dwMajorVersion < 6)
933 return FALSE;
934
935 /* the default EnableLUA value is 1 (Enabled) */
936 DWORD dwEnableLUA = 1;
937
938 HKEY hKey;
939 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
940 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
941 0, KEY_QUERY_VALUE, &hKey);
942
943 Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
944 if (rc == ERROR_SUCCESS)
945 {
946
947 DWORD cbEnableLUA = sizeof(dwEnableLUA);
948 rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
949 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
950
951 RegCloseKey(hKey);
952
953 Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
954 }
955
956 LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
957
958 return dwEnableLUA == 1;
959}
960
961/* end */
962
963static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
964 INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
965 int iDefaultInterface)
966{
967 LPWSTR lpszName;
968 GUID IfGuid;
969 HRESULT hr;
970 int rc = VERR_GENERAL_FAILURE;
971
972 hr = pncc->GetDisplayName(&lpszName);
973 Assert(hr == S_OK);
974 if (hr == S_OK)
975 {
976 Bstr name(lpszName);
977
978 hr = pncc->GetInstanceGuid(&IfGuid);
979 Assert(hr == S_OK);
980 if (hr == S_OK)
981 {
982 NETIFINFO Info;
983 RT_ZERO(Info);
984 Info.Uuid = *(Guid(IfGuid).raw());
985 rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
986 if (RT_FAILURE(rc))
987 {
988 LogRel(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
989 }
990 Log(("vboxNetWinAddComponent: adding %ls\n", lpszName));
991 /* create a new object and add it to the list */
992 ComObjPtr<HostNetworkInterface> iface;
993 iface.createObject();
994 /* remove the curly bracket at the end */
995 rc = iface->init(name, enmType, &Info);
996 if (SUCCEEDED(rc))
997 {
998 if (Info.bIsDefault)
999 pPist->push_front(iface);
1000 else
1001 pPist->push_back(iface);
1002 }
1003 else
1004 {
1005 LogRel(("vboxNetWinAddComponent: HostNetworkInterface::init() -> %Rrc\n", rc));
1006 Assert(0);
1007 }
1008 }
1009 else
1010 LogRel(("vboxNetWinAddComponent: failed to get device instance GUID (0x%x)\n", hr));
1011 CoTaskMemFree(lpszName);
1012 }
1013 else
1014 LogRel(("vboxNetWinAddComponent: failed to get device display name (0x%x)\n", hr));
1015
1016 return rc;
1017}
1018
1019#endif /* VBOX_WITH_NETFLT */
1020
1021
1022static int netIfListHostAdapters(INetCfg *pNc, std::list<ComObjPtr<HostNetworkInterface> > &list)
1023{
1024#ifndef VBOX_WITH_NETFLT
1025 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
1026 return VERR_NOT_IMPLEMENTED;
1027#else /* # if defined VBOX_WITH_NETFLT */
1028 INetCfgComponent *pMpNcc;
1029 HRESULT hr;
1030 IEnumNetCfgComponent *pEnumComponent;
1031
1032 hr = pNc->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent);
1033 if (hr == S_OK)
1034 {
1035 while ((hr = pEnumComponent->Next(1, &pMpNcc, NULL)) == S_OK)
1036 {
1037 LPWSTR pwszName;
1038 ULONG uComponentStatus;
1039 hr = pMpNcc->GetDisplayName(&pwszName);
1040 if (hr == S_OK)
1041 Log(("netIfListHostAdapters: %ls\n", pwszName));
1042 else
1043 LogRel(("netIfListHostAdapters: failed to get device display name (0x%x)\n", hr));
1044 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1045 if (hr == S_OK)
1046 {
1047 if (uComponentStatus == 0)
1048 {
1049 LPWSTR pId;
1050 hr = pMpNcc->GetId(&pId);
1051 Assert(hr == S_OK);
1052 if (hr == S_OK)
1053 {
1054 Log(("netIfListHostAdapters: id = %ls\n", pId));
1055 if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1056 {
1057 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
1058 }
1059 CoTaskMemFree(pId);
1060 }
1061 else
1062 LogRel(("netIfListHostAdapters: failed to get device id (0x%x)\n", hr));
1063 }
1064 }
1065 else
1066 LogRel(("netIfListHostAdapters: failed to get device status (0x%x)\n", hr));
1067 pMpNcc->Release();
1068 }
1069 Assert(hr == S_OK || hr == S_FALSE);
1070
1071 pEnumComponent->Release();
1072 }
1073 else
1074 LogRel(("netIfListHostAdapters: EnumComponents error (0x%x)\n", hr));
1075#endif /* # if defined VBOX_WITH_NETFLT */
1076 return VINF_SUCCESS;
1077}
1078
1079int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1080{
1081#ifndef VBOX_WITH_NETFLT
1082 return VERR_NOT_IMPLEMENTED;
1083#else
1084 Bstr name;
1085 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1086 if (hr == S_OK)
1087 {
1088 Bstr IfGuid;
1089 hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1090 Assert(hr == S_OK);
1091 if (hr == S_OK)
1092 {
1093 memset(pInfo, 0, sizeof(NETIFINFO));
1094 Guid guid(IfGuid);
1095 pInfo->Uuid = *(guid.raw());
1096
1097 return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
1098 }
1099 }
1100 return VERR_GENERAL_FAILURE;
1101#endif
1102}
1103
1104int NetIfGetConfigByName(PNETIFINFO)
1105{
1106 return VERR_NOT_IMPLEMENTED;
1107}
1108
1109/**
1110 * Obtain the current state of the interface.
1111 *
1112 * @returns VBox status code.
1113 *
1114 * @param pcszIfName Interface name.
1115 * @param penmState Where to store the retrieved state.
1116 */
1117int NetIfGetState(const char *pcszIfName, NETIFSTATUS *penmState)
1118{
1119 return VERR_NOT_IMPLEMENTED;
1120}
1121
1122/**
1123 * Retrieve the physical link speed in megabits per second. If the interface is
1124 * not up or otherwise unavailable the zero speed is returned.
1125 *
1126 * @returns VBox status code.
1127 *
1128 * @param pcszIfName Interface name.
1129 * @param puMbits Where to store the link speed.
1130 */
1131int NetIfGetLinkSpeed(const char * /*pcszIfName*/, uint32_t * /*puMbits*/)
1132{
1133 return VERR_NOT_IMPLEMENTED;
1134}
1135
1136int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
1137 IHostNetworkInterface **aHostNetworkInterface,
1138 IProgress **aProgress,
1139 const char *pcszName)
1140{
1141#ifndef VBOX_WITH_NETFLT
1142 return VERR_NOT_IMPLEMENTED;
1143#else
1144 /* create a progress object */
1145 ComObjPtr<Progress> progress;
1146 progress.createObject();
1147
1148 ComPtr<IHost> host;
1149 HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1150 if (SUCCEEDED(rc))
1151 {
1152 rc = progress->init(pVirtualBox, host,
1153 Bstr(_T("Creating host only network interface")).raw(),
1154 FALSE /* aCancelable */);
1155 if (SUCCEEDED(rc))
1156 {
1157 if (FAILED(rc)) return rc;
1158 progress.queryInterfaceTo(aProgress);
1159
1160 /* create a new uninitialized host interface object */
1161 ComObjPtr<HostNetworkInterface> iface;
1162 iface.createObject();
1163 iface.queryInterfaceTo(aHostNetworkInterface);
1164
1165 /* create the networkInterfaceHelperClient() argument */
1166 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1167
1168 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1169// d->name = aName;
1170 d->iface = iface;
1171 d->vBox = pVirtualBox;
1172
1173 rc = pVirtualBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1174 netIfNetworkInterfaceHelperClient,
1175 static_cast<void *>(d),
1176 progress);
1177 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1178
1179 }
1180 }
1181
1182 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1183#endif
1184}
1185
1186int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IN_GUID aId,
1187 IProgress **aProgress)
1188{
1189#ifndef VBOX_WITH_NETFLT
1190 return VERR_NOT_IMPLEMENTED;
1191#else
1192 /* create a progress object */
1193 ComObjPtr<Progress> progress;
1194 progress.createObject();
1195 ComPtr<IHost> host;
1196 HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1197 if (SUCCEEDED(rc))
1198 {
1199 rc = progress->init(pVirtualBox, host,
1200 Bstr(_T("Removing host network interface")).raw(),
1201 FALSE /* aCancelable */);
1202 if (SUCCEEDED(rc))
1203 {
1204 if (FAILED(rc)) return rc;
1205 progress.queryInterfaceTo(aProgress);
1206
1207 /* create the networkInterfaceHelperClient() argument */
1208 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1209
1210 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1211 d->guid = aId;
1212
1213 rc = pVirtualBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1214 netIfNetworkInterfaceHelperClient,
1215 static_cast<void *>(d),
1216 progress);
1217 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1218
1219 }
1220 }
1221
1222 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1223#endif
1224}
1225
1226int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1227{
1228#ifndef VBOX_WITH_NETFLT
1229 return VERR_NOT_IMPLEMENTED;
1230#else
1231 HRESULT rc;
1232 Bstr guid;
1233 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1234 if (SUCCEEDED(rc))
1235 {
1236// ComPtr<VirtualBox> vBox;
1237// rc = pIf->getVirtualBox(vBox.asOutParam());
1238// if (SUCCEEDED(rc))
1239 {
1240 /* create a progress object */
1241 ComObjPtr<Progress> progress;
1242 progress.createObject();
1243// ComPtr<IHost> host;
1244// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1245// if (SUCCEEDED(rc))
1246 {
1247 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1248 Bstr("Enabling Dynamic Ip Configuration").raw(),
1249 FALSE /* aCancelable */);
1250 if (SUCCEEDED(rc))
1251 {
1252 if (FAILED(rc)) return rc;
1253// progress.queryInterfaceTo(aProgress);
1254
1255 /* create the networkInterfaceHelperClient() argument */
1256 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1257
1258 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1259 d->guid = Guid(guid);
1260 d->iface = pIf;
1261 d->u.StaticIP.IPAddress = ip;
1262 d->u.StaticIP.IPNetMask = mask;
1263
1264 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1265 netIfNetworkInterfaceHelperClient,
1266 static_cast<void *>(d),
1267 progress);
1268 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1269
1270 if (SUCCEEDED(rc))
1271 {
1272 progress->WaitForCompletion(-1);
1273 }
1274 }
1275 }
1276 }
1277 }
1278
1279 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1280#endif
1281}
1282
1283int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address,
1284 IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1285{
1286#ifndef VBOX_WITH_NETFLT
1287 return VERR_NOT_IMPLEMENTED;
1288#else
1289 HRESULT rc;
1290 Bstr guid;
1291 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1292 if (SUCCEEDED(rc))
1293 {
1294// ComPtr<VirtualBox> vBox;
1295// rc = pIf->getVirtualBox(vBox.asOutParam());
1296// if (SUCCEEDED(rc))
1297 {
1298 /* create a progress object */
1299 ComObjPtr<Progress> progress;
1300 progress.createObject();
1301// ComPtr<IHost> host;
1302// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1303// if (SUCCEEDED(rc))
1304 {
1305 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1306 Bstr("Enabling Dynamic Ip Configuration").raw(),
1307 FALSE /* aCancelable */);
1308 if (SUCCEEDED(rc))
1309 {
1310 if (FAILED(rc)) return rc;
1311// progress.queryInterfaceTo(aProgress);
1312
1313 /* create the networkInterfaceHelperClient() argument */
1314 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1315
1316 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1317 d->guid = guid;
1318 d->iface = pIf;
1319 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1320 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1321
1322 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1323 netIfNetworkInterfaceHelperClient,
1324 static_cast<void *>(d),
1325 progress);
1326 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1327
1328 if (SUCCEEDED(rc))
1329 {
1330 progress->WaitForCompletion(-1);
1331 }
1332 }
1333 }
1334 }
1335 }
1336
1337 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1338#endif
1339}
1340
1341int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1342{
1343#ifndef VBOX_WITH_NETFLT
1344 return VERR_NOT_IMPLEMENTED;
1345#else
1346 HRESULT rc;
1347 Bstr guid;
1348 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1349 if (SUCCEEDED(rc))
1350 {
1351// ComPtr<VirtualBox> vBox;
1352// rc = pIf->getVirtualBox(vBox.asOutParam());
1353// if (SUCCEEDED(rc))
1354 {
1355 /* create a progress object */
1356 ComObjPtr<Progress> progress;
1357 progress.createObject();
1358// ComPtr<IHost> host;
1359// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1360// if (SUCCEEDED(rc))
1361 {
1362 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1363 Bstr("Enabling Dynamic Ip Configuration").raw(),
1364 FALSE /* aCancelable */);
1365 if (SUCCEEDED(rc))
1366 {
1367 if (FAILED(rc)) return rc;
1368// progress.queryInterfaceTo(aProgress);
1369
1370 /* create the networkInterfaceHelperClient() argument */
1371 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1372
1373 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1374 d->guid = guid;
1375 d->iface = pIf;
1376
1377 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1378 netIfNetworkInterfaceHelperClient,
1379 static_cast<void *>(d),
1380 progress);
1381 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1382
1383 if (SUCCEEDED(rc))
1384 {
1385 progress->WaitForCompletion(-1);
1386 }
1387 }
1388 }
1389 }
1390 }
1391
1392 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1393#endif
1394}
1395
1396int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1397{
1398#ifndef VBOX_WITH_NETFLT
1399 return VERR_NOT_IMPLEMENTED;
1400#else
1401 HRESULT rc;
1402 Bstr guid;
1403 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1404 if (SUCCEEDED(rc))
1405 {
1406// ComPtr<VirtualBox> vBox;
1407// rc = pIf->getVirtualBox(vBox.asOutParam());
1408// if (SUCCEEDED(rc))
1409 {
1410 /* create a progress object */
1411 ComObjPtr<Progress> progress;
1412 progress.createObject();
1413// ComPtr<IHost> host;
1414// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1415// if (SUCCEEDED(rc))
1416 {
1417 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1418 Bstr("Enabling Dynamic Ip Configuration").raw(),
1419 FALSE /* aCancelable */);
1420 if (SUCCEEDED(rc))
1421 {
1422 if (FAILED(rc)) return rc;
1423// progress.queryInterfaceTo(aProgress);
1424
1425 /* create the networkInterfaceHelperClient() argument */
1426 NetworkInterfaceHelperClientData* d = new NetworkInterfaceHelperClientData();
1427
1428 d->msgCode = SVCHlpMsg::DhcpRediscover;
1429 d->guid = guid;
1430 d->iface = pIf;
1431
1432 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1433 netIfNetworkInterfaceHelperClient,
1434 static_cast<void *>(d),
1435 progress);
1436 /* d is now owned by netIfNetworkInterfaceHelperClient(), no need to delete one here */
1437
1438 if (SUCCEEDED(rc))
1439 {
1440 progress->WaitForCompletion(-1);
1441 }
1442 }
1443 }
1444 }
1445 }
1446
1447 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1448#endif
1449}
1450
1451
1452#define netIfLog Log
1453
1454struct BoundAdapter
1455{
1456 LPWSTR pName;
1457 LPWSTR pHwId;
1458 RTUUID guid;
1459 PIP_ADAPTER_ADDRESSES pAdapter;
1460};
1461
1462static int netIfGetUnboundHostOnlyAdapters(INetCfg *pNetCfg, std::list<BoundAdapter> &adapters)
1463{
1464 INetCfgComponent *pMiniport;
1465 HRESULT hr;
1466 IEnumNetCfgComponent *pEnumComponent;
1467
1468 if ((hr = pNetCfg->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent)) != S_OK)
1469 LogRel(("netIfGetUnboundHostOnlyAdapters: failed to enumerate network adapter components (0x%x)\n", hr));
1470 else
1471 {
1472 while ((hr = pEnumComponent->Next(1, &pMiniport, NULL)) == S_OK)
1473 {
1474 GUID guid;
1475 ULONG uComponentStatus;
1476 struct BoundAdapter adapter;
1477 memset(&adapter, 0, sizeof(adapter));
1478 if ((hr = pMiniport->GetDisplayName(&adapter.pName)) != S_OK)
1479 LogRel(("netIfGetUnboundHostOnlyAdapters: failed to get device display name (0x%x)\n", hr));
1480 else if ((hr = pMiniport->GetDeviceStatus(&uComponentStatus)) != S_OK)
1481 netIfLog(("netIfGetUnboundHostOnlyAdapters: failed to get device status (0x%x)\n", hr));
1482 else if (uComponentStatus != 0)
1483 netIfLog(("netIfGetUnboundHostOnlyAdapters: wrong device status (0x%x)\n", uComponentStatus));
1484 else if ((hr = pMiniport->GetId(&adapter.pHwId)) != S_OK)
1485 LogRel(("netIfGetUnboundHostOnlyAdapters: failed to get device id (0x%x)\n", hr));
1486 else if (_wcsnicmp(adapter.pHwId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1487 netIfLog(("netIfGetUnboundHostOnlyAdapters: not host-only id = %ls, ignored\n", adapter.pHwId));
1488 else if ((hr = pMiniport->GetInstanceGuid(&guid)) != S_OK)
1489 LogRel(("netIfGetUnboundHostOnlyAdapters: failed to get instance id (0x%x)\n", hr));
1490 else
1491 {
1492 adapter.guid = *(Guid(guid).raw());
1493 netIfLog(("netIfGetUnboundHostOnlyAdapters: guid=%RTuuid, name=%ls id = %ls\n", &adapter.guid, adapter.pName, adapter.pHwId));
1494 adapters.push_back(adapter);
1495 adapter.pName = adapter.pHwId = NULL; /* do not free, will be done later */
1496 }
1497 if (adapter.pHwId)
1498 CoTaskMemFree(adapter.pHwId);
1499 if (adapter.pName)
1500 CoTaskMemFree(adapter.pName);
1501 pMiniport->Release();
1502 }
1503 Assert(hr == S_OK || hr == S_FALSE);
1504
1505 pEnumComponent->Release();
1506 }
1507 netIfLog(("netIfGetUnboundHostOnlyAdapters: return\n"));
1508 return VINF_SUCCESS;
1509}
1510
1511static HRESULT netIfGetBoundAdapters(std::list<BoundAdapter> &boundAdapters)
1512{
1513 INetCfg *pNetCfg = NULL;
1514 INetCfgComponent *pFilter;
1515 LPWSTR lpszApp;
1516 HRESULT hr;
1517
1518 netIfLog(("netIfGetBoundAdapters: building the list of interfaces\n"));
1519 /* we are using the INetCfg API for getting the list of miniports */
1520 hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, FALSE,
1521 VBOX_APP_NAME,
1522 10000,
1523 &lpszApp);
1524 Assert(hr == S_OK);
1525 if (hr != S_OK)
1526 {
1527 LogRel(("netIfGetBoundAdapters: failed to query INetCfg (0x%x)\n", hr));
1528 return hr;
1529 }
1530
1531 if ((hr = pNetCfg->FindComponent(L"oracle_VBoxNetLwf", &pFilter)) != S_OK
1532 /* fall back to NDIS5 miniport lookup */
1533 && (hr = pNetCfg->FindComponent(L"sun_VBoxNetFlt", &pFilter)))
1534 LogRel(("netIfGetBoundAdapters: could not find either 'oracle_VBoxNetLwf' or 'sun_VBoxNetFlt' components (0x%x)\n", hr));
1535 else
1536 {
1537 INetCfgComponentBindings *pFilterBindings;
1538 if ((pFilter->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pFilterBindings)) != S_OK)
1539 LogRel(("netIfGetBoundAdapters: failed to query INetCfgComponentBindings (0x%x)\n", hr));
1540 else
1541 {
1542 IEnumNetCfgBindingPath *pEnumBp;
1543 INetCfgBindingPath *pBp;
1544 if ((pFilterBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp)) != S_OK)
1545 LogRel(("netIfGetBoundAdapters: failed to enumerate binding paths (0x%x)\n", hr));
1546 else
1547 {
1548 pEnumBp->Reset();
1549 while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
1550 {
1551 IEnumNetCfgBindingInterface *pEnumBi;
1552 INetCfgBindingInterface *pBi;
1553 if (pBp->IsEnabled() != S_OK)
1554 {
1555 /* @todo some id of disabled path could be useful. */
1556 netIfLog(("netIfGetBoundAdapters: INetCfgBindingPath is disabled (0x%x)\n", hr));
1557 pBp->Release();
1558 continue;
1559 }
1560 if ((pBp->EnumBindingInterfaces(&pEnumBi)) != S_OK)
1561 LogRel(("netIfGetBoundAdapters: failed to enumerate binding interfaces (0x%x)\n", hr));
1562 else
1563 {
1564 hr = pEnumBi->Reset();
1565 while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
1566 {
1567 INetCfgComponent *pAdapter;
1568 if ((hr = pBi->GetLowerComponent(&pAdapter)) != S_OK)
1569 LogRel(("netIfGetBoundAdapters: failed to get lower component (0x%x)\n", hr));
1570 else
1571 {
1572 LPWSTR pwszName = NULL;
1573 if ((hr = pAdapter->GetDisplayName(&pwszName)) != S_OK)
1574 LogRel(("netIfGetBoundAdapters: failed to get display name (0x%x)\n", hr));
1575 else
1576 {
1577 ULONG uStatus;
1578 DWORD dwChars;
1579 if ((hr = pAdapter->GetDeviceStatus(&uStatus)) != S_OK)
1580 netIfLog(("netIfGetBoundAdapters: %ls: failed to get device status (0x%x)\n",
1581 pwszName, hr));
1582 else if ((hr = pAdapter->GetCharacteristics(&dwChars)) != S_OK)
1583 netIfLog(("netIfGetBoundAdapters: %ls: failed to get device characteristics (0x%x)\n",
1584 pwszName, hr));
1585 else if (uStatus != 0)
1586 netIfLog(("netIfGetBoundAdapters: %ls: wrong status 0x%x\n",
1587 pwszName, uStatus));
1588 else if (dwChars & NCF_HIDDEN)
1589 netIfLog(("netIfGetBoundAdapters: %ls: wrong characteristics 0x%x\n",
1590 pwszName, dwChars));
1591 else
1592 {
1593 GUID guid;
1594 LPWSTR pwszHwId = NULL;
1595 if ((hr = pAdapter->GetId(&pwszHwId)) != S_OK)
1596 LogRel(("netIfGetBoundAdapters: %ls: failed to get hardware id (0x%x)\n",
1597 pwszName, hr));
1598 else if (!_wcsnicmp(pwszHwId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1599 netIfLog(("netIfGetBoundAdapters: host-only adapter %ls, ignored\n", pwszName));
1600 else if ((hr = pAdapter->GetInstanceGuid(&guid)) != S_OK)
1601 LogRel(("netIfGetBoundAdapters: %ls: failed to get instance GUID (0x%x)\n",
1602 pwszName, hr));
1603 else
1604 {
1605 struct BoundAdapter adapter;
1606 adapter.pName = pwszName;
1607 adapter.pHwId = pwszHwId;
1608 adapter.guid = *(Guid(guid).raw());
1609 adapter.pAdapter = NULL;
1610 netIfLog(("netIfGetBoundAdapters: guid=%RTuuid, name=%ls, hwid=%ls, status=%x, chars=%x\n",
1611 &adapter.guid, pwszName, pwszHwId, uStatus, dwChars));
1612 boundAdapters.push_back(adapter);
1613 pwszName = pwszHwId = NULL; /* do not free, will be done later */
1614 }
1615 if (pwszHwId)
1616 CoTaskMemFree(pwszHwId);
1617 }
1618 if (pwszName)
1619 CoTaskMemFree(pwszName);
1620 }
1621
1622 pAdapter->Release();
1623 }
1624 pBi->Release();
1625 }
1626 pEnumBi->Release();
1627 }
1628 pBp->Release();
1629 }
1630 pEnumBp->Release();
1631 }
1632 pFilterBindings->Release();
1633 }
1634 pFilter->Release();
1635 }
1636 /* Host-only adapters are not necessarily bound, add them separately. */
1637 netIfGetUnboundHostOnlyAdapters(pNetCfg, boundAdapters);
1638 VBoxNetCfgWinReleaseINetCfg(pNetCfg, FALSE);
1639
1640 return S_OK;
1641}
1642
1643#if 0
1644static HRESULT netIfGetBoundAdaptersFallback(std::list<BoundAdapter> &boundAdapters)
1645{
1646 return CO_E_NOT_SUPPORTED;
1647}
1648#endif
1649
1650static void netIfFillInfoWithAddressesXp(PNETIFINFO pInfo, PIP_ADAPTER_ADDRESSES pAdapter)
1651{
1652 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
1653 bool fIPFound = false;
1654 bool fIPv6Found = false;
1655 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
1656 {
1657 switch (pAddr->Address.lpSockaddr->sa_family)
1658 {
1659 case AF_INET:
1660 if (!fIPFound)
1661 {
1662 fIPFound = true;
1663 memcpy(&pInfo->IPAddress,
1664 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
1665 sizeof(pInfo->IPAddress));
1666 }
1667 break;
1668 case AF_INET6:
1669 if (!fIPv6Found)
1670 {
1671 fIPv6Found = true;
1672 memcpy(&pInfo->IPv6Address,
1673 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
1674 sizeof(pInfo->IPv6Address));
1675 }
1676 break;
1677 }
1678 }
1679 PIP_ADAPTER_PREFIX pPrefix;
1680 ULONG uPrefixLenV4 = 0;
1681 ULONG uPrefixLenV6 = 0;
1682 for (pPrefix = pAdapter->FirstPrefix; pPrefix && !(uPrefixLenV4 && uPrefixLenV6); pPrefix = pPrefix->Next)
1683 {
1684 switch (pPrefix->Address.lpSockaddr->sa_family)
1685 {
1686 case AF_INET:
1687 if (!uPrefixLenV4)
1688 {
1689 ULONG ip = ((PSOCKADDR_IN)(pPrefix->Address.lpSockaddr))->sin_addr.s_addr;
1690 netIfLog(("netIfFillInfoWithAddressesXp: prefix=%RTnaipv4 len=%u\n", ip, pPrefix->PrefixLength));
1691 if ( pPrefix->PrefixLength < sizeof(pInfo->IPNetMask) * 8
1692 && pPrefix->PrefixLength > 0
1693 && (ip & 0xF0) < 224)
1694 {
1695 uPrefixLenV4 = pPrefix->PrefixLength;
1696 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
1697 }
1698 else
1699 netIfLog(("netIfFillInfoWithAddressesXp: Unexpected IPv4 prefix length of %d\n",
1700 pPrefix->PrefixLength));
1701 }
1702 break;
1703 case AF_INET6:
1704 if (!uPrefixLenV6)
1705 {
1706 PBYTE ipv6 = ((PSOCKADDR_IN6)(pPrefix->Address.lpSockaddr))->sin6_addr.s6_addr;
1707 netIfLog(("netIfFillInfoWithAddressesXp: prefix=%RTnaipv6 len=%u\n",
1708 ipv6, pPrefix->PrefixLength));
1709 if ( pPrefix->PrefixLength < sizeof(pInfo->IPv6NetMask) * 8
1710 && pPrefix->PrefixLength > 0
1711 && ipv6[0] != 0xFF)
1712 {
1713 uPrefixLenV6 = pPrefix->PrefixLength;
1714 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
1715 }
1716 else
1717 netIfLog(("netIfFillInfoWithAddressesXp: Unexpected IPv6 prefix length of %d\n",
1718 pPrefix->PrefixLength));
1719 }
1720 break;
1721 }
1722 }
1723 netIfLog(("netIfFillInfoWithAddressesXp: %RTnaipv4/%u\n",
1724 pInfo->IPAddress, uPrefixLenV4));
1725 netIfLog(("netIfFillInfoWithAddressesXp: %RTnaipv6/%u\n",
1726 &pInfo->IPv6Address, uPrefixLenV6));
1727}
1728
1729static void netIfFillInfoWithAddresses(PNETIFINFO pInfo, PIP_ADAPTER_ADDRESSES pAdapter)
1730{
1731 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
1732
1733 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
1734 netIfLog(("netIfFillInfoWithAddresses: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
1735 else
1736 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
1737
1738 bool fIPFound = false;
1739 bool fIPv6Found = false;
1740 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
1741 {
1742 if (pAddr->Length < sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH))
1743 {
1744 netIfLog(("netIfFillInfoWithAddresses: unicast address is too small (%u < %u), fall back to XP implementation\n",
1745 pAddr->Length, sizeof(IP_ADAPTER_UNICAST_ADDRESS_LH)));
1746 return netIfFillInfoWithAddressesXp(pInfo, pAdapter);
1747 }
1748 PIP_ADAPTER_UNICAST_ADDRESS_LH pAddrLh = (PIP_ADAPTER_UNICAST_ADDRESS_LH)pAddr;
1749 switch (pAddrLh->Address.lpSockaddr->sa_family)
1750 {
1751 case AF_INET:
1752 if (!fIPFound)
1753 {
1754 fIPFound = true;
1755 memcpy(&pInfo->IPAddress,
1756 &((struct sockaddr_in *)pAddrLh->Address.lpSockaddr)->sin_addr.s_addr,
1757 sizeof(pInfo->IPAddress));
1758 if (pAddrLh->OnLinkPrefixLength > 32)
1759 netIfLog(("netIfFillInfoWithAddresses: Invalid IPv4 prefix length of %d\n", pAddrLh->OnLinkPrefixLength));
1760 else
1761 ASMBitSetRange(&pInfo->IPNetMask, 0, pAddrLh->OnLinkPrefixLength);
1762 }
1763 break;
1764 case AF_INET6:
1765 if (!fIPv6Found)
1766 {
1767 fIPv6Found = true;
1768 memcpy(&pInfo->IPv6Address,
1769 ((struct sockaddr_in6 *)pAddrLh->Address.lpSockaddr)->sin6_addr.s6_addr,
1770 sizeof(pInfo->IPv6Address));
1771 if (pAddrLh->OnLinkPrefixLength > 128)
1772 netIfLog(("netIfFillInfoWithAddresses: Invalid IPv6 prefix length of %d\n", pAddrLh->OnLinkPrefixLength));
1773 else
1774 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pAddrLh->OnLinkPrefixLength);
1775 }
1776 break;
1777 }
1778 }
1779 netIfLog(("netIfFillInfoWithAddresses: %RTnaipv4/%u\n",
1780 pInfo->IPAddress, ASMBitFirstClear(&pInfo->IPNetMask, sizeof(RTNETADDRIPV4)*8)));
1781 netIfLog(("netIfFillInfoWithAddresses: %RTnaipv6/%u\n",
1782 &pInfo->IPv6Address, composeIPv6PrefixLenghFromAddress(&pInfo->IPv6NetMask)));
1783}
1784
1785#if (NTDDI_VERSION >= NTDDI_VISTA)
1786#define NETIF_GAA_FLAGS GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST
1787#else /* (NTDDI_VERSION < NTDDI_VISTA) */
1788#define NETIF_GAA_FLAGS GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST
1789#endif /* (NTDDI_VERSION < NTDDI_VISTA) */
1790
1791int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1792{
1793 HRESULT hr = S_OK;
1794 int iDefault = getDefaultInterfaceIndex();
1795 /* MSDN recommends to pre-allocate a 15KB buffer. */
1796 ULONG uBufLen = 15 * 1024;
1797 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
1798 if (!pAddresses)
1799 return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
1800 DWORD dwRc = GetAdaptersAddresses(AF_UNSPEC, NETIF_GAA_FLAGS, NULL, pAddresses, &uBufLen);
1801 for (int tries = 0; tries < 3 && dwRc == ERROR_BUFFER_OVERFLOW; ++tries)
1802 {
1803 /* Get more memory and try again. */
1804 free(pAddresses);
1805 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
1806 if (!pAddresses)
1807 return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
1808 dwRc = GetAdaptersAddresses(AF_UNSPEC, NETIF_GAA_FLAGS, NULL, pAddresses, &uBufLen);
1809 }
1810 if (dwRc != NO_ERROR)
1811 {
1812 LogRel(("NetIfList: GetAdaptersAddresses failed (0x%x)\n", dwRc));
1813 hr = HRESULT_FROM_WIN32(dwRc);
1814 }
1815 else
1816 {
1817 std::list<BoundAdapter> boundAdapters;
1818 HRESULT hr = netIfGetBoundAdapters(boundAdapters);
1819#if 0
1820 if (hr != S_OK)
1821 hr = netIfGetBoundAdaptersFallback(boundAdapters);
1822#endif
1823 if (hr != S_OK)
1824 LogRel(("NetIfList: netIfGetBoundAdapters failed (0x%x)\n", hr));
1825 else
1826 {
1827 PIP_ADAPTER_ADDRESSES pAdapter;
1828
1829 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
1830 {
1831 char *pszUuid = RTStrDup(pAdapter->AdapterName);
1832 if (!pszUuid)
1833 {
1834 LogRel(("NetIfList: out of memory\n"));
1835 break;
1836 }
1837 size_t len = strlen(pszUuid) - 1;
1838 if (pszUuid[0] != '{' || pszUuid[len] != '}')
1839 LogRel(("NetIfList: ignoring invalid GUID %s\n", pAdapter->AdapterName));
1840 else
1841 {
1842 std::list<BoundAdapter>::iterator it;
1843 pszUuid[len] = 0;
1844 for (it = boundAdapters.begin(); it != boundAdapters.end(); ++it)
1845 {
1846 if (!RTUuidCompareStr(&(*it).guid, pszUuid + 1))
1847 {
1848 (*it).pAdapter = pAdapter;
1849 break;
1850 }
1851 }
1852 }
1853 RTStrFree(pszUuid);
1854 }
1855 std::list<BoundAdapter>::iterator it;
1856 for (it = boundAdapters.begin(); it != boundAdapters.end(); ++it)
1857 {
1858 NETIFINFO info;
1859 memset(&info, 0, sizeof(info));
1860 info.Uuid = (*it).guid;
1861 info.enmMediumType = NETIF_T_ETHERNET;
1862 pAdapter = (*it).pAdapter;
1863 if (pAdapter)
1864 {
1865 info.enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
1866 info.bIsDefault = (pAdapter->IfIndex == iDefault);
1867 info.bDhcpEnabled = pAdapter->Flags & IP_ADAPTER_DHCP_ENABLED;
1868 netIfFillInfoWithAddresses(&info, pAdapter);
1869 }
1870 else
1871 info.enmStatus = NETIF_S_DOWN;
1872 /* create a new object and add it to the list */
1873 ComObjPtr<HostNetworkInterface> iface;
1874 iface.createObject();
1875 HostNetworkInterfaceType enmType =
1876 _wcsnicmp((*it).pHwId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2) ?
1877 HostNetworkInterfaceType_Bridged : HostNetworkInterfaceType_HostOnly;
1878 netIfLog(("Adding %ls as %s\n", (*it).pName,
1879 enmType == HostNetworkInterfaceType_Bridged ? "bridged" :
1880 enmType == HostNetworkInterfaceType_HostOnly ? "host-only" : "unknown"));
1881 int rc = iface->init((*it).pName, enmType, &info);
1882 if (FAILED(rc))
1883 LogRel(("NetIfList: HostNetworkInterface::init() -> %Rrc\n", rc));
1884 else
1885 {
1886 if (info.bIsDefault)
1887 list.push_front(iface);
1888 else
1889 list.push_back(iface);
1890 }
1891 if ((*it).pHwId)
1892 CoTaskMemFree((*it).pHwId);
1893 if ((*it).pName)
1894 CoTaskMemFree((*it).pName);
1895 }
1896 }
1897 }
1898 RTMemFree(pAddresses);
1899
1900 return hr;
1901}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette