VirtualBox

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

Last change on this file since 48330 was 47117, checked in by vboxsync, 11 years ago

Main: RT_ZERO() / RTStrCopy()

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