VirtualBox

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

Last change on this file since 43978 was 40080, checked in by vboxsync, 13 years ago

Another Windows build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.5 KB
Line 
1/* $Id: NetIf-win.cpp 40080 2012-02-11 11:37:28Z 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/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 memset(&Info, 0, sizeof(Info));
958 Info.Uuid = *(Guid(IfGuid).raw());
959 rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
960 if (RT_FAILURE(rc))
961 {
962 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
963 }
964 /* create a new object and add it to the list */
965 ComObjPtr<HostNetworkInterface> iface;
966 iface.createObject();
967 /* remove the curly bracket at the end */
968 if (SUCCEEDED(iface->init(name, enmType, &Info)))
969 {
970 if (Info.bIsDefault)
971 pPist->push_front(iface);
972 else
973 pPist->push_back(iface);
974 rc = VINF_SUCCESS;
975 }
976 else
977 {
978 Assert(0);
979 }
980 }
981 CoTaskMemFree(lpszName);
982 }
983
984 return rc;
985}
986
987#endif /* VBOX_WITH_NETFLT */
988
989
990static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
991{
992#ifndef VBOX_WITH_NETFLT
993 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
994 return VERR_NOT_IMPLEMENTED;
995#else /* # if defined VBOX_WITH_NETFLT */
996 INetCfg *pNc;
997 INetCfgComponent *pMpNcc;
998 LPWSTR lpszApp = NULL;
999 HRESULT hr;
1000 IEnumNetCfgComponent *pEnumComponent;
1001
1002 /* we are using the INetCfg API for getting the list of miniports */
1003 hr = VBoxNetCfgWinQueryINetCfg(&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
1085int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
1086 IHostNetworkInterface **aHostNetworkInterface,
1087 IProgress **aProgress,
1088 const char *pcszName)
1089{
1090#ifndef VBOX_WITH_NETFLT
1091 return VERR_NOT_IMPLEMENTED;
1092#else
1093 /* create a progress object */
1094 ComObjPtr<Progress> progress;
1095 progress.createObject();
1096
1097 ComPtr<IHost> host;
1098 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1099 if (SUCCEEDED(rc))
1100 {
1101 rc = progress->init(pVBox, host,
1102 Bstr(_T("Creating host only network interface")).raw(),
1103 FALSE /* aCancelable */);
1104 if (SUCCEEDED(rc))
1105 {
1106 if (FAILED(rc)) return rc;
1107 progress.queryInterfaceTo(aProgress);
1108
1109 /* create a new uninitialized host interface object */
1110 ComObjPtr<HostNetworkInterface> iface;
1111 iface.createObject();
1112 iface.queryInterfaceTo(aHostNetworkInterface);
1113
1114 /* create the networkInterfaceHelperClient() argument */
1115 std::auto_ptr<NetworkInterfaceHelperClientData>
1116 d(new NetworkInterfaceHelperClientData());
1117 AssertReturn(d.get(), E_OUTOFMEMORY);
1118
1119 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1120// d->name = aName;
1121 d->iface = iface;
1122 d->vBox = pVBox;
1123
1124 rc = pVBox->startSVCHelperClient(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 NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, IN_GUID aId,
1142 IProgress **aProgress)
1143{
1144#ifndef VBOX_WITH_NETFLT
1145 return VERR_NOT_IMPLEMENTED;
1146#else
1147 /* create a progress object */
1148 ComObjPtr<Progress> progress;
1149 progress.createObject();
1150 ComPtr<IHost> host;
1151 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1152 if (SUCCEEDED(rc))
1153 {
1154 rc = progress->init(pVBox, host,
1155 Bstr(_T("Removing host network interface")).raw(),
1156 FALSE /* aCancelable */);
1157 if (SUCCEEDED(rc))
1158 {
1159 if (FAILED(rc)) return rc;
1160 progress.queryInterfaceTo(aProgress);
1161
1162 /* create the networkInterfaceHelperClient() argument */
1163 std::auto_ptr<NetworkInterfaceHelperClientData>
1164 d(new NetworkInterfaceHelperClientData());
1165 AssertReturn(d.get(), E_OUTOFMEMORY);
1166
1167 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1168 d->guid = aId;
1169
1170 rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1171 netIfNetworkInterfaceHelperClient,
1172 static_cast<void *>(d.get()),
1173 progress);
1174
1175 if (SUCCEEDED(rc))
1176 {
1177 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1178 d.release();
1179 }
1180 }
1181 }
1182
1183 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1184#endif
1185}
1186
1187int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1188{
1189#ifndef VBOX_WITH_NETFLT
1190 return VERR_NOT_IMPLEMENTED;
1191#else
1192 HRESULT rc;
1193 Bstr guid;
1194 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1195 if (SUCCEEDED(rc))
1196 {
1197// ComPtr<VirtualBox> vBox;
1198// rc = pIf->getVirtualBox(vBox.asOutParam());
1199// if (SUCCEEDED(rc))
1200 {
1201 /* create a progress object */
1202 ComObjPtr<Progress> progress;
1203 progress.createObject();
1204// ComPtr<IHost> host;
1205// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1206// if (SUCCEEDED(rc))
1207 {
1208 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1209 Bstr("Enabling Dynamic Ip Configuration").raw(),
1210 FALSE /* aCancelable */);
1211 if (SUCCEEDED(rc))
1212 {
1213 if (FAILED(rc)) return rc;
1214// progress.queryInterfaceTo(aProgress);
1215
1216 /* create the networkInterfaceHelperClient() argument */
1217 std::auto_ptr<NetworkInterfaceHelperClientData>
1218 d(new NetworkInterfaceHelperClientData());
1219 AssertReturn(d.get(), E_OUTOFMEMORY);
1220
1221 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1222 d->guid = Guid(guid);
1223 d->iface = pIf;
1224 d->u.StaticIP.IPAddress = ip;
1225 d->u.StaticIP.IPNetMask = mask;
1226
1227 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1228 netIfNetworkInterfaceHelperClient,
1229 static_cast<void *>(d.get()),
1230 progress);
1231
1232 if (SUCCEEDED(rc))
1233 {
1234 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1235 d.release();
1236
1237 progress->WaitForCompletion(-1);
1238 }
1239 }
1240 }
1241 }
1242 }
1243
1244 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1245#endif
1246}
1247
1248int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1249{
1250#ifndef VBOX_WITH_NETFLT
1251 return VERR_NOT_IMPLEMENTED;
1252#else
1253 HRESULT rc;
1254 Bstr guid;
1255 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1256 if (SUCCEEDED(rc))
1257 {
1258// ComPtr<VirtualBox> vBox;
1259// rc = pIf->getVirtualBox(vBox.asOutParam());
1260// if (SUCCEEDED(rc))
1261 {
1262 /* create a progress object */
1263 ComObjPtr<Progress> progress;
1264 progress.createObject();
1265// ComPtr<IHost> host;
1266// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1267// if (SUCCEEDED(rc))
1268 {
1269 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1270 Bstr("Enabling Dynamic Ip Configuration").raw(),
1271 FALSE /* aCancelable */);
1272 if (SUCCEEDED(rc))
1273 {
1274 if (FAILED(rc)) return rc;
1275// progress.queryInterfaceTo(aProgress);
1276
1277 /* create the networkInterfaceHelperClient() argument */
1278 std::auto_ptr<NetworkInterfaceHelperClientData>
1279 d(new NetworkInterfaceHelperClientData());
1280 AssertReturn(d.get(), E_OUTOFMEMORY);
1281
1282 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1283 d->guid = guid;
1284 d->iface = pIf;
1285 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1286 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1287
1288 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1289 netIfNetworkInterfaceHelperClient,
1290 static_cast<void *>(d.get()),
1291 progress);
1292
1293 if (SUCCEEDED(rc))
1294 {
1295 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1296 d.release();
1297
1298 progress->WaitForCompletion(-1);
1299 }
1300 }
1301 }
1302 }
1303 }
1304
1305 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1306#endif
1307}
1308
1309int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1310{
1311#ifndef VBOX_WITH_NETFLT
1312 return VERR_NOT_IMPLEMENTED;
1313#else
1314 HRESULT rc;
1315 Bstr guid;
1316 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1317 if (SUCCEEDED(rc))
1318 {
1319// ComPtr<VirtualBox> vBox;
1320// rc = pIf->getVirtualBox(vBox.asOutParam());
1321// if (SUCCEEDED(rc))
1322 {
1323 /* create a progress object */
1324 ComObjPtr<Progress> progress;
1325 progress.createObject();
1326// ComPtr<IHost> host;
1327// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1328// if (SUCCEEDED(rc))
1329 {
1330 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1331 Bstr("Enabling Dynamic Ip Configuration").raw(),
1332 FALSE /* aCancelable */);
1333 if (SUCCEEDED(rc))
1334 {
1335 if (FAILED(rc)) return rc;
1336// progress.queryInterfaceTo(aProgress);
1337
1338 /* create the networkInterfaceHelperClient() argument */
1339 std::auto_ptr<NetworkInterfaceHelperClientData>
1340 d(new NetworkInterfaceHelperClientData());
1341 AssertReturn(d.get(), E_OUTOFMEMORY);
1342
1343 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1344 d->guid = guid;
1345 d->iface = pIf;
1346
1347 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1348 netIfNetworkInterfaceHelperClient,
1349 static_cast<void *>(d.get()),
1350 progress);
1351
1352 if (SUCCEEDED(rc))
1353 {
1354 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1355 d.release();
1356
1357 progress->WaitForCompletion(-1);
1358 }
1359 }
1360 }
1361 }
1362 }
1363
1364 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1365#endif
1366}
1367
1368int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1369{
1370#ifndef VBOX_WITH_NETFLT
1371 return VERR_NOT_IMPLEMENTED;
1372#else
1373 HRESULT rc;
1374 Bstr guid;
1375 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1376 if (SUCCEEDED(rc))
1377 {
1378// ComPtr<VirtualBox> vBox;
1379// rc = pIf->getVirtualBox(vBox.asOutParam());
1380// if (SUCCEEDED(rc))
1381 {
1382 /* create a progress object */
1383 ComObjPtr<Progress> progress;
1384 progress.createObject();
1385// ComPtr<IHost> host;
1386// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1387// if (SUCCEEDED(rc))
1388 {
1389 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1390 Bstr("Enabling Dynamic Ip Configuration").raw(),
1391 FALSE /* aCancelable */);
1392 if (SUCCEEDED(rc))
1393 {
1394 if (FAILED(rc)) return rc;
1395// progress.queryInterfaceTo(aProgress);
1396
1397 /* create the networkInterfaceHelperClient() argument */
1398 std::auto_ptr<NetworkInterfaceHelperClientData>
1399 d(new NetworkInterfaceHelperClientData());
1400 AssertReturn(d.get(), E_OUTOFMEMORY);
1401
1402 d->msgCode = SVCHlpMsg::DhcpRediscover;
1403 d->guid = guid;
1404 d->iface = pIf;
1405
1406 rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1407 netIfNetworkInterfaceHelperClient,
1408 static_cast<void *>(d.get()),
1409 progress);
1410
1411 if (SUCCEEDED(rc))
1412 {
1413 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1414 d.release();
1415
1416 progress->WaitForCompletion(-1);
1417 }
1418 }
1419 }
1420 }
1421 }
1422
1423 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1424#endif
1425}
1426
1427int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1428{
1429#ifndef VBOX_WITH_NETFLT
1430 return VERR_NOT_IMPLEMENTED;
1431#else /* # if defined VBOX_WITH_NETFLT */
1432 INetCfg *pNc;
1433 INetCfgComponent *pMpNcc;
1434 INetCfgComponent *pTcpIpNcc;
1435 LPWSTR lpszApp;
1436 HRESULT hr;
1437 IEnumNetCfgBindingPath *pEnumBp;
1438 INetCfgBindingPath *pBp;
1439 IEnumNetCfgBindingInterface *pEnumBi;
1440 INetCfgBindingInterface *pBi;
1441 int iDefault = getDefaultInterfaceIndex();
1442
1443 /* we are using the INetCfg API for getting the list of miniports */
1444 hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
1445 VBOX_APP_NAME,
1446 10000,
1447 &lpszApp);
1448 Assert(hr == S_OK);
1449 if (hr == S_OK)
1450 {
1451# ifdef VBOX_NETFLT_ONDEMAND_BIND
1452 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
1453 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
1454# else
1455 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
1456 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
1457# ifndef VBOX_WITH_HARDENING
1458 if (hr != S_OK)
1459 {
1460 /* TODO: try to install the netflt from here */
1461 }
1462# endif
1463
1464# endif
1465
1466 if (hr == S_OK)
1467 {
1468 INetCfgComponentBindings *pBindings;
1469 hr = pTcpIpNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindings);
1470 Assert(hr == S_OK);
1471 if (hr == S_OK)
1472 {
1473 hr = pBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp);
1474 Assert(hr == S_OK);
1475 if (hr == S_OK)
1476 {
1477 hr = pEnumBp->Reset();
1478 Assert(hr == S_OK);
1479 if (hr == S_OK)
1480 {
1481 while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
1482 {
1483 /* S_OK == enabled, S_FALSE == disabled */
1484 if (pBp->IsEnabled() == S_OK)
1485 {
1486 hr = pBp->EnumBindingInterfaces(&pEnumBi);
1487 Assert(hr == S_OK);
1488 if ( hr == S_OK )
1489 {
1490 hr = pEnumBi->Reset();
1491 Assert(hr == S_OK);
1492 if (hr == S_OK)
1493 {
1494 while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
1495 {
1496 hr = pBi->GetLowerComponent( &pMpNcc );
1497 Assert(hr == S_OK);
1498 if (hr == S_OK)
1499 {
1500 ULONG uComponentStatus;
1501 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1502 if (hr == S_OK)
1503 {
1504 if (uComponentStatus == 0)
1505 {
1506 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
1507 }
1508 }
1509 pMpNcc->Release();
1510 }
1511 pBi->Release();
1512 }
1513 Assert(hr == S_OK || hr == S_FALSE);
1514 }
1515 pEnumBi->Release();
1516 }
1517 }
1518 pBp->Release();
1519 }
1520 Assert(hr == S_OK || hr == S_FALSE);
1521 }
1522 pEnumBp->Release();
1523 }
1524 pBindings->Release();
1525 }
1526 pTcpIpNcc->Release();
1527 }
1528 else
1529 {
1530 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1531 }
1532
1533 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1534 }
1535
1536 netIfListHostAdapters(list);
1537
1538 return VINF_SUCCESS;
1539#endif /* # if defined VBOX_WITH_NETFLT */
1540}
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