From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Frontends/VBoxManage/VBoxManageList.cpp | 2434 ++++++++++++++++++++++ 1 file changed, 2434 insertions(+) create mode 100644 src/VBox/Frontends/VBoxManage/VBoxManageList.cpp (limited to 'src/VBox/Frontends/VBoxManage/VBoxManageList.cpp') diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp new file mode 100644 index 00000000..f2ed947d --- /dev/null +++ b/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp @@ -0,0 +1,2434 @@ +/* $Id: VBoxManageList.cpp $ */ +/** @file + * VBoxManage - The 'list' command. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "VBoxManage.h" +using namespace com; + +DECLARE_TRANSLATION_CONTEXT(List); + +#ifdef VBOX_WITH_HOSTNETIF_API +static const char *getHostIfMediumTypeText(HostNetworkInterfaceMediumType_T enmType) +{ + switch (enmType) + { + case HostNetworkInterfaceMediumType_Ethernet: return "Ethernet"; + case HostNetworkInterfaceMediumType_PPP: return "PPP"; + case HostNetworkInterfaceMediumType_SLIP: return "SLIP"; + case HostNetworkInterfaceMediumType_Unknown: return List::tr("Unknown"); +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case HostNetworkInterfaceMediumType_32BitHack: break; /* Shut up compiler warnings. */ +#endif + } + return List::tr("unknown"); +} + +static const char *getHostIfStatusText(HostNetworkInterfaceStatus_T enmStatus) +{ + switch (enmStatus) + { + case HostNetworkInterfaceStatus_Up: return List::tr("Up"); + case HostNetworkInterfaceStatus_Down: return List::tr("Down"); + case HostNetworkInterfaceStatus_Unknown: return List::tr("Unknown"); +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case HostNetworkInterfaceStatus_32BitHack: break; /* Shut up compiler warnings. */ +#endif + } + return List::tr("unknown"); +} +#endif /* VBOX_WITH_HOSTNETIF_API */ + +static const char*getDeviceTypeText(DeviceType_T enmType) +{ + switch (enmType) + { + case DeviceType_HardDisk: return List::tr("HardDisk"); + case DeviceType_DVD: return "DVD"; + case DeviceType_Floppy: return List::tr("Floppy"); + /* Make MSC happy */ + case DeviceType_Null: return "Null"; + case DeviceType_Network: return List::tr("Network"); + case DeviceType_USB: return "USB"; + case DeviceType_SharedFolder: return List::tr("SharedFolder"); + case DeviceType_Graphics3D: return List::tr("Graphics3D"); + case DeviceType_End: break; /* Shut up compiler warnings. */ +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case DeviceType_32BitHack: break; /* Shut up compiler warnings. */ +#endif + } + return List::tr("Unknown"); +} + + +/** + * List internal networks. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listInternalNetworks(const ComPtr pVirtualBox) +{ + HRESULT hrc; + com::SafeArray internalNetworks; + CHECK_ERROR(pVirtualBox, COMGETTER(InternalNetworks)(ComSafeArrayAsOutParam(internalNetworks))); + for (size_t i = 0; i < internalNetworks.size(); ++i) + { + RTPrintf(List::tr("Name: %ls\n"), internalNetworks[i]); + } + return hrc; +} + + +/** + * List network interfaces information (bridged/host only). + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + * @param fIsBridged Selects between listing host interfaces (for + * use with bridging) or host only interfaces. + */ +static HRESULT listNetworkInterfaces(const ComPtr pVirtualBox, + bool fIsBridged) +{ + HRESULT hrc; + ComPtr host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); + com::SafeIfaceArray hostNetworkInterfaces; +#if defined(VBOX_WITH_NETFLT) + if (fIsBridged) + CHECK_ERROR(host, FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_Bridged, + ComSafeArrayAsOutParam(hostNetworkInterfaces))); + else + CHECK_ERROR(host, FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_HostOnly, + ComSafeArrayAsOutParam(hostNetworkInterfaces))); +#else + RT_NOREF(fIsBridged); + CHECK_ERROR(host, COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces))); +#endif + for (size_t i = 0; i < hostNetworkInterfaces.size(); ++i) + { + ComPtr networkInterface = hostNetworkInterfaces[i]; +#ifndef VBOX_WITH_HOSTNETIF_API + Bstr interfaceName; + networkInterface->COMGETTER(Name)(interfaceName.asOutParam()); + RTPrintf(List::tr("Name: %ls\n"), interfaceName.raw()); + Guid interfaceGuid; + networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam()); + RTPrintf("GUID: %ls\n\n", Bstr(interfaceGuid.toString()).raw()); +#else /* VBOX_WITH_HOSTNETIF_API */ + Bstr interfaceName; + networkInterface->COMGETTER(Name)(interfaceName.asOutParam()); + RTPrintf(List::tr("Name: %ls\n"), interfaceName.raw()); + Bstr interfaceGuid; + networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam()); + RTPrintf("GUID: %ls\n", interfaceGuid.raw()); + BOOL fDHCPEnabled = FALSE; + networkInterface->COMGETTER(DHCPEnabled)(&fDHCPEnabled); + RTPrintf("DHCP: %s\n", fDHCPEnabled ? List::tr("Enabled") : List::tr("Disabled")); + + Bstr IPAddress; + networkInterface->COMGETTER(IPAddress)(IPAddress.asOutParam()); + RTPrintf(List::tr("IPAddress: %ls\n"), IPAddress.raw()); + Bstr NetworkMask; + networkInterface->COMGETTER(NetworkMask)(NetworkMask.asOutParam()); + RTPrintf(List::tr("NetworkMask: %ls\n"), NetworkMask.raw()); + Bstr IPV6Address; + networkInterface->COMGETTER(IPV6Address)(IPV6Address.asOutParam()); + RTPrintf(List::tr("IPV6Address: %ls\n"), IPV6Address.raw()); + ULONG IPV6NetworkMaskPrefixLength; + networkInterface->COMGETTER(IPV6NetworkMaskPrefixLength)(&IPV6NetworkMaskPrefixLength); + RTPrintf(List::tr("IPV6NetworkMaskPrefixLength: %d\n"), IPV6NetworkMaskPrefixLength); + Bstr HardwareAddress; + networkInterface->COMGETTER(HardwareAddress)(HardwareAddress.asOutParam()); + RTPrintf(List::tr("HardwareAddress: %ls\n"), HardwareAddress.raw()); + HostNetworkInterfaceMediumType_T Type; + networkInterface->COMGETTER(MediumType)(&Type); + RTPrintf(List::tr("MediumType: %s\n"), getHostIfMediumTypeText(Type)); + BOOL fWireless = FALSE; + networkInterface->COMGETTER(Wireless)(&fWireless); + RTPrintf(List::tr("Wireless: %s\n"), fWireless ? List::tr("Yes") : List::tr("No")); + HostNetworkInterfaceStatus_T Status; + networkInterface->COMGETTER(Status)(&Status); + RTPrintf(List::tr("Status: %s\n"), getHostIfStatusText(Status)); + Bstr netName; + networkInterface->COMGETTER(NetworkName)(netName.asOutParam()); + RTPrintf(List::tr("VBoxNetworkName: %ls\n\n"), netName.raw()); +#endif + } + return hrc; +} + + +#ifdef VBOX_WITH_VMNET +/** + * List configured host-only networks. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + * @param Reserved Placeholder! + */ +static HRESULT listHostOnlyNetworks(const ComPtr pVirtualBox) +{ + HRESULT hrc; + com::SafeIfaceArray hostOnlyNetworks; + CHECK_ERROR(pVirtualBox, COMGETTER(HostOnlyNetworks)(ComSafeArrayAsOutParam(hostOnlyNetworks))); + for (size_t i = 0; i < hostOnlyNetworks.size(); ++i) + { + ComPtr hostOnlyNetwork = hostOnlyNetworks[i]; + Bstr bstrNetworkName; + CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(NetworkName)(bstrNetworkName.asOutParam())); + RTPrintf(List::tr("Name: %ls\n"), bstrNetworkName.raw()); + + Bstr bstr; + CHECK_ERROR(hostOnlyNetwork, COMGETTER(Id)(bstr.asOutParam())); + RTPrintf("GUID: %ls\n\n", bstr.raw()); + + BOOL fEnabled = FALSE; + CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(Enabled)(&fEnabled)); + RTPrintf(List::tr("State: %s\n"), fEnabled ? List::tr("Enabled") : List::tr("Disabled")); + + CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(NetworkMask)(bstr.asOutParam())); + RTPrintf(List::tr("NetworkMask: %ls\n"), bstr.raw()); + + CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(LowerIP)(bstr.asOutParam())); + RTPrintf(List::tr("LowerIP: %ls\n"), bstr.raw()); + + CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(UpperIP)(bstr.asOutParam())); + RTPrintf(List::tr("UpperIP: %ls\n"), bstr.raw()); + + // CHECK_ERROR2I(hostOnlyNetwork, COMGETTER(Id)(bstr.asOutParam()); + // RTPrintf("NetworkId: %ls\n", bstr.raw()); + + RTPrintf(List::tr("VBoxNetworkName: hostonly-%ls\n\n"), bstrNetworkName.raw()); + } + return hrc; +} +#endif /* VBOX_WITH_VMNET */ + + +#ifdef VBOX_WITH_CLOUD_NET +/** + * List configured cloud network attachments. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + * @param Reserved Placeholder! + */ +static HRESULT listCloudNetworks(const ComPtr pVirtualBox) +{ + com::SafeIfaceArray cloudNetworks; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(CloudNetworks)(ComSafeArrayAsOutParam(cloudNetworks)), hrcCheck); + for (size_t i = 0; i < cloudNetworks.size(); ++i) + { + ComPtr cloudNetwork = cloudNetworks[i]; + Bstr networkName; + cloudNetwork->COMGETTER(NetworkName)(networkName.asOutParam()); + RTPrintf(List::tr("Name: %ls\n"), networkName.raw()); + // Guid interfaceGuid; + // cloudNetwork->COMGETTER(Id)(interfaceGuid.asOutParam()); + // RTPrintf("GUID: %ls\n\n", Bstr(interfaceGuid.toString()).raw()); + BOOL fEnabled = FALSE; + cloudNetwork->COMGETTER(Enabled)(&fEnabled); + RTPrintf(List::tr("State: %s\n"), fEnabled ? List::tr("Enabled") : List::tr("Disabled")); + + Bstr Provider; + cloudNetwork->COMGETTER(Provider)(Provider.asOutParam()); + RTPrintf(List::tr("CloudProvider: %ls\n"), Provider.raw()); + Bstr Profile; + cloudNetwork->COMGETTER(Profile)(Profile.asOutParam()); + RTPrintf(List::tr("CloudProfile: %ls\n"), Profile.raw()); + Bstr NetworkId; + cloudNetwork->COMGETTER(NetworkId)(NetworkId.asOutParam()); + RTPrintf(List::tr("CloudNetworkId: %ls\n"), NetworkId.raw()); + Bstr netName = BstrFmt("cloud-%ls", networkName.raw()); + RTPrintf(List::tr("VBoxNetworkName: %ls\n\n"), netName.raw()); + } + return S_OK; +} +#endif /* VBOX_WITH_CLOUD_NET */ + + +/** + * List host information. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listHostInfo(const ComPtr pVirtualBox) +{ + static struct + { + ProcessorFeature_T feature; + const char *pszName; + } features[] + = + { + { ProcessorFeature_HWVirtEx, List::tr("HW virtualization") }, + { ProcessorFeature_PAE, "PAE" }, + { ProcessorFeature_LongMode, List::tr("long mode") }, + { ProcessorFeature_NestedPaging, List::tr("nested paging") }, + { ProcessorFeature_UnrestrictedGuest, List::tr("unrestricted guest") }, + { ProcessorFeature_NestedHWVirt, List::tr("nested HW virtualization") }, + { ProcessorFeature_VirtVmsaveVmload, List::tr("virt. vmsave/vmload") }, + }; + HRESULT hrc; + ComPtr Host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(Host.asOutParam())); + + RTPrintf(List::tr("Host Information:\n\n")); + + LONG64 u64UtcTime = 0; + CHECK_ERROR(Host, COMGETTER(UTCTime)(&u64UtcTime)); + RTTIMESPEC timeSpec; + char szTime[32]; + RTPrintf(List::tr("Host time: %s\n"), RTTimeSpecToString(RTTimeSpecSetMilli(&timeSpec, u64UtcTime), szTime, sizeof(szTime))); + + ULONG processorOnlineCount = 0; + CHECK_ERROR(Host, COMGETTER(ProcessorOnlineCount)(&processorOnlineCount)); + RTPrintf(List::tr("Processor online count: %lu\n"), processorOnlineCount); + ULONG processorCount = 0; + CHECK_ERROR(Host, COMGETTER(ProcessorCount)(&processorCount)); + RTPrintf(List::tr("Processor count: %lu\n"), processorCount); + ULONG processorOnlineCoreCount = 0; + CHECK_ERROR(Host, COMGETTER(ProcessorOnlineCoreCount)(&processorOnlineCoreCount)); + RTPrintf(List::tr("Processor online core count: %lu\n"), processorOnlineCoreCount); + ULONG processorCoreCount = 0; + CHECK_ERROR(Host, COMGETTER(ProcessorCoreCount)(&processorCoreCount)); + RTPrintf(List::tr("Processor core count: %lu\n"), processorCoreCount); + for (unsigned i = 0; i < RT_ELEMENTS(features); i++) + { + BOOL supported; + CHECK_ERROR(Host, GetProcessorFeature(features[i].feature, &supported)); + RTPrintf(List::tr("Processor supports %s: %s\n"), features[i].pszName, supported ? List::tr("yes") : List::tr("no")); + } + for (ULONG i = 0; i < processorCount; i++) + { + ULONG processorSpeed = 0; + CHECK_ERROR(Host, GetProcessorSpeed(i, &processorSpeed)); + if (processorSpeed) + RTPrintf(List::tr("Processor#%u speed: %lu MHz\n"), i, processorSpeed); + else + RTPrintf(List::tr("Processor#%u speed: unknown\n"), i); + Bstr processorDescription; + CHECK_ERROR(Host, GetProcessorDescription(i, processorDescription.asOutParam())); + RTPrintf(List::tr("Processor#%u description: %ls\n"), i, processorDescription.raw()); + } + + ULONG memorySize = 0; + CHECK_ERROR(Host, COMGETTER(MemorySize)(&memorySize)); + RTPrintf(List::tr("Memory size: %lu MByte\n", "", memorySize), memorySize); + + ULONG memoryAvailable = 0; + CHECK_ERROR(Host, COMGETTER(MemoryAvailable)(&memoryAvailable)); + RTPrintf(List::tr("Memory available: %lu MByte\n", "", memoryAvailable), memoryAvailable); + + Bstr operatingSystem; + CHECK_ERROR(Host, COMGETTER(OperatingSystem)(operatingSystem.asOutParam())); + RTPrintf(List::tr("Operating system: %ls\n"), operatingSystem.raw()); + + Bstr oSVersion; + CHECK_ERROR(Host, COMGETTER(OSVersion)(oSVersion.asOutParam())); + RTPrintf(List::tr("Operating system version: %ls\n"), oSVersion.raw()); + return hrc; +} + + +/** + * List media information. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + * @param aMedia Medium objects to list information for. + * @param pszParentUUIDStr String with the parent UUID string (or "base"). + * @param fOptLong Long (@c true) or short list format. + */ +static HRESULT listMedia(const ComPtr pVirtualBox, + const com::SafeIfaceArray &aMedia, + const char *pszParentUUIDStr, + bool fOptLong) +{ + HRESULT hrc = S_OK; + for (size_t i = 0; i < aMedia.size(); ++i) + { + ComPtr pMedium = aMedia[i]; + + hrc = showMediumInfo(pVirtualBox, pMedium, pszParentUUIDStr, fOptLong); + + RTPrintf("\n"); + + com::SafeIfaceArray children; + CHECK_ERROR(pMedium, COMGETTER(Children)(ComSafeArrayAsOutParam(children))); + if (children.size() > 0) + { + Bstr uuid; + pMedium->COMGETTER(Id)(uuid.asOutParam()); + + // depth first listing of child media + hrc = listMedia(pVirtualBox, children, Utf8Str(uuid).c_str(), fOptLong); + } + } + + return hrc; +} + + +/** + * List virtual image backends. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listHddBackends(const ComPtr pVirtualBox) +{ + HRESULT hrc; + ComPtr systemProperties; + CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam())); + com::SafeIfaceArray mediumFormats; + CHECK_ERROR(systemProperties, COMGETTER(MediumFormats)(ComSafeArrayAsOutParam(mediumFormats))); + + RTPrintf(List::tr("Supported hard disk backends:\n\n")); + for (size_t i = 0; i < mediumFormats.size(); ++i) + { + /* General information */ + Bstr id; + CHECK_ERROR(mediumFormats[i], COMGETTER(Id)(id.asOutParam())); + + Bstr description; + CHECK_ERROR(mediumFormats[i], + COMGETTER(Name)(description.asOutParam())); + + ULONG caps = 0; + com::SafeArray mediumFormatCap; + CHECK_ERROR(mediumFormats[i], + COMGETTER(Capabilities)(ComSafeArrayAsOutParam(mediumFormatCap))); + for (ULONG j = 0; j < mediumFormatCap.size(); j++) + caps |= mediumFormatCap[j]; + + + RTPrintf(List::tr("Backend %u: id='%ls' description='%ls' capabilities=%#06x extensions='"), + i, id.raw(), description.raw(), caps); + + /* File extensions */ + com::SafeArray fileExtensions; + com::SafeArray deviceTypes; + CHECK_ERROR(mediumFormats[i], + DescribeFileExtensions(ComSafeArrayAsOutParam(fileExtensions), ComSafeArrayAsOutParam(deviceTypes))); + for (size_t j = 0; j < fileExtensions.size(); ++j) + { + RTPrintf("%ls (%s)", Bstr(fileExtensions[j]).raw(), getDeviceTypeText(deviceTypes[j])); + if (j != fileExtensions.size()-1) + RTPrintf(","); + } + RTPrintf("'"); + + /* Configuration keys */ + com::SafeArray propertyNames; + com::SafeArray propertyDescriptions; + com::SafeArray propertyTypes; + com::SafeArray propertyFlags; + com::SafeArray propertyDefaults; + CHECK_ERROR(mediumFormats[i], + DescribeProperties(ComSafeArrayAsOutParam(propertyNames), + ComSafeArrayAsOutParam(propertyDescriptions), + ComSafeArrayAsOutParam(propertyTypes), + ComSafeArrayAsOutParam(propertyFlags), + ComSafeArrayAsOutParam(propertyDefaults))); + + RTPrintf(List::tr(" properties=(")); + if (propertyNames.size() > 0) + { + for (size_t j = 0; j < propertyNames.size(); ++j) + { + RTPrintf(List::tr("\n name='%ls' desc='%ls' type="), + Bstr(propertyNames[j]).raw(), Bstr(propertyDescriptions[j]).raw()); + switch (propertyTypes[j]) + { + case DataType_Int32: RTPrintf(List::tr("int")); break; + case DataType_Int8: RTPrintf(List::tr("byte")); break; + case DataType_String: RTPrintf(List::tr("string")); break; +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case DataType_32BitHack: break; /* Shut up compiler warnings. */ +#endif + } + RTPrintf(List::tr(" flags=%#04x"), propertyFlags[j]); + RTPrintf(List::tr(" default='%ls'"), Bstr(propertyDefaults[j]).raw()); + if (j != propertyNames.size()-1) + RTPrintf(", "); + } + } + RTPrintf(")\n"); + } + return hrc; +} + + +/** + * List USB devices attached to the host. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listUsbHost(const ComPtr &pVirtualBox) +{ + HRESULT hrc; + ComPtr Host; + CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(Host.asOutParam()), 1); + + SafeIfaceArray CollPtr; + CHECK_ERROR_RET(Host, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(CollPtr)), 1); + + RTPrintf(List::tr("Host USB Devices:\n\n")); + + if (CollPtr.size() == 0) + { + RTPrintf(List::tr("\n\n")); + } + else + { + for (size_t i = 0; i < CollPtr.size(); ++i) + { + ComPtr dev = CollPtr[i]; + + /* Query info. */ + Bstr id; + CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), 1); + USHORT usVendorId; + CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), 1); + USHORT usProductId; + CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), 1); + USHORT bcdRevision; + CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), 1); + USHORT usPort; + CHECK_ERROR_RET(dev, COMGETTER(Port)(&usPort), 1); + USHORT usVersion; + CHECK_ERROR_RET(dev, COMGETTER(Version)(&usVersion), 1); + USBConnectionSpeed_T enmSpeed; + CHECK_ERROR_RET(dev, COMGETTER(Speed)(&enmSpeed), 1); + + RTPrintf(List::tr( + "UUID: %s\n" + "VendorId: %#06x (%04X)\n" + "ProductId: %#06x (%04X)\n" + "Revision: %u.%u (%02u%02u)\n" + "Port: %u\n"), + Utf8Str(id).c_str(), + usVendorId, usVendorId, usProductId, usProductId, + bcdRevision >> 8, bcdRevision & 0xff, + bcdRevision >> 8, bcdRevision & 0xff, + usPort); + + const char *pszSpeed = "?"; + switch (enmSpeed) + { + case USBConnectionSpeed_Low: + pszSpeed = List::tr("Low"); + break; + case USBConnectionSpeed_Full: + pszSpeed = List::tr("Full"); + break; + case USBConnectionSpeed_High: + pszSpeed = List::tr("High"); + break; + case USBConnectionSpeed_Super: + pszSpeed = List::tr("Super"); + break; + case USBConnectionSpeed_SuperPlus: + pszSpeed = List::tr("SuperPlus"); + break; + default: + ASSERT(false); + break; + } + + RTPrintf(List::tr("USB version/speed: %u/%s\n"), usVersion, pszSpeed); + + /* optional stuff. */ + SafeArray CollDevInfo; + Bstr bstr; + CHECK_ERROR_RET(dev, COMGETTER(DeviceInfo)(ComSafeArrayAsOutParam(CollDevInfo)), 1); + if (CollDevInfo.size() >= 1) + bstr = Bstr(CollDevInfo[0]); + if (!bstr.isEmpty()) + RTPrintf(List::tr("Manufacturer: %ls\n"), bstr.raw()); + if (CollDevInfo.size() >= 2) + bstr = Bstr(CollDevInfo[1]); + if (!bstr.isEmpty()) + RTPrintf(List::tr("Product: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), 1); + if (!bstr.isEmpty()) + RTPrintf(List::tr("SerialNumber: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), 1); + if (!bstr.isEmpty()) + RTPrintf(List::tr("Address: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(dev, COMGETTER(PortPath)(bstr.asOutParam()), 1); + if (!bstr.isEmpty()) + RTPrintf(List::tr("Port path: %ls\n"), bstr.raw()); + + /* current state */ + USBDeviceState_T state; + CHECK_ERROR_RET(dev, COMGETTER(State)(&state), 1); + const char *pszState = "?"; + switch (state) + { + case USBDeviceState_NotSupported: + pszState = List::tr("Not supported"); + break; + case USBDeviceState_Unavailable: + pszState = List::tr("Unavailable"); + break; + case USBDeviceState_Busy: + pszState = List::tr("Busy"); + break; + case USBDeviceState_Available: + pszState = List::tr("Available"); + break; + case USBDeviceState_Held: + pszState = List::tr("Held"); + break; + case USBDeviceState_Captured: + pszState = List::tr("Captured"); + break; + default: + ASSERT(false); + break; + } + RTPrintf(List::tr("Current State: %s\n\n"), pszState); + } + } + return hrc; +} + + +/** + * List USB filters. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listUsbFilters(const ComPtr &pVirtualBox) +{ + HRESULT hrc; + + RTPrintf(List::tr("Global USB Device Filters:\n\n")); + + ComPtr host; + CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(host.asOutParam()), 1); + + SafeIfaceArray coll; + CHECK_ERROR_RET(host, COMGETTER(USBDeviceFilters)(ComSafeArrayAsOutParam(coll)), 1); + + if (coll.size() == 0) + { + RTPrintf(List::tr("\n\n")); + } + else + { + for (size_t index = 0; index < coll.size(); ++index) + { + ComPtr flt = coll[index]; + + /* Query info. */ + + RTPrintf(List::tr("Index: %zu\n"), index); + + BOOL active = FALSE; + CHECK_ERROR_RET(flt, COMGETTER(Active)(&active), 1); + RTPrintf(List::tr("Active: %s\n"), active ? List::tr("yes") : List::tr("no")); + + USBDeviceFilterAction_T action; + CHECK_ERROR_RET(flt, COMGETTER(Action)(&action), 1); + const char *pszAction = List::tr(""); + switch (action) + { + case USBDeviceFilterAction_Ignore: + pszAction = List::tr("Ignore"); + break; + case USBDeviceFilterAction_Hold: + pszAction = List::tr("Hold"); + break; + default: + break; + } + RTPrintf(List::tr("Action: %s\n"), pszAction); + + Bstr bstr; + CHECK_ERROR_RET(flt, COMGETTER(Name)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Name: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(VendorId)(bstr.asOutParam()), 1); + RTPrintf(List::tr("VendorId: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(ProductId)(bstr.asOutParam()), 1); + RTPrintf(List::tr("ProductId: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(Revision)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Revision: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(Manufacturer)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Manufacturer: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(Product)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Product: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(SerialNumber)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Serial Number: %ls\n"), bstr.raw()); + CHECK_ERROR_RET(flt, COMGETTER(Port)(bstr.asOutParam()), 1); + RTPrintf(List::tr("Port: %ls\n\n"), bstr.raw()); + } + } + return hrc; +} + + +/** + * List system properties. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listSystemProperties(const ComPtr &pVirtualBox) +{ + ComPtr systemProperties; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck); + + Bstr str; + ULONG ulValue; + LONG64 i64Value; + BOOL fValue; + const char *psz; + + pVirtualBox->COMGETTER(APIVersion)(str.asOutParam()); + RTPrintf(List::tr("API version: %ls\n"), str.raw()); + + systemProperties->COMGETTER(MinGuestRAM)(&ulValue); + RTPrintf(List::tr("Minimum guest RAM size: %u Megabytes\n", "", ulValue), ulValue); + systemProperties->COMGETTER(MaxGuestRAM)(&ulValue); + RTPrintf(List::tr("Maximum guest RAM size: %u Megabytes\n", "", ulValue), ulValue); + systemProperties->COMGETTER(MinGuestVRAM)(&ulValue); + RTPrintf(List::tr("Minimum video RAM size: %u Megabytes\n", "", ulValue), ulValue); + systemProperties->COMGETTER(MaxGuestVRAM)(&ulValue); + RTPrintf(List::tr("Maximum video RAM size: %u Megabytes\n", "", ulValue), ulValue); + systemProperties->COMGETTER(MaxGuestMonitors)(&ulValue); + RTPrintf(List::tr("Maximum guest monitor count: %u\n"), ulValue); + systemProperties->COMGETTER(MinGuestCPUCount)(&ulValue); + RTPrintf(List::tr("Minimum guest CPU count: %u\n"), ulValue); + systemProperties->COMGETTER(MaxGuestCPUCount)(&ulValue); + RTPrintf(List::tr("Maximum guest CPU count: %u\n"), ulValue); + systemProperties->COMGETTER(InfoVDSize)(&i64Value); + RTPrintf(List::tr("Virtual disk limit (info): %lld Bytes\n", "" , i64Value), i64Value); + systemProperties->COMGETTER(SerialPortCount)(&ulValue); + RTPrintf(List::tr("Maximum Serial Port count: %u\n"), ulValue); + systemProperties->COMGETTER(ParallelPortCount)(&ulValue); + RTPrintf(List::tr("Maximum Parallel Port count: %u\n"), ulValue); + systemProperties->COMGETTER(MaxBootPosition)(&ulValue); + RTPrintf(List::tr("Maximum Boot Position: %u\n"), ulValue); + systemProperties->GetMaxNetworkAdapters(ChipsetType_PIIX3, &ulValue); + RTPrintf(List::tr("Maximum PIIX3 Network Adapter count: %u\n"), ulValue); + systemProperties->GetMaxNetworkAdapters(ChipsetType_ICH9, &ulValue); + RTPrintf(List::tr("Maximum ICH9 Network Adapter count: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_IDE, &ulValue); + RTPrintf(List::tr("Maximum PIIX3 IDE Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_IDE, &ulValue); + RTPrintf(List::tr("Maximum ICH9 IDE Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_IDE, &ulValue); + RTPrintf(List::tr("Maximum IDE Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_IDE, &ulValue); + RTPrintf(List::tr("Maximum Devices per IDE Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_SATA, &ulValue); + RTPrintf(List::tr("Maximum PIIX3 SATA Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_SATA, &ulValue); + RTPrintf(List::tr("Maximum ICH9 SATA Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_SATA, &ulValue); + RTPrintf(List::tr("Maximum SATA Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_SATA, &ulValue); + RTPrintf(List::tr("Maximum Devices per SATA Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_SCSI, &ulValue); + RTPrintf(List::tr("Maximum PIIX3 SCSI Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_SCSI, &ulValue); + RTPrintf(List::tr("Maximum ICH9 SCSI Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_SCSI, &ulValue); + RTPrintf(List::tr("Maximum SCSI Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_SCSI, &ulValue); + RTPrintf(List::tr("Maximum Devices per SCSI Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_SAS, &ulValue); + RTPrintf(List::tr("Maximum SAS PIIX3 Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_SAS, &ulValue); + RTPrintf(List::tr("Maximum SAS ICH9 Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_SAS, &ulValue); + RTPrintf(List::tr("Maximum SAS Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_SAS, &ulValue); + RTPrintf(List::tr("Maximum Devices per SAS Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_PCIe, &ulValue); + RTPrintf(List::tr("Maximum NVMe PIIX3 Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_PCIe, &ulValue); + RTPrintf(List::tr("Maximum NVMe ICH9 Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_PCIe, &ulValue); + RTPrintf(List::tr("Maximum NVMe Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_PCIe, &ulValue); + RTPrintf(List::tr("Maximum Devices per NVMe Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_VirtioSCSI, &ulValue); + RTPrintf(List::tr("Maximum virtio-scsi PIIX3 Controllers: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_VirtioSCSI, &ulValue); + RTPrintf(List::tr("Maximum virtio-scsi ICH9 Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_VirtioSCSI, &ulValue); + RTPrintf(List::tr("Maximum virtio-scsi Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_VirtioSCSI, &ulValue); + RTPrintf(List::tr("Maximum Devices per virtio-scsi Port: %u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_PIIX3, StorageBus_Floppy, &ulValue); + RTPrintf(List::tr("Maximum PIIX3 Floppy Controllers:%u\n"), ulValue); + systemProperties->GetMaxInstancesOfStorageBus(ChipsetType_ICH9, StorageBus_Floppy, &ulValue); + RTPrintf(List::tr("Maximum ICH9 Floppy Controllers: %u\n"), ulValue); + systemProperties->GetMaxPortCountForStorageBus(StorageBus_Floppy, &ulValue); + RTPrintf(List::tr("Maximum Floppy Port count: %u\n"), ulValue); + systemProperties->GetMaxDevicesPerPortForStorageBus(StorageBus_Floppy, &ulValue); + RTPrintf(List::tr("Maximum Devices per Floppy Port: %u\n"), ulValue); +#if 0 + systemProperties->GetFreeDiskSpaceWarning(&i64Value); + RTPrintf(List::tr("Free disk space warning at: %u Bytes\n", "", i64Value), i64Value); + systemProperties->GetFreeDiskSpacePercentWarning(&ulValue); + RTPrintf(List::tr("Free disk space warning at: %u %%\n"), ulValue); + systemProperties->GetFreeDiskSpaceError(&i64Value); + RTPrintf(List::tr("Free disk space error at: %u Bytes\n", "", i64Value), i64Value); + systemProperties->GetFreeDiskSpacePercentError(&ulValue); + RTPrintf(List::tr("Free disk space error at: %u %%\n"), ulValue); +#endif + systemProperties->COMGETTER(DefaultMachineFolder)(str.asOutParam()); + RTPrintf(List::tr("Default machine folder: %ls\n"), str.raw()); + systemProperties->COMGETTER(RawModeSupported)(&fValue); + RTPrintf(List::tr("Raw-mode Supported: %s\n"), fValue ? List::tr("yes") : List::tr("no")); + systemProperties->COMGETTER(ExclusiveHwVirt)(&fValue); + RTPrintf(List::tr("Exclusive HW virtualization use: %s\n"), fValue ? List::tr("on") : List::tr("off")); + systemProperties->COMGETTER(DefaultHardDiskFormat)(str.asOutParam()); + RTPrintf(List::tr("Default hard disk format: %ls\n"), str.raw()); + systemProperties->COMGETTER(VRDEAuthLibrary)(str.asOutParam()); + RTPrintf(List::tr("VRDE auth library: %ls\n"), str.raw()); + systemProperties->COMGETTER(WebServiceAuthLibrary)(str.asOutParam()); + RTPrintf(List::tr("Webservice auth. library: %ls\n"), str.raw()); + systemProperties->COMGETTER(DefaultVRDEExtPack)(str.asOutParam()); + RTPrintf(List::tr("Remote desktop ExtPack: %ls\n"), str.raw()); + systemProperties->COMGETTER(DefaultCryptoExtPack)(str.asOutParam()); + RTPrintf(List::tr("VM encryption ExtPack: %ls\n"), str.raw()); + systemProperties->COMGETTER(LogHistoryCount)(&ulValue); + RTPrintf(List::tr("Log history count: %u\n"), ulValue); + systemProperties->COMGETTER(DefaultFrontend)(str.asOutParam()); + RTPrintf(List::tr("Default frontend: %ls\n"), str.raw()); + AudioDriverType_T enmAudio; + systemProperties->COMGETTER(DefaultAudioDriver)(&enmAudio); + switch (enmAudio) + { + case AudioDriverType_Default: psz = List::tr("Default"); break; + case AudioDriverType_Null: psz = List::tr("Null"); break; + case AudioDriverType_OSS: psz = "OSS"; break; + case AudioDriverType_ALSA: psz = "ALSA"; break; + case AudioDriverType_Pulse: psz = "PulseAudio"; break; + case AudioDriverType_WinMM: psz = "WinMM"; break; + case AudioDriverType_DirectSound: psz = "DirectSound"; break; + case AudioDriverType_WAS: psz = "Windows Audio Session"; break; + case AudioDriverType_CoreAudio: psz = "CoreAudio"; break; + case AudioDriverType_SolAudio: psz = "SolAudio"; break; + case AudioDriverType_MMPM: psz = "MMPM"; break; + default: psz = List::tr("Unknown"); + } + RTPrintf(List::tr("Default audio driver: %s\n"), psz); + systemProperties->COMGETTER(AutostartDatabasePath)(str.asOutParam()); + RTPrintf(List::tr("Autostart database path: %ls\n"), str.raw()); + systemProperties->COMGETTER(DefaultAdditionsISO)(str.asOutParam()); + RTPrintf(List::tr("Default Guest Additions ISO: %ls\n"), str.raw()); + systemProperties->COMGETTER(LoggingLevel)(str.asOutParam()); + RTPrintf(List::tr("Logging Level: %ls\n"), str.raw()); + ProxyMode_T enmProxyMode = (ProxyMode_T)42; + systemProperties->COMGETTER(ProxyMode)(&enmProxyMode); + psz = List::tr("Unknown"); + switch (enmProxyMode) + { + case ProxyMode_System: psz = List::tr("System"); break; + case ProxyMode_NoProxy: psz = List::tr("NoProxy"); break; + case ProxyMode_Manual: psz = List::tr("Manual"); break; +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case ProxyMode_32BitHack: break; /* Shut up compiler warnings. */ +#endif + } + RTPrintf(List::tr("Proxy Mode: %s\n"), psz); + systemProperties->COMGETTER(ProxyURL)(str.asOutParam()); + RTPrintf(List::tr("Proxy URL: %ls\n"), str.raw()); +#ifdef VBOX_WITH_MAIN_NLS + systemProperties->COMGETTER(LanguageId)(str.asOutParam()); + RTPrintf(List::tr("User language: %ls\n"), str.raw()); +#endif + return S_OK; +} + +#ifdef VBOX_WITH_UPDATE_AGENT +static HRESULT listUpdateAgentConfig(ComPtr ptrUpdateAgent) +{ + BOOL fValue; + ptrUpdateAgent->COMGETTER(Enabled)(&fValue); + RTPrintf(List::tr("Enabled: %s\n"), fValue ? List::tr("yes") : List::tr("no")); + ULONG ulValue; + ptrUpdateAgent->COMGETTER(CheckCount)(&ulValue); + RTPrintf(List::tr("Check count: %u\n"), ulValue); + ptrUpdateAgent->COMGETTER(CheckFrequency)(&ulValue); + if (ulValue == 0) + RTPrintf(List::tr("Check frequency: never\n")); + else if (ulValue == 1) + RTPrintf(List::tr("Check frequency: every day\n")); + else + RTPrintf(List::tr("Check frequency: every %u days\n", "", ulValue), ulValue); + + Bstr str; + const char *psz; + UpdateChannel_T enmUpdateChannel; + ptrUpdateAgent->COMGETTER(Channel)(&enmUpdateChannel); + switch (enmUpdateChannel) + { + case UpdateChannel_Stable: + psz = List::tr("Stable: Maintenance and minor releases within the same major release"); + break; + case UpdateChannel_All: + psz = List::tr("All releases: All stable releases, including major versions"); + break; + case UpdateChannel_WithBetas: + psz = List::tr("With Betas: All stable and major releases, including beta versions"); + break; + case UpdateChannel_WithTesting: + psz = List::tr("With Testing: All stable, major and beta releases, including testing versions"); + break; + default: + psz = List::tr("Unset"); + break; + } + RTPrintf(List::tr("Channel: %s\n"), psz); + ptrUpdateAgent->COMGETTER(RepositoryURL)(str.asOutParam()); + RTPrintf(List::tr("Repository: %ls\n"), str.raw()); + ptrUpdateAgent->COMGETTER(LastCheckDate)(str.asOutParam()); + RTPrintf(List::tr("Last check date: %ls\n"), str.raw()); + + return S_OK; +} + +static HRESULT listUpdateAgents(const ComPtr &pVirtualBox) +{ + ComPtr pHost; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(Host)(pHost.asOutParam()), RTEXITCODE_FAILURE); + + ComPtr pUpdateHost; + CHECK_ERROR2I_RET(pHost, COMGETTER(UpdateHost)(pUpdateHost.asOutParam()), RTEXITCODE_FAILURE); + /** @todo Add other update agents here. */ + + return listUpdateAgentConfig(pUpdateHost); +} +#endif /* VBOX_WITH_UPDATE_AGENT */ + +/** + * Helper for listDhcpServers() that shows a DHCP configuration. + */ +static HRESULT showDhcpConfig(ComPtr ptrConfig) +{ + HRESULT hrcRet = S_OK; + + ULONG secs = 0; + CHECK_ERROR2I_STMT(ptrConfig, COMGETTER(MinLeaseTime)(&secs), hrcRet = hrcCheck); + if (secs == 0) + RTPrintf(List::tr(" minLeaseTime: default\n")); + else + RTPrintf(List::tr(" minLeaseTime: %u sec\n"), secs); + + secs = 0; + CHECK_ERROR2I_STMT(ptrConfig, COMGETTER(DefaultLeaseTime)(&secs), hrcRet = hrcCheck); + if (secs == 0) + RTPrintf(List::tr(" defaultLeaseTime: default\n")); + else + RTPrintf(List::tr(" defaultLeaseTime: %u sec\n"), secs); + + secs = 0; + CHECK_ERROR2I_STMT(ptrConfig, COMGETTER(MaxLeaseTime)(&secs), hrcRet = hrcCheck); + if (secs == 0) + RTPrintf(List::tr(" maxLeaseTime: default\n")); + else + RTPrintf(List::tr(" maxLeaseTime: %u sec\n"), secs); + + com::SafeArray Options; + HRESULT hrc; + CHECK_ERROR2_STMT(hrc, ptrConfig, COMGETTER(ForcedOptions(ComSafeArrayAsOutParam(Options))), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr(" Forced options: %Rhrc\n"), hrc); + else if (Options.size() == 0) + RTPrintf(List::tr(" Forced options: None\n")); + else + { + RTPrintf(List::tr(" Forced options: ")); + for (size_t i = 0; i < Options.size(); i++) + RTPrintf(i ? ", %u" : "%u", Options[i]); + RTPrintf("\n"); + } + + CHECK_ERROR2_STMT(hrc, ptrConfig, COMGETTER(SuppressedOptions(ComSafeArrayAsOutParam(Options))), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr(" Suppressed opt.s: %Rhrc\n"), hrc); + else if (Options.size() == 0) + RTPrintf(List::tr(" Suppressed opts.: None\n")); + else + { + RTPrintf(List::tr(" Suppressed opts.: ")); + for (size_t i = 0; i < Options.size(); i++) + RTPrintf(i ? ", %u" : "%u", Options[i]); + RTPrintf("\n"); + } + + com::SafeArray Encodings; + com::SafeArray Values; + CHECK_ERROR2_STMT(hrc, ptrConfig, GetAllOptions(ComSafeArrayAsOutParam(Options), + ComSafeArrayAsOutParam(Encodings), + ComSafeArrayAsOutParam(Values)), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr(" DHCP options: %Rhrc\n"), hrc); + else if (Options.size() != Encodings.size() || Options.size() != Values.size()) + { + RTPrintf(List::tr(" DHCP options: Return count mismatch: %zu, %zu, %zu\n"), + Options.size(), Encodings.size(), Values.size()); + hrcRet = E_FAIL; + } + else if (Options.size() == 0) + RTPrintf(List::tr(" DHCP options: None\n")); + else + for (size_t i = 0; i < Options.size(); i++) + { + switch (Encodings[i]) + { + case DHCPOptionEncoding_Normal: + RTPrintf(List::tr(" %3d/legacy: %ls\n"), Options[i], Values[i]); + break; + case DHCPOptionEncoding_Hex: + RTPrintf(" %3d/hex: %ls\n", Options[i], Values[i]); + break; + default: + RTPrintf(" %3d/%u?: %ls\n", Options[i], Encodings[i], Values[i]); + break; + } + } + + return S_OK; +} + + +/** + * List DHCP servers. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listDhcpServers(const ComPtr &pVirtualBox) +{ + HRESULT hrcRet = S_OK; + com::SafeIfaceArray DHCPServers; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(DHCPServers)(ComSafeArrayAsOutParam(DHCPServers)), hrcCheck); + for (size_t i = 0; i < DHCPServers.size(); ++i) + { + if (i > 0) + RTPrintf("\n"); + + ComPtr ptrDHCPServer = DHCPServers[i]; + Bstr bstr; + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(NetworkName)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("NetworkName: %ls\n"), bstr.raw()); + + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(IPAddress)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf("Dhcpd IP: %ls\n", bstr.raw()); + + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(LowerIP)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("LowerIPAddress: %ls\n"), bstr.raw()); + + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(UpperIP)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("UpperIPAddress: %ls\n"), bstr.raw()); + + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(NetworkMask)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("NetworkMask: %ls\n"), bstr.raw()); + + BOOL fEnabled = FALSE; + CHECK_ERROR2I_STMT(ptrDHCPServer, COMGETTER(Enabled)(&fEnabled), hrcRet = hrcCheck); + RTPrintf(List::tr("Enabled: %s\n"), fEnabled ? List::tr("Yes") : List::tr("No")); + + /* Global configuration: */ + RTPrintf(List::tr("Global Configuration:\n")); + HRESULT hrc; + ComPtr ptrGlobal; + CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(GlobalConfig)(ptrGlobal.asOutParam()), hrcRet = hrc); + if (SUCCEEDED(hrc)) + { + hrc = showDhcpConfig(ptrGlobal); + if (FAILED(hrc)) + hrcRet = hrc; + } + + /* Group configurations: */ + com::SafeIfaceArray Groups; + CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(GroupConfigs)(ComSafeArrayAsOutParam(Groups)), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr("Groups: %Rrc\n"), hrc); + else if (Groups.size() == 0) + RTPrintf(List::tr("Groups: None\n")); + else + { + for (size_t iGrp = 0; iGrp < Groups.size(); iGrp++) + { + CHECK_ERROR2I_STMT(Groups[iGrp], COMGETTER(Name)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("Group: %ls\n"), bstr.raw()); + + com::SafeIfaceArray Conditions; + CHECK_ERROR2_STMT(hrc, Groups[iGrp], COMGETTER(Conditions)(ComSafeArrayAsOutParam(Conditions)), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr(" Conditions: %Rhrc\n"), hrc); + else if (Conditions.size() == 0) + RTPrintf(List::tr(" Conditions: None\n")); + else + for (size_t iCond = 0; iCond < Conditions.size(); iCond++) + { + BOOL fInclusive = TRUE; + CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Inclusive)(&fInclusive), hrcRet = hrc); + DHCPGroupConditionType_T enmType = DHCPGroupConditionType_MAC; + CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Type)(&enmType), hrcRet = hrc); + CHECK_ERROR2_STMT(hrc, Conditions[iCond], COMGETTER(Value)(bstr.asOutParam()), hrcRet = hrc); + + RTPrintf(List::tr(" Conditions: %s %s %ls\n"), + fInclusive ? List::tr("include") : List::tr("exclude"), + enmType == DHCPGroupConditionType_MAC ? "MAC " + : enmType == DHCPGroupConditionType_MACWildcard ? "MAC* " + : enmType == DHCPGroupConditionType_vendorClassID ? "VendorCID " + : enmType == DHCPGroupConditionType_vendorClassIDWildcard ? "VendorCID*" + : enmType == DHCPGroupConditionType_userClassID ? "UserCID " + : enmType == DHCPGroupConditionType_userClassIDWildcard ? "UserCID* " + : "!UNKNOWN! ", + bstr.raw()); + } + + hrc = showDhcpConfig(Groups[iGrp]); + if (FAILED(hrc)) + hrcRet = hrc; + } + Groups.setNull(); + } + + /* Individual host / NIC configurations: */ + com::SafeIfaceArray Hosts; + CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMGETTER(IndividualConfigs)(ComSafeArrayAsOutParam(Hosts)), hrcRet = hrc); + if (FAILED(hrc)) + RTPrintf(List::tr("Individual Configs: %Rrc\n"), hrc); + else if (Hosts.size() == 0) + RTPrintf(List::tr("Individual Configs: None\n")); + else + { + for (size_t iHost = 0; iHost < Hosts.size(); iHost++) + { + DHCPConfigScope_T enmScope = DHCPConfigScope_MAC; + CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(Scope)(&enmScope), hrcRet = hrcCheck); + + if (enmScope == DHCPConfigScope_MAC) + { + CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(MACAddress)(bstr.asOutParam()), hrcRet = hrcCheck); + RTPrintf(List::tr("Individual Config: MAC %ls\n"), bstr.raw()); + } + else + { + ULONG uSlot = 0; + CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(Slot)(&uSlot), hrcRet = hrcCheck); + CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(MachineId)(bstr.asOutParam()), hrcRet = hrcCheck); + Bstr bstrMACAddress; + hrc = Hosts[iHost]->COMGETTER(MACAddress)(bstrMACAddress.asOutParam()); /* No CHECK_ERROR2 stuff! */ + if (SUCCEEDED(hrc)) + RTPrintf(List::tr("Individual Config: VM NIC: %ls slot %u, MAC %ls\n"), bstr.raw(), uSlot, + bstrMACAddress.raw()); + else + RTPrintf(List::tr("Individual Config: VM NIC: %ls slot %u, MAC %Rhrc\n"), bstr.raw(), uSlot, hrc); + } + + CHECK_ERROR2I_STMT(Hosts[iHost], COMGETTER(FixedAddress)(bstr.asOutParam()), hrcRet = hrcCheck); + if (bstr.isNotEmpty()) + RTPrintf(List::tr(" Fixed Address: %ls\n"), bstr.raw()); + else + RTPrintf(List::tr(" Fixed Address: dynamic\n")); + + hrc = showDhcpConfig(Hosts[iHost]); + if (FAILED(hrc)) + hrcRet = hrc; + } + Hosts.setNull(); + } + } + + return hrcRet; +} + +/** + * List extension packs. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listExtensionPacks(const ComPtr &pVirtualBox) +{ + ComObjPtr ptrExtPackMgr; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), hrcCheck); + + SafeIfaceArray extPacks; + CHECK_ERROR2I_RET(ptrExtPackMgr, COMGETTER(InstalledExtPacks)(ComSafeArrayAsOutParam(extPacks)), hrcCheck); + RTPrintf(List::tr("Extension Packs: %u\n"), extPacks.size()); + + HRESULT hrc = S_OK; + for (size_t i = 0; i < extPacks.size(); i++) + { + /* Read all the properties. */ + Bstr bstrName; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Name)(bstrName.asOutParam()), hrc = hrcCheck; bstrName.setNull()); + Bstr bstrDesc; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Description)(bstrDesc.asOutParam()), hrc = hrcCheck; bstrDesc.setNull()); + Bstr bstrVersion; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Version)(bstrVersion.asOutParam()), hrc = hrcCheck; bstrVersion.setNull()); + ULONG uRevision; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Revision)(&uRevision), hrc = hrcCheck; uRevision = 0); + Bstr bstrEdition; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Edition)(bstrEdition.asOutParam()), hrc = hrcCheck; bstrEdition.setNull()); + Bstr bstrVrdeModule; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(VRDEModule)(bstrVrdeModule.asOutParam()),hrc=hrcCheck; bstrVrdeModule.setNull()); + Bstr bstrCryptoModule; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(CryptoModule)(bstrCryptoModule.asOutParam()),hrc=hrcCheck; bstrCryptoModule.setNull()); + BOOL fUsable; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(Usable)(&fUsable), hrc = hrcCheck; fUsable = FALSE); + Bstr bstrWhy; + CHECK_ERROR2I_STMT(extPacks[i], COMGETTER(WhyUnusable)(bstrWhy.asOutParam()), hrc = hrcCheck; bstrWhy.setNull()); + + /* Display them. */ + if (i) + RTPrintf("\n"); + RTPrintf(List::tr( + "Pack no.%2zu: %ls\n" + "Version: %ls\n" + "Revision: %u\n" + "Edition: %ls\n" + "Description: %ls\n" + "VRDE Module: %ls\n" + "Crypto Module: %ls\n" + "Usable: %RTbool\n" + "Why unusable: %ls\n"), + i, bstrName.raw(), + bstrVersion.raw(), + uRevision, + bstrEdition.raw(), + bstrDesc.raw(), + bstrVrdeModule.raw(), + bstrCryptoModule.raw(), + fUsable != FALSE, + bstrWhy.raw()); + + /* Query plugins and display them. */ + } + return hrc; +} + + +/** + * List machine groups. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT listGroups(const ComPtr &pVirtualBox) +{ + SafeArray groups; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(MachineGroups)(ComSafeArrayAsOutParam(groups)), hrcCheck); + + for (size_t i = 0; i < groups.size(); i++) + { + RTPrintf("\"%ls\"\n", groups[i]); + } + return S_OK; +} + + +/** + * List video capture devices. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox pointer. + */ +static HRESULT listVideoInputDevices(const ComPtr &pVirtualBox) +{ + HRESULT hrc; + ComPtr host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); + com::SafeIfaceArray hostVideoInputDevices; + CHECK_ERROR(host, COMGETTER(VideoInputDevices)(ComSafeArrayAsOutParam(hostVideoInputDevices))); + RTPrintf(List::tr("Video Input Devices: %u\n"), hostVideoInputDevices.size()); + for (size_t i = 0; i < hostVideoInputDevices.size(); ++i) + { + ComPtr p = hostVideoInputDevices[i]; + Bstr name; + p->COMGETTER(Name)(name.asOutParam()); + Bstr path; + p->COMGETTER(Path)(path.asOutParam()); + Bstr alias; + p->COMGETTER(Alias)(alias.asOutParam()); + RTPrintf("%ls \"%ls\"\n%ls\n", alias.raw(), name.raw(), path.raw()); + } + return hrc; +} + +/** + * List supported screen shot formats. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox pointer. + */ +static HRESULT listScreenShotFormats(const ComPtr &pVirtualBox) +{ + HRESULT hrc = S_OK; + ComPtr systemProperties; + CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam())); + com::SafeArray formats; + CHECK_ERROR(systemProperties, COMGETTER(ScreenShotFormats)(ComSafeArrayAsOutParam(formats))); + + RTPrintf(List::tr("Supported %d screen shot formats:\n", "", formats.size()), formats.size()); + for (size_t i = 0; i < formats.size(); ++i) + { + uint32_t u32Format = (uint32_t)formats[i]; + char szFormat[5]; + szFormat[0] = RT_BYTE1(u32Format); + szFormat[1] = RT_BYTE2(u32Format); + szFormat[2] = RT_BYTE3(u32Format); + szFormat[3] = RT_BYTE4(u32Format); + szFormat[4] = 0; + RTPrintf(" BitmapFormat_%s (0x%08X)\n", szFormat, u32Format); + } + return hrc; +} + +/** + * List available cloud providers. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox pointer. + */ +static HRESULT listCloudProviders(const ComPtr &pVirtualBox) +{ + HRESULT hrc = S_OK; + ComPtr pCloudProviderManager; + CHECK_ERROR(pVirtualBox, COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam())); + com::SafeIfaceArray apCloudProviders; + CHECK_ERROR(pCloudProviderManager, COMGETTER(Providers)(ComSafeArrayAsOutParam(apCloudProviders))); + + RTPrintf(List::tr("Supported %d cloud providers:\n", "", apCloudProviders.size()), apCloudProviders.size()); + for (size_t i = 0; i < apCloudProviders.size(); ++i) + { + ComPtr pCloudProvider = apCloudProviders[i]; + Bstr bstrProviderName; + pCloudProvider->COMGETTER(Name)(bstrProviderName.asOutParam()); + RTPrintf(List::tr("Name: %ls\n"), bstrProviderName.raw()); + pCloudProvider->COMGETTER(ShortName)(bstrProviderName.asOutParam()); + RTPrintf(List::tr("Short Name: %ls\n"), bstrProviderName.raw()); + Bstr bstrProviderID; + pCloudProvider->COMGETTER(Id)(bstrProviderID.asOutParam()); + RTPrintf("GUID: %ls\n", bstrProviderID.raw()); + + RTPrintf("\n"); + } + return hrc; +} + + +/** + * List all available cloud profiles (by iterating over the cloud providers). + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox pointer. + * @param fOptLong If true, list all profile properties. + */ +static HRESULT listCloudProfiles(const ComPtr &pVirtualBox, bool fOptLong) +{ + HRESULT hrc = S_OK; + ComPtr pCloudProviderManager; + CHECK_ERROR(pVirtualBox, COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam())); + com::SafeIfaceArray apCloudProviders; + CHECK_ERROR(pCloudProviderManager, COMGETTER(Providers)(ComSafeArrayAsOutParam(apCloudProviders))); + + for (size_t i = 0; i < apCloudProviders.size(); ++i) + { + ComPtr pCloudProvider = apCloudProviders[i]; + com::SafeIfaceArray apCloudProfiles; + CHECK_ERROR(pCloudProvider, COMGETTER(Profiles)(ComSafeArrayAsOutParam(apCloudProfiles))); + for (size_t j = 0; j < apCloudProfiles.size(); ++j) + { + ComPtr pCloudProfile = apCloudProfiles[j]; + Bstr bstrProfileName; + pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam()); + RTPrintf(List::tr("Name: %ls\n"), bstrProfileName.raw()); + Bstr bstrProviderID; + pCloudProfile->COMGETTER(ProviderId)(bstrProviderID.asOutParam()); + RTPrintf(List::tr("Provider GUID: %ls\n"), bstrProviderID.raw()); + + if (fOptLong) + { + com::SafeArray names; + com::SafeArray values; + pCloudProfile->GetProperties(Bstr().raw(), ComSafeArrayAsOutParam(names), ComSafeArrayAsOutParam(values)); + size_t cNames = names.size(); + size_t cValues = values.size(); + bool fFirst = true; + for (size_t k = 0; k < cNames; k++) + { + Bstr value; + if (k < cValues) + value = values[k]; + RTPrintf("%s%ls=%ls\n", + fFirst ? List::tr("Property: ") : " ", + names[k], value.raw()); + fFirst = false; + } + } + + RTPrintf("\n"); + } + } + return hrc; +} + +static HRESULT displayCPUProfile(ICPUProfile *pProfile, size_t idx, int cchIdx, bool fOptLong, HRESULT hrc) +{ + /* Retrieve the attributes needed for both long and short display. */ + Bstr bstrName; + CHECK_ERROR2I_RET(pProfile, COMGETTER(Name)(bstrName.asOutParam()), hrcCheck); + + CPUArchitecture_T enmArchitecture = CPUArchitecture_Any; + CHECK_ERROR2I_RET(pProfile, COMGETTER(Architecture)(&enmArchitecture), hrcCheck); + const char *pszArchitecture = "???"; + switch (enmArchitecture) + { + case CPUArchitecture_x86: pszArchitecture = "x86"; break; + case CPUArchitecture_AMD64: pszArchitecture = "AMD64"; break; + +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case CPUArchitecture_32BitHack: +#endif + case CPUArchitecture_Any: + break; + } + + /* Print what we've got. */ + if (!fOptLong) + RTPrintf("#%0*zu: %ls [%s]\n", cchIdx, idx, bstrName.raw(), pszArchitecture); + else + { + RTPrintf(List::tr("CPU Profile #%02zu:\n"), idx); + RTPrintf(List::tr(" Architecture: %s\n"), pszArchitecture); + RTPrintf(List::tr(" Name: %ls\n"), bstrName.raw()); + CHECK_ERROR2I_RET(pProfile, COMGETTER(FullName)(bstrName.asOutParam()), hrcCheck); + RTPrintf(List::tr(" Full Name: %ls\n"), bstrName.raw()); + } + return hrc; +} + + +/** + * List all CPU profiles. + * + * @returns See produceList. + * @param ptrVirtualBox Reference to the smart IVirtualBox pointer. + * @param fOptLong If true, list all profile properties. + * @param fOptSorted Sort the output if true, otherwise display in + * system order. + */ +static HRESULT listCPUProfiles(const ComPtr &ptrVirtualBox, bool fOptLong, bool fOptSorted) +{ + ComPtr ptrSysProps; + CHECK_ERROR2I_RET(ptrVirtualBox, COMGETTER(SystemProperties)(ptrSysProps.asOutParam()), hrcCheck); + com::SafeIfaceArray aCPUProfiles; + CHECK_ERROR2I_RET(ptrSysProps, GetCPUProfiles(CPUArchitecture_Any, Bstr().raw(), + ComSafeArrayAsOutParam(aCPUProfiles)), hrcCheck); + + int const cchIdx = 1 + (aCPUProfiles.size() >= 10) + (aCPUProfiles.size() >= 100); + + HRESULT hrc = S_OK; + if (!fOptSorted) + for (size_t i = 0; i < aCPUProfiles.size(); i++) + hrc = displayCPUProfile(aCPUProfiles[i], i, cchIdx, fOptLong, hrc); + else + { + std::vector > vecSortedProfiles; + for (size_t i = 0; i < aCPUProfiles.size(); ++i) + { + Bstr bstrName; + CHECK_ERROR2I_RET(aCPUProfiles[i], COMGETTER(Name)(bstrName.asOutParam()), hrcCheck); + try + { + vecSortedProfiles.push_back(std::pair(bstrName, aCPUProfiles[i])); + } + catch (std::bad_alloc &) + { + return E_OUTOFMEMORY; + } + } + + std::sort(vecSortedProfiles.begin(), vecSortedProfiles.end()); + + for (size_t i = 0; i < vecSortedProfiles.size(); i++) + hrc = displayCPUProfile(vecSortedProfiles[i].second, i, cchIdx, fOptLong, hrc); + } + + return hrc; +} + + +/** + * Translates PartitionType_T to a string if possible. + * @returns read-only string if known value, @a pszUnknown if not. + */ +static const char *PartitionTypeToString(PartitionType_T enmType, const char *pszUnknown) +{ +#define MY_CASE_STR(a_Type) case RT_CONCAT(PartitionType_,a_Type): return #a_Type + switch (enmType) + { + MY_CASE_STR(Empty); + MY_CASE_STR(FAT12); + MY_CASE_STR(FAT16); + MY_CASE_STR(FAT); + MY_CASE_STR(IFS); + MY_CASE_STR(FAT32CHS); + MY_CASE_STR(FAT32LBA); + MY_CASE_STR(FAT16B); + MY_CASE_STR(Extended); + MY_CASE_STR(WindowsRE); + MY_CASE_STR(LinuxSwapOld); + MY_CASE_STR(LinuxOld); + MY_CASE_STR(DragonFlyBSDSlice); + MY_CASE_STR(LinuxSwap); + MY_CASE_STR(Linux); + MY_CASE_STR(LinuxExtended); + MY_CASE_STR(LinuxLVM); + MY_CASE_STR(BSDSlice); + MY_CASE_STR(AppleUFS); + MY_CASE_STR(AppleHFS); + MY_CASE_STR(Solaris); + MY_CASE_STR(GPT); + MY_CASE_STR(EFI); + MY_CASE_STR(Unknown); + MY_CASE_STR(MBR); + MY_CASE_STR(iFFS); + MY_CASE_STR(SonyBoot); + MY_CASE_STR(LenovoBoot); + MY_CASE_STR(WindowsMSR); + MY_CASE_STR(WindowsBasicData); + MY_CASE_STR(WindowsLDMMeta); + MY_CASE_STR(WindowsLDMData); + MY_CASE_STR(WindowsRecovery); + MY_CASE_STR(WindowsStorageSpaces); + MY_CASE_STR(WindowsStorageReplica); + MY_CASE_STR(IBMGPFS); + MY_CASE_STR(LinuxData); + MY_CASE_STR(LinuxRAID); + MY_CASE_STR(LinuxRootX86); + MY_CASE_STR(LinuxRootAMD64); + MY_CASE_STR(LinuxRootARM32); + MY_CASE_STR(LinuxRootARM64); + MY_CASE_STR(LinuxHome); + MY_CASE_STR(LinuxSrv); + MY_CASE_STR(LinuxPlainDmCrypt); + MY_CASE_STR(LinuxLUKS); + MY_CASE_STR(LinuxReserved); + MY_CASE_STR(FreeBSDBoot); + MY_CASE_STR(FreeBSDData); + MY_CASE_STR(FreeBSDSwap); + MY_CASE_STR(FreeBSDUFS); + MY_CASE_STR(FreeBSDVinum); + MY_CASE_STR(FreeBSDZFS); + MY_CASE_STR(FreeBSDUnknown); + MY_CASE_STR(AppleHFSPlus); + MY_CASE_STR(AppleAPFS); + MY_CASE_STR(AppleRAID); + MY_CASE_STR(AppleRAIDOffline); + MY_CASE_STR(AppleBoot); + MY_CASE_STR(AppleLabel); + MY_CASE_STR(AppleTvRecovery); + MY_CASE_STR(AppleCoreStorage); + MY_CASE_STR(SoftRAIDStatus); + MY_CASE_STR(SoftRAIDScratch); + MY_CASE_STR(SoftRAIDVolume); + MY_CASE_STR(SoftRAIDCache); + MY_CASE_STR(AppleUnknown); + MY_CASE_STR(SolarisBoot); + MY_CASE_STR(SolarisRoot); + MY_CASE_STR(SolarisSwap); + MY_CASE_STR(SolarisBackup); + MY_CASE_STR(SolarisUsr); + MY_CASE_STR(SolarisVar); + MY_CASE_STR(SolarisHome); + MY_CASE_STR(SolarisAltSector); + MY_CASE_STR(SolarisReserved); + MY_CASE_STR(SolarisUnknown); + MY_CASE_STR(NetBSDSwap); + MY_CASE_STR(NetBSDFFS); + MY_CASE_STR(NetBSDLFS); + MY_CASE_STR(NetBSDRAID); + MY_CASE_STR(NetBSDConcatenated); + MY_CASE_STR(NetBSDEncrypted); + MY_CASE_STR(NetBSDUnknown); + MY_CASE_STR(ChromeOSKernel); + MY_CASE_STR(ChromeOSRootFS); + MY_CASE_STR(ChromeOSFuture); + MY_CASE_STR(ContLnxUsr); + MY_CASE_STR(ContLnxRoot); + MY_CASE_STR(ContLnxReserved); + MY_CASE_STR(ContLnxRootRAID); + MY_CASE_STR(HaikuBFS); + MY_CASE_STR(MidntBSDBoot); + MY_CASE_STR(MidntBSDData); + MY_CASE_STR(MidntBSDSwap); + MY_CASE_STR(MidntBSDUFS); + MY_CASE_STR(MidntBSDVium); + MY_CASE_STR(MidntBSDZFS); + MY_CASE_STR(MidntBSDUnknown); + MY_CASE_STR(OpenBSDData); + MY_CASE_STR(QNXPowerSafeFS); + MY_CASE_STR(Plan9); + MY_CASE_STR(VMWareVMKCore); + MY_CASE_STR(VMWareVMFS); + MY_CASE_STR(VMWareReserved); + MY_CASE_STR(VMWareUnknown); + MY_CASE_STR(AndroidX86Bootloader); + MY_CASE_STR(AndroidX86Bootloader2); + MY_CASE_STR(AndroidX86Boot); + MY_CASE_STR(AndroidX86Recovery); + MY_CASE_STR(AndroidX86Misc); + MY_CASE_STR(AndroidX86Metadata); + MY_CASE_STR(AndroidX86System); + MY_CASE_STR(AndroidX86Cache); + MY_CASE_STR(AndroidX86Data); + MY_CASE_STR(AndroidX86Persistent); + MY_CASE_STR(AndroidX86Vendor); + MY_CASE_STR(AndroidX86Config); + MY_CASE_STR(AndroidX86Factory); + MY_CASE_STR(AndroidX86FactoryAlt); + MY_CASE_STR(AndroidX86Fastboot); + MY_CASE_STR(AndroidX86OEM); + MY_CASE_STR(AndroidARMMeta); + MY_CASE_STR(AndroidARMExt); + MY_CASE_STR(ONIEBoot); + MY_CASE_STR(ONIEConfig); + MY_CASE_STR(PowerPCPrep); + MY_CASE_STR(XDGShrBootConfig); + MY_CASE_STR(CephBlock); + MY_CASE_STR(CephBlockDB); + MY_CASE_STR(CephBlockDBDmc); + MY_CASE_STR(CephBlockDBDmcLUKS); + MY_CASE_STR(CephBlockDmc); + MY_CASE_STR(CephBlockDmcLUKS); + MY_CASE_STR(CephBlockWALog); + MY_CASE_STR(CephBlockWALogDmc); + MY_CASE_STR(CephBlockWALogDmcLUKS); + MY_CASE_STR(CephDisk); + MY_CASE_STR(CephDiskDmc); + MY_CASE_STR(CephJournal); + MY_CASE_STR(CephJournalDmc); + MY_CASE_STR(CephJournalDmcLUKS); + MY_CASE_STR(CephLockbox); + MY_CASE_STR(CephMultipathBlock1); + MY_CASE_STR(CephMultipathBlock2); + MY_CASE_STR(CephMultipathBlockDB); + MY_CASE_STR(CephMultipathBLockWALog); + MY_CASE_STR(CephMultipathJournal); + MY_CASE_STR(CephMultipathOSD); + MY_CASE_STR(CephOSD); + MY_CASE_STR(CephOSDDmc); + MY_CASE_STR(CephOSDDmcLUKS); +#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK + case PartitionType_32BitHack: break; +#endif + /* no default! */ + } +#undef MY_CASE_STR + return pszUnknown; +} + + +/** + * List all available host drives with their partitions. + * + * @returns See produceList. + * @param pVirtualBox Reference to the IVirtualBox pointer. + * @param fOptLong Long listing or human readable. + */ +static HRESULT listHostDrives(const ComPtr pVirtualBox, bool fOptLong) +{ + HRESULT hrc = S_OK; + ComPtr pHost; + CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(Host)(pHost.asOutParam()), hrcCheck); + com::SafeIfaceArray apHostDrives; + CHECK_ERROR2I_RET(pHost, COMGETTER(HostDrives)(ComSafeArrayAsOutParam(apHostDrives)), hrcCheck); + for (size_t i = 0; i < apHostDrives.size(); ++i) + { + ComPtr pHostDrive = apHostDrives[i]; + + /* The drivePath and model attributes are accessible even when the object + is in 'limited' mode. */ + com::Bstr bstrDrivePath; + CHECK_ERROR(pHostDrive,COMGETTER(DrivePath)(bstrDrivePath.asOutParam())); + if (SUCCEEDED(hrc)) + RTPrintf(List::tr("%sDrive: %ls\n"), i > 0 ? "\n" : "", bstrDrivePath.raw()); + else + RTPrintf(List::tr("%sDrive: %Rhrc\n"), i > 0 ? "\n" : "", hrc); + + com::Bstr bstrModel; + CHECK_ERROR(pHostDrive,COMGETTER(Model)(bstrModel.asOutParam())); + if (FAILED(hrc)) + RTPrintf(List::tr("Model: %Rhrc\n"), hrc); + else if (bstrModel.isNotEmpty()) + RTPrintf(List::tr("Model: \"%ls\"\n"), bstrModel.raw()); + else + RTPrintf(List::tr("Model: unknown/inaccessible\n")); + + /* The other attributes are not accessible in limited mode and will fail + with E_ACCESSDENIED. Typically means the user cannot read the drive. */ + com::Bstr bstrUuidDisk; + hrc = pHostDrive->COMGETTER(Uuid)(bstrUuidDisk.asOutParam()); + if (SUCCEEDED(hrc) && !com::Guid(bstrUuidDisk).isZero()) + RTPrintf("UUID: %ls\n", bstrUuidDisk.raw()); + else if (hrc == E_ACCESSDENIED) + { + RTPrintf(List::tr("Further disk and partitioning information is not available for drive \"%ls\". (E_ACCESSDENIED)\n"), + bstrDrivePath.raw()); + continue; + } + else if (FAILED(hrc)) + { + RTPrintf("UUID: %Rhrc\n", hrc); + com::GlueHandleComErrorNoCtx(pHostDrive, hrc); + } + + LONG64 cbSize = 0; + hrc = pHostDrive->COMGETTER(Size)(&cbSize); + if (SUCCEEDED(hrc) && fOptLong) + RTPrintf(List::tr("Size: %llu bytes (%Rhcb)\n", "", cbSize), cbSize, cbSize); + else if (SUCCEEDED(hrc)) + RTPrintf(List::tr("Size: %Rhcb\n"), cbSize); + else + { + RTPrintf(List::tr("Size: %Rhrc\n"), hrc); + com::GlueHandleComErrorNoCtx(pHostDrive, hrc); + } + + ULONG cbSectorSize = 0; + hrc = pHostDrive->COMGETTER(SectorSize)(&cbSectorSize); + if (SUCCEEDED(hrc)) + RTPrintf(List::tr("Sector Size: %u bytes\n", "", cbSectorSize), cbSectorSize); + else + { + RTPrintf(List::tr("Sector Size: %Rhrc\n"), hrc); + com::GlueHandleComErrorNoCtx(pHostDrive, hrc); + } + + PartitioningType_T partitioningType = (PartitioningType_T)9999; + hrc = pHostDrive->COMGETTER(PartitioningType)(&partitioningType); + if (SUCCEEDED(hrc)) + RTPrintf(List::tr("Scheme: %s\n"), partitioningType == PartitioningType_MBR ? "MBR" : "GPT"); + else + { + RTPrintf(List::tr("Scheme: %Rhrc\n"), hrc); + com::GlueHandleComErrorNoCtx(pHostDrive, hrc); + } + + com::SafeIfaceArray apHostDrivesPartitions; + hrc = pHostDrive->COMGETTER(Partitions)(ComSafeArrayAsOutParam(apHostDrivesPartitions)); + if (FAILED(hrc)) + { + RTPrintf(List::tr("Partitions: %Rhrc\n"), hrc); + com::GlueHandleComErrorNoCtx(pHostDrive, hrc); + } + else if (apHostDrivesPartitions.size() == 0) + RTPrintf(List::tr("Partitions: None (or not able to grok them).\n")); + else if (partitioningType == PartitioningType_MBR) + { + if (fOptLong) + RTPrintf(List::tr("Partitions: First Last\n" + "## Type Byte Size Byte Offset Cyl/Head/Sec Cyl/Head/Sec Active\n")); + else + RTPrintf(List::tr("Partitions: First Last\n" + "## Type Size Start Cyl/Head/Sec Cyl/Head/Sec Active\n")); + for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) + { + ComPtr pHostDrivePartition = apHostDrivesPartitions[j]; + + ULONG idx = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Number)(&idx)); + ULONG uType = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(TypeMBR)(&uType)); + ULONG uStartCylinder = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(StartCylinder)(&uStartCylinder)); + ULONG uStartHead = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(StartHead)(&uStartHead)); + ULONG uStartSector = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(StartSector)(&uStartSector)); + ULONG uEndCylinder = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(EndCylinder)(&uEndCylinder)); + ULONG uEndHead = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(EndHead)(&uEndHead)); + ULONG uEndSector = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(EndSector)(&uEndSector)); + cbSize = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Size)(&cbSize)); + LONG64 offStart = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Start)(&offStart)); + BOOL fActive = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Active)(&fActive)); + PartitionType_T enmType = PartitionType_Unknown; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); + + /* Max size & offset here is around 16TiB with 4KiB sectors. */ + if (fOptLong) /* cb/off: max 16TiB; idx: max 64. */ + RTPrintf("%2u %02x %14llu %14llu %4u/%3u/%2u %4u/%3u/%2u %s %s\n", + idx, uType, cbSize, offStart, + uStartCylinder, uStartHead, uStartSector, uEndCylinder, uEndHead, uEndSector, + fActive ? List::tr("yes") : List::tr("no"), PartitionTypeToString(enmType, "")); + else + RTPrintf("%2u %02x %8Rhcb %8Rhcb %4u/%3u/%2u %4u/%3u/%2u %s %s\n", + idx, uType, (uint64_t)cbSize, (uint64_t)offStart, + uStartCylinder, uStartHead, uStartSector, uEndCylinder, uEndHead, uEndSector, + fActive ? List::tr("yes") : List::tr("no"), PartitionTypeToString(enmType, "")); + } + } + else /* GPT */ + { + /* Determin the max partition type length to try reduce the table width: */ + size_t cchMaxType = 0; + for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) + { + ComPtr pHostDrivePartition = apHostDrivesPartitions[j]; + PartitionType_T enmType = PartitionType_Unknown; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); + size_t const cchTypeNm = strlen(PartitionTypeToString(enmType, "e530bf6d-2754-4e9d-b260-60a5d0b80457")); + cchMaxType = RT_MAX(cchTypeNm, cchMaxType); + } + cchMaxType = RT_MIN(cchMaxType, RTUUID_STR_LENGTH); + + if (fOptLong) + RTPrintf(List::tr( + "Partitions:\n" + "## %-*s Uuid Byte Size Byte Offset Active Name\n"), + (int)cchMaxType, List::tr("Type")); + else + RTPrintf(List::tr( + "Partitions:\n" + "## %-*s Uuid Size Start Active Name\n"), + (int)cchMaxType, List::tr("Type")); + + for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) + { + ComPtr pHostDrivePartition = apHostDrivesPartitions[j]; + + ULONG idx = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Number)(&idx)); + com::Bstr bstrUuidType; + CHECK_ERROR(pHostDrivePartition, COMGETTER(TypeUuid)(bstrUuidType.asOutParam())); + com::Bstr bstrUuidPartition; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Uuid)(bstrUuidPartition.asOutParam())); + cbSize = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Size)(&cbSize)); + LONG64 offStart = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Start)(&offStart)); + BOOL fActive = 0; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Active)(&fActive)); + com::Bstr bstrName; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Name)(bstrName.asOutParam())); + + PartitionType_T enmType = PartitionType_Unknown; + CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); + + Utf8Str strTypeConv; + const char *pszTypeNm = PartitionTypeToString(enmType, NULL); + if (!pszTypeNm) + pszTypeNm = (strTypeConv = bstrUuidType).c_str(); + else if (strlen(pszTypeNm) >= RTUUID_STR_LENGTH /* includes '\0' */) + pszTypeNm -= RTUUID_STR_LENGTH - 1 - strlen(pszTypeNm); + + if (fOptLong) + RTPrintf("%2u %-*s %36ls %19llu %19llu %-3s %ls\n", idx, cchMaxType, pszTypeNm, + bstrUuidPartition.raw(), cbSize, offStart, fActive ? List::tr("on") : List::tr("off"), + bstrName.raw()); + else + RTPrintf("%2u %-*s %36ls %8Rhcb %8Rhcb %-3s %ls\n", idx, cchMaxType, pszTypeNm, + bstrUuidPartition.raw(), cbSize, offStart, fActive ? List::tr("on") : List::tr("off"), + bstrName.raw()); + } + } + } + return hrc; +} + + +/** + * The type of lists we can produce. + */ +enum ListType_T +{ + kListNotSpecified = 1000, + kListVMs, + kListRunningVMs, + kListOsTypes, + kListHostDvds, + kListHostFloppies, + kListInternalNetworks, + kListBridgedInterfaces, +#if defined(VBOX_WITH_NETFLT) + kListHostOnlyInterfaces, +#endif +#if defined(VBOX_WITH_VMNET) + kListHostOnlyNetworks, +#endif +#if defined(VBOX_WITH_CLOUD_NET) + kListCloudNetworks, +#endif + kListHostCpuIDs, + kListHostInfo, + kListHddBackends, + kListHdds, + kListDvds, + kListFloppies, + kListUsbHost, + kListUsbFilters, + kListSystemProperties, +#if defined(VBOX_WITH_UPDATE_AGENT) + kListUpdateAgents, +#endif + kListDhcpServers, + kListExtPacks, + kListGroups, + kListNatNetworks, + kListVideoInputDevices, + kListScreenShotFormats, + kListCloudProviders, + kListCloudProfiles, + kListCPUProfiles, + kListHostDrives +}; + + +/** + * Produces the specified listing. + * + * @returns S_OK or some COM error code that has been reported in full. + * @param enmList The list to produce. + * @param fOptLong Long (@c true) or short list format. + * @param pVirtualBox Reference to the IVirtualBox smart pointer. + */ +static HRESULT produceList(enum ListType_T enmCommand, bool fOptLong, bool fOptSorted, const ComPtr &pVirtualBox) +{ + HRESULT hrc = S_OK; + switch (enmCommand) + { + case kListNotSpecified: + AssertFailed(); + return E_FAIL; + + case kListVMs: + { + /* + * Get the list of all registered VMs + */ + com::SafeIfaceArray machines; + hrc = pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)); + if (SUCCEEDED(hrc)) + { + /* + * Display it. + */ + if (!fOptSorted) + { + for (size_t i = 0; i < machines.size(); ++i) + if (machines[i]) + hrc = showVMInfo(pVirtualBox, machines[i], NULL, fOptLong ? VMINFO_STANDARD : VMINFO_COMPACT); + } + else + { + /* + * Sort the list by name before displaying it. + */ + std::vector > sortedMachines; + for (size_t i = 0; i < machines.size(); ++i) + { + IMachine *pMachine = machines[i]; + if (pMachine) /* no idea why we need to do this... */ + { + Bstr bstrName; + pMachine->COMGETTER(Name)(bstrName.asOutParam()); + sortedMachines.push_back(std::pair(bstrName, pMachine)); + } + } + + std::sort(sortedMachines.begin(), sortedMachines.end()); + + for (size_t i = 0; i < sortedMachines.size(); ++i) + hrc = showVMInfo(pVirtualBox, sortedMachines[i].second, NULL, fOptLong ? VMINFO_STANDARD : VMINFO_COMPACT); + } + } + break; + } + + case kListRunningVMs: + { + /* + * Get the list of all _running_ VMs + */ + com::SafeIfaceArray machines; + hrc = pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)); + com::SafeArray states; + if (SUCCEEDED(hrc)) + hrc = pVirtualBox->GetMachineStates(ComSafeArrayAsInParam(machines), ComSafeArrayAsOutParam(states)); + if (SUCCEEDED(hrc)) + { + /* + * Iterate through the collection + */ + for (size_t i = 0; i < machines.size(); ++i) + { + if (machines[i]) + { + MachineState_T machineState = states[i]; + switch (machineState) + { + case MachineState_Running: + case MachineState_Teleporting: + case MachineState_LiveSnapshotting: + case MachineState_Paused: + case MachineState_TeleportingPausedVM: + hrc = showVMInfo(pVirtualBox, machines[i], NULL, fOptLong ? VMINFO_STANDARD : VMINFO_COMPACT); + break; + default: break; /* Shut up MSC */ + } + } + } + } + break; + } + + case kListOsTypes: + { + com::SafeIfaceArray coll; + hrc = pVirtualBox->COMGETTER(GuestOSTypes)(ComSafeArrayAsOutParam(coll)); + if (SUCCEEDED(hrc)) + { + /* + * Iterate through the collection. + */ + for (size_t i = 0; i < coll.size(); ++i) + { + ComPtr guestOS; + guestOS = coll[i]; + Bstr guestId; + guestOS->COMGETTER(Id)(guestId.asOutParam()); + RTPrintf("ID: %ls\n", guestId.raw()); + Bstr guestDescription; + guestOS->COMGETTER(Description)(guestDescription.asOutParam()); + RTPrintf(List::tr("Description: %ls\n"), guestDescription.raw()); + Bstr familyId; + guestOS->COMGETTER(FamilyId)(familyId.asOutParam()); + RTPrintf(List::tr("Family ID: %ls\n"), familyId.raw()); + Bstr familyDescription; + guestOS->COMGETTER(FamilyDescription)(familyDescription.asOutParam()); + RTPrintf(List::tr("Family Desc: %ls\n"), familyDescription.raw()); + BOOL is64Bit; + guestOS->COMGETTER(Is64Bit)(&is64Bit); + RTPrintf(List::tr("64 bit: %RTbool\n"), is64Bit); + RTPrintf("\n"); + } + } + break; + } + + case kListHostDvds: + { + ComPtr host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); + com::SafeIfaceArray coll; + CHECK_ERROR(host, COMGETTER(DVDDrives)(ComSafeArrayAsOutParam(coll))); + if (SUCCEEDED(hrc)) + { + for (size_t i = 0; i < coll.size(); ++i) + { + ComPtr dvdDrive = coll[i]; + Bstr uuid; + dvdDrive->COMGETTER(Id)(uuid.asOutParam()); + RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str()); + Bstr location; + dvdDrive->COMGETTER(Location)(location.asOutParam()); + RTPrintf(List::tr("Name: %ls\n\n"), location.raw()); + } + } + break; + } + + case kListHostFloppies: + { + ComPtr host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); + com::SafeIfaceArray coll; + CHECK_ERROR(host, COMGETTER(FloppyDrives)(ComSafeArrayAsOutParam(coll))); + if (SUCCEEDED(hrc)) + { + for (size_t i = 0; i < coll.size(); ++i) + { + ComPtr floppyDrive = coll[i]; + Bstr uuid; + floppyDrive->COMGETTER(Id)(uuid.asOutParam()); + RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str()); + Bstr location; + floppyDrive->COMGETTER(Location)(location.asOutParam()); + RTPrintf(List::tr("Name: %ls\n\n"), location.raw()); + } + } + break; + } + + case kListInternalNetworks: + hrc = listInternalNetworks(pVirtualBox); + break; + + case kListBridgedInterfaces: +#if defined(VBOX_WITH_NETFLT) + case kListHostOnlyInterfaces: +#endif + hrc = listNetworkInterfaces(pVirtualBox, enmCommand == kListBridgedInterfaces); + break; + +#if defined(VBOX_WITH_VMNET) + case kListHostOnlyNetworks: + hrc = listHostOnlyNetworks(pVirtualBox); + break; +#endif + +#if defined(VBOX_WITH_CLOUD_NET) + case kListCloudNetworks: + hrc = listCloudNetworks(pVirtualBox); + break; +#endif + case kListHostInfo: + hrc = listHostInfo(pVirtualBox); + break; + + case kListHostCpuIDs: + { + ComPtr Host; + CHECK_ERROR(pVirtualBox, COMGETTER(Host)(Host.asOutParam())); + + RTPrintf(List::tr("Host CPUIDs:\n\nLeaf no. EAX EBX ECX EDX\n")); + ULONG uCpuNo = 0; /* ASSUMES that CPU#0 is online. */ + static uint32_t const s_auCpuIdRanges[] = + { + UINT32_C(0x00000000), UINT32_C(0x0000007f), + UINT32_C(0x80000000), UINT32_C(0x8000007f), + UINT32_C(0xc0000000), UINT32_C(0xc000007f) + }; + for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2) + { + ULONG uEAX, uEBX, uECX, uEDX, cLeafs; + CHECK_ERROR(Host, GetProcessorCPUIDLeaf(uCpuNo, s_auCpuIdRanges[i], 0, &cLeafs, &uEBX, &uECX, &uEDX)); + if (cLeafs < s_auCpuIdRanges[i] || cLeafs > s_auCpuIdRanges[i+1]) + continue; + cLeafs++; + for (ULONG iLeaf = s_auCpuIdRanges[i]; iLeaf <= cLeafs; iLeaf++) + { + CHECK_ERROR(Host, GetProcessorCPUIDLeaf(uCpuNo, iLeaf, 0, &uEAX, &uEBX, &uECX, &uEDX)); + RTPrintf("%08x %08x %08x %08x %08x\n", iLeaf, uEAX, uEBX, uECX, uEDX); + } + } + break; + } + + case kListHddBackends: + hrc = listHddBackends(pVirtualBox); + break; + + case kListHdds: + { + com::SafeIfaceArray hdds; + CHECK_ERROR(pVirtualBox, COMGETTER(HardDisks)(ComSafeArrayAsOutParam(hdds))); + hrc = listMedia(pVirtualBox, hdds, List::tr("base"), fOptLong); + break; + } + + case kListDvds: + { + com::SafeIfaceArray dvds; + CHECK_ERROR(pVirtualBox, COMGETTER(DVDImages)(ComSafeArrayAsOutParam(dvds))); + hrc = listMedia(pVirtualBox, dvds, NULL, fOptLong); + break; + } + + case kListFloppies: + { + com::SafeIfaceArray floppies; + CHECK_ERROR(pVirtualBox, COMGETTER(FloppyImages)(ComSafeArrayAsOutParam(floppies))); + hrc = listMedia(pVirtualBox, floppies, NULL, fOptLong); + break; + } + + case kListUsbHost: + hrc = listUsbHost(pVirtualBox); + break; + + case kListUsbFilters: + hrc = listUsbFilters(pVirtualBox); + break; + + case kListSystemProperties: + hrc = listSystemProperties(pVirtualBox); + break; + +#ifdef VBOX_WITH_UPDATE_AGENT + case kListUpdateAgents: + hrc = listUpdateAgents(pVirtualBox); + break; +#endif + case kListDhcpServers: + hrc = listDhcpServers(pVirtualBox); + break; + + case kListExtPacks: + hrc = listExtensionPacks(pVirtualBox); + break; + + case kListGroups: + hrc = listGroups(pVirtualBox); + break; + + case kListNatNetworks: + hrc = listNATNetworks(fOptLong, fOptSorted, pVirtualBox); + break; + + case kListVideoInputDevices: + hrc = listVideoInputDevices(pVirtualBox); + break; + + case kListScreenShotFormats: + hrc = listScreenShotFormats(pVirtualBox); + break; + + case kListCloudProviders: + hrc = listCloudProviders(pVirtualBox); + break; + + case kListCloudProfiles: + hrc = listCloudProfiles(pVirtualBox, fOptLong); + break; + + case kListCPUProfiles: + hrc = listCPUProfiles(pVirtualBox, fOptLong, fOptSorted); + break; + + case kListHostDrives: + hrc = listHostDrives(pVirtualBox, fOptLong); + break; + /* No default here, want gcc warnings. */ + + } /* end switch */ + + return hrc; +} + +/** + * Handles the 'list' command. + * + * @returns Appropriate exit code. + * @param a Handler argument. + */ +RTEXITCODE handleList(HandlerArg *a) +{ + bool fOptLong = false; + bool fOptMultiple = false; + bool fOptSorted = false; + bool fFirst = true; + enum ListType_T enmOptCommand = kListNotSpecified; + RTEXITCODE rcExit = RTEXITCODE_SUCCESS; + + static const RTGETOPTDEF s_aListOptions[] = + { + { "--long", 'l', RTGETOPT_REQ_NOTHING }, + { "--multiple", 'm', RTGETOPT_REQ_NOTHING }, /* not offical yet */ + { "--sorted", 's', RTGETOPT_REQ_NOTHING }, + { "vms", kListVMs, RTGETOPT_REQ_NOTHING }, + { "runningvms", kListRunningVMs, RTGETOPT_REQ_NOTHING }, + { "ostypes", kListOsTypes, RTGETOPT_REQ_NOTHING }, + { "hostdvds", kListHostDvds, RTGETOPT_REQ_NOTHING }, + { "hostfloppies", kListHostFloppies, RTGETOPT_REQ_NOTHING }, + { "intnets", kListInternalNetworks, RTGETOPT_REQ_NOTHING }, + { "hostifs", kListBridgedInterfaces, RTGETOPT_REQ_NOTHING }, /* backward compatibility */ + { "bridgedifs", kListBridgedInterfaces, RTGETOPT_REQ_NOTHING }, +#if defined(VBOX_WITH_NETFLT) + { "hostonlyifs", kListHostOnlyInterfaces, RTGETOPT_REQ_NOTHING }, +#endif +#if defined(VBOX_WITH_VMNET) + { "hostonlynets", kListHostOnlyNetworks, RTGETOPT_REQ_NOTHING }, +#endif +#if defined(VBOX_WITH_CLOUD_NET) + { "cloudnets", kListCloudNetworks, RTGETOPT_REQ_NOTHING }, +#endif + { "natnetworks", kListNatNetworks, RTGETOPT_REQ_NOTHING }, + { "natnets", kListNatNetworks, RTGETOPT_REQ_NOTHING }, + { "hostinfo", kListHostInfo, RTGETOPT_REQ_NOTHING }, + { "hostcpuids", kListHostCpuIDs, RTGETOPT_REQ_NOTHING }, + { "hddbackends", kListHddBackends, RTGETOPT_REQ_NOTHING }, + { "hdds", kListHdds, RTGETOPT_REQ_NOTHING }, + { "dvds", kListDvds, RTGETOPT_REQ_NOTHING }, + { "floppies", kListFloppies, RTGETOPT_REQ_NOTHING }, + { "usbhost", kListUsbHost, RTGETOPT_REQ_NOTHING }, + { "usbfilters", kListUsbFilters, RTGETOPT_REQ_NOTHING }, + { "systemproperties", kListSystemProperties, RTGETOPT_REQ_NOTHING }, +#if defined(VBOX_WITH_UPDATE_AGENT) + { "updates", kListUpdateAgents, RTGETOPT_REQ_NOTHING }, +#endif + { "dhcpservers", kListDhcpServers, RTGETOPT_REQ_NOTHING }, + { "extpacks", kListExtPacks, RTGETOPT_REQ_NOTHING }, + { "groups", kListGroups, RTGETOPT_REQ_NOTHING }, + { "webcams", kListVideoInputDevices, RTGETOPT_REQ_NOTHING }, + { "screenshotformats", kListScreenShotFormats, RTGETOPT_REQ_NOTHING }, + { "cloudproviders", kListCloudProviders, RTGETOPT_REQ_NOTHING }, + { "cloudprofiles", kListCloudProfiles, RTGETOPT_REQ_NOTHING }, + { "cpu-profiles", kListCPUProfiles, RTGETOPT_REQ_NOTHING }, + { "hostdrives", kListHostDrives, RTGETOPT_REQ_NOTHING }, + }; + + int ch; + RTGETOPTUNION ValueUnion; + RTGETOPTSTATE GetState; + RTGetOptInit(&GetState, a->argc, a->argv, s_aListOptions, RT_ELEMENTS(s_aListOptions), + 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); + while ((ch = RTGetOpt(&GetState, &ValueUnion))) + { + switch (ch) + { + case 'l': /* --long */ + fOptLong = true; + break; + + case 's': + fOptSorted = true; + break; + + case 'm': + fOptMultiple = true; + if (enmOptCommand == kListNotSpecified) + break; + ch = enmOptCommand; + RT_FALL_THRU(); + + case kListVMs: + case kListRunningVMs: + case kListOsTypes: + case kListHostDvds: + case kListHostFloppies: + case kListInternalNetworks: + case kListBridgedInterfaces: +#if defined(VBOX_WITH_NETFLT) + case kListHostOnlyInterfaces: +#endif +#if defined(VBOX_WITH_VMNET) + case kListHostOnlyNetworks: +#endif +#if defined(VBOX_WITH_CLOUD_NET) + case kListCloudNetworks: +#endif + case kListHostInfo: + case kListHostCpuIDs: + case kListHddBackends: + case kListHdds: + case kListDvds: + case kListFloppies: + case kListUsbHost: + case kListUsbFilters: + case kListSystemProperties: +#if defined(VBOX_WITH_UPDATE_AGENT) + case kListUpdateAgents: +#endif + case kListDhcpServers: + case kListExtPacks: + case kListGroups: + case kListNatNetworks: + case kListVideoInputDevices: + case kListScreenShotFormats: + case kListCloudProviders: + case kListCloudProfiles: + case kListCPUProfiles: + case kListHostDrives: + enmOptCommand = (enum ListType_T)ch; + if (fOptMultiple) + { + if (fFirst) + fFirst = false; + else + RTPrintf("\n"); + RTPrintf("[%s]\n", ValueUnion.pDef->pszLong); + HRESULT hrc = produceList(enmOptCommand, fOptLong, fOptSorted, a->virtualBox); + if (FAILED(hrc)) + rcExit = RTEXITCODE_FAILURE; + } + break; + + case VINF_GETOPT_NOT_OPTION: + return errorSyntax(List::tr("Unknown subcommand \"%s\"."), ValueUnion.psz); + + default: + return errorGetOpt(ch, &ValueUnion); + } + } + + /* + * If not in multiple list mode, we have to produce the list now. + */ + if (enmOptCommand == kListNotSpecified) + return errorSyntax(List::tr("Missing subcommand for \"list\" command.\n")); + if (!fOptMultiple) + { + HRESULT hrc = produceList(enmOptCommand, fOptLong, fOptSorted, a->virtualBox); + if (FAILED(hrc)) + rcExit = RTEXITCODE_FAILURE; + } + + return rcExit; +} + +/* vi: set tabstop=4 shiftwidth=4 expandtab: */ -- cgit v1.2.3