VirtualBox

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

Last change on this file since 32048 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.5 KB
Line 
1/* $Id: NetIf-win.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * Main - NetIfList, Windows implementation.
4 */
5
6/*
7 * Copyright (C) 2008 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, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
896{
897 LPWSTR lpszName;
898 GUID IfGuid;
899 HRESULT hr;
900 int rc = VERR_GENERAL_FAILURE;
901
902 hr = pncc->GetDisplayName( &lpszName );
903 Assert(hr == S_OK);
904 if(hr == S_OK)
905 {
906 Bstr name(lpszName);
907
908 hr = pncc->GetInstanceGuid(&IfGuid);
909 Assert(hr == S_OK);
910 if (hr == S_OK)
911 {
912 NETIFINFO Info;
913 memset(&Info, 0, sizeof(Info));
914 Info.Uuid = *(Guid(IfGuid).raw());
915 rc = collectNetIfInfo(name, Guid(IfGuid), &Info);
916 if (RT_FAILURE(rc))
917 {
918 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
919 }
920 /* create a new object and add it to the list */
921 ComObjPtr<HostNetworkInterface> iface;
922 iface.createObject();
923 /* remove the curly bracket at the end */
924 if (SUCCEEDED(iface->init (name, enmType, &Info)))
925 {
926 pPist->push_back (iface);
927 rc = VINF_SUCCESS;
928 }
929 else
930 {
931 Assert(0);
932 }
933 }
934 CoTaskMemFree(lpszName);
935 }
936
937 return rc;
938}
939
940#endif /* VBOX_WITH_NETFLT */
941
942
943static int netIfListHostAdapters(std::list <ComObjPtr<HostNetworkInterface> > &list)
944{
945#ifndef VBOX_WITH_NETFLT
946 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
947 return VERR_NOT_IMPLEMENTED;
948#else /* # if defined VBOX_WITH_NETFLT */
949 INetCfg *pNc;
950 INetCfgComponent *pMpNcc;
951 LPWSTR lpszApp = NULL;
952 HRESULT hr;
953 IEnumNetCfgComponent *pEnumComponent;
954
955 /* we are using the INetCfg API for getting the list of miniports */
956 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
957 VBOX_APP_NAME,
958 &pNc,
959 &lpszApp );
960 Assert(hr == S_OK);
961 if(hr == S_OK)
962 {
963 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
964 if(hr == S_OK)
965 {
966 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
967 {
968 ULONG uComponentStatus;
969 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
970 if(hr == S_OK)
971 {
972 if(uComponentStatus == 0)
973 {
974 LPWSTR pId;
975 hr = pMpNcc->GetId(&pId);
976 Assert(hr == S_OK);
977 if(hr == S_OK)
978 {
979 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
980 {
981 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
982 }
983 CoTaskMemFree(pId);
984 }
985 }
986 }
987 VBoxNetCfgWinReleaseRef(pMpNcc);
988 }
989 Assert(hr == S_OK || hr == S_FALSE);
990
991 VBoxNetCfgWinReleaseRef(pEnumComponent);
992 }
993 else
994 {
995 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
996 }
997
998 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
999 }
1000 else if(lpszApp)
1001 {
1002 CoTaskMemFree(lpszApp);
1003 }
1004#endif /* # if defined VBOX_WITH_NETFLT */
1005 return VINF_SUCCESS;
1006}
1007
1008int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1009{
1010#ifndef VBOX_WITH_NETFLT
1011 return VERR_NOT_IMPLEMENTED;
1012#else
1013 Bstr name;
1014 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1015 if(hr == S_OK)
1016 {
1017 Bstr IfGuid;
1018 hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1019 Assert(hr == S_OK);
1020 if (hr == S_OK)
1021 {
1022 memset(pInfo, 0, sizeof(NETIFINFO));
1023 Guid guid(IfGuid);
1024 pInfo->Uuid = *(guid.raw());
1025
1026 return collectNetIfInfo(name, guid, pInfo);
1027 }
1028 }
1029 return VERR_GENERAL_FAILURE;
1030#endif
1031}
1032
1033int NetIfGetConfigByName(PNETIFINFO)
1034{
1035 return VERR_NOT_IMPLEMENTED;
1036}
1037
1038int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox,
1039 IHostNetworkInterface **aHostNetworkInterface,
1040 IProgress **aProgress)
1041{
1042#ifndef VBOX_WITH_NETFLT
1043 return VERR_NOT_IMPLEMENTED;
1044#else
1045 /* create a progress object */
1046 ComObjPtr<Progress> progress;
1047 progress.createObject();
1048
1049 ComPtr<IHost> host;
1050 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1051 if(SUCCEEDED(rc))
1052 {
1053 rc = progress->init (pVBox, host,
1054 Bstr (_T ("Creating host only network interface")),
1055 FALSE /* aCancelable */);
1056 if(SUCCEEDED(rc))
1057 {
1058 if (FAILED(rc)) return rc;
1059 progress.queryInterfaceTo(aProgress);
1060
1061 /* create a new uninitialized host interface object */
1062 ComObjPtr<HostNetworkInterface> iface;
1063 iface.createObject();
1064 iface.queryInterfaceTo(aHostNetworkInterface);
1065
1066 /* create the networkInterfaceHelperClient() argument */
1067 std::auto_ptr <NetworkInterfaceHelperClientData>
1068 d (new NetworkInterfaceHelperClientData());
1069 AssertReturn(d.get(), E_OUTOFMEMORY);
1070
1071 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1072// d->name = aName;
1073 d->iface = iface;
1074 d->vBox = pVBox;
1075
1076 rc = pVBox->startSVCHelperClient (
1077 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")),
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 (
1124 IsUACEnabled() == TRUE /* aPrivileged */,
1125 netIfNetworkInterfaceHelperClient,
1126 static_cast <void *> (d.get()),
1127 progress);
1128
1129 if (SUCCEEDED(rc))
1130 {
1131 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1132 d.release();
1133 }
1134 }
1135 }
1136
1137 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1138#endif
1139}
1140
1141int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1142{
1143#ifndef VBOX_WITH_NETFLT
1144 return VERR_NOT_IMPLEMENTED;
1145#else
1146 HRESULT rc;
1147 Bstr guid;
1148 rc = pIf->COMGETTER(Id) (guid.asOutParam());
1149 if(SUCCEEDED(rc))
1150 {
1151// ComPtr<VirtualBox> vBox;
1152// rc = pIf->getVirtualBox (vBox.asOutParam());
1153// if(SUCCEEDED(rc))
1154 {
1155 /* create a progress object */
1156 ComObjPtr<Progress> progress;
1157 progress.createObject();
1158// ComPtr<IHost> host;
1159// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1160// if(SUCCEEDED(rc))
1161 {
1162 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1163 Bstr ("Enabling Dynamic Ip Configuration"),
1164 FALSE /* aCancelable */);
1165 if(SUCCEEDED(rc))
1166 {
1167 if (FAILED(rc)) return rc;
1168// progress.queryInterfaceTo(aProgress);
1169
1170 /* create the networkInterfaceHelperClient() argument */
1171 std::auto_ptr <NetworkInterfaceHelperClientData>
1172 d (new NetworkInterfaceHelperClientData());
1173 AssertReturn(d.get(), E_OUTOFMEMORY);
1174
1175 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1176 d->guid = Guid(guid);
1177 d->iface = pIf;
1178 d->u.StaticIP.IPAddress = ip;
1179 d->u.StaticIP.IPNetMask = mask;
1180
1181 rc = vBox->startSVCHelperClient (
1182 IsUACEnabled() == TRUE /* aPrivileged */,
1183 netIfNetworkInterfaceHelperClient,
1184 static_cast <void *> (d.get()),
1185 progress);
1186
1187 if (SUCCEEDED(rc))
1188 {
1189 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1190 d.release();
1191
1192 progress->WaitForCompletion(-1);
1193 }
1194 }
1195 }
1196 }
1197 }
1198
1199 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1200#endif
1201}
1202
1203int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1204{
1205#ifndef VBOX_WITH_NETFLT
1206 return VERR_NOT_IMPLEMENTED;
1207#else
1208 HRESULT rc;
1209 Bstr guid;
1210 rc = pIf->COMGETTER(Id) (guid.asOutParam());
1211 if(SUCCEEDED(rc))
1212 {
1213// ComPtr<VirtualBox> vBox;
1214// rc = pIf->getVirtualBox (vBox.asOutParam());
1215// if(SUCCEEDED(rc))
1216 {
1217 /* create a progress object */
1218 ComObjPtr<Progress> progress;
1219 progress.createObject();
1220// ComPtr<IHost> host;
1221// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1222// if(SUCCEEDED(rc))
1223 {
1224 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1225 Bstr ("Enabling Dynamic Ip Configuration"),
1226 FALSE /* aCancelable */);
1227 if(SUCCEEDED(rc))
1228 {
1229 if (FAILED(rc)) return rc;
1230// progress.queryInterfaceTo(aProgress);
1231
1232 /* create the networkInterfaceHelperClient() argument */
1233 std::auto_ptr <NetworkInterfaceHelperClientData>
1234 d (new NetworkInterfaceHelperClientData());
1235 AssertReturn(d.get(), E_OUTOFMEMORY);
1236
1237 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1238 d->guid = guid;
1239 d->iface = pIf;
1240 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1241 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1242
1243 rc = vBox->startSVCHelperClient (
1244 IsUACEnabled() == TRUE /* aPrivileged */,
1245 netIfNetworkInterfaceHelperClient,
1246 static_cast <void *> (d.get()),
1247 progress);
1248
1249 if (SUCCEEDED(rc))
1250 {
1251 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1252 d.release();
1253
1254 progress->WaitForCompletion(-1);
1255 }
1256 }
1257 }
1258 }
1259 }
1260
1261 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1262#endif
1263}
1264
1265int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1266{
1267#ifndef VBOX_WITH_NETFLT
1268 return VERR_NOT_IMPLEMENTED;
1269#else
1270 HRESULT rc;
1271 Bstr guid;
1272 rc = pIf->COMGETTER(Id) (guid.asOutParam());
1273 if(SUCCEEDED(rc))
1274 {
1275// ComPtr<VirtualBox> vBox;
1276// rc = pIf->getVirtualBox (vBox.asOutParam());
1277// if(SUCCEEDED(rc))
1278 {
1279 /* create a progress object */
1280 ComObjPtr<Progress> progress;
1281 progress.createObject();
1282// ComPtr<IHost> host;
1283// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1284// if(SUCCEEDED(rc))
1285 {
1286 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1287 Bstr ("Enabling Dynamic Ip Configuration"),
1288 FALSE /* aCancelable */);
1289 if(SUCCEEDED(rc))
1290 {
1291 if (FAILED(rc)) return rc;
1292// progress.queryInterfaceTo(aProgress);
1293
1294 /* create the networkInterfaceHelperClient() argument */
1295 std::auto_ptr <NetworkInterfaceHelperClientData>
1296 d (new NetworkInterfaceHelperClientData());
1297 AssertReturn(d.get(), E_OUTOFMEMORY);
1298
1299 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1300 d->guid = guid;
1301 d->iface = pIf;
1302
1303 rc = vBox->startSVCHelperClient (
1304 IsUACEnabled() == TRUE /* aPrivileged */,
1305 netIfNetworkInterfaceHelperClient,
1306 static_cast <void *> (d.get()),
1307 progress);
1308
1309 if (SUCCEEDED(rc))
1310 {
1311 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1312 d.release();
1313
1314 progress->WaitForCompletion(-1);
1315 }
1316 }
1317 }
1318 }
1319 }
1320
1321 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1322#endif
1323}
1324
1325int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1326{
1327#ifndef VBOX_WITH_NETFLT
1328 return VERR_NOT_IMPLEMENTED;
1329#else
1330 HRESULT rc;
1331 Bstr guid;
1332 rc = pIf->COMGETTER(Id) (guid.asOutParam());
1333 if(SUCCEEDED(rc))
1334 {
1335// ComPtr<VirtualBox> vBox;
1336// rc = pIf->getVirtualBox (vBox.asOutParam());
1337// if(SUCCEEDED(rc))
1338 {
1339 /* create a progress object */
1340 ComObjPtr<Progress> progress;
1341 progress.createObject();
1342// ComPtr<IHost> host;
1343// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1344// if(SUCCEEDED(rc))
1345 {
1346 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1347 Bstr ("Enabling Dynamic Ip Configuration"),
1348 FALSE /* aCancelable */);
1349 if(SUCCEEDED(rc))
1350 {
1351 if (FAILED(rc)) return rc;
1352// progress.queryInterfaceTo(aProgress);
1353
1354 /* create the networkInterfaceHelperClient() argument */
1355 std::auto_ptr <NetworkInterfaceHelperClientData>
1356 d (new NetworkInterfaceHelperClientData());
1357 AssertReturn(d.get(), E_OUTOFMEMORY);
1358
1359 d->msgCode = SVCHlpMsg::DhcpRediscover;
1360 d->guid = guid;
1361 d->iface = pIf;
1362
1363 rc = vBox->startSVCHelperClient (
1364 IsUACEnabled() == TRUE /* aPrivileged */,
1365 netIfNetworkInterfaceHelperClient,
1366 static_cast <void *> (d.get()),
1367 progress);
1368
1369 if (SUCCEEDED(rc))
1370 {
1371 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1372 d.release();
1373
1374 progress->WaitForCompletion(-1);
1375 }
1376 }
1377 }
1378 }
1379 }
1380
1381 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1382#endif
1383}
1384
1385int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
1386{
1387#ifndef VBOX_WITH_NETFLT
1388 return VERR_NOT_IMPLEMENTED;
1389#else /* # if defined VBOX_WITH_NETFLT */
1390 INetCfg *pNc;
1391 INetCfgComponent *pMpNcc;
1392 INetCfgComponent *pTcpIpNcc;
1393 LPWSTR lpszApp;
1394 HRESULT hr;
1395 IEnumNetCfgBindingPath *pEnumBp;
1396 INetCfgBindingPath *pBp;
1397 IEnumNetCfgBindingInterface *pEnumBi;
1398 INetCfgBindingInterface *pBi;
1399
1400 /* we are using the INetCfg API for getting the list of miniports */
1401 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
1402 VBOX_APP_NAME,
1403 &pNc,
1404 &lpszApp );
1405 Assert(hr == S_OK);
1406 if(hr == S_OK)
1407 {
1408# ifdef VBOX_NETFLT_ONDEMAND_BIND
1409 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
1410 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
1411# else
1412 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
1413 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
1414# ifndef VBOX_WITH_HARDENING
1415 if(hr != S_OK)
1416 {
1417 /* TODO: try to install the netflt from here */
1418 }
1419# endif
1420
1421# endif
1422
1423 if(hr == S_OK)
1424 {
1425 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
1426 Assert(hr == S_OK);
1427 if ( hr == S_OK )
1428 {
1429 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
1430 Assert(hr == S_OK || hr == S_FALSE);
1431 while( hr == S_OK )
1432 {
1433 /* S_OK == enabled, S_FALSE == disabled */
1434 if(pBp->IsEnabled() == S_OK)
1435 {
1436 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
1437 Assert(hr == S_OK);
1438 if ( hr == S_OK )
1439 {
1440 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
1441 Assert(hr == S_OK);
1442 while(hr == S_OK)
1443 {
1444 hr = pBi->GetLowerComponent( &pMpNcc );
1445 Assert(hr == S_OK);
1446 if(hr == S_OK)
1447 {
1448 ULONG uComponentStatus;
1449 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1450 if(hr == S_OK)
1451 {
1452 if(uComponentStatus == 0)
1453 {
1454 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
1455 }
1456 }
1457 VBoxNetCfgWinReleaseRef( pMpNcc );
1458 }
1459 VBoxNetCfgWinReleaseRef(pBi);
1460
1461 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
1462 }
1463 VBoxNetCfgWinReleaseRef(pEnumBi);
1464 }
1465 }
1466 VBoxNetCfgWinReleaseRef(pBp);
1467
1468 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
1469 }
1470 VBoxNetCfgWinReleaseRef(pEnumBp);
1471 }
1472 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
1473 }
1474 else
1475 {
1476 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1477 }
1478
1479 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1480 }
1481
1482 netIfListHostAdapters(list);
1483
1484 return VINF_SUCCESS;
1485#endif /* # if defined VBOX_WITH_NETFLT */
1486}
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