VirtualBox

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

Last change on this file since 57485 was 57485, checked in by vboxsync, 9 years ago

Main/Network: remove redundant INetCfg query/release during interface enumeration, plus more logging (#7993)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 58.1 KB
Line 
1/* $Id: NetIf-win.cpp 57485 2015-08-21 08:34:03Z 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->i_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(),
671 bstrErr.asOutParam());
672
673 if (hrc == S_OK)
674 {
675 ULONG ip, mask;
676 hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
677 if (hrc == S_OK)
678 {
679 /* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
680 * i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter */
681 ip = ip | (1 << 24);
682 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
683 }
684
685 /* write success followed by GUID */
686 vrc = aClient->write(SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
687 if (RT_FAILURE(vrc)) break;
688 vrc = aClient->write(Utf8Str(name));
689 if (RT_FAILURE(vrc)) break;
690 vrc = aClient->write(guid);
691 if (RT_FAILURE(vrc)) break;
692 }
693 else
694 {
695 vrc = VERR_GENERAL_FAILURE;
696 errMsg = Utf8Str(bstrErr);
697 /* write failure followed by error message */
698 if (errMsg.isEmpty())
699 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
700 vrc = aClient->write(SVCHlpMsg::Error);
701 if (RT_FAILURE(vrc)) break;
702 vrc = aClient->write(errMsg);
703 if (RT_FAILURE(vrc)) break;
704 }
705
706 break;
707 }
708 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
709 {
710 LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
711
712 Guid guid;
713 Bstr bstrErr;
714
715 vrc = aClient->read(guid);
716 if (RT_FAILURE(vrc)) break;
717
718 Utf8Str errMsg;
719 hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
720
721 if (hrc == S_OK)
722 {
723 /* write parameter-less success */
724 vrc = aClient->write(SVCHlpMsg::OK);
725 if (RT_FAILURE(vrc)) break;
726 }
727 else
728 {
729 vrc = VERR_GENERAL_FAILURE;
730 errMsg = Utf8Str(bstrErr);
731 /* write failure followed by error message */
732 if (errMsg.isEmpty())
733 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
734 vrc = aClient->write(SVCHlpMsg::Error);
735 if (RT_FAILURE(vrc)) break;
736 vrc = aClient->write(errMsg);
737 if (RT_FAILURE(vrc)) break;
738 }
739
740 break;
741 }
742 case SVCHlpMsg::EnableStaticIpConfigV6:
743 {
744 LogFlowFunc(("EnableStaticIpConfigV6:\n"));
745
746 Guid guid;
747 Utf8Str ipV6;
748 ULONG maskLengthV6;
749 vrc = aClient->read(guid);
750 if (RT_FAILURE(vrc)) break;
751 vrc = aClient->read(ipV6);
752 if (RT_FAILURE(vrc)) break;
753 vrc = aClient->read(maskLengthV6);
754 if (RT_FAILURE(vrc)) break;
755
756 Utf8Str errMsg;
757 vrc = VERR_NOT_IMPLEMENTED;
758
759 if (RT_SUCCESS(vrc))
760 {
761 /* write success followed by GUID */
762 vrc = aClient->write(SVCHlpMsg::OK);
763 if (RT_FAILURE(vrc)) break;
764 }
765 else
766 {
767 /* write failure followed by error message */
768 if (errMsg.isEmpty())
769 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
770 vrc = aClient->write(SVCHlpMsg::Error);
771 if (RT_FAILURE(vrc)) break;
772 vrc = aClient->write(errMsg);
773 if (RT_FAILURE(vrc)) break;
774 }
775
776 break;
777 }
778 case SVCHlpMsg::EnableStaticIpConfig:
779 {
780 LogFlowFunc(("EnableStaticIpConfig:\n"));
781
782 Guid guid;
783 ULONG ip, mask;
784 vrc = aClient->read(guid);
785 if (RT_FAILURE(vrc)) break;
786 vrc = aClient->read(ip);
787 if (RT_FAILURE(vrc)) break;
788 vrc = aClient->read(mask);
789 if (RT_FAILURE(vrc)) break;
790
791 Utf8Str errMsg;
792 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
793
794 if (hrc == S_OK)
795 {
796 /* write success followed by GUID */
797 vrc = aClient->write(SVCHlpMsg::OK);
798 if (RT_FAILURE(vrc)) break;
799 }
800 else
801 {
802 vrc = VERR_GENERAL_FAILURE;
803 /* write failure followed by error message */
804 if (errMsg.isEmpty())
805 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
806 vrc = aClient->write(SVCHlpMsg::Error);
807 if (RT_FAILURE(vrc)) break;
808 vrc = aClient->write(errMsg);
809 if (RT_FAILURE(vrc)) break;
810 }
811
812 break;
813 }
814 case SVCHlpMsg::EnableDynamicIpConfig:
815 {
816 LogFlowFunc(("EnableDynamicIpConfig:\n"));
817
818 Guid guid;
819 vrc = aClient->read(guid);
820 if (RT_FAILURE(vrc)) break;
821
822 Utf8Str errMsg;
823 hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
824
825 if (hrc == S_OK)
826 {
827 /* write success followed by GUID */
828 vrc = aClient->write(SVCHlpMsg::OK);
829 if (RT_FAILURE(vrc)) break;
830 }
831 else
832 {
833 vrc = VERR_GENERAL_FAILURE;
834 /* write failure followed by error message */
835 if (errMsg.isEmpty())
836 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
837 vrc = aClient->write(SVCHlpMsg::Error);
838 if (RT_FAILURE(vrc)) break;
839 vrc = aClient->write(errMsg);
840 if (RT_FAILURE(vrc)) break;
841 }
842
843 break;
844 }
845 case SVCHlpMsg::DhcpRediscover:
846 {
847 LogFlowFunc(("DhcpRediscover:\n"));
848
849 Guid guid;
850 vrc = aClient->read(guid);
851 if (RT_FAILURE(vrc)) break;
852
853 Utf8Str errMsg;
854 hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
855
856 if (hrc == S_OK)
857 {
858 /* write success followed by GUID */
859 vrc = aClient->write(SVCHlpMsg::OK);
860 if (RT_FAILURE(vrc)) break;
861 }
862 else
863 {
864 vrc = VERR_GENERAL_FAILURE;
865 /* write failure followed by error message */
866 if (errMsg.isEmpty())
867 errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
868 vrc = aClient->write(SVCHlpMsg::Error);
869 if (RT_FAILURE(vrc)) break;
870 vrc = aClient->write(errMsg);
871 if (RT_FAILURE(vrc)) break;
872 }
873
874 break;
875 }
876 default:
877 AssertMsgFailedBreakStmt(
878 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
879 VERR_GENERAL_FAILURE);
880 }
881
882 LogFlowFunc(("vrc=%Rrc\n", vrc));
883 LogFlowFuncLeave();
884 return vrc;
885}
886
887/** @todo REMOVE. OBSOLETE NOW. */
888/**
889 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
890 * later OSes) and it has the UAC (User Account Control) feature enabled.
891 */
892static BOOL IsUACEnabled()
893{
894 LONG rc = 0;
895
896 OSVERSIONINFOEX info;
897 ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
898 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
899 rc = GetVersionEx((OSVERSIONINFO *) &info);
900 AssertReturn(rc != 0, FALSE);
901
902 LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
903 info.dwMajorVersion, info.dwMinorVersion));
904
905 /* we are interested only in Vista (and newer versions...). In all
906 * earlier versions UAC is not present. */
907 if (info.dwMajorVersion < 6)
908 return FALSE;
909
910 /* the default EnableLUA value is 1 (Enabled) */
911 DWORD dwEnableLUA = 1;
912
913 HKEY hKey;
914 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
915 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
916 0, KEY_QUERY_VALUE, &hKey);
917
918 Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
919 if (rc == ERROR_SUCCESS)
920 {
921
922 DWORD cbEnableLUA = sizeof(dwEnableLUA);
923 rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
924 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
925
926 RegCloseKey(hKey);
927
928 Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
929 }
930
931 LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
932
933 return dwEnableLUA == 1;
934}
935
936/* end */
937
938static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
939 INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
940 int iDefaultInterface)
941{
942 LPWSTR lpszName;
943 GUID IfGuid;
944 HRESULT hr;
945 int rc = VERR_GENERAL_FAILURE;
946
947 hr = pncc->GetDisplayName(&lpszName);
948 Assert(hr == S_OK);
949 if (hr == S_OK)
950 {
951 Bstr name(lpszName);
952
953 hr = pncc->GetInstanceGuid(&IfGuid);
954 Assert(hr == S_OK);
955 if (hr == S_OK)
956 {
957 NETIFINFO Info;
958 RT_ZERO(Info);
959 Info.Uuid = *(Guid(IfGuid).raw());
960 rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
961 if (RT_FAILURE(rc))
962 {
963 LogRel(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
964 }
965 LogRel(("vboxNetWinAddComponent: adding %ls\n", lpszName));
966 /* create a new object and add it to the list */
967 ComObjPtr<HostNetworkInterface> iface;
968 iface.createObject();
969 /* remove the curly bracket at the end */
970 rc = iface->init(name, enmType, &Info);
971 if (SUCCEEDED(rc))
972 {
973 if (Info.bIsDefault)
974 pPist->push_front(iface);
975 else
976 pPist->push_back(iface);
977 }
978 else
979 {
980 LogRel(("vboxNetWinAddComponent: HostNetworkInterface::init() -> %Rrc\n", rc));
981 Assert(0);
982 }
983 }
984 else
985 LogRel(("vboxNetWinAddComponent: failed to get device instance GUID (0x%x)\n", hr));
986 CoTaskMemFree(lpszName);
987 }
988 else
989 LogRel(("vboxNetWinAddComponent: failed to get device display name (0x%x)\n", hr));
990
991 return rc;
992}
993
994#endif /* VBOX_WITH_NETFLT */
995
996
997static int netIfListHostAdapters(INetCfg *pNc, std::list<ComObjPtr<HostNetworkInterface> > &list)
998{
999#ifndef VBOX_WITH_NETFLT
1000 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
1001 return VERR_NOT_IMPLEMENTED;
1002#else /* # if defined VBOX_WITH_NETFLT */
1003 INetCfgComponent *pMpNcc;
1004 HRESULT hr;
1005 IEnumNetCfgComponent *pEnumComponent;
1006
1007 hr = pNc->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent);
1008 if (hr == S_OK)
1009 {
1010 while ((hr = pEnumComponent->Next(1, &pMpNcc, NULL)) == S_OK)
1011 {
1012 LPWSTR pwszName;
1013 ULONG uComponentStatus;
1014 hr = pMpNcc->GetDisplayName(&pwszName);
1015 if (hr == S_OK)
1016 LogRel(("netIfListHostAdapters: %ls\n", pwszName));
1017 else
1018 LogRel(("netIfListHostAdapters: failed to get device display name (0x%x)\n", hr));
1019 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1020 if (hr == S_OK)
1021 {
1022 if (uComponentStatus == 0)
1023 {
1024 LPWSTR pId;
1025 hr = pMpNcc->GetId(&pId);
1026 Assert(hr == S_OK);
1027 if (hr == S_OK)
1028 {
1029 LogRel(("netIfListHostAdapters: id = %ls\n", pId));
1030 if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1031 {
1032 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
1033 }
1034 CoTaskMemFree(pId);
1035 }
1036 else
1037 LogRel(("netIfListHostAdapters: failed to get device id (0x%x)\n", hr));
1038 }
1039 }
1040 else
1041 LogRel(("netIfListHostAdapters: failed to get device status (0x%x)\n", hr));
1042 pMpNcc->Release();
1043 }
1044 Assert(hr == S_OK || hr == S_FALSE);
1045
1046 pEnumComponent->Release();
1047 }
1048 else
1049 LogRel(("netIfListHostAdapters: EnumComponents error (0x%x)\n", hr));
1050#endif /* # if defined VBOX_WITH_NETFLT */
1051 return VINF_SUCCESS;
1052}
1053
1054int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1055{
1056#ifndef VBOX_WITH_NETFLT
1057 return VERR_NOT_IMPLEMENTED;
1058#else
1059 Bstr name;
1060 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1061 if (hr == S_OK)
1062 {
1063 Bstr IfGuid;
1064 hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1065 Assert(hr == S_OK);
1066 if (hr == S_OK)
1067 {
1068 memset(pInfo, 0, sizeof(NETIFINFO));
1069 Guid guid(IfGuid);
1070 pInfo->Uuid = *(guid.raw());
1071
1072 return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
1073 }
1074 }
1075 return VERR_GENERAL_FAILURE;
1076#endif
1077}
1078
1079int NetIfGetConfigByName(PNETIFINFO)
1080{
1081 return VERR_NOT_IMPLEMENTED;
1082}
1083
1084/**
1085 * Obtain the current state of the interface.
1086 *
1087 * @returns VBox status code.
1088 *
1089 * @param pcszIfName Interface name.
1090 * @param penmState Where to store the retrieved state.
1091 */
1092int NetIfGetState(const char *pcszIfName, NETIFSTATUS *penmState)
1093{
1094 return VERR_NOT_IMPLEMENTED;
1095}
1096
1097/**
1098 * Retrieve the physical link speed in megabits per second. If the interface is
1099 * not up or otherwise unavailable the zero speed is returned.
1100 *
1101 * @returns VBox status code.
1102 *
1103 * @param pcszIfName Interface name.
1104 * @param puMbits Where to store the link speed.
1105 */
1106int NetIfGetLinkSpeed(const char * /*pcszIfName*/, uint32_t * /*puMbits*/)
1107{
1108 return VERR_NOT_IMPLEMENTED;
1109}
1110
1111int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
1112 IHostNetworkInterface **aHostNetworkInterface,
1113 IProgress **aProgress,
1114 const char *pcszName)
1115{
1116#ifndef VBOX_WITH_NETFLT
1117 return VERR_NOT_IMPLEMENTED;
1118#else
1119 /* create a progress object */
1120 ComObjPtr<Progress> progress;
1121 progress.createObject();
1122
1123 ComPtr<IHost> host;
1124 HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1125 if (SUCCEEDED(rc))
1126 {
1127 rc = progress->init(pVirtualBox, host,
1128 Bstr(_T("Creating host only network interface")).raw(),
1129 FALSE /* aCancelable */);
1130 if (SUCCEEDED(rc))
1131 {
1132 if (FAILED(rc)) return rc;
1133 progress.queryInterfaceTo(aProgress);
1134
1135 /* create a new uninitialized host interface object */
1136 ComObjPtr<HostNetworkInterface> iface;
1137 iface.createObject();
1138 iface.queryInterfaceTo(aHostNetworkInterface);
1139
1140 /* create the networkInterfaceHelperClient() argument */
1141 std::auto_ptr<NetworkInterfaceHelperClientData>
1142 d(new NetworkInterfaceHelperClientData());
1143 AssertReturn(d.get(), E_OUTOFMEMORY);
1144
1145 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1146// d->name = aName;
1147 d->iface = iface;
1148 d->vBox = pVirtualBox;
1149
1150 rc = pVirtualBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1151 netIfNetworkInterfaceHelperClient,
1152 static_cast<void *>(d.get()),
1153 progress);
1154 if (SUCCEEDED(rc))
1155 {
1156 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1157 d.release();
1158 }
1159 }
1160 }
1161
1162 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1163#endif
1164}
1165
1166int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IN_GUID aId,
1167 IProgress **aProgress)
1168{
1169#ifndef VBOX_WITH_NETFLT
1170 return VERR_NOT_IMPLEMENTED;
1171#else
1172 /* create a progress object */
1173 ComObjPtr<Progress> progress;
1174 progress.createObject();
1175 ComPtr<IHost> host;
1176 HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1177 if (SUCCEEDED(rc))
1178 {
1179 rc = progress->init(pVirtualBox, host,
1180 Bstr(_T("Removing host network interface")).raw(),
1181 FALSE /* aCancelable */);
1182 if (SUCCEEDED(rc))
1183 {
1184 if (FAILED(rc)) return rc;
1185 progress.queryInterfaceTo(aProgress);
1186
1187 /* create the networkInterfaceHelperClient() argument */
1188 std::auto_ptr<NetworkInterfaceHelperClientData>
1189 d(new NetworkInterfaceHelperClientData());
1190 AssertReturn(d.get(), E_OUTOFMEMORY);
1191
1192 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1193 d->guid = aId;
1194
1195 rc = pVirtualBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1196 netIfNetworkInterfaceHelperClient,
1197 static_cast<void *>(d.get()),
1198 progress);
1199
1200 if (SUCCEEDED(rc))
1201 {
1202 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1203 d.release();
1204 }
1205 }
1206 }
1207
1208 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1209#endif
1210}
1211
1212int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1213{
1214#ifndef VBOX_WITH_NETFLT
1215 return VERR_NOT_IMPLEMENTED;
1216#else
1217 HRESULT rc;
1218 Bstr guid;
1219 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1220 if (SUCCEEDED(rc))
1221 {
1222// ComPtr<VirtualBox> vBox;
1223// rc = pIf->getVirtualBox(vBox.asOutParam());
1224// if (SUCCEEDED(rc))
1225 {
1226 /* create a progress object */
1227 ComObjPtr<Progress> progress;
1228 progress.createObject();
1229// ComPtr<IHost> host;
1230// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1231// if (SUCCEEDED(rc))
1232 {
1233 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1234 Bstr("Enabling Dynamic Ip Configuration").raw(),
1235 FALSE /* aCancelable */);
1236 if (SUCCEEDED(rc))
1237 {
1238 if (FAILED(rc)) return rc;
1239// progress.queryInterfaceTo(aProgress);
1240
1241 /* create the networkInterfaceHelperClient() argument */
1242 std::auto_ptr<NetworkInterfaceHelperClientData>
1243 d(new NetworkInterfaceHelperClientData());
1244 AssertReturn(d.get(), E_OUTOFMEMORY);
1245
1246 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1247 d->guid = Guid(guid);
1248 d->iface = pIf;
1249 d->u.StaticIP.IPAddress = ip;
1250 d->u.StaticIP.IPNetMask = mask;
1251
1252 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1253 netIfNetworkInterfaceHelperClient,
1254 static_cast<void *>(d.get()),
1255 progress);
1256
1257 if (SUCCEEDED(rc))
1258 {
1259 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1260 d.release();
1261
1262 progress->WaitForCompletion(-1);
1263 }
1264 }
1265 }
1266 }
1267 }
1268
1269 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1270#endif
1271}
1272
1273int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address,
1274 IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1275{
1276#ifndef VBOX_WITH_NETFLT
1277 return VERR_NOT_IMPLEMENTED;
1278#else
1279 HRESULT rc;
1280 Bstr guid;
1281 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1282 if (SUCCEEDED(rc))
1283 {
1284// ComPtr<VirtualBox> vBox;
1285// rc = pIf->getVirtualBox(vBox.asOutParam());
1286// if (SUCCEEDED(rc))
1287 {
1288 /* create a progress object */
1289 ComObjPtr<Progress> progress;
1290 progress.createObject();
1291// ComPtr<IHost> host;
1292// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1293// if (SUCCEEDED(rc))
1294 {
1295 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1296 Bstr("Enabling Dynamic Ip Configuration").raw(),
1297 FALSE /* aCancelable */);
1298 if (SUCCEEDED(rc))
1299 {
1300 if (FAILED(rc)) return rc;
1301// progress.queryInterfaceTo(aProgress);
1302
1303 /* create the networkInterfaceHelperClient() argument */
1304 std::auto_ptr<NetworkInterfaceHelperClientData>
1305 d(new NetworkInterfaceHelperClientData());
1306 AssertReturn(d.get(), E_OUTOFMEMORY);
1307
1308 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1309 d->guid = guid;
1310 d->iface = pIf;
1311 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1312 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1313
1314 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1315 netIfNetworkInterfaceHelperClient,
1316 static_cast<void *>(d.get()),
1317 progress);
1318
1319 if (SUCCEEDED(rc))
1320 {
1321 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1322 d.release();
1323
1324 progress->WaitForCompletion(-1);
1325 }
1326 }
1327 }
1328 }
1329 }
1330
1331 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1332#endif
1333}
1334
1335int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1336{
1337#ifndef VBOX_WITH_NETFLT
1338 return VERR_NOT_IMPLEMENTED;
1339#else
1340 HRESULT rc;
1341 Bstr guid;
1342 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1343 if (SUCCEEDED(rc))
1344 {
1345// ComPtr<VirtualBox> vBox;
1346// rc = pIf->getVirtualBox(vBox.asOutParam());
1347// if (SUCCEEDED(rc))
1348 {
1349 /* create a progress object */
1350 ComObjPtr<Progress> progress;
1351 progress.createObject();
1352// ComPtr<IHost> host;
1353// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1354// if (SUCCEEDED(rc))
1355 {
1356 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1357 Bstr("Enabling Dynamic Ip Configuration").raw(),
1358 FALSE /* aCancelable */);
1359 if (SUCCEEDED(rc))
1360 {
1361 if (FAILED(rc)) return rc;
1362// progress.queryInterfaceTo(aProgress);
1363
1364 /* create the networkInterfaceHelperClient() argument */
1365 std::auto_ptr<NetworkInterfaceHelperClientData>
1366 d(new NetworkInterfaceHelperClientData());
1367 AssertReturn(d.get(), E_OUTOFMEMORY);
1368
1369 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1370 d->guid = guid;
1371 d->iface = pIf;
1372
1373 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1374 netIfNetworkInterfaceHelperClient,
1375 static_cast<void *>(d.get()),
1376 progress);
1377
1378 if (SUCCEEDED(rc))
1379 {
1380 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1381 d.release();
1382
1383 progress->WaitForCompletion(-1);
1384 }
1385 }
1386 }
1387 }
1388 }
1389
1390 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1391#endif
1392}
1393
1394int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1395{
1396#ifndef VBOX_WITH_NETFLT
1397 return VERR_NOT_IMPLEMENTED;
1398#else
1399 HRESULT rc;
1400 Bstr guid;
1401 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1402 if (SUCCEEDED(rc))
1403 {
1404// ComPtr<VirtualBox> vBox;
1405// rc = pIf->getVirtualBox(vBox.asOutParam());
1406// if (SUCCEEDED(rc))
1407 {
1408 /* create a progress object */
1409 ComObjPtr<Progress> progress;
1410 progress.createObject();
1411// ComPtr<IHost> host;
1412// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1413// if (SUCCEEDED(rc))
1414 {
1415 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1416 Bstr("Enabling Dynamic Ip Configuration").raw(),
1417 FALSE /* aCancelable */);
1418 if (SUCCEEDED(rc))
1419 {
1420 if (FAILED(rc)) return rc;
1421// progress.queryInterfaceTo(aProgress);
1422
1423 /* create the networkInterfaceHelperClient() argument */
1424 std::auto_ptr<NetworkInterfaceHelperClientData>
1425 d(new NetworkInterfaceHelperClientData());
1426 AssertReturn(d.get(), E_OUTOFMEMORY);
1427
1428 d->msgCode = SVCHlpMsg::DhcpRediscover;
1429 d->guid = guid;
1430 d->iface = pIf;
1431
1432 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1433 netIfNetworkInterfaceHelperClient,
1434 static_cast<void *>(d.get()),
1435 progress);
1436
1437 if (SUCCEEDED(rc))
1438 {
1439 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1440 d.release();
1441
1442 progress->WaitForCompletion(-1);
1443 }
1444 }
1445 }
1446 }
1447 }
1448
1449 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1450#endif
1451}
1452
1453int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1454{
1455#ifndef VBOX_WITH_NETFLT
1456 return VERR_NOT_IMPLEMENTED;
1457#else /* # if defined VBOX_WITH_NETFLT */
1458 INetCfg *pNc = NULL;
1459 INetCfgComponent *pMpNcc;
1460 INetCfgComponent *pTcpIpNcc;
1461 LPWSTR lpszApp;
1462 HRESULT hr;
1463 IEnumNetCfgBindingPath *pEnumBp;
1464 INetCfgBindingPath *pBp;
1465 IEnumNetCfgBindingInterface *pEnumBi;
1466 INetCfgBindingInterface *pBi;
1467 int iDefault = getDefaultInterfaceIndex();
1468
1469 LogRel(("NetIfList: building the list of interfaces\n"));
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 (oracle_VBoxNetLwf)is bound to */
1483 hr = pNc->FindComponent(L"oracle_VBoxNetLwf", &pTcpIpNcc);
1484 if (hr != S_OK)
1485 {
1486 LogRel(("NetIfList: could not find VBoxNetLwf component (error 0x%x), trying VBoxNetFlt instead\n", hr));
1487 /* fall back to NDIS5 miniport lookup (sun_VBoxNetFlt) */
1488 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
1489 }
1490# ifndef VBOX_WITH_HARDENING
1491 if (hr != S_OK)
1492 {
1493 /* TODO: try to install the netflt from here */
1494 }
1495# endif
1496
1497# endif
1498
1499 if (hr == S_OK)
1500 {
1501 INetCfgComponentBindings *pBindings;
1502 hr = pTcpIpNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pBindings);
1503 Assert(hr == S_OK);
1504 if (hr == S_OK)
1505 {
1506 hr = pBindings->EnumBindingPaths(EBP_BELOW, &pEnumBp);
1507 Assert(hr == S_OK);
1508 if (hr == S_OK)
1509 {
1510 hr = pEnumBp->Reset();
1511 Assert(hr == S_OK);
1512 if (hr == S_OK)
1513 {
1514 while ((hr = pEnumBp->Next(1, &pBp, NULL)) == S_OK)
1515 {
1516 LogRel(("NetIfList: fetched INetCfgBindingPath interface\n"));
1517 /* S_OK == enabled, S_FALSE == disabled */
1518 if (pBp->IsEnabled() == S_OK)
1519 {
1520 hr = pBp->EnumBindingInterfaces(&pEnumBi);
1521 Assert(hr == S_OK);
1522 if (hr == S_OK)
1523 {
1524 hr = pEnumBi->Reset();
1525 Assert(hr == S_OK);
1526 if (hr == S_OK)
1527 {
1528 while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
1529 {
1530 LogRel(("NetIfList: fetched INetCfgBindingInterface interface\n"));
1531 hr = pBi->GetLowerComponent(&pMpNcc);
1532 Assert(hr == S_OK);
1533 if (hr == S_OK)
1534 {
1535 LPWSTR pwszName;
1536 ULONG uComponentStatus;
1537 hr = pMpNcc->GetDisplayName(&pwszName);
1538 if (hr == S_OK)
1539 LogRel(("NetIfList: got %ls\n", pwszName));
1540 else
1541 LogRel(("NetIfList: failed to get device display name (0x%x)\n", hr));
1542 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1543 if (hr == S_OK)
1544 {
1545 if (uComponentStatus == 0)
1546 {
1547 LPWSTR pId;
1548 hr = pMpNcc->GetId(&pId);
1549 Assert(hr == S_OK);
1550 if (hr == S_OK)
1551 {
1552 LogRel(("NetIfList: fetched network adapter id: %.80ls\n", pId));
1553 /*
1554 * Host-only interfaces are ignored here and included into the list
1555 * later in netIfListHostAdapters()
1556 */
1557 if (_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1558 {
1559 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged,
1560 iDefault);
1561 }
1562 CoTaskMemFree(pId);
1563 }
1564 else
1565 LogRel(("NetIfList: failed to get device id (0x%x)\n", hr));
1566 }
1567 else
1568 LogRel(("NetIfList: wrong device status (0x%x)\n", uComponentStatus));
1569 }
1570 else
1571 LogRel(("NetIfList: failed to get device status (0x%x)\n", hr));
1572 pMpNcc->Release();
1573 }
1574 else
1575 LogRel(("NetIfList: failed to get lower component (0x%x)\n", hr));
1576 pBi->Release();
1577 }
1578 Assert(hr == S_OK || hr == S_FALSE);
1579 }
1580 else
1581 LogRel(("NetIfList: IEnumNetCfgBindingInterface::Reset failed (0x%x)\n", hr));
1582 pEnumBi->Release();
1583 }
1584 else
1585 LogRel(("NetIfList: failed to enumerate binding interfaces (0x%x)\n", hr));
1586 }
1587 else
1588 LogRel(("NetIfList: INetCfgBindingPath is disabled\n"));
1589 pBp->Release();
1590 }
1591 Assert(hr == S_OK || hr == S_FALSE);
1592 }
1593 else
1594 LogRel(("NetIfList: IEnumNetCfgBindingPath::Reset failed (0x%x)\n", hr));
1595 pEnumBp->Release();
1596 }
1597 else
1598 LogRel(("NetIfList: EnumBindingPaths failed (0x%x)\n", hr));
1599 pBindings->Release();
1600 }
1601 else
1602 LogRel(("NetIfList: failed to acquire INetCfgComponentBindings interface\n"));
1603 pTcpIpNcc->Release();
1604 }
1605 else
1606 {
1607 LogRel(("failed to get the oracle_VBoxNetLwf(sun_VBoxNetFlt) component, error (0x%x)\n", hr));
1608 }
1609
1610 /* Add host-only adapters to the list */
1611 netIfListHostAdapters(pNc, list);
1612
1613 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1614 }
1615 else
1616 {
1617 if (pNc)
1618 pNc->Release();
1619 pNc = NULL;
1620 LogRel(("NetIfList: failed to acquire INetCfg interface (0x%x), trying CoCreateInstance...\n", hr));
1621 hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNc);
1622 LogRel(("NetIfList: CoCreateInstance failed with 0x%x\n", hr));
1623 if (pNc)
1624 pNc->Release();
1625 }
1626
1627 return VINF_SUCCESS;
1628#endif /* # if defined VBOX_WITH_NETFLT */
1629}
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