VirtualBox

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

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

com/string: Windows build fixes

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