HostImpl.cpp revision 57b49c1557a310ee615bc0ee79dd2a2e92319a1b
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox COM class implementation: Host
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * additional information or have any questions.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_NETFLT) */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <sys/types.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <sys/stat.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <unistd.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <fcntl.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <mntent.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* bird: This is a hack to work around conflicts between these linux kernel headers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * and the GLIBC tcpip headers. They have different declarations of the 4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * standard byte order functions. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # define _LINUX_BYTEORDER_GENERIC_H
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// # include <linux/cdrom.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* RT_OS_LINUX */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* Dynamic loading of libhal on Solaris hosts */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* RT_OS_SOLARIS */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* RT_OS_WINDOWS */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// constructor / destructor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/////////////////////////////////////////////////////////////////////////////
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// public initializer/uninitializer for internal purposes only
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/////////////////////////////////////////////////////////////////////////////
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Initializes the host object.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param aParent VirtualBox parent object.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Create and initialize the USB Proxy Service.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# if defined (RT_OS_DARWIN)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mUSBProxyService = new USBProxyServiceDarwin (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mUSBProxyService = new USBProxyServiceLinux (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mUSBProxyService = new USBProxyServiceSolaris (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mUSBProxyService = new USBProxyServiceWindows (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* VBOX_WITH_USB */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* VBOX_WITH_RESOURCE_USAGE_API */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mHostPowerService = new HostPowerServiceWin (mParent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mHostPowerService = new HostPowerServiceDarwin (mParent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mHostPowerService = new HostPowerService (mParent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Cache the features reported by GetProcessorFeature. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX, u32AMDFeatureEDX, u32AMDFeatureECX;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASMCpuId (0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASMCpuId (1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Query AMD features. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASMCpuId (0x80000001, &u32Dummy, &u32Dummy, &u32AMDFeatureECX, &u32AMDFeatureEDX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fLongModeSupported = !!(u32AMDFeatureEDX & X86_CPUID_AMD_FEATURE_EDX_LONG_MODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync fPAESupported = !!(u32FeaturesEDX & X86_CPUID_FEATURE_EDX_PAE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( (u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Uninitializes the host object and sets the ready flag to FALSE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unregisterMetrics (mParent->performanceCollector());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif /* VBOX_WITH_RESOURCE_USAGE_API */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* wait for USB proxy service to terminate before we uninit all USB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * devices */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogFlowThisFunc (("Stopping USB proxy service...\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogFlowThisFunc (("Done stopping USB proxy service.\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* uninit all USB device filters still referenced by clients */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// IHost properties
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/////////////////////////////////////////////////////////////////////////////
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Returns a list of host DVD drives.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns COM status code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param drives address of result pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSTDMETHODIMP Host::COMGETTER(DVDDrives) (ComSafeArrayOut (IHostDVDDrive *, aDrives))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (*p);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Not all Solaris versions ship with libhal.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // So use a fallback approach similar to Linux.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cdromDrive = strtok(cdromEnv, ":"); /** @todo use strtok_r. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // this might work on Solaris version older than Nevada.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check the mounted drives
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DriveInfoList::const_iterator it = mHostDrives.DVDBegin();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SUCCEEDED (rc) && it != mHostDrives.DVDEnd(); ++it)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bstr udi (it->mUdi.empty() ? NULL : it->mUdi.c_str());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bstr description (it->mDescription.empty() ? NULL : it->mDescription.c_str());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (device.isNull() || (!it->mUdi.empty() && udi.isNull()) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (!it->mDescription.empty() && description.isNull()))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rc = hostDVDDriveObj->init (device, udi, description);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* PORTME */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Returns a list of host floppy drives.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @returns COM status code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param drives address of result pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSTDMETHODIMP Host::COMGETTER(FloppyDrives) (ComSafeArrayOut (IHostFloppyDrive *, aDrives))
#ifdef RT_OS_WINDOWS
driveName[0] = *p;
delete[] hostDrives;
return rc;
#ifdef RT_OS_SOLARIS
static void vboxSolarisAddHostIface(char *pszIface, int Instance, PCRTMAC pMac, void *pvHostNetworkInterfaceList)
std::list<ComObjPtr <HostNetworkInterface> > *pList = (std::list<ComObjPtr <HostNetworkInterface> > *)pvHostNetworkInterfaceList;
if (pMac)
static boolean_t vboxSolarisAddLinkHostIface(const char *pszIface, void *pvHostNetworkInterfaceList)
if (pszColon)
int cbInstance = 0;
cbInstance++;
pszEnd--;
return _B_FALSE;
static bool vboxSolarisSortNICList(const ComObjPtr <HostNetworkInterface> Iface1, const ComObjPtr <HostNetworkInterface> Iface2)
static bool vboxSolarisSameNIC(const ComObjPtr <HostNetworkInterface> Iface1, const ComObjPtr <HostNetworkInterface> Iface2)
# ifdef VBOX_SOLARIS_NSL_RESOLVED
static int vboxSolarisAddPhysHostIface(di_node_t Node, di_minor_t Minor, void *pvHostNetworkInterfaceList)
return DI_WALK_CONTINUE;
return DI_WALK_CONTINUE;
return DI_WALK_CONTINUE;
static int vboxNetWinAddComponent(std::list <ComObjPtr <HostNetworkInterface> > * pPist, INetCfgComponent * pncc)
Assert(0);
return rc;
STDMETHODIMP Host::COMGETTER(NetworkInterfaces) (ComSafeArrayOut (IHostNetworkInterface *, aNetworkInterfaces))
return E_POINTER;
CHECK_READY();
#ifdef VBOX_WITH_HOSTNETIF_API
if (rc)
# if defined(RT_OS_DARWIN)
while (pEtherNICs)
if (SUCCEEDED(IfObj->init(Bstr(pEtherNICs->szName), Guid(pEtherNICs->Uuid), HostNetworkInterfaceType_Bridged)))
# ifdef VBOX_SOLARIS_NSL_RESOLVED
if (VBoxSolarisLibDlpiFound())
if (Sock > 0)
if (!rc)
if (!rc)
if (!rc)
if (!rc)
# ifndef VBOX_WITH_NETFLT
&pNc,
&lpszApp );
#ifdef VBOX_NETFLT_ONDEMAND_BIND
/* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
# ifndef VBOX_WITH_HARDENING
if(uComponentStatus == 0)
if (sock >= 0)
return S_OK;
#ifdef VBOX_WITH_USB
CHECK_READY();
STDMETHODIMP Host::COMGETTER(USBDeviceFilters) (ComSafeArrayOut (IHostUSBDeviceFilter *, aUSBDeviceFilters))
#ifdef VBOX_WITH_USB
CHECK_READY();
return rc;
CHECK_READY();
return S_OK;
CHECK_READY();
return S_OK;
CHECK_READY();
return S_OK;
CHECK_READY();
CHECK_READY();
switch (aFeature)
case ProcessorFeature_PAE:
return S_OK;
CHECK_READY();
if (!hal)
return E_FAIL;
delete hal;
return rc;
CHECK_READY();
if (!hal)
return E_FAIL;
delete hal;
return rc;
CHECK_READY();
return S_OK;
CHECK_READY();
return S_OK;
CHECK_READY();
return S_OK;
CHECK_READY();
if(RT_SUCCESS(r))
return S_OK;
CHECK_READY();
if(RT_SUCCESS(r))
return S_OK;
#ifdef VBOX_WITH_USB
CHECK_READY();
return S_OK;
#ifdef VBOX_WITH_USB
CHECK_READY();
if (!filter)
#ifdef VBOX_WITH_USB
CHECK_READY();
using namespace settings;
CHECK_READY();
#ifdef VBOX_WITH_USB
action);
return rc;
using namespace settings;
CHECK_READY();
#ifdef VBOX_WITH_USB
++ it;
return S_OK;
#ifdef VBOX_WITH_USB
CHECK_READY();
if (aActiveChanged)
return S_OK;
void Host::getUSBFilters(Host::USBDeviceFilterList *aGlobalFilters, VirtualBox::SessionMachineVector *aMachines)
bool halSuccess = false;
if (!gLibHalCheckPresence())
if (dbusConnection != 0)
if (halContext != 0)
int numDevices;
if (halDevices != 0)
halSuccess = true;
for (int i = 0; i < numDevices; i++)
#ifdef RT_OS_SOLARIS
if (devNode != 0)
if (product == 0)
LogRel(("Host::COMGETTER(DVDDrives): failed to get property \"info.product\" for device %s. dbus error: %s (%s)\n",
if (vendor != 0)
if (product != 0)
#ifndef RT_OS_SOLARIS
LogRel(("Host::COMGETTER(DVDDrives): failed to get property \"block.device\" for device %s. dbus error: %s (%s)\n",
LogRel(("Host::COMGETTER(DVDDrives): failed to get devices with capability \"storage.cdrom\". dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(DVDDrives): failed to shutdown the libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(DVDDrives): failed to initialise libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(DVDDrives): failed to connect to dbus. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
return halSuccess;
bool halSuccess = false;
if (!gLibHalCheckPresence())
if (dbusConnection != 0)
if (halContext != 0)
int numDevices;
if (halDevices != 0)
halSuccess = true;
for (int i = 0; i < numDevices; i++)
if (driveType != 0)
if (devNode != 0)
if (product == 0)
LogRel(("Host::COMGETTER(FloppyDrives): failed to get property \"info.product\" for device %s. dbus error: %s (%s)\n",
if (vendor != 0)
if (product != 0)
// LogRel(("Host::COMGETTER(FloppyDrives): failed to validate the block device %s as a floppy drive\n"));
LogRel(("Host::COMGETTER(FloppyDrives): failed to get property \"block.device\" for device %s. dbus error: %s (%s)\n",
LogRel(("Host::COMGETTER(FloppyDrives): failed to get devices with capability \"storage.cdrom\". dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(FloppyDrives): failed to shutdown the libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(FloppyDrives): failed to initialise libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
LogRel(("Host::COMGETTER(FloppyDrives): failed to connect to dbus. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
return halSuccess;
#if defined(RT_OS_SOLARIS)
#ifdef RT_OS_LINUX
if (mtab)
char *mnt_type;
char *mnt_dev;
char *tmp;
if (tmp)
if (mnt_type)
if (tmp)
if (tmp)
if (mnt_dev)
if (tmp)
if (mntFile)
bool retValue = false;
if (!deviceNode)
if (isCDROM)
int fileHandle;
if (fileHandle >= 0)
#ifdef RT_OS_LINUX
retValue = true;
retValue = true;
return retValue;
#ifdef VBOX_WITH_USB
CHECK_READY();
#ifdef RT_OS_LINUX
# ifdef VBOX_WITH_DBUS
tr ("The USB Proxy Service could not be started, because neither the USB file system (usbfs) nor the hardware information service (hal) is available")
tr ("The USB Proxy Service could not be started, because the USB file system (usbfs) is not available")
return S_OK;
#ifdef VBOX_WITH_RESOURCE_USAGE_API
STDMETHODIMP Host::FindHostNetworkInterfaceByName(IN_BSTR name, IHostNetworkInterface **networkInterface)
#ifndef VBOX_WITH_HOSTNETIF_API
return E_NOTIMPL;
if (!name)
return E_INVALIDARG;
if (!networkInterface)
return E_POINTER;
return E_FAIL;
Bstr n;
if (n == name)
if (!found)
STDMETHODIMP Host::FindHostNetworkInterfaceById(IN_BSTR id, IHostNetworkInterface **networkInterface)
#ifndef VBOX_WITH_HOSTNETIF_API
return E_NOTIMPL;
return E_INVALIDARG;
if (!networkInterface)
return E_POINTER;
return E_FAIL;
Bstr g;
if (g == id)
if (!found)
STDMETHODIMP Host::FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_T type, ComSafeArrayOut (IHostNetworkInterface *, aNetworkInterfaces))
return E_FAIL;
return hr;
if(t == type)
return S_OK;
#ifdef VBOX_WITH_USB
aAddress);
return E_NOTIMPL;
#ifdef VBOX_WITH_USB
return E_NOTIMPL;