VirtualBox

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

Last change on this file since 35356 was 35356, checked in by vboxsync, 14 years ago

Main/NetIf: Default (primary) NIC detection on Windows hosts (#3773)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 51.8 KB
Line 
1/* $Id: NetIf-win.cpp 35356 2010-12-27 21:00:23Z vboxsync $ */
2/** @file
3 * Main - NetIfList, Windows implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2010 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#include <iprt/asm.h>
26#include <iprt/err.h>
27#include <list>
28
29#define _WIN32_DCOM
30#include <winsock2.h>
31#include <ws2tcpip.h>
32#include <windows.h>
33
34#ifdef VBOX_WITH_NETFLT
35#include "VBox/WinNetConfig.h"
36#include "devguid.h"
37#endif
38
39#include <iphlpapi.h>
40
41#include "Logging.h"
42#include "HostNetworkInterfaceImpl.h"
43#include "ProgressImpl.h"
44#include "VirtualBoxImpl.h"
45#include "netif.h"
46
47#ifdef VBOX_WITH_NETFLT
48#include <Wbemidl.h>
49#include <comdef.h>
50
51#include "svchlp.h"
52
53#include <shellapi.h>
54#define INITGUID
55#include <guiddef.h>
56#include <devguid.h>
57#include <objbase.h>
58#include <setupapi.h>
59#include <shlobj.h>
60#include <cfgmgr32.h>
61
62#define VBOX_APP_NAME L"VirtualBox"
63
64static int getDefaultInterfaceIndex()
65{
66 PMIB_IPFORWARDTABLE pIpTable;
67 DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
68 DWORD dwRC = NO_ERROR;
69 int iIndex = -1;
70
71 pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
72 if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
73 {
74 RTMemFree(pIpTable);
75 pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
76 if (!pIpTable)
77 return -1;
78 }
79 dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
80 if (dwRC == NO_ERROR)
81 {
82 for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
83 if (pIpTable->table[i].dwForwardDest == 0)
84 {
85 iIndex = pIpTable->table[i].dwForwardIfIndex;
86 break;
87 }
88 }
89 RTMemFree(pIpTable);
90 return iIndex;
91}
92
93static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
94{
95 DWORD dwRc;
96 int rc = VINF_SUCCESS;
97 /*
98 * Most of the hosts probably have less than 10 adapters,
99 * so we'll mostly succeed from the first attempt.
100 */
101 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
102 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
103 if (!pAddresses)
104 return VERR_NO_MEMORY;
105 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
106 if (dwRc == ERROR_BUFFER_OVERFLOW)
107 {
108 /* Impressive! More than 10 adapters! Get more memory and try again. */
109 RTMemFree(pAddresses);
110 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
111 if (!pAddresses)
112 return VERR_NO_MEMORY;
113 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
114 }
115 if (dwRc == NO_ERROR)
116 {
117 PIP_ADAPTER_ADDRESSES pAdapter;
118 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
119 {
120 char *pszUuid = RTStrDup(pAdapter->AdapterName);
121 size_t len = strlen(pszUuid) - 1;
122 if (pszUuid[0] == '{' && pszUuid[len] == '}')
123 {
124 pszUuid[len] = 0;
125 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
126 {
127 bool fIPFound, fIPv6Found;
128 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
129 fIPFound = fIPv6Found = false;
130 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
131 {
132 switch (pAddr->Address.lpSockaddr->sa_family)
133 {
134 case AF_INET:
135 if (!fIPFound)
136 {
137 fIPFound = true;
138 memcpy(&pInfo->IPAddress,
139 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
140 sizeof(pInfo->IPAddress));
141 }
142 break;
143 case AF_INET6:
144 if (!fIPv6Found)
145 {
146 fIPv6Found = true;
147 memcpy(&pInfo->IPv6Address,
148 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
149 sizeof(pInfo->IPv6Address));
150 }
151 break;
152 }
153 }
154 PIP_ADAPTER_PREFIX pPrefix;
155 fIPFound = fIPv6Found = false;
156 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
157 {
158 switch (pPrefix->Address.lpSockaddr->sa_family)
159 {
160 case AF_INET:
161 if (!fIPFound)
162 {
163 if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
164 {
165 fIPFound = true;
166 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
167 }
168 else
169 Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
170 pPrefix->PrefixLength));
171 }
172 break;
173 case AF_INET6:
174 if (!fIPv6Found)
175 {
176 if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
177 {
178 fIPv6Found = true;
179 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
180 }
181 else
182 Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
183 pPrefix->PrefixLength));
184 }
185 break;
186 }
187 }
188 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
189 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
190 else
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);
195 RTStrFree(pszUuid);
196 break;
197 }
198 }
199 RTStrFree(pszUuid);
200 }
201
202 ADAPTER_SETTINGS Settings;
203 HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
204 if (hr == S_OK)
205 {
206 if (Settings.ip)
207 {
208 pInfo->IPAddress.u = Settings.ip;
209 pInfo->IPNetMask.u = Settings.mask;
210 }
211 pInfo->bDhcpEnabled = Settings.bDhcp;
212 }
213 else
214 {
215 pInfo->bDhcpEnabled = false;
216 }
217 }
218 RTMemFree(pAddresses);
219
220 return VINF_SUCCESS;
221}
222
223/* svc helper func */
224
225struct StaticIpConfig
226{
227 ULONG IPAddress;
228 ULONG IPNetMask;
229};
230
231struct StaticIpV6Config
232{
233 BSTR IPV6Address;
234 ULONG IPV6NetMaskLength;
235};
236
237struct NetworkInterfaceHelperClientData
238{
239 SVCHlpMsg::Code msgCode;
240 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
241 Bstr name;
242 ComObjPtr<HostNetworkInterface> iface;
243 ComObjPtr<VirtualBox> vBox;
244 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
245 Guid guid;
246
247 union
248 {
249 StaticIpConfig StaticIP;
250 StaticIpV6Config StaticIPV6;
251 } u;
252
253
254};
255
256static HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
257 Progress *aProgress,
258 void *aUser, int *aVrc)
259{
260 LogFlowFuncEnter();
261 LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
262 aClient, aProgress, aUser));
263
264 AssertReturn( (aClient == NULL && aProgress == NULL && aVrc == NULL)
265 || (aClient != NULL && aProgress != NULL && aVrc != NULL),
266 E_POINTER);
267 AssertReturn(aUser, E_POINTER);
268
269 std::auto_ptr<NetworkInterfaceHelperClientData>
270 d(static_cast<NetworkInterfaceHelperClientData *>(aUser));
271
272 if (aClient == NULL)
273 {
274 /* "cleanup only" mode, just return (it will free aUser) */
275 return S_OK;
276 }
277
278 HRESULT rc = S_OK;
279 int vrc = VINF_SUCCESS;
280
281 switch (d->msgCode)
282 {
283 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
284 {
285 LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
286 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
287
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;
293
294 /* wait for a reply */
295 bool endLoop = false;
296 while (!endLoop)
297 {
298 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
299
300 vrc = aClient->read(reply);
301 if (RT_FAILURE(vrc)) break;
302
303 switch (reply)
304 {
305 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
306 {
307 /* read the GUID */
308 Guid guid;
309 Utf8Str name;
310 vrc = aClient->read(name);
311 if (RT_FAILURE(vrc)) break;
312 vrc = aClient->read(guid);
313 if (RT_FAILURE(vrc)) break;
314
315 LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
316
317 /* initialize the object returned to the caller by
318 * CreateHostOnlyNetworkInterface() */
319 rc = d->iface->init(Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
320 if (SUCCEEDED(rc))
321 {
322 rc = d->iface->setVirtualBox(d->vBox);
323 if (SUCCEEDED(rc))
324 {
325 rc = d->iface->updateConfig();
326 }
327 }
328 endLoop = true;
329 break;
330 }
331 case SVCHlpMsg::Error:
332 {
333 /* read the error message */
334 Utf8Str errMsg;
335 vrc = aClient->read(errMsg);
336 if (RT_FAILURE(vrc)) break;
337
338 rc = E_FAIL;//TODO: setError(E_FAIL, errMsg);
339 endLoop = true;
340 break;
341 }
342 default:
343 {
344 endLoop = true;
345 rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
346 //"Invalid message code %d (%08lX)\n",
347 //reply, reply),
348 //rc = E_FAIL);
349 }
350 }
351 }
352
353 break;
354 }
355 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
356 {
357 LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
358 LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
359
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;
365
366 /* wait for a reply */
367 bool endLoop = false;
368 while (!endLoop)
369 {
370 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
371
372 vrc = aClient->read(reply);
373 if (RT_FAILURE(vrc)) break;
374
375 switch (reply)
376 {
377 case SVCHlpMsg::OK:
378 {
379 /* no parameters */
380 rc = S_OK;
381 endLoop = true;
382 break;
383 }
384 case SVCHlpMsg::Error:
385 {
386 /* read the error message */
387 Utf8Str errMsg;
388 vrc = aClient->read(errMsg);
389 if (RT_FAILURE(vrc)) break;
390
391 rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
392 endLoop = true;
393 break;
394 }
395 default:
396 {
397 endLoop = true;
398 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
399 //"Invalid message code %d (%08lX)\n",
400 //reply, reply),
401 //rc = E_FAIL);
402 }
403 }
404 }
405
406 break;
407 }
408 case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
409 {
410 LogFlowFunc(("EnableDynamicIpConfig:\n"));
411 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
412
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;
418
419 /* wait for a reply */
420 bool endLoop = false;
421 while (!endLoop)
422 {
423 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
424
425 vrc = aClient->read(reply);
426 if (RT_FAILURE(vrc)) break;
427
428 switch (reply)
429 {
430 case SVCHlpMsg::OK:
431 {
432 /* no parameters */
433 rc = d->iface->updateConfig();
434 endLoop = true;
435 break;
436 }
437 case SVCHlpMsg::Error:
438 {
439 /* read the error message */
440 Utf8Str errMsg;
441 vrc = aClient->read(errMsg);
442 if (RT_FAILURE(vrc)) break;
443
444 rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
445 endLoop = true;
446 break;
447 }
448 default:
449 {
450 endLoop = true;
451 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
452 //"Invalid message code %d (%08lX)\n",
453 //reply, reply),
454 //rc = E_FAIL);
455 }
456 }
457 }
458
459 break;
460 }
461 case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
462 {
463 LogFlowFunc(("EnableStaticIpConfig:\n"));
464 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
465
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;
475
476 /* wait for a reply */
477 bool endLoop = false;
478 while (!endLoop)
479 {
480 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
481
482 vrc = aClient->read(reply);
483 if (RT_FAILURE(vrc)) break;
484
485 switch (reply)
486 {
487 case SVCHlpMsg::OK:
488 {
489 /* no parameters */
490 rc = d->iface->updateConfig();
491 endLoop = true;
492 break;
493 }
494 case SVCHlpMsg::Error:
495 {
496 /* read the error message */
497 Utf8Str errMsg;
498 vrc = aClient->read(errMsg);
499 if (RT_FAILURE(vrc)) break;
500
501 rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
502 endLoop = true;
503 break;
504 }
505 default:
506 {
507 endLoop = true;
508 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
509 //"Invalid message code %d (%08lX)\n",
510 //reply, reply),
511 //rc = E_FAIL);
512 }
513 }
514 }
515
516 break;
517 }
518 case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
519 {
520 LogFlowFunc(("EnableStaticIpConfigV6:\n"));
521 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
522
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;
532
533 /* wait for a reply */
534 bool endLoop = false;
535 while (!endLoop)
536 {
537 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
538
539 vrc = aClient->read(reply);
540 if (RT_FAILURE(vrc)) break;
541
542 switch (reply)
543 {
544 case SVCHlpMsg::OK:
545 {
546 /* no parameters */
547 rc = d->iface->updateConfig();
548 endLoop = true;
549 break;
550 }
551 case SVCHlpMsg::Error:
552 {
553 /* read the error message */
554 Utf8Str errMsg;
555 vrc = aClient->read(errMsg);
556 if (RT_FAILURE(vrc)) break;
557
558 rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
559 endLoop = true;
560 break;
561 }
562 default:
563 {
564 endLoop = true;
565 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
566 //"Invalid message code %d (%08lX)\n",
567 //reply, reply),
568 //rc = E_FAIL);
569 }
570 }
571 }
572
573 break;
574 }
575 case SVCHlpMsg::DhcpRediscover: /* see usage in code */
576 {
577 LogFlowFunc(("DhcpRediscover:\n"));
578 LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
579
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;
585
586 /* wait for a reply */
587 bool endLoop = false;
588 while (!endLoop)
589 {
590 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
591
592 vrc = aClient->read(reply);
593 if (RT_FAILURE(vrc)) break;
594
595 switch (reply)
596 {
597 case SVCHlpMsg::OK:
598 {
599 /* no parameters */
600 rc = d->iface->updateConfig();
601 endLoop = true;
602 break;
603 }
604 case SVCHlpMsg::Error:
605 {
606 /* read the error message */
607 Utf8Str errMsg;
608 vrc = aClient->read(errMsg);
609 if (RT_FAILURE(vrc)) break;
610
611 rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
612 endLoop = true;
613 break;
614 }
615 default:
616 {
617 endLoop = true;
618 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
619 //"Invalid message code %d (%08lX)\n",
620 //reply, reply),
621 //rc = E_FAIL);
622 }
623 }
624 }
625
626 break;
627 }
628 default:
629 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
630// "Invalid message code %d (%08lX)\n",
631// d->msgCode, d->msgCode),
632// rc = E_FAIL);
633 }
634
635 if (aVrc)
636 *aVrc = vrc;
637
638 LogFlowFunc(("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
639 LogFlowFuncLeave();
640 return rc;
641}
642
643
644int netIfNetworkInterfaceHelperServer(SVCHlpClient *aClient,
645 SVCHlpMsg::Code aMsgCode)
646{
647 LogFlowFuncEnter();
648 LogFlowFunc(("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
649
650 AssertReturn(aClient, VERR_INVALID_POINTER);
651
652 int vrc = VINF_SUCCESS;
653 HRESULT hrc;
654
655 switch (aMsgCode)
656 {
657 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
658 {
659 LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
660
661// Utf8Str name;
662// vrc = aClient->read(name);
663// if (RT_FAILURE(vrc)) break;
664
665 Guid guid;
666 Utf8Str errMsg;
667 Bstr name;
668 Bstr bstrErr;
669
670 hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), name.asOutParam(), bstrErr.asOutParam());
671
672 if (hrc == S_OK)
673 {
674 ULONG ip, mask;
675 hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
676 if (hrc == S_OK)
677 {
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 */
680 ip = ip | (1 << 24);
681 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
682 }
683
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;
691 }
692 else
693 {
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;
703 }
704
705 break;
706 }
707 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
708 {
709 LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
710
711 Guid guid;
712 Bstr bstrErr;
713
714 vrc = aClient->read(guid);
715 if (RT_FAILURE(vrc)) break;
716
717 Utf8Str errMsg;
718 hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
719
720 if (hrc == S_OK)
721 {
722 /* write parameter-less success */
723 vrc = aClient->write(SVCHlpMsg::OK);
724 if (RT_FAILURE(vrc)) break;
725 }
726 else
727 {
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;
737 }
738
739 break;
740 }
741 case SVCHlpMsg::EnableStaticIpConfigV6:
742 {
743 LogFlowFunc(("EnableStaticIpConfigV6:\n"));
744
745 Guid guid;
746 Utf8Str ipV6;
747 ULONG maskLengthV6;
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;
754
755 Utf8Str errMsg;
756 vrc = VERR_NOT_IMPLEMENTED;
757
758 if (RT_SUCCESS(vrc))
759 {
760 /* write success followed by GUID */
761 vrc = aClient->write(SVCHlpMsg::OK);
762 if (RT_FAILURE(vrc)) break;
763 }
764 else
765 {
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;
773 }
774
775 break;
776 }
777 case SVCHlpMsg::EnableStaticIpConfig:
778 {
779 LogFlowFunc(("EnableStaticIpConfig:\n"));
780
781 Guid guid;
782 ULONG ip, mask;
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;
789
790 Utf8Str errMsg;
791 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
792
793 if (hrc == S_OK)
794 {
795 /* write success followed by GUID */
796 vrc = aClient->write(SVCHlpMsg::OK);
797 if (RT_FAILURE(vrc)) break;
798 }
799 else
800 {
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;
809 }
810
811 break;
812 }
813 case SVCHlpMsg::EnableDynamicIpConfig:
814 {
815 LogFlowFunc(("EnableDynamicIpConfig:\n"));
816
817 Guid guid;
818 vrc = aClient->read(guid);
819 if (RT_FAILURE(vrc)) break;
820
821 Utf8Str errMsg;
822 hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
823
824 if (hrc == S_OK)
825 {
826 /* write success followed by GUID */
827 vrc = aClient->write(SVCHlpMsg::OK);
828 if (RT_FAILURE(vrc)) break;
829 }
830 else
831 {
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;
840 }
841
842 break;
843 }
844 case SVCHlpMsg::DhcpRediscover:
845 {
846 LogFlowFunc(("DhcpRediscover:\n"));
847
848 Guid guid;
849 vrc = aClient->read(guid);
850 if (RT_FAILURE(vrc)) break;
851
852 Utf8Str errMsg;
853 hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
854
855 if (hrc == S_OK)
856 {
857 /* write success followed by GUID */
858 vrc = aClient->write(SVCHlpMsg::OK);
859 if (RT_FAILURE(vrc)) break;
860 }
861 else
862 {
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;
871 }
872
873 break;
874 }
875 default:
876 AssertMsgFailedBreakStmt(
877 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
878 VERR_GENERAL_FAILURE);
879 }
880
881 LogFlowFunc(("vrc=%Rrc\n", vrc));
882 LogFlowFuncLeave();
883 return vrc;
884}
885
886/** @todo REMOVE. OBSOLETE NOW. */
887/**
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.
890 */
891static BOOL IsUACEnabled()
892{
893 LONG rc = 0;
894
895 OSVERSIONINFOEX info;
896 ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
897 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
898 rc = GetVersionEx((OSVERSIONINFO *) &info);
899 AssertReturn(rc != 0, FALSE);
900
901 LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
902 info.dwMajorVersion, info.dwMinorVersion));
903
904 /* we are interested only in Vista (and newer versions...). In all
905 * earlier versions UAC is not present. */
906 if (info.dwMajorVersion < 6)
907 return FALSE;
908
909 /* the default EnableLUA value is 1 (Enabled) */
910 DWORD dwEnableLUA = 1;
911
912 HKEY hKey;
913 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
914 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
915 0, KEY_QUERY_VALUE, &hKey);
916
917 Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
918 if (rc == ERROR_SUCCESS)
919 {
920
921 DWORD cbEnableLUA = sizeof(dwEnableLUA);
922 rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
923 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
924
925 RegCloseKey(hKey);
926
927 Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
928 }
929
930 LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
931
932 return dwEnableLUA == 1;
933}
934
935/* end */
936
937static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
938 INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
939 int iDefaultInterface)
940{
941 LPWSTR lpszName;
942 GUID IfGuid;
943 HRESULT hr;
944 int rc = VERR_GENERAL_FAILURE;
945
946 hr = pncc->GetDisplayName(&lpszName);
947 Assert(hr == S_OK);
948 if (hr == S_OK)
949 {
950 Bstr name(lpszName);
951
952 hr = pncc->GetInstanceGuid(&IfGuid);
953 Assert(hr == S_OK);
954 if (hr == S_OK)
955 {
956 NETIFINFO Info;
957 memset(&Info, 0, sizeof(Info));
958 Info.Uuid = *(Guid(IfGuid).raw());
959 rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
960 if (RT_FAILURE(rc))
961 {
962 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
963 }
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)))
969 {
970 if (Info.bIsDefault)
971 pPist->push_front(iface);
972 else
973 pPist->push_back(iface);
974 rc = VINF_SUCCESS;
975 }
976 else
977 {
978 Assert(0);
979 }
980 }
981 CoTaskMemFree(lpszName);
982 }
983
984 return rc;
985}
986
987#endif /* VBOX_WITH_NETFLT */
988
989
990static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
991{
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 */
996 INetCfg *pNc;
997 INetCfgComponent *pMpNcc;
998 LPWSTR lpszApp = NULL;
999 HRESULT hr;
1000 IEnumNetCfgComponent *pEnumComponent;
1001
1002 /* we are using the INetCfg API for getting the list of miniports */
1003 hr = VBoxNetCfgWinQueryINetCfg(FALSE,
1004 VBOX_APP_NAME,
1005 &pNc,
1006 &lpszApp);
1007 Assert(hr == S_OK);
1008 if (hr == S_OK)
1009 {
1010 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
1011 if (hr == S_OK)
1012 {
1013 while ((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
1014 {
1015 ULONG uComponentStatus;
1016 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1017 if (hr == S_OK)
1018 {
1019 if (uComponentStatus == 0)
1020 {
1021 LPWSTR pId;
1022 hr = pMpNcc->GetId(&pId);
1023 Assert(hr == S_OK);
1024 if (hr == S_OK)
1025 {
1026 if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1027 {
1028 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
1029 }
1030 CoTaskMemFree(pId);
1031 }
1032 }
1033 }
1034 VBoxNetCfgWinReleaseRef(pMpNcc);
1035 }
1036 Assert(hr == S_OK || hr == S_FALSE);
1037
1038 VBoxNetCfgWinReleaseRef(pEnumComponent);
1039 }
1040 else
1041 {
1042 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1043 }
1044
1045 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1046 }
1047 else if (lpszApp)
1048 {
1049 CoTaskMemFree(lpszApp);
1050 }
1051#endif /* # if defined VBOX_WITH_NETFLT */
1052 return VINF_SUCCESS;
1053}
1054
1055int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1056{
1057#ifndef VBOX_WITH_NETFLT
1058 return VERR_NOT_IMPLEMENTED;
1059#else
1060 Bstr name;
1061 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1062 if (hr == S_OK)
1063 {
1064 Bstr IfGuid;
1065 hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1066 Assert(hr == S_OK);
1067 if (hr == S_OK)
1068 {
1069 memset(pInfo, 0, sizeof(NETIFINFO));
1070 Guid guid(IfGuid);
1071 pInfo->Uuid = *(guid.raw());
1072
1073 return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
1074 }
1075 }
1076 return VERR_GENERAL_FAILURE;
1077#endif
1078}
1079
1080int NetIfGetConfigByName(PNETIFINFO)
1081{
1082 return VERR_NOT_IMPLEMENTED;
1083}
1084
1085int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
1086 IHostNetworkInterface **aHostNetworkInterface,
1087 IProgress **aProgress)
1088{
1089#ifndef VBOX_WITH_NETFLT
1090 return VERR_NOT_IMPLEMENTED;
1091#else
1092 /* create a progress object */
1093 ComObjPtr<Progress> progress;
1094 progress.createObject();
1095
1096 ComPtr<IHost> host;
1097 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1098 if (SUCCEEDED(rc))
1099 {
1100 rc = progress->init(pVBox, host,
1101 Bstr(_T("Creating host only network interface")).raw(),
1102 FALSE /* aCancelable */);
1103 if (SUCCEEDED(rc))
1104 {
1105 if (FAILED(rc)) return rc;
1106 progress.queryInterfaceTo(aProgress);
1107
1108 /* create a new uninitialized host interface object */
1109 ComObjPtr<HostNetworkInterface> iface;
1110 iface.createObject();
1111 iface.queryInterfaceTo(aHostNetworkInterface);
1112
1113 /* create the networkInterfaceHelperClient() argument */
1114 std::auto_ptr<NetworkInterfaceHelperClientData>
1115 d(new NetworkInterfaceHelperClientData());
1116 AssertReturn(d.get(), E_OUTOFMEMORY);
1117
1118 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1119// d->name = aName;
1120 d->iface = iface;
1121 d->vBox = pVBox;
1122
1123 rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1124 netIfNetworkInterfaceHelperClient,
1125 static_cast<void *>(d.get()),
1126 progress);
1127
1128 if (SUCCEEDED(rc))
1129 {
1130 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1131 d.release();
1132 }
1133 }
1134 }
1135
1136 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1137#endif
1138}
1139
1140int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, IN_GUID aId,
1141 IProgress **aProgress)
1142{
1143#ifndef VBOX_WITH_NETFLT
1144 return VERR_NOT_IMPLEMENTED;
1145#else
1146 /* create a progress object */
1147 ComObjPtr<Progress> progress;
1148 progress.createObject();
1149 ComPtr<IHost> host;
1150 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1151 if (SUCCEEDED(rc))
1152 {
1153 rc = progress->init(pVBox, host,
1154 Bstr(_T("Removing host network interface")).raw(),
1155 FALSE /* aCancelable */);
1156 if (SUCCEEDED(rc))
1157 {
1158 if (FAILED(rc)) return rc;
1159 progress.queryInterfaceTo(aProgress);
1160
1161 /* create the networkInterfaceHelperClient() argument */
1162 std::auto_ptr<NetworkInterfaceHelperClientData>
1163 d(new NetworkInterfaceHelperClientData());
1164 AssertReturn(d.get(), E_OUTOFMEMORY);
1165
1166 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1167 d->guid = aId;
1168
1169 rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1170 netIfNetworkInterfaceHelperClient,
1171 static_cast<void *>(d.get()),
1172 progress);
1173
1174 if (SUCCEEDED(rc))
1175 {
1176 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1177 d.release();
1178 }
1179 }
1180 }
1181
1182 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1183#endif
1184}
1185
1186int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1187{
1188#ifndef VBOX_WITH_NETFLT
1189 return VERR_NOT_IMPLEMENTED;
1190#else
1191 HRESULT rc;
1192 Bstr guid;
1193 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1194 if (SUCCEEDED(rc))
1195 {
1196// ComPtr<VirtualBox> vBox;
1197// rc = pIf->getVirtualBox(vBox.asOutParam());
1198// if (SUCCEEDED(rc))
1199 {
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))
1206 {
1207 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1208 Bstr("Enabling Dynamic Ip Configuration").raw(),
1209 FALSE /* aCancelable */);
1210 if (SUCCEEDED(rc))
1211 {
1212 if (FAILED(rc)) return rc;
1213// progress.queryInterfaceTo(aProgress);
1214
1215 /* create the networkInterfaceHelperClient() argument */
1216 std::auto_ptr<NetworkInterfaceHelperClientData>
1217 d(new NetworkInterfaceHelperClientData());
1218 AssertReturn(d.get(), E_OUTOFMEMORY);
1219
1220 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1221 d->guid = Guid(guid);
1222 d->iface = pIf;
1223 d->u.StaticIP.IPAddress = ip;
1224 d->u.StaticIP.IPNetMask = mask;
1225
1226 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1227 netIfNetworkInterfaceHelperClient,
1228 static_cast<void *>(d.get()),
1229 progress);
1230
1231 if (SUCCEEDED(rc))
1232 {
1233 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1234 d.release();
1235
1236 progress->WaitForCompletion(-1);
1237 }
1238 }
1239 }
1240 }
1241 }
1242
1243 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1244#endif
1245}
1246
1247int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1248{
1249#ifndef VBOX_WITH_NETFLT
1250 return VERR_NOT_IMPLEMENTED;
1251#else
1252 HRESULT rc;
1253 Bstr guid;
1254 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1255 if (SUCCEEDED(rc))
1256 {
1257// ComPtr<VirtualBox> vBox;
1258// rc = pIf->getVirtualBox(vBox.asOutParam());
1259// if (SUCCEEDED(rc))
1260 {
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))
1267 {
1268 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1269 Bstr("Enabling Dynamic Ip Configuration").raw(),
1270 FALSE /* aCancelable */);
1271 if (SUCCEEDED(rc))
1272 {
1273 if (FAILED(rc)) return rc;
1274// progress.queryInterfaceTo(aProgress);
1275
1276 /* create the networkInterfaceHelperClient() argument */
1277 std::auto_ptr<NetworkInterfaceHelperClientData>
1278 d(new NetworkInterfaceHelperClientData());
1279 AssertReturn(d.get(), E_OUTOFMEMORY);
1280
1281 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1282 d->guid = guid;
1283 d->iface = pIf;
1284 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1285 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1286
1287 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1288 netIfNetworkInterfaceHelperClient,
1289 static_cast<void *>(d.get()),
1290 progress);
1291
1292 if (SUCCEEDED(rc))
1293 {
1294 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1295 d.release();
1296
1297 progress->WaitForCompletion(-1);
1298 }
1299 }
1300 }
1301 }
1302 }
1303
1304 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1305#endif
1306}
1307
1308int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1309{
1310#ifndef VBOX_WITH_NETFLT
1311 return VERR_NOT_IMPLEMENTED;
1312#else
1313 HRESULT rc;
1314 Bstr guid;
1315 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1316 if (SUCCEEDED(rc))
1317 {
1318// ComPtr<VirtualBox> vBox;
1319// rc = pIf->getVirtualBox(vBox.asOutParam());
1320// if (SUCCEEDED(rc))
1321 {
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))
1328 {
1329 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1330 Bstr("Enabling Dynamic Ip Configuration").raw(),
1331 FALSE /* aCancelable */);
1332 if (SUCCEEDED(rc))
1333 {
1334 if (FAILED(rc)) return rc;
1335// progress.queryInterfaceTo(aProgress);
1336
1337 /* create the networkInterfaceHelperClient() argument */
1338 std::auto_ptr<NetworkInterfaceHelperClientData>
1339 d(new NetworkInterfaceHelperClientData());
1340 AssertReturn(d.get(), E_OUTOFMEMORY);
1341
1342 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1343 d->guid = guid;
1344 d->iface = pIf;
1345
1346 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1347 netIfNetworkInterfaceHelperClient,
1348 static_cast<void *>(d.get()),
1349 progress);
1350
1351 if (SUCCEEDED(rc))
1352 {
1353 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1354 d.release();
1355
1356 progress->WaitForCompletion(-1);
1357 }
1358 }
1359 }
1360 }
1361 }
1362
1363 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1364#endif
1365}
1366
1367int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1368{
1369#ifndef VBOX_WITH_NETFLT
1370 return VERR_NOT_IMPLEMENTED;
1371#else
1372 HRESULT rc;
1373 Bstr guid;
1374 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1375 if (SUCCEEDED(rc))
1376 {
1377// ComPtr<VirtualBox> vBox;
1378// rc = pIf->getVirtualBox(vBox.asOutParam());
1379// if (SUCCEEDED(rc))
1380 {
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))
1387 {
1388 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1389 Bstr("Enabling Dynamic Ip Configuration").raw(),
1390 FALSE /* aCancelable */);
1391 if (SUCCEEDED(rc))
1392 {
1393 if (FAILED(rc)) return rc;
1394// progress.queryInterfaceTo(aProgress);
1395
1396 /* create the networkInterfaceHelperClient() argument */
1397 std::auto_ptr<NetworkInterfaceHelperClientData>
1398 d(new NetworkInterfaceHelperClientData());
1399 AssertReturn(d.get(), E_OUTOFMEMORY);
1400
1401 d->msgCode = SVCHlpMsg::DhcpRediscover;
1402 d->guid = guid;
1403 d->iface = pIf;
1404
1405 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1406 netIfNetworkInterfaceHelperClient,
1407 static_cast<void *>(d.get()),
1408 progress);
1409
1410 if (SUCCEEDED(rc))
1411 {
1412 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1413 d.release();
1414
1415 progress->WaitForCompletion(-1);
1416 }
1417 }
1418 }
1419 }
1420 }
1421
1422 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1423#endif
1424}
1425
1426int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1427{
1428#ifndef VBOX_WITH_NETFLT
1429 return VERR_NOT_IMPLEMENTED;
1430#else /* # if defined VBOX_WITH_NETFLT */
1431 INetCfg *pNc;
1432 INetCfgComponent *pMpNcc;
1433 INetCfgComponent *pTcpIpNcc;
1434 LPWSTR lpszApp;
1435 HRESULT hr;
1436 IEnumNetCfgBindingPath *pEnumBp;
1437 INetCfgBindingPath *pBp;
1438 IEnumNetCfgBindingInterface *pEnumBi;
1439 INetCfgBindingInterface *pBi;
1440 int iDefault = getDefaultInterfaceIndex();
1441
1442 /* we are using the INetCfg API for getting the list of miniports */
1443 hr = VBoxNetCfgWinQueryINetCfg(FALSE,
1444 VBOX_APP_NAME,
1445 &pNc,
1446 &lpszApp);
1447 Assert(hr == S_OK);
1448 if (hr == S_OK)
1449 {
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);
1453# else
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
1457 if (hr != S_OK)
1458 {
1459 /* TODO: try to install the netflt from here */
1460 }
1461# endif
1462
1463# endif
1464
1465 if (hr == S_OK)
1466 {
1467 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
1468 Assert(hr == S_OK);
1469 if (hr == S_OK)
1470 {
1471 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
1472 Assert(hr == S_OK || hr == S_FALSE);
1473 while (hr == S_OK)
1474 {
1475 /* S_OK == enabled, S_FALSE == disabled */
1476 if (pBp->IsEnabled() == S_OK)
1477 {
1478 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
1479 Assert(hr == S_OK);
1480 if ( hr == S_OK )
1481 {
1482 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
1483 Assert(hr == S_OK);
1484 while (hr == S_OK)
1485 {
1486 hr = pBi->GetLowerComponent( &pMpNcc );
1487 Assert(hr == S_OK);
1488 if (hr == S_OK)
1489 {
1490 ULONG uComponentStatus;
1491 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1492 if (hr == S_OK)
1493 {
1494 if (uComponentStatus == 0)
1495 {
1496 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
1497 }
1498 }
1499 VBoxNetCfgWinReleaseRef( pMpNcc );
1500 }
1501 VBoxNetCfgWinReleaseRef(pBi);
1502
1503 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
1504 }
1505 VBoxNetCfgWinReleaseRef(pEnumBi);
1506 }
1507 }
1508 VBoxNetCfgWinReleaseRef(pBp);
1509
1510 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
1511 }
1512 VBoxNetCfgWinReleaseRef(pEnumBp);
1513 }
1514 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
1515 }
1516 else
1517 {
1518 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1519 }
1520
1521 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1522 }
1523
1524 netIfListHostAdapters(list);
1525
1526 return VINF_SUCCESS;
1527#endif /* # if defined VBOX_WITH_NETFLT */
1528}
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