HostImpl.cpp revision 2e472cd3c6bfef41e092240234c070e89b2bf47c
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/* $Id$ */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/** @file
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * VirtualBox COM class implementation: Host
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/*
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * available from http://www.virtualbox.org. This file is free software;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * General Public License (GPL) as published by the Free Software
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * additional information or have any questions.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#define __STDC_LIMIT_MACROS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#define __STDC_CONSTANT_MACROS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_LINUX
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/types.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/stat.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <unistd.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/ioctl.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <fcntl.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <mntent.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/* bird: This is a hack to work around conflicts between these linux kernel headers
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * and the GLIBC tcpip headers. They have different declarations of the 4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * standard byte order functions. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# define _LINUX_BYTEORDER_GENERIC_H
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <linux/cdrom.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# ifdef VBOX_USE_LIBHAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// # include <libhal.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// /* These are defined by libhal.h and by VBox header files. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// # undef TRUE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// # undef FALSE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "vbox-libhal.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <errno.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* RT_OS_LINUX */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_SOLARIS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <fcntl.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <unistd.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <stropts.h>
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync# include <errno.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <limits.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <stdio.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/types.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/stat.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/cdio.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/dkio.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/mnttab.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <sys/mntent.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# ifdef VBOX_USE_LIBHAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "vbox-libhal.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncextern "C" char *getfullrawname(char *);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* RT_OS_SOLARIS */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# define _WIN32_DCOM
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <windows.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <shellapi.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# define INITGUID
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <guiddef.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <devguid.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <objbase.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <setupapi.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <shlobj.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <cfgmgr32.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* RT_OS_WINDOWS */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "HostImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "HostDVDDriveImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "HostFloppyDriveImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "HostUSBDeviceImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "USBDeviceFilterImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "USBProxyService.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "VirtualBoxImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "MachineImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include "Logging.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_DARWIN
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "darwin/iokit.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include "HostNetworkInterfaceImpl.h"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <VBox/usb.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <VBox/err.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/string.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/** @todo the following line becomes obsolete after switching to Mp runtime functions */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/system.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/mp.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/time.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/param.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <iprt/env.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_SOLARIS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# include <iprt/path.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#include <stdio.h>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync#include <algorithm>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// constructor / destructor
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/////////////////////////////////////////////////////////////////////////////
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncHRESULT Host::FinalConstruct()
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncvoid Host::FinalRelease()
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (isReady())
c64777b77514bdc924249d2f9900be25079b0d84vboxsync uninit();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// public initializer/uninitializer for internal purposes only
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/////////////////////////////////////////////////////////////////////////////
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Initializes the host object.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM result indicator
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param parent handle of our parent object
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncHRESULT Host::init (VirtualBox *parent)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowThisFunc (("isReady=%d\n", isReady()));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComAssertRet (parent, E_INVALIDARG);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComAssertRet (!isReady(), E_UNEXPECTED);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mParent = parent;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /*
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Create and initialize the USB Proxy Service.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# if defined (RT_OS_DARWIN)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyServiceDarwin (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# elif defined (RT_OS_LINUX)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyServiceLinux (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# elif defined (RT_OS_OS2)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyServiceOs2 (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# elif defined (RT_OS_SOLARIS) && 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyServiceSolaris (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# elif defined (RT_OS_WINDOWS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyServiceWindows (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = new USBProxyService (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HRESULT hrc = mUSBProxyService->init();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertComRCReturn(hrc, hrc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* VBOX_WITH_USB */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_RESOURCE_USAGE_API
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Start resource usage sampler */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync int vrc = RTTimerCreate (&mUsageSampler, VBOX_USAGE_SAMPLER_INTERVAL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync UsageSamplerCallback, this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertMsgRC (vrc, ("Failed to create resource usage sampling "
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "timer (%Rra)\n", vrc));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (RT_FAILURE (vrc))
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync return E_FAIL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* VBOX_WITH_RESOURCE_USAGE_API */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync setReady(true);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Uninitializes the host object and sets the ready flag to FALSE.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncvoid Host::uninit()
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowThisFunc (("isReady=%d\n", isReady()));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertReturn (isReady(), (void) 0);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* wait for USB proxy service to terminate before we uninit all USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * devices */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowThisFunc (("Stopping USB proxy service...\n"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync delete mUSBProxyService;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService = NULL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowThisFunc (("Done stopping USB proxy service.\n"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* uninit all USB device filters still referenced by clients */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync uninitDependentChildren();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBDeviceFilters.clear();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_RESOURCE_USAGE_API
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Destroy resource usage sampler */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync int vrc = RTTimerDestroy (mUsageSampler);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertMsgRC (vrc, ("Failed to destroy resource usage "
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "sampling timer (%Rra)\n", vrc));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* VBOX_WITH_RESOURCE_USAGE_API */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync setReady (FALSE);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// IHost properties
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/////////////////////////////////////////////////////////////////////////////
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns a list of host DVD drives.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param drives address of result pointer
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(DVDDrives) (IHostDVDDriveCollection **drives)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!drives)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::list <ComObjPtr <HostDVDDrive> > list;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#if defined(RT_OS_WINDOWS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync int sz = GetLogicalDriveStrings(0, NULL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync TCHAR *hostDrives = new TCHAR[sz+1];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync GetLogicalDriveStrings(sz, hostDrives);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wchar_t driveName[3] = { '?', ':', '\0' };
c64777b77514bdc924249d2f9900be25079b0d84vboxsync TCHAR *p = hostDrives;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync do
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (GetDriveType(p) == DRIVE_CDROM)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync driveName[0] = *p;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init (Bstr (driveName));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync p += _tcslen(p) + 1;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (*p);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync delete[] hostDrives;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#elif defined(RT_OS_SOLARIS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# ifdef VBOX_USE_LIBHAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!getDVDInfoFromHal(list))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync# endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // Not all Solaris versions ship with libhal.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // So use a fallback approach similar to Linux.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (RTEnvGet("VBOX_CDROM"))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *cdromEnv = strdup(RTEnvGet("VBOX_CDROM"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *cdromDrive;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cdromDrive = strtok(cdromEnv, ":"); /** @todo use strtok_r. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (cdromDrive)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice(cdromDrive, true))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init (Bstr (cdromDrive));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cdromDrive = strtok(NULL, ":");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync free(cdromEnv);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // this might work on Solaris version older than Nevada.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice("/cdrom/cdrom0", true))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init (Bstr ("cdrom/cdrom0"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // check the mounted drives
c64777b77514bdc924249d2f9900be25079b0d84vboxsync parseMountTable(MNTTAB, list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#elif defined(RT_OS_LINUX)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_USE_LIBHAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!getDVDInfoFromHal(list)) /* Playing with #defines in this way is nasty, I know. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* USE_LIBHAL defined */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // On Linux without hal, the situation is much more complex. We will take a
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // heuristical approach and also allow the user to specify a list of host
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // CDROMs using an environment variable.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // The general strategy is to try some known device names and see of they
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // exist. At last, we'll enumerate the /etc/fstab file (luckily there's an
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // API to parse it) for CDROM devices. Ok, let's start!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (RTEnvGet("VBOX_CDROM"))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *cdromEnv = strdupa(RTEnvGet("VBOX_CDROM"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *cdromDrive;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cdromDrive = strtok(cdromEnv, ":"); /** @todo use strtok_r */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (cdromDrive)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice(cdromDrive, true))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init (Bstr (cdromDrive));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cdromDrive = strtok(NULL, ":");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // this is a good guess usually
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice("/dev/cdrom", true))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init (Bstr ("/dev/cdrom"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // check the mounted drives
c64777b77514bdc924249d2f9900be25079b0d84vboxsync parseMountTable((char*)"/etc/mtab", list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // check the drives that can be mounted
c64777b77514bdc924249d2f9900be25079b0d84vboxsync parseMountTable((char*)"/etc/fstab", list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#elif defined(RT_OS_DARWIN)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync PDARWINDVD cur = DarwinGetDVDDrives();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (cur)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr<HostDVDDrive> hostDVDDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostDVDDriveObj->init(Bstr(cur->szName));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back(hostDVDDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* next */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync void *freeMe = cur;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cur = cur->pNext;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RTMemFree(freeMe);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* PORTME */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr<HostDVDDriveCollection> collection;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection->init (list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.queryInterfaceTo(drives);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns a list of host floppy drives.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param drives address of result pointer
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(FloppyDrives) (IHostFloppyDriveCollection **drives)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!drives)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
ee2aeb0cd5535f38ee098713a9cebb74dc1c2e30vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::list <ComObjPtr <HostFloppyDrive> > list;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync int sz = GetLogicalDriveStrings(0, NULL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync TCHAR *hostDrives = new TCHAR[sz+1];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync GetLogicalDriveStrings(sz, hostDrives);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wchar_t driveName[3] = { '?', ':', '\0' };
c64777b77514bdc924249d2f9900be25079b0d84vboxsync TCHAR *p = hostDrives;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync do
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (GetDriveType(p) == DRIVE_REMOVABLE)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync driveName[0] = *p;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostFloppyDrive> hostFloppyDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj->init (Bstr (driveName));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostFloppyDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync p += _tcslen(p) + 1;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (*p);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync delete[] hostDrives;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#elif defined(RT_OS_LINUX)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_USE_LIBHAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!getFloppyInfoFromHal(list)) /* Playing with #defines in this way is nasty, I know. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* USE_LIBHAL defined */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // As with the CDROMs, on Linux we have to take a multi-level approach
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // involving parsing the mount tables. As this is not bulletproof, we'll
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // give the user the chance to override the detection by an environment
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // variable and skip the detection.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (RTEnvGet("VBOX_FLOPPY"))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *floppyEnv = strdupa(RTEnvGet("VBOX_FLOPPY"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char *floppyDrive;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync floppyDrive = strtok(floppyEnv, ":");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while (floppyDrive)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // check if this is an acceptable device
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice(floppyDrive, false))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostFloppyDrive> hostFloppyDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj->init (Bstr (floppyDrive));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostFloppyDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync floppyDrive = strtok(NULL, ":");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync // we assume that a floppy is always /dev/fd[x] with x from 0 to 7
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char devName[10];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync for (int i = 0; i <= 7; i++)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync sprintf(devName, "/dev/fd%d", i);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (validateDevice(devName, false))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostFloppyDrive> hostFloppyDriveObj;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync hostFloppyDriveObj->init (Bstr (devName));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (hostFloppyDriveObj);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* PORTME */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr<HostFloppyDriveCollection> collection;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection->init (list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.queryInterfaceTo(drives);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncstatic bool IsTAPDevice(const char *guid)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HKEY hNetcard;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LONG status;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD len;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync int i = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync bool ret = false;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &hNetcard);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status != ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return false;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync while(true)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szEnumName[256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szNetCfgInstanceId[256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD dwKeyType;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HKEY hNetCardGUID;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync len = sizeof(szEnumName);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegEnumKeyExA(hNetcard, i, szEnumName, &len, NULL, NULL, NULL, NULL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status != ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync break;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegOpenKeyExA(hNetcard, szEnumName, 0, KEY_READ, &hNetCardGUID);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status == ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync len = sizeof (szNetCfgInstanceId);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegQueryValueExA(hNetCardGUID, "NetCfgInstanceId", NULL, &dwKeyType, (LPBYTE)szNetCfgInstanceId, &len);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szNetProductName[256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szNetProviderName[256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync szNetProductName[0] = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync len = sizeof(szNetProductName);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegQueryValueExA(hNetCardGUID, "ProductName", NULL, &dwKeyType, (LPBYTE)szNetProductName, &len);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync szNetProviderName[0] = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync len = sizeof(szNetProviderName);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegQueryValueExA(hNetCardGUID, "ProviderName", NULL, &dwKeyType, (LPBYTE)szNetProviderName, &len);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if ( !strcmp(szNetCfgInstanceId, guid)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync && !strcmp(szNetProductName, "VirtualBox TAP Adapter")
c64777b77514bdc924249d2f9900be25079b0d84vboxsync && (!strcmp(szNetProviderName, "innotek GmbH") || !strcmp(szNetProviderName, "Sun Microsystems, Inc.")))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ret = true;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey(hNetCardGUID);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync break;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey(hNetCardGUID);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ++i;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey (hNetcard);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return ret;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns a list of host network interfaces.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param drives address of result pointer
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(NetworkInterfaces) (IHostNetworkInterfaceCollection **networkInterfaces)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!networkInterfaces)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::list <ComObjPtr <HostNetworkInterface> > list;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync static const char *NetworkKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "{4D36E972-E325-11CE-BFC1-08002BE10318}";
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HKEY hCtrlNet;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LONG status;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD len;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, NetworkKey, 0, KEY_READ, &hCtrlNet);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status != ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_FAIL, tr("Could not open registry key \"%s\""), NetworkKey);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync for (int i = 0;; ++ i)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szNetworkGUID [256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HKEY hConnection;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync char szNetworkConnection [256];
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync len = sizeof (szNetworkGUID);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegEnumKeyExA (hCtrlNet, i, szNetworkGUID, &len, NULL, NULL, NULL, NULL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status != ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync break;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!IsTAPDevice(szNetworkGUID))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync continue;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RTStrPrintf (szNetworkConnection, sizeof (szNetworkConnection),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "%s\\Connection", szNetworkGUID);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegOpenKeyExA (hCtrlNet, szNetworkConnection, 0, KEY_READ, &hConnection);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status == ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD dwKeyType;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync &dwKeyType, NULL, &len);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status == ERROR_SUCCESS && dwKeyType == REG_SZ)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync size_t uniLen = (len + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr name (uniLen + 1 /* extra zero */);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync status = RegQueryValueExW (hConnection, TEXT("Name"), NULL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync &dwKeyType, (LPBYTE) name.mutableRaw(), &len);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (status == ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RTLogPrintf("Connection name %ls\n", name.mutableRaw());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* put a trailing zero, just in case (see MSDN) */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync name.mutableRaw() [uniLen] = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create a new object and add it to the list */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostNetworkInterface> iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iface.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* remove the curly bracket at the end */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync szNetworkGUID [strlen(szNetworkGUID) - 1] = '\0';
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (SUCCEEDED (iface->init (name, Guid (szNetworkGUID + 1))))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync list.push_back (iface);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey (hConnection);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey (hCtrlNet);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostNetworkInterfaceCollection> collection;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection->init (list);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.queryInterfaceTo (networkInterfaces);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* RT_OS_WINDOWS */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(USBDevices)(IHostUSBDeviceCollection **aUSBDevices)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aUSBDevices)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync MultiResult rc = checkUSBProxyService();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return mUSBProxyService->getDeviceCollection (aUSBDevices);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: The GUI depends on this method returning E_NOTIMPL with no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * extended error info to indicate that USB is simply not available
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * (w/o treting it as a failure), for example, as in OSE */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(USBDeviceFilters) (IHostUSBDeviceFilterCollection **aUSBDeviceFilters)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aUSBDeviceFilters)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync MultiResult rc = checkUSBProxyService();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostUSBDeviceFilterCollection> collection;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection->init (mUSBDeviceFilters);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync collection.queryInterfaceTo (aUSBDeviceFilters);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return rc;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: The GUI depends on this method returning E_NOTIMPL with no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * extended error info to indicate that USB is simply not available
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * (w/o treting it as a failure), for example, as in OSE */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the number of installed logical processors
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param count address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(ProcessorCount)(ULONG *count)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!count)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *count = RTSystemProcessorGetCount();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo after implementing the Mp runtime on all platforms replace with
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * *count = RTMpGetOnlineCount(); */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the (approximate) maximum speed of the given host CPU in MHz
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param cpu id to get info for.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param speed address of result variable, speed is 0 if unknown or cpuId is invalid.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(ProcessorSpeed)(ULONG cpuId, ULONG *speed)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!speed)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo after implementing the Mp runtime on all platforms replace with
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * *speed = RTMpGetOnlineCpuMaxSpeed(cpuId); */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *speed = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns a description string for the host CPU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param cpu id to get info for.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param description address of result variable, NULL if known or cpuId is invalid.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(ProcessorDescription)(ULONG cpuId, BSTR *description)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!description)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the amount of installed system memory in megabytes
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param size address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(MemorySize)(ULONG *size)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!size)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the current system memory free space in megabytes
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param available address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(MemoryAvailable)(ULONG *available)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!available)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the name string of the host operating system
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param os address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(OperatingSystem)(BSTR *os)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!os)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the version string of the host operating system
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param os address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(OSVersion)(BSTR *version)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!version)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /** @todo */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns the current host time in milliseconds since 1970-01-01 UTC.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @returns COM status code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * @param time address of result variable
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::COMGETTER(UTCTime)(LONG64 *aUTCTime)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aUTCTime)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RTTIMESPEC now;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *aUTCTime = RTTimeSpecGetMilli(RTTimeNow(&now));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// IHost methods
c64777b77514bdc924249d2f9900be25079b0d84vboxsync////////////////////////////////////////////////////////////////////////////////
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync/**
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * later OSes) and it has the UAC (User Account Control) feature enabled.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync */
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncstatic BOOL IsUACEnabled()
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LONG rc = 0;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync OSVERSIONINFOEX info;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ZeroMemory (&info, sizeof (OSVERSIONINFOEX));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = GetVersionEx ((OSVERSIONINFO *) &info);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertReturn (rc != 0, FALSE);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowFunc (("dwMajorVersion=%d, dwMinorVersion=%d\n",
c64777b77514bdc924249d2f9900be25079b0d84vboxsync info.dwMajorVersion, info.dwMinorVersion));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* we are interested only in Vista (and newer versions...). In all
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * earlier versions UAC is not present. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (info.dwMajorVersion < 6)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return FALSE;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* the default EnableLUA value is 1 (Enabled) */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD dwEnableLUA = 1;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HKEY hKey;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 0, KEY_QUERY_VALUE, &hKey);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Assert (rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (rc == ERROR_SUCCESS)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DWORD cbEnableLUA = sizeof (dwEnableLUA);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = RegQueryValueExA (hKey, "EnableLUA", NULL, NULL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync (LPBYTE) &dwEnableLUA, &cbEnableLUA);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync RegCloseKey (hKey);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Assert (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync LogFlowFunc (("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return dwEnableLUA == 1;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncstruct NetworkInterfaceHelperClientData
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync SVCHlpMsg::Code msgCode;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* for SVCHlpMsg::CreateHostNetworkInterface */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr name;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostNetworkInterface> iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* for SVCHlpMsg::RemoveHostNetworkInterface */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Guid guid;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync};
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncHost::CreateHostNetworkInterface (INPTR BSTR aName,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IHostNetworkInterface **aHostNetworkInterface,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IProgress **aProgress)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aName)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_INVALIDARG;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aHostNetworkInterface)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aProgress)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HRESULT rc = S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* first check whether an interface with the given name already exists */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComPtr <IHostNetworkInterfaceCollection> coll;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = COMGETTER(NetworkInterfaces) (coll.asOutParam());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComPtr <IHostNetworkInterface> iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (SUCCEEDED (coll->FindByName (aName, iface.asOutParam())))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_FAIL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("Host network interface '%ls' already exists"), aName);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create a progress object */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <Progress> progress;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = progress->init (mParent, static_cast <IHost *> (this),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr (tr ("Creating host network interface")),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FALSE /* aCancelable */);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress.queryInterfaceTo (aProgress);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create a new uninitialized host interface object */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostNetworkInterface> iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iface.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iface.queryInterfaceTo (aHostNetworkInterface);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create the networkInterfaceHelperClient() argument */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::auto_ptr <NetworkInterfaceHelperClientData>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d (new NetworkInterfaceHelperClientData());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertReturn (d.get(), E_OUTOFMEMORY);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d->msgCode = SVCHlpMsg::CreateHostNetworkInterface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d->name = aName;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d->iface = iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = mParent->startSVCHelperClient (
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IsUACEnabled() == TRUE /* aPrivileged */,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync networkInterfaceHelperClient,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync static_cast <void *> (d.get()),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (SUCCEEDED (rc))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* d is now owned by networkInterfaceHelperClient(), so release it */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d.release();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return rc;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncHost::RemoveHostNetworkInterface (INPTR GUIDPARAM aId,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IHostNetworkInterface **aHostNetworkInterface,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IProgress **aProgress)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aHostNetworkInterface)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aProgress)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HRESULT rc = S_OK;
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync /* first check whether an interface with the given name already exists */
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync {
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync ComPtr <IHostNetworkInterfaceCollection> coll;
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync rc = COMGETTER(NetworkInterfaces) (coll.asOutParam());
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComPtr <IHostNetworkInterface> iface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (FAILED (coll->FindById (aId, iface.asOutParam())))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_FAIL,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("Host network interface with UUID {%Vuuid} does not exist"),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Guid (aId).raw());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* return the object to be removed to the caller */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iface.queryInterfaceTo (aHostNetworkInterface);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create a progress object */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <Progress> progress;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = progress->init (mParent, static_cast <IHost *> (this),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr (tr ("Removing host network interface")),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FALSE /* aCancelable */);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress.queryInterfaceTo (aProgress);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* create the networkInterfaceHelperClient() argument */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::auto_ptr <NetworkInterfaceHelperClientData>
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d (new NetworkInterfaceHelperClientData());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertReturn (d.get(), E_OUTOFMEMORY);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d->msgCode = SVCHlpMsg::RemoveHostNetworkInterface;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d->guid = aId;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = mParent->startSVCHelperClient (
c64777b77514bdc924249d2f9900be25079b0d84vboxsync IsUACEnabled() == TRUE /* aPrivileged */,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync networkInterfaceHelperClient,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync static_cast <void *> (d.get()),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync progress);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (SUCCEEDED (rc))
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* d is now owned by networkInterfaceHelperClient(), so release it */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync d.release();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return rc;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* RT_OS_WINDOWS */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::CreateUSBDeviceFilter (INPTR BSTR aName, IHostUSBDeviceFilter **aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aName || *aName == 0)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_INVALIDARG;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostUSBDeviceFilter> filter;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter.createObject();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HRESULT rc = filter->init (this, aName);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComAssertComRCRet (rc, rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rc = filter.queryInterfaceTo (aFilter);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertComRCReturn (rc, rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: The GUI depends on this method returning E_NOTIMPL with no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * extended error info to indicate that USB is simply not available
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * (w/o treting it as a failure), for example, as in OSE */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::InsertUSBDeviceFilter (ULONG aPosition, IHostUSBDeviceFilter *aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_INVALIDARG;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: HostUSBDeviceFilter and USBProxyService also uses this lock. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync MultiResult rc = checkUSBProxyService();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostUSBDeviceFilter> filter = getDependentChild (aFilter);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!filter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_INVALIDARG,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("The given USB device filter is not created within "
c64777b77514bdc924249d2f9900be25079b0d84vboxsync "this VirtualBox instance"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (filter->mInList)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_INVALIDARG,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("The given USB device filter is already in the list"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* iterate to the position... */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync USBDeviceFilterList::iterator it = mUSBDeviceFilters.begin();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::advance (it, aPosition);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* ...and insert */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBDeviceFilters.insert (it, filter);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter->mInList = true;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* notify the proxy (only when the filter is active) */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (mUSBProxyService->isActive() && filter->data().mActive)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComAssertRet (filter->id() == NULL, E_FAIL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter->id() = mUSBProxyService->insertFilter (&filter->data().mUSBFilter);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* save the global settings */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync alock.unlock();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return rc = mParent->saveSettings();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: The GUI depends on this method returning E_NOTIMPL with no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * extended error info to indicate that USB is simply not available
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * (w/o treting it as a failure), for example, as in OSE */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::RemoveUSBDeviceFilter (ULONG aPosition, IHostUSBDeviceFilter **aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!aFilter)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: HostUSBDeviceFilter and USBProxyService also uses this lock. */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync MultiResult rc = checkUSBProxyService();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CheckComRCReturnRC (rc);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (!mUSBDeviceFilters.size())
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_INVALIDARG,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("The USB device filter list is empty"));
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (aPosition >= mUSBDeviceFilters.size())
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return setError (E_INVALIDARG,
c64777b77514bdc924249d2f9900be25079b0d84vboxsync tr ("Invalid position: %lu (must be in range [0, %lu])"),
c64777b77514bdc924249d2f9900be25079b0d84vboxsync aPosition, mUSBDeviceFilters.size() - 1);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComObjPtr <HostUSBDeviceFilter> filter;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* iterate to the position... */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync USBDeviceFilterList::iterator it = mUSBDeviceFilters.begin();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync std::advance (it, aPosition);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* ...get an element from there... */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter = *it;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* ...and remove */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter->mInList = false;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBDeviceFilters.erase (it);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter.queryInterfaceTo (aFilter);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* notify the proxy (only when the filter is active) */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (mUSBProxyService->isActive() && filter->data().mActive)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ComAssertRet (filter->id() != NULL, E_FAIL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mUSBProxyService->removeFilter (filter->id());
c64777b77514bdc924249d2f9900be25079b0d84vboxsync filter->id() = NULL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync }
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* save the global settings */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync alock.unlock();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return rc = mParent->saveSettings();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync /* Note: The GUI depends on this method returning E_NOTIMPL with no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * extended error info to indicate that USB is simply not available
c64777b77514bdc924249d2f9900be25079b0d84vboxsync * (w/o treting it as a failure), for example, as in OSE */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncSTDMETHODIMP Host::GetProcessorUsage (ULONG *aUser, ULONG *aSystem, ULONG *aIdle)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_RESOURCE_USAGE_API
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (aUser == NULL || aSystem == NULL || aIdle == NULL)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_POINTER;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *aUser = mCpuStats.u32User;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *aSystem = mCpuStats.u32System;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync *aIdle = mCpuStats.u32Idle;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#else /* !VBOX_WITH_RESOURCE_USAGE_API */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync return E_NOTIMPL;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#endif /* !VBOX_WITH_RESOURCE_USAGE_API */
c64777b77514bdc924249d2f9900be25079b0d84vboxsync}
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync// public methods only for internal purposes
c64777b77514bdc924249d2f9900be25079b0d84vboxsync////////////////////////////////////////////////////////////////////////////////
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncHRESULT Host::loadSettings (const settings::Key &aGlobal)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync{
c64777b77514bdc924249d2f9900be25079b0d84vboxsync using namespace settings;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AutoWriteLock alock (this);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync CHECK_READY();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync AssertReturn (!aGlobal.isNull(), E_FAIL);
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync HRESULT rc = S_OK;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync#ifdef VBOX_WITH_USB
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Key::List filters = aGlobal.key ("USBDeviceFilters").keys ("DeviceFilter");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync for (Key::List::const_iterator it = filters.begin();
c64777b77514bdc924249d2f9900be25079b0d84vboxsync it != filters.end(); ++ it)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync {
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr name = (*it).stringValue ("name");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync bool active = (*it).value <bool> ("active");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr vendorId = (*it).stringValue ("vendorId");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr productId = (*it).stringValue ("productId");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr revision = (*it).stringValue ("revision");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr manufacturer = (*it).stringValue ("manufacturer");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr product = (*it).stringValue ("product");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr serialNumber = (*it).stringValue ("serialNumber");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Bstr port = (*it).stringValue ("port");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync USBDeviceFilterAction_T action;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync action = USBDeviceFilterAction_Ignore;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync const char *actionStr = (*it).stringValue ("action");
c64777b77514bdc924249d2f9900be25079b0d84vboxsync if (strcmp (actionStr, "Ignore") == 0)
action = USBDeviceFilterAction_Ignore;
else
if (strcmp (actionStr, "Hold") == 0)
action = USBDeviceFilterAction_Hold;
else
AssertMsgFailed (("Invalid action: '%s'\n", actionStr));
ComObjPtr <HostUSBDeviceFilter> filterObj;
filterObj.createObject();
rc = filterObj->init (this,
name, active, vendorId, productId, revision,
manufacturer, product, serialNumber, port,
action);
/* error info is set by init() when appropriate */
CheckComRCBreakRC (rc);
mUSBDeviceFilters.push_back (filterObj);
filterObj->mInList = true;
/* notify the proxy (only when the filter is active) */
if (filterObj->data().mActive)
{
HostUSBDeviceFilter *flt = filterObj; /* resolve ambiguity */
flt->id() = mUSBProxyService->insertFilter (&filterObj->data().mUSBFilter);
}
}
#endif /* VBOX_WITH_USB */
return rc;
}
HRESULT Host::saveSettings (settings::Key &aGlobal)
{
using namespace settings;
AutoWriteLock alock (this);
CHECK_READY();
ComAssertRet (!aGlobal.isNull(), E_FAIL);
#ifdef VBOX_WITH_USB
/* first, delete the entry */
Key filters = aGlobal.findKey ("USBDeviceFilters");
if (!filters.isNull())
filters.zap();
/* then, recreate it */
filters = aGlobal.createKey ("USBDeviceFilters");
USBDeviceFilterList::const_iterator it = mUSBDeviceFilters.begin();
while (it != mUSBDeviceFilters.end())
{
AutoWriteLock filterLock (*it);
const HostUSBDeviceFilter::Data &data = (*it)->data();
Key filter = filters.appendKey ("DeviceFilter");
filter.setValue <Bstr> ("name", data.mName);
filter.setValue <bool> ("active", !!data.mActive);
/* all are optional */
Bstr str;
(*it)->COMGETTER (VendorId) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("vendorId", str);
(*it)->COMGETTER (ProductId) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("productId", str);
(*it)->COMGETTER (Revision) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("revision", str);
(*it)->COMGETTER (Manufacturer) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("manufacturer", str);
(*it)->COMGETTER (Product) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("product", str);
(*it)->COMGETTER (SerialNumber) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("serialNumber", str);
(*it)->COMGETTER (Port) (str.asOutParam());
if (!str.isNull())
filter.setValue <Bstr> ("port", str);
/* action is mandatory */
USBDeviceFilterAction_T action = USBDeviceFilterAction_Null;
(*it)->COMGETTER (Action) (&action);
if (action == USBDeviceFilterAction_Ignore)
filter.setStringValue ("action", "Ignore");
else if (action == USBDeviceFilterAction_Hold)
filter.setStringValue ("action", "Hold");
else
AssertMsgFailed (("Invalid action: %d\n", action));
++ it;
}
#endif /* VBOX_WITH_USB */
return S_OK;
}
#ifdef VBOX_WITH_USB
/**
* Called by setter methods of all USB device filters.
*/
HRESULT Host::onUSBDeviceFilterChange (HostUSBDeviceFilter *aFilter,
BOOL aActiveChanged /* = FALSE */)
{
AutoWriteLock alock (this);
CHECK_READY();
if (aFilter->mInList)
{
if (aActiveChanged)
{
// insert/remove the filter from the proxy
if (aFilter->data().mActive)
{
ComAssertRet (aFilter->id() == NULL, E_FAIL);
aFilter->id() = mUSBProxyService->insertFilter (&aFilter->data().mUSBFilter);
}
else
{
ComAssertRet (aFilter->id() != NULL, E_FAIL);
mUSBProxyService->removeFilter (aFilter->id());
aFilter->id() = NULL;
}
}
else
{
if (aFilter->data().mActive)
{
// update the filter in the proxy
ComAssertRet (aFilter->id() != NULL, E_FAIL);
mUSBProxyService->removeFilter (aFilter->id());
aFilter->id() = mUSBProxyService->insertFilter (&aFilter->data().mUSBFilter);
}
}
// save the global settings... yeah, on every single filter property change
alock.unlock();
return mParent->saveSettings();
}
return S_OK;
}
/**
* Interface for obtaining a copy of the USBDeviceFilterList,
* used by the USBProxyService.
*
* @param aGlobalFilters Where to put the global filter list copy.
* @param aMachines Where to put the machine vector.
*/
void Host::getUSBFilters(Host::USBDeviceFilterList *aGlobalFilters, VirtualBox::SessionMachineVector *aMachines)
{
AutoWriteLock alock (this);
mParent->getOpenedMachines (*aMachines);
*aGlobalFilters = mUSBDeviceFilters;
}
#endif /* VBOX_WITH_USB */
// private methods
////////////////////////////////////////////////////////////////////////////////
#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
# ifdef VBOX_USE_LIBHAL
/**
* Helper function to query the hal subsystem for information about DVD drives attached to the
* system.
*
* @returns true if information was successfully obtained, false otherwise
* @retval list drives found will be attached to this list
*/
bool Host::getDVDInfoFromHal(std::list <ComObjPtr <HostDVDDrive> > &list)
{
bool halSuccess = false;
DBusError dbusError;
if (!gLibHalCheckPresence())
return false;
gDBusErrorInit (&dbusError);
DBusConnection *dbusConnection = gDBusBusGet(DBUS_BUS_SYSTEM, &dbusError);
if (dbusConnection != 0)
{
LibHalContext *halContext = gLibHalCtxNew();
if (halContext != 0)
{
if (gLibHalCtxSetDBusConnection (halContext, dbusConnection))
{
if (gLibHalCtxInit(halContext, &dbusError))
{
int numDevices;
char **halDevices = gLibHalFindDeviceStringMatch(halContext,
"storage.drive_type", "cdrom",
&numDevices, &dbusError);
if (halDevices != 0)
{
/* Hal is installed and working, so if no devices are reported, assume
that there are none. */
halSuccess = true;
for (int i = 0; i < numDevices; i++)
{
char *devNode = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "block.device", &dbusError);
#ifdef RT_OS_SOLARIS
/* The CD/DVD ioctls work only for raw device nodes. */
char *tmp = getfullrawname(devNode);
gLibHalFreeString(devNode);
devNode = tmp;
#endif
if (devNode != 0)
{
// if (validateDevice(devNode, true))
// {
Utf8Str description;
char *vendor, *product;
/* We do not check the error here, as this field may
not even exist. */
vendor = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "info.vendor", 0);
product = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "info.product", &dbusError);
if ((product != 0 && product[0] != 0))
{
if ((vendor != 0) && (vendor[0] != 0))
{
description = Utf8StrFmt ("%s %s",
vendor, product);
}
else
{
description = product;
}
ComObjPtr <HostDVDDrive> hostDVDDriveObj;
hostDVDDriveObj.createObject();
hostDVDDriveObj->init (Bstr (devNode),
Bstr (halDevices[i]),
Bstr (description));
list.push_back (hostDVDDriveObj);
}
else
{
if (product == 0)
{
LogRel(("Host::COMGETTER(DVDDrives): failed to get property \"info.product\" for device %s. dbus error: %s (%s)\n",
halDevices[i], dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
ComObjPtr <HostDVDDrive> hostDVDDriveObj;
hostDVDDriveObj.createObject();
hostDVDDriveObj->init (Bstr (devNode),
Bstr (halDevices[i]));
list.push_back (hostDVDDriveObj);
}
if (vendor != 0)
{
gLibHalFreeString(vendor);
}
if (product != 0)
{
gLibHalFreeString(product);
}
// }
// else
// {
// LogRel(("Host::COMGETTER(DVDDrives): failed to validate the block device %s as a DVD drive\n"));
// }
#ifndef RT_OS_SOLARIS
gLibHalFreeString(devNode);
#else
free(devNode);
#endif
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to get property \"block.device\" for device %s. dbus error: %s (%s)\n",
halDevices[i], dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
}
gLibHalFreeStringArray(halDevices);
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to get devices with capability \"storage.cdrom\". dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
if (!gLibHalCtxShutdown(halContext, &dbusError)) /* what now? */
{
LogRel(("Host::COMGETTER(DVDDrives): failed to shutdown the libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to initialise libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
gLibHalCtxFree(halContext);
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to set libhal connection to dbus.\n"));
}
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to get a libhal context - out of memory?\n"));
}
gDBusConnectionUnref(dbusConnection);
}
else
{
LogRel(("Host::COMGETTER(DVDDrives): failed to connect to dbus. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
return halSuccess;
}
/**
* Helper function to query the hal subsystem for information about floppy drives attached to the
* system.
*
* @returns true if information was successfully obtained, false otherwise
* @retval list drives found will be attached to this list
*/
bool Host::getFloppyInfoFromHal(std::list <ComObjPtr <HostFloppyDrive> > &list)
{
bool halSuccess = false;
DBusError dbusError;
if (!gLibHalCheckPresence())
return false;
gDBusErrorInit (&dbusError);
DBusConnection *dbusConnection = gDBusBusGet(DBUS_BUS_SYSTEM, &dbusError);
if (dbusConnection != 0)
{
LibHalContext *halContext = gLibHalCtxNew();
if (halContext != 0)
{
if (gLibHalCtxSetDBusConnection (halContext, dbusConnection))
{
if (gLibHalCtxInit(halContext, &dbusError))
{
int numDevices;
char **halDevices = gLibHalFindDeviceStringMatch(halContext,
"storage.drive_type", "floppy",
&numDevices, &dbusError);
if (halDevices != 0)
{
/* Hal is installed and working, so if no devices are reported, assume
that there are none. */
halSuccess = true;
for (int i = 0; i < numDevices; i++)
{
char *driveType = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "storage.drive_type", 0);
if (driveType != 0)
{
if (strcmp(driveType, "floppy") != 0)
{
gLibHalFreeString(driveType);
continue;
}
gLibHalFreeString(driveType);
}
else
{
/* An error occurred. The attribute "storage.drive_type"
probably didn't exist. */
continue;
}
char *devNode = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "block.device", &dbusError);
if (devNode != 0)
{
// if (validateDevice(devNode, false))
// {
Utf8Str description;
char *vendor, *product;
/* We do not check the error here, as this field may
not even exist. */
vendor = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "info.vendor", 0);
product = gLibHalDeviceGetPropertyString(halContext,
halDevices[i], "info.product", &dbusError);
if ((product != 0) && (product[0] != 0))
{
if ((vendor != 0) && (vendor[0] != 0))
{
description = Utf8StrFmt ("%s %s",
vendor, product);
}
else
{
description = product;
}
ComObjPtr <HostFloppyDrive> hostFloppyDrive;
hostFloppyDrive.createObject();
hostFloppyDrive->init (Bstr (devNode),
Bstr (halDevices[i]),
Bstr (description));
list.push_back (hostFloppyDrive);
}
else
{
if (product == 0)
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to get property \"info.product\" for device %s. dbus error: %s (%s)\n",
halDevices[i], dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
ComObjPtr <HostFloppyDrive> hostFloppyDrive;
hostFloppyDrive.createObject();
hostFloppyDrive->init (Bstr (devNode),
Bstr (halDevices[i]));
list.push_back (hostFloppyDrive);
}
if (vendor != 0)
{
gLibHalFreeString(vendor);
}
if (product != 0)
{
gLibHalFreeString(product);
}
// }
// else
// {
// LogRel(("Host::COMGETTER(FloppyDrives): failed to validate the block device %s as a floppy drive\n"));
// }
gLibHalFreeString(devNode);
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to get property \"block.device\" for device %s. dbus error: %s (%s)\n",
halDevices[i], dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
}
gLibHalFreeStringArray(halDevices);
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to get devices with capability \"storage.cdrom\". dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
if (!gLibHalCtxShutdown(halContext, &dbusError)) /* what now? */
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to shutdown the libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to initialise libhal context. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
gLibHalCtxFree(halContext);
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to set libhal connection to dbus.\n"));
}
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to get a libhal context - out of memory?\n"));
}
gDBusConnectionUnref(dbusConnection);
}
else
{
LogRel(("Host::COMGETTER(FloppyDrives): failed to connect to dbus. dbus error: %s (%s)\n", dbusError.name, dbusError.message));
gDBusErrorFree(&dbusError);
}
return halSuccess;
}
# endif /* VBOX_USE_HAL defined */
/**
* Helper function to parse the given mount file and add found entries
*/
void Host::parseMountTable(char *mountTable, std::list <ComObjPtr <HostDVDDrive> > &list)
{
#ifdef RT_OS_LINUX
FILE *mtab = setmntent(mountTable, "r");
if (mtab)
{
struct mntent *mntent;
char *mnt_type;
char *mnt_dev;
char *tmp;
while ((mntent = getmntent(mtab)))
{
mnt_type = (char*)malloc(strlen(mntent->mnt_type) + 1);
mnt_dev = (char*)malloc(strlen(mntent->mnt_fsname) + 1);
strcpy(mnt_type, mntent->mnt_type);
strcpy(mnt_dev, mntent->mnt_fsname);
// supermount fs case
if (strcmp(mnt_type, "supermount") == 0)
{
tmp = strstr(mntent->mnt_opts, "fs=");
if (tmp)
{
free(mnt_type);
mnt_type = strdup(tmp + strlen("fs="));
if (mnt_type)
{
tmp = strchr(mnt_type, ',');
if (tmp)
*tmp = '\0';
}
}
tmp = strstr(mntent->mnt_opts, "dev=");
if (tmp)
{
free(mnt_dev);
mnt_dev = strdup(tmp + strlen("dev="));
if (mnt_dev)
{
tmp = strchr(mnt_dev, ',');
if (tmp)
*tmp = '\0';
}
}
}
// use strstr here to cover things fs types like "udf,iso9660"
if (strstr(mnt_type, "iso9660") == 0)
{
/** @todo check whether we've already got the drive in our list! */
if (validateDevice(mnt_dev, true))
{
ComObjPtr <HostDVDDrive> hostDVDDriveObj;
hostDVDDriveObj.createObject();
hostDVDDriveObj->init (Bstr (mnt_dev));
list.push_back (hostDVDDriveObj);
}
}
free(mnt_dev);
free(mnt_type);
}
endmntent(mtab);
}
#else // RT_OS_SOLARIS
FILE *mntFile = fopen(mountTable, "r");
if (mntFile)
{
struct mnttab mntTab;
while (getmntent(mntFile, &mntTab) == 0)
{
char *mountName = strdup(mntTab.mnt_special);
char *mountPoint = strdup(mntTab.mnt_mountp);
char *mountFSType = strdup(mntTab.mnt_fstype);
// skip devices we are not interested in
if ((*mountName && mountName[0] == '/') && // skip 'fake' devices (like -hosts, proc, fd, swap)
(*mountFSType && (strcmp(mountFSType, "devfs") != 0 && // skip devfs (i.e. /devices)
strcmp(mountFSType, "dev") != 0 && // skip dev (i.e. /dev)
strcmp(mountFSType, "lofs") != 0)) && // skip loop-back file-system (lofs)
(*mountPoint && strcmp(mountPoint, "/") != 0)) // skip point '/' (Can CD/DVD be mounted at '/' ???)
{
char *rawDevName = getfullrawname(mountName);
if (validateDevice(rawDevName, true))
{
ComObjPtr <HostDVDDrive> hostDVDDriveObj;
hostDVDDriveObj.createObject();
hostDVDDriveObj->init (Bstr (rawDevName));
list.push_back (hostDVDDriveObj);
}
free(rawDevName);
}
free(mountName);
free(mountPoint);
free(mountFSType);
}
fclose(mntFile);
}
#endif
}
/**
* Helper function to check whether the given device node is a valid drive
*/
bool Host::validateDevice(const char *deviceNode, bool isCDROM)
{
struct stat statInfo;
bool retValue = false;
// sanity check
if (!deviceNode)
{
return false;
}
// first a simple stat() call
if (stat(deviceNode, &statInfo) < 0)
{
return false;
} else
{
if (isCDROM)
{
if (S_ISCHR(statInfo.st_mode) || S_ISBLK(statInfo.st_mode))
{
int fileHandle;
// now try to open the device
fileHandle = open(deviceNode, O_RDONLY | O_NONBLOCK, 0);
if (fileHandle >= 0)
{
cdrom_subchnl cdChannelInfo;
cdChannelInfo.cdsc_format = CDROM_MSF;
// this call will finally reveal the whole truth
#ifdef RT_OS_LINUX
if ((ioctl(fileHandle, CDROMSUBCHNL, &cdChannelInfo) == 0) ||
(errno == EIO) || (errno == ENOENT) ||
(errno == EINVAL) || (errno == ENOMEDIUM))
#else
if ((ioctl(fileHandle, CDROMSUBCHNL, &cdChannelInfo) == 0) ||
(errno == EIO) || (errno == ENOENT) ||
(errno == EINVAL))
#endif
{
retValue = true;
}
close(fileHandle);
}
}
} else
{
// floppy case
if (S_ISCHR(statInfo.st_mode) || S_ISBLK(statInfo.st_mode))
{
/// @todo do some more testing, maybe a nice IOCTL!
retValue = true;
}
}
}
return retValue;
}
#endif // RT_OS_LINUX || RT_OS_SOLARIS
#ifdef VBOX_WITH_USB
/**
* Checks for the presense and status of the USB Proxy Service.
* Returns S_OK when the Proxy is present and OK, or E_FAIL and a
* corresponding error message otherwise. Intended to be used by methods
* that rely on the Proxy Service availability.
*
* @note This method may return a warning result code. It is recommended to use
* MultiError to store the return value.
*
* @note Locks this object for reading.
*/
HRESULT Host::checkUSBProxyService()
{
AutoWriteLock alock (this);
CHECK_READY();
AssertReturn (mUSBProxyService, E_FAIL);
if (!mUSBProxyService->isActive())
{
/* disable the USB controller completely to avoid assertions if the
* USB proxy service could not start. */
if (mUSBProxyService->getLastError() == VERR_FILE_NOT_FOUND)
return setWarning (E_FAIL,
tr ("Could not load the Host USB Proxy Service (%Vrc). "
"The service might be not installed on the host computer"),
mUSBProxyService->getLastError());
if (mUSBProxyService->getLastError() == VINF_SUCCESS)
return setWarning (E_FAIL,
tr ("The USB Proxy Service has not yet been ported to this host"));
return setWarning (E_FAIL,
tr ("Could not load the Host USB Proxy service (%Vrc)"),
mUSBProxyService->getLastError());
}
return S_OK;
}
#endif /* VBOX_WITH_USB */
#ifdef RT_OS_WINDOWS
/* The original source of the VBoxTAP adapter creation/destruction code has the following copyright */
/*
Copyright 2004 by the Massachusetts Institute of Technology
All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the Massachusetts
Institute of Technology (M.I.T.) not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
*/
#define NETSHELL_LIBRARY _T("netshell.dll")
/**
* Use the IShellFolder API to rename the connection.
*/
static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName)
{
/* This is the GUID for the network connections folder. It is constant.
* {7007ACC7-3202-11D1-AAD2-00805FC1270E} */
const GUID CLSID_NetworkConnections = {
0x7007ACC7, 0x3202, 0x11D1, {
0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
}
};
LPITEMIDLIST pidl = NULL;
IShellFolder *pShellFolder = NULL;
HRESULT hr;
/* Build the display name in the form "::{GUID}". */
if (wcslen (wGuid) >= MAX_PATH)
return E_INVALIDARG;
WCHAR szAdapterGuid[MAX_PATH + 2] = {0};
swprintf (szAdapterGuid, L"::%ls", wGuid);
/* Create an instance of the network connections folder. */
hr = CoCreateInstance (CLSID_NetworkConnections, NULL,
CLSCTX_INPROC_SERVER, IID_IShellFolder,
reinterpret_cast <LPVOID *> (&pShellFolder));
/* Parse the display name. */
if (SUCCEEDED (hr))
{
hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL,
&pidl, NULL);
}
if (SUCCEEDED (hr))
{
hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL,
&pidl);
}
CoTaskMemFree (pidl);
if (pShellFolder)
pShellFolder->Release();
return hr;
}
extern "C" HRESULT RenameConnection (PCWSTR GuidString, PCWSTR NewName)
{
typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR);
lpHrRenameConnection RenameConnectionFunc = NULL;
HRESULT status;
/* First try the IShellFolder interface, which was unimplemented
* for the network connections folder before XP. */
status = rename_shellfolder (GuidString, NewName);
if (status == E_NOTIMPL)
{
/** @todo that code doesn't seem to work! */
/* The IShellFolder interface is not implemented on this platform.
* Try the (undocumented) HrRenameConnection API in the netshell
* library. */
CLSID clsid;
HINSTANCE hNetShell;
status = CLSIDFromString ((LPOLESTR) GuidString, &clsid);
if (FAILED(status))
return E_FAIL;
hNetShell = LoadLibrary (NETSHELL_LIBRARY);
if (hNetShell == NULL)
return E_FAIL;
RenameConnectionFunc =
(lpHrRenameConnection) GetProcAddress (hNetShell,
"HrRenameConnection");
if (RenameConnectionFunc == NULL)
{
FreeLibrary (hNetShell);
return E_FAIL;
}
status = RenameConnectionFunc (&clsid, NewName);
FreeLibrary (hNetShell);
}
if (FAILED (status))
return status;
return S_OK;
}
#define DRIVERHWID _T("vboxtap")
#define SetErrBreak(strAndArgs) \
if (1) { \
aErrMsg = Utf8StrFmt strAndArgs; vrc = VERR_GENERAL_FAILURE; break; \
} else do {} while (0)
/* static */
int Host::createNetworkInterface (SVCHlpClient *aClient,
const Utf8Str &aName,
Guid &aGUID, Utf8Str &aErrMsg)
{
LogFlowFuncEnter();
LogFlowFunc (("Network connection name = '%s'\n", aName.raw()));
AssertReturn (aClient, VERR_INVALID_POINTER);
AssertReturn (!aName.isNull(), VERR_INVALID_PARAMETER);
int vrc = VINF_SUCCESS;
HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
DWORD ret = 0;
BOOL found = FALSE;
BOOL registered = FALSE;
BOOL destroyList = FALSE;
TCHAR pCfgGuidString [50];
do
{
BOOL ok;
GUID netGuid;
SP_DRVINFO_DATA DriverInfoData;
SP_DEVINSTALL_PARAMS DeviceInstallParams;
TCHAR className [MAX_PATH];
DWORD index = 0;
PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
/* for our purposes, 2k buffer is more
* than enough to obtain the hardware ID
* of the VBoxTAP driver. */
DWORD detailBuf [2048];
HKEY hkey = NULL;
DWORD cbSize;
DWORD dwValueType;
/* initialize the structure size */
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
/* copy the net class GUID */
memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
/* create an empty device info set associated with the net class GUID */
hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)",
GetLastError()));
/* get the class name from GUID */
ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL);
if (!ok)
SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)",
GetLastError()));
/* create a device info element and add the new device instance
* key to registry */
ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL,
DICD_GENERATE_ID, &DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)",
GetLastError()));
/* select the newly created device info to be the currently
selected member */
ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
GetLastError()));
/* build a list of class drivers */
ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData,
SPDIT_CLASSDRIVER);
if (!ok)
SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)",
GetLastError()));
destroyList = TRUE;
/* enumerate the driver info list */
while (TRUE)
{
BOOL ret;
ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData,
SPDIT_CLASSDRIVER, index, &DriverInfoData);
/* if the function failed and GetLastError() returned
* ERROR_NO_MORE_ITEMS, then we have reached the end of the
* list. Othewise there was something wrong with this
* particular driver. */
if (!ret)
{
if(GetLastError() == ERROR_NO_MORE_ITEMS)
break;
else
{
index++;
continue;
}
}
pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
/* if we successfully find the hardware ID and it turns out to
* be the one for the loopback driver, then we are done. */
if (SetupDiGetDriverInfoDetail (hDeviceInfo,
&DeviceInfoData,
&DriverInfoData,
pDriverInfoDetail,
sizeof (detailBuf),
NULL))
{
TCHAR * t;
/* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the
* whole list and see if there is a match somewhere. */
t = pDriverInfoDetail->HardwareID;
while (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])])
{
if (!_tcsicmp(t, DRIVERHWID))
break;
t += _tcslen(t) + 1;
}
if (t && *t && t < (TCHAR *) &detailBuf [sizeof(detailBuf) / sizeof (detailBuf[0])])
{
found = TRUE;
break;
}
}
index ++;
}
if (!found)
SetErrBreak ((tr ("Could not find Host Interface Networking driver! "
"Please reinstall")));
/* set the loopback driver to be the currently selected */
ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData,
&DriverInfoData);
if (!ok)
SetErrBreak (("SetupDiSetSelectedDriver failed (0x%08X)",
GetLastError()));
/* register the phantom device to prepare for install */
ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo,
&DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)",
GetLastError()));
/* registered, but remove if errors occur in the following code */
registered = TRUE;
/* ask the installer if we can install the device */
ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo,
&DeviceInfoData);
if (!ok)
{
if (GetLastError() != ERROR_DI_DO_DEFAULT)
SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)",
GetLastError()));
/* that's fine */
}
/* install the files first */
ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo,
&DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)",
GetLastError()));
/* get the device install parameters and disable filecopy */
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
&DeviceInstallParams);
if (ok)
{
DeviceInstallParams.Flags |= DI_NOFILECOPY;
ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData,
&DeviceInstallParams);
if (!ok)
SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)",
GetLastError()));
}
/*
* Register any device-specific co-installers for this device,
*/
ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS,
hDeviceInfo,
&DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)",
GetLastError()));
/*
* install any installer-specified interfaces.
* and then do the real install
*/
ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES,
hDeviceInfo,
&DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)",
GetLastError()));
ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE,
hDeviceInfo,
&DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)",
GetLastError()));
/* Figure out NetCfgInstanceId */
hkey = SetupDiOpenDevRegKey (hDeviceInfo,
&DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
KEY_READ);
if (hkey == INVALID_HANDLE_VALUE)
SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)",
GetLastError()));
cbSize = sizeof (pCfgGuidString);
DWORD ret;
ret = RegQueryValueEx (hkey, _T ("NetCfgInstanceId"), NULL,
&dwValueType, (LPBYTE) pCfgGuidString, &cbSize);
RegCloseKey (hkey);
ret = RenameConnection (pCfgGuidString, Bstr (aName));
if (FAILED (ret))
SetErrBreak (("Failed to set interface name (ret=0x%08X, "
"pCfgGuidString='%ls', cbSize=%d)",
ret, pCfgGuidString, cbSize));
}
while (0);
/*
* cleanup
*/
if (hDeviceInfo != INVALID_HANDLE_VALUE)
{
/* an error has occured, but the device is registered, we must remove it */
if (ret != 0 && registered)
SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData);
/* destroy the driver info list */
if (destroyList)
SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData,
SPDIT_CLASSDRIVER);
/* clean up the device info set */
SetupDiDestroyDeviceInfoList (hDeviceInfo);
}
/* return the network connection GUID on success */
if (VBOX_SUCCESS (vrc))
{
/* remove the curly bracket at the end */
pCfgGuidString [_tcslen (pCfgGuidString) - 1] = '\0';
LogFlowFunc (("Network connection GUID string = {%ls}\n", pCfgGuidString + 1));
aGUID = Guid (Utf8Str (pCfgGuidString + 1));
LogFlowFunc (("Network connection GUID = {%Vuuid}\n", aGUID.raw()));
Assert (!aGUID.isEmpty());
}
LogFlowFunc (("vrc=%Vrc\n", vrc));
LogFlowFuncLeave();
return vrc;
}
/* static */
int Host::removeNetworkInterface (SVCHlpClient *aClient,
const Guid &aGUID,
Utf8Str &aErrMsg)
{
LogFlowFuncEnter();
LogFlowFunc (("Network connection GUID = {%Vuuid}\n", aGUID.raw()));
AssertReturn (aClient, VERR_INVALID_POINTER);
AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER);
int vrc = VINF_SUCCESS;
do
{
TCHAR lszPnPInstanceId [512] = {0};
/* We have to find the device instance ID through a registry search */
HKEY hkeyNetwork = 0;
HKEY hkeyConnection = 0;
do
{
char strRegLocation [256];
sprintf (strRegLocation,
"SYSTEM\\CurrentControlSet\\Control\\Network\\"
"{4D36E972-E325-11CE-BFC1-08002BE10318}\\{%s}",
aGUID.toString().raw());
LONG status;
status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, strRegLocation, 0,
KEY_READ, &hkeyNetwork);
if ((status != ERROR_SUCCESS) || !hkeyNetwork)
SetErrBreak ((
tr ("Host interface network is not found in registry (%s) [1]"),
strRegLocation));
status = RegOpenKeyExA (hkeyNetwork, "Connection", 0,
KEY_READ, &hkeyConnection);
if ((status != ERROR_SUCCESS) || !hkeyConnection)
SetErrBreak ((
tr ("Host interface network is not found in registry (%s) [2]"),
strRegLocation));
DWORD len = sizeof (lszPnPInstanceId);
DWORD dwKeyType;
status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL,
&dwKeyType, (LPBYTE) lszPnPInstanceId, &len);
if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ))
SetErrBreak ((
tr ("Host interface network is not found in registry (%s) [3]"),
strRegLocation));
}
while (0);
if (hkeyConnection)
RegCloseKey (hkeyConnection);
if (hkeyNetwork)
RegCloseKey (hkeyNetwork);
if (VBOX_FAILURE (vrc))
break;
/*
* Now we are going to enumerate all network devices and
* wait until we encounter the right device instance ID
*/
HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
do
{
BOOL ok;
DWORD ret = 0;
GUID netGuid;
SP_DEVINFO_DATA DeviceInfoData;
DWORD index = 0;
BOOL found = FALSE;
DWORD size = 0;
/* initialize the structure size */
DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
/* copy the net class GUID */
memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET));
/* return a device info set contains all installed devices of the Net class */
hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError()));
/* enumerate the driver info list */
while (TRUE)
{
TCHAR *deviceHwid;
ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData);
if (!ok)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
else
{
index++;
continue;
}
}
/* try to get the hardware ID registry property */
ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
&DeviceInfoData,
SPDRP_HARDWAREID,
NULL,
NULL,
0,
&size);
if (!ok)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
index++;
continue;
}
deviceHwid = (TCHAR *) malloc (size);
ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo,
&DeviceInfoData,
SPDRP_HARDWAREID,
NULL,
(PBYTE)deviceHwid,
size,
NULL);
if (!ok)
{
free (deviceHwid);
deviceHwid = NULL;
index++;
continue;
}
}
else
{
/* something is wrong. This shouldn't have worked with a NULL buffer */
index++;
continue;
}
for (TCHAR *t = deviceHwid;
t && *t && t < &deviceHwid[size / sizeof(TCHAR)];
t += _tcslen (t) + 1)
{
if (!_tcsicmp (DRIVERHWID, t))
{
/* get the device instance ID */
TCHAR devID [MAX_DEVICE_ID_LEN];
if (CM_Get_Device_ID(DeviceInfoData.DevInst,
devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
{
/* compare to what we determined before */
if (wcscmp(devID, lszPnPInstanceId) == 0)
{
found = TRUE;
break;
}
}
}
}
if (deviceHwid)
{
free (deviceHwid);
deviceHwid = NULL;
}
if (found)
break;
index++;
}
if (found == FALSE)
SetErrBreak ((tr ("Host Interface Network driver not found (0x%08X)"),
GetLastError()));
ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)",
GetLastError()));
ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
if (!ok)
SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)",
GetLastError()));
}
while (0);
/* clean up the device info set */
if (hDeviceInfo != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList (hDeviceInfo);
if (VBOX_FAILURE (vrc))
break;
}
while (0);
LogFlowFunc (("vrc=%Vrc\n", vrc));
LogFlowFuncLeave();
return vrc;
}
#undef SetErrBreak
/* static */
HRESULT Host::networkInterfaceHelperClient (SVCHlpClient *aClient,
Progress *aProgress,
void *aUser, int *aVrc)
{
LogFlowFuncEnter();
LogFlowFunc (("aClient={%p}, aProgress={%p}, aUser={%p}\n",
aClient, aProgress, aUser));
AssertReturn ((aClient == NULL && aProgress == NULL && aVrc == NULL) ||
(aClient != NULL && aProgress != NULL && aVrc != NULL),
E_POINTER);
AssertReturn (aUser, E_POINTER);
std::auto_ptr <NetworkInterfaceHelperClientData>
d (static_cast <NetworkInterfaceHelperClientData *> (aUser));
if (aClient == NULL)
{
/* "cleanup only" mode, just return (it will free aUser) */
return S_OK;
}
HRESULT rc = S_OK;
int vrc = VINF_SUCCESS;
switch (d->msgCode)
{
case SVCHlpMsg::CreateHostNetworkInterface:
{
LogFlowFunc (("CreateHostNetworkInterface:\n"));
LogFlowFunc (("Network connection name = '%ls'\n", d->name.raw()));
/* write message and parameters */
vrc = aClient->write (d->msgCode);
if (VBOX_FAILURE (vrc)) break;
vrc = aClient->write (Utf8Str (d->name));
if (VBOX_FAILURE (vrc)) break;
/* wait for a reply */
bool endLoop = false;
while (!endLoop)
{
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
vrc = aClient->read (reply);
if (VBOX_FAILURE (vrc)) break;
switch (reply)
{
case SVCHlpMsg::CreateHostNetworkInterface_OK:
{
/* read the GUID */
Guid guid;
vrc = aClient->read (guid);
if (VBOX_FAILURE (vrc)) break;
LogFlowFunc (("Network connection GUID = {%Vuuid}\n", guid.raw()));
/* initialize the object returned to the caller by
* CreateHostNetworkInterface() */
rc = d->iface->init (d->name, guid);
endLoop = true;
break;
}
case SVCHlpMsg::Error:
{
/* read the error message */
Utf8Str errMsg;
vrc = aClient->read (errMsg);
if (VBOX_FAILURE (vrc)) break;
rc = setError (E_FAIL, errMsg);
endLoop = true;
break;
}
default:
{
endLoop = true;
ComAssertMsgFailedBreak ((
"Invalid message code %d (%08lX)\n",
reply, reply),
rc = E_FAIL);
}
}
}
break;
}
case SVCHlpMsg::RemoveHostNetworkInterface:
{
LogFlowFunc (("RemoveHostNetworkInterface:\n"));
LogFlowFunc (("Network connection GUID = {%Vuuid}\n", d->guid.raw()));
/* write message and parameters */
vrc = aClient->write (d->msgCode);
if (VBOX_FAILURE (vrc)) break;
vrc = aClient->write (d->guid);
if (VBOX_FAILURE (vrc)) break;
/* wait for a reply */
bool endLoop = false;
while (!endLoop)
{
SVCHlpMsg::Code reply = SVCHlpMsg::Null;
vrc = aClient->read (reply);
if (VBOX_FAILURE (vrc)) break;
switch (reply)
{
case SVCHlpMsg::OK:
{
/* no parameters */
rc = S_OK;
endLoop = true;
break;
}
case SVCHlpMsg::Error:
{
/* read the error message */
Utf8Str errMsg;
vrc = aClient->read (errMsg);
if (VBOX_FAILURE (vrc)) break;
rc = setError (E_FAIL, errMsg);
endLoop = true;
break;
}
default:
{
endLoop = true;
ComAssertMsgFailedBreak ((
"Invalid message code %d (%08lX)\n",
reply, reply),
rc = E_FAIL);
}
}
}
break;
}
default:
ComAssertMsgFailedBreak ((
"Invalid message code %d (%08lX)\n",
d->msgCode, d->msgCode),
rc = E_FAIL);
}
if (aVrc)
*aVrc = vrc;
LogFlowFunc (("rc=0x%08X, vrc=%Vrc\n", rc, vrc));
LogFlowFuncLeave();
return rc;
}
/* static */
int Host::networkInterfaceHelperServer (SVCHlpClient *aClient,
SVCHlpMsg::Code aMsgCode)
{
LogFlowFuncEnter();
LogFlowFunc (("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
AssertReturn (aClient, VERR_INVALID_POINTER);
int vrc = VINF_SUCCESS;
switch (aMsgCode)
{
case SVCHlpMsg::CreateHostNetworkInterface:
{
LogFlowFunc (("CreateHostNetworkInterface:\n"));
Utf8Str name;
vrc = aClient->read (name);
if (VBOX_FAILURE (vrc)) break;
Guid guid;
Utf8Str errMsg;
vrc = createNetworkInterface (aClient, name, guid, errMsg);
if (VBOX_SUCCESS (vrc))
{
/* write success followed by GUID */
vrc = aClient->write (SVCHlpMsg::CreateHostNetworkInterface_OK);
if (VBOX_FAILURE (vrc)) break;
vrc = aClient->write (guid);
if (VBOX_FAILURE (vrc)) break;
}
else
{
/* write failure followed by error message */
if (errMsg.isEmpty())
errMsg = Utf8StrFmt ("Unspecified error (%Vrc)", vrc);
vrc = aClient->write (SVCHlpMsg::Error);
if (VBOX_FAILURE (vrc)) break;
vrc = aClient->write (errMsg);
if (VBOX_FAILURE (vrc)) break;
}
break;
}
case SVCHlpMsg::RemoveHostNetworkInterface:
{
LogFlowFunc (("RemoveHostNetworkInterface:\n"));
Guid guid;
vrc = aClient->read (guid);
if (VBOX_FAILURE (vrc)) break;
Utf8Str errMsg;
vrc = removeNetworkInterface (aClient, guid, errMsg);
if (VBOX_SUCCESS (vrc))
{
/* write parameter-less success */
vrc = aClient->write (SVCHlpMsg::OK);
if (VBOX_FAILURE (vrc)) break;
}
else
{
/* write failure followed by error message */
if (errMsg.isEmpty())
errMsg = Utf8StrFmt ("Unspecified error (%Vrc)", vrc);
vrc = aClient->write (SVCHlpMsg::Error);
if (VBOX_FAILURE (vrc)) break;
vrc = aClient->write (errMsg);
if (VBOX_FAILURE (vrc)) break;
}
break;
}
default:
AssertMsgFailedBreakStmt (
("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
VERR_GENERAL_FAILURE);
}
LogFlowFunc (("vrc=%Vrc\n", vrc));
LogFlowFuncLeave();
return vrc;
}
#endif /* RT_OS_WINDOWS */
#ifdef VBOX_WITH_RESOURCE_USAGE_API
/* static */
void Host::UsageSamplerCallback (PRTTIMER pTimer, void *pvUser, uint64_t iTick)
{
AssertReturnVoid (pvUser != NULL);
static_cast <Host *> (pvUser)->usageSamplerCallback();
}
void Host::usageSamplerCallback()
{
int vrc = RTSystemProcessorGetUsageStats (&mCpuStats);
AssertMsgRC (vrc, ("Failed to get CPU stats (%Rra)\n", vrc));
// LogFlowThisFunc (("user=%u%% system=%u%% &mCpuStats=%p\n",
// mCpuStats.u32User / 10000000,
// mCpuStats.u32System / 10000000, &mCpuStats);
// LogFlowThisFunc (("user=%.2f system=%.2f idle=%.2f\n", mCpuStats.u32User/10000000.,
// mCpuStats.u32System/10000000., mCpuStats.u32Idle/10000000.);
}
#endif /* VBOX_WITH_RESOURCE_USAGE_API */