VirtualBox

source: vbox/trunk/src/VBox/Main/win/NetIfList-win.cpp@ 18599

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

NetAdp/win: rename connection fix, remove on uninstall temporary disabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 94.1 KB
Line 
1/* $Id: NetIfList-win.cpp 18543 2009-03-30 13:08:12Z 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 netIfEnableStaticIpConfig(const Guid &guid, ULONG ip, ULONG mask)
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 BOOL bIsHostOnly;
814 hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
815 if(SUCCEEDED(hr))
816 {
817 if(bIsHostOnly)
818 {
819 in_addr aIp[1];
820 in_addr aMask[1];
821 aIp[0].S_un.S_addr = ip;
822 aMask[0].S_un.S_addr = mask;
823
824 BSTR ObjPath;
825 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
826 if(SUCCEEDED(hr))
827 {
828 hr = netIfWinEnableStaticV4(pSvc, ObjPath, aIp, aMask, ip != 0 ? 1 : 0);
829 if(SUCCEEDED(hr))
830 {
831#if 0
832 in_addr aGw[1];
833 aGw[0].S_un.S_addr = gw;
834 hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1);
835 if(SUCCEEDED(hr))
836#endif
837 {
838 // hr = netIfWinUpdateConfig(pIf);
839 }
840 }
841 SysFreeString(ObjPath);
842 }
843 }
844 else
845 {
846 hr = E_FAIL;
847 }
848 }
849 }
850 }
851
852 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
853}
854
855static int netIfEnableStaticIpConfigV6(const Guid & guid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
856{
857 HRESULT hr;
858 ComPtr <IWbemServices> pSvc;
859 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
860 if(SUCCEEDED(hr))
861 {
862 ComPtr <IWbemClassObject> pAdapterConfig;
863 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
864 if(SUCCEEDED(hr))
865 {
866 BSTR ObjPath;
867 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
868 if(SUCCEEDED(hr))
869 {
870 hr = netIfWinEnableStaticV4V6(pSvc, ObjPath, aIPV6Address, aIPV6Mask);
871 if(SUCCEEDED(hr))
872 {
873 if(aIPV6DefaultGateway)
874 {
875 hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway);
876 }
877 if(SUCCEEDED(hr))
878 {
879// hr = netIfWinUpdateConfig(pIf);
880 }
881 }
882 SysFreeString(ObjPath);
883 }
884 }
885 }
886
887 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
888}
889
890static int netIfEnableStaticIpConfigV6(const Guid &guid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
891{
892#if 0
893 RTNETADDRIPV6 Mask;
894 int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask);
895 if(RT_SUCCESS(rc))
896 {
897 Bstr maskStr = composeIPv6Address(&Mask);
898 rc = netIfEnableStaticIpConfigV6(guid, aIPV6Address, maskStr, NULL);
899 }
900 return rc;
901#else
902 return VERR_NOT_IMPLEMENTED;
903#endif
904}
905
906static HRESULT netIfEnableDynamicIpConfig(const Guid &guid)
907{
908 HRESULT hr;
909 ComPtr <IWbemServices> pSvc;
910 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
911 if(SUCCEEDED(hr))
912 {
913 ComPtr <IWbemClassObject> pAdapterConfig;
914 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
915 if(SUCCEEDED(hr))
916 {
917 BOOL bIsHostOnly;
918 hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
919 if(SUCCEEDED(hr))
920 {
921 if(bIsHostOnly)
922 {
923 BSTR ObjPath;
924 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
925 if(SUCCEEDED(hr))
926 {
927 hr = netIfWinEnableDHCP(pSvc, ObjPath);
928 if(SUCCEEDED(hr))
929 {
930// hr = netIfWinUpdateConfig(pIf);
931 }
932 SysFreeString(ObjPath);
933 }
934 }
935 else
936 {
937 hr = E_FAIL;
938 }
939 }
940 }
941 }
942
943
944 return hr;
945}
946
947static HRESULT netIfDhcpRediscover(const Guid &guid)
948{
949 HRESULT hr;
950 ComPtr <IWbemServices> pSvc;
951 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
952 if(SUCCEEDED(hr))
953 {
954 ComPtr <IWbemClassObject> pAdapterConfig;
955 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
956 if(SUCCEEDED(hr))
957 {
958 BOOL bIsHostOnly;
959 hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly);
960 if(SUCCEEDED(hr))
961 {
962 if(bIsHostOnly)
963 {
964 BSTR ObjPath;
965 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
966 if(SUCCEEDED(hr))
967 {
968 hr = netIfWinDhcpRediscover(pSvc, ObjPath);
969 if(SUCCEEDED(hr))
970 {
971// hr = netIfWinUpdateConfig(pIf);
972 }
973 SysFreeString(ObjPath);
974 }
975 }
976 else
977 {
978 hr = E_FAIL;
979 }
980 }
981 }
982 }
983
984
985 return hr;
986}
987
988/* svc helper func */
989
990struct StaticIpConfig
991{
992 ULONG IPAddress;
993 ULONG IPNetMask;
994};
995
996struct StaticIpV6Config
997{
998 BSTR IPV6Address;
999 ULONG IPV6NetMaskLength;
1000};
1001
1002struct NetworkInterfaceHelperClientData
1003{
1004 SVCHlpMsg::Code msgCode;
1005 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
1006 Bstr name;
1007 ComObjPtr <HostNetworkInterface> iface;
1008 ComObjPtr <VirtualBox> vBox;
1009 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
1010 Guid guid;
1011
1012 union
1013 {
1014 StaticIpConfig StaticIP;
1015 StaticIpV6Config StaticIPV6;
1016 } u;
1017
1018
1019};
1020
1021static HRESULT netIfNetworkInterfaceHelperClient (SVCHlpClient *aClient,
1022 Progress *aProgress,
1023 void *aUser, int *aVrc)
1024{
1025 LogFlowFuncEnter();
1026 LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n",
1027 aClient, aProgress, aUser));
1028
1029 AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) ||
1030 (aClient != NULL && aProgress != NULL && aVrc != NULL),
1031 E_POINTER);
1032 AssertReturn (aUser, E_POINTER);
1033
1034 std::auto_ptr <NetworkInterfaceHelperClientData>
1035 d (static_cast <NetworkInterfaceHelperClientData *> (aUser));
1036
1037 if (aClient == NULL)
1038 {
1039 /* "cleanup only" mode, just return (it will free aUser) */
1040 return S_OK;
1041 }
1042
1043 HRESULT rc = S_OK;
1044 int vrc = VINF_SUCCESS;
1045
1046 switch (d->msgCode)
1047 {
1048 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1049 {
1050 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
1051 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1052
1053 /* write message and parameters */
1054 vrc = aClient->write (d->msgCode);
1055 if (RT_FAILURE (vrc)) break;
1056// vrc = aClient->write (Utf8Str (d->name));
1057// if (RT_FAILURE (vrc)) break;
1058
1059 /* wait for a reply */
1060 bool endLoop = false;
1061 while (!endLoop)
1062 {
1063 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1064
1065 vrc = aClient->read (reply);
1066 if (RT_FAILURE (vrc)) break;
1067
1068 switch (reply)
1069 {
1070 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
1071 {
1072 /* read the GUID */
1073 Guid guid;
1074 Utf8Str name;
1075 vrc = aClient->read (name);
1076 if (RT_FAILURE (vrc)) break;
1077 vrc = aClient->read (guid);
1078 if (RT_FAILURE (vrc)) break;
1079
1080 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", guid.raw()));
1081
1082 /* initialize the object returned to the caller by
1083 * CreateHostOnlyNetworkInterface() */
1084 rc = d->iface->init (Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
1085 if(SUCCEEDED(rc))
1086 {
1087 rc = d->iface->setVirtualBox(d->vBox);
1088 if(SUCCEEDED(rc))
1089 {
1090 rc = d->iface->updateConfig();
1091 }
1092 }
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::RemoveHostOnlyNetworkInterface:
1121 {
1122 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
1123 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", d->guid.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 = S_OK;
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::EnableDynamicIpConfig: /* see usage in code */
1174 {
1175 LogFlowFunc (("EnableDynamicIpConfig:\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
1184 /* wait for a reply */
1185 bool endLoop = false;
1186 while (!endLoop)
1187 {
1188 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1189
1190 vrc = aClient->read (reply);
1191 if (RT_FAILURE (vrc)) break;
1192
1193 switch (reply)
1194 {
1195 case SVCHlpMsg::OK:
1196 {
1197 /* no parameters */
1198 rc = d->iface->updateConfig();
1199 endLoop = true;
1200 break;
1201 }
1202 case SVCHlpMsg::Error:
1203 {
1204 /* read the error message */
1205 Utf8Str errMsg;
1206 vrc = aClient->read (errMsg);
1207 if (RT_FAILURE (vrc)) break;
1208
1209 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1210 endLoop = true;
1211 break;
1212 }
1213 default:
1214 {
1215 endLoop = true;
1216 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1217 //"Invalid message code %d (%08lX)\n",
1218 //reply, reply),
1219 //rc = E_FAIL);
1220 }
1221 }
1222 }
1223
1224 break;
1225 }
1226 case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
1227 {
1228 LogFlowFunc (("EnableStaticIpConfig:\n"));
1229 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1230
1231 /* write message and parameters */
1232 vrc = aClient->write (d->msgCode);
1233 if (RT_FAILURE (vrc)) break;
1234 vrc = aClient->write (d->guid);
1235 if (RT_FAILURE (vrc)) break;
1236 vrc = aClient->write (d->u.StaticIP.IPAddress);
1237 if (RT_FAILURE (vrc)) break;
1238 vrc = aClient->write (d->u.StaticIP.IPNetMask);
1239 if (RT_FAILURE (vrc)) break;
1240
1241 /* wait for a reply */
1242 bool endLoop = false;
1243 while (!endLoop)
1244 {
1245 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1246
1247 vrc = aClient->read (reply);
1248 if (RT_FAILURE (vrc)) break;
1249
1250 switch (reply)
1251 {
1252 case SVCHlpMsg::OK:
1253 {
1254 /* no parameters */
1255 rc = d->iface->updateConfig();
1256 endLoop = true;
1257 break;
1258 }
1259 case SVCHlpMsg::Error:
1260 {
1261 /* read the error message */
1262 Utf8Str errMsg;
1263 vrc = aClient->read (errMsg);
1264 if (RT_FAILURE (vrc)) break;
1265
1266 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1267 endLoop = true;
1268 break;
1269 }
1270 default:
1271 {
1272 endLoop = true;
1273 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1274 //"Invalid message code %d (%08lX)\n",
1275 //reply, reply),
1276 //rc = E_FAIL);
1277 }
1278 }
1279 }
1280
1281 break;
1282 }
1283 case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
1284 {
1285 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
1286 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1287
1288 /* write message and parameters */
1289 vrc = aClient->write (d->msgCode);
1290 if (RT_FAILURE (vrc)) break;
1291 vrc = aClient->write (d->guid);
1292 if (RT_FAILURE (vrc)) break;
1293 vrc = aClient->write (Utf8Str(d->u.StaticIPV6.IPV6Address));
1294 if (RT_FAILURE (vrc)) break;
1295 vrc = aClient->write (d->u.StaticIPV6.IPV6NetMaskLength);
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 case SVCHlpMsg::DhcpRediscover: /* see usage in code */
1341 {
1342 LogFlowFunc (("DhcpRediscover:\n"));
1343 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1344
1345 /* write message and parameters */
1346 vrc = aClient->write (d->msgCode);
1347 if (RT_FAILURE (vrc)) break;
1348 vrc = aClient->write (d->guid);
1349 if (RT_FAILURE (vrc)) break;
1350
1351 /* wait for a reply */
1352 bool endLoop = false;
1353 while (!endLoop)
1354 {
1355 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1356
1357 vrc = aClient->read (reply);
1358 if (RT_FAILURE (vrc)) break;
1359
1360 switch (reply)
1361 {
1362 case SVCHlpMsg::OK:
1363 {
1364 /* no parameters */
1365 rc = d->iface->updateConfig();
1366 endLoop = true;
1367 break;
1368 }
1369 case SVCHlpMsg::Error:
1370 {
1371 /* read the error message */
1372 Utf8Str errMsg;
1373 vrc = aClient->read (errMsg);
1374 if (RT_FAILURE (vrc)) break;
1375
1376 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1377 endLoop = true;
1378 break;
1379 }
1380 default:
1381 {
1382 endLoop = true;
1383 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1384 //"Invalid message code %d (%08lX)\n",
1385 //reply, reply),
1386 //rc = E_FAIL);
1387 }
1388 }
1389 }
1390
1391 break;
1392 }
1393 default:
1394 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1395// "Invalid message code %d (%08lX)\n",
1396// d->msgCode, d->msgCode),
1397// rc = E_FAIL);
1398 }
1399
1400 if (aVrc)
1401 *aVrc = vrc;
1402
1403 LogFlowFunc (("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
1404 LogFlowFuncLeave();
1405 return rc;
1406}
1407
1408
1409/* The original source of the VBoxTAP adapter creation/destruction code has the following copyright */
1410/*
1411 Copyright 2004 by the Massachusetts Institute of Technology
1412
1413 All rights reserved.
1414
1415 Permission to use, copy, modify, and distribute this software and its
1416 documentation for any purpose and without fee is hereby granted,
1417 provided that the above copyright notice appear in all copies and that
1418 both that copyright notice and this permission notice appear in
1419 supporting documentation, and that the name of the Massachusetts
1420 Institute of Technology (M.I.T.) not be used in advertising or publicity
1421 pertaining to distribution of the software without specific, written
1422 prior permission.
1423
1424 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1425 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1426 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1427 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1428 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1429 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1430 SOFTWARE.
1431*/
1432
1433
1434#define DRIVERHWID _T("sun_VBoxNetAdp")
1435
1436#define SetErrBreak(strAndArgs) \
1437 if (1) { \
1438 aErrMsg = Utf8StrFmt strAndArgs; vrc = VERR_GENERAL_FAILURE; break; \
1439 } else do {} while (0)
1440
1441/* static */
1442static int createNetworkInterface (SVCHlpClient *aClient,
1443 BSTR * pName,
1444 Guid &aGUID, Utf8Str &aErrMsg)
1445{
1446 LogFlowFuncEnter();
1447// LogFlowFunc (("Network connection name = '%s'\n", aName.raw()));
1448
1449 AssertReturn (aClient, VERR_INVALID_POINTER);
1450// AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER);
1451
1452 int vrc = VINF_SUCCESS;
1453
1454 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1455 SP_DEVINFO_DATA DeviceInfoData;
1456 DWORD ret = 0;
1457 BOOL found = FALSE;
1458 BOOL registered = FALSE;
1459 BOOL destroyList = FALSE;
1460 TCHAR pCfgGuidString [50];
1461
1462 do
1463 {
1464 BOOL ok;
1465 GUID netGuid;
1466 SP_DRVINFO_DATA DriverInfoData;
1467 SP_DEVINSTALL_PARAMS DeviceInstallParams;
1468 TCHAR className [MAX_PATH];
1469 DWORD index = 0;
1470 PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
1471 /* for our purposes, 2k buffer is more
1472 * than enough to obtain the hardware ID
1473 * of the VBoxTAP driver. */
1474 DWORD detailBuf [2048];
1475
1476 HKEY hkey = NULL;
1477 DWORD cbSize;
1478 DWORD dwValueType;
1479
1480 /* initialize the structure size */
1481 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
1482 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
1483
1484 /* copy the net class GUID */
1485 memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
1486
1487 /* create an empty device info set associated with the net class GUID */
1488 hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);
1489 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1490 SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
1491 GetLastError()));
1492
1493 /* get the class name from GUID */
1494 ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
1495 if (!ok)
1496 SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
1497 GetLastError()));
1498
1499 /* create a device info element and add the new device instance
1500 * key to registry */
1501 ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
1502 DICD_GENERATE_ID, &DeviceInfoData);
1503 if (!ok)
1504 SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
1505 GetLastError()));
1506
1507 /* select the newly created device info to be the currently
1508 selected member */
1509 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1510 if (!ok)
1511 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1512 GetLastError()));
1513
1514 /* build a list of class drivers */
1515 ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
1516 SPDIT_CLASSDRIVER);
1517 if (!ok)
1518 SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
1519 GetLastError()));
1520
1521 destroyList = TRUE;
1522
1523 /* enumerate the driver info list */
1524 while (TRUE)
1525 {
1526 BOOL ret;
1527
1528 ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
1529 SPDIT_CLASSDRIVER, index, &DriverInfoData);
1530
1531 /* if the function failed and GetLastError() returned
1532 * ERROR_NO_MORE_ITEMS, then we have reached the end of the
1533 * list. Othewise there was something wrong with this
1534 * particular driver. */
1535 if (!ret)
1536 {
1537 if(GetLastError() == ERROR_NO_MORE_ITEMS)
1538 break;
1539 else
1540 {
1541 index++;
1542 continue;
1543 }
1544 }
1545
1546 pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
1547 pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
1548
1549 /* if we successfully find the hardware ID and it turns out to
1550 * be the one for the loopback driver, then we are done. */
1551 if (SetupDiGetDriverInfoDetail (hDeviceInfo,
1552 &DeviceInfoData,
1553 &DriverInfoData,
1554 pDriverInfoDetail,
1555 sizeof (detailBuf),
1556 NULL))
1557 {
1558 TCHAR * t;
1559
1560 /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
1561 * whole list and see if there is a match somewhere. */
1562 t = pDriverInfoDetail->HardwareID;
1563 while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1564 {
1565 if (!_tcsicmp(t, DRIVERHWID))
1566 break;
1567
1568 t += _tcslen(t) + 1;
1569 }
1570
1571 if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1572 {
1573 found = TRUE;
1574 break;
1575 }
1576 }
1577
1578 index ++;
1579 }
1580
1581 if (!found)
1582 SetErrBreak (("Could not find Host Interface Networking driver! "
1583 "Please reinstall"));
1584
1585 /* set the loopback driver to be the currently selected */
1586 ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
1587 &DriverInfoData);
1588 if (!ok)
1589 SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)",
1590 GetLastError()));
1591
1592 /* register the phantom device to prepare for install */
1593 ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
1594 &DeviceInfoData);
1595 if (!ok)
1596 SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
1597 GetLastError()));
1598
1599 /* registered, but remove if errors occur in the following code */
1600 registered = TRUE;
1601
1602 /* ask the installer if we can install the device */
1603 ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
1604 &DeviceInfoData);
1605 if (!ok)
1606 {
1607 if (GetLastError() != ERROR_DI_DO_DEFAULT)
1608 SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
1609 GetLastError()));
1610 /* that's fine */
1611 }
1612
1613 /* install the files first */
1614 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
1615 &DeviceInfoData);
1616 if (!ok)
1617 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
1618 GetLastError()));
1619
1620 /* get the device install parameters and disable filecopy */
1621 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1622 ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1623 &DeviceInstallParams);
1624 if (ok)
1625 {
1626 DeviceInstallParams.Flags |= DI_NOFILECOPY;
1627 ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1628 &DeviceInstallParams);
1629 if (!ok)
1630 SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
1631 GetLastError()));
1632 }
1633
1634 /*
1635 * Register any device-specific co-installers for this device,
1636 */
1637
1638 ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,
1639 hDeviceInfo,
1640 &DeviceInfoData);
1641 if (!ok)
1642 SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
1643 GetLastError()));
1644
1645 /*
1646 * install any installer-specified interfaces.
1647 * and then do the real install
1648 */
1649 ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,
1650 hDeviceInfo,
1651 &DeviceInfoData);
1652 if (!ok)
1653 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
1654 GetLastError()));
1655
1656 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,
1657 hDeviceInfo,
1658 &DeviceInfoData);
1659 if (!ok)
1660 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
1661 GetLastError()));
1662
1663 /* Figure out NetCfgInstanceId */
1664 hkey = SetupDiOpenDevRegKey (hDeviceInfo,
1665 &DeviceInfoData,
1666 DICS_FLAG_GLOBAL,
1667 0,
1668 DIREG_DRV,
1669 KEY_READ);
1670 if (hkey == INVALID_HANDLE_VALUE)
1671 SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",
1672 GetLastError()));
1673
1674 cbSize = sizeof (pCfgGuidString);
1675 DWORD ret;
1676 ret = RegQueryValueEx (hkey, _T("NetCfgInstanceId"), NULL,
1677 &dwValueType, (LPBYTE) pCfgGuidString, &cbSize);
1678 RegCloseKey (hkey);
1679 }
1680 while (0);
1681
1682 /*
1683 * cleanup
1684 */
1685
1686 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1687 {
1688 /* an error has occured, but the device is registered, we must remove it */
1689 if (ret != 0 && registered)
1690 SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1691
1692 found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);
1693
1694 /* destroy the driver info list */
1695 if (destroyList)
1696 SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,
1697 SPDIT_CLASSDRIVER);
1698 /* clean up the device info set */
1699 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1700 }
1701
1702 /* return the network connection GUID on success */
1703 if (RT_SUCCESS (vrc))
1704 {
1705 /* remove the curly bracket at the end */
1706 pCfgGuidString [_tcslen (pCfgGuidString) - 1] = '\0';
1707 LogFlowFunc (("Network connection GUID string = {%ls}\n", pCfgGuidString + 1));
1708
1709 aGUID = Guid (Utf8Str (pCfgGuidString + 1));
1710 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1711 Assert (!aGUID.isEmpty());
1712
1713 INetCfg *pNc;
1714 INetCfgComponent *pMpNcc;
1715 LPWSTR lpszApp;
1716 WCHAR ConnectoinName[128];
1717
1718 HRESULT hr = VBoxNetCfgWinQueryINetCfg( FALSE,
1719 VBOX_APP_NAME,
1720 &pNc,
1721 &lpszApp );
1722 if(hr == S_OK)
1723 {
1724 hr = VBoxNetCfgWinGetComponentByGuid(pNc,
1725 &GUID_DEVCLASS_NET,
1726 aGUID.asOutParam(),
1727 &pMpNcc);
1728 if(hr == S_OK)
1729 {
1730 LPWSTR name;
1731 hr = pMpNcc->GetDisplayName(&name);
1732 if(hr == S_OK)
1733 {
1734 Bstr str(name);
1735 str.detachTo(pName);
1736 ULONG cbBuf = sizeof(ConnectoinName);
1737
1738 hr = VBoxNetCfgWinGenHostonlyConnectionName (name, ConnectoinName, &cbBuf);
1739
1740 CoTaskMemFree (name);
1741 }
1742
1743 VBoxNetCfgWinReleaseRef(pMpNcc);
1744 }
1745 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1746 }
1747
1748 if(hr == S_OK)
1749 {
1750 hr = VBoxNetCfgWinRenameConnection ((GUID*)aGUID.raw(), ConnectoinName);
1751 }
1752
1753 if(hr != S_OK)
1754 {
1755 vrc = VERR_GENERAL_FAILURE;
1756 }
1757
1758 }
1759
1760 LogFlowFunc (("vrc=%Rrc\n", vrc));
1761 LogFlowFuncLeave();
1762 return vrc;
1763}
1764
1765/* static */
1766static int removeNetworkInterface (SVCHlpClient *aClient,
1767 const Guid &aGUID,
1768 Utf8Str &aErrMsg)
1769{
1770 LogFlowFuncEnter();
1771 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1772
1773 AssertReturn (aClient, VERR_INVALID_POINTER);
1774 AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);
1775
1776 int vrc = VINF_SUCCESS;
1777
1778 do
1779 {
1780 TCHAR lszPnPInstanceId [512] = {0};
1781
1782 /* We have to find the device instance ID through a registry search */
1783
1784 HKEY hkeyNetwork = 0;
1785 HKEY hkeyConnection = 0;
1786
1787 do
1788 {
1789 char strRegLocation [256];
1790 sprintf (strRegLocation,
1791 "SYSTEM\\CurrentControlSet\\Control\\Network\\"
1792 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}",
1793 aGUID.toString().raw());
1794 LONG status;
1795 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0,
1796 KEY_READ, &hkeyNetwork);
1797 if ((status != ERROR_SUCCESS) || !hkeyNetwork)
1798 SetErrBreak ((
1799 "Host interface network is not found in registry (%s) [1]",
1800 strRegLocation));
1801
1802 status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,
1803 KEY_READ, &hkeyConnection);
1804 if ((status != ERROR_SUCCESS) || !hkeyConnection)
1805 SetErrBreak ((
1806 "Host interface network is not found in registry (%s) [2]",
1807 strRegLocation));
1808
1809 DWORD len = sizeof (lszPnPInstanceId);
1810 DWORD dwKeyType;
1811 status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
1812 &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
1813 if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
1814 SetErrBreak ((
1815 "Host interface network is not found in registry (%s) [3]",
1816 strRegLocation));
1817 }
1818 while (0);
1819
1820 if (hkeyConnection)
1821 RegCloseKey (hkeyConnection);
1822 if (hkeyNetwork)
1823 RegCloseKey (hkeyNetwork);
1824
1825 if (RT_FAILURE (vrc))
1826 break;
1827
1828 /*
1829 * Now we are going to enumerate all network devices and
1830 * wait until we encounter the right device instance ID
1831 */
1832
1833 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1834
1835 do
1836 {
1837 BOOL ok;
1838 DWORD ret = 0;
1839 GUID netGuid;
1840 SP_DEVINFO_DATA DeviceInfoData;
1841 DWORD index = 0;
1842 BOOL found = FALSE;
1843 DWORD size = 0;
1844
1845 /* initialize the structure size */
1846 DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
1847
1848 /* copy the net class GUID */
1849 memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
1850
1851 /* return a device info set contains all installed devices of the Net class */
1852 hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
1853
1854 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1855 SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
1856
1857 /* enumerate the driver info list */
1858 while (TRUE)
1859 {
1860 TCHAR *deviceHwid;
1861
1862 ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
1863
1864 if (!ok)
1865 {
1866 if (GetLastError() == ERROR_NO_MORE_ITEMS)
1867 break;
1868 else
1869 {
1870 index++;
1871 continue;
1872 }
1873 }
1874
1875 /* try to get the hardware ID registry property */
1876 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1877 &DeviceInfoData,
1878 SPDRP_HARDWAREID,
1879 NULL,
1880 NULL,
1881 0,
1882 &size);
1883 if (!ok)
1884 {
1885 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1886 {
1887 index++;
1888 continue;
1889 }
1890
1891 deviceHwid = (TCHAR *) malloc (size);
1892 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1893 &DeviceInfoData,
1894 SPDRP_HARDWAREID,
1895 NULL,
1896 (PBYTE)deviceHwid,
1897 size,
1898 NULL);
1899 if (!ok)
1900 {
1901 free (deviceHwid);
1902 deviceHwid = NULL;
1903 index++;
1904 continue;
1905 }
1906 }
1907 else
1908 {
1909 /* something is wrong. This shouldn't have worked with a NULL buffer */
1910 index++;
1911 continue;
1912 }
1913
1914 for (TCHAR *t = deviceHwid;
1915 t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
1916 t += _tcslen (t) + 1)
1917 {
1918 if (!_tcsicmp (DRIVERHWID, t))
1919 {
1920 /* get the device instance ID */
1921 TCHAR devID [MAX_DEVICE_ID_LEN];
1922 if (CM_Get_Device_ID(DeviceInfoData.DevInst,
1923 devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
1924 {
1925 /* compare to what we determined before */
1926 if (wcscmp(devID, lszPnPInstanceId) == 0)
1927 {
1928 found = TRUE;
1929 break;
1930 }
1931 }
1932 }
1933 }
1934
1935 if (deviceHwid)
1936 {
1937 free (deviceHwid);
1938 deviceHwid = NULL;
1939 }
1940
1941 if (found)
1942 break;
1943
1944 index++;
1945 }
1946
1947 if (found == FALSE)
1948 SetErrBreak (("Host Interface Network driver not found (0x%08X)",
1949 GetLastError()));
1950
1951 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1952 if (!ok)
1953 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1954 GetLastError()));
1955
1956 ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1957 if (!ok)
1958 SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
1959 GetLastError()));
1960 }
1961 while (0);
1962
1963 /* clean up the device info set */
1964 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1965 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1966
1967 if (RT_FAILURE (vrc))
1968 break;
1969 }
1970 while (0);
1971
1972 LogFlowFunc (("vrc=%Rrc\n", vrc));
1973 LogFlowFuncLeave();
1974 return vrc;
1975}
1976
1977#undef SetErrBreak
1978
1979int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient,
1980 SVCHlpMsg::Code aMsgCode)
1981{
1982 LogFlowFuncEnter();
1983 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
1984
1985 AssertReturn (aClient, VERR_INVALID_POINTER);
1986
1987 int vrc = VINF_SUCCESS;
1988
1989 switch (aMsgCode)
1990 {
1991 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1992 {
1993 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
1994
1995// Utf8Str name;
1996// vrc = aClient->read (name);
1997// if (RT_FAILURE (vrc)) break;
1998
1999 Guid guid;
2000 Utf8Str errMsg;
2001 Bstr name;
2002 vrc = createNetworkInterface (aClient, name.asOutParam(), guid, errMsg);
2003
2004 if (RT_SUCCESS (vrc))
2005 {
2006 /* write success followed by GUID */
2007 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
2008 if (RT_FAILURE (vrc)) break;
2009 vrc = aClient->write (Utf8Str (name));
2010 if (RT_FAILURE (vrc)) break;
2011 vrc = aClient->write (guid);
2012 if (RT_FAILURE (vrc)) break;
2013 }
2014 else
2015 {
2016 /* write failure followed by error message */
2017 if (errMsg.isEmpty())
2018 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2019 vrc = aClient->write (SVCHlpMsg::Error);
2020 if (RT_FAILURE (vrc)) break;
2021 vrc = aClient->write (errMsg);
2022 if (RT_FAILURE (vrc)) break;
2023 }
2024
2025 break;
2026 }
2027 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
2028 {
2029 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
2030
2031 Guid guid;
2032 vrc = aClient->read (guid);
2033 if (RT_FAILURE (vrc)) break;
2034
2035 Utf8Str errMsg;
2036 vrc = removeNetworkInterface (aClient, guid, errMsg);
2037
2038 if (RT_SUCCESS (vrc))
2039 {
2040 /* write parameter-less success */
2041 vrc = aClient->write (SVCHlpMsg::OK);
2042 if (RT_FAILURE (vrc)) break;
2043 }
2044 else
2045 {
2046 /* write failure followed by error message */
2047 if (errMsg.isEmpty())
2048 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2049 vrc = aClient->write (SVCHlpMsg::Error);
2050 if (RT_FAILURE (vrc)) break;
2051 vrc = aClient->write (errMsg);
2052 if (RT_FAILURE (vrc)) break;
2053 }
2054
2055 break;
2056 }
2057 case SVCHlpMsg::EnableStaticIpConfigV6:
2058 {
2059 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
2060
2061 Guid guid;
2062 Utf8Str ipV6;
2063 ULONG maskLengthV6;
2064 vrc = aClient->read (guid);
2065 if (RT_FAILURE (vrc)) break;
2066 vrc = aClient->read (ipV6);
2067 if (RT_FAILURE (vrc)) break;
2068 vrc = aClient->read (maskLengthV6);
2069 if (RT_FAILURE (vrc)) break;
2070
2071 Utf8Str errMsg;
2072 vrc = netIfEnableStaticIpConfigV6 (guid, Bstr(ipV6), maskLengthV6);
2073
2074 if (RT_SUCCESS (vrc))
2075 {
2076 /* write success followed by GUID */
2077 vrc = aClient->write (SVCHlpMsg::OK);
2078 if (RT_FAILURE (vrc)) break;
2079 }
2080 else
2081 {
2082 /* write failure followed by error message */
2083 if (errMsg.isEmpty())
2084 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2085 vrc = aClient->write (SVCHlpMsg::Error);
2086 if (RT_FAILURE (vrc)) break;
2087 vrc = aClient->write (errMsg);
2088 if (RT_FAILURE (vrc)) break;
2089 }
2090
2091 break;
2092 }
2093 case SVCHlpMsg::EnableStaticIpConfig:
2094 {
2095 LogFlowFunc (("EnableStaticIpConfig:\n"));
2096
2097 Guid guid;
2098 ULONG ip, mask;
2099 vrc = aClient->read (guid);
2100 if (RT_FAILURE (vrc)) break;
2101 vrc = aClient->read (ip);
2102 if (RT_FAILURE (vrc)) break;
2103 vrc = aClient->read (mask);
2104 if (RT_FAILURE (vrc)) break;
2105
2106 Utf8Str errMsg;
2107 vrc = netIfEnableStaticIpConfig (guid, ip, mask);
2108
2109 if (RT_SUCCESS (vrc))
2110 {
2111 /* write success followed by GUID */
2112 vrc = aClient->write (SVCHlpMsg::OK);
2113 if (RT_FAILURE (vrc)) break;
2114 }
2115 else
2116 {
2117 /* write failure followed by error message */
2118 if (errMsg.isEmpty())
2119 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2120 vrc = aClient->write (SVCHlpMsg::Error);
2121 if (RT_FAILURE (vrc)) break;
2122 vrc = aClient->write (errMsg);
2123 if (RT_FAILURE (vrc)) break;
2124 }
2125
2126 break;
2127 }
2128 case SVCHlpMsg::EnableDynamicIpConfig:
2129 {
2130 LogFlowFunc (("EnableDynamicIpConfig:\n"));
2131
2132 Guid guid;
2133 vrc = aClient->read (guid);
2134 if (RT_FAILURE (vrc)) break;
2135
2136 Utf8Str errMsg;
2137 vrc = netIfEnableDynamicIpConfig (guid);
2138
2139 if (RT_SUCCESS (vrc))
2140 {
2141 /* write success followed by GUID */
2142 vrc = aClient->write (SVCHlpMsg::OK);
2143 if (RT_FAILURE (vrc)) break;
2144 }
2145 else
2146 {
2147 /* write failure followed by error message */
2148 if (errMsg.isEmpty())
2149 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2150 vrc = aClient->write (SVCHlpMsg::Error);
2151 if (RT_FAILURE (vrc)) break;
2152 vrc = aClient->write (errMsg);
2153 if (RT_FAILURE (vrc)) break;
2154 }
2155
2156 break;
2157 }
2158 case SVCHlpMsg::DhcpRediscover:
2159 {
2160 LogFlowFunc (("DhcpRediscover:\n"));
2161
2162 Guid guid;
2163 vrc = aClient->read (guid);
2164 if (RT_FAILURE (vrc)) break;
2165
2166 Utf8Str errMsg;
2167 vrc = netIfDhcpRediscover (guid);
2168
2169 if (RT_SUCCESS (vrc))
2170 {
2171 /* write success followed by GUID */
2172 vrc = aClient->write (SVCHlpMsg::OK);
2173 if (RT_FAILURE (vrc)) break;
2174 }
2175 else
2176 {
2177 /* write failure followed by error message */
2178 if (errMsg.isEmpty())
2179 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2180 vrc = aClient->write (SVCHlpMsg::Error);
2181 if (RT_FAILURE (vrc)) break;
2182 vrc = aClient->write (errMsg);
2183 if (RT_FAILURE (vrc)) break;
2184 }
2185
2186 break;
2187 }
2188 default:
2189 AssertMsgFailedBreakStmt (
2190 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
2191 VERR_GENERAL_FAILURE);
2192 }
2193
2194 LogFlowFunc (("vrc=%Rrc\n", vrc));
2195 LogFlowFuncLeave();
2196 return vrc;
2197}
2198
2199/** @todo REMOVE. OBSOLETE NOW. */
2200/**
2201 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
2202 * later OSes) and it has the UAC (User Account Control) feature enabled.
2203 */
2204static BOOL IsUACEnabled()
2205{
2206 LONG rc = 0;
2207
2208 OSVERSIONINFOEX info;
2209 ZeroMemory (&info, sizeof (OSVERSIONINFOEX));
2210 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
2211 rc = GetVersionEx ((OSVERSIONINFO *) &info);
2212 AssertReturn (rc != 0, FALSE);
2213
2214 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",
2215 info.dwMajorVersion, info.dwMinorVersion));
2216
2217 /* we are interested only in Vista (and newer versions...). In all
2218 * earlier versions UAC is not present. */
2219 if (info.dwMajorVersion < 6)
2220 return FALSE;
2221
2222 /* the default EnableLUA value is 1 (Enabled) */
2223 DWORD dwEnableLUA = 1;
2224
2225 HKEY hKey;
2226 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
2227 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
2228 0, KEY_QUERY_VALUE, &hKey);
2229
2230 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
2231 if (rc == ERROR_SUCCESS)
2232 {
2233
2234 DWORD cbEnableLUA = sizeof (dwEnableLUA);
2235 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,
2236 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
2237
2238 RegCloseKey (hKey);
2239
2240 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
2241 }
2242
2243 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
2244
2245 return dwEnableLUA == 1;
2246}
2247
2248/* end */
2249
2250static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
2251{
2252 LPWSTR lpszName;
2253 GUID IfGuid;
2254 HRESULT hr;
2255 int rc = VERR_GENERAL_FAILURE;
2256
2257 hr = pncc->GetDisplayName( &lpszName );
2258 Assert(hr == S_OK);
2259 if(hr == S_OK)
2260 {
2261 size_t cUnicodeName = wcslen(lpszName) + 1;
2262 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
2263 Bstr name (uniLen + 1 /* extra zero */);
2264 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
2265
2266 hr = pncc->GetInstanceGuid(&IfGuid);
2267 Assert(hr == S_OK);
2268 if (hr == S_OK)
2269 {
2270 NETIFINFO Info;
2271 memset(&Info, 0, sizeof(Info));
2272 Info.Uuid = *(Guid(IfGuid).raw());
2273 rc = collectNetIfInfo(name, Guid(IfGuid), &Info);
2274 if (RT_FAILURE(rc))
2275 {
2276 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
2277 }
2278 /* create a new object and add it to the list */
2279 ComObjPtr <HostNetworkInterface> iface;
2280 iface.createObject();
2281 /* remove the curly bracket at the end */
2282 if (SUCCEEDED (iface->init (name, enmType, &Info)))
2283 {
2284 pPist->push_back (iface);
2285 rc = VINF_SUCCESS;
2286 }
2287 else
2288 {
2289 Assert(0);
2290 }
2291 }
2292 CoTaskMemFree(lpszName);
2293 }
2294
2295 return rc;
2296}
2297
2298#endif /* VBOX_WITH_NETFLT */
2299
2300
2301static int netIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
2302{
2303#ifndef VBOX_WITH_NETFLT
2304 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
2305 return VERR_NOT_IMPLEMENTED;
2306#else /* # if defined VBOX_WITH_NETFLT */
2307 INetCfg *pNc;
2308 INetCfgComponent *pMpNcc;
2309 LPWSTR lpszApp = NULL;
2310 HRESULT hr;
2311 IEnumNetCfgComponent *pEnumComponent;
2312
2313 /* we are using the INetCfg API for getting the list of miniports */
2314 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2315 VBOX_APP_NAME,
2316 &pNc,
2317 &lpszApp );
2318 Assert(hr == S_OK);
2319 if(hr == S_OK)
2320 {
2321 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
2322 if(hr == S_OK)
2323 {
2324 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
2325 {
2326 ULONG uComponentStatus;
2327 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2328//#ifndef DEBUG_bird
2329// Assert(hr == S_OK);
2330//#endif
2331 if(hr == S_OK)
2332 {
2333 if(uComponentStatus == 0)
2334 {
2335 LPWSTR pId;
2336 hr = pMpNcc->GetId(&pId);
2337 Assert(hr == S_OK);
2338 if(hr == S_OK)
2339 {
2340 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
2341 {
2342 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
2343 }
2344 CoTaskMemFree(pId);
2345 }
2346 }
2347 }
2348 VBoxNetCfgWinReleaseRef(pMpNcc);
2349 }
2350 Assert(hr == S_OK || hr == S_FALSE);
2351
2352 VBoxNetCfgWinReleaseRef(pEnumComponent);
2353 }
2354 else
2355 {
2356 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2357 }
2358
2359 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2360 }
2361 else if(lpszApp)
2362 {
2363 CoTaskMemFree(lpszApp);
2364 }
2365#endif /* # if defined VBOX_WITH_NETFLT */
2366 return VINF_SUCCESS;
2367}
2368
2369int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
2370{
2371#ifndef VBOX_WITH_NETFLT
2372 return VERR_NOT_IMPLEMENTED;
2373#else
2374 Bstr name;
2375 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
2376 if(hr == S_OK)
2377 {
2378 GUID IfGuid;
2379 hr = pIf->COMGETTER(Id)(&IfGuid);
2380 Assert(hr == S_OK);
2381 if (hr == S_OK)
2382 {
2383 return collectNetIfInfo(name, Guid(IfGuid), pInfo);
2384 }
2385 }
2386 return VERR_GENERAL_FAILURE;
2387#endif
2388}
2389
2390int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox,
2391 IHostNetworkInterface **aHostNetworkInterface,
2392 IProgress **aProgress)
2393{
2394#ifndef VBOX_WITH_NETFLT
2395 return VERR_NOT_IMPLEMENTED;
2396#else
2397 /* create a progress object */
2398 ComObjPtr <Progress> progress;
2399 progress.createObject();
2400
2401 ComPtr<IHost> host;
2402 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2403 if(SUCCEEDED(rc))
2404 {
2405 rc = progress->init (pVBox, host,
2406 Bstr (_T ("Creating host only network interface")),
2407 FALSE /* aCancelable */);
2408 if(SUCCEEDED(rc))
2409 {
2410 CheckComRCReturnRC (rc);
2411 progress.queryInterfaceTo (aProgress);
2412
2413 /* create a new uninitialized host interface object */
2414 ComObjPtr <HostNetworkInterface> iface;
2415 iface.createObject();
2416 iface.queryInterfaceTo (aHostNetworkInterface);
2417
2418 /* create the networkInterfaceHelperClient() argument */
2419 std::auto_ptr <NetworkInterfaceHelperClientData>
2420 d (new NetworkInterfaceHelperClientData());
2421 AssertReturn (d.get(), E_OUTOFMEMORY);
2422
2423 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
2424// d->name = aName;
2425 d->iface = iface;
2426 d->vBox = pVBox;
2427
2428 rc = pVBox->startSVCHelperClient (
2429 IsUACEnabled() == TRUE /* aPrivileged */,
2430 netIfNetworkInterfaceHelperClient,
2431 static_cast <void *> (d.get()),
2432 progress);
2433
2434 if (SUCCEEDED (rc))
2435 {
2436 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2437 d.release();
2438 }
2439 }
2440 }
2441
2442 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2443#endif
2444}
2445
2446int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVBox, IN_GUID aId,
2447 IHostNetworkInterface **aHostNetworkInterface,
2448 IProgress **aProgress)
2449{
2450#ifndef VBOX_WITH_NETFLT
2451 return VERR_NOT_IMPLEMENTED;
2452#else
2453 /* create a progress object */
2454 ComObjPtr <Progress> progress;
2455 progress.createObject();
2456 ComPtr<IHost> host;
2457 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2458 if(SUCCEEDED(rc))
2459 {
2460 rc = progress->init (pVBox, host,
2461 Bstr (_T ("Removing host network interface")),
2462 FALSE /* aCancelable */);
2463 if(SUCCEEDED(rc))
2464 {
2465 CheckComRCReturnRC (rc);
2466 progress.queryInterfaceTo (aProgress);
2467
2468 /* create the networkInterfaceHelperClient() argument */
2469 std::auto_ptr <NetworkInterfaceHelperClientData>
2470 d (new NetworkInterfaceHelperClientData());
2471 AssertReturn (d.get(), E_OUTOFMEMORY);
2472
2473 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
2474 d->guid = aId;
2475
2476 rc = pVBox->startSVCHelperClient (
2477 IsUACEnabled() == TRUE /* aPrivileged */,
2478 netIfNetworkInterfaceHelperClient,
2479 static_cast <void *> (d.get()),
2480 progress);
2481
2482 if (SUCCEEDED (rc))
2483 {
2484 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2485 d.release();
2486 }
2487 }
2488 }
2489
2490 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2491#endif
2492}
2493
2494int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
2495{
2496#ifndef VBOX_WITH_NETFLT
2497 return VERR_NOT_IMPLEMENTED;
2498#else
2499 HRESULT rc;
2500 GUID guid;
2501 rc = pIf->COMGETTER(Id) (&guid);
2502 if(SUCCEEDED(rc))
2503 {
2504// ComPtr<VirtualBox> vBox;
2505// rc = pIf->getVirtualBox (vBox.asOutParam());
2506// if(SUCCEEDED(rc))
2507 {
2508 /* create a progress object */
2509 ComObjPtr <Progress> progress;
2510 progress.createObject();
2511// ComPtr<IHost> host;
2512// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2513// if(SUCCEEDED(rc))
2514 {
2515 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2516 Bstr ("Enabling Dynamic Ip Configuration"),
2517 FALSE /* aCancelable */);
2518 if(SUCCEEDED(rc))
2519 {
2520 CheckComRCReturnRC (rc);
2521// progress.queryInterfaceTo (aProgress);
2522
2523 /* create the networkInterfaceHelperClient() argument */
2524 std::auto_ptr <NetworkInterfaceHelperClientData>
2525 d (new NetworkInterfaceHelperClientData());
2526 AssertReturn (d.get(), E_OUTOFMEMORY);
2527
2528 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
2529 d->guid = guid;
2530 d->iface = pIf;
2531 d->u.StaticIP.IPAddress = ip;
2532 d->u.StaticIP.IPNetMask = mask;
2533
2534 rc = vBox->startSVCHelperClient (
2535 IsUACEnabled() == TRUE /* aPrivileged */,
2536 netIfNetworkInterfaceHelperClient,
2537 static_cast <void *> (d.get()),
2538 progress);
2539
2540 if (SUCCEEDED (rc))
2541 {
2542 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2543 d.release();
2544
2545 progress->WaitForCompletion(-1);
2546 }
2547 }
2548 }
2549 }
2550 }
2551
2552 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2553#endif
2554}
2555
2556int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
2557{
2558#ifndef VBOX_WITH_NETFLT
2559 return VERR_NOT_IMPLEMENTED;
2560#else
2561 HRESULT rc;
2562 GUID guid;
2563 rc = pIf->COMGETTER(Id) (&guid);
2564 if(SUCCEEDED(rc))
2565 {
2566// ComPtr<VirtualBox> vBox;
2567// rc = pIf->getVirtualBox (vBox.asOutParam());
2568// if(SUCCEEDED(rc))
2569 {
2570 /* create a progress object */
2571 ComObjPtr <Progress> progress;
2572 progress.createObject();
2573// ComPtr<IHost> host;
2574// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2575// if(SUCCEEDED(rc))
2576 {
2577 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2578 Bstr ("Enabling Dynamic Ip Configuration"),
2579 FALSE /* aCancelable */);
2580 if(SUCCEEDED(rc))
2581 {
2582 CheckComRCReturnRC (rc);
2583// progress.queryInterfaceTo (aProgress);
2584
2585 /* create the networkInterfaceHelperClient() argument */
2586 std::auto_ptr <NetworkInterfaceHelperClientData>
2587 d (new NetworkInterfaceHelperClientData());
2588 AssertReturn (d.get(), E_OUTOFMEMORY);
2589
2590 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
2591 d->guid = guid;
2592 d->iface = pIf;
2593 d->u.StaticIPV6.IPV6Address = aIPV6Address;
2594 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
2595
2596 rc = vBox->startSVCHelperClient (
2597 IsUACEnabled() == TRUE /* aPrivileged */,
2598 netIfNetworkInterfaceHelperClient,
2599 static_cast <void *> (d.get()),
2600 progress);
2601
2602 if (SUCCEEDED (rc))
2603 {
2604 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2605 d.release();
2606
2607 progress->WaitForCompletion(-1);
2608 }
2609 }
2610 }
2611 }
2612 }
2613
2614 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2615#endif
2616}
2617
2618int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
2619{
2620#ifndef VBOX_WITH_NETFLT
2621 return VERR_NOT_IMPLEMENTED;
2622#else
2623 HRESULT rc;
2624 GUID guid;
2625 rc = pIf->COMGETTER(Id) (&guid);
2626 if(SUCCEEDED(rc))
2627 {
2628// ComPtr<VirtualBox> vBox;
2629// rc = pIf->getVirtualBox (vBox.asOutParam());
2630// if(SUCCEEDED(rc))
2631 {
2632 /* create a progress object */
2633 ComObjPtr <Progress> progress;
2634 progress.createObject();
2635// ComPtr<IHost> host;
2636// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2637// if(SUCCEEDED(rc))
2638 {
2639 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2640 Bstr ("Enabling Dynamic Ip Configuration"),
2641 FALSE /* aCancelable */);
2642 if(SUCCEEDED(rc))
2643 {
2644 CheckComRCReturnRC (rc);
2645// progress.queryInterfaceTo (aProgress);
2646
2647 /* create the networkInterfaceHelperClient() argument */
2648 std::auto_ptr <NetworkInterfaceHelperClientData>
2649 d (new NetworkInterfaceHelperClientData());
2650 AssertReturn (d.get(), E_OUTOFMEMORY);
2651
2652 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
2653 d->guid = guid;
2654 d->iface = pIf;
2655
2656 rc = vBox->startSVCHelperClient (
2657 IsUACEnabled() == TRUE /* aPrivileged */,
2658 netIfNetworkInterfaceHelperClient,
2659 static_cast <void *> (d.get()),
2660 progress);
2661
2662 if (SUCCEEDED (rc))
2663 {
2664 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2665 d.release();
2666
2667 progress->WaitForCompletion(-1);
2668 }
2669 }
2670 }
2671 }
2672 }
2673
2674 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2675#endif
2676}
2677
2678int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
2679{
2680#ifndef VBOX_WITH_NETFLT
2681 return VERR_NOT_IMPLEMENTED;
2682#else
2683 HRESULT rc;
2684 GUID guid;
2685 rc = pIf->COMGETTER(Id) (&guid);
2686 if(SUCCEEDED(rc))
2687 {
2688// ComPtr<VirtualBox> vBox;
2689// rc = pIf->getVirtualBox (vBox.asOutParam());
2690// if(SUCCEEDED(rc))
2691 {
2692 /* create a progress object */
2693 ComObjPtr <Progress> progress;
2694 progress.createObject();
2695// ComPtr<IHost> host;
2696// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2697// if(SUCCEEDED(rc))
2698 {
2699 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2700 Bstr ("Enabling Dynamic Ip Configuration"),
2701 FALSE /* aCancelable */);
2702 if(SUCCEEDED(rc))
2703 {
2704 CheckComRCReturnRC (rc);
2705// progress.queryInterfaceTo (aProgress);
2706
2707 /* create the networkInterfaceHelperClient() argument */
2708 std::auto_ptr <NetworkInterfaceHelperClientData>
2709 d (new NetworkInterfaceHelperClientData());
2710 AssertReturn (d.get(), E_OUTOFMEMORY);
2711
2712 d->msgCode = SVCHlpMsg::DhcpRediscover;
2713 d->guid = guid;
2714 d->iface = pIf;
2715
2716 rc = vBox->startSVCHelperClient (
2717 IsUACEnabled() == TRUE /* aPrivileged */,
2718 netIfNetworkInterfaceHelperClient,
2719 static_cast <void *> (d.get()),
2720 progress);
2721
2722 if (SUCCEEDED (rc))
2723 {
2724 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2725 d.release();
2726
2727 progress->WaitForCompletion(-1);
2728 }
2729 }
2730 }
2731 }
2732 }
2733
2734 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2735#endif
2736}
2737
2738int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
2739{
2740#ifndef VBOX_WITH_NETFLT
2741 return VERR_NOT_IMPLEMENTED;
2742#else /* # if defined VBOX_WITH_NETFLT */
2743 INetCfg *pNc;
2744 INetCfgComponent *pMpNcc;
2745 INetCfgComponent *pTcpIpNcc;
2746 LPWSTR lpszApp;
2747 HRESULT hr;
2748 IEnumNetCfgBindingPath *pEnumBp;
2749 INetCfgBindingPath *pBp;
2750 IEnumNetCfgBindingInterface *pEnumBi;
2751 INetCfgBindingInterface *pBi;
2752
2753 /* we are using the INetCfg API for getting the list of miniports */
2754 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2755 VBOX_APP_NAME,
2756 &pNc,
2757 &lpszApp );
2758 Assert(hr == S_OK);
2759 if(hr == S_OK)
2760 {
2761# ifdef VBOX_NETFLT_ONDEMAND_BIND
2762 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
2763 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
2764# else
2765 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
2766 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
2767# ifndef VBOX_WITH_HARDENING
2768 if(hr != S_OK)
2769 {
2770 /* TODO: try to install the netflt from here */
2771 }
2772# endif
2773
2774# endif
2775
2776 if(hr == S_OK)
2777 {
2778 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
2779 Assert(hr == S_OK);
2780 if ( hr == S_OK )
2781 {
2782 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
2783 Assert(hr == S_OK || hr == S_FALSE);
2784 while( hr == S_OK )
2785 {
2786 /* S_OK == enabled, S_FALSE == disabled */
2787 if(pBp->IsEnabled() == S_OK)
2788 {
2789 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
2790 Assert(hr == S_OK);
2791 if ( hr == S_OK )
2792 {
2793 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
2794 Assert(hr == S_OK);
2795 while(hr == S_OK)
2796 {
2797 hr = pBi->GetLowerComponent( &pMpNcc );
2798 Assert(hr == S_OK);
2799 if(hr == S_OK)
2800 {
2801 ULONG uComponentStatus;
2802 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2803//#ifndef DEBUG_bird
2804// Assert(hr == S_OK);
2805//#endif
2806 if(hr == S_OK)
2807 {
2808 if(uComponentStatus == 0)
2809 {
2810 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
2811 }
2812 }
2813 VBoxNetCfgWinReleaseRef( pMpNcc );
2814 }
2815 VBoxNetCfgWinReleaseRef(pBi);
2816
2817 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
2818 }
2819 VBoxNetCfgWinReleaseRef(pEnumBi);
2820 }
2821 }
2822 VBoxNetCfgWinReleaseRef(pBp);
2823
2824 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
2825 }
2826 VBoxNetCfgWinReleaseRef(pEnumBp);
2827 }
2828 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
2829 }
2830 else
2831 {
2832 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2833 }
2834
2835 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2836 }
2837
2838 netIfListHostAdapters(list);
2839
2840 return VINF_SUCCESS;
2841#endif /* # if defined VBOX_WITH_NETFLT */
2842}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette