VirtualBox

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

Last change on this file since 53390 was 53318, checked in by vboxsync, 10 years ago

NDIS6/NetLwf: Use new component id (oracle_VBoxNetLwf) instead of old sun_VBoxNetFlt

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.8 KB
Line 
1/* $Id: NetIf-win.cpp 53318 2014-11-13 10:06:29Z 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 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
964 }
965 /* create a new object and add it to the list */
966 ComObjPtr<HostNetworkInterface> iface;
967 iface.createObject();
968 /* remove the curly bracket at the end */
969 if (SUCCEEDED(iface->init(name, enmType, &Info)))
970 {
971 if (Info.bIsDefault)
972 pPist->push_front(iface);
973 else
974 pPist->push_back(iface);
975 rc = VINF_SUCCESS;
976 }
977 else
978 {
979 Assert(0);
980 }
981 }
982 CoTaskMemFree(lpszName);
983 }
984
985 return rc;
986}
987
988#endif /* VBOX_WITH_NETFLT */
989
990
991static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
992{
993#ifndef VBOX_WITH_NETFLT
994 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
995 return VERR_NOT_IMPLEMENTED;
996#else /* # if defined VBOX_WITH_NETFLT */
997 INetCfg *pNc;
998 INetCfgComponent *pMpNcc;
999 LPWSTR lpszApp = NULL;
1000 HRESULT hr;
1001 IEnumNetCfgComponent *pEnumComponent;
1002
1003 /* we are using the INetCfg API for getting the list of miniports */
1004 hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
1005 VBOX_APP_NAME,
1006 10000,
1007 &lpszApp);
1008 Assert(hr == S_OK);
1009 if (hr == S_OK)
1010 {
1011 hr = pNc->EnumComponents(&GUID_DEVCLASS_NET, &pEnumComponent);
1012 if (hr == S_OK)
1013 {
1014 while ((hr = pEnumComponent->Next(1, &pMpNcc, NULL)) == S_OK)
1015 {
1016 ULONG uComponentStatus;
1017 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1018 if (hr == S_OK)
1019 {
1020 if (uComponentStatus == 0)
1021 {
1022 LPWSTR pId;
1023 hr = pMpNcc->GetId(&pId);
1024 Assert(hr == S_OK);
1025 if (hr == S_OK)
1026 {
1027 if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1028 {
1029 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
1030 }
1031 CoTaskMemFree(pId);
1032 }
1033 }
1034 }
1035 pMpNcc->Release();
1036 }
1037 Assert(hr == S_OK || hr == S_FALSE);
1038
1039 pEnumComponent->Release();
1040 }
1041 else
1042 {
1043 LogRel((__FUNCTION__": EnumComponents error (0x%x)", hr));
1044 }
1045
1046 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1047 }
1048 else if (lpszApp)
1049 {
1050 CoTaskMemFree(lpszApp);
1051 }
1052#endif /* # if defined VBOX_WITH_NETFLT */
1053 return VINF_SUCCESS;
1054}
1055
1056int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1057{
1058#ifndef VBOX_WITH_NETFLT
1059 return VERR_NOT_IMPLEMENTED;
1060#else
1061 Bstr name;
1062 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1063 if (hr == S_OK)
1064 {
1065 Bstr IfGuid;
1066 hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
1067 Assert(hr == S_OK);
1068 if (hr == S_OK)
1069 {
1070 memset(pInfo, 0, sizeof(NETIFINFO));
1071 Guid guid(IfGuid);
1072 pInfo->Uuid = *(guid.raw());
1073
1074 return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
1075 }
1076 }
1077 return VERR_GENERAL_FAILURE;
1078#endif
1079}
1080
1081int NetIfGetConfigByName(PNETIFINFO)
1082{
1083 return VERR_NOT_IMPLEMENTED;
1084}
1085
1086/**
1087 * Obtain the current state of the interface.
1088 *
1089 * @returns VBox status code.
1090 *
1091 * @param pcszIfName Interface name.
1092 * @param penmState Where to store the retrieved state.
1093 */
1094int NetIfGetState(const char *pcszIfName, NETIFSTATUS *penmState)
1095{
1096 return VERR_NOT_IMPLEMENTED;
1097}
1098
1099/**
1100 * Retrieve the physical link speed in megabits per second. If the interface is
1101 * not up or otherwise unavailable the zero speed is returned.
1102 *
1103 * @returns VBox status code.
1104 *
1105 * @param pcszIfName Interface name.
1106 * @param puMbits Where to store the link speed.
1107 */
1108int NetIfGetLinkSpeed(const char * /*pcszIfName*/, uint32_t * /*puMbits*/)
1109{
1110 return VERR_NOT_IMPLEMENTED;
1111}
1112
1113int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox,
1114 IHostNetworkInterface **aHostNetworkInterface,
1115 IProgress **aProgress,
1116 const char *pcszName)
1117{
1118#ifndef VBOX_WITH_NETFLT
1119 return VERR_NOT_IMPLEMENTED;
1120#else
1121 /* create a progress object */
1122 ComObjPtr<Progress> progress;
1123 progress.createObject();
1124
1125 ComPtr<IHost> host;
1126 HRESULT rc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1127 if (SUCCEEDED(rc))
1128 {
1129 rc = progress->init(pVirtualBox, host,
1130 Bstr(_T("Creating host only network interface")).raw(),
1131 FALSE /* aCancelable */);
1132 if (SUCCEEDED(rc))
1133 {
1134 if (FAILED(rc)) return rc;
1135 progress.queryInterfaceTo(aProgress);
1136
1137 /* create a new uninitialized host interface object */
1138 ComObjPtr<HostNetworkInterface> iface;
1139 iface.createObject();
1140 iface.queryInterfaceTo(aHostNetworkInterface);
1141
1142 /* create the networkInterfaceHelperClient() argument */
1143 std::auto_ptr<NetworkInterfaceHelperClientData>
1144 d(new NetworkInterfaceHelperClientData());
1145 AssertReturn(d.get(), E_OUTOFMEMORY);
1146
1147 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1148// d->name = aName;
1149 d->iface = iface;
1150 d->vBox = pVirtualBox;
1151
1152 rc = pVirtualBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1153 netIfNetworkInterfaceHelperClient,
1154 static_cast<void *>(d.get()),
1155 progress);
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 *pVirtualBox, 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 = pVirtualBox->COMGETTER(Host)(host.asOutParam());
1179 if (SUCCEEDED(rc))
1180 {
1181 rc = progress->init(pVirtualBox, 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 = pVirtualBox->i_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->i_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,
1276 IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1277{
1278#ifndef VBOX_WITH_NETFLT
1279 return VERR_NOT_IMPLEMENTED;
1280#else
1281 HRESULT rc;
1282 Bstr guid;
1283 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1284 if (SUCCEEDED(rc))
1285 {
1286// ComPtr<VirtualBox> vBox;
1287// rc = pIf->getVirtualBox(vBox.asOutParam());
1288// if (SUCCEEDED(rc))
1289 {
1290 /* create a progress object */
1291 ComObjPtr<Progress> progress;
1292 progress.createObject();
1293// ComPtr<IHost> host;
1294// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1295// if (SUCCEEDED(rc))
1296 {
1297 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1298 Bstr("Enabling Dynamic Ip Configuration").raw(),
1299 FALSE /* aCancelable */);
1300 if (SUCCEEDED(rc))
1301 {
1302 if (FAILED(rc)) return rc;
1303// progress.queryInterfaceTo(aProgress);
1304
1305 /* create the networkInterfaceHelperClient() argument */
1306 std::auto_ptr<NetworkInterfaceHelperClientData>
1307 d(new NetworkInterfaceHelperClientData());
1308 AssertReturn(d.get(), E_OUTOFMEMORY);
1309
1310 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1311 d->guid = guid;
1312 d->iface = pIf;
1313 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1314 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1315
1316 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1317 netIfNetworkInterfaceHelperClient,
1318 static_cast<void *>(d.get()),
1319 progress);
1320
1321 if (SUCCEEDED(rc))
1322 {
1323 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1324 d.release();
1325
1326 progress->WaitForCompletion(-1);
1327 }
1328 }
1329 }
1330 }
1331 }
1332
1333 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1334#endif
1335}
1336
1337int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
1338{
1339#ifndef VBOX_WITH_NETFLT
1340 return VERR_NOT_IMPLEMENTED;
1341#else
1342 HRESULT rc;
1343 Bstr guid;
1344 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1345 if (SUCCEEDED(rc))
1346 {
1347// ComPtr<VirtualBox> vBox;
1348// rc = pIf->getVirtualBox(vBox.asOutParam());
1349// if (SUCCEEDED(rc))
1350 {
1351 /* create a progress object */
1352 ComObjPtr<Progress> progress;
1353 progress.createObject();
1354// ComPtr<IHost> host;
1355// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1356// if (SUCCEEDED(rc))
1357 {
1358 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1359 Bstr("Enabling Dynamic Ip Configuration").raw(),
1360 FALSE /* aCancelable */);
1361 if (SUCCEEDED(rc))
1362 {
1363 if (FAILED(rc)) return rc;
1364// progress.queryInterfaceTo(aProgress);
1365
1366 /* create the networkInterfaceHelperClient() argument */
1367 std::auto_ptr<NetworkInterfaceHelperClientData>
1368 d(new NetworkInterfaceHelperClientData());
1369 AssertReturn(d.get(), E_OUTOFMEMORY);
1370
1371 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
1372 d->guid = guid;
1373 d->iface = pIf;
1374
1375 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1376 netIfNetworkInterfaceHelperClient,
1377 static_cast<void *>(d.get()),
1378 progress);
1379
1380 if (SUCCEEDED(rc))
1381 {
1382 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1383 d.release();
1384
1385 progress->WaitForCompletion(-1);
1386 }
1387 }
1388 }
1389 }
1390 }
1391
1392 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1393#endif
1394}
1395
1396int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
1397{
1398#ifndef VBOX_WITH_NETFLT
1399 return VERR_NOT_IMPLEMENTED;
1400#else
1401 HRESULT rc;
1402 Bstr guid;
1403 rc = pIf->COMGETTER(Id)(guid.asOutParam());
1404 if (SUCCEEDED(rc))
1405 {
1406// ComPtr<VirtualBox> vBox;
1407// rc = pIf->getVirtualBox(vBox.asOutParam());
1408// if (SUCCEEDED(rc))
1409 {
1410 /* create a progress object */
1411 ComObjPtr<Progress> progress;
1412 progress.createObject();
1413// ComPtr<IHost> host;
1414// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1415// if (SUCCEEDED(rc))
1416 {
1417 rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
1418 Bstr("Enabling Dynamic Ip Configuration").raw(),
1419 FALSE /* aCancelable */);
1420 if (SUCCEEDED(rc))
1421 {
1422 if (FAILED(rc)) return rc;
1423// progress.queryInterfaceTo(aProgress);
1424
1425 /* create the networkInterfaceHelperClient() argument */
1426 std::auto_ptr<NetworkInterfaceHelperClientData>
1427 d(new NetworkInterfaceHelperClientData());
1428 AssertReturn(d.get(), E_OUTOFMEMORY);
1429
1430 d->msgCode = SVCHlpMsg::DhcpRediscover;
1431 d->guid = guid;
1432 d->iface = pIf;
1433
1434 rc = vBox->i_startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
1435 netIfNetworkInterfaceHelperClient,
1436 static_cast<void *>(d.get()),
1437 progress);
1438
1439 if (SUCCEEDED(rc))
1440 {
1441 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1442 d.release();
1443
1444 progress->WaitForCompletion(-1);
1445 }
1446 }
1447 }
1448 }
1449 }
1450
1451 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1452#endif
1453}
1454
1455int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
1456{
1457#ifndef VBOX_WITH_NETFLT
1458 return VERR_NOT_IMPLEMENTED;
1459#else /* # if defined VBOX_WITH_NETFLT */
1460 INetCfg *pNc;
1461 INetCfgComponent *pMpNcc;
1462 INetCfgComponent *pTcpIpNcc;
1463 LPWSTR lpszApp;
1464 HRESULT hr;
1465 IEnumNetCfgBindingPath *pEnumBp;
1466 INetCfgBindingPath *pBp;
1467 IEnumNetCfgBindingInterface *pEnumBi;
1468 INetCfgBindingInterface *pBi;
1469 int iDefault = getDefaultInterfaceIndex();
1470
1471 /* we are using the INetCfg API for getting the list of miniports */
1472 hr = VBoxNetCfgWinQueryINetCfg(&pNc, FALSE,
1473 VBOX_APP_NAME,
1474 10000,
1475 &lpszApp);
1476 Assert(hr == S_OK);
1477 if (hr == S_OK)
1478 {
1479# ifdef VBOX_NETFLT_ONDEMAND_BIND
1480 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
1481 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
1482# else
1483 /* for the filter-based approach we get all miniports our filter (oracle_VBoxNetLwf)is bound to */
1484 hr = pNc->FindComponent(L"oracle_VBoxNetLwf", &pTcpIpNcc);
1485 if (hr != S_OK)
1486 {
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 /* S_OK == enabled, S_FALSE == disabled */
1517 if (pBp->IsEnabled() == S_OK)
1518 {
1519 hr = pBp->EnumBindingInterfaces(&pEnumBi);
1520 Assert(hr == S_OK);
1521 if (hr == S_OK)
1522 {
1523 hr = pEnumBi->Reset();
1524 Assert(hr == S_OK);
1525 if (hr == S_OK)
1526 {
1527 while ((hr = pEnumBi->Next(1, &pBi, NULL)) == S_OK)
1528 {
1529 hr = pBi->GetLowerComponent(&pMpNcc);
1530 Assert(hr == S_OK);
1531 if (hr == S_OK)
1532 {
1533 ULONG uComponentStatus;
1534 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1535 if (hr == S_OK)
1536 {
1537 if (uComponentStatus == 0)
1538 {
1539 LPWSTR pId;
1540 hr = pMpNcc->GetId(&pId);
1541 Assert(hr == S_OK);
1542 if (hr == S_OK)
1543 {
1544 /*
1545 * Host-only interfaces are ignored here and included into the list
1546 * later in netIfListHostAdapters()
1547 */
1548 if (_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1549 {
1550 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged,
1551 iDefault);
1552 }
1553 CoTaskMemFree(pId);
1554 }
1555 }
1556 }
1557 pMpNcc->Release();
1558 }
1559 pBi->Release();
1560 }
1561 Assert(hr == S_OK || hr == S_FALSE);
1562 }
1563 pEnumBi->Release();
1564 }
1565 }
1566 pBp->Release();
1567 }
1568 Assert(hr == S_OK || hr == S_FALSE);
1569 }
1570 pEnumBp->Release();
1571 }
1572 pBindings->Release();
1573 }
1574 pTcpIpNcc->Release();
1575 }
1576 else
1577 {
1578 LogRel(("failed to get the oracle_VBoxNetLwf(sun_VBoxNetFlt) component, error (0x%x)\n", hr));
1579 }
1580
1581 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1582 }
1583
1584 /* Add host-only adapters to the list */
1585 netIfListHostAdapters(list);
1586
1587 return VINF_SUCCESS;
1588#endif /* # if defined VBOX_WITH_NETFLT */
1589}
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