VirtualBox

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

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

burn fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.7 KB
Line 
1/* $Id: NetIfList-win.cpp 17337 2009-03-04 09:29:53Z 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 "netif.h"
48
49#ifdef VBOX_WITH_NETFLT
50#include <Wbemidl.h>
51#include <comdef.h>
52
53static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc)
54{
55 HRESULT hres;
56
57 // Step 3: ---------------------------------------------------
58 // Obtain the initial locator to WMI -------------------------
59
60 IWbemLocator *pLoc = NULL;
61
62 hres = CoCreateInstance(
63 CLSID_WbemLocator,
64 0,
65 CLSCTX_INPROC_SERVER,
66 IID_IWbemLocator, (LPVOID *) &pLoc);
67 if(SUCCEEDED(hres))
68 {
69 // Step 4: -----------------------------------------------------
70 // Connect to WMI through the IWbemLocator::ConnectServer method
71
72 IWbemServices *pSvc = NULL;
73
74 // Connect to the root\cimv2 namespace with
75 // the current user and obtain pointer pSvc
76 // to make IWbemServices calls.
77 hres = pLoc->ConnectServer(
78 _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
79 NULL, // User name. NULL = current user
80 NULL, // User password. NULL = current
81 0, // Locale. NULL indicates current
82 NULL, // Security flags.
83 0, // Authority (e.g. Kerberos)
84 0, // Context object
85 &pSvc // pointer to IWbemServices proxy
86 );
87 if(SUCCEEDED(hres))
88 {
89 LogRel(("Connected to ROOT\\CIMV2 WMI namespace\n"));
90
91 // Step 5: --------------------------------------------------
92 // Set security levels on the proxy -------------------------
93
94 hres = CoSetProxyBlanket(
95 pSvc, // Indicates the proxy to set
96 RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
97 RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
98 NULL, // Server principal name
99 RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
100 RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
101 NULL, // client identity
102 EOAC_NONE // proxy capabilities
103 );
104 if(SUCCEEDED(hres))
105 {
106 *ppSvc = pSvc;
107 /* do not need it any more */
108 pLoc->Release();
109 return hres;
110 }
111 else
112 {
113 LogRel(("Could not set proxy blanket. Error code = 0x%x\n", hres));
114 }
115
116 pSvc->Release();
117 }
118 else
119 {
120 LogRel(("Could not connect. Error code = 0x%x\n", hres));
121 }
122
123 pLoc->Release();
124 }
125 else
126 {
127 LogRel(("Failed to create IWbemLocator object. Err code = 0x%x\n", hres));
128// CoUninitialize();
129 }
130
131 return hres;
132}
133
134static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, GUID * pGuid, IWbemClassObject **pAdapterConfig)
135{
136 HRESULT hres;
137 WCHAR aQueryString[256];
138 char uuidStr[RTUUID_STR_LENGTH];
139 int rc = RTUuidToStr((PCRTUUID)pGuid, uuidStr, sizeof(uuidStr));
140 if(RT_SUCCESS(rc))
141 {
142 swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"{%S}\"", uuidStr);
143 // Step 6: --------------------------------------------------
144 // Use the IWbemServices pointer to make requests of WMI ----
145
146 IEnumWbemClassObject* pEnumerator = NULL;
147 hres = pSvc->ExecQuery(
148 bstr_t("WQL"),
149 bstr_t(aQueryString),
150 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
151 NULL,
152 &pEnumerator);
153 if(SUCCEEDED(hres))
154 {
155 // Step 7: -------------------------------------------------
156 // Get the data from the query in step 6 -------------------
157
158 IWbemClassObject *pclsObj;
159 ULONG uReturn = 0;
160
161 while (pEnumerator)
162 {
163 HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
164 &pclsObj, &uReturn);
165
166 if(SUCCEEDED(hres))
167 {
168 if(uReturn)
169 {
170 pEnumerator->Release();
171 *pAdapterConfig = pclsObj;
172 hres = S_OK;
173 return hres;
174 }
175 else
176 {
177 hres = S_FALSE;
178 }
179 }
180
181 }
182 pEnumerator->Release();
183 }
184 else
185 {
186 Log(("Query for operating system name failed. Error code = 0x%x\n", hres));
187 }
188 }
189 else
190 {
191 hres = -1;
192 }
193
194 return hres;
195}
196
197static HRESULT netIfAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr)
198{
199 VARIANT index;
200
201 // Get the value of the key property
202 HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0);
203 if(SUCCEEDED(hr))
204 {
205 WCHAR strIndex[8];
206 swprintf(strIndex, L"%u", index.uintVal);
207 *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy();
208 }
209 else
210 {
211 DWORD dwError = GetLastError();
212 Assert(0);
213 hr = HRESULT_FROM_WIN32( dwError );
214 }
215 return hr;
216}
217
218static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath,
219 BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs,
220 IWbemClassObject** ppOutParams
221 )
222{
223 HRESULT hres;
224 // Step 6: --------------------------------------------------
225 // Use the IWbemServices pointer to make requests of WMI ----
226
227 IWbemClassObject* pInParamsDefinition = NULL;
228 hres = pClass->GetMethod(MethodName, 0,
229 &pInParamsDefinition, NULL);
230 if(SUCCEEDED(hres))
231 {
232 IWbemClassObject* pClassInstance = NULL;
233 hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);
234
235 if(SUCCEEDED(hres))
236 {
237 for(UINT i = 0; i < cArgs; i++)
238 {
239 // Store the value for the in parameters
240 hres = pClassInstance->Put(pArgNames[i], 0,
241 pArgs[i], 0);
242 if(FAILED(hres))
243 {
244 break;
245 }
246 }
247
248 if(SUCCEEDED(hres))
249 {
250 IWbemClassObject* pOutParams = NULL;
251 hres = pSvc->ExecMethod(ObjPath, MethodName, 0,
252 NULL, pClassInstance, &pOutParams, NULL);
253 if(SUCCEEDED(hres))
254 {
255 *ppOutParams = pOutParams;
256 }
257 }
258
259 pClassInstance->Release();
260 }
261
262 pInParamsDefinition->Release();
263 }
264
265 return hres;
266}
267
268static HRESULT createIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp)
269{
270 HRESULT hr;
271 SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp);
272 if(pIpArray)
273 {
274 for(UINT i = 0; i < cIp; i++)
275 {
276 char* addr = inet_ntoa(aIp[i]);
277 BSTR val = bstr_t(addr).copy();
278 long aIndex[1];
279 aIndex[0] = i;
280 hr = SafeArrayPutElement(pIpArray, aIndex, val);
281 if(FAILED(hr))
282 {
283 SysFreeString(val);
284 SafeArrayDestroy(pIpArray);
285 break;
286 }
287 }
288
289 if(SUCCEEDED(hr))
290 {
291 *ppArray = pIpArray;
292 }
293 }
294 else
295 {
296 DWORD dwError = GetLastError();
297 Assert(0);
298 hr = HRESULT_FROM_WIN32( dwError );
299 }
300
301 return hr;
302}
303
304static HRESULT VBoxNetCfgWinEnableStatic(IWbemServices * pSvc, IWbemClassObject *pObj, in_addr* aIp, in_addr * aMask, UINT cIp)
305{
306 IWbemClassObject * pClass;
307 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
308 HRESULT hr;
309 if(ClassName)
310 {
311 hr = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
312 if(SUCCEEDED(hr))
313 {
314 BSTR ObjPath;
315 hr = netIfAdapterConfigPath(pObj, &ObjPath);
316 if(SUCCEEDED(hr))
317 {
318 LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"};
319 VARIANT ipAddresses;
320 VariantInit(&ipAddresses);
321 ipAddresses.vt = VT_ARRAY | VT_BSTR;
322 SAFEARRAY *pIpArray;
323 hr = createIpArray(&pIpArray, aIp, cIp);
324 if(SUCCEEDED(hr))
325 {
326 ipAddresses.parray = pIpArray;
327 VARIANT ipMasks;
328 VariantInit(&ipMasks);
329 ipMasks.vt = VT_ARRAY | VT_BSTR;
330 SAFEARRAY *pMaskArray;
331 hr = createIpArray(&pMaskArray, aMask, cIp);
332 if(SUCCEEDED(hr))
333 {
334 ipMasks.parray = pMaskArray;
335 LPVARIANT args[] = {&ipAddresses, &ipMasks};
336 IWbemClassObject * pOutParams;
337
338 hr = netIfExecMethod(pSvc, pClass, ObjPath,
339 bstr_t(L"EnableStatic"), argNames, args, 2, &pOutParams);
340 if(SUCCEEDED(hr))
341 {
342 }
343 SafeArrayDestroy(pMaskArray);
344 }
345 SafeArrayDestroy(pIpArray);
346 }
347 SysFreeString(ObjPath);
348 }
349 pClass->Release();
350 }
351 SysFreeString(ClassName);
352 }
353 else
354 {
355 DWORD dwError = GetLastError();
356 Assert(0);
357 hr = HRESULT_FROM_WIN32( dwError );
358 }
359
360 return hr;
361}
362
363static HRESULT VBoxNetCfgWinEnableDHCP(IWbemServices * pSvc, IWbemClassObject *pObj, in_addr* aIp, in_addr * aMask, UINT cIp)
364{
365 IWbemClassObject * pClass;
366 BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration");
367 HRESULT hr;
368 if(ClassName)
369 {
370 hr = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
371 if(SUCCEEDED(hr))
372 {
373 BSTR ObjPath;
374 hr = netIfAdapterConfigPath(pObj, &ObjPath);
375 if(SUCCEEDED(hr))
376 {
377 IWbemClassObject * pOutParams;
378
379 hr = netIfExecMethod(pSvc, pClass, ObjPath,
380 bstr_t(L"EnableDHCP"), NULL, NULL, 0, &pOutParams);
381 if(SUCCEEDED(hr))
382 {
383 }
384 SysFreeString(ObjPath);
385 }
386 pClass->Release();
387 }
388 SysFreeString(ClassName);
389 }
390 else
391 {
392 DWORD dwError = GetLastError();
393 Assert(0);
394 hr = HRESULT_FROM_WIN32( dwError );
395 }
396
397 return hr;
398}
399
400static int collectNetIfInfo(Bstr &strName, PNETIFINFO pInfo)
401{
402 DWORD dwRc;
403 /*
404 * Most of the hosts probably have less than 10 adapters,
405 * so we'll mostly succeed from the first attempt.
406 */
407 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
408 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
409 if (!pAddresses)
410 return VERR_NO_MEMORY;
411 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
412 if (dwRc == ERROR_BUFFER_OVERFLOW)
413 {
414 /* Impressive! More than 10 adapters! Get more memory and try again. */
415 RTMemFree(pAddresses);
416 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
417 if (!pAddresses)
418 return VERR_NO_MEMORY;
419 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
420 }
421 if (dwRc == NO_ERROR)
422 {
423 PIP_ADAPTER_ADDRESSES pAdapter;
424 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
425 {
426 char *pszUuid = RTStrDup(pAdapter->AdapterName);
427 size_t len = strlen(pszUuid) - 1;
428 if (pszUuid[0] == '{' && pszUuid[len] == '}')
429 {
430 pszUuid[len] = 0;
431 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
432 {
433 bool fIPFound, fIPv6Found;
434 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
435 fIPFound = fIPv6Found = false;
436 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
437 {
438 switch (pAddr->Address.lpSockaddr->sa_family)
439 {
440 case AF_INET:
441 if (!fIPFound)
442 {
443 fIPFound = true;
444 memcpy(&pInfo->IPAddress,
445 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
446 sizeof(pInfo->IPAddress));
447 }
448 break;
449 case AF_INET6:
450 if (!fIPv6Found)
451 {
452 fIPv6Found = true;
453 memcpy(&pInfo->IPv6Address,
454 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
455 sizeof(pInfo->IPv6Address));
456 }
457 break;
458 }
459 }
460 PIP_ADAPTER_PREFIX pPrefix;
461 fIPFound = fIPv6Found = false;
462 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
463 {
464 switch (pPrefix->Address.lpSockaddr->sa_family)
465 {
466 case AF_INET:
467 if (!fIPFound)
468 {
469 fIPFound = true;
470 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
471 }
472 break;
473 case AF_INET6:
474 if (!fIPv6Found)
475 {
476 fIPv6Found = true;
477 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
478 }
479 break;
480 }
481 }
482 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
483 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
484 else
485 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
486 pInfo->enmMediumType = NETIF_T_ETHERNET;
487 pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
488 RTStrFree(pszUuid);
489 break;
490 }
491 }
492 RTStrFree(pszUuid);
493 }
494 }
495 RTMemFree(pAddresses);
496
497 return VINF_SUCCESS;
498}
499
500# define VBOX_APP_NAME L"VirtualBox"
501
502static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, HostNetworkInterfaceType enmType)
503{
504 LPWSTR lpszName;
505 GUID IfGuid;
506 HRESULT hr;
507 int rc = VERR_GENERAL_FAILURE;
508
509 hr = pncc->GetDisplayName( &lpszName );
510 Assert(hr == S_OK);
511 if(hr == S_OK)
512 {
513 size_t cUnicodeName = wcslen(lpszName) + 1;
514 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
515 Bstr name (uniLen + 1 /* extra zero */);
516 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
517
518 hr = pncc->GetInstanceGuid(&IfGuid);
519 Assert(hr == S_OK);
520 if (hr == S_OK)
521 {
522 NETIFINFO Info;
523 memset(&Info, 0, sizeof(Info));
524 Info.Uuid = *(Guid(IfGuid).raw());
525 rc = collectNetIfInfo(name, &Info);
526 if (RT_FAILURE(rc))
527 {
528 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
529 }
530 /* create a new object and add it to the list */
531 ComObjPtr <HostNetworkInterface> iface;
532 iface.createObject();
533 /* remove the curly bracket at the end */
534 if (SUCCEEDED (iface->init (name, enmType, &Info)))
535 {
536 pPist->push_back (iface);
537 rc = VINF_SUCCESS;
538 }
539 else
540 {
541 Assert(0);
542 }
543 }
544 CoTaskMemFree(lpszName);
545 }
546
547 return rc;
548}
549
550#else /* #ifndef VBOX_WITH_NETFLT */
551/**
552 * Windows helper function for NetIfList().
553 *
554 * @returns true / false.
555 *
556 * @param guid The GUID.
557 */
558static bool IsTAPDevice(const char *guid)
559{
560 HKEY hNetcard;
561 LONG status;
562 DWORD len;
563 int i = 0;
564 bool ret = false;
565
566 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &hNetcard);
567 if (status != ERROR_SUCCESS)
568 return false;
569
570 for (;;)
571 {
572 char szEnumName[256];
573 char szNetCfgInstanceId[256];
574 DWORD dwKeyType;
575 HKEY hNetCardGUID;
576
577 len = sizeof(szEnumName);
578 status = RegEnumKeyExA(hNetcard, i, szEnumName, &len, NULL, NULL, NULL, NULL);
579 if (status != ERROR_SUCCESS)
580 break;
581
582 status = RegOpenKeyExA(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
583 if (status == ERROR_SUCCESS)
584 {
585 len = sizeof(szNetCfgInstanceId);
586 status = RegQueryValueExA(hNetCardGUID, "NetCfgInstanceId", NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &len);
587 if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
588 {
589 char szNetProductName[256];
590 char szNetProviderName[256];
591
592 szNetProductName[0] = 0;
593 len = sizeof(szNetProductName);
594 status = RegQueryValueExA(hNetCardGUID, "ProductName", NULL, &dwKeyType, (LPBYTE)szNetProductName, &len);
595
596 szNetProviderName[0] = 0;
597 len = sizeof(szNetProviderName);
598 status = RegQueryValueExA(hNetCardGUID, "ProviderName", NULL, &dwKeyType, (LPBYTE)szNetProviderName, &len);
599
600 if ( !strcmp(szNetCfgInstanceId, guid)
601 && !strcmp(szNetProductName, "VirtualBox TAP Adapter")
602 && ( (!strcmp(szNetProviderName, "innotek GmbH"))
603 || (!strcmp(szNetProviderName, "Sun Microsystems, Inc."))))
604 {
605 ret = true;
606 RegCloseKey(hNetCardGUID);
607 break;
608 }
609 }
610 RegCloseKey(hNetCardGUID);
611 }
612 ++i;
613 }
614
615 RegCloseKey(hNetcard);
616 return ret;
617}
618#endif /* #ifndef VBOX_WITH_NETFLT */
619
620
621static int NetIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
622{
623#ifndef VBOX_WITH_NETFLT
624 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
625 return VERR_NOT_IMPLEMENTED;
626#else /* # if defined VBOX_WITH_NETFLT */
627 INetCfg *pNc;
628 INetCfgComponent *pMpNcc;
629 LPWSTR lpszApp = NULL;
630 HRESULT hr;
631 IEnumNetCfgComponent *pEnumComponent;
632
633 /* we are using the INetCfg API for getting the list of miniports */
634 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
635 VBOX_APP_NAME,
636 &pNc,
637 &lpszApp );
638 Assert(hr == S_OK);
639 if(hr == S_OK)
640 {
641 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
642 if(hr == S_OK)
643 {
644 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
645 {
646 ULONG uComponentStatus;
647 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
648//#ifndef DEBUG_bird
649// Assert(hr == S_OK);
650//#endif
651 if(hr == S_OK)
652 {
653 if(uComponentStatus == 0)
654 {
655 LPWSTR pId;
656 hr = pMpNcc->GetId(&pId);
657 Assert(hr == S_OK);
658 if(hr == S_OK)
659 {
660 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
661 {
662 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly);
663 }
664 CoTaskMemFree(pId);
665 }
666 }
667 }
668 VBoxNetCfgWinReleaseRef(pMpNcc);
669 }
670 Assert(hr == S_OK || hr == S_FALSE);
671
672 VBoxNetCfgWinReleaseRef(pEnumComponent);
673 }
674 else
675 {
676 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
677 }
678
679 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
680 }
681 else if(lpszApp)
682 {
683 CoTaskMemFree(lpszApp);
684 }
685#endif /* # if defined VBOX_WITH_NETFLT */
686 return VINF_SUCCESS;
687}
688
689//TODO: this is sample currently, hardcoded balues should be removed and exposed to the API
690#if 0
691static int NetIfEnableStatic()
692{
693 INetCfg *pnc;
694 LPWSTR lpszLockedBy = NULL;
695 int r = 1;
696 HRESULT hr;
697
698 hr = VBoxNetCfgWinQueryINetCfg(FALSE, VBOX_APP_NAME, &pnc, &lpszLockedBy);
699 if(hr == S_OK)
700 {
701 INetCfgComponent *pComponent;
702 HRESULT hr = pnc->FindComponent(L"*msloop", &pComponent);
703 if(hr == S_OK)
704 {
705 GUID guid;
706 hr = pComponent->GetInstanceGuid(&guid);
707 if(SUCCEEDED(hr))
708 {
709 IWbemServices * pSvc;
710 hr = netIfWinCreateIWbemServices(&pSvc);
711 if(SUCCEEDED(hr))
712 {
713 IWbemClassObject *pAdapterConfig;
714 hr = netIfWinFindAdapterClassById(pSvc, &guid, &pAdapterConfig);
715 if(SUCCEEDED(hr))
716 {
717 in_addr ip[1];
718 in_addr mask[1];
719 ip[0].S_un.S_addr = inet_addr("192.168.5.1");
720 mask[0].S_un.S_addr = inet_addr("255.255.255.0");
721
722 hr = VBoxNetCfgWinEnableStatic(pSvc, pAdapterConfig, ip, mask, 1);
723 if(SUCCEEDED(hr))
724 {
725 printf("succees!!!\n");
726 r = 0;
727 }
728 }
729 }
730
731 }
732 }
733 }
734
735
736 return r;
737}
738#endif
739
740int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
741{
742#ifndef VBOX_WITH_NETFLT
743 static const char *NetworkKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\"
744 "{4D36E972-E325-11CE-BFC1-08002BE10318}";
745 HKEY hCtrlNet;
746 LONG status;
747 DWORD len;
748 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
749 if (status != ERROR_SUCCESS)
750 {
751 Log(("NetIfList: Could not open registry key \"%s\"", NetworkKey));
752 return E_FAIL;
753 }
754
755 for (int i = 0;; ++ i)
756 {
757 char szNetworkGUID [256];
758 HKEY hConnection;
759 char szNetworkConnection [256];
760
761 len = sizeof (szNetworkGUID);
762 status = RegEnumKeyExA (hCtrlNet, i, szNetworkGUID, &len, NULL, NULL, NULL, NULL);
763 if (status != ERROR_SUCCESS)
764 break;
765
766 if (!IsTAPDevice(szNetworkGUID))
767 continue;
768
769 RTStrPrintf (szNetworkConnection, sizeof (szNetworkConnection),
770 "%s\\Connection", szNetworkGUID);
771 status = RegOpenKeyExA (hCtrlNet, szNetworkConnection, 0, KEY_READ, &hConnection);
772 if (status == ERROR_SUCCESS)
773 {
774 DWORD dwKeyType;
775 status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
776 &dwKeyType, NULL, &len);
777 if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
778 {
779 size_t uniLen = (len + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
780 Bstr name (uniLen + 1 /* extra zero */);
781 status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
782 &dwKeyType, (LPBYTE) name.mutableRaw(), &len);
783 if (status == ERROR_SUCCESS)
784 {
785 LogFunc(("Connection name %ls\n", name.mutableRaw()));
786 /* put a trailing zero, just in case (see MSDN) */
787 name.mutableRaw() [uniLen] = 0;
788 /* create a new object and add it to the list */
789 ComObjPtr <HostNetworkInterface> iface;
790 iface.createObject();
791 /* remove the curly bracket at the end */
792 szNetworkGUID [strlen(szNetworkGUID) - 1] = '\0';
793
794 NETIFINFO Info;
795 memset(&Info, 0, sizeof(Info));
796 Info.Uuid = *(Guid(szNetworkGUID + 1).raw());
797 int rc = collectNetIfInfo(name, &Info);
798 if (RT_FAILURE(rc))
799 {
800 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
801 }
802
803 if (SUCCEEDED (iface->init (name, HostNetworkInterfaceType_Bridged, &Info)))
804 list.push_back (iface);
805 }
806 }
807 RegCloseKey (hConnection);
808 }
809 }
810 RegCloseKey (hCtrlNet);
811#else /* # if defined VBOX_WITH_NETFLT */
812 INetCfg *pNc;
813 INetCfgComponent *pMpNcc;
814 INetCfgComponent *pTcpIpNcc;
815 LPWSTR lpszApp;
816 HRESULT hr;
817 IEnumNetCfgBindingPath *pEnumBp;
818 INetCfgBindingPath *pBp;
819 IEnumNetCfgBindingInterface *pEnumBi;
820 INetCfgBindingInterface *pBi;
821
822 /* we are using the INetCfg API for getting the list of miniports */
823 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
824 VBOX_APP_NAME,
825 &pNc,
826 &lpszApp );
827 Assert(hr == S_OK);
828 if(hr == S_OK)
829 {
830# ifdef VBOX_NETFLT_ONDEMAND_BIND
831 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
832 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
833# else
834 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
835 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
836# ifndef VBOX_WITH_HARDENING
837 if(hr != S_OK)
838 {
839 /* TODO: try to install the netflt from here */
840 }
841# endif
842
843# endif
844
845 if(hr == S_OK)
846 {
847 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
848 Assert(hr == S_OK);
849 if ( hr == S_OK )
850 {
851 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
852 Assert(hr == S_OK || hr == S_FALSE);
853 while( hr == S_OK )
854 {
855 /* S_OK == enabled, S_FALSE == disabled */
856 if(pBp->IsEnabled() == S_OK)
857 {
858 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
859 Assert(hr == S_OK);
860 if ( hr == S_OK )
861 {
862 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
863 Assert(hr == S_OK);
864 while(hr == S_OK)
865 {
866 hr = pBi->GetLowerComponent( &pMpNcc );
867 Assert(hr == S_OK);
868 if(hr == S_OK)
869 {
870 ULONG uComponentStatus;
871 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
872//#ifndef DEBUG_bird
873// Assert(hr == S_OK);
874//#endif
875 if(hr == S_OK)
876 {
877 if(uComponentStatus == 0)
878 {
879 vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged);
880 }
881 }
882 VBoxNetCfgWinReleaseRef( pMpNcc );
883 }
884 VBoxNetCfgWinReleaseRef(pBi);
885
886 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
887 }
888 VBoxNetCfgWinReleaseRef(pEnumBi);
889 }
890 }
891 VBoxNetCfgWinReleaseRef(pBp);
892
893 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
894 }
895 VBoxNetCfgWinReleaseRef(pEnumBp);
896 }
897 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
898 }
899 else
900 {
901 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
902 }
903
904 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
905 }
906
907 NetIfListHostAdapters(list);
908#endif /* # if defined VBOX_WITH_NETFLT */
909 return VINF_SUCCESS;
910}
Note: See TracBrowser for help on using the repository browser.

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