Changeset 17494 in vbox
- Timestamp:
- Mar 6, 2009 4:55:44 PM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HostImpl.cpp
r17394 r17494 77 77 # include <devguid.h> 78 78 # include <objbase.h> 79 # include <setupapi.h>79 //# include <setupapi.h> 80 80 # include <shlobj.h> 81 81 # include <cfgmgr32.h> … … 727 727 if (SUCCEEDED (iface->init (name, Guid (IfGuid), HostNetworkInterfaceType_Bridged))) 728 728 { 729 // iface->setVirtualBox(mParent); 729 730 pPist->push_back (iface); 730 731 rc = VINF_SUCCESS; … … 1062 1063 # endif /* RT_OS_LINUX */ 1063 1064 #endif 1065 1066 std::list <ComObjPtr <HostNetworkInterface> >::iterator it; 1067 for (it = list.begin(); it != list.end(); ++it) 1068 { 1069 (*it)->setVirtualBox(mParent); 1070 } 1071 1072 1064 1073 SafeIfaceArray <IHostNetworkInterface> networkInterfaces (list); 1065 1074 networkInterfaces.detachTo (ComSafeArrayOutArg (aNetworkInterfaces)); … … 1305 1314 1306 1315 #ifdef RT_OS_WINDOWS 1307 /** @todo REMOVE. OBSOLETE NOW. */1308 /**1309 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and1310 * later OSes) and it has the UAC (User Account Control) feature enabled.1311 */1312 static BOOL IsUACEnabled()1313 {1314 LONG rc = 0;1315 1316 OSVERSIONINFOEX info;1317 ZeroMemory (&info, sizeof (OSVERSIONINFOEX));1318 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);1319 rc = GetVersionEx ((OSVERSIONINFO *) &info);1320 AssertReturn (rc != 0, FALSE);1321 1322 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",1323 info.dwMajorVersion, info.dwMinorVersion));1324 1325 /* we are interested only in Vista (and newer versions...). In all1326 * earlier versions UAC is not present. */1327 if (info.dwMajorVersion < 6)1328 return FALSE;1329 1330 /* the default EnableLUA value is 1 (Enabled) */1331 DWORD dwEnableLUA = 1;1332 1333 HKEY hKey;1334 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,1335 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",1336 0, KEY_QUERY_VALUE, &hKey);1337 1338 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);1339 if (rc == ERROR_SUCCESS)1340 {1341 1342 DWORD cbEnableLUA = sizeof (dwEnableLUA);1343 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,1344 (LPBYTE) &dwEnableLUA, &cbEnableLUA);1345 1346 RegCloseKey (hKey);1347 1348 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);1349 }1350 1351 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));1352 1353 return dwEnableLUA == 1;1354 }1355 1356 struct NetworkInterfaceHelperClientData1357 {1358 SVCHlpMsg::Code msgCode;1359 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */1360 Bstr name;1361 ComObjPtr <HostNetworkInterface> iface;1362 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */1363 Guid guid;1364 };1365 1316 1366 1317 STDMETHODIMP … … 1376 1327 CHECK_READY(); 1377 1328 1378 HRESULT rc = S_OK;1379 1380 1329 /* first check whether an interface with the given name already exists */ 1381 1330 { … … 1386 1335 } 1387 1336 1388 /* create a progress object */ 1389 ComObjPtr <Progress> progress; 1390 progress.createObject(); 1391 rc = progress->init (mParent, static_cast <IHost *> (this), 1392 Bstr (tr ("Creating host network interface")), 1393 FALSE /* aCancelable */); 1394 CheckComRCReturnRC (rc); 1395 progress.queryInterfaceTo (aProgress); 1396 1397 /* create a new uninitialized host interface object */ 1398 ComObjPtr <HostNetworkInterface> iface; 1399 iface.createObject(); 1400 iface.queryInterfaceTo (aHostNetworkInterface); 1401 1402 /* create the networkInterfaceHelperClient() argument */ 1403 std::auto_ptr <NetworkInterfaceHelperClientData> 1404 d (new NetworkInterfaceHelperClientData()); 1405 AssertReturn (d.get(), E_OUTOFMEMORY); 1406 1407 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface; 1408 d->name = aName; 1409 d->iface = iface; 1410 1411 rc = mParent->startSVCHelperClient ( 1412 IsUACEnabled() == TRUE /* aPrivileged */, 1413 networkInterfaceHelperClient, 1414 static_cast <void *> (d.get()), 1415 progress); 1416 1417 if (SUCCEEDED (rc)) 1418 { 1419 /* d is now owned by networkInterfaceHelperClient(), so release it */ 1420 d.release(); 1421 } 1422 1423 return rc; 1337 int r = NetIfCreateHostOnlyNetworkInterface (mParent, aName, aHostNetworkInterface, aProgress); 1338 if(RT_SUCCESS(r)) 1339 { 1340 return S_OK; 1341 } 1342 1343 return r == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; 1424 1344 } 1425 1345 … … 1434 1354 AutoWriteLock alock (this); 1435 1355 CHECK_READY(); 1436 1437 HRESULT rc = S_OK;1438 1356 1439 1357 /* first check whether an interface with the given name already exists */ … … 1444 1362 tr ("Host network interface with UUID {%RTuuid} does not exist"), 1445 1363 Guid (aId).raw()); 1446 1447 /* return the object to be removed to the caller */ 1448 iface.queryInterfaceTo (aHostNetworkInterface); 1449 } 1450 1451 /* create a progress object */ 1452 ComObjPtr <Progress> progress; 1453 progress.createObject(); 1454 rc = progress->init (mParent, static_cast <IHost *> (this), 1455 Bstr (tr ("Removing host network interface")), 1456 FALSE /* aCancelable */); 1457 CheckComRCReturnRC (rc); 1458 progress.queryInterfaceTo (aProgress); 1459 1460 /* create the networkInterfaceHelperClient() argument */ 1461 std::auto_ptr <NetworkInterfaceHelperClientData> 1462 d (new NetworkInterfaceHelperClientData()); 1463 AssertReturn (d.get(), E_OUTOFMEMORY); 1464 1465 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface; 1466 d->guid = aId; 1467 1468 rc = mParent->startSVCHelperClient ( 1469 IsUACEnabled() == TRUE /* aPrivileged */, 1470 networkInterfaceHelperClient, 1471 static_cast <void *> (d.get()), 1472 progress); 1473 1474 if (SUCCEEDED (rc)) 1475 { 1476 /* d is now owned by networkInterfaceHelperClient(), so release it */ 1477 d.release(); 1478 } 1479 1480 return rc; 1364 } 1365 1366 int r = NetIfRemoveHostOnlyNetworkInterface (mParent, aId, aHostNetworkInterface, aProgress); 1367 if(RT_SUCCESS(r)) 1368 { 1369 return S_OK; 1370 } 1371 1372 return r == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; 1481 1373 } 1482 1374 … … 2350 2242 #endif /* VBOX_WITH_USB */ 2351 2243 2352 #ifdef RT_OS_WINDOWS2353 2354 /* The original source of the VBoxTAP adapter creation/destruction code has the following copyright */2355 /*2356 Copyright 2004 by the Massachusetts Institute of Technology2357 2358 All rights reserved.2359 2360 Permission to use, copy, modify, and distribute this software and its2361 documentation for any purpose and without fee is hereby granted,2362 provided that the above copyright notice appear in all copies and that2363 both that copyright notice and this permission notice appear in2364 supporting documentation, and that the name of the Massachusetts2365 Institute of Technology (M.I.T.) not be used in advertising or publicity2366 pertaining to distribution of the software without specific, written2367 prior permission.2368 2369 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING2370 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL2371 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR2372 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,2373 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,2374 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS2375 SOFTWARE.2376 */2377 2378 2379 #define NETSHELL_LIBRARY _T("netshell.dll")2380 2381 /**2382 * Use the IShellFolder API to rename the connection.2383 */2384 static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName)2385 {2386 /* This is the GUID for the network connections folder. It is constant.2387 * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */2388 const GUID CLSID_NetworkConnections = {2389 0x7007ACC7, 0x3202, 0x11D1, {2390 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E2391 }2392 };2393 2394 LPITEMIDLIST pidl = NULL;2395 IShellFolder *pShellFolder = NULL;2396 HRESULT hr;2397 2398 /* Build the display name in the form "::{GUID}". */2399 if (wcslen (wGuid) >= MAX_PATH)2400 return E_INVALIDARG;2401 WCHAR szAdapterGuid[MAX_PATH + 2] = {0};2402 swprintf (szAdapterGuid, L"::%ls", wGuid);2403 2404 /* Create an instance of the network connections folder. */2405 hr = CoCreateInstance (CLSID_NetworkConnections, NULL,2406 CLSCTX_INPROC_SERVER, IID_IShellFolder,2407 reinterpret_cast <LPVOID *> (&pShellFolder));2408 /* Parse the display name. */2409 if (SUCCEEDED (hr))2410 {2411 hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL,2412 &pidl, NULL);2413 }2414 if (SUCCEEDED (hr))2415 {2416 hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL,2417 &pidl);2418 }2419 2420 CoTaskMemFree (pidl);2421 2422 if (pShellFolder)2423 pShellFolder->Release();2424 2425 return hr;2426 }2427 2428 extern "C" HRESULT RenameConnection (PCWSTR GuidString, PCWSTR NewName)2429 {2430 typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR);2431 lpHrRenameConnection RenameConnectionFunc = NULL;2432 HRESULT status;2433 2434 /* First try the IShellFolder interface, which was unimplemented2435 * for the network connections folder before XP. */2436 status = rename_shellfolder (GuidString, NewName);2437 if (status == E_NOTIMPL)2438 {2439 /** @todo that code doesn't seem to work! */2440 /* The IShellFolder interface is not implemented on this platform.2441 * Try the (undocumented) HrRenameConnection API in the netshell2442 * library. */2443 CLSID clsid;2444 HINSTANCE hNetShell;2445 status = CLSIDFromString ((LPOLESTR) GuidString, &clsid);2446 if (FAILED(status))2447 return E_FAIL;2448 hNetShell = LoadLibrary (NETSHELL_LIBRARY);2449 if (hNetShell == NULL)2450 return E_FAIL;2451 RenameConnectionFunc =2452 (lpHrRenameConnection) GetProcAddress (hNetShell,2453 "HrRenameConnection");2454 if (RenameConnectionFunc == NULL)2455 {2456 FreeLibrary (hNetShell);2457 return E_FAIL;2458 }2459 status = RenameConnectionFunc (&clsid, NewName);2460 FreeLibrary (hNetShell);2461 }2462 if (FAILED (status))2463 return status;2464 2465 return S_OK;2466 }2467 #ifdef VBOX_WITH_NETFLT2468 # define DRIVERHWID _T("sun_VBoxNetAdp")2469 #else2470 # define DRIVERHWID _T("vboxtap")2471 #endif2472 2473 2474 #define SetErrBreak(strAndArgs) \2475 if (1) { \2476 aErrMsg = Utf8StrFmt strAndArgs; vrc = VERR_GENERAL_FAILURE; break; \2477 } else do {} while (0)2478 2479 /* static */2480 int Host::createNetworkInterface (SVCHlpClient *aClient,2481 const Utf8Str &aName,2482 Guid &aGUID, Utf8Str &aErrMsg)2483 {2484 LogFlowFuncEnter();2485 LogFlowFunc (("Network connection name = '%s'\n", aName.raw()));2486 2487 AssertReturn (aClient, VERR_INVALID_POINTER);2488 AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER);2489 2490 int vrc = VINF_SUCCESS;2491 2492 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;2493 SP_DEVINFO_DATA DeviceInfoData;2494 DWORD ret = 0;2495 BOOL found = FALSE;2496 BOOL registered = FALSE;2497 BOOL destroyList = FALSE;2498 TCHAR pCfgGuidString [50];2499 2500 do2501 {2502 BOOL ok;2503 GUID netGuid;2504 SP_DRVINFO_DATA DriverInfoData;2505 SP_DEVINSTALL_PARAMS DeviceInstallParams;2506 TCHAR className [MAX_PATH];2507 DWORD index = 0;2508 PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;2509 /* for our purposes, 2k buffer is more2510 * than enough to obtain the hardware ID2511 * of the VBoxTAP driver. */2512 DWORD detailBuf [2048];2513 2514 HKEY hkey = NULL;2515 DWORD cbSize;2516 DWORD dwValueType;2517 2518 /* initialize the structure size */2519 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);2520 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);2521 2522 /* copy the net class GUID */2523 memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));2524 2525 /* create an empty device info set associated with the net class GUID */2526 hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);2527 if (hDeviceInfo == INVALID_HANDLE_VALUE)2528 SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",2529 GetLastError()));2530 2531 /* get the class name from GUID */2532 ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);2533 if (!ok)2534 SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",2535 GetLastError()));2536 2537 /* create a device info element and add the new device instance2538 * key to registry */2539 ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,2540 DICD_GENERATE_ID, &DeviceInfoData);2541 if (!ok)2542 SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",2543 GetLastError()));2544 2545 /* select the newly created device info to be the currently2546 selected member */2547 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);2548 if (!ok)2549 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",2550 GetLastError()));2551 2552 /* build a list of class drivers */2553 ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,2554 SPDIT_CLASSDRIVER);2555 if (!ok)2556 SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",2557 GetLastError()));2558 2559 destroyList = TRUE;2560 2561 /* enumerate the driver info list */2562 while (TRUE)2563 {2564 BOOL ret;2565 2566 ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,2567 SPDIT_CLASSDRIVER, index, &DriverInfoData);2568 2569 /* if the function failed and GetLastError() returned2570 * ERROR_NO_MORE_ITEMS, then we have reached the end of the2571 * list. Othewise there was something wrong with this2572 * particular driver. */2573 if (!ret)2574 {2575 if(GetLastError() == ERROR_NO_MORE_ITEMS)2576 break;2577 else2578 {2579 index++;2580 continue;2581 }2582 }2583 2584 pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;2585 pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);2586 2587 /* if we successfully find the hardware ID and it turns out to2588 * be the one for the loopback driver, then we are done. */2589 if (SetupDiGetDriverInfoDetail (hDeviceInfo,2590 &DeviceInfoData,2591 &DriverInfoData,2592 pDriverInfoDetail,2593 sizeof (detailBuf),2594 NULL))2595 {2596 TCHAR * t;2597 2598 /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the2599 * whole list and see if there is a match somewhere. */2600 t = pDriverInfoDetail->HardwareID;2601 while (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])])2602 {2603 if (!_tcsicmp(t, DRIVERHWID))2604 break;2605 2606 t += _tcslen(t) + 1;2607 }2608 2609 if (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])])2610 {2611 found = TRUE;2612 break;2613 }2614 }2615 2616 index ++;2617 }2618 2619 if (!found)2620 SetErrBreak ((tr ("Could not find Host Interface Networking driver! "2621 "Please reinstall")));2622 2623 /* set the loopback driver to be the currently selected */2624 ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,2625 &DriverInfoData);2626 if (!ok)2627 SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)",2628 GetLastError()));2629 2630 /* register the phantom device to prepare for install */2631 ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,2632 &DeviceInfoData);2633 if (!ok)2634 SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",2635 GetLastError()));2636 2637 /* registered, but remove if errors occur in the following code */2638 registered = TRUE;2639 2640 /* ask the installer if we can install the device */2641 ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,2642 &DeviceInfoData);2643 if (!ok)2644 {2645 if (GetLastError() != ERROR_DI_DO_DEFAULT)2646 SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",2647 GetLastError()));2648 /* that's fine */2649 }2650 2651 /* install the files first */2652 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,2653 &DeviceInfoData);2654 if (!ok)2655 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",2656 GetLastError()));2657 2658 /* get the device install parameters and disable filecopy */2659 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);2660 ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,2661 &DeviceInstallParams);2662 if (ok)2663 {2664 DeviceInstallParams.Flags |= DI_NOFILECOPY;2665 ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,2666 &DeviceInstallParams);2667 if (!ok)2668 SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",2669 GetLastError()));2670 }2671 2672 /*2673 * Register any device-specific co-installers for this device,2674 */2675 2676 ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,2677 hDeviceInfo,2678 &DeviceInfoData);2679 if (!ok)2680 SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",2681 GetLastError()));2682 2683 /*2684 * install any installer-specified interfaces.2685 * and then do the real install2686 */2687 ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,2688 hDeviceInfo,2689 &DeviceInfoData);2690 if (!ok)2691 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",2692 GetLastError()));2693 2694 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,2695 hDeviceInfo,2696 &DeviceInfoData);2697 if (!ok)2698 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",2699 GetLastError()));2700 2701 /* Figure out NetCfgInstanceId */2702 hkey = SetupDiOpenDevRegKey (hDeviceInfo,2703 &DeviceInfoData,2704 DICS_FLAG_GLOBAL,2705 0,2706 DIREG_DRV,2707 KEY_READ);2708 if (hkey == INVALID_HANDLE_VALUE)2709 SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",2710 GetLastError()));2711 2712 cbSize = sizeof (pCfgGuidString);2713 DWORD ret;2714 ret = RegQueryValueEx (hkey, _T ("NetCfgInstanceId"), NULL,2715 &dwValueType, (LPBYTE) pCfgGuidString, &cbSize);2716 RegCloseKey (hkey);2717 2718 ret = RenameConnection (pCfgGuidString, Bstr (aName));2719 if (FAILED (ret))2720 SetErrBreak (("Failed to set interface name (ret=0x%08X, "2721 "pCfgGuidString='%ls', cbSize=%d)",2722 ret, pCfgGuidString, cbSize));2723 }2724 while (0);2725 2726 /*2727 * cleanup2728 */2729 2730 if (hDeviceInfo != INVALID_HANDLE_VALUE)2731 {2732 /* an error has occured, but the device is registered, we must remove it */2733 if (ret != 0 && registered)2734 SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);2735 2736 found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);2737 2738 /* destroy the driver info list */2739 if (destroyList)2740 SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,2741 SPDIT_CLASSDRIVER);2742 /* clean up the device info set */2743 SetupDiDestroyDeviceInfoList (hDeviceInfo);2744 }2745 2746 /* return the network connection GUID on success */2747 if (RT_SUCCESS (vrc))2748 {2749 /* remove the curly bracket at the end */2750 pCfgGuidString [_tcslen (pCfgGuidString) - 1] = '\0';2751 LogFlowFunc (("Network connection GUID string = {%ls}\n", pCfgGuidString + 1));2752 2753 aGUID = Guid (Utf8Str (pCfgGuidString + 1));2754 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));2755 Assert (!aGUID.isEmpty());2756 }2757 2758 LogFlowFunc (("vrc=%Rrc\n", vrc));2759 LogFlowFuncLeave();2760 return vrc;2761 }2762 2763 /* static */2764 int Host::removeNetworkInterface (SVCHlpClient *aClient,2765 const Guid &aGUID,2766 Utf8Str &aErrMsg)2767 {2768 LogFlowFuncEnter();2769 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw()));2770 2771 AssertReturn (aClient, VERR_INVALID_POINTER);2772 AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);2773 2774 int vrc = VINF_SUCCESS;2775 2776 do2777 {2778 TCHAR lszPnPInstanceId [512] = {0};2779 2780 /* We have to find the device instance ID through a registry search */2781 2782 HKEY hkeyNetwork = 0;2783 HKEY hkeyConnection = 0;2784 2785 do2786 {2787 char strRegLocation [256];2788 sprintf (strRegLocation,2789 "SYSTEM\\CurrentControlSet\\Control\\Network\\"2790 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}",2791 aGUID.toString().raw());2792 LONG status;2793 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0,2794 KEY_READ, &hkeyNetwork);2795 if ((status != ERROR_SUCCESS) || !hkeyNetwork)2796 SetErrBreak ((2797 tr ("Host interface network is not found in registry (%s) [1]"),2798 strRegLocation));2799 2800 status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,2801 KEY_READ, &hkeyConnection);2802 if ((status != ERROR_SUCCESS) || !hkeyConnection)2803 SetErrBreak ((2804 tr ("Host interface network is not found in registry (%s) [2]"),2805 strRegLocation));2806 2807 DWORD len = sizeof (lszPnPInstanceId);2808 DWORD dwKeyType;2809 status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,2810 &dwKeyType, (LPBYTE) lszPnPInstanceId, &len);2811 if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))2812 SetErrBreak ((2813 tr ("Host interface network is not found in registry (%s) [3]"),2814 strRegLocation));2815 }2816 while (0);2817 2818 if (hkeyConnection)2819 RegCloseKey (hkeyConnection);2820 if (hkeyNetwork)2821 RegCloseKey (hkeyNetwork);2822 2823 if (RT_FAILURE (vrc))2824 break;2825 2826 /*2827 * Now we are going to enumerate all network devices and2828 * wait until we encounter the right device instance ID2829 */2830 2831 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;2832 2833 do2834 {2835 BOOL ok;2836 DWORD ret = 0;2837 GUID netGuid;2838 SP_DEVINFO_DATA DeviceInfoData;2839 DWORD index = 0;2840 BOOL found = FALSE;2841 DWORD size = 0;2842 2843 /* initialize the structure size */2844 DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);2845 2846 /* copy the net class GUID */2847 memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));2848 2849 /* return a device info set contains all installed devices of the Net class */2850 hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);2851 2852 if (hDeviceInfo == INVALID_HANDLE_VALUE)2853 SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));2854 2855 /* enumerate the driver info list */2856 while (TRUE)2857 {2858 TCHAR *deviceHwid;2859 2860 ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);2861 2862 if (!ok)2863 {2864 if (GetLastError() == ERROR_NO_MORE_ITEMS)2865 break;2866 else2867 {2868 index++;2869 continue;2870 }2871 }2872 2873 /* try to get the hardware ID registry property */2874 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,2875 &DeviceInfoData,2876 SPDRP_HARDWAREID,2877 NULL,2878 NULL,2879 0,2880 &size);2881 if (!ok)2882 {2883 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)2884 {2885 index++;2886 continue;2887 }2888 2889 deviceHwid = (TCHAR *) malloc (size);2890 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,2891 &DeviceInfoData,2892 SPDRP_HARDWAREID,2893 NULL,2894 (PBYTE)deviceHwid,2895 size,2896 NULL);2897 if (!ok)2898 {2899 free (deviceHwid);2900 deviceHwid = NULL;2901 index++;2902 continue;2903 }2904 }2905 else2906 {2907 /* something is wrong. This shouldn't have worked with a NULL buffer */2908 index++;2909 continue;2910 }2911 2912 for (TCHAR *t = deviceHwid;2913 t && *t && t < &deviceHwid[size / sizeof(TCHAR)];2914 t += _tcslen (t) + 1)2915 {2916 if (!_tcsicmp (DRIVERHWID, t))2917 {2918 /* get the device instance ID */2919 TCHAR devID [MAX_DEVICE_ID_LEN];2920 if (CM_Get_Device_ID(DeviceInfoData.DevInst,2921 devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)2922 {2923 /* compare to what we determined before */2924 if (wcscmp(devID, lszPnPInstanceId) == 0)2925 {2926 found = TRUE;2927 break;2928 }2929 }2930 }2931 }2932 2933 if (deviceHwid)2934 {2935 free (deviceHwid);2936 deviceHwid = NULL;2937 }2938 2939 if (found)2940 break;2941 2942 index++;2943 }2944 2945 if (found == FALSE)2946 SetErrBreak ((tr ("Host Interface Network driver not found (0x%08X)"),2947 GetLastError()));2948 2949 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);2950 if (!ok)2951 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",2952 GetLastError()));2953 2954 ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);2955 if (!ok)2956 SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",2957 GetLastError()));2958 }2959 while (0);2960 2961 /* clean up the device info set */2962 if (hDeviceInfo != INVALID_HANDLE_VALUE)2963 SetupDiDestroyDeviceInfoList (hDeviceInfo);2964 2965 if (RT_FAILURE (vrc))2966 break;2967 }2968 while (0);2969 2970 LogFlowFunc (("vrc=%Rrc\n", vrc));2971 LogFlowFuncLeave();2972 return vrc;2973 }2974 2975 #undef SetErrBreak2976 2977 /* static */2978 HRESULT Host::networkInterfaceHelperClient (SVCHlpClient *aClient,2979 Progress *aProgress,2980 void *aUser, int *aVrc)2981 {2982 LogFlowFuncEnter();2983 LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n",2984 aClient, aProgress, aUser));2985 2986 AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) ||2987 (aClient != NULL && aProgress != NULL && aVrc != NULL),2988 E_POINTER);2989 AssertReturn (aUser, E_POINTER);2990 2991 std::auto_ptr <NetworkInterfaceHelperClientData>2992 d (static_cast <NetworkInterfaceHelperClientData *> (aUser));2993 2994 if (aClient == NULL)2995 {2996 /* "cleanup only" mode, just return (it will free aUser) */2997 return S_OK;2998 }2999 3000 HRESULT rc = S_OK;3001 int vrc = VINF_SUCCESS;3002 3003 switch (d->msgCode)3004 {3005 case SVCHlpMsg::CreateHostOnlyNetworkInterface:3006 {3007 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));3008 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));3009 3010 /* write message and parameters */3011 vrc = aClient->write (d->msgCode);3012 if (RT_FAILURE (vrc)) break;3013 vrc = aClient->write (Utf8Str (d->name));3014 if (RT_FAILURE (vrc)) break;3015 3016 /* wait for a reply */3017 bool endLoop = false;3018 while (!endLoop)3019 {3020 SVCHlpMsg::Code reply = SVCHlpMsg::Null;3021 3022 vrc = aClient->read (reply);3023 if (RT_FAILURE (vrc)) break;3024 3025 switch (reply)3026 {3027 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:3028 {3029 /* read the GUID */3030 Guid guid;3031 vrc = aClient->read (guid);3032 if (RT_FAILURE (vrc)) break;3033 3034 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", guid.raw()));3035 3036 /* initialize the object returned to the caller by3037 * CreateHostOnlyNetworkInterface() */3038 rc = d->iface->init (d->name, guid, HostNetworkInterfaceType_HostOnly);3039 endLoop = true;3040 break;3041 }3042 case SVCHlpMsg::Error:3043 {3044 /* read the error message */3045 Utf8Str errMsg;3046 vrc = aClient->read (errMsg);3047 if (RT_FAILURE (vrc)) break;3048 3049 rc = setError (E_FAIL, errMsg);3050 endLoop = true;3051 break;3052 }3053 default:3054 {3055 endLoop = true;3056 ComAssertMsgFailedBreak ((3057 "Invalid message code %d (%08lX)\n",3058 reply, reply),3059 rc = E_FAIL);3060 }3061 }3062 }3063 3064 break;3065 }3066 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:3067 {3068 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));3069 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", d->guid.raw()));3070 3071 /* write message and parameters */3072 vrc = aClient->write (d->msgCode);3073 if (RT_FAILURE (vrc)) break;3074 vrc = aClient->write (d->guid);3075 if (RT_FAILURE (vrc)) break;3076 3077 /* wait for a reply */3078 bool endLoop = false;3079 while (!endLoop)3080 {3081 SVCHlpMsg::Code reply = SVCHlpMsg::Null;3082 3083 vrc = aClient->read (reply);3084 if (RT_FAILURE (vrc)) break;3085 3086 switch (reply)3087 {3088 case SVCHlpMsg::OK:3089 {3090 /* no parameters */3091 rc = S_OK;3092 endLoop = true;3093 break;3094 }3095 case SVCHlpMsg::Error:3096 {3097 /* read the error message */3098 Utf8Str errMsg;3099 vrc = aClient->read (errMsg);3100 if (RT_FAILURE (vrc)) break;3101 3102 rc = setError (E_FAIL, errMsg);3103 endLoop = true;3104 break;3105 }3106 default:3107 {3108 endLoop = true;3109 ComAssertMsgFailedBreak ((3110 "Invalid message code %d (%08lX)\n",3111 reply, reply),3112 rc = E_FAIL);3113 }3114 }3115 }3116 3117 break;3118 }3119 default:3120 ComAssertMsgFailedBreak ((3121 "Invalid message code %d (%08lX)\n",3122 d->msgCode, d->msgCode),3123 rc = E_FAIL);3124 }3125 3126 if (aVrc)3127 *aVrc = vrc;3128 3129 LogFlowFunc (("rc=0x%08X, vrc=%Rrc\n", rc, vrc));3130 LogFlowFuncLeave();3131 return rc;3132 }3133 3134 /* static */3135 int Host::networkInterfaceHelperServer (SVCHlpClient *aClient,3136 SVCHlpMsg::Code aMsgCode)3137 {3138 LogFlowFuncEnter();3139 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));3140 3141 AssertReturn (aClient, VERR_INVALID_POINTER);3142 3143 int vrc = VINF_SUCCESS;3144 3145 switch (aMsgCode)3146 {3147 case SVCHlpMsg::CreateHostOnlyNetworkInterface:3148 {3149 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n"));3150 3151 Utf8Str name;3152 vrc = aClient->read (name);3153 if (RT_FAILURE (vrc)) break;3154 3155 Guid guid;3156 Utf8Str errMsg;3157 vrc = createNetworkInterface (aClient, name, guid, errMsg);3158 3159 if (RT_SUCCESS (vrc))3160 {3161 /* write success followed by GUID */3162 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);3163 if (RT_FAILURE (vrc)) break;3164 vrc = aClient->write (guid);3165 if (RT_FAILURE (vrc)) break;3166 }3167 else3168 {3169 /* write failure followed by error message */3170 if (errMsg.isEmpty())3171 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);3172 vrc = aClient->write (SVCHlpMsg::Error);3173 if (RT_FAILURE (vrc)) break;3174 vrc = aClient->write (errMsg);3175 if (RT_FAILURE (vrc)) break;3176 }3177 3178 break;3179 }3180 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:3181 {3182 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n"));3183 3184 Guid guid;3185 vrc = aClient->read (guid);3186 if (RT_FAILURE (vrc)) break;3187 3188 Utf8Str errMsg;3189 vrc = removeNetworkInterface (aClient, guid, errMsg);3190 3191 if (RT_SUCCESS (vrc))3192 {3193 /* write parameter-less success */3194 vrc = aClient->write (SVCHlpMsg::OK);3195 if (RT_FAILURE (vrc)) break;3196 }3197 else3198 {3199 /* write failure followed by error message */3200 if (errMsg.isEmpty())3201 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc);3202 vrc = aClient->write (SVCHlpMsg::Error);3203 if (RT_FAILURE (vrc)) break;3204 vrc = aClient->write (errMsg);3205 if (RT_FAILURE (vrc)) break;3206 }3207 3208 break;3209 }3210 default:3211 AssertMsgFailedBreakStmt (3212 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),3213 VERR_GENERAL_FAILURE);3214 }3215 3216 LogFlowFunc (("vrc=%Rrc\n", vrc));3217 LogFlowFuncLeave();3218 return vrc;3219 }3220 3221 #endif /* RT_OS_WINDOWS */3222 3223 2244 #ifdef VBOX_WITH_RESOURCE_USAGE_API 3224 2245 void Host::registerMetrics (PerformanceCollector *aCollector) … … 3417 2438 "The host network interface with the given name could not be found")); 3418 2439 2440 found->setVirtualBox(mParent); 2441 3419 2442 return found.queryInterfaceTo (networkInterface); 3420 2443 #endif … … 3453 2476 "The host network interface with the given GUID could not be found")); 3454 2477 2478 found->setVirtualBox(mParent); 2479 3455 2480 return found.queryInterfaceTo (networkInterface); 3456 2481 #endif … … 3459 2484 STDMETHODIMP Host::FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_T type, ComSafeArrayOut (IHostNetworkInterface *, aNetworkInterfaces)) 3460 2485 { 3461 com::SafeIfaceArray <IHostNetworkInterface> hostNetworkInterfaces; 3462 HRESULT hr = COMGETTER(NetworkInterfaces) (ComSafeArrayAsOutParam (hostNetworkInterfaces)); 3463 if(FAILED(hr)) 3464 { 3465 return hr; 3466 } 3467 3468 std::list <ComObjPtr <IHostNetworkInterface> > list; 3469 3470 for (size_t i = 0; i < hostNetworkInterfaces.size(); ++i) 3471 { 3472 IHostNetworkInterface * networkInterface = hostNetworkInterfaces[i]; 2486 std::list <ComObjPtr <HostNetworkInterface> > allList; 2487 int rc = NetIfList(allList); 2488 if(RT_FAILURE(rc)) 2489 return E_FAIL; 2490 2491 std::list <ComObjPtr <HostNetworkInterface> > resultList; 2492 2493 std::list <ComObjPtr <HostNetworkInterface> >::iterator it; 2494 for (it = allList.begin(); it != allList.end(); ++it) 2495 { 3473 2496 HostNetworkInterfaceType_T t; 3474 hr = networkInterface->COMGETTER(InterfaceType)(&t);2497 HRESULT hr = (*it)->COMGETTER(InterfaceType)(&t); 3475 2498 if(FAILED(hr)) 3476 {3477 2499 return hr; 3478 }3479 2500 3480 2501 if(t == type) 3481 2502 { 3482 list.push_back (networkInterface); 3483 } 3484 } 3485 3486 SafeIfaceArray <IHostNetworkInterface> filteredNetworkInterfaces (list); 2503 (*it)->setVirtualBox(mParent); 2504 resultList.push_back (*it); 2505 } 2506 } 2507 2508 SafeIfaceArray <IHostNetworkInterface> filteredNetworkInterfaces (resultList); 3487 2509 filteredNetworkInterfaces.detachTo (ComSafeArrayOutArg (aNetworkInterfaces)); 3488 2510 -
trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp
r17419 r17494 76 76 #ifdef VBOX_WITH_HOSTNETIF_API 77 77 78 HRESULT HostNetworkInterface::updateConfig (struct NETIFINFO *pIf) 79 { 78 HRESULT HostNetworkInterface::updateConfig () 79 { 80 NETIFINFO info; 81 int rc = NetIfGetConfig(this, &info); 82 if(RT_SUCCESS(rc)) 83 { 84 m.IPAddress = info.IPAddress.u; 85 m.networkMask = info.IPNetMask.u; 86 m.IPV6Address = composeIPv6Address(&info.IPv6Address); 87 m.IPV6NetworkMask = composeIPv6Address(&info.IPv6NetMask); 88 m.hardwareAddress = composeHardwareAddress(&info.MACAddress); 89 #ifdef RT_OS_WINDOWS 90 m.mediumType = (HostNetworkInterfaceMediumType)info.enmMediumType; 91 m.status = (HostNetworkInterfaceStatus)info.enmStatus; 92 #else /* !RT_OS_WINDOWS */ 93 m.mediumType = info.enmMediumType; 94 m.status = info.enmStatus; 95 96 #endif /* !RT_OS_WINDOWS */ 97 return S_OK; 98 } 99 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; 100 } 101 102 /** 103 * Initializes the host object. 104 * 105 * @returns COM result indicator 106 * @param aInterfaceName name of the network interface 107 * @param aGuid GUID of the host network interface 108 */ 109 HRESULT HostNetworkInterface::init (Bstr aInterfaceName, HostNetworkInterfaceType_T ifType, PNETIFINFO pIf) 110 { 111 // LogFlowThisFunc (("aInterfaceName={%ls}, aGuid={%s}\n", 112 // aInterfaceName.raw(), aGuid.toString().raw())); 113 114 // ComAssertRet (aInterfaceName, E_INVALIDARG); 115 // ComAssertRet (!aGuid.isEmpty(), E_INVALIDARG); 116 ComAssertRet (pIf, E_INVALIDARG); 117 118 /* Enclose the state transition NotReady->InInit->Ready */ 119 AutoInitSpan autoInitSpan (this); 120 AssertReturn (autoInitSpan.isOk(), E_FAIL); 121 122 unconst (mInterfaceName) = aInterfaceName; 123 unconst (mGuid) = pIf->Uuid; 124 mIfType = ifType; 125 80 126 m.IPAddress = pIf->IPAddress.u; 81 127 m.networkMask = pIf->IPNetMask.u; … … 91 137 #endif /* !RT_OS_WINDOWS */ 92 138 93 return S_OK;94 }95 96 /**97 * Initializes the host object.98 *99 * @returns COM result indicator100 * @param aInterfaceName name of the network interface101 * @param aGuid GUID of the host network interface102 */103 HRESULT HostNetworkInterface::init (Bstr aInterfaceName, HostNetworkInterfaceType_T ifType, PNETIFINFO pIf)104 {105 // LogFlowThisFunc (("aInterfaceName={%ls}, aGuid={%s}\n",106 // aInterfaceName.raw(), aGuid.toString().raw()));107 108 // ComAssertRet (aInterfaceName, E_INVALIDARG);109 // ComAssertRet (!aGuid.isEmpty(), E_INVALIDARG);110 ComAssertRet (pIf, E_INVALIDARG);111 112 /* Enclose the state transition NotReady->InInit->Ready */113 AutoInitSpan autoInitSpan (this);114 AssertReturn (autoInitSpan.isOk(), E_FAIL);115 116 unconst (mInterfaceName) = aInterfaceName;117 unconst (mGuid) = pIf->Uuid;118 mIfType = ifType;119 120 updateConfig(pIf);121 122 139 /* Confirm a successful initialization */ 123 140 autoInitSpan.setSucceeded(); … … 380 397 } 381 398 399 HRESULT HostNetworkInterface::setVirtualBox(VirtualBox *pVBox) 400 { 401 AutoCaller autoCaller (this); 402 CheckComRCReturnRC (autoCaller.rc()); 403 mVBox = pVBox; 404 405 return S_OK; 406 } 407 408 HRESULT HostNetworkInterface::getVirtualBox(VirtualBox **ppVBox) 409 { 410 AutoCaller autoCaller (this); 411 CheckComRCReturnRC (autoCaller.rc()); 412 413 if (!ppVBox) 414 return E_INVALIDARG; 415 416 *ppVBox = mVBox; 417 return S_OK; 418 } 419 382 420 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/generic/NetIf-generic.cpp
r17490 r17494 37 37 return VERR_NOT_IMPLEMENTED; 38 38 } 39 40 int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVbox, IN_BSTR aName, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress) 41 { 42 return VERR_NOT_IMPLEMENTED; 43 } 44 45 int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVbox, IN_GUID aId, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress) 46 { 47 return VERR_NOT_IMPLEMENTED; 48 } 49 50 int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *) 51 { 52 return VERR_NOT_IMPLEMENTED; 53 } -
trunk/src/VBox/Main/include/HostImpl.h
r17394 r17494 33 33 #endif 34 34 #include "HostPower.h" 35 36 #ifdef RT_OS_WINDOWS37 # include "win/svchlp.h"38 #endif39 35 40 36 #ifdef RT_OS_LINUX … … 133 129 #endif /* !VBOX_WITH_USB */ 134 130 135 #ifdef RT_OS_WINDOWS136 static int networkInterfaceHelperServer (SVCHlpClient *aClient,137 SVCHlpMsg::Code aMsgCode);138 #endif139 140 131 // for VirtualBoxSupportErrorInfoImpl 141 132 static const wchar_t *getComponentName() { return L"Host"; } … … 162 153 } 163 154 #endif /* VBOX_WITH_USB */ 164 165 #ifdef RT_OS_WINDOWS166 static int createNetworkInterface (SVCHlpClient *aClient,167 const Utf8Str &aName,168 Guid &aGUID, Utf8Str &aErrMsg);169 static int removeNetworkInterface (SVCHlpClient *aClient,170 const Guid &aGUID,171 Utf8Str &aErrMsg);172 static HRESULT networkInterfaceHelperClient (SVCHlpClient *aClient,173 Progress *aProgress,174 void *aUser, int *aVrc);175 #endif176 155 177 156 #ifdef VBOX_WITH_RESOURCE_USAGE_API -
trunk/src/VBox/Main/include/HostNetworkInterfaceImpl.h
r17419 r17494 63 63 #ifdef VBOX_WITH_HOSTNETIF_API 64 64 HRESULT init (Bstr aInterfaceName, HostNetworkInterfaceType_T ifType, struct NETIFINFO *pIfs); 65 HRESULT updateConfig ( struct NETIFINFO *pIfs);65 HRESULT updateConfig (); 66 66 #endif 67 67 … … 86 86 static const wchar_t *getComponentName() { return L"HostNetworkInterface"; } 87 87 88 HRESULT setVirtualBox(VirtualBox *pVBox); 89 HRESULT getVirtualBox(VirtualBox **ppVBox); 88 90 private: 89 91 const Bstr mInterfaceName; 90 92 const Guid mGuid; 91 93 HostNetworkInterfaceType_T mIfType; 94 95 ComObjPtr <VirtualBox, ComWeakRef> mVBox; 92 96 93 97 struct Data -
trunk/src/VBox/Main/include/netif.h
r17447 r17494 80 80 int NetIfEnableStaticIpConfigV6(HostNetworkInterface * pIf, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength); 81 81 int NetIfEnableDynamicIpConfig(HostNetworkInterface * pIf); 82 int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVbox, IN_BSTR aName, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress); 83 int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVbox, IN_GUID aId, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress); 84 int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *); 82 85 83 86 DECLINLINE(Bstr) composeIPv6Address(PRTNETADDRIPV6 aAddrPtr) -
trunk/src/VBox/Main/win/NetIfList-win.cpp
r17419 r17494 45 45 #include "Logging.h" 46 46 #include "HostNetworkInterfaceImpl.h" 47 #include "ProgressImpl.h" 48 #include "VirtualBoxImpl.h" 47 49 #include "netif.h" 48 50 … … 50 52 #include <Wbemidl.h> 51 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 52 66 53 67 static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc) … … 620 634 } 621 635 622 static HRESULT netIfWinUpdateConfig(HostNetworkInterface * pIf)623 {624 NETIFINFO Info;625 memset(&Info, 0, sizeof(Info));626 GUID guid;627 HRESULT hr = pIf->COMGETTER(Id) (&guid);628 if(SUCCEEDED(hr))629 {630 Info.Uuid = (RTUUID)*(RTUUID*)&guid;631 BSTR name;632 hr = pIf->COMGETTER(Name) (&name);633 Assert(hr == S_OK);634 if(hr == S_OK)635 {636 int rc = collectNetIfInfo(Bstr(name), &Info);637 if (RT_SUCCESS(rc))638 {639 hr = pIf->updateConfig(&Info);640 }641 else642 {643 Log(("netIfWinUpdateConfig: collectNetIfInfo() -> %Vrc\n", rc));644 hr = E_FAIL;645 }646 }647 }648 649 return hr;650 }636 //static HRESULT netIfWinUpdateConfig(HostNetworkInterface * pIf) 637 //{ 638 // NETIFINFO Info; 639 // memset(&Info, 0, sizeof(Info)); 640 // GUID guid; 641 // HRESULT hr = pIf->COMGETTER(Id) (&guid); 642 // if(SUCCEEDED(hr)) 643 // { 644 // Info.Uuid = (RTUUID)*(RTUUID*)&guid; 645 // BSTR name; 646 // hr = pIf->COMGETTER(Name) (&name); 647 // Assert(hr == S_OK); 648 // if(hr == S_OK) 649 // { 650 // int rc = collectNetIfInfo(Bstr(name), &Info); 651 // if (RT_SUCCESS(rc)) 652 // { 653 // hr = pIf->updateConfig(&Info); 654 // } 655 // else 656 // { 657 // Log(("netIfWinUpdateConfig: collectNetIfInfo() -> %Vrc\n", rc)); 658 // hr = E_FAIL; 659 // } 660 // } 661 // } 662 // 663 // return hr; 664 //} 651 665 652 666 int NetIfEnableStaticIpConfig(HostNetworkInterface * pIf, ULONG ip, ULONG mask) … … 684 698 #endif 685 699 { 686 hr = netIfWinUpdateConfig(pIf);700 // hr = netIfWinUpdateConfig(pIf); 687 701 } 688 702 } … … 724 738 if(SUCCEEDED(hr)) 725 739 { 726 hr = netIfWinUpdateConfig(pIf);740 // hr = netIfWinUpdateConfig(pIf); 727 741 } 728 742 } … … 770 784 if(SUCCEEDED(hr)) 771 785 { 772 hr = netIfWinUpdateConfig(pIf);786 // hr = netIfWinUpdateConfig(pIf); 773 787 } 774 788 SysFreeString(ObjPath); … … 779 793 780 794 return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 795 } 796 797 /* svc helper func */ 798 799 struct StaticIpConfig 800 { 801 RTNETADDRIPV4 IPAddress; 802 RTNETADDRIPV4 IPNetMask; 803 }; 804 805 struct StaticIpV6Config 806 { 807 RTNETADDRIPV6 IPV6Address; 808 RTNETADDRIPV6 IPV6NetMaskLength; 809 }; 810 811 struct NetworkInterfaceHelperClientData 812 { 813 SVCHlpMsg::Code msgCode; 814 /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */ 815 Bstr name; 816 ComObjPtr <HostNetworkInterface> iface; 817 /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */ 818 Guid guid; 819 820 union 821 { 822 StaticIpConfig StaticIP; 823 StaticIpV6Config StaticIPV6; 824 } u; 825 826 827 }; 828 829 static HRESULT netIfNetworkInterfaceHelperClient (SVCHlpClient *aClient, 830 Progress *aProgress, 831 void *aUser, int *aVrc) 832 { 833 LogFlowFuncEnter(); 834 LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n", 835 aClient, aProgress, aUser)); 836 837 AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) || 838 (aClient != NULL && aProgress != NULL && aVrc != NULL), 839 E_POINTER); 840 AssertReturn (aUser, E_POINTER); 841 842 std::auto_ptr <NetworkInterfaceHelperClientData> 843 d (static_cast <NetworkInterfaceHelperClientData *> (aUser)); 844 845 if (aClient == NULL) 846 { 847 /* "cleanup only" mode, just return (it will free aUser) */ 848 return S_OK; 849 } 850 851 HRESULT rc = S_OK; 852 int vrc = VINF_SUCCESS; 853 854 switch (d->msgCode) 855 { 856 case SVCHlpMsg::CreateHostOnlyNetworkInterface: 857 { 858 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n")); 859 LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw())); 860 861 /* write message and parameters */ 862 vrc = aClient->write (d->msgCode); 863 if (RT_FAILURE (vrc)) break; 864 vrc = aClient->write (Utf8Str (d->name)); 865 if (RT_FAILURE (vrc)) break; 866 867 /* wait for a reply */ 868 bool endLoop = false; 869 while (!endLoop) 870 { 871 SVCHlpMsg::Code reply = SVCHlpMsg::Null; 872 873 vrc = aClient->read (reply); 874 if (RT_FAILURE (vrc)) break; 875 876 switch (reply) 877 { 878 case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK: 879 { 880 /* read the GUID */ 881 Guid guid; 882 vrc = aClient->read (guid); 883 if (RT_FAILURE (vrc)) break; 884 885 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", guid.raw())); 886 887 /* initialize the object returned to the caller by 888 * CreateHostOnlyNetworkInterface() */ 889 rc = d->iface->init (d->name, guid, HostNetworkInterfaceType_HostOnly); 890 endLoop = true; 891 break; 892 } 893 case SVCHlpMsg::Error: 894 { 895 /* read the error message */ 896 Utf8Str errMsg; 897 vrc = aClient->read (errMsg); 898 if (RT_FAILURE (vrc)) break; 899 900 rc = E_FAIL;//TODO: setError (E_FAIL, errMsg); 901 endLoop = true; 902 break; 903 } 904 default: 905 { 906 endLoop = true; 907 ComAssertMsgFailedBreak (( 908 "Invalid message code %d (%08lX)\n", 909 reply, reply), 910 rc = E_FAIL); 911 } 912 } 913 } 914 915 break; 916 } 917 case SVCHlpMsg::RemoveHostOnlyNetworkInterface: 918 { 919 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n")); 920 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", d->guid.raw())); 921 922 /* write message and parameters */ 923 vrc = aClient->write (d->msgCode); 924 if (RT_FAILURE (vrc)) break; 925 vrc = aClient->write (d->guid); 926 if (RT_FAILURE (vrc)) break; 927 928 /* wait for a reply */ 929 bool endLoop = false; 930 while (!endLoop) 931 { 932 SVCHlpMsg::Code reply = SVCHlpMsg::Null; 933 934 vrc = aClient->read (reply); 935 if (RT_FAILURE (vrc)) break; 936 937 switch (reply) 938 { 939 case SVCHlpMsg::OK: 940 { 941 /* no parameters */ 942 rc = S_OK; 943 endLoop = true; 944 break; 945 } 946 case SVCHlpMsg::Error: 947 { 948 /* read the error message */ 949 Utf8Str errMsg; 950 vrc = aClient->read (errMsg); 951 if (RT_FAILURE (vrc)) break; 952 953 rc = E_FAIL; // TODO: setError (E_FAIL, errMsg); 954 endLoop = true; 955 break; 956 } 957 default: 958 { 959 endLoop = true; 960 ComAssertMsgFailedBreak (( 961 "Invalid message code %d (%08lX)\n", 962 reply, reply), 963 rc = E_FAIL); 964 } 965 } 966 } 967 968 break; 969 } 970 default: 971 ComAssertMsgFailedBreak (( 972 "Invalid message code %d (%08lX)\n", 973 d->msgCode, d->msgCode), 974 rc = E_FAIL); 975 } 976 977 if (aVrc) 978 *aVrc = vrc; 979 980 LogFlowFunc (("rc=0x%08X, vrc=%Rrc\n", rc, vrc)); 981 LogFlowFuncLeave(); 982 return rc; 983 } 984 985 986 /* The original source of the VBoxTAP adapter creation/destruction code has the following copyright */ 987 /* 988 Copyright 2004 by the Massachusetts Institute of Technology 989 990 All rights reserved. 991 992 Permission to use, copy, modify, and distribute this software and its 993 documentation for any purpose and without fee is hereby granted, 994 provided that the above copyright notice appear in all copies and that 995 both that copyright notice and this permission notice appear in 996 supporting documentation, and that the name of the Massachusetts 997 Institute of Technology (M.I.T.) not be used in advertising or publicity 998 pertaining to distribution of the software without specific, written 999 prior permission. 1000 1001 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1002 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 1003 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1004 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 1005 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 1006 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 1007 SOFTWARE. 1008 */ 1009 1010 1011 #define NETSHELL_LIBRARY _T("netshell.dll") 1012 1013 /** 1014 * Use the IShellFolder API to rename the connection. 1015 */ 1016 static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName) 1017 { 1018 /* This is the GUID for the network connections folder. It is constant. 1019 * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */ 1020 const GUID CLSID_NetworkConnections = { 1021 0x7007ACC7, 0x3202, 0x11D1, { 1022 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E 1023 } 1024 }; 1025 1026 LPITEMIDLIST pidl = NULL; 1027 IShellFolder *pShellFolder = NULL; 1028 HRESULT hr; 1029 1030 /* Build the display name in the form "::{GUID}". */ 1031 if (wcslen (wGuid) >= MAX_PATH) 1032 return E_INVALIDARG; 1033 WCHAR szAdapterGuid[MAX_PATH + 2] = {0}; 1034 swprintf (szAdapterGuid, L"::%ls", wGuid); 1035 1036 /* Create an instance of the network connections folder. */ 1037 hr = CoCreateInstance (CLSID_NetworkConnections, NULL, 1038 CLSCTX_INPROC_SERVER, IID_IShellFolder, 1039 reinterpret_cast <LPVOID *> (&pShellFolder)); 1040 /* Parse the display name. */ 1041 if (SUCCEEDED (hr)) 1042 { 1043 hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL, 1044 &pidl, NULL); 1045 } 1046 if (SUCCEEDED (hr)) 1047 { 1048 hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL, 1049 &pidl); 1050 } 1051 1052 CoTaskMemFree (pidl); 1053 1054 if (pShellFolder) 1055 pShellFolder->Release(); 1056 1057 return hr; 1058 } 1059 1060 extern "C" HRESULT RenameConnection (PCWSTR GuidString, PCWSTR NewName) 1061 { 1062 typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR); 1063 lpHrRenameConnection RenameConnectionFunc = NULL; 1064 HRESULT status; 1065 1066 /* First try the IShellFolder interface, which was unimplemented 1067 * for the network connections folder before XP. */ 1068 status = rename_shellfolder (GuidString, NewName); 1069 if (status == E_NOTIMPL) 1070 { 1071 /** @todo that code doesn't seem to work! */ 1072 /* The IShellFolder interface is not implemented on this platform. 1073 * Try the (undocumented) HrRenameConnection API in the netshell 1074 * library. */ 1075 CLSID clsid; 1076 HINSTANCE hNetShell; 1077 status = CLSIDFromString ((LPOLESTR) GuidString, &clsid); 1078 if (FAILED(status)) 1079 return E_FAIL; 1080 hNetShell = LoadLibrary (NETSHELL_LIBRARY); 1081 if (hNetShell == NULL) 1082 return E_FAIL; 1083 RenameConnectionFunc = 1084 (lpHrRenameConnection) GetProcAddress (hNetShell, 1085 "HrRenameConnection"); 1086 if (RenameConnectionFunc == NULL) 1087 { 1088 FreeLibrary (hNetShell); 1089 return E_FAIL; 1090 } 1091 status = RenameConnectionFunc (&clsid, NewName); 1092 FreeLibrary (hNetShell); 1093 } 1094 if (FAILED (status)) 1095 return status; 1096 1097 return S_OK; 1098 } 1099 1100 #define DRIVERHWID _T("sun_VBoxNetAdp") 1101 1102 #define SetErrBreak(strAndArgs) \ 1103 if (1) { \ 1104 aErrMsg = Utf8StrFmt strAndArgs; vrc = VERR_GENERAL_FAILURE; break; \ 1105 } else do {} while (0) 1106 1107 /* static */ 1108 static int createNetworkInterface (SVCHlpClient *aClient, 1109 const Utf8Str &aName, 1110 Guid &aGUID, Utf8Str &aErrMsg) 1111 { 1112 LogFlowFuncEnter(); 1113 LogFlowFunc (("Network connection name = '%s'\n", aName.raw())); 1114 1115 AssertReturn (aClient, VERR_INVALID_POINTER); 1116 AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER); 1117 1118 int vrc = VINF_SUCCESS; 1119 1120 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; 1121 SP_DEVINFO_DATA DeviceInfoData; 1122 DWORD ret = 0; 1123 BOOL found = FALSE; 1124 BOOL registered = FALSE; 1125 BOOL destroyList = FALSE; 1126 TCHAR pCfgGuidString [50]; 1127 1128 do 1129 { 1130 BOOL ok; 1131 GUID netGuid; 1132 SP_DRVINFO_DATA DriverInfoData; 1133 SP_DEVINSTALL_PARAMS DeviceInstallParams; 1134 TCHAR className [MAX_PATH]; 1135 DWORD index = 0; 1136 PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; 1137 /* for our purposes, 2k buffer is more 1138 * than enough to obtain the hardware ID 1139 * of the VBoxTAP driver. */ 1140 DWORD detailBuf [2048]; 1141 1142 HKEY hkey = NULL; 1143 DWORD cbSize; 1144 DWORD dwValueType; 1145 1146 /* initialize the structure size */ 1147 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 1148 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); 1149 1150 /* copy the net class GUID */ 1151 memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); 1152 1153 /* create an empty device info set associated with the net class GUID */ 1154 hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL); 1155 if (hDeviceInfo == INVALID_HANDLE_VALUE) 1156 SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)", 1157 GetLastError())); 1158 1159 /* get the class name from GUID */ 1160 ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL); 1161 if (!ok) 1162 SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)", 1163 GetLastError())); 1164 1165 /* create a device info element and add the new device instance 1166 * key to registry */ 1167 ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL, 1168 DICD_GENERATE_ID, &DeviceInfoData); 1169 if (!ok) 1170 SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)", 1171 GetLastError())); 1172 1173 /* select the newly created device info to be the currently 1174 selected member */ 1175 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); 1176 if (!ok) 1177 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)", 1178 GetLastError())); 1179 1180 /* build a list of class drivers */ 1181 ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData, 1182 SPDIT_CLASSDRIVER); 1183 if (!ok) 1184 SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)", 1185 GetLastError())); 1186 1187 destroyList = TRUE; 1188 1189 /* enumerate the driver info list */ 1190 while (TRUE) 1191 { 1192 BOOL ret; 1193 1194 ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData, 1195 SPDIT_CLASSDRIVER, index, &DriverInfoData); 1196 1197 /* if the function failed and GetLastError() returned 1198 * ERROR_NO_MORE_ITEMS, then we have reached the end of the 1199 * list. Othewise there was something wrong with this 1200 * particular driver. */ 1201 if (!ret) 1202 { 1203 if(GetLastError() == ERROR_NO_MORE_ITEMS) 1204 break; 1205 else 1206 { 1207 index++; 1208 continue; 1209 } 1210 } 1211 1212 pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; 1213 pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); 1214 1215 /* if we successfully find the hardware ID and it turns out to 1216 * be the one for the loopback driver, then we are done. */ 1217 if (SetupDiGetDriverInfoDetail (hDeviceInfo, 1218 &DeviceInfoData, 1219 &DriverInfoData, 1220 pDriverInfoDetail, 1221 sizeof (detailBuf), 1222 NULL)) 1223 { 1224 TCHAR * t; 1225 1226 /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the 1227 * whole list and see if there is a match somewhere. */ 1228 t = pDriverInfoDetail->HardwareID; 1229 while (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])]) 1230 { 1231 if (!_tcsicmp(t, DRIVERHWID)) 1232 break; 1233 1234 t += _tcslen(t) + 1; 1235 } 1236 1237 if (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])]) 1238 { 1239 found = TRUE; 1240 break; 1241 } 1242 } 1243 1244 index ++; 1245 } 1246 1247 if (!found) 1248 SetErrBreak (("Could not find Host Interface Networking driver! " 1249 "Please reinstall")); 1250 1251 /* set the loopback driver to be the currently selected */ 1252 ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData, 1253 &DriverInfoData); 1254 if (!ok) 1255 SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)", 1256 GetLastError())); 1257 1258 /* register the phantom device to prepare for install */ 1259 ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo, 1260 &DeviceInfoData); 1261 if (!ok) 1262 SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)", 1263 GetLastError())); 1264 1265 /* registered, but remove if errors occur in the following code */ 1266 registered = TRUE; 1267 1268 /* ask the installer if we can install the device */ 1269 ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo, 1270 &DeviceInfoData); 1271 if (!ok) 1272 { 1273 if (GetLastError() != ERROR_DI_DO_DEFAULT) 1274 SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)", 1275 GetLastError())); 1276 /* that's fine */ 1277 } 1278 1279 /* install the files first */ 1280 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo, 1281 &DeviceInfoData); 1282 if (!ok) 1283 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)", 1284 GetLastError())); 1285 1286 /* get the device install parameters and disable filecopy */ 1287 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 1288 ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, 1289 &DeviceInstallParams); 1290 if (ok) 1291 { 1292 DeviceInstallParams.Flags |= DI_NOFILECOPY; 1293 ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, 1294 &DeviceInstallParams); 1295 if (!ok) 1296 SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)", 1297 GetLastError())); 1298 } 1299 1300 /* 1301 * Register any device-specific co-installers for this device, 1302 */ 1303 1304 ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS, 1305 hDeviceInfo, 1306 &DeviceInfoData); 1307 if (!ok) 1308 SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)", 1309 GetLastError())); 1310 1311 /* 1312 * install any installer-specified interfaces. 1313 * and then do the real install 1314 */ 1315 ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES, 1316 hDeviceInfo, 1317 &DeviceInfoData); 1318 if (!ok) 1319 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)", 1320 GetLastError())); 1321 1322 ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE, 1323 hDeviceInfo, 1324 &DeviceInfoData); 1325 if (!ok) 1326 SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)", 1327 GetLastError())); 1328 1329 /* Figure out NetCfgInstanceId */ 1330 hkey = SetupDiOpenDevRegKey (hDeviceInfo, 1331 &DeviceInfoData, 1332 DICS_FLAG_GLOBAL, 1333 0, 1334 DIREG_DRV, 1335 KEY_READ); 1336 if (hkey == INVALID_HANDLE_VALUE) 1337 SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)", 1338 GetLastError())); 1339 1340 cbSize = sizeof (pCfgGuidString); 1341 DWORD ret; 1342 ret = RegQueryValueEx (hkey, _T("NetCfgInstanceId"), NULL, 1343 &dwValueType, (LPBYTE) pCfgGuidString, &cbSize); 1344 RegCloseKey (hkey); 1345 1346 ret = RenameConnection (pCfgGuidString, Bstr (aName)); 1347 if (FAILED (ret)) 1348 SetErrBreak (("Failed to set interface name (ret=0x%08X, " 1349 "pCfgGuidString='%ls', cbSize=%d)", 1350 ret, pCfgGuidString, cbSize)); 1351 } 1352 while (0); 1353 1354 /* 1355 * cleanup 1356 */ 1357 1358 if (hDeviceInfo != INVALID_HANDLE_VALUE) 1359 { 1360 /* an error has occured, but the device is registered, we must remove it */ 1361 if (ret != 0 && registered) 1362 SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData); 1363 1364 found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData); 1365 1366 /* destroy the driver info list */ 1367 if (destroyList) 1368 SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData, 1369 SPDIT_CLASSDRIVER); 1370 /* clean up the device info set */ 1371 SetupDiDestroyDeviceInfoList (hDeviceInfo); 1372 } 1373 1374 /* return the network connection GUID on success */ 1375 if (RT_SUCCESS (vrc)) 1376 { 1377 /* remove the curly bracket at the end */ 1378 pCfgGuidString [_tcslen (pCfgGuidString) - 1] = '\0'; 1379 LogFlowFunc (("Network connection GUID string = {%ls}\n", pCfgGuidString + 1)); 1380 1381 aGUID = Guid (Utf8Str (pCfgGuidString + 1)); 1382 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw())); 1383 Assert (!aGUID.isEmpty()); 1384 } 1385 1386 LogFlowFunc (("vrc=%Rrc\n", vrc)); 1387 LogFlowFuncLeave(); 1388 return vrc; 1389 } 1390 1391 /* static */ 1392 static int removeNetworkInterface (SVCHlpClient *aClient, 1393 const Guid &aGUID, 1394 Utf8Str &aErrMsg) 1395 { 1396 LogFlowFuncEnter(); 1397 LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw())); 1398 1399 AssertReturn (aClient, VERR_INVALID_POINTER); 1400 AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER); 1401 1402 int vrc = VINF_SUCCESS; 1403 1404 do 1405 { 1406 TCHAR lszPnPInstanceId [512] = {0}; 1407 1408 /* We have to find the device instance ID through a registry search */ 1409 1410 HKEY hkeyNetwork = 0; 1411 HKEY hkeyConnection = 0; 1412 1413 do 1414 { 1415 char strRegLocation [256]; 1416 sprintf (strRegLocation, 1417 "SYSTEM\\CurrentControlSet\\Control\\Network\\" 1418 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}", 1419 aGUID.toString().raw()); 1420 LONG status; 1421 status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0, 1422 KEY_READ, &hkeyNetwork); 1423 if ((status != ERROR_SUCCESS) || !hkeyNetwork) 1424 SetErrBreak (( 1425 "Host interface network is not found in registry (%s) [1]", 1426 strRegLocation)); 1427 1428 status = RegOpenKeyExA (hkeyNetwork, "Connection", 0, 1429 KEY_READ, &hkeyConnection); 1430 if ((status != ERROR_SUCCESS) || !hkeyConnection) 1431 SetErrBreak (( 1432 "Host interface network is not found in registry (%s) [2]", 1433 strRegLocation)); 1434 1435 DWORD len = sizeof (lszPnPInstanceId); 1436 DWORD dwKeyType; 1437 status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL, 1438 &dwKeyType, (LPBYTE) lszPnPInstanceId, &len); 1439 if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ)) 1440 SetErrBreak (( 1441 "Host interface network is not found in registry (%s) [3]", 1442 strRegLocation)); 1443 } 1444 while (0); 1445 1446 if (hkeyConnection) 1447 RegCloseKey (hkeyConnection); 1448 if (hkeyNetwork) 1449 RegCloseKey (hkeyNetwork); 1450 1451 if (RT_FAILURE (vrc)) 1452 break; 1453 1454 /* 1455 * Now we are going to enumerate all network devices and 1456 * wait until we encounter the right device instance ID 1457 */ 1458 1459 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; 1460 1461 do 1462 { 1463 BOOL ok; 1464 DWORD ret = 0; 1465 GUID netGuid; 1466 SP_DEVINFO_DATA DeviceInfoData; 1467 DWORD index = 0; 1468 BOOL found = FALSE; 1469 DWORD size = 0; 1470 1471 /* initialize the structure size */ 1472 DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA); 1473 1474 /* copy the net class GUID */ 1475 memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET)); 1476 1477 /* return a device info set contains all installed devices of the Net class */ 1478 hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT); 1479 1480 if (hDeviceInfo == INVALID_HANDLE_VALUE) 1481 SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError())); 1482 1483 /* enumerate the driver info list */ 1484 while (TRUE) 1485 { 1486 TCHAR *deviceHwid; 1487 1488 ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData); 1489 1490 if (!ok) 1491 { 1492 if (GetLastError() == ERROR_NO_MORE_ITEMS) 1493 break; 1494 else 1495 { 1496 index++; 1497 continue; 1498 } 1499 } 1500 1501 /* try to get the hardware ID registry property */ 1502 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, 1503 &DeviceInfoData, 1504 SPDRP_HARDWAREID, 1505 NULL, 1506 NULL, 1507 0, 1508 &size); 1509 if (!ok) 1510 { 1511 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 1512 { 1513 index++; 1514 continue; 1515 } 1516 1517 deviceHwid = (TCHAR *) malloc (size); 1518 ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, 1519 &DeviceInfoData, 1520 SPDRP_HARDWAREID, 1521 NULL, 1522 (PBYTE)deviceHwid, 1523 size, 1524 NULL); 1525 if (!ok) 1526 { 1527 free (deviceHwid); 1528 deviceHwid = NULL; 1529 index++; 1530 continue; 1531 } 1532 } 1533 else 1534 { 1535 /* something is wrong. This shouldn't have worked with a NULL buffer */ 1536 index++; 1537 continue; 1538 } 1539 1540 for (TCHAR *t = deviceHwid; 1541 t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; 1542 t += _tcslen (t) + 1) 1543 { 1544 if (!_tcsicmp (DRIVERHWID, t)) 1545 { 1546 /* get the device instance ID */ 1547 TCHAR devID [MAX_DEVICE_ID_LEN]; 1548 if (CM_Get_Device_ID(DeviceInfoData.DevInst, 1549 devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS) 1550 { 1551 /* compare to what we determined before */ 1552 if (wcscmp(devID, lszPnPInstanceId) == 0) 1553 { 1554 found = TRUE; 1555 break; 1556 } 1557 } 1558 } 1559 } 1560 1561 if (deviceHwid) 1562 { 1563 free (deviceHwid); 1564 deviceHwid = NULL; 1565 } 1566 1567 if (found) 1568 break; 1569 1570 index++; 1571 } 1572 1573 if (found == FALSE) 1574 SetErrBreak (("Host Interface Network driver not found (0x%08X)", 1575 GetLastError())); 1576 1577 ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); 1578 if (!ok) 1579 SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)", 1580 GetLastError())); 1581 1582 ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData); 1583 if (!ok) 1584 SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)", 1585 GetLastError())); 1586 } 1587 while (0); 1588 1589 /* clean up the device info set */ 1590 if (hDeviceInfo != INVALID_HANDLE_VALUE) 1591 SetupDiDestroyDeviceInfoList (hDeviceInfo); 1592 1593 if (RT_FAILURE (vrc)) 1594 break; 1595 } 1596 while (0); 1597 1598 LogFlowFunc (("vrc=%Rrc\n", vrc)); 1599 LogFlowFuncLeave(); 1600 return vrc; 1601 } 1602 1603 #undef SetErrBreak 1604 1605 int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient, 1606 SVCHlpMsg::Code aMsgCode) 1607 { 1608 LogFlowFuncEnter(); 1609 LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode)); 1610 1611 AssertReturn (aClient, VERR_INVALID_POINTER); 1612 1613 int vrc = VINF_SUCCESS; 1614 1615 switch (aMsgCode) 1616 { 1617 case SVCHlpMsg::CreateHostOnlyNetworkInterface: 1618 { 1619 LogFlowFunc (("CreateHostOnlyNetworkInterface:\n")); 1620 1621 Utf8Str name; 1622 vrc = aClient->read (name); 1623 if (RT_FAILURE (vrc)) break; 1624 1625 Guid guid; 1626 Utf8Str errMsg; 1627 vrc = createNetworkInterface (aClient, name, guid, errMsg); 1628 1629 if (RT_SUCCESS (vrc)) 1630 { 1631 /* write success followed by GUID */ 1632 vrc = aClient->write (SVCHlpMsg::CreateHostOnlyNetworkInterface_OK); 1633 if (RT_FAILURE (vrc)) break; 1634 vrc = aClient->write (guid); 1635 if (RT_FAILURE (vrc)) break; 1636 } 1637 else 1638 { 1639 /* write failure followed by error message */ 1640 if (errMsg.isEmpty()) 1641 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc); 1642 vrc = aClient->write (SVCHlpMsg::Error); 1643 if (RT_FAILURE (vrc)) break; 1644 vrc = aClient->write (errMsg); 1645 if (RT_FAILURE (vrc)) break; 1646 } 1647 1648 break; 1649 } 1650 case SVCHlpMsg::RemoveHostOnlyNetworkInterface: 1651 { 1652 LogFlowFunc (("RemoveHostOnlyNetworkInterface:\n")); 1653 1654 Guid guid; 1655 vrc = aClient->read (guid); 1656 if (RT_FAILURE (vrc)) break; 1657 1658 Utf8Str errMsg; 1659 vrc = removeNetworkInterface (aClient, guid, errMsg); 1660 1661 if (RT_SUCCESS (vrc)) 1662 { 1663 /* write parameter-less success */ 1664 vrc = aClient->write (SVCHlpMsg::OK); 1665 if (RT_FAILURE (vrc)) break; 1666 } 1667 else 1668 { 1669 /* write failure followed by error message */ 1670 if (errMsg.isEmpty()) 1671 errMsg = Utf8StrFmt ("Unspecified error (%Rrc)", vrc); 1672 vrc = aClient->write (SVCHlpMsg::Error); 1673 if (RT_FAILURE (vrc)) break; 1674 vrc = aClient->write (errMsg); 1675 if (RT_FAILURE (vrc)) break; 1676 } 1677 1678 break; 1679 } 1680 default: 1681 AssertMsgFailedBreakStmt ( 1682 ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode), 1683 VERR_GENERAL_FAILURE); 1684 } 1685 1686 LogFlowFunc (("vrc=%Rrc\n", vrc)); 1687 LogFlowFuncLeave(); 1688 return vrc; 1689 } 1690 1691 /** @todo REMOVE. OBSOLETE NOW. */ 1692 /** 1693 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and 1694 * later OSes) and it has the UAC (User Account Control) feature enabled. 1695 */ 1696 static BOOL IsUACEnabled() 1697 { 1698 LONG rc = 0; 1699 1700 OSVERSIONINFOEX info; 1701 ZeroMemory (&info, sizeof (OSVERSIONINFOEX)); 1702 info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); 1703 rc = GetVersionEx ((OSVERSIONINFO *) &info); 1704 AssertReturn (rc != 0, FALSE); 1705 1706 LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n", 1707 info.dwMajorVersion, info.dwMinorVersion)); 1708 1709 /* we are interested only in Vista (and newer versions...). In all 1710 * earlier versions UAC is not present. */ 1711 if (info.dwMajorVersion < 6) 1712 return FALSE; 1713 1714 /* the default EnableLUA value is 1 (Enabled) */ 1715 DWORD dwEnableLUA = 1; 1716 1717 HKEY hKey; 1718 rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE, 1719 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 1720 0, KEY_QUERY_VALUE, &hKey); 1721 1722 Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND); 1723 if (rc == ERROR_SUCCESS) 1724 { 1725 1726 DWORD cbEnableLUA = sizeof (dwEnableLUA); 1727 rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL, 1728 (LPBYTE) &dwEnableLUA, &cbEnableLUA); 1729 1730 RegCloseKey (hKey); 1731 1732 Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND); 1733 } 1734 1735 LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA)); 1736 1737 return dwEnableLUA == 1; 1738 } 1739 1740 /* end */ 1741 1742 int NetIfCreateHostOnlyNetworkInterface (VirtualBox *pVBox, IN_BSTR aName, 1743 IHostNetworkInterface **aHostNetworkInterface, 1744 IProgress **aProgress) 1745 { 1746 /* create a progress object */ 1747 ComObjPtr <Progress> progress; 1748 progress.createObject(); 1749 1750 ComPtr<IHost> host; 1751 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam()); 1752 if(SUCCEEDED(rc)) 1753 { 1754 rc = progress->init (pVBox, host, 1755 Bstr (_T ("Creating host only network interface")), 1756 FALSE /* aCancelable */); 1757 if(SUCCEEDED(rc)) 1758 { 1759 CheckComRCReturnRC (rc); 1760 progress.queryInterfaceTo (aProgress); 1761 1762 /* create a new uninitialized host interface object */ 1763 ComObjPtr <HostNetworkInterface> iface; 1764 iface.createObject(); 1765 iface.queryInterfaceTo (aHostNetworkInterface); 1766 1767 /* create the networkInterfaceHelperClient() argument */ 1768 std::auto_ptr <NetworkInterfaceHelperClientData> 1769 d (new NetworkInterfaceHelperClientData()); 1770 AssertReturn (d.get(), E_OUTOFMEMORY); 1771 1772 d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface; 1773 d->name = aName; 1774 d->iface = iface; 1775 1776 rc = pVBox->startSVCHelperClient ( 1777 IsUACEnabled() == TRUE /* aPrivileged */, 1778 netIfNetworkInterfaceHelperClient, 1779 static_cast <void *> (d.get()), 1780 progress); 1781 1782 if (SUCCEEDED (rc)) 1783 { 1784 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */ 1785 d.release(); 1786 } 1787 } 1788 } 1789 1790 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 1791 } 1792 1793 int NetIfRemoveHostOnlyNetworkInterface (VirtualBox *pVBox, IN_GUID aId, 1794 IHostNetworkInterface **aHostNetworkInterface, 1795 IProgress **aProgress) 1796 { 1797 /* create a progress object */ 1798 ComObjPtr <Progress> progress; 1799 progress.createObject(); 1800 ComPtr<IHost> host; 1801 HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam()); 1802 if(SUCCEEDED(rc)) 1803 { 1804 rc = progress->init (pVBox, host, 1805 Bstr (_T ("Removing host network interface")), 1806 FALSE /* aCancelable */); 1807 if(SUCCEEDED(rc)) 1808 { 1809 CheckComRCReturnRC (rc); 1810 progress.queryInterfaceTo (aProgress); 1811 1812 /* create the networkInterfaceHelperClient() argument */ 1813 std::auto_ptr <NetworkInterfaceHelperClientData> 1814 d (new NetworkInterfaceHelperClientData()); 1815 AssertReturn (d.get(), E_OUTOFMEMORY); 1816 1817 d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface; 1818 d->guid = aId; 1819 1820 rc = pVBox->startSVCHelperClient ( 1821 IsUACEnabled() == TRUE /* aPrivileged */, 1822 netIfNetworkInterfaceHelperClient, 1823 static_cast <void *> (d.get()), 1824 progress); 1825 1826 if (SUCCEEDED (rc)) 1827 { 1828 /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */ 1829 d.release(); 1830 } 1831 } 1832 } 1833 1834 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 781 1835 } 782 1836 … … 901 1955 #endif /* #ifndef VBOX_WITH_NETFLT */ 902 1956 1957 int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *) 1958 { 1959 return VERR_NOT_IMPLEMENTED; 1960 } 903 1961 904 1962 static int NetIfListHostAdapters(std::list <ComObjPtr <HostNetworkInterface> > &list) -
trunk/src/VBox/Main/win/svchlp.cpp
r17275 r17494 22 22 #include "svchlp.h" 23 23 24 #include "HostImpl.h"24 //#include "HostImpl.h" 25 25 #include "Logging.h" 26 26 27 27 #include <VBox/err.h> 28 29 int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient, 30 SVCHlpMsg::Code aMsgCode); 28 31 29 32 using namespace com; … … 274 277 case SVCHlpMsg::CreateHostOnlyNetworkInterface: 275 278 case SVCHlpMsg::RemoveHostOnlyNetworkInterface: 279 case SVCHlpMsg::EnableDynamicIpConfig: 280 case SVCHlpMsg::EnableStaticIpConfig: 281 case SVCHlpMsg::EnableStaticIpConfigV6: 276 282 { 277 vrc = Host::networkInterfaceHelperServer (this, msgCode);283 vrc = netIfNetworkInterfaceHelperServer (this, msgCode); 278 284 break; 279 285 } -
trunk/src/VBox/Main/win/svchlp.h
r17275 r17494 41 41 CreateHostOnlyNetworkInterface_OK, /* see usage in code */ 42 42 RemoveHostOnlyNetworkInterface, /* see usage in code */ 43 EnableDynamicIpConfig, /* see usage in code */ 44 EnableStaticIpConfig, /* see usage in code */ 45 EnableStaticIpConfigV6, /* see usage in code */ 43 46 }; 44 47 };
Note:
See TracChangeset
for help on using the changeset viewer.