VirtualBox

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

Last change on this file since 19130 was 19130, checked in by vboxsync, 16 years ago

NetAdp/win: static ip settings by default, dynamic calculation

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 72.7 KB
Line 
1/* $Id: NetIf-win.cpp 19130 2009-04-23 08:19:03Z vboxsync $ */
2/** @file
3 * Main - NetIfList, Windows implementation.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_MAIN
28
29#include <iprt/asm.h>
30#include <iprt/err.h>
31#include <list>
32
33#define _WIN32_DCOM
34#include <winsock2.h>
35#include <ws2tcpip.h>
36#include <windows.h>
37
38#ifdef VBOX_WITH_NETFLT
39#include "VBox/WinNetConfig.h"
40#include "devguid.h"
41#endif
42
43#include <iphlpapi.h>
44
45#include "Logging.h"
46#include "HostNetworkInterfaceImpl.h"
47#include "ProgressImpl.h"
48#include "VirtualBoxImpl.h"
49#include "netif.h"
50
51#ifdef VBOX_WITH_NETFLT
52#include <Wbemidl.h>
53#include <comdef.h>
54
55#include "svchlp.h"
56
57#include <shellapi.h>
58#define INITGUID
59#include <guiddef.h>
60#include <devguid.h>
61#include <objbase.h>
62#include <setupapi.h>
63#include <shlobj.h>
64#include <cfgmgr32.h>
65
66#define VBOX_APP_NAME L"VirtualBox"
67
68static HRESULT netIfWinIsHostOnly(IWbemClassObject * pAdapterConfig, BOOL * pbIsHostOnly)
69{
70 VARIANT vtServiceName;
71 BOOL bIsHostOnly = FALSE;
72 VariantInit(&vtServiceName);
73
74 HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0, &vtServiceName, 0, 0);
75 if(SUCCEEDED(hr))
76 {
77 *pbIsHostOnly = !Bstr(vtServiceName.bstrVal).compare(Bstr("VBoxNetAdp"));
78
79 VariantClear(&vtServiceName);
80 }
81
82 return hr;
83}
84
85static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc)
86{
87 HRESULT hres;
88
89 // Step 3: ---------------------------------------------------
90 // Obtain the initial locator to WMI -------------------------
91
92 IWbemLocator *pLoc = NULL;
93
94 hres = CoCreateInstance(
95 CLSID_WbemLocator,
96 0,
97 CLSCTX_INPROC_SERVER,
98 IID_IWbemLocator, (LPVOID *) &pLoc);
99 if(SUCCEEDED(hres))
100 {
101 // Step 4: -----------------------------------------------------
102 // Connect to WMI through the IWbemLocator::ConnectServer method
103
104 IWbemServices *pSvc = NULL;
105
106 // Connect to the root\cimv2 namespace with
107 // the current user and obtain pointer pSvc
108 // to make IWbemServices calls.
109 hres = pLoc->ConnectServer(
110 _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
111 NULL, // User name. NULL = current user
112 NULL, // User password. NULL = current
113 0, // Locale. NULL indicates current
114 NULL, // Security flags.
115 0, // Authority (e.g. Kerberos)
116 0, // Context object
117 &pSvc // pointer to IWbemServices proxy
118 );
119 if(SUCCEEDED(hres))
120 {
121 LogRel(("Connected to ROOT\\CIMV2 WMI namespace\n"));
122
123 // Step 5: --------------------------------------------------
124 // Set security levels on the proxy -------------------------
125
126 hres = CoSetProxyBlanket(
127 pSvc, // Indicates the proxy to set
128 RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
129 RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
130 NULL, // Server principal name
131 RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
132 RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
133 NULL, // client identity
134 EOAC_NONE // proxy capabilities
135 );
136 if(SUCCEEDED(hres))
137 {
138 *ppSvc = pSvc;
139 /* do not need it any more */
140 pLoc->Release();
141 return hres;
142 }
143 else
144 {
145 LogRel(("Could not set proxy blanket. Error code = 0x%x\n", hres));
146 }
147
148 pSvc->Release();
149 }
150 else
151 {
152 LogRel(("Could not connect. Error code = 0x%x\n", hres));
153 }
154
155 pLoc->Release();
156 }
157 else
158 {
159 LogRel(("Failed to create IWbemLocator object. Err code = 0x%x\n", hres));
160// CoUninitialize();
161 }
162
163 return hres;
164}
165
166static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const Guid &guid, IWbemClassObject **pAdapterConfig)
167{
168 HRESULT hres;
169 WCHAR aQueryString[256];
170// char uuidStr[RTUUID_STR_LENGTH];
171// int rc = RTUuidToStr(guid.toString().raw(), uuidStr, sizeof(uuidStr));
172 {
173 swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"{%S}\"", guid.toString().raw());
174 // Step 6: --------------------------------------------------
175 // Use the IWbemServices pointer to make requests of WMI ----
176
177 IEnumWbemClassObject* pEnumerator = NULL;
178 hres = pSvc->ExecQuery(
179 bstr_t("WQL"),
180 bstr_t(aQueryString),
181 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
182 NULL,
183 &pEnumerator);
184 if(SUCCEEDED(hres))
185 {
186 // Step 7: -------------------------------------------------
187 // Get the data from the query in step 6 -------------------
188
189 IWbemClassObject *pclsObj;
190 ULONG uReturn = 0;
191
192 while (pEnumerator)
193 {
194 HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
195 &pclsObj, &uReturn);
196
197 if(SUCCEEDED(hres))
198 {
199 if(uReturn)
200 {
201 pEnumerator->Release();
202 *pAdapterConfig = pclsObj;
203 hres = S_OK;
204 return hres;
205 }
206 else
207 {
208 hres = S_FALSE;
209 }
210 }
211
212 }
213 pEnumerator->Release();
214 }
215 else
216 {
217 Log(("Query for operating system name failed. Error code = 0x%x\n", hres));
218 }
219 }
220
221 return hres;
222}
223
224static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr)
225{
226 VARIANT index;
227
228 // Get the value of the key property
229 HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0);
230 if(SUCCEEDED(hr))
231 {
232 WCHAR strIndex[8];
233 swprintf(strIndex, L"%u", index.uintVal);
234 *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy();
235 }
236 else
237 {
238 DWORD dwError = GetLastError();
239 Assert(0);
240 hr = HRESULT_FROM_WIN32( dwError );
241 }
242 return hr;
243}
244
245static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath,
246 BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs,
247 IWbemClassObject** ppOutParams
248 )
249{
250 HRESULT hres = S_OK;
251 // Step 6: --------------------------------------------------
252 // Use the IWbemServices pointer to make requests of WMI ----
253
254 ComPtr<IWbemClassObject> pInParamsDefinition;
255 ComPtr<IWbemClassObject> pClassInstance;
256
257 if(cArgs)
258 {
259 hres = pClass->GetMethod(MethodName, 0,
260 pInParamsDefinition.asOutParam(), NULL);
261 if(SUCCEEDED(hres))
262 {
263 hres = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam());
264
265 if(SUCCEEDED(hres))
266 {
267 for(UINT i = 0; i < cArgs; i++)
268 {
269 // Store the value for the in parameters
270 hres = pClassInstance->Put(pArgNames[i], 0,
271 pArgs[i], 0);
272 if(FAILED(hres))
273 {
274 break;
275 }
276 }
277 }
278 }
279 }
280
281 if(SUCCEEDED(hres))
282 {
283 IWbemClassObject* pOutParams = NULL;
284 hres = pSvc->ExecMethod(ObjPath, MethodName, 0,
285 NULL, pClassInstance, &pOutParams, NULL);
286 if(SUCCEEDED(hres))
287 {
288 *ppOutParams = pOutParams;
289 }
290 }
291
292 return hres;
293}
294
295static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp)
296{
297 HRESULT hr;
298 SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp);
299 if(pIpArray)
300 {
301 for(UINT i = 0; i < cIp; i++)
302 {
303 char* addr = inet_ntoa(aIp[i]);
304 BSTR val = bstr_t(addr).copy();
305 long aIndex[1];
306 aIndex[0] = i;
307 hr = SafeArrayPutElement(pIpArray, aIndex, val);
308 if(FAILED(hr))
309 {
310 SysFreeString(val);
311 SafeArrayDestroy(pIpArray);
312 break;
313 }
314 }
315
316 if(SUCCEEDED(hr))
317 {
318 *ppArray = pIpArray;
319 }
320 }
321 else
322 {
323 DWORD dwError = GetLastError();
324 Assert(0);
325 hr = HRESULT_FROM_WIN32( dwError );
326 }
327
328 return hr;
329}
330
331static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip)
332{
333 HRESULT hr;
334 SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1);
335 if(pIpArray)
336 {
337 BSTR val = bstr_t(Ip, false).copy();
338 long aIndex[1];
339 aIndex[0] = 0;
340 hr = SafeArrayPutElement(pIpArray, aIndex, val);
341 if(FAILED(hr))
342 {
343 SysFreeString(val);
344 SafeArrayDestroy(pIpArray);
345 }
346
347 if(SUCCEEDED(hr))
348 {
349 *ppArray = pIpArray;
350 }
351 }
352 else
353 {
354 DWORD dwError = GetLastError();
355 Assert(0);
356 hr = HRESULT_FROM_WIN32( dwError );
357 }
358
359 return hr;
360}
361
362
363static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp)
364{
365 HRESULT hr;
366 VariantInit(pIpAddresses);
367 pIpAddresses->vt = VT_ARRAY | VT_BSTR;
368 SAFEARRAY *pIpArray;
369 hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp);
370 if(SUCCEEDED(hr))
371 {
372 pIpAddresses->parray = pIpArray;
373 }
374 return hr;
375}
376
377static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip)
378{
379 HRESULT hr;
380 VariantInit(pIpAddresses);
381 pIpAddresses->vt = VT_ARRAY | VT_BSTR;
382 SAFEARRAY *pIpArray;
383 hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip);
384 if(SUCCEEDED(hr))
385 {
386 pIpAddresses->parray = pIpArray;
387 }
388 return hr;
389}
390
391static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask)
392{
393 ComPtr<IWbemClassObject> pClass;
394 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
395 HRESULT hr;
396 if(ClassName)
397 {
398 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
399 if(SUCCEEDED(hr))
400 {
401 LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"};
402 LPVARIANT args[] = {pIp, pMask};
403 ComPtr<IWbemClassObject> pOutParams;
404
405 hr = netIfExecMethod(pSvc, pClass, ObjPath,
406 bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam());
407 if(SUCCEEDED(hr))
408 {
409 VARIANT varReturnValue;
410 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
411 &varReturnValue, NULL, 0);
412 Assert(SUCCEEDED(hr));
413 if(SUCCEEDED(hr))
414 {
415// Assert(varReturnValue.vt == VT_UINT);
416 int winEr = varReturnValue.uintVal;
417 switch(winEr)
418 {
419 case 0:
420 hr = S_OK;
421 break;
422 default:
423 hr = HRESULT_FROM_WIN32( winEr );
424 break;
425 }
426 }
427 }
428 }
429 SysFreeString(ClassName);
430 }
431 else
432 {
433 DWORD dwError = GetLastError();
434 Assert(0);
435 hr = HRESULT_FROM_WIN32( dwError );
436 }
437
438 return hr;
439}
440
441
442static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp)
443{
444 VARIANT ipAddresses;
445 HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp);
446 if(SUCCEEDED(hr))
447 {
448 VARIANT ipMasks;
449 hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp);
450 if(SUCCEEDED(hr))
451 {
452 netIfWinEnableStatic(pSvc, ObjPath, &ipAddresses, &ipMasks);
453 VariantClear(&ipMasks);
454 }
455 VariantClear(&ipAddresses);
456 }
457 return hr;
458}
459
460static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Ip, BSTR Mask)
461{
462 VARIANT ipAddresses;
463 HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip);
464 if(SUCCEEDED(hr))
465 {
466 VARIANT ipMasks;
467 hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask);
468 if(SUCCEEDED(hr))
469 {
470 netIfWinEnableStatic(pSvc, ObjPath, &ipAddresses, &ipMasks);
471 VariantClear(&ipMasks);
472 }
473 VariantClear(&ipAddresses);
474 }
475 return hr;
476}
477
478/* win API allows to set gw metrics as well, we are not setting them */
479static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw)
480{
481 ComPtr<IWbemClassObject> pClass;
482 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
483 HRESULT hr;
484 if(ClassName)
485 {
486 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
487 if(SUCCEEDED(hr))
488 {
489 LPWSTR argNames[] = {L"DefaultIPGateway"};
490 LPVARIANT args[] = {pGw};
491 ComPtr<IWbemClassObject> pOutParams;
492
493 hr = netIfExecMethod(pSvc, pClass, ObjPath,
494 bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
495 if(SUCCEEDED(hr))
496 {
497 VARIANT varReturnValue;
498 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
499 &varReturnValue, NULL, 0);
500 Assert(SUCCEEDED(hr));
501 if(SUCCEEDED(hr))
502 {
503// Assert(varReturnValue.vt == VT_UINT);
504 int winEr = varReturnValue.uintVal;
505 switch(winEr)
506 {
507 case 0:
508 hr = S_OK;
509 break;
510 default:
511 hr = HRESULT_FROM_WIN32( winEr );
512 break;
513 }
514 }
515 } }
516 SysFreeString(ClassName);
517 }
518 else
519 {
520 DWORD dwError = GetLastError();
521 Assert(0);
522 hr = HRESULT_FROM_WIN32( dwError );
523 }
524
525 return hr;
526}
527
528/* win API allows to set gw metrics as well, we are not setting them */
529static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw)
530{
531 VARIANT gwais;
532 HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw);
533 if(SUCCEEDED(hr))
534 {
535 netIfWinSetGateways(pSvc, ObjPath, &gwais);
536 VariantClear(&gwais);
537 }
538 return hr;
539}
540
541/* win API allows to set gw metrics as well, we are not setting them */
542static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw)
543{
544 VARIANT vGw;
545 HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw);
546 if(SUCCEEDED(hr))
547 {
548 netIfWinSetGateways(pSvc, ObjPath, &vGw);
549 VariantClear(&vGw);
550 }
551 return hr;
552}
553
554static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath)
555{
556 ComPtr<IWbemClassObject> pClass;
557 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
558 HRESULT hr;
559 if(ClassName)
560 {
561 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
562 if(SUCCEEDED(hr))
563 {
564 ComPtr<IWbemClassObject> pOutParams;
565
566 hr = netIfExecMethod(pSvc, pClass, ObjPath,
567 bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
568 if(SUCCEEDED(hr))
569 {
570 VARIANT varReturnValue;
571 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
572 &varReturnValue, NULL, 0);
573 Assert(SUCCEEDED(hr));
574 if(SUCCEEDED(hr))
575 {
576// Assert(varReturnValue.vt == VT_UINT);
577 int winEr = varReturnValue.uintVal;
578 switch(winEr)
579 {
580 case 0:
581 hr = S_OK;
582 break;
583 default:
584 hr = HRESULT_FROM_WIN32( winEr );
585 break;
586 }
587 }
588 }
589 }
590 SysFreeString(ClassName);
591 }
592 else
593 {
594 DWORD dwError = GetLastError();
595 Assert(0);
596 hr = HRESULT_FROM_WIN32( dwError );
597 }
598
599 return hr;
600}
601
602static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath)
603{
604 ComPtr<IWbemClassObject> pClass;
605 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
606 HRESULT hr;
607 if(ClassName)
608 {
609 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
610 if(SUCCEEDED(hr))
611 {
612 ComPtr<IWbemClassObject> pOutParams;
613
614 hr = netIfExecMethod(pSvc, pClass, ObjPath,
615 bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
616 if(SUCCEEDED(hr))
617 {
618 VARIANT varReturnValue;
619 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
620 &varReturnValue, NULL, 0);
621 Assert(SUCCEEDED(hr));
622 if(SUCCEEDED(hr))
623 {
624// Assert(varReturnValue.vt == VT_UINT);
625 int winEr = varReturnValue.uintVal;
626 if(winEr == 0)
627 {
628 hr = netIfExecMethod(pSvc, pClass, ObjPath,
629 bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
630 if(SUCCEEDED(hr))
631 {
632 VARIANT varReturnValue;
633 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
634 &varReturnValue, NULL, 0);
635 Assert(SUCCEEDED(hr));
636 if(SUCCEEDED(hr))
637 {
638 // Assert(varReturnValue.vt == VT_UINT);
639 int winEr = varReturnValue.uintVal;
640 if(winEr == 0)
641 {
642 hr = S_OK;
643 }
644 else
645 {
646 hr = HRESULT_FROM_WIN32( winEr );
647 }
648 }
649 }
650 }
651 else
652 {
653 hr = HRESULT_FROM_WIN32( winEr );
654 }
655 }
656 }
657 }
658 SysFreeString(ClassName);
659 }
660 else
661 {
662 DWORD dwError = GetLastError();
663 Assert(0);
664 hr = HRESULT_FROM_WIN32( dwError );
665 }
666
667 return hr;
668}
669
670static int netIfWinIsDhcpEnabled(const Guid &guid, BOOL *pEnabled)
671{
672 HRESULT hr;
673 ComPtr <IWbemServices> pSvc;
674 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
675 if(SUCCEEDED(hr))
676 {
677 ComPtr <IWbemClassObject> pAdapterConfig;
678 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
679 if(SUCCEEDED(hr))
680 {
681 VARIANT vtEnabled;
682 hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
683 if(SUCCEEDED(hr))
684 {
685 *pEnabled = vtEnabled.boolVal;
686 }
687 }
688 }
689
690 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
691}
692
693static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo)
694{
695 DWORD dwRc;
696 int rc = VINF_SUCCESS;
697 /*
698 * Most of the hosts probably have less than 10 adapters,
699 * so we'll mostly succeed from the first attempt.
700 */
701 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
702 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
703 if (!pAddresses)
704 return VERR_NO_MEMORY;
705 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
706 if (dwRc == ERROR_BUFFER_OVERFLOW)
707 {
708 /* Impressive! More than 10 adapters! Get more memory and try again. */
709 RTMemFree(pAddresses);
710 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
711 if (!pAddresses)
712 return VERR_NO_MEMORY;
713 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
714 }
715 if (dwRc == NO_ERROR)
716 {
717 PIP_ADAPTER_ADDRESSES pAdapter;
718 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
719 {
720 char *pszUuid = RTStrDup(pAdapter->AdapterName);
721 size_t len = strlen(pszUuid) - 1;
722 if (pszUuid[0] == '{' && pszUuid[len] == '}')
723 {
724 pszUuid[len] = 0;
725 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
726 {
727 bool fIPFound, fIPv6Found;
728 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
729 fIPFound = fIPv6Found = false;
730 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
731 {
732 switch (pAddr->Address.lpSockaddr->sa_family)
733 {
734 case AF_INET:
735 if (!fIPFound)
736 {
737 fIPFound = true;
738 memcpy(&pInfo->IPAddress,
739 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
740 sizeof(pInfo->IPAddress));
741 }
742 break;
743 case AF_INET6:
744 if (!fIPv6Found)
745 {
746 fIPv6Found = true;
747 memcpy(&pInfo->IPv6Address,
748 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
749 sizeof(pInfo->IPv6Address));
750 }
751 break;
752 }
753 }
754 PIP_ADAPTER_PREFIX pPrefix;
755 fIPFound = fIPv6Found = false;
756 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
757 {
758 switch (pPrefix->Address.lpSockaddr->sa_family)
759 {
760 case AF_INET:
761 if (!fIPFound)
762 {
763 fIPFound = true;
764 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
765 }
766 break;
767 case AF_INET6:
768 if (!fIPv6Found)
769 {
770 fIPv6Found = true;
771 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
772 }
773 break;
774 }
775 }
776 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
777 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
778 else
779 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
780 pInfo->enmMediumType = NETIF_T_ETHERNET;
781 pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
782 RTStrFree(pszUuid);
783 break;
784 }
785 }
786 RTStrFree(pszUuid);
787 }
788
789 BOOL bEnabled;
790 rc = netIfWinIsDhcpEnabled(guid, &bEnabled);
791 Assert(RT_SUCCESS(rc));
792 if(RT_SUCCESS(rc))
793 {
794 pInfo->bDhcpEnabled = bEnabled;
795 }
796 }
797 RTMemFree(pAddresses);
798
799 return VINF_SUCCESS;
800}
801
802static int netIfEnableStaticIpConfigV6(const Guid & guid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
803{
804 HRESULT hr;
805 ComPtr <IWbemServices> pSvc;
806 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
807 if(SUCCEEDED(hr))
808 {
809 ComPtr <IWbemClassObject> pAdapterConfig;
810 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
811 if(SUCCEEDED(hr))
812 {
813 BSTR ObjPath;
814 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
815 if(SUCCEEDED(hr))
816 {
817 hr = netIfWinEnableStaticV4V6(pSvc, ObjPath, aIPV6Address, aIPV6Mask);
818 if(SUCCEEDED(hr))
819 {
820 if(aIPV6DefaultGateway)
821 {
822 hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway);
823 }
824 if(SUCCEEDED(hr))
825 {
826// hr = netIfWinUpdateConfig(pIf);
827 }
828 }
829 SysFreeString(ObjPath);
830 }
831 }
832 }
833
834 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
835}
836
837static int netIfEnableStaticIpConfigV6(const Guid &guid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
838{
839#if 0
840 RTNETADDRIPV6 Mask;
841 int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask);
842 if(RT_SUCCESS(rc))
843 {
844 Bstr maskStr = composeIPv6Address(&Mask);
845 rc = netIfEnableStaticIpConfigV6(guid, aIPV6Address, maskStr, NULL);
846 }
847 return rc;
848#else
849 return VERR_NOT_IMPLEMENTED;
850#endif
851}
852
853static HRESULT netIfEnableDynamicIpConfig(const Guid &guid)
854{
855 HRESULT hr;
856 ComPtr <IWbemServices> pSvc;
857 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
858 if(SUCCEEDED(hr))
859 {
860 ComPtr <IWbemClassObject> pAdapterConfig;
861 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
862 if(SUCCEEDED(hr))
863 {
864 BOOL bIsHostOnly;
865 hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
866 if(SUCCEEDED(hr))
867 {
868 if(bIsHostOnly)
869 {
870 BSTR ObjPath;
871 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
872 if(SUCCEEDED(hr))
873 {
874 hr = netIfWinEnableDHCP(pSvc, ObjPath);
875 if(SUCCEEDED(hr))
876 {
877// hr = netIfWinUpdateConfig(pIf);
878 }
879 SysFreeString(ObjPath);
880 }
881 }
882 else
883 {
884 hr = E_FAIL;
885 }
886 }
887 }
888 }
889
890
891 return hr;
892}
893
894static HRESULT netIfDhcpRediscover(const Guid &guid)
895{
896 HRESULT hr;
897 ComPtr <IWbemServices> pSvc;
898 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
899 if(SUCCEEDED(hr))
900 {
901 ComPtr <IWbemClassObject> pAdapterConfig;
902 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
903 if(SUCCEEDED(hr))
904 {
905 BOOL bIsHostOnly;
906 hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
907 if(SUCCEEDED(hr))
908 {
909 if(bIsHostOnly)
910 {
911 BSTR ObjPath;
912 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
913 if(SUCCEEDED(hr))
914 {
915 hr = netIfWinDhcpRediscover(pSvc, ObjPath);
916 if(SUCCEEDED(hr))
917 {
918// hr = netIfWinUpdateConfig(pIf);
919 }
920 SysFreeString(ObjPath);
921 }
922 }
923 else
924 {
925 hr = E_FAIL;
926 }
927 }
928 }
929 }
930
931
932 return hr;
933}
934
935/* svc helper func */
936
937struct StaticIpConfig
938{
939 ULONG IPAddress;
940 ULONG IPNetMask;
941};
942
943struct StaticIpV6Config
944{
945 BSTR IPV6Address;
946 ULONG IPV6NetMaskLength;
947};
948
949struct NetworkInterfaceHelperClientData
950{
951 SVCHlpMsg::Code msgCode;
952 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
953 Bstr name;
954 ComObjPtr <HostNetworkInterface> iface;
955 ComObjPtr <VirtualBox> vBox;
956 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
957 Guid guid;
958
959 union
960 {
961 StaticIpConfig StaticIP;
962 StaticIpV6Config StaticIPV6;
963 } u;
964
965
966};
967
968static HRESULT netIfNetworkInterfaceHelperClient (SVCHlpClient *aClient,
969 Progress *aProgress,
970 void *aUser, int *aVrc)
971{
972 LogFlowFuncEnter();
973 LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n",
974 aClient, aProgress, aUser));
975
976 AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) ||
977 (aClient != NULL && aProgress != NULL && aVrc != NULL),
978 E_POINTER);
979 AssertReturn (aUser, E_POINTER);
980
981 std::auto_ptr <NetworkInterfaceHelperClientData>
982 d (static_cast <NetworkInterfaceHelperClientData *> (aUser));
983
984 if (aClient == NULL)
985 {
986 /* "cleanup only" mode, just return (it will free aUser) */
987 return S_OK;
988 }
989
990 HRESULT rc = S_OK;
991 int vrc = VINF_SUCCESS;
992
993 switch (d->msgCode)
994 {
995 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
996 {
997 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
998 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
999
1000 /* write message and parameters */
1001 vrc = aClient->write (d->msgCode);
1002 if (RT_FAILURE (vrc)) break;
1003// vrc = aClient->write (Utf8Str (d->name));
1004// if (RT_FAILURE (vrc)) break;
1005
1006 /* wait for a reply */
1007 bool endLoop = false;
1008 while (!endLoop)
1009 {
1010 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1011
1012 vrc = aClient->read (reply);
1013 if (RT_FAILURE (vrc)) break;
1014
1015 switch (reply)
1016 {
1017 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
1018 {
1019 /* read the GUID */
1020 Guid guid;
1021 Utf8Str name;
1022 vrc = aClient->read (name);
1023 if (RT_FAILURE (vrc)) break;
1024 vrc = aClient->read (guid);
1025 if (RT_FAILURE (vrc)) break;
1026
1027 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", guid.raw()));
1028
1029 /* initialize the object returned to the caller by
1030 * CreateHostOnlyNetworkInterface() */
1031 rc = d->iface->init (Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
1032 if(SUCCEEDED(rc))
1033 {
1034 rc = d->iface->setVirtualBox(d->vBox);
1035 if(SUCCEEDED(rc))
1036 {
1037 rc = d->iface->updateConfig();
1038 }
1039 }
1040 endLoop = true;
1041 break;
1042 }
1043 case SVCHlpMsg::Error:
1044 {
1045 /* read the error message */
1046 Utf8Str errMsg;
1047 vrc = aClient->read (errMsg);
1048 if (RT_FAILURE (vrc)) break;
1049
1050 rc = E_FAIL;//TODO: setError (E_FAIL, errMsg);
1051 endLoop = true;
1052 break;
1053 }
1054 default:
1055 {
1056 endLoop = true;
1057 rc = E_FAIL;//TODO: ComAssertMsgFailedBreak ((
1058 //"Invalid message code %d (%08lX)\n",
1059 //reply, reply),
1060 //rc = E_FAIL);
1061 }
1062 }
1063 }
1064
1065 break;
1066 }
1067 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
1068 {
1069 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
1070 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
1071
1072 /* write message and parameters */
1073 vrc = aClient->write (d->msgCode);
1074 if (RT_FAILURE (vrc)) break;
1075 vrc = aClient->write (d->guid);
1076 if (RT_FAILURE (vrc)) break;
1077
1078 /* wait for a reply */
1079 bool endLoop = false;
1080 while (!endLoop)
1081 {
1082 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1083
1084 vrc = aClient->read (reply);
1085 if (RT_FAILURE (vrc)) break;
1086
1087 switch (reply)
1088 {
1089 case SVCHlpMsg::OK:
1090 {
1091 /* no parameters */
1092 rc = S_OK;
1093 endLoop = true;
1094 break;
1095 }
1096 case SVCHlpMsg::Error:
1097 {
1098 /* read the error message */
1099 Utf8Str errMsg;
1100 vrc = aClient->read (errMsg);
1101 if (RT_FAILURE (vrc)) break;
1102
1103 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1104 endLoop = true;
1105 break;
1106 }
1107 default:
1108 {
1109 endLoop = true;
1110 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1111 //"Invalid message code %d (%08lX)\n",
1112 //reply, reply),
1113 //rc = E_FAIL);
1114 }
1115 }
1116 }
1117
1118 break;
1119 }
1120 case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
1121 {
1122 LogFlowFunc (("EnableDynamicIpConfig:\n"));
1123 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1124
1125 /* write message and parameters */
1126 vrc = aClient->write (d->msgCode);
1127 if (RT_FAILURE (vrc)) break;
1128 vrc = aClient->write (d->guid);
1129 if (RT_FAILURE (vrc)) break;
1130
1131 /* wait for a reply */
1132 bool endLoop = false;
1133 while (!endLoop)
1134 {
1135 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1136
1137 vrc = aClient->read (reply);
1138 if (RT_FAILURE (vrc)) break;
1139
1140 switch (reply)
1141 {
1142 case SVCHlpMsg::OK:
1143 {
1144 /* no parameters */
1145 rc = d->iface->updateConfig();
1146 endLoop = true;
1147 break;
1148 }
1149 case SVCHlpMsg::Error:
1150 {
1151 /* read the error message */
1152 Utf8Str errMsg;
1153 vrc = aClient->read (errMsg);
1154 if (RT_FAILURE (vrc)) break;
1155
1156 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1157 endLoop = true;
1158 break;
1159 }
1160 default:
1161 {
1162 endLoop = true;
1163 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1164 //"Invalid message code %d (%08lX)\n",
1165 //reply, reply),
1166 //rc = E_FAIL);
1167 }
1168 }
1169 }
1170
1171 break;
1172 }
1173 case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
1174 {
1175 LogFlowFunc (("EnableStaticIpConfig:\n"));
1176 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1177
1178 /* write message and parameters */
1179 vrc = aClient->write (d->msgCode);
1180 if (RT_FAILURE (vrc)) break;
1181 vrc = aClient->write (d->guid);
1182 if (RT_FAILURE (vrc)) break;
1183 vrc = aClient->write (d->u.StaticIP.IPAddress);
1184 if (RT_FAILURE (vrc)) break;
1185 vrc = aClient->write (d->u.StaticIP.IPNetMask);
1186 if (RT_FAILURE (vrc)) break;
1187
1188 /* wait for a reply */
1189 bool endLoop = false;
1190 while (!endLoop)
1191 {
1192 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1193
1194 vrc = aClient->read (reply);
1195 if (RT_FAILURE (vrc)) break;
1196
1197 switch (reply)
1198 {
1199 case SVCHlpMsg::OK:
1200 {
1201 /* no parameters */
1202 rc = d->iface->updateConfig();
1203 endLoop = true;
1204 break;
1205 }
1206 case SVCHlpMsg::Error:
1207 {
1208 /* read the error message */
1209 Utf8Str errMsg;
1210 vrc = aClient->read (errMsg);
1211 if (RT_FAILURE (vrc)) break;
1212
1213 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1214 endLoop = true;
1215 break;
1216 }
1217 default:
1218 {
1219 endLoop = true;
1220 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1221 //"Invalid message code %d (%08lX)\n",
1222 //reply, reply),
1223 //rc = E_FAIL);
1224 }
1225 }
1226 }
1227
1228 break;
1229 }
1230 case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
1231 {
1232 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
1233 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1234
1235 /* write message and parameters */
1236 vrc = aClient->write (d->msgCode);
1237 if (RT_FAILURE (vrc)) break;
1238 vrc = aClient->write (d->guid);
1239 if (RT_FAILURE (vrc)) break;
1240 vrc = aClient->write (Utf8Str(d->u.StaticIPV6.IPV6Address));
1241 if (RT_FAILURE (vrc)) break;
1242 vrc = aClient->write (d->u.StaticIPV6.IPV6NetMaskLength);
1243 if (RT_FAILURE (vrc)) break;
1244
1245 /* wait for a reply */
1246 bool endLoop = false;
1247 while (!endLoop)
1248 {
1249 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1250
1251 vrc = aClient->read (reply);
1252 if (RT_FAILURE (vrc)) break;
1253
1254 switch (reply)
1255 {
1256 case SVCHlpMsg::OK:
1257 {
1258 /* no parameters */
1259 rc = d->iface->updateConfig();
1260 endLoop = true;
1261 break;
1262 }
1263 case SVCHlpMsg::Error:
1264 {
1265 /* read the error message */
1266 Utf8Str errMsg;
1267 vrc = aClient->read (errMsg);
1268 if (RT_FAILURE (vrc)) break;
1269
1270 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1271 endLoop = true;
1272 break;
1273 }
1274 default:
1275 {
1276 endLoop = true;
1277 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1278 //"Invalid message code %d (%08lX)\n",
1279 //reply, reply),
1280 //rc = E_FAIL);
1281 }
1282 }
1283 }
1284
1285 break;
1286 }
1287 case SVCHlpMsg::DhcpRediscover: /* see usage in code */
1288 {
1289 LogFlowFunc (("DhcpRediscover:\n"));
1290 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1291
1292 /* write message and parameters */
1293 vrc = aClient->write (d->msgCode);
1294 if (RT_FAILURE (vrc)) break;
1295 vrc = aClient->write (d->guid);
1296 if (RT_FAILURE (vrc)) break;
1297
1298 /* wait for a reply */
1299 bool endLoop = false;
1300 while (!endLoop)
1301 {
1302 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1303
1304 vrc = aClient->read (reply);
1305 if (RT_FAILURE (vrc)) break;
1306
1307 switch (reply)
1308 {
1309 case SVCHlpMsg::OK:
1310 {
1311 /* no parameters */
1312 rc = d->iface->updateConfig();
1313 endLoop = true;
1314 break;
1315 }
1316 case SVCHlpMsg::Error:
1317 {
1318 /* read the error message */
1319 Utf8Str errMsg;
1320 vrc = aClient->read (errMsg);
1321 if (RT_FAILURE (vrc)) break;
1322
1323 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1324 endLoop = true;
1325 break;
1326 }
1327 default:
1328 {
1329 endLoop = true;
1330 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1331 //"Invalid message code %d (%08lX)\n",
1332 //reply, reply),
1333 //rc = E_FAIL);
1334 }
1335 }
1336 }
1337
1338 break;
1339 }
1340 default:
1341 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1342// "Invalid message code %d (%08lX)\n",
1343// d->msgCode, d->msgCode),
1344// rc = E_FAIL);
1345 }
1346
1347 if (aVrc)
1348 *aVrc = vrc;
1349
1350 LogFlowFunc (("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
1351 LogFlowFuncLeave();
1352 return rc;
1353}
1354
1355
1356int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient,
1357 SVCHlpMsg::Code aMsgCode)
1358{
1359 LogFlowFuncEnter();
1360 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
1361
1362 AssertReturn (aClient, VERR_INVALID_POINTER);
1363
1364 int vrc = VINF_SUCCESS;
1365 HRESULT hrc;
1366
1367 switch (aMsgCode)
1368 {
1369 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1370 {
1371 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
1372
1373// Utf8Str name;
1374// vrc = aClient->read (name);
1375// if (RT_FAILURE (vrc)) break;
1376
1377 Guid guid;
1378 Utf8Str errMsg;
1379 Bstr name;
1380 Bstr bstrErr;
1381
1382 hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface (guid.asOutParam(), name.asOutParam(), bstrErr.asOutParam());
1383
1384 if (hrc == S_OK)
1385 {
1386 ULONG ip, mask;
1387 hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
1388 if(hrc == S_OK)
1389 {
1390 /* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
1391 * i.e. 192.168.xxx.0, assign 192.168.xxx.1 for the hostonly adapter */
1392 ip = ip | (1 << 24);
1393 hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
1394 }
1395
1396 /* write success followed by GUID */
1397 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
1398 if (RT_FAILURE (vrc)) break;
1399 vrc = aClient->write (Utf8Str (name));
1400 if (RT_FAILURE (vrc)) break;
1401 vrc = aClient->write (guid);
1402 if (RT_FAILURE (vrc)) break;
1403 }
1404 else
1405 {
1406 vrc = VERR_GENERAL_FAILURE;
1407 errMsg = Utf8Str(bstrErr);
1408 /* write failure followed by error message */
1409 if (errMsg.isEmpty())
1410 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1411 vrc = aClient->write (SVCHlpMsg::Error);
1412 if (RT_FAILURE (vrc)) break;
1413 vrc = aClient->write (errMsg);
1414 if (RT_FAILURE (vrc)) break;
1415 }
1416
1417 break;
1418 }
1419 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
1420 {
1421 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
1422
1423 Guid guid;
1424 Bstr bstrErr;
1425
1426 vrc = aClient->read (guid);
1427 if (RT_FAILURE (vrc)) break;
1428
1429 Utf8Str errMsg;
1430 hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface ((const GUID*)guid.raw(), bstrErr.asOutParam());
1431
1432 if (hrc == S_OK)
1433 {
1434 /* write parameter-less success */
1435 vrc = aClient->write (SVCHlpMsg::OK);
1436 if (RT_FAILURE (vrc)) break;
1437 }
1438 else
1439 {
1440 vrc = VERR_GENERAL_FAILURE;
1441 errMsg = Utf8Str(bstrErr);
1442 /* write failure followed by error message */
1443 if (errMsg.isEmpty())
1444 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1445 vrc = aClient->write (SVCHlpMsg::Error);
1446 if (RT_FAILURE (vrc)) break;
1447 vrc = aClient->write (errMsg);
1448 if (RT_FAILURE (vrc)) break;
1449 }
1450
1451 break;
1452 }
1453 case SVCHlpMsg::EnableStaticIpConfigV6:
1454 {
1455 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
1456
1457 Guid guid;
1458 Utf8Str ipV6;
1459 ULONG maskLengthV6;
1460 vrc = aClient->read (guid);
1461 if (RT_FAILURE (vrc)) break;
1462 vrc = aClient->read (ipV6);
1463 if (RT_FAILURE (vrc)) break;
1464 vrc = aClient->read (maskLengthV6);
1465 if (RT_FAILURE (vrc)) break;
1466
1467 Utf8Str errMsg;
1468 vrc = VERR_NOT_IMPLEMENTED;
1469
1470 if (RT_SUCCESS (vrc))
1471 {
1472 /* write success followed by GUID */
1473 vrc = aClient->write (SVCHlpMsg::OK);
1474 if (RT_FAILURE (vrc)) break;
1475 }
1476 else
1477 {
1478 /* write failure followed by error message */
1479 if (errMsg.isEmpty())
1480 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1481 vrc = aClient->write (SVCHlpMsg::Error);
1482 if (RT_FAILURE (vrc)) break;
1483 vrc = aClient->write (errMsg);
1484 if (RT_FAILURE (vrc)) break;
1485 }
1486
1487 break;
1488 }
1489 case SVCHlpMsg::EnableStaticIpConfig:
1490 {
1491 LogFlowFunc (("EnableStaticIpConfig:\n"));
1492
1493 Guid guid;
1494 ULONG ip, mask;
1495 vrc = aClient->read (guid);
1496 if (RT_FAILURE (vrc)) break;
1497 vrc = aClient->read (ip);
1498 if (RT_FAILURE (vrc)) break;
1499 vrc = aClient->read (mask);
1500 if (RT_FAILURE (vrc)) break;
1501
1502 Utf8Str errMsg;
1503 hrc = VBoxNetCfgWinEnableStaticIpConfig ((const GUID *)guid.raw(), ip, mask);
1504
1505 if (hrc == S_OK)
1506 {
1507 /* write success followed by GUID */
1508 vrc = aClient->write (SVCHlpMsg::OK);
1509 if (RT_FAILURE (vrc)) break;
1510 }
1511 else
1512 {
1513 vrc = VERR_GENERAL_FAILURE;
1514 /* write failure followed by error message */
1515 if (errMsg.isEmpty())
1516 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1517 vrc = aClient->write (SVCHlpMsg::Error);
1518 if (RT_FAILURE (vrc)) break;
1519 vrc = aClient->write (errMsg);
1520 if (RT_FAILURE (vrc)) break;
1521 }
1522
1523 break;
1524 }
1525 case SVCHlpMsg::EnableDynamicIpConfig:
1526 {
1527 LogFlowFunc (("EnableDynamicIpConfig:\n"));
1528
1529 Guid guid;
1530 vrc = aClient->read (guid);
1531 if (RT_FAILURE (vrc)) break;
1532
1533 Utf8Str errMsg;
1534 hrc = VBoxNetCfgWinEnableDynamicIpConfig ((const GUID *)guid.raw());
1535
1536 if (hrc == S_OK)
1537 {
1538 /* write success followed by GUID */
1539 vrc = aClient->write (SVCHlpMsg::OK);
1540 if (RT_FAILURE (vrc)) break;
1541 }
1542 else
1543 {
1544 vrc = VERR_GENERAL_FAILURE;
1545 /* write failure followed by error message */
1546 if (errMsg.isEmpty())
1547 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1548 vrc = aClient->write (SVCHlpMsg::Error);
1549 if (RT_FAILURE (vrc)) break;
1550 vrc = aClient->write (errMsg);
1551 if (RT_FAILURE (vrc)) break;
1552 }
1553
1554 break;
1555 }
1556 case SVCHlpMsg::DhcpRediscover:
1557 {
1558 LogFlowFunc (("DhcpRediscover:\n"));
1559
1560 Guid guid;
1561 vrc = aClient->read (guid);
1562 if (RT_FAILURE (vrc)) break;
1563
1564 Utf8Str errMsg;
1565 hrc = VBoxNetCfgWinDhcpRediscover ((const GUID *)guid.raw());
1566
1567 if (hrc == S_OK)
1568 {
1569 /* write success followed by GUID */
1570 vrc = aClient->write (SVCHlpMsg::OK);
1571 if (RT_FAILURE (vrc)) break;
1572 }
1573 else
1574 {
1575 vrc = VERR_GENERAL_FAILURE;
1576 /* write failure followed by error message */
1577 if (errMsg.isEmpty())
1578 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1579 vrc = aClient->write (SVCHlpMsg::Error);
1580 if (RT_FAILURE (vrc)) break;
1581 vrc = aClient->write (errMsg);
1582 if (RT_FAILURE (vrc)) break;
1583 }
1584
1585 break;
1586 }
1587 default:
1588 AssertMsgFailedBreakStmt (
1589 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
1590 VERR_GENERAL_FAILURE);
1591 }
1592
1593 LogFlowFunc (("vrc=%Rrc\n", vrc));
1594 LogFlowFuncLeave();
1595 return vrc;
1596}
1597
1598/** @todo REMOVE. OBSOLETE NOW. */
1599/**
1600 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
1601 * later OSes) and it has the UAC (User Account Control) feature enabled.
1602 */
1603static BOOL IsUACEnabled()
1604{
1605 LONG rc = 0;
1606
1607 OSVERSIONINFOEX info;
1608 ZeroMemory (&info, sizeof (OSVERSIONINFOEX));
1609 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
1610 rc = GetVersionEx ((OSVERSIONINFO *) &info);
1611 AssertReturn (rc != 0, FALSE);
1612
1613 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",
1614 info.dwMajorVersion, info.dwMinorVersion));
1615
1616 /* we are interested only in Vista (and newer versions...). In all
1617 * earlier versions UAC is not present. */
1618 if (info.dwMajorVersion < 6)
1619 return FALSE;
1620
1621 /* the default EnableLUA value is 1 (Enabled) */
1622 DWORD dwEnableLUA = 1;
1623
1624 HKEY hKey;
1625 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
1626 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
1627 0, KEY_QUERY_VALUE, &hKey);
1628
1629 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
1630 if (rc == ERROR_SUCCESS)
1631 {
1632
1633 DWORD cbEnableLUA = sizeof (dwEnableLUA);
1634 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,
1635 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
1636
1637 RegCloseKey (hKey);
1638
1639 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
1640 }
1641
1642 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
1643
1644 return dwEnableLUA == 1;
1645}
1646
1647/* end */
1648
1649static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
1650{
1651 LPWSTR lpszName;
1652 GUID IfGuid;
1653 HRESULT hr;
1654 int rc = VERR_GENERAL_FAILURE;
1655
1656 hr = pncc->GetDisplayName( &lpszName );
1657 Assert(hr == S_OK);
1658 if(hr == S_OK)
1659 {
1660 size_t cUnicodeName = wcslen(lpszName) + 1;
1661 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
1662 Bstr name (uniLen + 1 /* extra zero */);
1663 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
1664
1665 hr = pncc->GetInstanceGuid(&IfGuid);
1666 Assert(hr == S_OK);
1667 if (hr == S_OK)
1668 {
1669 NETIFINFO Info;
1670 memset(&Info, 0, sizeof(Info));
1671 Info.Uuid = *(Guid(IfGuid).raw());
1672 rc = collectNetIfInfo(name, Guid(IfGuid), &Info);
1673 if (RT_FAILURE(rc))
1674 {
1675 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
1676 }
1677 /* create a new object and add it to the list */
1678 ComObjPtr <HostNetworkInterface> iface;
1679 iface.createObject();
1680 /* remove the curly bracket at the end */
1681 if (SUCCEEDED (iface->init (name, enmType, &Info)))
1682 {
1683 pPist->push_back (iface);
1684 rc = VINF_SUCCESS;
1685 }
1686 else
1687 {
1688 Assert(0);
1689 }
1690 }
1691 CoTaskMemFree(lpszName);
1692 }
1693
1694 return rc;
1695}
1696
1697#endif /* VBOX_WITH_NETFLT */
1698
1699
1700static int netIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
1701{
1702#ifndef VBOX_WITH_NETFLT
1703 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
1704 return VERR_NOT_IMPLEMENTED;
1705#else /* # if defined VBOX_WITH_NETFLT */
1706 INetCfg *pNc;
1707 INetCfgComponent *pMpNcc;
1708 LPWSTR lpszApp = NULL;
1709 HRESULT hr;
1710 IEnumNetCfgComponent *pEnumComponent;
1711
1712 /* we are using the INetCfg API for getting the list of miniports */
1713 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
1714 VBOX_APP_NAME,
1715 &pNc,
1716 &lpszApp );
1717 Assert(hr == S_OK);
1718 if(hr == S_OK)
1719 {
1720 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
1721 if(hr == S_OK)
1722 {
1723 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
1724 {
1725 ULONG uComponentStatus;
1726 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
1727//#ifndef DEBUG_bird
1728// Assert(hr == S_OK);
1729//#endif
1730 if(hr == S_OK)
1731 {
1732 if(uComponentStatus == 0)
1733 {
1734 LPWSTR pId;
1735 hr = pMpNcc->GetId(&pId);
1736 Assert(hr == S_OK);
1737 if(hr == S_OK)
1738 {
1739 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
1740 {
1741 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
1742 }
1743 CoTaskMemFree(pId);
1744 }
1745 }
1746 }
1747 VBoxNetCfgWinReleaseRef(pMpNcc);
1748 }
1749 Assert(hr == S_OK || hr == S_FALSE);
1750
1751 VBoxNetCfgWinReleaseRef(pEnumComponent);
1752 }
1753 else
1754 {
1755 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
1756 }
1757
1758 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1759 }
1760 else if(lpszApp)
1761 {
1762 CoTaskMemFree(lpszApp);
1763 }
1764#endif /* # if defined VBOX_WITH_NETFLT */
1765 return VINF_SUCCESS;
1766}
1767
1768int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
1769{
1770#ifndef VBOX_WITH_NETFLT
1771 return VERR_NOT_IMPLEMENTED;
1772#else
1773 Bstr name;
1774 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
1775 if(hr == S_OK)
1776 {
1777 GUID IfGuid;
1778 hr = pIf->COMGETTER(Id)(&IfGuid);
1779 Assert(hr == S_OK);
1780 if (hr == S_OK)
1781 {
1782 memset(pInfo, 0, sizeof(NETIFINFO));
1783 Guid guid(IfGuid);
1784 pInfo->Uuid = *(guid.raw());
1785
1786 return collectNetIfInfo(name, guid, pInfo);
1787 }
1788 }
1789 return VERR_GENERAL_FAILURE;
1790#endif
1791}
1792
1793int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox,
1794 IHostNetworkInterface **aHostNetworkInterface,
1795 IProgress **aProgress)
1796{
1797#ifndef VBOX_WITH_NETFLT
1798 return VERR_NOT_IMPLEMENTED;
1799#else
1800 /* create a progress object */
1801 ComObjPtr <Progress> progress;
1802 progress.createObject();
1803
1804 ComPtr<IHost> host;
1805 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1806 if(SUCCEEDED(rc))
1807 {
1808 rc = progress->init (pVBox, host,
1809 Bstr (_T ("Creating host only network interface")),
1810 FALSE /* aCancelable */);
1811 if(SUCCEEDED(rc))
1812 {
1813 CheckComRCReturnRC (rc);
1814 progress.queryInterfaceTo (aProgress);
1815
1816 /* create a new uninitialized host interface object */
1817 ComObjPtr <HostNetworkInterface> iface;
1818 iface.createObject();
1819 iface.queryInterfaceTo (aHostNetworkInterface);
1820
1821 /* create the networkInterfaceHelperClient() argument */
1822 std::auto_ptr <NetworkInterfaceHelperClientData>
1823 d (new NetworkInterfaceHelperClientData());
1824 AssertReturn (d.get(), E_OUTOFMEMORY);
1825
1826 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
1827// d->name = aName;
1828 d->iface = iface;
1829 d->vBox = pVBox;
1830
1831 rc = pVBox->startSVCHelperClient (
1832 IsUACEnabled() == TRUE /* aPrivileged */,
1833 netIfNetworkInterfaceHelperClient,
1834 static_cast <void *> (d.get()),
1835 progress);
1836
1837 if (SUCCEEDED (rc))
1838 {
1839 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1840 d.release();
1841 }
1842 }
1843 }
1844
1845 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1846#endif
1847}
1848
1849int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVBox, IN_GUID aId,
1850 IHostNetworkInterface **aHostNetworkInterface,
1851 IProgress **aProgress)
1852{
1853#ifndef VBOX_WITH_NETFLT
1854 return VERR_NOT_IMPLEMENTED;
1855#else
1856 /* create a progress object */
1857 ComObjPtr <Progress> progress;
1858 progress.createObject();
1859 ComPtr<IHost> host;
1860 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
1861 if(SUCCEEDED(rc))
1862 {
1863 rc = progress->init (pVBox, host,
1864 Bstr (_T ("Removing host network interface")),
1865 FALSE /* aCancelable */);
1866 if(SUCCEEDED(rc))
1867 {
1868 CheckComRCReturnRC (rc);
1869 progress.queryInterfaceTo (aProgress);
1870
1871 /* create the networkInterfaceHelperClient() argument */
1872 std::auto_ptr <NetworkInterfaceHelperClientData>
1873 d (new NetworkInterfaceHelperClientData());
1874 AssertReturn (d.get(), E_OUTOFMEMORY);
1875
1876 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
1877 d->guid = aId;
1878
1879 rc = pVBox->startSVCHelperClient (
1880 IsUACEnabled() == TRUE /* aPrivileged */,
1881 netIfNetworkInterfaceHelperClient,
1882 static_cast <void *> (d.get()),
1883 progress);
1884
1885 if (SUCCEEDED (rc))
1886 {
1887 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1888 d.release();
1889 }
1890 }
1891 }
1892
1893 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1894#endif
1895}
1896
1897int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
1898{
1899#ifndef VBOX_WITH_NETFLT
1900 return VERR_NOT_IMPLEMENTED;
1901#else
1902 HRESULT rc;
1903 GUID guid;
1904 rc = pIf->COMGETTER(Id) (&guid);
1905 if(SUCCEEDED(rc))
1906 {
1907// ComPtr<VirtualBox> vBox;
1908// rc = pIf->getVirtualBox (vBox.asOutParam());
1909// if(SUCCEEDED(rc))
1910 {
1911 /* create a progress object */
1912 ComObjPtr <Progress> progress;
1913 progress.createObject();
1914// ComPtr<IHost> host;
1915// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1916// if(SUCCEEDED(rc))
1917 {
1918 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1919 Bstr ("Enabling Dynamic Ip Configuration"),
1920 FALSE /* aCancelable */);
1921 if(SUCCEEDED(rc))
1922 {
1923 CheckComRCReturnRC (rc);
1924// progress.queryInterfaceTo (aProgress);
1925
1926 /* create the networkInterfaceHelperClient() argument */
1927 std::auto_ptr <NetworkInterfaceHelperClientData>
1928 d (new NetworkInterfaceHelperClientData());
1929 AssertReturn (d.get(), E_OUTOFMEMORY);
1930
1931 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
1932 d->guid = guid;
1933 d->iface = pIf;
1934 d->u.StaticIP.IPAddress = ip;
1935 d->u.StaticIP.IPNetMask = mask;
1936
1937 rc = vBox->startSVCHelperClient (
1938 IsUACEnabled() == TRUE /* aPrivileged */,
1939 netIfNetworkInterfaceHelperClient,
1940 static_cast <void *> (d.get()),
1941 progress);
1942
1943 if (SUCCEEDED (rc))
1944 {
1945 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
1946 d.release();
1947
1948 progress->WaitForCompletion(-1);
1949 }
1950 }
1951 }
1952 }
1953 }
1954
1955 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
1956#endif
1957}
1958
1959int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
1960{
1961#ifndef VBOX_WITH_NETFLT
1962 return VERR_NOT_IMPLEMENTED;
1963#else
1964 HRESULT rc;
1965 GUID guid;
1966 rc = pIf->COMGETTER(Id) (&guid);
1967 if(SUCCEEDED(rc))
1968 {
1969// ComPtr<VirtualBox> vBox;
1970// rc = pIf->getVirtualBox (vBox.asOutParam());
1971// if(SUCCEEDED(rc))
1972 {
1973 /* create a progress object */
1974 ComObjPtr <Progress> progress;
1975 progress.createObject();
1976// ComPtr<IHost> host;
1977// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
1978// if(SUCCEEDED(rc))
1979 {
1980 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
1981 Bstr ("Enabling Dynamic Ip Configuration"),
1982 FALSE /* aCancelable */);
1983 if(SUCCEEDED(rc))
1984 {
1985 CheckComRCReturnRC (rc);
1986// progress.queryInterfaceTo (aProgress);
1987
1988 /* create the networkInterfaceHelperClient() argument */
1989 std::auto_ptr <NetworkInterfaceHelperClientData>
1990 d (new NetworkInterfaceHelperClientData());
1991 AssertReturn (d.get(), E_OUTOFMEMORY);
1992
1993 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
1994 d->guid = guid;
1995 d->iface = pIf;
1996 d->u.StaticIPV6.IPV6Address = aIPV6Address;
1997 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
1998
1999 rc = vBox->startSVCHelperClient (
2000 IsUACEnabled() == TRUE /* aPrivileged */,
2001 netIfNetworkInterfaceHelperClient,
2002 static_cast <void *> (d.get()),
2003 progress);
2004
2005 if (SUCCEEDED (rc))
2006 {
2007 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2008 d.release();
2009
2010 progress->WaitForCompletion(-1);
2011 }
2012 }
2013 }
2014 }
2015 }
2016
2017 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2018#endif
2019}
2020
2021int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
2022{
2023#ifndef VBOX_WITH_NETFLT
2024 return VERR_NOT_IMPLEMENTED;
2025#else
2026 HRESULT rc;
2027 GUID guid;
2028 rc = pIf->COMGETTER(Id) (&guid);
2029 if(SUCCEEDED(rc))
2030 {
2031// ComPtr<VirtualBox> vBox;
2032// rc = pIf->getVirtualBox (vBox.asOutParam());
2033// if(SUCCEEDED(rc))
2034 {
2035 /* create a progress object */
2036 ComObjPtr <Progress> progress;
2037 progress.createObject();
2038// ComPtr<IHost> host;
2039// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2040// if(SUCCEEDED(rc))
2041 {
2042 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2043 Bstr ("Enabling Dynamic Ip Configuration"),
2044 FALSE /* aCancelable */);
2045 if(SUCCEEDED(rc))
2046 {
2047 CheckComRCReturnRC (rc);
2048// progress.queryInterfaceTo (aProgress);
2049
2050 /* create the networkInterfaceHelperClient() argument */
2051 std::auto_ptr <NetworkInterfaceHelperClientData>
2052 d (new NetworkInterfaceHelperClientData());
2053 AssertReturn (d.get(), E_OUTOFMEMORY);
2054
2055 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
2056 d->guid = guid;
2057 d->iface = pIf;
2058
2059 rc = vBox->startSVCHelperClient (
2060 IsUACEnabled() == TRUE /* aPrivileged */,
2061 netIfNetworkInterfaceHelperClient,
2062 static_cast <void *> (d.get()),
2063 progress);
2064
2065 if (SUCCEEDED (rc))
2066 {
2067 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2068 d.release();
2069
2070 progress->WaitForCompletion(-1);
2071 }
2072 }
2073 }
2074 }
2075 }
2076
2077 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2078#endif
2079}
2080
2081int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
2082{
2083#ifndef VBOX_WITH_NETFLT
2084 return VERR_NOT_IMPLEMENTED;
2085#else
2086 HRESULT rc;
2087 GUID guid;
2088 rc = pIf->COMGETTER(Id) (&guid);
2089 if(SUCCEEDED(rc))
2090 {
2091// ComPtr<VirtualBox> vBox;
2092// rc = pIf->getVirtualBox (vBox.asOutParam());
2093// if(SUCCEEDED(rc))
2094 {
2095 /* create a progress object */
2096 ComObjPtr <Progress> progress;
2097 progress.createObject();
2098// ComPtr<IHost> host;
2099// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2100// if(SUCCEEDED(rc))
2101 {
2102 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2103 Bstr ("Enabling Dynamic Ip Configuration"),
2104 FALSE /* aCancelable */);
2105 if(SUCCEEDED(rc))
2106 {
2107 CheckComRCReturnRC (rc);
2108// progress.queryInterfaceTo (aProgress);
2109
2110 /* create the networkInterfaceHelperClient() argument */
2111 std::auto_ptr <NetworkInterfaceHelperClientData>
2112 d (new NetworkInterfaceHelperClientData());
2113 AssertReturn (d.get(), E_OUTOFMEMORY);
2114
2115 d->msgCode = SVCHlpMsg::DhcpRediscover;
2116 d->guid = guid;
2117 d->iface = pIf;
2118
2119 rc = vBox->startSVCHelperClient (
2120 IsUACEnabled() == TRUE /* aPrivileged */,
2121 netIfNetworkInterfaceHelperClient,
2122 static_cast <void *> (d.get()),
2123 progress);
2124
2125 if (SUCCEEDED (rc))
2126 {
2127 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2128 d.release();
2129
2130 progress->WaitForCompletion(-1);
2131 }
2132 }
2133 }
2134 }
2135 }
2136
2137 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2138#endif
2139}
2140
2141int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
2142{
2143#ifndef VBOX_WITH_NETFLT
2144 return VERR_NOT_IMPLEMENTED;
2145#else /* # if defined VBOX_WITH_NETFLT */
2146 INetCfg *pNc;
2147 INetCfgComponent *pMpNcc;
2148 INetCfgComponent *pTcpIpNcc;
2149 LPWSTR lpszApp;
2150 HRESULT hr;
2151 IEnumNetCfgBindingPath *pEnumBp;
2152 INetCfgBindingPath *pBp;
2153 IEnumNetCfgBindingInterface *pEnumBi;
2154 INetCfgBindingInterface *pBi;
2155
2156 /* we are using the INetCfg API for getting the list of miniports */
2157 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2158 VBOX_APP_NAME,
2159 &pNc,
2160 &lpszApp );
2161 Assert(hr == S_OK);
2162 if(hr == S_OK)
2163 {
2164# ifdef VBOX_NETFLT_ONDEMAND_BIND
2165 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
2166 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
2167# else
2168 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
2169 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
2170# ifndef VBOX_WITH_HARDENING
2171 if(hr != S_OK)
2172 {
2173 /* TODO: try to install the netflt from here */
2174 }
2175# endif
2176
2177# endif
2178
2179 if(hr == S_OK)
2180 {
2181 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
2182 Assert(hr == S_OK);
2183 if ( hr == S_OK )
2184 {
2185 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
2186 Assert(hr == S_OK || hr == S_FALSE);
2187 while( hr == S_OK )
2188 {
2189 /* S_OK == enabled, S_FALSE == disabled */
2190 if(pBp->IsEnabled() == S_OK)
2191 {
2192 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
2193 Assert(hr == S_OK);
2194 if ( hr == S_OK )
2195 {
2196 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
2197 Assert(hr == S_OK);
2198 while(hr == S_OK)
2199 {
2200 hr = pBi->GetLowerComponent( &pMpNcc );
2201 Assert(hr == S_OK);
2202 if(hr == S_OK)
2203 {
2204 ULONG uComponentStatus;
2205 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2206//#ifndef DEBUG_bird
2207// Assert(hr == S_OK);
2208//#endif
2209 if(hr == S_OK)
2210 {
2211 if(uComponentStatus == 0)
2212 {
2213 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
2214 }
2215 }
2216 VBoxNetCfgWinReleaseRef( pMpNcc );
2217 }
2218 VBoxNetCfgWinReleaseRef(pBi);
2219
2220 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
2221 }
2222 VBoxNetCfgWinReleaseRef(pEnumBi);
2223 }
2224 }
2225 VBoxNetCfgWinReleaseRef(pBp);
2226
2227 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
2228 }
2229 VBoxNetCfgWinReleaseRef(pEnumBp);
2230 }
2231 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
2232 }
2233 else
2234 {
2235 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2236 }
2237
2238 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2239 }
2240
2241 netIfListHostAdapters(list);
2242
2243 return VINF_SUCCESS;
2244#endif /* # if defined VBOX_WITH_NETFLT */
2245}
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