VirtualBox

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

Last change on this file since 17174 was 17174, 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: 29.6 KB
Line 
1/* $Id: NetIfList-win.cpp 17174 2009-02-26 16:05:01Z 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
363
364static int collectNetIfInfo(Bstr &strName, PNETIFINFO pInfo)
365{
366 DWORD dwRc;
367 /*
368 * Most of the hosts probably have less than 10 adapters,
369 * so we'll mostly succeed from the first attempt.
370 */
371 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
372 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
373 if (!pAddresses)
374 return VERR_NO_MEMORY;
375 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
376 if (dwRc == ERROR_BUFFER_OVERFLOW)
377 {
378 /* Impressive! More than 10 adapters! Get more memory and try again. */
379 RTMemFree(pAddresses);
380 pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
381 if (!pAddresses)
382 return VERR_NO_MEMORY;
383 dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
384 }
385 if (dwRc == NO_ERROR)
386 {
387 PIP_ADAPTER_ADDRESSES pAdapter;
388 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
389 {
390 char *pszUuid = RTStrDup(pAdapter->AdapterName);
391 size_t len = strlen(pszUuid) - 1;
392 if (pszUuid[0] == '{' && pszUuid[len] == '}')
393 {
394 pszUuid[len] = 0;
395 if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
396 {
397 bool fIPFound, fIPv6Found;
398 PIP_ADAPTER_UNICAST_ADDRESS pAddr;
399 fIPFound = fIPv6Found = false;
400 for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
401 {
402 switch (pAddr->Address.lpSockaddr->sa_family)
403 {
404 case AF_INET:
405 if (!fIPFound)
406 {
407 fIPFound = true;
408 memcpy(&pInfo->IPAddress,
409 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
410 sizeof(pInfo->IPAddress));
411 }
412 break;
413 case AF_INET6:
414 if (!fIPv6Found)
415 {
416 fIPv6Found = true;
417 memcpy(&pInfo->IPv6Address,
418 ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
419 sizeof(pInfo->IPv6Address));
420 }
421 break;
422 }
423 }
424 PIP_ADAPTER_PREFIX pPrefix;
425 fIPFound = fIPv6Found = false;
426 for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
427 {
428 switch (pPrefix->Address.lpSockaddr->sa_family)
429 {
430 case AF_INET:
431 if (!fIPFound)
432 {
433 fIPFound = true;
434 ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
435 }
436 break;
437 case AF_INET6:
438 if (!fIPv6Found)
439 {
440 fIPv6Found = true;
441 ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
442 }
443 break;
444 }
445 }
446 if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
447 Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
448 else
449 memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
450 pInfo->enmType = NETIF_T_ETHERNET;
451 pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
452 RTStrFree(pszUuid);
453 break;
454 }
455 }
456 RTStrFree(pszUuid);
457 }
458 }
459 RTMemFree(pAddresses);
460
461 return VINF_SUCCESS;
462}
463
464# define VBOX_APP_NAME L"VirtualBox"
465
466static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc, bool bReal)
467{
468 LPWSTR lpszName;
469 GUID IfGuid;
470 HRESULT hr;
471 int rc = VERR_GENERAL_FAILURE;
472
473 hr = pncc->GetDisplayName( &lpszName );
474 Assert(hr == S_OK);
475 if(hr == S_OK)
476 {
477 size_t cUnicodeName = wcslen(lpszName) + 1;
478 size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
479 Bstr name (uniLen + 1 /* extra zero */);
480 wcscpy((wchar_t *) name.mutableRaw(), lpszName);
481
482 hr = pncc->GetInstanceGuid(&IfGuid);
483 Assert(hr == S_OK);
484 if (hr == S_OK)
485 {
486 NETIFINFO Info;
487 memset(&Info, 0, sizeof(Info));
488 Info.Uuid = *(Guid(IfGuid).raw());
489 rc = collectNetIfInfo(name, &Info);
490 if (RT_FAILURE(rc))
491 {
492 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
493 }
494 /* create a new object and add it to the list */
495 ComObjPtr <HostNetworkInterface> iface;
496 iface.createObject();
497 /* remove the curly bracket at the end */
498 if (SUCCEEDED (iface->init (name, bReal, &Info)))
499 {
500 pPist->push_back (iface);
501 rc = VINF_SUCCESS;
502 }
503 else
504 {
505 Assert(0);
506 }
507 }
508 CoTaskMemFree(lpszName);
509 }
510
511 return rc;
512}
513
514#else /* #ifndef VBOX_WITH_NETFLT */
515/**
516 * Windows helper function for NetIfList().
517 *
518 * @returns true / false.
519 *
520 * @param guid The GUID.
521 */
522static bool IsTAPDevice(const char *guid)
523{
524 HKEY hNetcard;
525 LONG status;
526 DWORD len;
527 int i = 0;
528 bool ret = false;
529
530 status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &hNetcard);
531 if (status != ERROR_SUCCESS)
532 return false;
533
534 for (;;)
535 {
536 char szEnumName[256];
537 char szNetCfgInstanceId[256];
538 DWORD dwKeyType;
539 HKEY hNetCardGUID;
540
541 len = sizeof(szEnumName);
542 status = RegEnumKeyExA(hNetcard, i, szEnumName, &len, NULL, NULL, NULL, NULL);
543 if (status != ERROR_SUCCESS)
544 break;
545
546 status = RegOpenKeyExA(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
547 if (status == ERROR_SUCCESS)
548 {
549 len = sizeof(szNetCfgInstanceId);
550 status = RegQueryValueExA(hNetCardGUID, "NetCfgInstanceId", NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &len);
551 if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
552 {
553 char szNetProductName[256];
554 char szNetProviderName[256];
555
556 szNetProductName[0] = 0;
557 len = sizeof(szNetProductName);
558 status = RegQueryValueExA(hNetCardGUID, "ProductName", NULL, &dwKeyType, (LPBYTE)szNetProductName, &len);
559
560 szNetProviderName[0] = 0;
561 len = sizeof(szNetProviderName);
562 status = RegQueryValueExA(hNetCardGUID, "ProviderName", NULL, &dwKeyType, (LPBYTE)szNetProviderName, &len);
563
564 if ( !strcmp(szNetCfgInstanceId, guid)
565 && !strcmp(szNetProductName, "VirtualBox TAP Adapter")
566 && ( (!strcmp(szNetProviderName, "innotek GmbH"))
567 || (!strcmp(szNetProviderName, "Sun Microsystems, Inc."))))
568 {
569 ret = true;
570 RegCloseKey(hNetCardGUID);
571 break;
572 }
573 }
574 RegCloseKey(hNetCardGUID);
575 }
576 ++i;
577 }
578
579 RegCloseKey(hNetcard);
580 return ret;
581}
582#endif /* #ifndef VBOX_WITH_NETFLT */
583
584
585static int NetIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list)
586{
587#ifndef VBOX_WITH_NETFLT
588 /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
589 return VERR_NOT_IMPLEMENTED;
590#else /* # if defined VBOX_WITH_NETFLT */
591 INetCfg *pNc;
592 INetCfgComponent *pMpNcc;
593 LPWSTR lpszApp = NULL;
594 HRESULT hr;
595 IEnumNetCfgComponent *pEnumComponent;
596
597 /* we are using the INetCfg API for getting the list of miniports */
598 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
599 VBOX_APP_NAME,
600 &pNc,
601 &lpszApp );
602 Assert(hr == S_OK);
603 if(hr == S_OK)
604 {
605 hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
606 if(hr == S_OK)
607 {
608 while((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
609 {
610 ULONG uComponentStatus;
611 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
612#ifndef DEBUG_bird
613 Assert(hr == S_OK);
614#endif
615 if(hr == S_OK)
616 {
617 if(uComponentStatus == 0)
618 {
619 LPWSTR pId;
620 hr = pMpNcc->GetId(&pId);
621 Assert(hr == S_OK);
622 if(hr == S_OK)
623 {
624 if(!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
625 {
626 vboxNetWinAddComponent(&list, pMpNcc, false);
627 }
628 CoTaskMemFree(pId);
629 }
630 }
631 }
632 VBoxNetCfgWinReleaseRef(pMpNcc);
633 }
634 Assert(hr == S_OK || hr == S_FALSE);
635
636 VBoxNetCfgWinReleaseRef(pEnumComponent);
637 }
638 else
639 {
640 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
641 }
642
643 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
644 }
645 else if(lpszApp)
646 {
647 CoTaskMemFree(lpszApp);
648 }
649#endif /* # if defined VBOX_WITH_NETFLT */
650 return VINF_SUCCESS;
651}
652
653#if 0
654//TODO: this is sample currently, hardcoded balues should be removed and exposed to the API
655static int enableStatic()
656{
657 INetCfg *pnc;
658 LPWSTR lpszLockedBy = NULL;
659 int r = 1;
660 HRESULT hr;
661
662 hr = VBoxNetCfgWinQueryINetCfg(FALSE, VBOX_APP_NAME, &pnc, &lpszLockedBy);
663 if(hr == S_OK)
664 {
665 INetCfgComponent *pComponent;
666 HRESULT hr = pnc->FindComponent(L"*msloop", &pComponent);
667 if(hr == S_OK)
668 {
669 GUID guid;
670 hr = pComponent->GetInstanceGuid(&guid);
671 if(SUCCEEDED(hr))
672 {
673 IWbemServices * pSvc;
674 hr = netIfWinCreateIWbemServices(&pSvc);
675 if(SUCCEEDED(hr))
676 {
677 IWbemClassObject *pAdapterConfig;
678 hr = netIfWinFindAdapterClassById(pSvc, &guid, &pAdapterConfig);
679 if(SUCCEEDED(hr))
680 {
681 in_addr ip[1];
682 in_addr mask[1];
683 ip[0].S_un.S_addr = inet_addr("192.168.5.1");
684 mask[0].S_un.S_addr = inet_addr("255.255.255.0");
685
686 hr = VBoxNetCfgWinEnableStatic(pSvc, pAdapterConfig, ip, mask, 1);
687 if(SUCCEEDED(hr))
688 {
689 printf("succees!!!\n");
690 r = 0;
691 }
692 }
693 }
694
695 }
696 }
697 }
698
699
700 return r;
701}
702#endif
703
704int NetIfList(std::list <ComObjPtr <HostNetworkInterface> > &list)
705{
706#ifndef VBOX_WITH_NETFLT
707 static const char *NetworkKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\"
708 "{4D36E972-E325-11CE-BFC1-08002BE10318}";
709 HKEY hCtrlNet;
710 LONG status;
711 DWORD len;
712 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
713 if (status != ERROR_SUCCESS)
714 {
715 Log(("NetIfList: Could not open registry key \"%s\"", NetworkKey));
716 return E_FAIL;
717 }
718
719 for (int i = 0;; ++ i)
720 {
721 char szNetworkGUID [256];
722 HKEY hConnection;
723 char szNetworkConnection [256];
724
725 len = sizeof (szNetworkGUID);
726 status = RegEnumKeyExA (hCtrlNet, i, szNetworkGUID, &len, NULL, NULL, NULL, NULL);
727 if (status != ERROR_SUCCESS)
728 break;
729
730 if (!IsTAPDevice(szNetworkGUID))
731 continue;
732
733 RTStrPrintf (szNetworkConnection, sizeof (szNetworkConnection),
734 "%s\\Connection", szNetworkGUID);
735 status = RegOpenKeyExA (hCtrlNet, szNetworkConnection, 0, KEY_READ, &hConnection);
736 if (status == ERROR_SUCCESS)
737 {
738 DWORD dwKeyType;
739 status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
740 &dwKeyType, NULL, &len);
741 if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
742 {
743 size_t uniLen = (len + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
744 Bstr name (uniLen + 1 /* extra zero */);
745 status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
746 &dwKeyType, (LPBYTE) name.mutableRaw(), &len);
747 if (status == ERROR_SUCCESS)
748 {
749 LogFunc(("Connection name %ls\n", name.mutableRaw()));
750 /* put a trailing zero, just in case (see MSDN) */
751 name.mutableRaw() [uniLen] = 0;
752 /* create a new object and add it to the list */
753 ComObjPtr <HostNetworkInterface> iface;
754 iface.createObject();
755 /* remove the curly bracket at the end */
756 szNetworkGUID [strlen(szNetworkGUID) - 1] = '\0';
757
758 NETIFINFO Info;
759 memset(&Info, 0, sizeof(Info));
760 Info.Uuid = *(Guid(szNetworkGUID + 1).raw());
761 int rc = collectNetIfInfo(name, &Info);
762 if (RT_FAILURE(rc))
763 {
764 Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Vrc\n", rc));
765 }
766
767 if (SUCCEEDED (iface->init (name, TRUE, &Info)))
768 list.push_back (iface);
769 }
770 }
771 RegCloseKey (hConnection);
772 }
773 }
774 RegCloseKey (hCtrlNet);
775#else /* # if defined VBOX_WITH_NETFLT */
776 INetCfg *pNc;
777 INetCfgComponent *pMpNcc;
778 INetCfgComponent *pTcpIpNcc;
779 LPWSTR lpszApp;
780 HRESULT hr;
781 IEnumNetCfgBindingPath *pEnumBp;
782 INetCfgBindingPath *pBp;
783 IEnumNetCfgBindingInterface *pEnumBi;
784 INetCfgBindingInterface *pBi;
785
786 /* we are using the INetCfg API for getting the list of miniports */
787 hr = VBoxNetCfgWinQueryINetCfg( FALSE,
788 VBOX_APP_NAME,
789 &pNc,
790 &lpszApp );
791 Assert(hr == S_OK);
792 if(hr == S_OK)
793 {
794# ifdef VBOX_NETFLT_ONDEMAND_BIND
795 /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
796 hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
797# else
798 /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
799 hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
800# ifndef VBOX_WITH_HARDENING
801 if(hr != S_OK)
802 {
803 /* TODO: try to install the netflt from here */
804 }
805# endif
806
807# endif
808
809 if(hr == S_OK)
810 {
811 hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
812 Assert(hr == S_OK);
813 if ( hr == S_OK )
814 {
815 hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
816 Assert(hr == S_OK || hr == S_FALSE);
817 while( hr == S_OK )
818 {
819 /* S_OK == enabled, S_FALSE == disabled */
820 if(pBp->IsEnabled() == S_OK)
821 {
822 hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
823 Assert(hr == S_OK);
824 if ( hr == S_OK )
825 {
826 hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
827 Assert(hr == S_OK);
828 while(hr == S_OK)
829 {
830 hr = pBi->GetLowerComponent( &pMpNcc );
831 Assert(hr == S_OK);
832 if(hr == S_OK)
833 {
834 ULONG uComponentStatus;
835 hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
836//#ifndef DEBUG_bird
837// Assert(hr == S_OK);
838//#endif
839 if(hr == S_OK)
840 {
841 if(uComponentStatus == 0)
842 {
843 vboxNetWinAddComponent(&list, pMpNcc, true);
844 }
845 }
846 VBoxNetCfgWinReleaseRef( pMpNcc );
847 }
848 VBoxNetCfgWinReleaseRef(pBi);
849
850 hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
851 }
852 VBoxNetCfgWinReleaseRef(pEnumBi);
853 }
854 }
855 VBoxNetCfgWinReleaseRef(pBp);
856
857 hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
858 }
859 VBoxNetCfgWinReleaseRef(pEnumBp);
860 }
861 VBoxNetCfgWinReleaseRef(pTcpIpNcc);
862 }
863 else
864 {
865 LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
866 }
867
868 VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
869 }
870
871 NetIfListHostAdapters(list);
872#endif /* # if defined VBOX_WITH_NETFLT */
873 return VINF_SUCCESS;
874}
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