VirtualBox

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

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

NetIf/win: clear static ip impl

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 91.9 KB
Line 
1/* $Id: NetIfList-win.cpp 17985 2009-03-16 22:02:09Z 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 netIfWinCreateIWbemServices(IWbemServices ** ppSvc)
69{
70 HRESULT hres;
71
72 // Step 3: ---------------------------------------------------
73 // Obtain the initial locator to WMI -------------------------
74
75 IWbemLocator *pLoc = NULL;
76
77 hres = CoCreateInstance(
78 CLSID_WbemLocator,
79 0,
80 CLSCTX_INPROC_SERVER,
81 IID_IWbemLocator, (LPVOID *) &pLoc);
82 if(SUCCEEDED(hres))
83 {
84 // Step 4: -----------------------------------------------------
85 // Connect to WMI through the IWbemLocator::ConnectServer method
86
87 IWbemServices *pSvc = NULL;
88
89 // Connect to the root\cimv2 namespace with
90 // the current user and obtain pointer pSvc
91 // to make IWbemServices calls.
92 hres = pLoc->ConnectServer(
93 _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
94 NULL, // User name. NULL = current user
95 NULL, // User password. NULL = current
96 0, // Locale. NULL indicates current
97 NULL, // Security flags.
98 0, // Authority (e.g. Kerberos)
99 0, // Context object
100 &pSvc // pointer to IWbemServices proxy
101 );
102 if(SUCCEEDED(hres))
103 {
104 LogRel(("Connected to ROOT\\CIMV2 WMI namespace\n"));
105
106 // Step 5: --------------------------------------------------
107 // Set security levels on the proxy -------------------------
108
109 hres = CoSetProxyBlanket(
110 pSvc, // Indicates the proxy to set
111 RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
112 RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
113 NULL, // Server principal name
114 RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
115 RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
116 NULL, // client identity
117 EOAC_NONE // proxy capabilities
118 );
119 if(SUCCEEDED(hres))
120 {
121 *ppSvc = pSvc;
122 /* do not need it any more */
123 pLoc->Release();
124 return hres;
125 }
126 else
127 {
128 LogRel(("Could not set proxy blanket. Error code = 0x%x\n", hres));
129 }
130
131 pSvc->Release();
132 }
133 else
134 {
135 LogRel(("Could not connect. Error code = 0x%x\n", hres));
136 }
137
138 pLoc->Release();
139 }
140 else
141 {
142 LogRel(("Failed to create IWbemLocator object. Err code = 0x%x\n", hres));
143// CoUninitialize();
144 }
145
146 return hres;
147}
148
149static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const Guid &guid, IWbemClassObject **pAdapterConfig)
150{
151 HRESULT hres;
152 WCHAR aQueryString[256];
153// char uuidStr[RTUUID_STR_LENGTH];
154// int rc = RTUuidToStr(guid.toString().raw(), uuidStr, sizeof(uuidStr));
155 {
156 swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"{%S}\"", guid.toString().raw());
157 // Step 6: --------------------------------------------------
158 // Use the IWbemServices pointer to make requests of WMI ----
159
160 IEnumWbemClassObject* pEnumerator = NULL;
161 hres = pSvc->ExecQuery(
162 bstr_t("WQL"),
163 bstr_t(aQueryString),
164 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
165 NULL,
166 &pEnumerator);
167 if(SUCCEEDED(hres))
168 {
169 // Step 7: -------------------------------------------------
170 // Get the data from the query in step 6 -------------------
171
172 IWbemClassObject *pclsObj;
173 ULONG uReturn = 0;
174
175 while (pEnumerator)
176 {
177 HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
178 &pclsObj, &uReturn);
179
180 if(SUCCEEDED(hres))
181 {
182 if(uReturn)
183 {
184 pEnumerator->Release();
185 *pAdapterConfig = pclsObj;
186 hres = S_OK;
187 return hres;
188 }
189 else
190 {
191 hres = S_FALSE;
192 }
193 }
194
195 }
196 pEnumerator->Release();
197 }
198 else
199 {
200 Log(("Query for operating system name failed. Error code = 0x%x\n", hres));
201 }
202 }
203
204 return hres;
205}
206
207static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr)
208{
209 VARIANT index;
210
211 // Get the value of the key property
212 HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0);
213 if(SUCCEEDED(hr))
214 {
215 WCHAR strIndex[8];
216 swprintf(strIndex, L"%u", index.uintVal);
217 *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy();
218 }
219 else
220 {
221 DWORD dwError = GetLastError();
222 Assert(0);
223 hr = HRESULT_FROM_WIN32( dwError );
224 }
225 return hr;
226}
227
228static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath,
229 BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs,
230 IWbemClassObject** ppOutParams
231 )
232{
233 HRESULT hres = S_OK;
234 // Step 6: --------------------------------------------------
235 // Use the IWbemServices pointer to make requests of WMI ----
236
237 ComPtr<IWbemClassObject> pInParamsDefinition;
238 ComPtr<IWbemClassObject> pClassInstance;
239
240 if(cArgs)
241 {
242 hres = pClass->GetMethod(MethodName, 0,
243 pInParamsDefinition.asOutParam(), NULL);
244 if(SUCCEEDED(hres))
245 {
246 hres = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam());
247
248 if(SUCCEEDED(hres))
249 {
250 for(UINT i = 0; i < cArgs; i++)
251 {
252 // Store the value for the in parameters
253 hres = pClassInstance->Put(pArgNames[i], 0,
254 pArgs[i], 0);
255 if(FAILED(hres))
256 {
257 break;
258 }
259 }
260 }
261 }
262 }
263
264 if(SUCCEEDED(hres))
265 {
266 IWbemClassObject* pOutParams = NULL;
267 hres = pSvc->ExecMethod(ObjPath, MethodName, 0,
268 NULL, pClassInstance, &pOutParams, NULL);
269 if(SUCCEEDED(hres))
270 {
271 *ppOutParams = pOutParams;
272 }
273 }
274
275 return hres;
276}
277
278static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp)
279{
280 HRESULT hr;
281 SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp);
282 if(pIpArray)
283 {
284 for(UINT i = 0; i < cIp; i++)
285 {
286 char* addr = inet_ntoa(aIp[i]);
287 BSTR val = bstr_t(addr).copy();
288 long aIndex[1];
289 aIndex[0] = i;
290 hr = SafeArrayPutElement(pIpArray, aIndex, val);
291 if(FAILED(hr))
292 {
293 SysFreeString(val);
294 SafeArrayDestroy(pIpArray);
295 break;
296 }
297 }
298
299 if(SUCCEEDED(hr))
300 {
301 *ppArray = pIpArray;
302 }
303 }
304 else
305 {
306 DWORD dwError = GetLastError();
307 Assert(0);
308 hr = HRESULT_FROM_WIN32( dwError );
309 }
310
311 return hr;
312}
313
314static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip)
315{
316 HRESULT hr;
317 SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1);
318 if(pIpArray)
319 {
320 BSTR val = bstr_t(Ip, false).copy();
321 long aIndex[1];
322 aIndex[0] = 0;
323 hr = SafeArrayPutElement(pIpArray, aIndex, val);
324 if(FAILED(hr))
325 {
326 SysFreeString(val);
327 SafeArrayDestroy(pIpArray);
328 }
329
330 if(SUCCEEDED(hr))
331 {
332 *ppArray = pIpArray;
333 }
334 }
335 else
336 {
337 DWORD dwError = GetLastError();
338 Assert(0);
339 hr = HRESULT_FROM_WIN32( dwError );
340 }
341
342 return hr;
343}
344
345
346static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp)
347{
348 HRESULT hr;
349 VariantInit(pIpAddresses);
350 pIpAddresses->vt = VT_ARRAY | VT_BSTR;
351 SAFEARRAY *pIpArray;
352 hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp);
353 if(SUCCEEDED(hr))
354 {
355 pIpAddresses->parray = pIpArray;
356 }
357 return hr;
358}
359
360static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip)
361{
362 HRESULT hr;
363 VariantInit(pIpAddresses);
364 pIpAddresses->vt = VT_ARRAY | VT_BSTR;
365 SAFEARRAY *pIpArray;
366 hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip);
367 if(SUCCEEDED(hr))
368 {
369 pIpAddresses->parray = pIpArray;
370 }
371 return hr;
372}
373
374static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask)
375{
376 ComPtr<IWbemClassObject> pClass;
377 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
378 HRESULT hr;
379 if(ClassName)
380 {
381 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
382 if(SUCCEEDED(hr))
383 {
384 LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"};
385 LPVARIANT args[] = {pIp, pMask};
386 ComPtr<IWbemClassObject> pOutParams;
387
388 hr = netIfExecMethod(pSvc, pClass, ObjPath,
389 bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam());
390 if(SUCCEEDED(hr))
391 {
392 VARIANT varReturnValue;
393 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
394 &varReturnValue, NULL, 0);
395 Assert(SUCCEEDED(hr));
396 if(SUCCEEDED(hr))
397 {
398// Assert(varReturnValue.vt == VT_UINT);
399 int winEr = varReturnValue.uintVal;
400 switch(winEr)
401 {
402 case 0:
403 hr = S_OK;
404 break;
405 default:
406 hr = HRESULT_FROM_WIN32( winEr );
407 break;
408 }
409 }
410 }
411 }
412 SysFreeString(ClassName);
413 }
414 else
415 {
416 DWORD dwError = GetLastError();
417 Assert(0);
418 hr = HRESULT_FROM_WIN32( dwError );
419 }
420
421 return hr;
422}
423
424
425static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp)
426{
427 VARIANT ipAddresses;
428 HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp);
429 if(SUCCEEDED(hr))
430 {
431 VARIANT ipMasks;
432 hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp);
433 if(SUCCEEDED(hr))
434 {
435 netIfWinEnableStatic(pSvc, ObjPath, &ipAddresses, &ipMasks);
436 VariantClear(&ipMasks);
437 }
438 VariantClear(&ipAddresses);
439 }
440 return hr;
441}
442
443static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Ip, BSTR Mask)
444{
445 VARIANT ipAddresses;
446 HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip);
447 if(SUCCEEDED(hr))
448 {
449 VARIANT ipMasks;
450 hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask);
451 if(SUCCEEDED(hr))
452 {
453 netIfWinEnableStatic(pSvc, ObjPath, &ipAddresses, &ipMasks);
454 VariantClear(&ipMasks);
455 }
456 VariantClear(&ipAddresses);
457 }
458 return hr;
459}
460
461/* win API allows to set gw metrics as well, we are not setting them */
462static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw)
463{
464 ComPtr<IWbemClassObject> pClass;
465 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
466 HRESULT hr;
467 if(ClassName)
468 {
469 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
470 if(SUCCEEDED(hr))
471 {
472 LPWSTR argNames[] = {L"DefaultIPGateway"};
473 LPVARIANT args[] = {pGw};
474 ComPtr<IWbemClassObject> pOutParams;
475
476 hr = netIfExecMethod(pSvc, pClass, ObjPath,
477 bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam());
478 if(SUCCEEDED(hr))
479 {
480 VARIANT varReturnValue;
481 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
482 &varReturnValue, NULL, 0);
483 Assert(SUCCEEDED(hr));
484 if(SUCCEEDED(hr))
485 {
486// Assert(varReturnValue.vt == VT_UINT);
487 int winEr = varReturnValue.uintVal;
488 switch(winEr)
489 {
490 case 0:
491 hr = S_OK;
492 break;
493 default:
494 hr = HRESULT_FROM_WIN32( winEr );
495 break;
496 }
497 }
498 } }
499 SysFreeString(ClassName);
500 }
501 else
502 {
503 DWORD dwError = GetLastError();
504 Assert(0);
505 hr = HRESULT_FROM_WIN32( dwError );
506 }
507
508 return hr;
509}
510
511/* win API allows to set gw metrics as well, we are not setting them */
512static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw)
513{
514 VARIANT gwais;
515 HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw);
516 if(SUCCEEDED(hr))
517 {
518 netIfWinSetGateways(pSvc, ObjPath, &gwais);
519 VariantClear(&gwais);
520 }
521 return hr;
522}
523
524/* win API allows to set gw metrics as well, we are not setting them */
525static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw)
526{
527 VARIANT vGw;
528 HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw);
529 if(SUCCEEDED(hr))
530 {
531 netIfWinSetGateways(pSvc, ObjPath, &vGw);
532 VariantClear(&vGw);
533 }
534 return hr;
535}
536
537static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath)
538{
539 ComPtr<IWbemClassObject> pClass;
540 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
541 HRESULT hr;
542 if(ClassName)
543 {
544 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
545 if(SUCCEEDED(hr))
546 {
547 ComPtr<IWbemClassObject> pOutParams;
548
549 hr = netIfExecMethod(pSvc, pClass, ObjPath,
550 bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam());
551 if(SUCCEEDED(hr))
552 {
553 VARIANT varReturnValue;
554 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
555 &varReturnValue, NULL, 0);
556 Assert(SUCCEEDED(hr));
557 if(SUCCEEDED(hr))
558 {
559// Assert(varReturnValue.vt == VT_UINT);
560 int winEr = varReturnValue.uintVal;
561 switch(winEr)
562 {
563 case 0:
564 hr = S_OK;
565 break;
566 default:
567 hr = HRESULT_FROM_WIN32( winEr );
568 break;
569 }
570 }
571 }
572 }
573 SysFreeString(ClassName);
574 }
575 else
576 {
577 DWORD dwError = GetLastError();
578 Assert(0);
579 hr = HRESULT_FROM_WIN32( dwError );
580 }
581
582 return hr;
583}
584
585static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath)
586{
587 ComPtr<IWbemClassObject> pClass;
588 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
589 HRESULT hr;
590 if(ClassName)
591 {
592 hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL);
593 if(SUCCEEDED(hr))
594 {
595 ComPtr<IWbemClassObject> pOutParams;
596
597 hr = netIfExecMethod(pSvc, pClass, ObjPath,
598 bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
599 if(SUCCEEDED(hr))
600 {
601 VARIANT varReturnValue;
602 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
603 &varReturnValue, NULL, 0);
604 Assert(SUCCEEDED(hr));
605 if(SUCCEEDED(hr))
606 {
607// Assert(varReturnValue.vt == VT_UINT);
608 int winEr = varReturnValue.uintVal;
609 if(winEr == 0)
610 {
611 hr = netIfExecMethod(pSvc, pClass, ObjPath,
612 bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam());
613 if(SUCCEEDED(hr))
614 {
615 VARIANT varReturnValue;
616 hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0,
617 &varReturnValue, NULL, 0);
618 Assert(SUCCEEDED(hr));
619 if(SUCCEEDED(hr))
620 {
621 // Assert(varReturnValue.vt == VT_UINT);
622 int winEr = varReturnValue.uintVal;
623 if(winEr == 0)
624 {
625 hr = S_OK;
626 }
627 else
628 {
629 hr = HRESULT_FROM_WIN32( winEr );
630 }
631 }
632 }
633 }
634 else
635 {
636 hr = HRESULT_FROM_WIN32( winEr );
637 }
638 }
639 }
640 }
641 SysFreeString(ClassName);
642 }
643 else
644 {
645 DWORD dwError = GetLastError();
646 Assert(0);
647 hr = HRESULT_FROM_WIN32( dwError );
648 }
649
650 return hr;
651}
652
653static int netIfWinIsDhcpEnabled(const Guid &guid, BOOL *pEnabled)
654{
655 HRESULT hr;
656 ComPtr <IWbemServices> pSvc;
657 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
658 if(SUCCEEDED(hr))
659 {
660 ComPtr <IWbemClassObject> pAdapterConfig;
661 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
662 if(SUCCEEDED(hr))
663 {
664 VARIANT vtEnabled;
665 hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0);
666 if(SUCCEEDED(hr))
667 {
668 *pEnabled = vtEnabled.boolVal;
669 }
670 }
671 }
672
673 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
674}
675
676static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo)
677{
678 DWORD dwRc;
679 int rc = VINF_SUCCESS;
680 /*
681 * Most of the hosts probably have less than 10 adapters,
682 * so we'll mostly succeed from the first attempt.
683 */
684 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
685 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
686 if (!pAddresses)
687 return VERR_NO_MEMORY;
688 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
689 if (dwRc == ERROR_BUFFER_OVERFLOW)
690 {
691 /* Impressive! More than 10 adapters! Get more memory and try again. */
692 RTMemFree(pAddresses);
693 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
694 if (!pAddresses)
695 return VERR_NO_MEMORY;
696 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
697 }
698 if (dwRc == NO_ERROR)
699 {
700 PIP_ADAPTER_ADDRESSES pAdapter;
701 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
702 {
703 char *pszUuid = RTStrDup(pAdapter->AdapterName);
704 size_t len = strlen(pszUuid) - 1;
705 if (pszUuid[0] == '{' && pszUuid[len] == '}')
706 {
707 pszUuid[len] = 0;
708 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
709 {
710 bool fIPFound, fIPv6Found;
711 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
712 fIPFound = fIPv6Found = false;
713 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
714 {
715 switch (pAddr->Address.lpSockaddr->sa_family)
716 {
717 case AF_INET:
718 if (!fIPFound)
719 {
720 fIPFound = true;
721 memcpy(&pInfo->IPAddress,
722 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
723 sizeof(pInfo->IPAddress));
724 }
725 break;
726 case AF_INET6:
727 if (!fIPv6Found)
728 {
729 fIPv6Found = true;
730 memcpy(&pInfo->IPv6Address,
731 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
732 sizeof(pInfo->IPv6Address));
733 }
734 break;
735 }
736 }
737 PIP_ADAPTER_PREFIX pPrefix;
738 fIPFound = fIPv6Found = false;
739 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
740 {
741 switch (pPrefix->Address.lpSockaddr->sa_family)
742 {
743 case AF_INET:
744 if (!fIPFound)
745 {
746 fIPFound = true;
747 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
748 }
749 break;
750 case AF_INET6:
751 if (!fIPv6Found)
752 {
753 fIPv6Found = true;
754 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
755 }
756 break;
757 }
758 }
759 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
760 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
761 else
762 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
763 pInfo->enmMediumType = NETIF_T_ETHERNET;
764 pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
765 RTStrFree(pszUuid);
766 break;
767 }
768 }
769 RTStrFree(pszUuid);
770 }
771
772 BOOL bEnabled;
773 rc = netIfWinIsDhcpEnabled(guid, &bEnabled);
774 Assert(RT_SUCCESS(rc));
775 if(RT_SUCCESS(rc))
776 {
777 pInfo->bDhcpEnabled = bEnabled;
778 }
779 }
780 RTMemFree(pAddresses);
781
782 return VINF_SUCCESS;
783}
784
785static int netIfEnableStaticIpConfig(const Guid &guid, ULONG ip, ULONG mask)
786{
787 HRESULT hr;
788 ComPtr <IWbemServices> pSvc;
789 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
790 if(SUCCEEDED(hr))
791 {
792 ComPtr <IWbemClassObject> pAdapterConfig;
793 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
794 if(SUCCEEDED(hr))
795 {
796 in_addr aIp[1];
797 in_addr aMask[1];
798 aIp[0].S_un.S_addr = ip;
799 aMask[0].S_un.S_addr = mask;
800
801 BSTR ObjPath;
802 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
803 if(SUCCEEDED(hr))
804 {
805 hr = netIfWinEnableStaticV4(pSvc, ObjPath, aIp, aMask, ip != 0 ? 1 : 0);
806 if(SUCCEEDED(hr))
807 {
808#if 0
809 in_addr aGw[1];
810 aGw[0].S_un.S_addr = gw;
811 hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1);
812 if(SUCCEEDED(hr))
813#endif
814 {
815// hr = netIfWinUpdateConfig(pIf);
816 }
817 }
818 SysFreeString(ObjPath);
819 }
820 }
821 }
822
823 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
824}
825
826static int netIfEnableStaticIpConfigV6(const Guid & guid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway)
827{
828 HRESULT hr;
829 ComPtr <IWbemServices> pSvc;
830 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
831 if(SUCCEEDED(hr))
832 {
833 ComPtr <IWbemClassObject> pAdapterConfig;
834 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
835 if(SUCCEEDED(hr))
836 {
837 BSTR ObjPath;
838 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
839 if(SUCCEEDED(hr))
840 {
841 hr = netIfWinEnableStaticV4V6(pSvc, ObjPath, aIPV6Address, aIPV6Mask);
842 if(SUCCEEDED(hr))
843 {
844 if(aIPV6DefaultGateway)
845 {
846 hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway);
847 }
848 if(SUCCEEDED(hr))
849 {
850// hr = netIfWinUpdateConfig(pIf);
851 }
852 }
853 SysFreeString(ObjPath);
854 }
855 }
856 }
857
858 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
859}
860
861static int netIfEnableStaticIpConfigV6(const Guid &guid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
862{
863 RTNETADDRIPV6 Mask;
864 int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask);
865 if(RT_SUCCESS(rc))
866 {
867 Bstr maskStr = composeIPv6Address(&Mask);
868 rc = netIfEnableStaticIpConfigV6(guid, aIPV6Address, maskStr, NULL);
869 }
870 return rc;
871}
872
873static HRESULT netIfEnableDynamicIpConfig(const Guid &guid)
874{
875 HRESULT hr;
876 ComPtr <IWbemServices> pSvc;
877 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
878 if(SUCCEEDED(hr))
879 {
880 ComPtr <IWbemClassObject> pAdapterConfig;
881 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
882 if(SUCCEEDED(hr))
883 {
884 BSTR ObjPath;
885 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
886 if(SUCCEEDED(hr))
887 {
888 hr = netIfWinEnableDHCP(pSvc, ObjPath);
889 if(SUCCEEDED(hr))
890 {
891// hr = netIfWinUpdateConfig(pIf);
892 }
893 SysFreeString(ObjPath);
894 }
895 }
896 }
897
898
899 return hr;
900}
901
902static HRESULT netIfDhcpRediscover(const Guid &guid)
903{
904 HRESULT hr;
905 ComPtr <IWbemServices> pSvc;
906 hr = netIfWinCreateIWbemServices(pSvc.asOutParam());
907 if(SUCCEEDED(hr))
908 {
909 ComPtr <IWbemClassObject> pAdapterConfig;
910 hr = netIfWinFindAdapterClassById(pSvc, guid, pAdapterConfig.asOutParam());
911 if(SUCCEEDED(hr))
912 {
913 BSTR ObjPath;
914 hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath);
915 if(SUCCEEDED(hr))
916 {
917 hr = netIfWinDhcpRediscover(pSvc, ObjPath);
918 if(SUCCEEDED(hr))
919 {
920// hr = netIfWinUpdateConfig(pIf);
921 }
922 SysFreeString(ObjPath);
923 }
924 }
925 }
926
927
928 return hr;
929}
930
931/* svc helper func */
932
933struct StaticIpConfig
934{
935 ULONG IPAddress;
936 ULONG IPNetMask;
937};
938
939struct StaticIpV6Config
940{
941 BSTR IPV6Address;
942 ULONG IPV6NetMaskLength;
943};
944
945struct NetworkInterfaceHelperClientData
946{
947 SVCHlpMsg::Code msgCode;
948 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
949 Bstr name;
950 ComObjPtr <HostNetworkInterface> iface;
951 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
952 Guid guid;
953
954 union
955 {
956 StaticIpConfig StaticIP;
957 StaticIpV6Config StaticIPV6;
958 } u;
959
960
961};
962
963static HRESULT netIfNetworkInterfaceHelperClient (SVCHlpClient *aClient,
964 Progress *aProgress,
965 void *aUser, int *aVrc)
966{
967 LogFlowFuncEnter();
968 LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n",
969 aClient, aProgress, aUser));
970
971 AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) ||
972 (aClient != NULL && aProgress != NULL && aVrc != NULL),
973 E_POINTER);
974 AssertReturn (aUser, E_POINTER);
975
976 std::auto_ptr <NetworkInterfaceHelperClientData>
977 d (static_cast <NetworkInterfaceHelperClientData *> (aUser));
978
979 if (aClient == NULL)
980 {
981 /* "cleanup only" mode, just return (it will free aUser) */
982 return S_OK;
983 }
984
985 HRESULT rc = S_OK;
986 int vrc = VINF_SUCCESS;
987
988 switch (d->msgCode)
989 {
990 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
991 {
992 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
993 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
994
995 /* write message and parameters */
996 vrc = aClient->write (d->msgCode);
997 if (RT_FAILURE (vrc)) break;
998// vrc = aClient->write (Utf8Str (d->name));
999// if (RT_FAILURE (vrc)) break;
1000
1001 /* wait for a reply */
1002 bool endLoop = false;
1003 while (!endLoop)
1004 {
1005 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1006
1007 vrc = aClient->read (reply);
1008 if (RT_FAILURE (vrc)) break;
1009
1010 switch (reply)
1011 {
1012 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
1013 {
1014 /* read the GUID */
1015 Guid guid;
1016 Utf8Str name;
1017 vrc = aClient->read (name);
1018 if (RT_FAILURE (vrc)) break;
1019 vrc = aClient->read (guid);
1020 if (RT_FAILURE (vrc)) break;
1021
1022 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", guid.raw()));
1023
1024 /* initialize the object returned to the caller by
1025 * CreateHostOnlyNetworkInterface() */
1026 rc = d->iface->init (Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
1027 endLoop = true;
1028 break;
1029 }
1030 case SVCHlpMsg::Error:
1031 {
1032 /* read the error message */
1033 Utf8Str errMsg;
1034 vrc = aClient->read (errMsg);
1035 if (RT_FAILURE (vrc)) break;
1036
1037 rc = E_FAIL;//TODO: setError (E_FAIL, errMsg);
1038 endLoop = true;
1039 break;
1040 }
1041 default:
1042 {
1043 endLoop = true;
1044 rc = E_FAIL;//TODO: ComAssertMsgFailedBreak ((
1045 //"Invalid message code %d (%08lX)\n",
1046 //reply, reply),
1047 //rc = E_FAIL);
1048 }
1049 }
1050 }
1051
1052 break;
1053 }
1054 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
1055 {
1056 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
1057 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
1058
1059 /* write message and parameters */
1060 vrc = aClient->write (d->msgCode);
1061 if (RT_FAILURE (vrc)) break;
1062 vrc = aClient->write (d->guid);
1063 if (RT_FAILURE (vrc)) break;
1064
1065 /* wait for a reply */
1066 bool endLoop = false;
1067 while (!endLoop)
1068 {
1069 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1070
1071 vrc = aClient->read (reply);
1072 if (RT_FAILURE (vrc)) break;
1073
1074 switch (reply)
1075 {
1076 case SVCHlpMsg::OK:
1077 {
1078 /* no parameters */
1079 rc = S_OK;
1080 endLoop = true;
1081 break;
1082 }
1083 case SVCHlpMsg::Error:
1084 {
1085 /* read the error message */
1086 Utf8Str errMsg;
1087 vrc = aClient->read (errMsg);
1088 if (RT_FAILURE (vrc)) break;
1089
1090 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1091 endLoop = true;
1092 break;
1093 }
1094 default:
1095 {
1096 endLoop = true;
1097 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1098 //"Invalid message code %d (%08lX)\n",
1099 //reply, reply),
1100 //rc = E_FAIL);
1101 }
1102 }
1103 }
1104
1105 break;
1106 }
1107 case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
1108 {
1109 LogFlowFunc (("EnableDynamicIpConfig:\n"));
1110 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1111
1112 /* write message and parameters */
1113 vrc = aClient->write (d->msgCode);
1114 if (RT_FAILURE (vrc)) break;
1115 vrc = aClient->write (d->guid);
1116 if (RT_FAILURE (vrc)) break;
1117
1118 /* wait for a reply */
1119 bool endLoop = false;
1120 while (!endLoop)
1121 {
1122 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1123
1124 vrc = aClient->read (reply);
1125 if (RT_FAILURE (vrc)) break;
1126
1127 switch (reply)
1128 {
1129 case SVCHlpMsg::OK:
1130 {
1131 /* no parameters */
1132 rc = d->iface->updateConfig();
1133 endLoop = true;
1134 break;
1135 }
1136 case SVCHlpMsg::Error:
1137 {
1138 /* read the error message */
1139 Utf8Str errMsg;
1140 vrc = aClient->read (errMsg);
1141 if (RT_FAILURE (vrc)) break;
1142
1143 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1144 endLoop = true;
1145 break;
1146 }
1147 default:
1148 {
1149 endLoop = true;
1150 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1151 //"Invalid message code %d (%08lX)\n",
1152 //reply, reply),
1153 //rc = E_FAIL);
1154 }
1155 }
1156 }
1157
1158 break;
1159 }
1160 case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
1161 {
1162 LogFlowFunc (("EnableStaticIpConfig:\n"));
1163 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1164
1165 /* write message and parameters */
1166 vrc = aClient->write (d->msgCode);
1167 if (RT_FAILURE (vrc)) break;
1168 vrc = aClient->write (d->guid);
1169 if (RT_FAILURE (vrc)) break;
1170 vrc = aClient->write (d->u.StaticIP.IPAddress);
1171 if (RT_FAILURE (vrc)) break;
1172 vrc = aClient->write (d->u.StaticIP.IPNetMask);
1173 if (RT_FAILURE (vrc)) break;
1174
1175 /* wait for a reply */
1176 bool endLoop = false;
1177 while (!endLoop)
1178 {
1179 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1180
1181 vrc = aClient->read (reply);
1182 if (RT_FAILURE (vrc)) break;
1183
1184 switch (reply)
1185 {
1186 case SVCHlpMsg::OK:
1187 {
1188 /* no parameters */
1189 rc = d->iface->updateConfig();
1190 endLoop = true;
1191 break;
1192 }
1193 case SVCHlpMsg::Error:
1194 {
1195 /* read the error message */
1196 Utf8Str errMsg;
1197 vrc = aClient->read (errMsg);
1198 if (RT_FAILURE (vrc)) break;
1199
1200 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1201 endLoop = true;
1202 break;
1203 }
1204 default:
1205 {
1206 endLoop = true;
1207 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1208 //"Invalid message code %d (%08lX)\n",
1209 //reply, reply),
1210 //rc = E_FAIL);
1211 }
1212 }
1213 }
1214
1215 break;
1216 }
1217 case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
1218 {
1219 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
1220 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1221
1222 /* write message and parameters */
1223 vrc = aClient->write (d->msgCode);
1224 if (RT_FAILURE (vrc)) break;
1225 vrc = aClient->write (d->guid);
1226 if (RT_FAILURE (vrc)) break;
1227 vrc = aClient->write (Utf8Str(d->u.StaticIPV6.IPV6Address));
1228 if (RT_FAILURE (vrc)) break;
1229 vrc = aClient->write (d->u.StaticIPV6.IPV6NetMaskLength);
1230 if (RT_FAILURE (vrc)) break;
1231
1232 /* wait for a reply */
1233 bool endLoop = false;
1234 while (!endLoop)
1235 {
1236 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1237
1238 vrc = aClient->read (reply);
1239 if (RT_FAILURE (vrc)) break;
1240
1241 switch (reply)
1242 {
1243 case SVCHlpMsg::OK:
1244 {
1245 /* no parameters */
1246 rc = d->iface->updateConfig();
1247 endLoop = true;
1248 break;
1249 }
1250 case SVCHlpMsg::Error:
1251 {
1252 /* read the error message */
1253 Utf8Str errMsg;
1254 vrc = aClient->read (errMsg);
1255 if (RT_FAILURE (vrc)) break;
1256
1257 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1258 endLoop = true;
1259 break;
1260 }
1261 default:
1262 {
1263 endLoop = true;
1264 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1265 //"Invalid message code %d (%08lX)\n",
1266 //reply, reply),
1267 //rc = E_FAIL);
1268 }
1269 }
1270 }
1271
1272 break;
1273 }
1274 case SVCHlpMsg::DhcpRediscover: /* see usage in code */
1275 {
1276 LogFlowFunc (("DhcpRediscover:\n"));
1277 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
1278
1279 /* write message and parameters */
1280 vrc = aClient->write (d->msgCode);
1281 if (RT_FAILURE (vrc)) break;
1282 vrc = aClient->write (d->guid);
1283 if (RT_FAILURE (vrc)) break;
1284
1285 /* wait for a reply */
1286 bool endLoop = false;
1287 while (!endLoop)
1288 {
1289 SVCHlpMsg::Code reply = SVCHlpMsg::Null;
1290
1291 vrc = aClient->read (reply);
1292 if (RT_FAILURE (vrc)) break;
1293
1294 switch (reply)
1295 {
1296 case SVCHlpMsg::OK:
1297 {
1298 /* no parameters */
1299 rc = d->iface->updateConfig();
1300 endLoop = true;
1301 break;
1302 }
1303 case SVCHlpMsg::Error:
1304 {
1305 /* read the error message */
1306 Utf8Str errMsg;
1307 vrc = aClient->read (errMsg);
1308 if (RT_FAILURE (vrc)) break;
1309
1310 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg);
1311 endLoop = true;
1312 break;
1313 }
1314 default:
1315 {
1316 endLoop = true;
1317 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1318 //"Invalid message code %d (%08lX)\n",
1319 //reply, reply),
1320 //rc = E_FAIL);
1321 }
1322 }
1323 }
1324
1325 break;
1326 }
1327 default:
1328 rc = E_FAIL; // TODO: ComAssertMsgFailedBreak ((
1329// "Invalid message code %d (%08lX)\n",
1330// d->msgCode, d->msgCode),
1331// rc = E_FAIL);
1332 }
1333
1334 if (aVrc)
1335 *aVrc = vrc;
1336
1337 LogFlowFunc (("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
1338 LogFlowFuncLeave();
1339 return rc;
1340}
1341
1342
1343/* The original source of the VBoxTAP adapter creation/destruction code has the following copyright */
1344/*
1345 Copyright 2004 by the Massachusetts Institute of Technology
1346
1347 All rights reserved.
1348
1349 Permission to use, copy, modify, and distribute this software and its
1350 documentation for any purpose and without fee is hereby granted,
1351 provided that the above copyright notice appear in all copies and that
1352 both that copyright notice and this permission notice appear in
1353 supporting documentation, and that the name of the Massachusetts
1354 Institute of Technology (M.I.T.) not be used in advertising or publicity
1355 pertaining to distribution of the software without specific, written
1356 prior permission.
1357
1358 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1359 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1360 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1361 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1362 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1363 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1364 SOFTWARE.
1365*/
1366
1367
1368#define DRIVERHWID _T("sun_VBoxNetAdp")
1369
1370#define SetErrBreak(strAndArgs) \
1371 if (1) { \
1372 aErrMsg = Utf8StrFmt strAndArgs; vrc = VERR_GENERAL_FAILURE; break; \
1373 } else do {} while (0)
1374
1375/* static */
1376static int createNetworkInterface (SVCHlpClient *aClient,
1377 BSTR * pName,
1378 Guid &aGUID, Utf8Str &aErrMsg)
1379{
1380 LogFlowFuncEnter();
1381// LogFlowFunc (("Network connection name = '%s'\n", aName.raw()));
1382
1383 AssertReturn (aClient, VERR_INVALID_POINTER);
1384// AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER);
1385
1386 int vrc = VINF_SUCCESS;
1387
1388 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1389 SP_DEVINFO_DATA DeviceInfoData;
1390 DWORD ret = 0;
1391 BOOL found = FALSE;
1392 BOOL registered = FALSE;
1393 BOOL destroyList = FALSE;
1394 TCHAR pCfgGuidString [50];
1395
1396 do
1397 {
1398 BOOL ok;
1399 GUID netGuid;
1400 SP_DRVINFO_DATA DriverInfoData;
1401 SP_DEVINSTALL_PARAMS DeviceInstallParams;
1402 TCHAR className [MAX_PATH];
1403 DWORD index = 0;
1404 PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
1405 /* for our purposes, 2k buffer is more
1406 * than enough to obtain the hardware ID
1407 * of the VBoxTAP driver. */
1408 DWORD detailBuf [2048];
1409
1410 HKEY hkey = NULL;
1411 DWORD cbSize;
1412 DWORD dwValueType;
1413
1414 /* initialize the structure size */
1415 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
1416 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
1417
1418 /* copy the net class GUID */
1419 memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
1420
1421 /* create an empty device info set associated with the net class GUID */
1422 hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);
1423 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1424 SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
1425 GetLastError()));
1426
1427 /* get the class name from GUID */
1428 ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
1429 if (!ok)
1430 SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
1431 GetLastError()));
1432
1433 /* create a device info element and add the new device instance
1434 * key to registry */
1435 ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
1436 DICD_GENERATE_ID, &DeviceInfoData);
1437 if (!ok)
1438 SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
1439 GetLastError()));
1440
1441 /* select the newly created device info to be the currently
1442 selected member */
1443 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1444 if (!ok)
1445 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1446 GetLastError()));
1447
1448 /* build a list of class drivers */
1449 ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
1450 SPDIT_CLASSDRIVER);
1451 if (!ok)
1452 SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
1453 GetLastError()));
1454
1455 destroyList = TRUE;
1456
1457 /* enumerate the driver info list */
1458 while (TRUE)
1459 {
1460 BOOL ret;
1461
1462 ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
1463 SPDIT_CLASSDRIVER, index, &DriverInfoData);
1464
1465 /* if the function failed and GetLastError() returned
1466 * ERROR_NO_MORE_ITEMS, then we have reached the end of the
1467 * list. Othewise there was something wrong with this
1468 * particular driver. */
1469 if (!ret)
1470 {
1471 if(GetLastError() == ERROR_NO_MORE_ITEMS)
1472 break;
1473 else
1474 {
1475 index++;
1476 continue;
1477 }
1478 }
1479
1480 pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
1481 pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
1482
1483 /* if we successfully find the hardware ID and it turns out to
1484 * be the one for the loopback driver, then we are done. */
1485 if (SetupDiGetDriverInfoDetail (hDeviceInfo,
1486 &DeviceInfoData,
1487 &DriverInfoData,
1488 pDriverInfoDetail,
1489 sizeof (detailBuf),
1490 NULL))
1491 {
1492 TCHAR * t;
1493
1494 /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
1495 * whole list and see if there is a match somewhere. */
1496 t = pDriverInfoDetail->HardwareID;
1497 while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1498 {
1499 if (!_tcsicmp(t, DRIVERHWID))
1500 break;
1501
1502 t += _tcslen(t) + 1;
1503 }
1504
1505 if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)])
1506 {
1507 found = TRUE;
1508 break;
1509 }
1510 }
1511
1512 index ++;
1513 }
1514
1515 if (!found)
1516 SetErrBreak (("Could not find Host Interface Networking driver! "
1517 "Please reinstall"));
1518
1519 /* set the loopback driver to be the currently selected */
1520 ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
1521 &DriverInfoData);
1522 if (!ok)
1523 SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)",
1524 GetLastError()));
1525
1526 /* register the phantom device to prepare for install */
1527 ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
1528 &DeviceInfoData);
1529 if (!ok)
1530 SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
1531 GetLastError()));
1532
1533 /* registered, but remove if errors occur in the following code */
1534 registered = TRUE;
1535
1536 /* ask the installer if we can install the device */
1537 ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
1538 &DeviceInfoData);
1539 if (!ok)
1540 {
1541 if (GetLastError() != ERROR_DI_DO_DEFAULT)
1542 SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
1543 GetLastError()));
1544 /* that's fine */
1545 }
1546
1547 /* install the files first */
1548 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
1549 &DeviceInfoData);
1550 if (!ok)
1551 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
1552 GetLastError()));
1553
1554 /* get the device install parameters and disable filecopy */
1555 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
1556 ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1557 &DeviceInstallParams);
1558 if (ok)
1559 {
1560 DeviceInstallParams.Flags |= DI_NOFILECOPY;
1561 ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
1562 &DeviceInstallParams);
1563 if (!ok)
1564 SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
1565 GetLastError()));
1566 }
1567
1568 /*
1569 * Register any device-specific co-installers for this device,
1570 */
1571
1572 ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,
1573 hDeviceInfo,
1574 &DeviceInfoData);
1575 if (!ok)
1576 SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
1577 GetLastError()));
1578
1579 /*
1580 * install any installer-specified interfaces.
1581 * and then do the real install
1582 */
1583 ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,
1584 hDeviceInfo,
1585 &DeviceInfoData);
1586 if (!ok)
1587 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
1588 GetLastError()));
1589
1590 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,
1591 hDeviceInfo,
1592 &DeviceInfoData);
1593 if (!ok)
1594 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
1595 GetLastError()));
1596
1597 /* Figure out NetCfgInstanceId */
1598 hkey = SetupDiOpenDevRegKey (hDeviceInfo,
1599 &DeviceInfoData,
1600 DICS_FLAG_GLOBAL,
1601 0,
1602 DIREG_DRV,
1603 KEY_READ);
1604 if (hkey == INVALID_HANDLE_VALUE)
1605 SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",
1606 GetLastError()));
1607
1608 cbSize = sizeof (pCfgGuidString);
1609 DWORD ret;
1610 ret = RegQueryValueEx (hkey, _T("NetCfgInstanceId"), NULL,
1611 &dwValueType, (LPBYTE) pCfgGuidString, &cbSize);
1612 RegCloseKey (hkey);
1613 }
1614 while (0);
1615
1616 /*
1617 * cleanup
1618 */
1619
1620 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1621 {
1622 /* an error has occured, but the device is registered, we must remove it */
1623 if (ret != 0 && registered)
1624 SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1625
1626 found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);
1627
1628 /* destroy the driver info list */
1629 if (destroyList)
1630 SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,
1631 SPDIT_CLASSDRIVER);
1632 /* clean up the device info set */
1633 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1634 }
1635
1636 /* return the network connection GUID on success */
1637 if (RT_SUCCESS (vrc))
1638 {
1639 /* remove the curly bracket at the end */
1640 pCfgGuidString [_tcslen (pCfgGuidString) - 1] = '\0';
1641 LogFlowFunc (("Network connection GUID string = {%ls}\n", pCfgGuidString + 1));
1642
1643 aGUID = Guid (Utf8Str (pCfgGuidString + 1));
1644 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1645 Assert (!aGUID.isEmpty());
1646
1647 INetCfg *pNc;
1648 INetCfgComponent *pMpNcc;
1649 LPWSTR lpszApp;
1650
1651 HRESULT hr = VBoxNetCfgWinQueryINetCfg( FALSE,
1652 VBOX_APP_NAME,
1653 &pNc,
1654 &lpszApp );
1655 if(hr == S_OK)
1656 {
1657 hr = VBoxNetCfgWinGetComponentByGuid(pNc,
1658 &GUID_DEVCLASS_NET,
1659 aGUID.asOutParam(),
1660 &pMpNcc);
1661 if(hr == S_OK)
1662 {
1663 LPWSTR name;
1664 hr = pMpNcc->GetDisplayName(&name);
1665 if(hr == S_OK)
1666 {
1667 Bstr str(name);
1668 str.detachTo(pName);
1669 WCHAR ConnectoinName[128];
1670 ULONG cbBuf = sizeof(ConnectoinName);
1671
1672 hr = VBoxNetCfgWinGenHostonlyConnectionName (name, ConnectoinName, &cbBuf);
1673 if(hr == S_OK)
1674 {
1675 hr = VBoxNetCfgWinRenameConnection ((GUID*)aGUID.raw(), ConnectoinName);
1676 }
1677
1678 CoTaskMemFree (name);
1679 }
1680
1681 VBoxNetCfgWinReleaseRef(pMpNcc);
1682 }
1683 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
1684 }
1685
1686 if(hr != S_OK)
1687 {
1688 vrc = VERR_GENERAL_FAILURE;
1689 }
1690
1691 }
1692
1693 LogFlowFunc (("vrc=%Rrc\n", vrc));
1694 LogFlowFuncLeave();
1695 return vrc;
1696}
1697
1698/* static */
1699static int removeNetworkInterface (SVCHlpClient *aClient,
1700 const Guid &aGUID,
1701 Utf8Str &aErrMsg)
1702{
1703 LogFlowFuncEnter();
1704 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));
1705
1706 AssertReturn (aClient, VERR_INVALID_POINTER);
1707 AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);
1708
1709 int vrc = VINF_SUCCESS;
1710
1711 do
1712 {
1713 TCHAR lszPnPInstanceId [512] = {0};
1714
1715 /* We have to find the device instance ID through a registry search */
1716
1717 HKEY hkeyNetwork = 0;
1718 HKEY hkeyConnection = 0;
1719
1720 do
1721 {
1722 char strRegLocation [256];
1723 sprintf (strRegLocation,
1724 "SYSTEM\\CurrentControlSet\\Control\\Network\\"
1725 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}",
1726 aGUID.toString().raw());
1727 LONG status;
1728 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0,
1729 KEY_READ, &hkeyNetwork);
1730 if ((status != ERROR_SUCCESS) || !hkeyNetwork)
1731 SetErrBreak ((
1732 "Host interface network is not found in registry (%s) [1]",
1733 strRegLocation));
1734
1735 status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,
1736 KEY_READ, &hkeyConnection);
1737 if ((status != ERROR_SUCCESS) || !hkeyConnection)
1738 SetErrBreak ((
1739 "Host interface network is not found in registry (%s) [2]",
1740 strRegLocation));
1741
1742 DWORD len = sizeof (lszPnPInstanceId);
1743 DWORD dwKeyType;
1744 status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
1745 &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
1746 if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
1747 SetErrBreak ((
1748 "Host interface network is not found in registry (%s) [3]",
1749 strRegLocation));
1750 }
1751 while (0);
1752
1753 if (hkeyConnection)
1754 RegCloseKey (hkeyConnection);
1755 if (hkeyNetwork)
1756 RegCloseKey (hkeyNetwork);
1757
1758 if (RT_FAILURE (vrc))
1759 break;
1760
1761 /*
1762 * Now we are going to enumerate all network devices and
1763 * wait until we encounter the right device instance ID
1764 */
1765
1766 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
1767
1768 do
1769 {
1770 BOOL ok;
1771 DWORD ret = 0;
1772 GUID netGuid;
1773 SP_DEVINFO_DATA DeviceInfoData;
1774 DWORD index = 0;
1775 BOOL found = FALSE;
1776 DWORD size = 0;
1777
1778 /* initialize the structure size */
1779 DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
1780
1781 /* copy the net class GUID */
1782 memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
1783
1784 /* return a device info set contains all installed devices of the Net class */
1785 hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
1786
1787 if (hDeviceInfo == INVALID_HANDLE_VALUE)
1788 SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
1789
1790 /* enumerate the driver info list */
1791 while (TRUE)
1792 {
1793 TCHAR *deviceHwid;
1794
1795 ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
1796
1797 if (!ok)
1798 {
1799 if (GetLastError() == ERROR_NO_MORE_ITEMS)
1800 break;
1801 else
1802 {
1803 index++;
1804 continue;
1805 }
1806 }
1807
1808 /* try to get the hardware ID registry property */
1809 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1810 &DeviceInfoData,
1811 SPDRP_HARDWAREID,
1812 NULL,
1813 NULL,
1814 0,
1815 &size);
1816 if (!ok)
1817 {
1818 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1819 {
1820 index++;
1821 continue;
1822 }
1823
1824 deviceHwid = (TCHAR *) malloc (size);
1825 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
1826 &DeviceInfoData,
1827 SPDRP_HARDWAREID,
1828 NULL,
1829 (PBYTE)deviceHwid,
1830 size,
1831 NULL);
1832 if (!ok)
1833 {
1834 free (deviceHwid);
1835 deviceHwid = NULL;
1836 index++;
1837 continue;
1838 }
1839 }
1840 else
1841 {
1842 /* something is wrong. This shouldn't have worked with a NULL buffer */
1843 index++;
1844 continue;
1845 }
1846
1847 for (TCHAR *t = deviceHwid;
1848 t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
1849 t += _tcslen (t) + 1)
1850 {
1851 if (!_tcsicmp (DRIVERHWID, t))
1852 {
1853 /* get the device instance ID */
1854 TCHAR devID [MAX_DEVICE_ID_LEN];
1855 if (CM_Get_Device_ID(DeviceInfoData.DevInst,
1856 devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
1857 {
1858 /* compare to what we determined before */
1859 if (wcscmp(devID, lszPnPInstanceId) == 0)
1860 {
1861 found = TRUE;
1862 break;
1863 }
1864 }
1865 }
1866 }
1867
1868 if (deviceHwid)
1869 {
1870 free (deviceHwid);
1871 deviceHwid = NULL;
1872 }
1873
1874 if (found)
1875 break;
1876
1877 index++;
1878 }
1879
1880 if (found == FALSE)
1881 SetErrBreak (("Host Interface Network driver not found (0x%08X)",
1882 GetLastError()));
1883
1884 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
1885 if (!ok)
1886 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
1887 GetLastError()));
1888
1889 ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
1890 if (!ok)
1891 SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
1892 GetLastError()));
1893 }
1894 while (0);
1895
1896 /* clean up the device info set */
1897 if (hDeviceInfo != INVALID_HANDLE_VALUE)
1898 SetupDiDestroyDeviceInfoList (hDeviceInfo);
1899
1900 if (RT_FAILURE (vrc))
1901 break;
1902 }
1903 while (0);
1904
1905 LogFlowFunc (("vrc=%Rrc\n", vrc));
1906 LogFlowFuncLeave();
1907 return vrc;
1908}
1909
1910#undef SetErrBreak
1911
1912int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient,
1913 SVCHlpMsg::Code aMsgCode)
1914{
1915 LogFlowFuncEnter();
1916 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
1917
1918 AssertReturn (aClient, VERR_INVALID_POINTER);
1919
1920 int vrc = VINF_SUCCESS;
1921
1922 switch (aMsgCode)
1923 {
1924 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
1925 {
1926 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));
1927
1928// Utf8Str name;
1929// vrc = aClient->read (name);
1930// if (RT_FAILURE (vrc)) break;
1931
1932 Guid guid;
1933 Utf8Str errMsg;
1934 Bstr name;
1935 vrc = createNetworkInterface (aClient, name.asOutParam(), guid, errMsg);
1936
1937 if (RT_SUCCESS (vrc))
1938 {
1939 /* write success followed by GUID */
1940 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
1941 if (RT_FAILURE (vrc)) break;
1942 vrc = aClient->write (Utf8Str (name));
1943 if (RT_FAILURE (vrc)) break;
1944 vrc = aClient->write (guid);
1945 if (RT_FAILURE (vrc)) break;
1946 }
1947 else
1948 {
1949 /* write failure followed by error message */
1950 if (errMsg.isEmpty())
1951 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1952 vrc = aClient->write (SVCHlpMsg::Error);
1953 if (RT_FAILURE (vrc)) break;
1954 vrc = aClient->write (errMsg);
1955 if (RT_FAILURE (vrc)) break;
1956 }
1957
1958 break;
1959 }
1960 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
1961 {
1962 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));
1963
1964 Guid guid;
1965 vrc = aClient->read (guid);
1966 if (RT_FAILURE (vrc)) break;
1967
1968 Utf8Str errMsg;
1969 vrc = removeNetworkInterface (aClient, guid, errMsg);
1970
1971 if (RT_SUCCESS (vrc))
1972 {
1973 /* write parameter-less success */
1974 vrc = aClient->write (SVCHlpMsg::OK);
1975 if (RT_FAILURE (vrc)) break;
1976 }
1977 else
1978 {
1979 /* write failure followed by error message */
1980 if (errMsg.isEmpty())
1981 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
1982 vrc = aClient->write (SVCHlpMsg::Error);
1983 if (RT_FAILURE (vrc)) break;
1984 vrc = aClient->write (errMsg);
1985 if (RT_FAILURE (vrc)) break;
1986 }
1987
1988 break;
1989 }
1990 case SVCHlpMsg::EnableStaticIpConfigV6:
1991 {
1992 LogFlowFunc (("EnableStaticIpConfigV6:\n"));
1993
1994 Guid guid;
1995 Utf8Str ipV6;
1996 ULONG maskLengthV6;
1997 vrc = aClient->read (guid);
1998 if (RT_FAILURE (vrc)) break;
1999 vrc = aClient->read (ipV6);
2000 if (RT_FAILURE (vrc)) break;
2001 vrc = aClient->read (maskLengthV6);
2002 if (RT_FAILURE (vrc)) break;
2003
2004 Utf8Str errMsg;
2005 vrc = netIfEnableStaticIpConfigV6 (guid, Bstr(ipV6), maskLengthV6);
2006
2007 if (RT_SUCCESS (vrc))
2008 {
2009 /* write success followed by GUID */
2010 vrc = aClient->write (SVCHlpMsg::OK);
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::EnableStaticIpConfig:
2027 {
2028 LogFlowFunc (("EnableStaticIpConfig:\n"));
2029
2030 Guid guid;
2031 ULONG ip, mask;
2032 vrc = aClient->read (guid);
2033 if (RT_FAILURE (vrc)) break;
2034 vrc = aClient->read (ip);
2035 if (RT_FAILURE (vrc)) break;
2036 vrc = aClient->read (mask);
2037 if (RT_FAILURE (vrc)) break;
2038
2039 Utf8Str errMsg;
2040 vrc = netIfEnableStaticIpConfig (guid, ip, mask);
2041
2042 if (RT_SUCCESS (vrc))
2043 {
2044 /* write success followed by GUID */
2045 vrc = aClient->write (SVCHlpMsg::OK);
2046 if (RT_FAILURE (vrc)) break;
2047 }
2048 else
2049 {
2050 /* write failure followed by error message */
2051 if (errMsg.isEmpty())
2052 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2053 vrc = aClient->write (SVCHlpMsg::Error);
2054 if (RT_FAILURE (vrc)) break;
2055 vrc = aClient->write (errMsg);
2056 if (RT_FAILURE (vrc)) break;
2057 }
2058
2059 break;
2060 }
2061 case SVCHlpMsg::EnableDynamicIpConfig:
2062 {
2063 LogFlowFunc (("EnableDynamicIpConfig:\n"));
2064
2065 Guid guid;
2066 vrc = aClient->read (guid);
2067 if (RT_FAILURE (vrc)) break;
2068
2069 Utf8Str errMsg;
2070 vrc = netIfEnableDynamicIpConfig (guid);
2071
2072 if (RT_SUCCESS (vrc))
2073 {
2074 /* write success followed by GUID */
2075 vrc = aClient->write (SVCHlpMsg::OK);
2076 if (RT_FAILURE (vrc)) break;
2077 }
2078 else
2079 {
2080 /* write failure followed by error message */
2081 if (errMsg.isEmpty())
2082 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2083 vrc = aClient->write (SVCHlpMsg::Error);
2084 if (RT_FAILURE (vrc)) break;
2085 vrc = aClient->write (errMsg);
2086 if (RT_FAILURE (vrc)) break;
2087 }
2088
2089 break;
2090 }
2091 case SVCHlpMsg::DhcpRediscover:
2092 {
2093 LogFlowFunc (("DhcpRediscover:\n"));
2094
2095 Guid guid;
2096 vrc = aClient->read (guid);
2097 if (RT_FAILURE (vrc)) break;
2098
2099 Utf8Str errMsg;
2100 vrc = netIfDhcpRediscover (guid);
2101
2102 if (RT_SUCCESS (vrc))
2103 {
2104 /* write success followed by GUID */
2105 vrc = aClient->write (SVCHlpMsg::OK);
2106 if (RT_FAILURE (vrc)) break;
2107 }
2108 else
2109 {
2110 /* write failure followed by error message */
2111 if (errMsg.isEmpty())
2112 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);
2113 vrc = aClient->write (SVCHlpMsg::Error);
2114 if (RT_FAILURE (vrc)) break;
2115 vrc = aClient->write (errMsg);
2116 if (RT_FAILURE (vrc)) break;
2117 }
2118
2119 break;
2120 }
2121 default:
2122 AssertMsgFailedBreakStmt (
2123 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
2124 VERR_GENERAL_FAILURE);
2125 }
2126
2127 LogFlowFunc (("vrc=%Rrc\n", vrc));
2128 LogFlowFuncLeave();
2129 return vrc;
2130}
2131
2132/** @todo REMOVE. OBSOLETE NOW. */
2133/**
2134 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
2135 * later OSes) and it has the UAC (User Account Control) feature enabled.
2136 */
2137static BOOL IsUACEnabled()
2138{
2139 LONG rc = 0;
2140
2141 OSVERSIONINFOEX info;
2142 ZeroMemory (&info, sizeof (OSVERSIONINFOEX));
2143 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
2144 rc = GetVersionEx ((OSVERSIONINFO *) &info);
2145 AssertReturn (rc != 0, FALSE);
2146
2147 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",
2148 info.dwMajorVersion, info.dwMinorVersion));
2149
2150 /* we are interested only in Vista (and newer versions...). In all
2151 * earlier versions UAC is not present. */
2152 if (info.dwMajorVersion < 6)
2153 return FALSE;
2154
2155 /* the default EnableLUA value is 1 (Enabled) */
2156 DWORD dwEnableLUA = 1;
2157
2158 HKEY hKey;
2159 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
2160 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
2161 0, KEY_QUERY_VALUE, &hKey);
2162
2163 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
2164 if (rc == ERROR_SUCCESS)
2165 {
2166
2167 DWORD cbEnableLUA = sizeof (dwEnableLUA);
2168 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,
2169 (LPBYTE) &dwEnableLUA, &cbEnableLUA);
2170
2171 RegCloseKey (hKey);
2172
2173 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
2174 }
2175
2176 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
2177
2178 return dwEnableLUA == 1;
2179}
2180
2181/* end */
2182
2183static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
2184{
2185 LPWSTR lpszName;
2186 GUID IfGuid;
2187 HRESULT hr;
2188 int rc = VERR_GENERAL_FAILURE;
2189
2190 hr = pncc->GetDisplayName( &lpszName );
2191 Assert(hr == S_OK);
2192 if(hr == S_OK)
2193 {
2194 size_t cUnicodeName = wcslen(lpszName) + 1;
2195 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
2196 Bstr name (uniLen + 1 /* extra zero */);
2197 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
2198
2199 hr = pncc->GetInstanceGuid(&IfGuid);
2200 Assert(hr == S_OK);
2201 if (hr == S_OK)
2202 {
2203 NETIFINFO Info;
2204 memset(&Info, 0, sizeof(Info));
2205 Info.Uuid = *(Guid(IfGuid).raw());
2206 rc = collectNetIfInfo(name, Guid(IfGuid), &Info);
2207 if (RT_FAILURE(rc))
2208 {
2209 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
2210 }
2211 /* create a new object and add it to the list */
2212 ComObjPtr <HostNetworkInterface> iface;
2213 iface.createObject();
2214 /* remove the curly bracket at the end */
2215 if (SUCCEEDED (iface->init (name, enmType, &Info)))
2216 {
2217 pPist->push_back (iface);
2218 rc = VINF_SUCCESS;
2219 }
2220 else
2221 {
2222 Assert(0);
2223 }
2224 }
2225 CoTaskMemFree(lpszName);
2226 }
2227
2228 return rc;
2229}
2230
2231#endif /* VBOX_WITH_NETFLT */
2232
2233
2234static int netIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
2235{
2236#ifndef VBOX_WITH_NETFLT
2237 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
2238 return VERR_NOT_IMPLEMENTED;
2239#else /* # if defined VBOX_WITH_NETFLT */
2240 INetCfg *pNc;
2241 INetCfgComponent *pMpNcc;
2242 LPWSTR lpszApp = NULL;
2243 HRESULT hr;
2244 IEnumNetCfgComponent *pEnumComponent;
2245
2246 /* we are using the INetCfg API for getting the list of miniports */
2247 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2248 VBOX_APP_NAME,
2249 &pNc,
2250 &lpszApp );
2251 Assert(hr == S_OK);
2252 if(hr == S_OK)
2253 {
2254 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
2255 if(hr == S_OK)
2256 {
2257 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
2258 {
2259 ULONG uComponentStatus;
2260 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2261//#ifndef DEBUG_bird
2262// Assert(hr == S_OK);
2263//#endif
2264 if(hr == S_OK)
2265 {
2266 if(uComponentStatus == 0)
2267 {
2268 LPWSTR pId;
2269 hr = pMpNcc->GetId(&pId);
2270 Assert(hr == S_OK);
2271 if(hr == S_OK)
2272 {
2273 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
2274 {
2275 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
2276 }
2277 CoTaskMemFree(pId);
2278 }
2279 }
2280 }
2281 VBoxNetCfgWinReleaseRef(pMpNcc);
2282 }
2283 Assert(hr == S_OK || hr == S_FALSE);
2284
2285 VBoxNetCfgWinReleaseRef(pEnumComponent);
2286 }
2287 else
2288 {
2289 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2290 }
2291
2292 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2293 }
2294 else if(lpszApp)
2295 {
2296 CoTaskMemFree(lpszApp);
2297 }
2298#endif /* # if defined VBOX_WITH_NETFLT */
2299 return VINF_SUCCESS;
2300}
2301
2302int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
2303{
2304#ifndef VBOX_WITH_NETFLT
2305 return VERR_NOT_IMPLEMENTED;
2306#else
2307 Bstr name;
2308 HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
2309 if(hr == S_OK)
2310 {
2311 GUID IfGuid;
2312 hr = pIf->COMGETTER(Id)(&IfGuid);
2313 Assert(hr == S_OK);
2314 if (hr == S_OK)
2315 {
2316 return collectNetIfInfo(name, Guid(IfGuid), pInfo);
2317 }
2318 }
2319 return VERR_GENERAL_FAILURE;
2320#endif
2321}
2322
2323int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox,
2324 IHostNetworkInterface **aHostNetworkInterface,
2325 IProgress **aProgress)
2326{
2327#ifndef VBOX_WITH_NETFLT
2328 return VERR_NOT_IMPLEMENTED;
2329#else
2330 /* create a progress object */
2331 ComObjPtr <Progress> progress;
2332 progress.createObject();
2333
2334 ComPtr<IHost> host;
2335 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2336 if(SUCCEEDED(rc))
2337 {
2338 rc = progress->init (pVBox, host,
2339 Bstr (_T ("Creating host only network interface")),
2340 FALSE /* aCancelable */);
2341 if(SUCCEEDED(rc))
2342 {
2343 CheckComRCReturnRC (rc);
2344 progress.queryInterfaceTo (aProgress);
2345
2346 /* create a new uninitialized host interface object */
2347 ComObjPtr <HostNetworkInterface> iface;
2348 iface.createObject();
2349 iface.queryInterfaceTo (aHostNetworkInterface);
2350
2351 /* create the networkInterfaceHelperClient() argument */
2352 std::auto_ptr <NetworkInterfaceHelperClientData>
2353 d (new NetworkInterfaceHelperClientData());
2354 AssertReturn (d.get(), E_OUTOFMEMORY);
2355
2356 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
2357// d->name = aName;
2358 d->iface = iface;
2359
2360 rc = pVBox->startSVCHelperClient (
2361 IsUACEnabled() == TRUE /* aPrivileged */,
2362 netIfNetworkInterfaceHelperClient,
2363 static_cast <void *> (d.get()),
2364 progress);
2365
2366 if (SUCCEEDED (rc))
2367 {
2368 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2369 d.release();
2370 }
2371 }
2372 }
2373
2374 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2375#endif
2376}
2377
2378int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVBox, IN_GUID aId,
2379 IHostNetworkInterface **aHostNetworkInterface,
2380 IProgress **aProgress)
2381{
2382#ifndef VBOX_WITH_NETFLT
2383 return VERR_NOT_IMPLEMENTED;
2384#else
2385 /* create a progress object */
2386 ComObjPtr <Progress> progress;
2387 progress.createObject();
2388 ComPtr<IHost> host;
2389 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
2390 if(SUCCEEDED(rc))
2391 {
2392 rc = progress->init (pVBox, host,
2393 Bstr (_T ("Removing host network interface")),
2394 FALSE /* aCancelable */);
2395 if(SUCCEEDED(rc))
2396 {
2397 CheckComRCReturnRC (rc);
2398 progress.queryInterfaceTo (aProgress);
2399
2400 /* create the networkInterfaceHelperClient() argument */
2401 std::auto_ptr <NetworkInterfaceHelperClientData>
2402 d (new NetworkInterfaceHelperClientData());
2403 AssertReturn (d.get(), E_OUTOFMEMORY);
2404
2405 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
2406 d->guid = aId;
2407
2408 rc = pVBox->startSVCHelperClient (
2409 IsUACEnabled() == TRUE /* aPrivileged */,
2410 netIfNetworkInterfaceHelperClient,
2411 static_cast <void *> (d.get()),
2412 progress);
2413
2414 if (SUCCEEDED (rc))
2415 {
2416 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2417 d.release();
2418 }
2419 }
2420 }
2421
2422 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2423#endif
2424}
2425
2426int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
2427{
2428#ifndef VBOX_WITH_NETFLT
2429 return VERR_NOT_IMPLEMENTED;
2430#else
2431 HRESULT rc;
2432 GUID guid;
2433 rc = pIf->COMGETTER(Id) (&guid);
2434 if(SUCCEEDED(rc))
2435 {
2436// ComPtr<VirtualBox> vBox;
2437// rc = pIf->getVirtualBox (vBox.asOutParam());
2438// if(SUCCEEDED(rc))
2439 {
2440 /* create a progress object */
2441 ComObjPtr <Progress> progress;
2442 progress.createObject();
2443// ComPtr<IHost> host;
2444// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2445// if(SUCCEEDED(rc))
2446 {
2447 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2448 Bstr ("Enabling Dynamic Ip Configuration"),
2449 FALSE /* aCancelable */);
2450 if(SUCCEEDED(rc))
2451 {
2452 CheckComRCReturnRC (rc);
2453// progress.queryInterfaceTo (aProgress);
2454
2455 /* create the networkInterfaceHelperClient() argument */
2456 std::auto_ptr <NetworkInterfaceHelperClientData>
2457 d (new NetworkInterfaceHelperClientData());
2458 AssertReturn (d.get(), E_OUTOFMEMORY);
2459
2460 d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
2461 d->guid = guid;
2462 d->iface = pIf;
2463 d->u.StaticIP.IPAddress = ip;
2464 d->u.StaticIP.IPNetMask = mask;
2465
2466 rc = vBox->startSVCHelperClient (
2467 IsUACEnabled() == TRUE /* aPrivileged */,
2468 netIfNetworkInterfaceHelperClient,
2469 static_cast <void *> (d.get()),
2470 progress);
2471
2472 if (SUCCEEDED (rc))
2473 {
2474 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2475 d.release();
2476
2477 progress->WaitForCompletion(-1);
2478 }
2479 }
2480 }
2481 }
2482 }
2483
2484 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2485#endif
2486}
2487
2488int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
2489{
2490#ifndef VBOX_WITH_NETFLT
2491 return VERR_NOT_IMPLEMENTED;
2492#else
2493 HRESULT rc;
2494 GUID guid;
2495 rc = pIf->COMGETTER(Id) (&guid);
2496 if(SUCCEEDED(rc))
2497 {
2498// ComPtr<VirtualBox> vBox;
2499// rc = pIf->getVirtualBox (vBox.asOutParam());
2500// if(SUCCEEDED(rc))
2501 {
2502 /* create a progress object */
2503 ComObjPtr <Progress> progress;
2504 progress.createObject();
2505// ComPtr<IHost> host;
2506// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2507// if(SUCCEEDED(rc))
2508 {
2509 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2510 Bstr ("Enabling Dynamic Ip Configuration"),
2511 FALSE /* aCancelable */);
2512 if(SUCCEEDED(rc))
2513 {
2514 CheckComRCReturnRC (rc);
2515// progress.queryInterfaceTo (aProgress);
2516
2517 /* create the networkInterfaceHelperClient() argument */
2518 std::auto_ptr <NetworkInterfaceHelperClientData>
2519 d (new NetworkInterfaceHelperClientData());
2520 AssertReturn (d.get(), E_OUTOFMEMORY);
2521
2522 d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
2523 d->guid = guid;
2524 d->iface = pIf;
2525 d->u.StaticIPV6.IPV6Address = aIPV6Address;
2526 d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
2527
2528 rc = vBox->startSVCHelperClient (
2529 IsUACEnabled() == TRUE /* aPrivileged */,
2530 netIfNetworkInterfaceHelperClient,
2531 static_cast <void *> (d.get()),
2532 progress);
2533
2534 if (SUCCEEDED (rc))
2535 {
2536 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2537 d.release();
2538
2539 progress->WaitForCompletion(-1);
2540 }
2541 }
2542 }
2543 }
2544 }
2545
2546 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2547#endif
2548}
2549
2550int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
2551{
2552#ifndef VBOX_WITH_NETFLT
2553 return VERR_NOT_IMPLEMENTED;
2554#else
2555 HRESULT rc;
2556 GUID guid;
2557 rc = pIf->COMGETTER(Id) (&guid);
2558 if(SUCCEEDED(rc))
2559 {
2560// ComPtr<VirtualBox> vBox;
2561// rc = pIf->getVirtualBox (vBox.asOutParam());
2562// if(SUCCEEDED(rc))
2563 {
2564 /* create a progress object */
2565 ComObjPtr <Progress> progress;
2566 progress.createObject();
2567// ComPtr<IHost> host;
2568// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2569// if(SUCCEEDED(rc))
2570 {
2571 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2572 Bstr ("Enabling Dynamic Ip Configuration"),
2573 FALSE /* aCancelable */);
2574 if(SUCCEEDED(rc))
2575 {
2576 CheckComRCReturnRC (rc);
2577// progress.queryInterfaceTo (aProgress);
2578
2579 /* create the networkInterfaceHelperClient() argument */
2580 std::auto_ptr <NetworkInterfaceHelperClientData>
2581 d (new NetworkInterfaceHelperClientData());
2582 AssertReturn (d.get(), E_OUTOFMEMORY);
2583
2584 d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
2585 d->guid = guid;
2586 d->iface = pIf;
2587
2588 rc = vBox->startSVCHelperClient (
2589 IsUACEnabled() == TRUE /* aPrivileged */,
2590 netIfNetworkInterfaceHelperClient,
2591 static_cast <void *> (d.get()),
2592 progress);
2593
2594 if (SUCCEEDED (rc))
2595 {
2596 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2597 d.release();
2598
2599 progress->WaitForCompletion(-1);
2600 }
2601 }
2602 }
2603 }
2604 }
2605
2606 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2607#endif
2608}
2609
2610int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
2611{
2612#ifndef VBOX_WITH_NETFLT
2613 return VERR_NOT_IMPLEMENTED;
2614#else
2615 HRESULT rc;
2616 GUID guid;
2617 rc = pIf->COMGETTER(Id) (&guid);
2618 if(SUCCEEDED(rc))
2619 {
2620// ComPtr<VirtualBox> vBox;
2621// rc = pIf->getVirtualBox (vBox.asOutParam());
2622// if(SUCCEEDED(rc))
2623 {
2624 /* create a progress object */
2625 ComObjPtr <Progress> progress;
2626 progress.createObject();
2627// ComPtr<IHost> host;
2628// HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
2629// if(SUCCEEDED(rc))
2630 {
2631 rc = progress->init (vBox, (IHostNetworkInterface*)pIf,
2632 Bstr ("Enabling Dynamic Ip Configuration"),
2633 FALSE /* aCancelable */);
2634 if(SUCCEEDED(rc))
2635 {
2636 CheckComRCReturnRC (rc);
2637// progress.queryInterfaceTo (aProgress);
2638
2639 /* create the networkInterfaceHelperClient() argument */
2640 std::auto_ptr <NetworkInterfaceHelperClientData>
2641 d (new NetworkInterfaceHelperClientData());
2642 AssertReturn (d.get(), E_OUTOFMEMORY);
2643
2644 d->msgCode = SVCHlpMsg::DhcpRediscover;
2645 d->guid = guid;
2646 d->iface = pIf;
2647
2648 rc = vBox->startSVCHelperClient (
2649 IsUACEnabled() == TRUE /* aPrivileged */,
2650 netIfNetworkInterfaceHelperClient,
2651 static_cast <void *> (d.get()),
2652 progress);
2653
2654 if (SUCCEEDED (rc))
2655 {
2656 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
2657 d.release();
2658
2659 progress->WaitForCompletion(-1);
2660 }
2661 }
2662 }
2663 }
2664 }
2665
2666 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
2667#endif
2668}
2669
2670int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
2671{
2672#ifndef VBOX_WITH_NETFLT
2673 return VERR_NOT_IMPLEMENTED;
2674#else /* # if defined VBOX_WITH_NETFLT */
2675 INetCfg *pNc;
2676 INetCfgComponent *pMpNcc;
2677 INetCfgComponent *pTcpIpNcc;
2678 LPWSTR lpszApp;
2679 HRESULT hr;
2680 IEnumNetCfgBindingPath *pEnumBp;
2681 INetCfgBindingPath *pBp;
2682 IEnumNetCfgBindingInterface *pEnumBi;
2683 INetCfgBindingInterface *pBi;
2684
2685 /* we are using the INetCfg API for getting the list of miniports */
2686 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
2687 VBOX_APP_NAME,
2688 &pNc,
2689 &lpszApp );
2690 Assert(hr == S_OK);
2691 if(hr == S_OK)
2692 {
2693# ifdef VBOX_NETFLT_ONDEMAND_BIND
2694 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
2695 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
2696# else
2697 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
2698 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
2699# ifndef VBOX_WITH_HARDENING
2700 if(hr != S_OK)
2701 {
2702 /* TODO: try to install the netflt from here */
2703 }
2704# endif
2705
2706# endif
2707
2708 if(hr == S_OK)
2709 {
2710 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
2711 Assert(hr == S_OK);
2712 if ( hr == S_OK )
2713 {
2714 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
2715 Assert(hr == S_OK || hr == S_FALSE);
2716 while( hr == S_OK )
2717 {
2718 /* S_OK == enabled, S_FALSE == disabled */
2719 if(pBp->IsEnabled() == S_OK)
2720 {
2721 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
2722 Assert(hr == S_OK);
2723 if ( hr == S_OK )
2724 {
2725 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
2726 Assert(hr == S_OK);
2727 while(hr == S_OK)
2728 {
2729 hr = pBi->GetLowerComponent( &pMpNcc );
2730 Assert(hr == S_OK);
2731 if(hr == S_OK)
2732 {
2733 ULONG uComponentStatus;
2734 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
2735//#ifndef DEBUG_bird
2736// Assert(hr == S_OK);
2737//#endif
2738 if(hr == S_OK)
2739 {
2740 if(uComponentStatus == 0)
2741 {
2742 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
2743 }
2744 }
2745 VBoxNetCfgWinReleaseRef( pMpNcc );
2746 }
2747 VBoxNetCfgWinReleaseRef(pBi);
2748
2749 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
2750 }
2751 VBoxNetCfgWinReleaseRef(pEnumBi);
2752 }
2753 }
2754 VBoxNetCfgWinReleaseRef(pBp);
2755
2756 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
2757 }
2758 VBoxNetCfgWinReleaseRef(pEnumBp);
2759 }
2760 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
2761 }
2762 else
2763 {
2764 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
2765 }
2766
2767 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
2768 }
2769
2770 netIfListHostAdapters(list);
2771
2772 return VINF_SUCCESS;
2773#endif /* # if defined VBOX_WITH_NETFLT */
2774}
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