VirtualBox

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

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

rename TAP to NetAdp, remove abandoned tap win code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 94.5 KB
Line 
1/* $Id: NetIfList-win.cpp 18704 2009-04-03 16:59:22Z 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 VBoxNetAdp 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; \
1439 Assert(0);\
1440 break; \
1441 } else do {} while (0)
1442
1443/* static */
1444static int createNetworkInterface (SVCHlpClient *aClient,
1445 BSTR * pName,
1446 Guid &aGUID, Utf8Str &aErrMsg)
1447{
1448 LogFlowFuncEnter();
1449// LogFlowFunc (("Network connection name = '%s'\n", aName.raw()));
1450
1451 AssertReturn (aClient, VERR_INVALID_POINTER);
1452// AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER);
1453
1454 int vrc = VINF_SUCCESS;
1455
1456 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1457 SP_DEVINFO_DATA DeviceInfoData;
1458 DWORD ret = 0;
1459 BOOL found = FALSE;
1460 BOOL registered = FALSE;
1461 BOOL destroyList = FALSE;
1462 WCHAR pWCfgGuidString [50];
1463 WCHAR DevName[256];
1464
1465 do
1466 {
1467 BOOL ok;
1468 GUID netGuid;
1469 SP_DRVINFO_DATA DriverInfoData;
1470 SP_DEVINSTALL_PARAMS DeviceInstallParams;
1471 TCHAR className [MAX_PATH];
1472 DWORD index = 0;
1473 PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
1474 /* for our purposes, 2k buffer is more
1475 * than enough to obtain the hardware ID
1476 * of the VBoxNetAdp driver. */
1477 DWORD detailBuf [2048];
1478
1479 HKEY hkey = NULL;
1480 DWORD cbSize;
1481 DWORD dwValueType;
1482
1483 /* initialize the structure size */
1484 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
1485 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
1486
1487 /* copy the net class GUID */
1488 memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
1489
1490 /* create an empty device info set associated with the net class GUID */
1491 hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);
1492 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1493 SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
1494 GetLastError()));
1495
1496 /* get the class name from GUID */
1497 ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
1498 if (!ok)
1499 SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
1500 GetLastError()));
1501
1502 /* create a device info element and add the new device instance
1503 * key to registry */
1504 ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
1505 DICD_GENERATE_ID, &DeviceInfoData);
1506 if (!ok)
1507 SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
1508 GetLastError()));
1509
1510 /* select the newly created device info to be the currently
1511 selected member */
1512 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1513 if (!ok)
1514 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1515 GetLastError()));
1516
1517 /* build a list of class drivers */
1518 ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
1519 SPDIT_CLASSDRIVER);
1520 if (!ok)
1521 SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
1522 GetLastError()));
1523
1524 destroyList = TRUE;
1525
1526 /* enumerate the driver info list */
1527 while (TRUE)
1528 {
1529 BOOL ret;
1530
1531 ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
1532 SPDIT_CLASSDRIVER, index, &DriverInfoData);
1533
1534 /* if the function failed and GetLastError() returned
1535 * ERROR_NO_MORE_ITEMS, then we have reached the end of the
1536 * list. Othewise there was something wrong with this
1537 * particular driver. */
1538 if (!ret)
1539 {
1540 if(GetLastError() == ERROR_NO_MORE_ITEMS)
1541 break;
1542 else
1543 {
1544 index++;
1545 continue;
1546 }
1547 }
1548
1549 pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
1550 pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
1551
1552 /* if we successfully find the hardware ID and it turns out to
1553 * be the one for the loopback driver, then we are done. */
1554 if (SetupDiGetDriverInfoDetail (hDeviceInfo,
1555 &DeviceInfoData,
1556 &DriverInfoData,
1557 pDriverInfoDetail,
1558 sizeof (detailBuf),
1559 NULL))
1560 {
1561 TCHAR * t;
1562
1563 /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
1564 * whole list and see if there is a match somewhere. */
1565 t = pDriverInfoDetail->HardwareID;
1566 while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1567 {
1568 if (!_tcsicmp(t, DRIVERHWID))
1569 break;
1570
1571 t += _tcslen(t) + 1;
1572 }
1573
1574 if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1575 {
1576 found = TRUE;
1577 break;
1578 }
1579 }
1580
1581 index ++;
1582 }
1583
1584 if (!found)
1585 SetErrBreak (("Could not find Host Interface Networking driver! "
1586 "Please reinstall"));
1587
1588 /* set the loopback driver to be the currently selected */
1589 ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
1590 &DriverInfoData);
1591 if (!ok)
1592 SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)",
1593 GetLastError()));
1594
1595 /* register the phantom device to prepare for install */
1596 ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
1597 &DeviceInfoData);
1598 if (!ok)
1599 SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
1600 GetLastError()));
1601
1602 /* registered, but remove if errors occur in the following code */
1603 registered = TRUE;
1604
1605 /* ask the installer if we can install the device */
1606 ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
1607 &DeviceInfoData);
1608 if (!ok)
1609 {
1610 if (GetLastError() != ERROR_DI_DO_DEFAULT)
1611 SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
1612 GetLastError()));
1613 /* that's fine */
1614 }
1615
1616 /* install the files first */
1617 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
1618 &DeviceInfoData);
1619 if (!ok)
1620 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
1621 GetLastError()));
1622
1623 /* get the device install parameters and disable filecopy */
1624 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1625 ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1626 &DeviceInstallParams);
1627 if (ok)
1628 {
1629 DeviceInstallParams.Flags |= DI_NOFILECOPY;
1630 ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1631 &DeviceInstallParams);
1632 if (!ok)
1633 SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
1634 GetLastError()));
1635 }
1636
1637 /*
1638 * Register any device-specific co-installers for this device,
1639 */
1640
1641 ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,
1642 hDeviceInfo,
1643 &DeviceInfoData);
1644 if (!ok)
1645 SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
1646 GetLastError()));
1647
1648 /*
1649 * install any installer-specified interfaces.
1650 * and then do the real install
1651 */
1652 ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,
1653 hDeviceInfo,
1654 &DeviceInfoData);
1655 if (!ok)
1656 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
1657 GetLastError()));
1658
1659 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,
1660 hDeviceInfo,
1661 &DeviceInfoData);
1662 if (!ok)
1663 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
1664 GetLastError()));
1665
1666 /* Figure out NetCfgInstanceId */
1667 hkey = SetupDiOpenDevRegKey (hDeviceInfo,
1668 &DeviceInfoData,
1669 DICS_FLAG_GLOBAL,
1670 0,
1671 DIREG_DRV,
1672 KEY_READ);
1673 if (hkey == INVALID_HANDLE_VALUE)
1674 SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",
1675 GetLastError()));
1676
1677 cbSize = sizeof (pWCfgGuidString);
1678 DWORD ret;
1679 ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL,
1680 &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize);
1681
1682 RegCloseKey (hkey);
1683
1684 if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
1685 SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/
1686 NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
1687 (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
1688 sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
1689 NULL /*OUT PDWORD RequiredSize OPTIONAL*/
1690 ))
1691 {
1692 int err = GetLastError();
1693 if(err != ERROR_INVALID_DATA)
1694 {
1695 SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
1696 err));
1697 }
1698
1699 if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData,
1700 SPDRP_DEVICEDESC , /* IN DWORD Property,*/
1701 NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/
1702 (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/
1703 sizeof(DevName), /* IN DWORD PropertyBufferSize,*/
1704 NULL /*OUT PDWORD RequiredSize OPTIONAL*/
1705 ))
1706 {
1707 err = GetLastError();
1708 SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)",
1709 err));
1710 }
1711 }
1712 }
1713 while (0);
1714
1715 /*
1716 * cleanup
1717 */
1718
1719 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1720 {
1721 /* an error has occured, but the device is registered, we must remove it */
1722 if (ret != 0 && registered)
1723 SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1724
1725 found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);
1726
1727 /* destroy the driver info list */
1728 if (destroyList)
1729 SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,
1730 SPDIT_CLASSDRIVER);
1731 /* clean up the device info set */
1732 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1733 }
1734
1735 /* return the network connection GUID on success */
1736 if (RT_SUCCESS (vrc))
1737 {
1738 Bstr str(DevName);
1739 str.detachTo(pName);
1740
1741 WCHAR ConnectoinName[128];
1742 ULONG cbName = sizeof(ConnectoinName);
1743
1744 HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName);
1745 if(hr == S_OK)
1746 {
1747 hr = VBoxNetCfgWinRenameConnection (pWCfgGuidString, ConnectoinName);
1748 }
1749
1750 /* remove the curly bracket at the end */
1751 pWCfgGuidString [wcslen (pWCfgGuidString) - 1] = L'\0';
1752 LogFlowFunc (("Network connection GUID string = {%ls}\n", pWCfgGuidString + 1));
1753
1754 aGUID = Guid (Utf8Str (pWCfgGuidString + 1));
1755 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1756 Assert (!aGUID.isEmpty());
1757 }
1758
1759 LogFlowFunc (("vrc=%Rrc\n", vrc));
1760 LogFlowFuncLeave();
1761 return vrc;
1762}
1763
1764/* static */
1765static int removeNetworkInterface (SVCHlpClient *aClient,
1766 const Guid &aGUID,
1767 Utf8Str &aErrMsg)
1768{
1769 LogFlowFuncEnter();
1770 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1771
1772 AssertReturn (aClient, VERR_INVALID_POINTER);
1773 AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);
1774
1775 int vrc = VINF_SUCCESS;
1776
1777 do
1778 {
1779 TCHAR lszPnPInstanceId [512] = {0};
1780
1781 /* We have to find the device instance ID through a registry search */
1782
1783 HKEY hkeyNetwork = 0;
1784 HKEY hkeyConnection = 0;
1785
1786 do
1787 {
1788 char strRegLocation [256];
1789 sprintf (strRegLocation,
1790 "SYSTEM\\CurrentControlSet\\Control\\Network\\"
1791 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}",
1792 aGUID.toString().raw());
1793 LONG status;
1794 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0,
1795 KEY_READ, &hkeyNetwork);
1796 if ((status != ERROR_SUCCESS) || !hkeyNetwork)
1797 SetErrBreak ((
1798 "Host interface network is not found in registry (%s) [1]",
1799 strRegLocation));
1800
1801 status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,
1802 KEY_READ, &hkeyConnection);
1803 if ((status != ERROR_SUCCESS) || !hkeyConnection)
1804 SetErrBreak ((
1805 "Host interface network is not found in registry (%s) [2]",
1806 strRegLocation));
1807
1808 DWORD len = sizeof (lszPnPInstanceId);
1809 DWORD dwKeyType;
1810 status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
1811 &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
1812 if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
1813 SetErrBreak ((
1814 "Host interface network is not found in registry (%s) [3]",
1815 strRegLocation));
1816 }
1817 while (0);
1818
1819 if (hkeyConnection)
1820 RegCloseKey (hkeyConnection);
1821 if (hkeyNetwork)
1822 RegCloseKey (hkeyNetwork);
1823
1824 if (RT_FAILURE (vrc))
1825 break;
1826
1827 /*
1828 * Now we are going to enumerate all network devices and
1829 * wait until we encounter the right device instance ID
1830 */
1831
1832 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1833
1834 do
1835 {
1836 BOOL ok;
1837 DWORD ret = 0;
1838 GUID netGuid;
1839 SP_DEVINFO_DATA DeviceInfoData;
1840 DWORD index = 0;
1841 BOOL found = FALSE;
1842 DWORD size = 0;
1843
1844 /* initialize the structure size */
1845 DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
1846
1847 /* copy the net class GUID */
1848 memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
1849
1850 /* return a device info set contains all installed devices of the Net class */
1851 hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
1852
1853 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1854 SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
1855
1856 /* enumerate the driver info list */
1857 while (TRUE)
1858 {
1859 TCHAR *deviceHwid;
1860
1861 ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
1862
1863 if (!ok)
1864 {
1865 if (GetLastError() == ERROR_NO_MORE_ITEMS)
1866 break;
1867 else
1868 {
1869 index++;
1870 continue;
1871 }
1872 }
1873
1874 /* try to get the hardware ID registry property */
1875 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1876 &DeviceInfoData,
1877 SPDRP_HARDWAREID,
1878 NULL,
1879 NULL,
1880 0,
1881 &size);
1882 if (!ok)
1883 {
1884 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1885 {
1886 index++;
1887 continue;
1888 }
1889
1890 deviceHwid = (TCHAR *) malloc (size);
1891 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1892 &DeviceInfoData,
1893 SPDRP_HARDWAREID,
1894 NULL,
1895 (PBYTE)deviceHwid,
1896 size,
1897 NULL);
1898 if (!ok)
1899 {
1900 free (deviceHwid);
1901 deviceHwid = NULL;
1902 index++;
1903 continue;
1904 }
1905 }
1906 else
1907 {
1908 /* something is wrong. This shouldn't have worked with a NULL buffer */
1909 index++;
1910 continue;
1911 }
1912
1913 for (TCHAR *t = deviceHwid;
1914 t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
1915 t += _tcslen (t) + 1)
1916 {
1917 if (!_tcsicmp (DRIVERHWID, t))
1918 {
1919 /* get the device instance ID */
1920 TCHAR devID [MAX_DEVICE_ID_LEN];
1921 if (CM_Get_Device_ID(DeviceInfoData.DevInst,
1922 devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
1923 {
1924 /* compare to what we determined before */
1925 if (wcscmp(devID, lszPnPInstanceId) == 0)
1926 {
1927 found = TRUE;
1928 break;
1929 }
1930 }
1931 }
1932 }
1933
1934 if (deviceHwid)
1935 {
1936 free (deviceHwid);
1937 deviceHwid = NULL;
1938 }
1939
1940 if (found)
1941 break;
1942
1943 index++;
1944 }
1945
1946 if (found == FALSE)
1947 SetErrBreak (("Host Interface Network driver not found (0x%08X)",
1948 GetLastError()));
1949
1950 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1951 if (!ok)
1952 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1953 GetLastError()));
1954
1955 ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1956 if (!ok)
1957 SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
1958 GetLastError()));
1959 }
1960 while (0);
1961
1962 /* clean up the device info set */
1963 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1964 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1965
1966 if (RT_FAILURE (vrc))
1967 break;
1968 }
1969 while (0);
1970
1971 LogFlowFunc (("vrc=%Rrc\n", vrc));
1972 LogFlowFuncLeave();
1973 return vrc;
1974}
1975
1976#undef SetErrBreak
1977
1978int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient,
1979 SVCHlpMsg::Code aMsgCode)
1980{
1981 LogFlowFuncEnter();
1982 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
1983
1984 AssertReturn (aClient, VERR_INVALID_POINTER);
1985
1986 int vrc = VINF_SUCCESS;
1987
1988 switch (aMsgCode)
1989 {
1990 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1991 {
1992 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
1993
1994// Utf8Str name;
1995// vrc = aClient->read (name);
1996// if (RT_FAILURE (vrc)) break;
1997
1998 Guid guid;
1999 Utf8Str errMsg;
2000 Bstr name;
2001 vrc = createNetworkInterface (aClient, name.asOutParam(), guid, errMsg);
2002
2003 if (RT_SUCCESS (vrc))
2004 {
2005 /* write success followed by GUID */
2006 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
2007 if (RT_FAILURE (vrc)) break;
2008 vrc = aClient->write (Utf8Str (name));
2009 if (RT_FAILURE (vrc)) break;
2010 vrc = aClient->write (guid);
2011 if (RT_FAILURE (vrc)) break;
2012 }
2013 else
2014 {
2015 /* write failure followed by error message */
2016 if (errMsg.isEmpty())
2017 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2018 vrc = aClient->write (SVCHlpMsg::Error);
2019 if (RT_FAILURE (vrc)) break;
2020 vrc = aClient->write (errMsg);
2021 if (RT_FAILURE (vrc)) break;
2022 }
2023
2024 break;
2025 }
2026 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
2027 {
2028 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
2029
2030 Guid guid;
2031 vrc = aClient->read (guid);
2032 if (RT_FAILURE (vrc)) break;
2033
2034 Utf8Str errMsg;
2035 vrc = removeNetworkInterface (aClient, guid, errMsg);
2036
2037 if (RT_SUCCESS (vrc))
2038 {
2039 /* write parameter-less success */
2040 vrc = aClient->write (SVCHlpMsg::OK);
2041 if (RT_FAILURE (vrc)) break;
2042 }
2043 else
2044 {
2045 /* write failure followed by error message */
2046 if (errMsg.isEmpty())
2047 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2048 vrc = aClient->write (SVCHlpMsg::Error);
2049 if (RT_FAILURE (vrc)) break;
2050 vrc = aClient->write (errMsg);
2051 if (RT_FAILURE (vrc)) break;
2052 }
2053
2054 break;
2055 }
2056 case SVCHlpMsg::EnableStaticIpConfigV6:
2057 {
2058 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
2059
2060 Guid guid;
2061 Utf8Str ipV6;
2062 ULONG maskLengthV6;
2063 vrc = aClient->read (guid);
2064 if (RT_FAILURE (vrc)) break;
2065 vrc = aClient->read (ipV6);
2066 if (RT_FAILURE (vrc)) break;
2067 vrc = aClient->read (maskLengthV6);
2068 if (RT_FAILURE (vrc)) break;
2069
2070 Utf8Str errMsg;
2071 vrc = netIfEnableStaticIpConfigV6 (guid, Bstr(ipV6), maskLengthV6);
2072
2073 if (RT_SUCCESS (vrc))
2074 {
2075 /* write success followed by GUID */
2076 vrc = aClient->write (SVCHlpMsg::OK);
2077 if (RT_FAILURE (vrc)) break;
2078 }
2079 else
2080 {
2081 /* write failure followed by error message */
2082 if (errMsg.isEmpty())
2083 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2084 vrc = aClient->write (SVCHlpMsg::Error);
2085 if (RT_FAILURE (vrc)) break;
2086 vrc = aClient->write (errMsg);
2087 if (RT_FAILURE (vrc)) break;
2088 }
2089
2090 break;
2091 }
2092 case SVCHlpMsg::EnableStaticIpConfig:
2093 {
2094 LogFlowFunc (("EnableStaticIpConfig:\n"));
2095
2096 Guid guid;
2097 ULONG ip, mask;
2098 vrc = aClient->read (guid);
2099 if (RT_FAILURE (vrc)) break;
2100 vrc = aClient->read (ip);
2101 if (RT_FAILURE (vrc)) break;
2102 vrc = aClient->read (mask);
2103 if (RT_FAILURE (vrc)) break;
2104
2105 Utf8Str errMsg;
2106 vrc = netIfEnableStaticIpConfig (guid, ip, mask);
2107
2108 if (RT_SUCCESS (vrc))
2109 {
2110 /* write success followed by GUID */
2111 vrc = aClient->write (SVCHlpMsg::OK);
2112 if (RT_FAILURE (vrc)) break;
2113 }
2114 else
2115 {
2116 /* write failure followed by error message */
2117 if (errMsg.isEmpty())
2118 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2119 vrc = aClient->write (SVCHlpMsg::Error);
2120 if (RT_FAILURE (vrc)) break;
2121 vrc = aClient->write (errMsg);
2122 if (RT_FAILURE (vrc)) break;
2123 }
2124
2125 break;
2126 }
2127 case SVCHlpMsg::EnableDynamicIpConfig:
2128 {
2129 LogFlowFunc (("EnableDynamicIpConfig:\n"));
2130
2131 Guid guid;
2132 vrc = aClient->read (guid);
2133 if (RT_FAILURE (vrc)) break;
2134
2135 Utf8Str errMsg;
2136 vrc = netIfEnableDynamicIpConfig (guid);
2137
2138 if (RT_SUCCESS (vrc))
2139 {
2140 /* write success followed by GUID */
2141 vrc = aClient->write (SVCHlpMsg::OK);
2142 if (RT_FAILURE (vrc)) break;
2143 }
2144 else
2145 {
2146 /* write failure followed by error message */
2147 if (errMsg.isEmpty())
2148 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2149 vrc = aClient->write (SVCHlpMsg::Error);
2150 if (RT_FAILURE (vrc)) break;
2151 vrc = aClient->write (errMsg);
2152 if (RT_FAILURE (vrc)) break;
2153 }
2154
2155 break;
2156 }
2157 case SVCHlpMsg::DhcpRediscover:
2158 {
2159 LogFlowFunc (("DhcpRediscover:\n"));
2160
2161 Guid guid;
2162 vrc = aClient->read (guid);
2163 if (RT_FAILURE (vrc)) break;
2164
2165 Utf8Str errMsg;
2166 vrc = netIfDhcpRediscover (guid);
2167
2168 if (RT_SUCCESS (vrc))
2169 {
2170 /* write success followed by GUID */
2171 vrc = aClient->write (SVCHlpMsg::OK);
2172 if (RT_FAILURE (vrc)) break;
2173 }
2174 else
2175 {
2176 /* write failure followed by error message */
2177 if (errMsg.isEmpty())
2178 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2179 vrc = aClient->write (SVCHlpMsg::Error);
2180 if (RT_FAILURE (vrc)) break;
2181 vrc = aClient->write (errMsg);
2182 if (RT_FAILURE (vrc)) break;
2183 }
2184
2185 break;
2186 }
2187 default:
2188 AssertMsgFailedBreakStmt (
2189 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
2190 VERR_GENERAL_FAILURE);
2191 }
2192
2193 LogFlowFunc (("vrc=%Rrc\n", vrc));
2194 LogFlowFuncLeave();
2195 return vrc;
2196}
2197
2198/** @todo REMOVE. OBSOLETE NOW. */
2199/**
2200 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
2201 * later OSes) and it has the UAC (User Account Control) feature enabled.
2202 */
2203static BOOL IsUACEnabled()
2204{
2205 LONG rc = 0;
2206
2207 OSVERSIONINFOEX info;
2208 ZeroMemory (&info, sizeof (OSVERSIONINFOEX));
2209 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
2210 rc = GetVersionEx ((OSVERSIONINFO *) &info);
2211 AssertReturn (rc != 0, FALSE);
2212
2213 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",
2214 info.dwMajorVersion, info.dwMinorVersion));
2215
2216 /* we are interested only in Vista (and newer versions...). In all
2217 * earlier versions UAC is not present. */
2218 if (info.dwMajorVersion < 6)
2219 return FALSE;
2220
2221 /* the default EnableLUA value is 1 (Enabled) */
2222 DWORD dwEnableLUA = 1;
2223
2224 HKEY hKey;
2225 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
2226 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
2227 0, KEY_QUERY_VALUE, &hKey);
2228
2229 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
2230 if (rc == ERROR_SUCCESS)
2231 {
2232
2233 DWORD cbEnableLUA = sizeof (dwEnableLUA);
2234 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,
2235 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
2236
2237 RegCloseKey (hKey);
2238
2239 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
2240 }
2241
2242 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
2243
2244 return dwEnableLUA == 1;
2245}
2246
2247/* end */
2248
2249static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
2250{
2251 LPWSTR lpszName;
2252 GUID IfGuid;
2253 HRESULT hr;
2254 int rc = VERR_GENERAL_FAILURE;
2255
2256 hr = pncc->GetDisplayName( &lpszName );
2257 Assert(hr == S_OK);
2258 if(hr == S_OK)
2259 {
2260 size_t cUnicodeName = wcslen(lpszName) + 1;
2261 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
2262 Bstr name (uniLen + 1 /* extra zero */);
2263 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
2264
2265 hr = pncc->GetInstanceGuid(&IfGuid);
2266 Assert(hr == S_OK);
2267 if (hr == S_OK)
2268 {
2269 NETIFINFO Info;
2270 memset(&Info, 0, sizeof(Info));
2271 Info.Uuid = *(Guid(IfGuid).raw());
2272 rc = collectNetIfInfo(name, Guid(IfGuid), &Info);
2273 if (RT_FAILURE(rc))
2274 {
2275 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
2276 }
2277 /* create a new object and add it to the list */
2278 ComObjPtr <HostNetworkInterface> iface;
2279 iface.createObject();
2280 /* remove the curly bracket at the end */
2281 if (SUCCEEDED (iface->init (name, enmType, &Info)))
2282 {
2283 pPist->push_back (iface);
2284 rc = VINF_SUCCESS;
2285 }
2286 else
2287 {
2288 Assert(0);
2289 }
2290 }
2291 CoTaskMemFree(lpszName);
2292 }
2293
2294 return rc;
2295}
2296
2297#endif /* VBOX_WITH_NETFLT */
2298
2299
2300static int netIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
2301{
2302#ifndef VBOX_WITH_NETFLT
2303 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
2304 return VERR_NOT_IMPLEMENTED;
2305#else /* # if defined VBOX_WITH_NETFLT */
2306 INetCfg *pNc;
2307 INetCfgComponent *pMpNcc;
2308 LPWSTR lpszApp = NULL;
2309 HRESULT hr;
2310 IEnumNetCfgComponent *pEnumComponent;
2311
2312 /* we are using the INetCfg API for getting the list of miniports */
2313 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2314 VBOX_APP_NAME,
2315 &pNc,
2316 &lpszApp );
2317 Assert(hr == S_OK);
2318 if(hr == S_OK)
2319 {
2320 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
2321 if(hr == S_OK)
2322 {
2323 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
2324 {
2325 ULONG uComponentStatus;
2326 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2327//#ifndef DEBUG_bird
2328// Assert(hr == S_OK);
2329//#endif
2330 if(hr == S_OK)
2331 {
2332 if(uComponentStatus == 0)
2333 {
2334 LPWSTR pId;
2335 hr = pMpNcc->GetId(&pId);
2336 Assert(hr == S_OK);
2337 if(hr == S_OK)
2338 {
2339 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
2340 {
2341 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
2342 }
2343 CoTaskMemFree(pId);
2344 }
2345 }
2346 }
2347 VBoxNetCfgWinReleaseRef(pMpNcc);
2348 }
2349 Assert(hr == S_OK || hr == S_FALSE);
2350
2351 VBoxNetCfgWinReleaseRef(pEnumComponent);
2352 }
2353 else
2354 {
2355 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2356 }
2357
2358 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2359 }
2360 else if(lpszApp)
2361 {
2362 CoTaskMemFree(lpszApp);
2363 }
2364#endif /* # if defined VBOX_WITH_NETFLT */
2365 return VINF_SUCCESS;
2366}
2367
2368int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
2369{
2370#ifndef VBOX_WITH_NETFLT
2371 return VERR_NOT_IMPLEMENTED;
2372#else
2373 Bstr name;
2374 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
2375 if(hr == S_OK)
2376 {
2377 GUID IfGuid;
2378 hr = pIf->COMGETTER(Id)(&IfGuid);
2379 Assert(hr == S_OK);
2380 if (hr == S_OK)
2381 {
2382 return collectNetIfInfo(name, Guid(IfGuid), pInfo);
2383 }
2384 }
2385 return VERR_GENERAL_FAILURE;
2386#endif
2387}
2388
2389int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox,
2390 IHostNetworkInterface **aHostNetworkInterface,
2391 IProgress **aProgress)
2392{
2393#ifndef VBOX_WITH_NETFLT
2394 return VERR_NOT_IMPLEMENTED;
2395#else
2396 /* create a progress object */
2397 ComObjPtr <Progress> progress;
2398 progress.createObject();
2399
2400 ComPtr<IHost> host;
2401 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2402 if(SUCCEEDED(rc))
2403 {
2404 rc = progress->init (pVBox, host,
2405 Bstr (_T ("Creating host only network interface")),
2406 FALSE /* aCancelable */);
2407 if(SUCCEEDED(rc))
2408 {
2409 CheckComRCReturnRC (rc);
2410 progress.queryInterfaceTo (aProgress);
2411
2412 /* create a new uninitialized host interface object */
2413 ComObjPtr <HostNetworkInterface> iface;
2414 iface.createObject();
2415 iface.queryInterfaceTo (aHostNetworkInterface);
2416
2417 /* create the networkInterfaceHelperClient() argument */
2418 std::auto_ptr <NetworkInterfaceHelperClientData>
2419 d (new NetworkInterfaceHelperClientData());
2420 AssertReturn (d.get(), E_OUTOFMEMORY);
2421
2422 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
2423// d->name = aName;
2424 d->iface = iface;
2425 d->vBox = pVBox;
2426
2427 rc = pVBox->startSVCHelperClient (
2428 IsUACEnabled() == TRUE /* aPrivileged */,
2429 netIfNetworkInterfaceHelperClient,
2430 static_cast <void *> (d.get()),
2431 progress);
2432
2433 if (SUCCEEDED (rc))
2434 {
2435 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2436 d.release();
2437 }
2438 }
2439 }
2440
2441 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2442#endif
2443}
2444
2445int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVBox, IN_GUID aId,
2446 IHostNetworkInterface **aHostNetworkInterface,
2447 IProgress **aProgress)
2448{
2449#ifndef VBOX_WITH_NETFLT
2450 return VERR_NOT_IMPLEMENTED;
2451#else
2452 /* create a progress object */
2453 ComObjPtr <Progress> progress;
2454 progress.createObject();
2455 ComPtr<IHost> host;
2456 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2457 if(SUCCEEDED(rc))
2458 {
2459 rc = progress->init (pVBox, host,
2460 Bstr (_T ("Removing host network interface")),
2461 FALSE /* aCancelable */);
2462 if(SUCCEEDED(rc))
2463 {
2464 CheckComRCReturnRC (rc);
2465 progress.queryInterfaceTo (aProgress);
2466
2467 /* create the networkInterfaceHelperClient() argument */
2468 std::auto_ptr <NetworkInterfaceHelperClientData>
2469 d (new NetworkInterfaceHelperClientData());
2470 AssertReturn (d.get(), E_OUTOFMEMORY);
2471
2472 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
2473 d->guid = aId;
2474
2475 rc = pVBox->startSVCHelperClient (
2476 IsUACEnabled() == TRUE /* aPrivileged */,
2477 netIfNetworkInterfaceHelperClient,
2478 static_cast <void *> (d.get()),
2479 progress);
2480
2481 if (SUCCEEDED (rc))
2482 {
2483 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2484 d.release();
2485 }
2486 }
2487 }
2488
2489 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2490#endif
2491}
2492
2493int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
2494{
2495#ifndef VBOX_WITH_NETFLT
2496 return VERR_NOT_IMPLEMENTED;
2497#else
2498 HRESULT rc;
2499 GUID guid;
2500 rc = pIf->COMGETTER(Id) (&guid);
2501 if(SUCCEEDED(rc))
2502 {
2503// ComPtr<VirtualBox> vBox;
2504// rc = pIf->getVirtualBox (vBox.asOutParam());
2505// if(SUCCEEDED(rc))
2506 {
2507 /* create a progress object */
2508 ComObjPtr <Progress> progress;
2509 progress.createObject();
2510// ComPtr<IHost> host;
2511// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2512// if(SUCCEEDED(rc))
2513 {
2514 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2515 Bstr ("Enabling Dynamic Ip Configuration"),
2516 FALSE /* aCancelable */);
2517 if(SUCCEEDED(rc))
2518 {
2519 CheckComRCReturnRC (rc);
2520// progress.queryInterfaceTo (aProgress);
2521
2522 /* create the networkInterfaceHelperClient() argument */
2523 std::auto_ptr <NetworkInterfaceHelperClientData>
2524 d (new NetworkInterfaceHelperClientData());
2525 AssertReturn (d.get(), E_OUTOFMEMORY);
2526
2527 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
2528 d->guid = guid;
2529 d->iface = pIf;
2530 d->u.StaticIP.IPAddress = ip;
2531 d->u.StaticIP.IPNetMask = mask;
2532
2533 rc = vBox->startSVCHelperClient (
2534 IsUACEnabled() == TRUE /* aPrivileged */,
2535 netIfNetworkInterfaceHelperClient,
2536 static_cast <void *> (d.get()),
2537 progress);
2538
2539 if (SUCCEEDED (rc))
2540 {
2541 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2542 d.release();
2543
2544 progress->WaitForCompletion(-1);
2545 }
2546 }
2547 }
2548 }
2549 }
2550
2551 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2552#endif
2553}
2554
2555int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
2556{
2557#ifndef VBOX_WITH_NETFLT
2558 return VERR_NOT_IMPLEMENTED;
2559#else
2560 HRESULT rc;
2561 GUID guid;
2562 rc = pIf->COMGETTER(Id) (&guid);
2563 if(SUCCEEDED(rc))
2564 {
2565// ComPtr<VirtualBox> vBox;
2566// rc = pIf->getVirtualBox (vBox.asOutParam());
2567// if(SUCCEEDED(rc))
2568 {
2569 /* create a progress object */
2570 ComObjPtr <Progress> progress;
2571 progress.createObject();
2572// ComPtr<IHost> host;
2573// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2574// if(SUCCEEDED(rc))
2575 {
2576 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2577 Bstr ("Enabling Dynamic Ip Configuration"),
2578 FALSE /* aCancelable */);
2579 if(SUCCEEDED(rc))
2580 {
2581 CheckComRCReturnRC (rc);
2582// progress.queryInterfaceTo (aProgress);
2583
2584 /* create the networkInterfaceHelperClient() argument */
2585 std::auto_ptr <NetworkInterfaceHelperClientData>
2586 d (new NetworkInterfaceHelperClientData());
2587 AssertReturn (d.get(), E_OUTOFMEMORY);
2588
2589 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
2590 d->guid = guid;
2591 d->iface = pIf;
2592 d->u.StaticIPV6.IPV6Address = aIPV6Address;
2593 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
2594
2595 rc = vBox->startSVCHelperClient (
2596 IsUACEnabled() == TRUE /* aPrivileged */,
2597 netIfNetworkInterfaceHelperClient,
2598 static_cast <void *> (d.get()),
2599 progress);
2600
2601 if (SUCCEEDED (rc))
2602 {
2603 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2604 d.release();
2605
2606 progress->WaitForCompletion(-1);
2607 }
2608 }
2609 }
2610 }
2611 }
2612
2613 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2614#endif
2615}
2616
2617int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
2618{
2619#ifndef VBOX_WITH_NETFLT
2620 return VERR_NOT_IMPLEMENTED;
2621#else
2622 HRESULT rc;
2623 GUID guid;
2624 rc = pIf->COMGETTER(Id) (&guid);
2625 if(SUCCEEDED(rc))
2626 {
2627// ComPtr<VirtualBox> vBox;
2628// rc = pIf->getVirtualBox (vBox.asOutParam());
2629// if(SUCCEEDED(rc))
2630 {
2631 /* create a progress object */
2632 ComObjPtr <Progress> progress;
2633 progress.createObject();
2634// ComPtr<IHost> host;
2635// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2636// if(SUCCEEDED(rc))
2637 {
2638 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2639 Bstr ("Enabling Dynamic Ip Configuration"),
2640 FALSE /* aCancelable */);
2641 if(SUCCEEDED(rc))
2642 {
2643 CheckComRCReturnRC (rc);
2644// progress.queryInterfaceTo (aProgress);
2645
2646 /* create the networkInterfaceHelperClient() argument */
2647 std::auto_ptr <NetworkInterfaceHelperClientData>
2648 d (new NetworkInterfaceHelperClientData());
2649 AssertReturn (d.get(), E_OUTOFMEMORY);
2650
2651 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
2652 d->guid = guid;
2653 d->iface = pIf;
2654
2655 rc = vBox->startSVCHelperClient (
2656 IsUACEnabled() == TRUE /* aPrivileged */,
2657 netIfNetworkInterfaceHelperClient,
2658 static_cast <void *> (d.get()),
2659 progress);
2660
2661 if (SUCCEEDED (rc))
2662 {
2663 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2664 d.release();
2665
2666 progress->WaitForCompletion(-1);
2667 }
2668 }
2669 }
2670 }
2671 }
2672
2673 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2674#endif
2675}
2676
2677int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
2678{
2679#ifndef VBOX_WITH_NETFLT
2680 return VERR_NOT_IMPLEMENTED;
2681#else
2682 HRESULT rc;
2683 GUID guid;
2684 rc = pIf->COMGETTER(Id) (&guid);
2685 if(SUCCEEDED(rc))
2686 {
2687// ComPtr<VirtualBox> vBox;
2688// rc = pIf->getVirtualBox (vBox.asOutParam());
2689// if(SUCCEEDED(rc))
2690 {
2691 /* create a progress object */
2692 ComObjPtr <Progress> progress;
2693 progress.createObject();
2694// ComPtr<IHost> host;
2695// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2696// if(SUCCEEDED(rc))
2697 {
2698 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2699 Bstr ("Enabling Dynamic Ip Configuration"),
2700 FALSE /* aCancelable */);
2701 if(SUCCEEDED(rc))
2702 {
2703 CheckComRCReturnRC (rc);
2704// progress.queryInterfaceTo (aProgress);
2705
2706 /* create the networkInterfaceHelperClient() argument */
2707 std::auto_ptr <NetworkInterfaceHelperClientData>
2708 d (new NetworkInterfaceHelperClientData());
2709 AssertReturn (d.get(), E_OUTOFMEMORY);
2710
2711 d->msgCode = SVCHlpMsg::DhcpRediscover;
2712 d->guid = guid;
2713 d->iface = pIf;
2714
2715 rc = vBox->startSVCHelperClient (
2716 IsUACEnabled() == TRUE /* aPrivileged */,
2717 netIfNetworkInterfaceHelperClient,
2718 static_cast <void *> (d.get()),
2719 progress);
2720
2721 if (SUCCEEDED (rc))
2722 {
2723 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2724 d.release();
2725
2726 progress->WaitForCompletion(-1);
2727 }
2728 }
2729 }
2730 }
2731 }
2732
2733 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2734#endif
2735}
2736
2737int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
2738{
2739#ifndef VBOX_WITH_NETFLT
2740 return VERR_NOT_IMPLEMENTED;
2741#else /* # if defined VBOX_WITH_NETFLT */
2742 INetCfg *pNc;
2743 INetCfgComponent *pMpNcc;
2744 INetCfgComponent *pTcpIpNcc;
2745 LPWSTR lpszApp;
2746 HRESULT hr;
2747 IEnumNetCfgBindingPath *pEnumBp;
2748 INetCfgBindingPath *pBp;
2749 IEnumNetCfgBindingInterface *pEnumBi;
2750 INetCfgBindingInterface *pBi;
2751
2752 /* we are using the INetCfg API for getting the list of miniports */
2753 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2754 VBOX_APP_NAME,
2755 &pNc,
2756 &lpszApp );
2757 Assert(hr == S_OK);
2758 if(hr == S_OK)
2759 {
2760# ifdef VBOX_NETFLT_ONDEMAND_BIND
2761 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
2762 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
2763# else
2764 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
2765 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
2766# ifndef VBOX_WITH_HARDENING
2767 if(hr != S_OK)
2768 {
2769 /* TODO: try to install the netflt from here */
2770 }
2771# endif
2772
2773# endif
2774
2775 if(hr == S_OK)
2776 {
2777 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
2778 Assert(hr == S_OK);
2779 if ( hr == S_OK )
2780 {
2781 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
2782 Assert(hr == S_OK || hr == S_FALSE);
2783 while( hr == S_OK )
2784 {
2785 /* S_OK == enabled, S_FALSE == disabled */
2786 if(pBp->IsEnabled() == S_OK)
2787 {
2788 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
2789 Assert(hr == S_OK);
2790 if ( hr == S_OK )
2791 {
2792 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
2793 Assert(hr == S_OK);
2794 while(hr == S_OK)
2795 {
2796 hr = pBi->GetLowerComponent( &pMpNcc );
2797 Assert(hr == S_OK);
2798 if(hr == S_OK)
2799 {
2800 ULONG uComponentStatus;
2801 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2802//#ifndef DEBUG_bird
2803// Assert(hr == S_OK);
2804//#endif
2805 if(hr == S_OK)
2806 {
2807 if(uComponentStatus == 0)
2808 {
2809 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
2810 }
2811 }
2812 VBoxNetCfgWinReleaseRef( pMpNcc );
2813 }
2814 VBoxNetCfgWinReleaseRef(pBi);
2815
2816 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
2817 }
2818 VBoxNetCfgWinReleaseRef(pEnumBi);
2819 }
2820 }
2821 VBoxNetCfgWinReleaseRef(pBp);
2822
2823 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
2824 }
2825 VBoxNetCfgWinReleaseRef(pEnumBp);
2826 }
2827 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
2828 }
2829 else
2830 {
2831 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2832 }
2833
2834 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2835 }
2836
2837 netIfListHostAdapters(list);
2838
2839 return VINF_SUCCESS;
2840#endif /* # if defined VBOX_WITH_NETFLT */
2841}
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