VirtualBox

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

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

typo

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