summaryrefslogtreecommitdiffstats
path: root/src/VBox/Frontends/VBoxManage
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Frontends/VBoxManage
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Frontends/VBoxManage')
-rw-r--r--src/VBox/Frontends/VBoxManage/.scm-settings29
-rw-r--r--src/VBox/Frontends/VBoxManage/Makefile.kmk413
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp2114
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManage.cpp950
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManage.h313
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManage.rc61
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp2916
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp384
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp2654
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageCloudMachine.cpp1482
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp2287
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp1343
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp976
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp2753
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp3707
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.h270
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrlListener.cpp578
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp601
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp513
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp546
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp3231
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageList.cpp2434
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp671
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp2920
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageModifyNvram.cpp582
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp3646
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp702
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp670
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp1306
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp581
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageUpdateCheck.cpp392
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageUtils.cpp131
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageUtils.h45
-rw-r--r--src/VBox/Frontends/VBoxManage/nls/ApprovedLanguages.kmk40
-rw-r--r--src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_ru.ts12354
-rw-r--r--src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_xx_YY.ts10640
36 files changed, 65235 insertions, 0 deletions
diff --git a/src/VBox/Frontends/VBoxManage/.scm-settings b/src/VBox/Frontends/VBoxManage/.scm-settings
new file mode 100644
index 00000000..014df96e
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/.scm-settings
@@ -0,0 +1,29 @@
+# $Id: .scm-settings $
+## @file
+# Source code massager settings for VBoxManage.
+#
+
+#
+# Copyright (C) 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 <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+/*: --no-rc-use
+
diff --git a/src/VBox/Frontends/VBoxManage/Makefile.kmk b/src/VBox/Frontends/VBoxManage/Makefile.kmk
new file mode 100644
index 00000000..2a63da42
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/Makefile.kmk
@@ -0,0 +1,413 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for VBoxManage (the CLI frontend).
+#
+
+#
+# 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 <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+include $(PATH_ROOT)/doc/manual/Config.kmk
+
+
+## @todo r=andy Sort this stuff alphabetically!
+VBOX_COMMON_VBOXMANAGE_DEFS = \
+ $(if $(VBOX_WITH_AHCI), VBOX_WITH_AHCI) \
+ $(if $(VBOX_WITH_COPYTOGUEST),VBOX_WITH_COPYTOGUEST) \
+ $(if $(VBOX_WITH_E1000),VBOX_WITH_E1000) \
+ $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL) \
+ $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS) \
+ $(if $(VBOX_WITH_HEADLESS), VBOX_WITH_HEADLESS) \
+ $(if $(VBOX_WITH_HGCM), VBOX_WITH_HGCM) \
+ $(if $(VBOX_WITH_HOSTNETIF_API), VBOX_WITH_HOSTNETIF_API) \
+ $(if $(VBOX_WITH_NETFLT), VBOX_WITH_NETFLT) \
+ $(if-expr defined(VBOX_WITH_VMNET) && "$(KBUILD_TARGET)"=="darwin",VBOX_WITH_VMNET,) \
+ $(if $(VBOX_WITH_CLOUD_NET), VBOX_WITH_CLOUD_NET) \
+ $(if $(VBOX_WITH_AUDIO_OSS), VBOX_WITH_AUDIO_OSS) \
+ $(if $(VBOX_WITH_AUDIO_ALSA), VBOX_WITH_AUDIO_ALSA) \
+ $(if $(VBOX_WITH_AUDIO_PULSE),VBOX_WITH_AUDIO_PULSE) \
+ $(if $(VBOX_WITH_SCSI), VBOX_WITH_SCSI) \
+ $(if $(VBOX_WITH_VBOXSDL), VBOX_WITH_VBOXSDL) \
+ $(if $(VBOX_WITH_VIDEOHWACCEL), VBOX_WITH_VIDEOHWACCEL) \
+ $(if $(VBOX_WITH_VIRTIO),VBOX_WITH_VIRTIO) \
+ $(if $(VBOX_WITH_VIRTIO_NET_1_0),VBOX_WITH_VIRTIO_NET_1_0) \
+ $(if $(VBOX_WITH_USB_CARDREADER),VBOX_WITH_USB_CARDREADER) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH) \
+ $(if $(VBOX_WITH_RECORDING),VBOX_WITH_RECORDING) \
+ $(if $(VBOX_WITH_AUDIO_RECORDING),VBOX_WITH_AUDIO_RECORDING) \
+ $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE) \
+ $(if $(VBOX_WITH_SHARED_CLIPBOARD),VBOX_WITH_SHARED_CLIPBOARD) \
+ $(if $(VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS),VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS) \
+ $(if $(VBOX_WITH_IOMMU_AMD),VBOX_WITH_IOMMU_AMD) \
+ $(if $(VBOX_WITH_IOMMU_INTEL),VBOX_WITH_IOMMU_INTEL) \
+ $(if $(VBOX_WITH_UPDATE_AGENT), VBOX_WITH_UPDATE_AGENT) \
+ $(if $(VBOX_WITH_VMSVGA),VBOX_WITH_VMSVGA) \
+ $(if $(VBOX_WITH_MAIN_NLS),VBOX_WITH_MAIN_NLS) \
+ $(if $(VBOX_WITH_TPM),VBOX_WITH_TPM) \
+ $(if $(VBOX_WITH_FULL_VM_ENCRYPTION),VBOX_WITH_FULL_VM_ENCRYPTION)
+
+
+ifndef VBOX_ONLY_DOCS
+ PROGRAMS += VBoxManage
+ VBoxManage_TEMPLATE = VBoxMainClientExe
+ VBoxManage_DEFS += $(VBOX_COMMON_VBOXMANAGE_DEFS)
+ VBoxManage_DEFS.win = _WIN32_WINNT=0x0500
+ VBoxManage_INCS = \
+ $(VBoxManage_0_OUTDIR) \
+ ../Common
+ VBoxManage_INTERMEDIATES = \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h
+ VBoxManage_SOURCES = \
+ VBoxManage.cpp \
+ VBoxManageUtils.cpp \
+ VBoxInternalManage.cpp \
+ VBoxManageAppliance.cpp \
+ VBoxManageBandwidthControl.cpp \
+ VBoxManageControlVM.cpp \
+ VBoxManageDebugVM.cpp \
+ VBoxManageDHCPServer.cpp \
+ VBoxManageDisk.cpp \
+ $(if $(VBOX_WITH_GUEST_CONTROL),VBoxManageGuestCtrl.cpp) \
+ $(if $(VBOX_WITH_GUEST_CONTROL),VBoxManageGuestCtrlListener.cpp) \
+ $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
+ VBoxManageHelp.cpp \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.cpp \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_en_US.cpp \
+ VBoxManageHostonly.cpp \
+ VBoxManageInfo.cpp \
+ VBoxManageList.cpp \
+ VBoxManageMetrics.cpp \
+ VBoxManageMisc.cpp \
+ VBoxManageModifyVM.cpp \
+ VBoxManageModifyNvram.cpp \
+ VBoxManageSnapshot.cpp \
+ VBoxManageStorageController.cpp \
+ $(if $(VBOX_WITH_UPDATE_AGENT),VBoxManageUpdateCheck.cpp) \
+ VBoxManageUSB.cpp \
+ $(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,) \
+ $(if $(VBOX_WITH_NAT_SERVICE),../../NetworkServices/NetLib/VBoxNetPortForwardString.cpp,) \
+ VBoxManageCloud.cpp \
+ VBoxManageCloudMachine.cpp \
+ ../Common/PasswordInput.cpp
+ VBoxManage_SOURCES.win = \
+ VBoxManage.rc
+ VBoxManage_LIBS += $(LIB_DDU)
+
+ ifdef VBOX_WITH_VBOXMANAGE_NLS
+ VBOX_PATH_VBOXMANAGE_SRC := $(PATH_SUB_CURRENT)
+ include $(PATH_SUB_CURRENT)/nls/ApprovedLanguages.kmk
+
+ VBoxManage_DEFS += VBOX_WITH_VBOXMANAGE_NLS
+ VBoxManage_INCS += \
+ $(PATH_ROOT)/src/VBox/Main/include
+ VBoxManage_SOURCES += \
+ $(PATH_ROOT)/src/VBox/Main/src-all/VirtualBoxTranslator.cpp \
+ $(PATH_ROOT)/src/VBox/Main/src-all/QMTranslatorImpl.cpp \
+ $(PATH_ROOT)/src/VBox/Main/src-all/GlobalStatusConversion.cpp
+
+ # $(addsuffix /VBoxManageBuiltInHelp.cpp,$(addprefix $(VBoxManage_0_OUTDIR)/,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES)))
+ #VBoxManage_INTERMEDIATES += \
+ # $(addsuffix /VBoxManageBuiltInHelp.h,$(addprefix $(VBoxManage_0_OUTDIR)/,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES)))
+
+ # define qt5 tools for translation
+ USES += qt5
+
+ PROGRAMS += VBoxManageNls
+ VBoxManageNls_TEMPLATE = VBoxNLS
+ VBoxManageNls_QT_TRANSLATIONS = $(addsuffix .ts,$(addprefix $(VBOX_PATH_VBOXMANAGE_SRC)/nls/VBoxManageNls_,$(VBOX_APPROVED_VBOXMANAGE_LANGUAGES)))
+ VBoxManageNls_VBOX_ALL_NLS_SOURCES = $(wildcard \
+ $(VBOX_PATH_VBOXMANAGE_SRC)/*.h \
+ $(VBOX_PATH_VBOXMANAGE_SRC)/*.cpp )
+
+ updatenls:: makeallnls $(VBOX_PATH_VBOXMANAGE_SRC)/nls/VBoxManageNls_en.ts
+
+ makeallnls:: $(VBoxManageNls_VBOX_ALL_NLS_SOURCES)
+ $(call MSG_L1,lupdate all languages (nls/*.ts))
+ $(QUIET)$(TOOL_QT5_LUPDATE) \
+ $^ \
+ -ts \
+ $(filter-out nls/VBoxManageNls_en.ts, $(VBoxManageNls_QT_TRANSLATIONS)) \
+ $(VBOX_PATH_VBOXMANAGE_SRC)/nls/VBoxManageNls_xx_YY.ts
+
+ # fake-main-nls:
+ # $(foreach file, $(VBoxManageNls_QT_TRANSLATIONS) \
+ # ,$(NLTAB)$(SED) -i \
+ # -e '/<source>.*<\/source>/h' \
+ # -e '/<source>.*<\/source>/p' \
+ # -e '/<translation type="unfinished"><\/translation>/{' \
+ # -e 'x' \
+ # -e 's/<source>\(.*\)<\/source>/<translation type="unfinished">$(notdir $(file)): \1<\/translation>/' \
+ # -e '}' \
+ # $(file) )
+
+
+ # Create the English translation file. This is something special cause it will
+ # contain the plural forms only.
+ $(VBOX_PATH_VBOXMANAGE_SRC)/nls/VBoxManageNls_en.ts: $(VBoxManageNls_VBOX_ALL_NLS_SOURCES)
+ $(call MSG_L1,lupdate $@)
+ $(QUIET)$(TOOL_QT5_LUPDATE) \
+ $^ \
+ -ts \
+ "$@"
+ $(QUIET)$(SED) -n -i \
+ -e '/<context>/,/<\/context>/!p' \
+ -e '/<context>/h' \
+ -e '/<name>/H' \
+ -e '/<message numerus="yes">/,/<\/message>/H' \
+ -e '/<\/context>/{H;x;/<message/p}' \
+ "$@"
+
+ endif # VBOX_WITH_VBOXMANAGE_NLS
+
+
+ # VBoxNetPortForwardString.h
+ VBoxManageNATNetwork.cpp_INCS += ../../NetworkServices/NetLib/
+
+endif # VBOX_ONLY_DOCS
+
+ifneq ($(KBUILD_TARGET),win)
+ # Workaround for buggy gcc-4.3 compilers, see
+ #
+ # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36474
+ #
+ # Some later revisions of version 4.3.1 are known to work so we assume
+ # that version 4.3.2 or later has this bug definitely fixed.
+ VBoxManage_CXXFLAGS.release += \
+ $(if $(VBOX_GCC_VERSION_CXX),$(if-expr $(VBOX_GCC_VERSION_CXX) < 40300 || $(VBOX_GCC_VERSION_CXX) > 40301,,--param max-fields-for-field-sensitive=0),)
+ VBoxManageHelp_CXXFLAGS.release = $(VBoxManage_CXXFLAGS.release)
+endif
+
+
+#
+# VBoxManage built-in help from XML refentry in doc/manual/en_US/.
+#
+$(call KB_FN_DO_PASS0_ON_TARGET,VBoxManage)
+
+VBoxManage_CLEAN += \
+ $(VBOX_XML_CATALOG) \
+ $(VBOX_XML_CATALOG_DOCBOOK) \
+ $(VBOX_XML_CATALOG_MANUAL) \
+ $(VBOX_XML_ENTITIES) \
+ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/, $(VBOX_XML_XREF_TO_TEXT) $(VBOX_XML_XREF_TO_TEXT).cat) \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_en_US.cpp \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_en_US.cpp.ts \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.cpp \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.cpp.ts \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h.ts \
+ $(addprefix $(VBoxManage_0_OUTDIR)/,$(filter man_VBoxManage-%,$(VBOX_MANUAL_XML_REFENTRY_FILES)))
+
+# Preprocess the xml files, applying remarks.
+$(foreach file,$(filter man_VBoxManage-%,$(VBOX_MANUAL_XML_REFENTRY_FILES)) \
+, $(evalcall2 def_vbox_refentry_preprocess_for_manpage,$(VBoxManage_0_OUTDIR),$(file), \
+ $(VBOX_PATH_MANUAL_SRC)/en_US/$(file),replace-xrefs,en_US))
+
+
+##
+# Emits rules for generating cpp files from man pages.
+#
+# $(evalcall2 def_vbox_man_generate_cpp_help)
+# @param 1 Folder with preprocessed man_VBoxManage_* files
+# @param 2 language code.
+define def_vbox_man_generate_cpp_help
+ ifneq ($(2),en_US)
+ VBOX_DOCBOOK_REFENTRY_TO_C_HELP_$(2) = $(VBOX_PATH_MANUAL_SRC)/$(2)/docbook-refentry-to-C-help.xsl
+ else
+ VBOX_DOCBOOK_REFENTRY_TO_C_HELP_$(2) = $(VBOX_DOCBOOK_REFENTRY_TO_C_HELP)
+ endif
+ $$(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_$(2).cpp.ts \
+ +| $$(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_$(2).cpp: \
+ $$(VBOX_DOCBOOK_REFENTRY_TO_C_HELP_$(2)) \
+ $$(VBOX_DOCBOOK_REFENTRY_TO_C_HELP) \
+ $$(addprefix $(1)/,$$(filter man_VBoxManage-%,$$(VBOX_MANUAL_XML_REFENTRY_FILES))) \
+ $$(VBOX_XML_CATALOG) $$(VBOX_XML_CATALOG_DOCBOOK) $$(MAKEFILE) | $$$$(dir $$$$@)
+ $$(call MSG_TOOL,xsltproc $$(notdir $$(firstword $$(filter %.xsl,$$^))),,$$(filter %.xml,$$^),$$(patsubst %.ts,%,$$@))
+ $$(QUIET)$$(APPEND) -tn "$$@" \
+ '/* Autogenerated by $$<, do not edit! */' \
+ '' \
+ '#include "VBoxManageBuiltInHelp.h"' \
+ '' \
+ 'RT_C_DECLS_BEGIN' \
+ '/* make next variables visible outside the module */' \
+ 'extern PCRTMSGREFENTRY g_apHelpEntries_$(2)[];' \
+ 'extern const uint32_t g_cHelpEntries_$(2);' \
+ 'RT_C_DECLS_END' \
+ '' \
+ $$(foreach refentry,$$(filter %.xml,$$^) \
+ ,$$(NLTAB)$$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT, -a+to "$$@") \
+ --path '$(VBOX_PATH_MANUAL_SRC)/$(2) $(VBOX_PATH_MANUAL_SRC)/en_US' $$< $$(refentry))
+ $$(QUIET)$$(APPEND) -n "$$@" \
+ '' \
+ 'PCRTMSGREFENTRY g_apHelpEntries_$(2)[] =' \
+ '{'
+ $$(foreach refentry,$$(filter %.xml,$$^) \
+ ,$$(NLTAB)$$(QUIET)$$(APPEND) -n "$$@" \
+ ' &g_$$(subst -,_,$$(tolower $$(patsubst man_%,%,$$(notdir $$(basename $$(refentry)))))),')
+ $$(QUIET)$$(APPEND) -n "$$@" \
+ '};' \
+ '' \
+ 'const uint32_t g_cHelpEntries_$(2) = RT_ELEMENTS(g_apHelpEntries_$(2));' \
+ ''
+ $$(QUIET)$$(CP) --changed -- "$$@" "$$(patsubst %.ts,%,$$@)"
+endef
+# The above APPEND stuff trigger some kind of problem on some boxes when not split up...
+# update: Fixed in SVN (strcpy -> memmove in new_job(), job.c - r2591). Just need to rebuild all platforms.
+
+# Generate the .cpp file.
+$(evalcall2 def_vbox_man_generate_cpp_help, $(VBoxManage_0_OUTDIR),en_US)
+
+
+# Generate built-in help for all languages (English is implicit).
+$(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.cpp.ts \
++| $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.cpp: \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_en_US.cpp \
+ $(foreach lang,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES), $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_$(lang).cpp ) \
+ $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h
+ $(QUIET)$(APPEND) -tn "$@" \
+ '/* Autogenerated, do not edit! */' \
+ '' \
+ '#include "VBoxManageBuiltInHelp.h"' \
+ '' \
+ 'RT_C_DECLS_BEGIN' \
+ '' \
+ 'extern PCRTMSGREFENTRY g_apHelpEntries_en_US[];' \
+ 'extern const uint32_t g_cHelpEntries_en_US;'
+ifdef VBOX_WITH_VBOXMANAGE_NLS
+ $(foreach lang,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ ,$(NLTAB)$(QUIET)$(APPEND) -n "$@" \
+ '' \
+ 'extern PCRTMSGREFENTRY g_apHelpEntries_$(lang)[];' \
+ 'extern const uint32_t g_cHelpEntries_$(lang);')
+endif
+ $(QUIET)$(APPEND) -n "$@" \
+ '' \
+ 'RT_C_DECLS_END' \
+ '' \
+ 'HELP_LANG_ENTRY_T const g_aHelpLangEntries[] = ' \
+ '{' \
+ ' { "en_US", 5, &g_apHelpEntries_en_US[0], &g_cHelpEntries_en_US },'
+ifdef VBOX_WITH_VBOXMANAGE_NLS
+ $(foreach lang,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ ,$(NLTAB)$(QUIET)$(APPEND) "$@" ' { "$(lang)", $(length $(lang)), &g_apHelpEntries_$(lang)[0], &g_cHelpEntries_$(lang) },' )
+endif
+ $(QUIET)$(APPEND) -n "$@" \
+ '};' \
+ '' \
+ 'uint32_t const g_cHelpLangEntries = RT_ELEMENTS(g_aHelpLangEntries);' \
+ '' \
+ 'PCHELP_LANG_ENTRY_T volatile g_pHelpLangEntry = &g_aHelpLangEntries[0];'\
+ ''
+ $(QUIET)$(CP) --changed -- "$@" "$(patsubst %.ts,%,$@)"
+
+
+$(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h.ts \
++| $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h: \
+ $(VBOX_DOCBOOK_REFENTRY_TO_H_HELP) \
+ $(addprefix $(VBoxManage_0_OUTDIR)/,$(filter man_VBoxManage-%,$(VBOX_MANUAL_XML_REFENTRY_FILES))) \
+ $(VBOX_XML_CATALOG) $(VBOX_XML_CATALOG_DOCBOOK) $(MAKEFILE) | $$(dir $$@)
+ $(call MSG_TOOL,xsltproc $(notdir $(firstword $(filter %.xsl,$^))),,$(filter %.xml,$^),$(patsubst %.ts,%,$@))
+ $(QUIET)$(APPEND) -tn "$@" \
+ '/* Autogenerated by $<, do not edit! */' \
+ '' \
+ '#ifndef ___VBoxManageBuiltInHelp_h___' \
+ '#define ___VBoxManageBuiltInHelp_h___' \
+ '' \
+ '#include <iprt/message.h>' \
+ '#include <iprt/assertcompile.h>' \
+ '' \
+ 'RT_C_DECLS_BEGIN' \
+ '' \
+ 'typedef enum HELP_CMD_VBOXMANAGE' \
+ '{' \
+ ' HELP_CMD_VBOXMANAGE_INVALID = 0,'
+ $(foreach refentry,$(filter %.xml,$^) \
+ ,$(NLTAB)$(QUIET)$(call VBOX_XSLTPROC_WITH_CAT, -a+to "$@") \
+ --stringparam 'g_sMode' 'cmd' $< $(refentry))
+ $(QUIET)$(APPEND) -n "$@" \
+ ' HELP_CMD_VBOXMANAGE_END' \
+ '} HELP_CMD_VBOXMANAGE;'
+ $(foreach refentry,$(filter %.xml,$^) \
+ ,$(NLTAB)$(QUIET)$(call VBOX_XSLTPROC_WITH_CAT, -a+to "$@") \
+ --stringparam 'g_sMode' 'subcmd' $< $(refentry))
+ $(QUIET)$(APPEND) -n "$@" \
+ '' \
+ 'typedef struct HELP_LANG_ENTRY_T' \
+ '{' \
+ ' const char *pszLang;' \
+ ' size_t cchLang;' \
+ ' PCRTMSGREFENTRY *papHelpEntries;' \
+ ' uint32_t const *pcHelpEntries;' \
+ '} HELP_LANG_ENTRY_T;' \
+ 'typedef HELP_LANG_ENTRY_T const *PCHELP_LANG_ENTRY_T;' \
+ '' \
+ 'extern HELP_LANG_ENTRY_T const g_aHelpLangEntries[];' \
+ 'extern const uint32_t g_cHelpLangEntries;' \
+ '' \
+ 'extern PCHELP_LANG_ENTRY_T volatile g_pHelpLangEntry;' \
+ '' \
+ 'RT_C_DECLS_END' \
+ '' \
+ '#endif' \
+ ''
+ $(QUIET)$(CP) --changed -- "$@" "$(patsubst %.ts,%,$@)"
+
+ifdef VBOX_WITH_VBOXMANAGE_NLS
+ VBoxManage_BLDDIRS += \
+ $(addprefix $(VBoxManage_0_OUTDIR)/,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES))
+
+ VBoxManage_SOURCES += \
+ $(foreach lang, $(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ , $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_$(lang).cpp)
+
+ VBoxManage_CLEAN += \
+ $(foreach lang,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES), \
+ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/, \
+ $(VBOX_XML_XREF_TO_TEXT) \
+ $(VBOX_XML_XREF_TO_TEXT).cat \
+ )) \
+ $(addsuffix .cpp,$(addprefix $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES))) \
+ $(addsuffix .cpp.ts,$(addprefix $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp_,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES))) \
+ $(foreach file, $(filter man_VBoxManage-%,$(VBOX_MANUAL_XML_REFENTRY_FILES)) \
+ , $(addsuffix /$(file),$(addprefix $(VBoxManage_0_OUTDIR)/,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES))))
+
+ # Preprocess the xml files, applying remarks.
+ $(foreach lang, $(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ , $(foreach file,$(filter man_VBoxManage-%,$(VBOX_MANUAL_XML_REFENTRY_FILES)) \
+ , $(evalcall2 def_vbox_refentry_preprocess_for_manpage,$(VBoxManage_0_OUTDIR)/$(lang),$(file) \
+ ,$(VBOX_PATH_MANUAL_SRC)/$(lang)/$(file),replace-xrefs,$(lang))))
+
+ # Generate the .cpp file.
+ $(foreach lang, $(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ , $(evalcall2 def_vbox_man_generate_cpp_help,$(VBoxManage_0_OUTDIR)/$(lang),$(lang)))
+
+ # Ensure $(lang) subfolder in the $(VBOX_PATH_MANUAL_OUTBASE) is created (for section names file)
+ BLDDIRS += $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/,$(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES))
+
+ # Generate sections names file for $(lang)
+ $(foreach lang, $(VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES) \
+ , $(evalcall2 def_vbox_xref_to_text,$(lang)))
+
+endif
+
+include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
new file mode 100644
index 00000000..f290fb57
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
@@ -0,0 +1,2114 @@
+/* $Id: VBoxInternalManage.cpp $ */
+/** @file
+ * VBoxManage - The 'internalcommands' command.
+ *
+ * VBoxInternalManage used to be a second CLI for doing special tricks,
+ * not intended for general usage, only for assisting VBox developers.
+ * It is now integrated into VBoxManage.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+
+#include <VBox/com/VirtualBox.h>
+
+#include <VBox/vd.h>
+#include <VBox/sup.h>
+#include <VBox/log.h>
+#include <VBox/version.h>
+
+#include <iprt/buildconfig.h>
+#include <iprt/ctype.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/uuid.h>
+#include <iprt/sha.h>
+
+#include "VBoxManage.h"
+
+/* Includes for the raw disk stuff. */
+#ifdef RT_OS_WINDOWS
+# include <iprt/win/windows.h>
+# include <winioctl.h>
+#elif defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) \
+ || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+# include <errno.h>
+# include <sys/ioctl.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+#endif
+#ifdef RT_OS_LINUX
+# include <sys/utsname.h>
+# include <linux/hdreg.h>
+# include <linux/fs.h>
+# include <stdlib.h> /* atoi() */
+#endif /* RT_OS_LINUX */
+#ifdef RT_OS_DARWIN
+# include <sys/disk.h>
+#endif /* RT_OS_DARWIN */
+#ifdef RT_OS_SOLARIS
+# include <stropts.h>
+# include <sys/dkio.h>
+# include <sys/vtoc.h>
+#endif /* RT_OS_SOLARIS */
+#ifdef RT_OS_FREEBSD
+# include <sys/disk.h>
+#endif /* RT_OS_FREEBSD */
+
+using namespace com;
+
+
+/** Macro for checking whether a partition is of extended type or not. */
+#define PARTTYPE_IS_EXTENDED(x) ((x) == 0x05 || (x) == 0x0f || (x) == 0x85)
+
+/** Maximum number of partitions we can deal with.
+ * Ridiculously large number, but the memory consumption is rather low so who
+ * cares about never using most entries. */
+#define HOSTPARTITION_MAX 100
+
+DECLARE_TRANSLATION_CONTEXT(Internal);
+
+
+typedef struct HOSTPARTITION
+{
+ /** partition number */
+ unsigned uIndex;
+ /** partition number (internal only, windows specific numbering) */
+ unsigned uIndexWin;
+ /** partition type */
+ unsigned uType;
+ /** CHS/cylinder of the first sector */
+ unsigned uStartCylinder;
+ /** CHS/head of the first sector */
+ unsigned uStartHead;
+ /** CHS/head of the first sector */
+ unsigned uStartSector;
+ /** CHS/cylinder of the last sector */
+ unsigned uEndCylinder;
+ /** CHS/head of the last sector */
+ unsigned uEndHead;
+ /** CHS/sector of the last sector */
+ unsigned uEndSector;
+ /** start sector of this partition relative to the beginning of the hard
+ * disk or relative to the beginning of the extended partition table */
+ uint64_t uStart;
+ /** numer of sectors of the partition */
+ uint64_t uSize;
+ /** start sector of this partition _table_ */
+ uint64_t uPartDataStart;
+ /** numer of sectors of this partition _table_ */
+ uint64_t cPartDataSectors;
+} HOSTPARTITION, *PHOSTPARTITION;
+
+typedef struct HOSTPARTITIONS
+{
+ /** partitioning type - MBR or GPT */
+ VDISKPARTTYPE uPartitioningType;
+ unsigned cPartitions;
+ HOSTPARTITION aPartitions[HOSTPARTITION_MAX];
+} HOSTPARTITIONS, *PHOSTPARTITIONS;
+
+
+/** @name Syntax diagram category, i.e. the command.
+ * @{ */
+typedef enum
+{
+ USAGE_INVALID = 0,
+ USAGE_I_LOADSYMS,
+ USAGE_I_LOADMAP,
+ USAGE_I_SETHDUUID,
+ USAGE_I_LISTPARTITIONS,
+ USAGE_I_CREATERAWVMDK,
+ USAGE_I_MODINSTALL,
+ USAGE_I_MODUNINSTALL,
+ USAGE_I_RENAMEVMDK,
+ USAGE_I_CONVERTTORAW,
+ USAGE_I_CONVERTHD,
+ USAGE_I_DUMPHDINFO,
+ USAGE_I_DEBUGLOG,
+ USAGE_I_SETHDPARENTUUID,
+ USAGE_I_PASSWORDHASH,
+ USAGE_I_GUESTSTATS,
+ USAGE_I_REPAIRHD,
+ USAGE_I_ALL
+} USAGECATEGORY;
+/** @} */
+
+
+/**
+ * Print the usage info.
+ */
+static void printUsageInternal(USAGECATEGORY enmCommand, PRTSTREAM pStrm)
+{
+ Assert(enmCommand != USAGE_INVALID);
+ RTStrmPrintf(pStrm,
+ Internal::tr(
+ "Usage: VBoxManage internalcommands <command> [command arguments]\n"
+ "\n"
+ "Commands:\n"
+ "\n"
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+ "WARNING: This is a development tool and should only be used to analyse\n"
+ " problems. It is completely unsupported and will change in\n"
+ " incompatible ways without warning.\n"),
+
+ (enmCommand == USAGE_I_LOADMAP || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " loadmap <vmname|uuid> <symfile> <address> [module] [subtrahend] [segment]\n"
+ " This will instruct DBGF to load the given map file\n"
+ " during initialization. (See also loadmap in the debugger.)\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_LOADSYMS || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " loadsyms <vmname|uuid> <symfile> [delta] [module] [module address]\n"
+ " This will instruct DBGF to load the given symbol file\n"
+ " during initialization.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_SETHDUUID || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " sethduuid <filepath> [<uuid>]\n"
+ " Assigns a new UUID to the given image file. This way, multiple copies\n"
+ " of a container can be registered.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_SETHDPARENTUUID || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " sethdparentuuid <filepath> <uuid>\n"
+ " Assigns a new parent UUID to the given image file.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_DUMPHDINFO || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " dumphdinfo <filepath>\n"
+ " Prints information about the image at the given location.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_LISTPARTITIONS || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " listpartitions -rawdisk <diskname>\n"
+ " Lists all partitions on <diskname>.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_CREATERAWVMDK || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " createrawvmdk --filename <filename> --rawdisk <diskname>\n"
+ " [--partitions <list of partition numbers> [--mbr <filename>] ]\n"
+ " [--relative]\n"
+ " Creates a new VMDK image which gives direct access to a physical hard\n"
+ " disk on the host. The entire disk can be presented to the guest or\n"
+ " just specific partitions specified using the --partitions parameter.\n"
+ " If access to individual partitions is granted, then the --mbr parameter\n"
+ " can be used to specify an alternative Master Boot Record (MBR) (note\n"
+ " that the partitioning information in the MBR file is ignored). The\n"
+ " format of the diskname argument for the --rawdisk parameter varies by\n"
+ " platform but can be determined using the command:\n"
+ " VBoxManage list hostdrives\n"
+ " The output lists the available drives and their partitions along with\n"
+ " their partition types and sizes.\n"
+ " On Linux, FreeBSD, and Windows hosts the --relative parameter creates a\n"
+ " VMDK image file which references the specified individual partitions\n"
+ " directly instead of referencing the partitions by their offset from\n"
+ " the start of the physical disk.\n"
+ "\n"
+ " Nota Bene: The 'createrawvdk' subcommand is deprecated. The equivalent\n"
+ " functionality is available using the 'VBoxManage createmedium' command\n"
+ " and should be used instead. See 'VBoxManage help createmedium' for\n"
+ " details.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_RENAMEVMDK || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " renamevmdk -from <filename> -to <filename>\n"
+ " Renames an existing VMDK image, including the base file and all its extents.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_CONVERTTORAW || enmCommand == USAGE_I_ALL)
+#ifdef ENABLE_CONVERT_RAW_TO_STDOUT
+ ? Internal::tr(
+ " converttoraw [-format <fileformat>] <filename> <outputfile>|stdout"
+ "\n"
+ " Convert image to raw, writing to file or stdout.\n"
+ "\n")
+#else
+ ? Internal::tr(
+ " converttoraw [-format <fileformat>] <filename> <outputfile>"
+ "\n"
+ " Convert image to raw, writing to file.\n"
+ "\n")
+#endif
+ : "",
+ (enmCommand == USAGE_I_CONVERTHD || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " converthd [-srcformat VDI|VMDK|VHD|RAW]\n"
+ " [-dstformat VDI|VMDK|VHD|RAW]\n"
+ " <inputfile> <outputfile>\n"
+ " converts hard disk images between formats\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_REPAIRHD || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " repairhd [-dry-run]\n"
+ " [-format VDI|VMDK|VHD|...]\n"
+ " <filename>\n"
+ " Tries to repair corrupted disk images\n"
+ "\n")
+ : "",
+#ifdef RT_OS_WINDOWS
+ (enmCommand == USAGE_I_MODINSTALL || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " modinstall\n"
+ " Installs the necessary driver for the host OS\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_MODUNINSTALL || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " moduninstall\n"
+ " Deinstalls the driver\n"
+ "\n")
+ : "",
+#else
+ "",
+ "",
+#endif
+ (enmCommand == USAGE_I_DEBUGLOG || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " debuglog <vmname|uuid> [--enable|--disable] [--flags todo]\n"
+ " [--groups todo] [--destinations todo]\n"
+ " Controls debug logging.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_PASSWORDHASH || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " passwordhash <password>\n"
+ " Generates a password hash.\n"
+ "\n")
+ : "",
+ (enmCommand == USAGE_I_GUESTSTATS || enmCommand == USAGE_I_ALL)
+ ? Internal::tr(
+ " gueststats <vmname|uuid> [--interval <seconds>]\n"
+ " Obtains and prints internal guest statistics.\n"
+ " Sets the update interval if specified.\n"
+ "\n")
+ : ""
+ );
+}
+
+
+/**
+ * Print a usage synopsis and the syntax error message.
+ * @returns RTEXITCODE_SYNTAX.
+ */
+static RTEXITCODE errorSyntaxInternal(USAGECATEGORY enmCommand, const char *pszFormat, ...)
+{
+ va_list args;
+ showLogo(g_pStdErr); // show logo even if suppressed
+
+ printUsageInternal(enmCommand, g_pStdErr);
+
+ va_start(args, pszFormat);
+ RTStrmPrintf(g_pStdErr, Internal::tr("\nSyntax error: %N\n"), pszFormat, &args);
+ va_end(args);
+ return RTEXITCODE_SYNTAX;
+}
+
+
+/**
+ * errorSyntaxInternal for RTGetOpt users.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ *
+ * @param enmCommand The command.
+ * @param vrc The RTGetOpt return code.
+ * @param pValueUnion The value union.
+ */
+static RTEXITCODE errorGetOptInternal(USAGECATEGORY enmCommand, int vrc, union RTGETOPTUNION const *pValueUnion)
+{
+ /*
+ * Check if it is an unhandled standard option.
+ */
+ if (vrc == 'V')
+ {
+ RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
+ return RTEXITCODE_SUCCESS;
+ }
+
+ if (vrc == 'h')
+ {
+ showLogo(g_pStdErr);
+ printUsageInternal(enmCommand, g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ /*
+ * General failure.
+ */
+ showLogo(g_pStdErr); // show logo even if suppressed
+
+ printUsageInternal(enmCommand, g_pStdErr);
+
+ if (vrc == VINF_GETOPT_NOT_OPTION)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Internal::tr("Invalid parameter '%s'"), pValueUnion->psz);
+ if (vrc > 0)
+ {
+ if (RT_C_IS_PRINT(vrc))
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Internal::tr("Invalid option -%c"), vrc);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Internal::tr("Invalid option case %i"), vrc);
+ }
+ if (vrc == VERR_GETOPT_UNKNOWN_OPTION)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Internal::tr("Unknown option: %s"), pValueUnion->psz);
+ if (vrc == VERR_GETOPT_INVALID_ARGUMENT_FORMAT)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Internal::tr("Invalid argument format: %s"), pValueUnion->psz);
+ if (pValueUnion->pDef)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%s: %Rrs", pValueUnion->pDef->pszLong, vrc);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%Rrs", vrc);
+}
+
+
+/**
+ * Externally visible wrapper around printUsageInternal() to dump the
+ * complete usage text.
+ *
+ * @param pStrm The stream to dump the usage text to.
+ */
+DECLHIDDEN(void) printUsageInternalCmds(PRTSTREAM pStrm)
+{
+ printUsageInternal(USAGE_I_ALL, pStrm);
+}
+
+
+/** @todo this is no longer necessary, we can enumerate extra data */
+/**
+ * Finds a new unique key name.
+ *
+ * I don't think this is 100% race condition proof, but we assumes
+ * the user is not trying to push this point.
+ *
+ * @returns Result from the insert.
+ * @param pMachine The Machine object.
+ * @param pszKeyBase The base key.
+ * @param rKey Reference to the string object in which we will return the key.
+ */
+static HRESULT NewUniqueKey(ComPtr<IMachine> pMachine, const char *pszKeyBase, Utf8Str &rKey)
+{
+ Bstr KeyBase(pszKeyBase);
+ Bstr Keys;
+ HRESULT hrc = pMachine->GetExtraData(KeyBase.raw(), Keys.asOutParam());
+ if (FAILED(hrc))
+ return hrc;
+
+ /* if there are no keys, it's simple. */
+ if (Keys.isEmpty())
+ {
+ rKey = "1";
+ return pMachine->SetExtraData(KeyBase.raw(), Bstr(rKey).raw());
+ }
+
+ /* find a unique number - brute force rulez. */
+ Utf8Str KeysUtf8(Keys);
+ const char *pszKeys = RTStrStripL(KeysUtf8.c_str());
+ for (unsigned i = 1; i < 1000000; i++)
+ {
+ char szKey[32];
+ size_t cchKey = RTStrPrintf(szKey, sizeof(szKey), "%#x", i);
+ const char *psz = strstr(pszKeys, szKey);
+ while (psz)
+ {
+ if ( ( psz == pszKeys
+ || psz[-1] == ' ')
+ && ( psz[cchKey] == ' '
+ || !psz[cchKey])
+ )
+ break;
+ psz = strstr(psz + cchKey, szKey);
+ }
+ if (!psz)
+ {
+ rKey = szKey;
+ Utf8StrFmt NewKeysUtf8("%s %s", pszKeys, szKey);
+ return pMachine->SetExtraData(KeyBase.raw(),
+ Bstr(NewKeysUtf8).raw());
+ }
+ }
+ RTMsgError(Internal::tr("Cannot find unique key for '%s'!"), pszKeyBase);
+ return E_FAIL;
+}
+
+
+#if 0
+/**
+ * Remove a key.
+ *
+ * I don't think this isn't 100% race condition proof, but we assumes
+ * the user is not trying to push this point.
+ *
+ * @returns Result from the insert.
+ * @param pMachine The machine object.
+ * @param pszKeyBase The base key.
+ * @param pszKey The key to remove.
+ */
+static HRESULT RemoveKey(ComPtr<IMachine> pMachine, const char *pszKeyBase, const char *pszKey)
+{
+ Bstr Keys;
+ HRESULT hrc = pMachine->GetExtraData(Bstr(pszKeyBase), Keys.asOutParam());
+ if (FAILED(hrc))
+ return hrc;
+
+ /* if there are no keys, it's simple. */
+ if (Keys.isEmpty())
+ return S_OK;
+
+ char *pszKeys;
+ int vrc = RTUtf16ToUtf8(Keys.raw(), &pszKeys);
+ if (RT_SUCCESS(vrc))
+ {
+ /* locate it */
+ size_t cchKey = strlen(pszKey);
+ char *psz = strstr(pszKeys, pszKey);
+ while (psz)
+ {
+ if ( ( psz == pszKeys
+ || psz[-1] == ' ')
+ && ( psz[cchKey] == ' '
+ || !psz[cchKey])
+ )
+ break;
+ psz = strstr(psz + cchKey, pszKey);
+ }
+ if (psz)
+ {
+ /* remove it */
+ char *pszNext = RTStrStripL(psz + cchKey);
+ if (*pszNext)
+ memmove(psz, pszNext, strlen(pszNext) + 1);
+ else
+ *psz = '\0';
+ psz = RTStrStrip(pszKeys);
+
+ /* update */
+ hrc = pMachine->SetExtraData(Bstr(pszKeyBase), Bstr(psz));
+ }
+
+ RTStrFree(pszKeys);
+ return hrc;
+ }
+ else
+ RTMsgError(Internal::tr("Failed to delete key '%s' from '%s', string conversion error %Rrc!"),
+ pszKey, pszKeyBase, vrc);
+
+ return E_FAIL;
+}
+#endif
+
+
+/**
+ * Sets a key value, does necessary error bitching.
+ *
+ * @returns COM status code.
+ * @param pMachine The Machine object.
+ * @param pszKeyBase The key base.
+ * @param pszKey The key.
+ * @param pszAttribute The attribute name.
+ * @param pszValue The string value.
+ */
+static HRESULT SetString(ComPtr<IMachine> pMachine, const char *pszKeyBase, const char *pszKey, const char *pszAttribute, const char *pszValue)
+{
+ HRESULT hrc = pMachine->SetExtraData(BstrFmt("%s/%s/%s", pszKeyBase,
+ pszKey, pszAttribute).raw(),
+ Bstr(pszValue).raw());
+ if (FAILED(hrc))
+ RTMsgError(Internal::tr("Failed to set '%s/%s/%s' to '%s'! hrc=%#x"),
+ pszKeyBase, pszKey, pszAttribute, pszValue, hrc);
+ return hrc;
+}
+
+
+/**
+ * Sets a key value, does necessary error bitching.
+ *
+ * @returns COM status code.
+ * @param pMachine The Machine object.
+ * @param pszKeyBase The key base.
+ * @param pszKey The key.
+ * @param pszAttribute The attribute name.
+ * @param u64Value The value.
+ */
+static HRESULT SetUInt64(ComPtr<IMachine> pMachine, const char *pszKeyBase, const char *pszKey, const char *pszAttribute, uint64_t u64Value)
+{
+ char szValue[64];
+ RTStrPrintf(szValue, sizeof(szValue), "%#RX64", u64Value);
+ return SetString(pMachine, pszKeyBase, pszKey, pszAttribute, szValue);
+}
+
+
+/**
+ * Sets a key value, does necessary error bitching.
+ *
+ * @returns COM status code.
+ * @param pMachine The Machine object.
+ * @param pszKeyBase The key base.
+ * @param pszKey The key.
+ * @param pszAttribute The attribute name.
+ * @param i64Value The value.
+ */
+static HRESULT SetInt64(ComPtr<IMachine> pMachine, const char *pszKeyBase, const char *pszKey, const char *pszAttribute, int64_t i64Value)
+{
+ char szValue[64];
+ RTStrPrintf(szValue, sizeof(szValue), "%RI64", i64Value);
+ return SetString(pMachine, pszKeyBase, pszKey, pszAttribute, szValue);
+}
+
+
+/**
+ * Identical to the 'loadsyms' command.
+ */
+static RTEXITCODE CmdLoadSyms(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aSession);
+ HRESULT hrc;
+
+ /*
+ * Get the VM
+ */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /*
+ * Parse the command.
+ */
+ const char *pszFilename;
+ int64_t offDelta = 0;
+ const char *pszModule = NULL;
+ uint64_t ModuleAddress = UINT64_MAX;
+ uint64_t ModuleSize = 0;
+
+ /* filename */
+ if (argc < 2)
+ return errorArgument(Internal::tr("Missing the filename argument!\n"));
+ pszFilename = argv[1];
+
+ /* offDelta */
+ if (argc >= 3)
+ {
+ int vrc = RTStrToInt64Ex(argv[2], NULL, 0, &offDelta);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read delta '%s', vrc=%Rrc\n"), argv[2], vrc);
+ }
+
+ /* pszModule */
+ if (argc >= 4)
+ pszModule = argv[3];
+
+ /* ModuleAddress */
+ if (argc >= 5)
+ {
+ int vrc = RTStrToUInt64Ex(argv[4], NULL, 0, &ModuleAddress);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read module address '%s', vrc=%Rrc\n"), argv[4], vrc);
+ }
+
+ /* ModuleSize */
+ if (argc >= 6)
+ {
+ int vrc = RTStrToUInt64Ex(argv[5], NULL, 0, &ModuleSize);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read module size '%s', vrc=%Rrc\n"), argv[5], vrc);
+ }
+
+ /*
+ * Add extra data.
+ */
+ Utf8Str KeyStr;
+ hrc = NewUniqueKey(machine, "VBoxInternal/DBGF/loadsyms", KeyStr);
+ if (SUCCEEDED(hrc))
+ hrc = SetString(machine, "VBoxInternal/DBGF/loadsyms", KeyStr.c_str(), "Filename", pszFilename);
+ if (SUCCEEDED(hrc) && argc >= 3)
+ hrc = SetInt64(machine, "VBoxInternal/DBGF/loadsyms", KeyStr.c_str(), "Delta", offDelta);
+ if (SUCCEEDED(hrc) && argc >= 4)
+ hrc = SetString(machine, "VBoxInternal/DBGF/loadsyms", KeyStr.c_str(), "Module", pszModule);
+ if (SUCCEEDED(hrc) && argc >= 5)
+ hrc = SetUInt64(machine, "VBoxInternal/DBGF/loadsyms", KeyStr.c_str(), "ModuleAddress", ModuleAddress);
+ if (SUCCEEDED(hrc) && argc >= 6)
+ hrc = SetUInt64(machine, "VBoxInternal/DBGF/loadsyms", KeyStr.c_str(), "ModuleSize", ModuleSize);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Identical to the 'loadmap' command.
+ */
+static RTEXITCODE CmdLoadMap(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aSession);
+ HRESULT hrc;
+
+ /*
+ * Get the VM
+ */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /*
+ * Parse the command.
+ */
+ const char *pszFilename;
+ uint64_t ModuleAddress = UINT64_MAX;
+ const char *pszModule = NULL;
+ uint64_t offSubtrahend = 0;
+ uint32_t iSeg = UINT32_MAX;
+
+ /* filename */
+ if (argc < 2)
+ return errorArgument(Internal::tr("Missing the filename argument!\n"));
+ pszFilename = argv[1];
+
+ /* address */
+ if (argc < 3)
+ return errorArgument(Internal::tr("Missing the module address argument!\n"));
+ int vrc = RTStrToUInt64Ex(argv[2], NULL, 0, &ModuleAddress);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read module address '%s', vrc=%Rrc\n"), argv[2], vrc);
+
+ /* name (optional) */
+ if (argc > 3)
+ pszModule = argv[3];
+
+ /* subtrahend (optional) */
+ if (argc > 4)
+ {
+ vrc = RTStrToUInt64Ex(argv[4], NULL, 0, &offSubtrahend);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read subtrahend '%s', vrc=%Rrc\n"), argv[4], vrc);
+ }
+
+ /* segment (optional) */
+ if (argc > 5)
+ {
+ vrc = RTStrToUInt32Ex(argv[5], NULL, 0, &iSeg);
+ if (RT_FAILURE(vrc))
+ return errorArgument(argv[0], Internal::tr("Failed to read segment number '%s', vrc=%Rrc\n"), argv[5], vrc);
+ }
+
+ /*
+ * Add extra data.
+ */
+ Utf8Str KeyStr;
+ hrc = NewUniqueKey(machine, "VBoxInternal/DBGF/loadmap", KeyStr);
+ if (SUCCEEDED(hrc))
+ hrc = SetString(machine, "VBoxInternal/DBGF/loadmap", KeyStr.c_str(), "Filename", pszFilename);
+ if (SUCCEEDED(hrc))
+ hrc = SetUInt64(machine, "VBoxInternal/DBGF/loadmap", KeyStr.c_str(), "Address", ModuleAddress);
+ if (SUCCEEDED(hrc) && pszModule != NULL)
+ hrc = SetString(machine, "VBoxInternal/DBGF/loadmap", KeyStr.c_str(), "Name", pszModule);
+ if (SUCCEEDED(hrc) && offSubtrahend != 0)
+ hrc = SetUInt64(machine, "VBoxInternal/DBGF/loadmap", KeyStr.c_str(), "Subtrahend", offSubtrahend);
+ if (SUCCEEDED(hrc) && iSeg != UINT32_MAX)
+ hrc = SetUInt64(machine, "VBoxInternal/DBGF/loadmap", KeyStr.c_str(), "Segment", iSeg);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static DECLCALLBACK(void) handleVDError(void *pvUser, int vrc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+ RT_NOREF(pvUser);
+ RTMsgErrorV(pszFormat, va);
+ RTMsgError(Internal::tr("Error code %Rrc at %s(%u) in function %s"), vrc, RT_SRC_POS_ARGS);
+}
+
+static DECLCALLBACK(int) handleVDMessage(void *pvUser, const char *pszFormat, va_list va)
+{
+ NOREF(pvUser);
+ return RTPrintfV(pszFormat, va);
+}
+
+static RTEXITCODE CmdSetHDUUID(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Guid uuid;
+ RTUUID rtuuid;
+ enum eUuidType {
+ HDUUID,
+ HDPARENTUUID
+ } uuidType;
+
+ if (!strcmp(argv[0], "sethduuid"))
+ {
+ uuidType = HDUUID;
+ if (argc != 3 && argc != 2)
+ return errorSyntaxInternal(USAGE_I_SETHDUUID, Internal::tr("Not enough parameters"));
+ /* if specified, take UUID, otherwise generate a new one */
+ if (argc == 3)
+ {
+ if (RT_FAILURE(RTUuidFromStr(&rtuuid, argv[2])))
+ return errorSyntaxInternal(USAGE_I_SETHDUUID, Internal::tr("Invalid UUID parameter"));
+ uuid = argv[2];
+ } else
+ uuid.create();
+ }
+ else if (!strcmp(argv[0], "sethdparentuuid"))
+ {
+ uuidType = HDPARENTUUID;
+ if (argc != 3)
+ return errorSyntaxInternal(USAGE_I_SETHDPARENTUUID, Internal::tr("Not enough parameters"));
+ if (RT_FAILURE(RTUuidFromStr(&rtuuid, argv[2])))
+ return errorSyntaxInternal(USAGE_I_SETHDPARENTUUID, Internal::tr("Invalid UUID parameter"));
+ uuid = argv[2];
+ }
+ else
+ return errorSyntaxInternal(USAGE_I_SETHDUUID, Internal::tr("Invalid invocation"));
+
+ /* just try it */
+ char *pszFormat = NULL;
+ VDTYPE enmType = VDTYPE_INVALID;
+ int vrc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */, argv[1], VDTYPE_INVALID, &pszFormat, &enmType);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Format autodetect failed: %Rrc"), vrc);
+
+ PVDISK pDisk = NULL;
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ vrc = VDCreate(pVDIfs, enmType, &pDisk);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot create the virtual disk container: %Rrc"), vrc);
+
+ /* Open the image */
+ vrc = VDOpen(pDisk, pszFormat, argv[1], VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_INFO, NULL);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot open the image: %Rrc"), vrc);
+
+ if (uuidType == HDUUID)
+ vrc = VDSetUuid(pDisk, VD_LAST_IMAGE, uuid.raw());
+ else
+ vrc = VDSetParentUuid(pDisk, VD_LAST_IMAGE, uuid.raw());
+ if (RT_FAILURE(vrc))
+ RTMsgError(Internal::tr("Cannot set a new UUID: %Rrc"), vrc);
+ else
+ RTPrintf(Internal::tr("UUID changed to: %s\n"), uuid.toString().c_str());
+
+ VDCloseAll(pDisk);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static RTEXITCODE CmdDumpHDInfo(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+
+ /* we need exactly one parameter: the image file */
+ if (argc != 1)
+ {
+ return errorSyntaxInternal(USAGE_I_DUMPHDINFO, Internal::tr("Not enough parameters"));
+ }
+
+ /* just try it */
+ char *pszFormat = NULL;
+ VDTYPE enmType = VDTYPE_INVALID;
+ int vrc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */, argv[0], VDTYPE_INVALID, &pszFormat, &enmType);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Format autodetect failed: %Rrc"), vrc);
+
+ PVDISK pDisk = NULL;
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ vrc = VDCreate(pVDIfs, enmType, &pDisk);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot create the virtual disk container: %Rrc"), vrc);
+
+ /* Open the image */
+ vrc = VDOpen(pDisk, pszFormat, argv[0], VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO, NULL);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot open the image: %Rrc"), vrc);
+
+ VDDumpImages(pDisk);
+
+ VDCloseAll(pDisk);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static int partRead(RTFILE File, PHOSTPARTITIONS pPart)
+{
+ uint8_t aBuffer[512];
+ uint8_t partitionTableHeader[512];
+ uint32_t sector_size = 512;
+ uint64_t lastUsableLBA = 0;
+
+ VDISKPARTTYPE partitioningType;
+
+ pPart->cPartitions = 0;
+ memset(pPart->aPartitions, '\0', sizeof(pPart->aPartitions));
+
+ int vrc = RTFileReadAt(File, 0, &aBuffer, sizeof(aBuffer), NULL);
+ if (RT_FAILURE(vrc))
+ return vrc;
+
+ if (aBuffer[450] == 0xEE)/* check the sign of the GPT disk*/
+ {
+ partitioningType = VDISKPARTTYPE_GPT;
+ pPart->uPartitioningType = VDISKPARTTYPE_GPT;//partitioningType;
+
+ if (aBuffer[510] != 0x55 || aBuffer[511] != 0xaa)
+ return VERR_INVALID_PARAMETER;
+
+ vrc = RTFileReadAt(File, sector_size, &partitionTableHeader, sector_size, NULL);
+ if (RT_SUCCESS(vrc))
+ {
+ /** @todo r=bird: This is a 64-bit magic value, right... */
+ const char *l_ppth = (char *)partitionTableHeader;
+ if (strncmp(l_ppth, "EFI PART", 8))
+ return VERR_INVALID_PARAMETER;
+
+ /** @todo check GPT Version */
+
+ /** @todo r=bird: C have this handy concept called structures which
+ * greatly simplify data access... (Someone is really lazy here!) */
+#if 0 /* unused */
+ uint64_t firstUsableLBA = RT_MAKE_U64_FROM_U8(partitionTableHeader[40],
+ partitionTableHeader[41],
+ partitionTableHeader[42],
+ partitionTableHeader[43],
+ partitionTableHeader[44],
+ partitionTableHeader[45],
+ partitionTableHeader[46],
+ partitionTableHeader[47]
+ );
+#endif
+ lastUsableLBA = RT_MAKE_U64_FROM_U8(partitionTableHeader[48],
+ partitionTableHeader[49],
+ partitionTableHeader[50],
+ partitionTableHeader[51],
+ partitionTableHeader[52],
+ partitionTableHeader[53],
+ partitionTableHeader[54],
+ partitionTableHeader[55]
+ );
+ uint32_t partitionsNumber = RT_MAKE_U32_FROM_U8(partitionTableHeader[80],
+ partitionTableHeader[81],
+ partitionTableHeader[82],
+ partitionTableHeader[83]
+ );
+ uint32_t partitionEntrySize = RT_MAKE_U32_FROM_U8(partitionTableHeader[84],
+ partitionTableHeader[85],
+ partitionTableHeader[86],
+ partitionTableHeader[87]
+ );
+
+ uint32_t currentEntry = 0;
+
+ if (partitionEntrySize * partitionsNumber > 4 * _1M)
+ {
+ RTMsgError(Internal::tr("The GPT header seems corrupt because it contains too many entries"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ uint8_t *pbPartTable = (uint8_t *)RTMemAllocZ(RT_ALIGN_Z(partitionEntrySize * partitionsNumber, 512));
+ if (!pbPartTable)
+ {
+ RTMsgError(Internal::tr("Allocating memory for the GPT partitions entries failed"));
+ return VERR_NO_MEMORY;
+ }
+
+ /* partition entries begin from LBA2 */
+ /** @todo r=aeichner: Reading from LBA 2 is not always correct, the header will contain the starting LBA. */
+ vrc = RTFileReadAt(File, 1024, pbPartTable, RT_ALIGN_Z(partitionEntrySize * partitionsNumber, 512), NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("Reading the partition table failed"));
+ RTMemFree(pbPartTable);
+ return vrc;
+ }
+
+ while (currentEntry < partitionsNumber)
+ {
+ uint8_t *partitionEntry = pbPartTable + currentEntry * partitionEntrySize;
+
+ uint64_t start = RT_MAKE_U64_FROM_U8(partitionEntry[32], partitionEntry[33], partitionEntry[34], partitionEntry[35],
+ partitionEntry[36], partitionEntry[37], partitionEntry[38], partitionEntry[39]);
+ uint64_t end = RT_MAKE_U64_FROM_U8(partitionEntry[40], partitionEntry[41], partitionEntry[42], partitionEntry[43],
+ partitionEntry[44], partitionEntry[45], partitionEntry[46], partitionEntry[47]);
+
+ PHOSTPARTITION pCP = &pPart->aPartitions[pPart->cPartitions++];
+ pCP->uIndex = currentEntry + 1;
+ pCP->uIndexWin = currentEntry + 1;
+ pCP->uType = 0;
+ pCP->uStartCylinder = 0;
+ pCP->uStartHead = 0;
+ pCP->uStartSector = 0;
+ pCP->uEndCylinder = 0;
+ pCP->uEndHead = 0;
+ pCP->uEndSector = 0;
+ pCP->uPartDataStart = 0; /* will be filled out later properly. */
+ pCP->cPartDataSectors = 0;
+ if (start==0 || end==0)
+ {
+ pCP->uIndex = 0;
+ pCP->uIndexWin = 0;
+ --pPart->cPartitions;
+ break;
+ }
+ else
+ {
+ pCP->uStart = start;
+ pCP->uSize = (end +1) - start;/*+1 LBA because the last address is included*/
+ }
+
+ ++currentEntry;
+ }
+
+ RTMemFree(pbPartTable);
+ }
+ }
+ else
+ {
+ partitioningType = VDISKPARTTYPE_MBR;
+ pPart->uPartitioningType = VDISKPARTTYPE_MBR;//partitioningType;
+
+ if (aBuffer[510] != 0x55 || aBuffer[511] != 0xaa)
+ return VERR_INVALID_PARAMETER;
+
+ unsigned uExtended = (unsigned)-1;
+ unsigned uIndexWin = 1;
+
+ for (unsigned i = 0; i < 4; i++)
+ {
+ uint8_t *p = &aBuffer[0x1be + i * 16];
+ if (p[4] == 0)
+ continue;
+ PHOSTPARTITION pCP = &pPart->aPartitions[pPart->cPartitions++];
+ pCP->uIndex = i + 1;
+ pCP->uType = p[4];
+ pCP->uStartCylinder = (uint32_t)p[3] + ((uint32_t)(p[2] & 0xc0) << 2);
+ pCP->uStartHead = p[1];
+ pCP->uStartSector = p[2] & 0x3f;
+ pCP->uEndCylinder = (uint32_t)p[7] + ((uint32_t)(p[6] & 0xc0) << 2);
+ pCP->uEndHead = p[5];
+ pCP->uEndSector = p[6] & 0x3f;
+ pCP->uStart = RT_MAKE_U32_FROM_U8(p[8], p[9], p[10], p[11]);
+ pCP->uSize = RT_MAKE_U32_FROM_U8(p[12], p[13], p[14], p[15]);
+ pCP->uPartDataStart = 0; /* will be filled out later properly. */
+ pCP->cPartDataSectors = 0;
+
+ if (PARTTYPE_IS_EXTENDED(p[4]))
+ {
+ if (uExtended == (unsigned)-1)
+ {
+ uExtended = (unsigned)(pCP - pPart->aPartitions);
+ pCP->uIndexWin = 0;
+ }
+ else
+ {
+ RTMsgError(Internal::tr("More than one extended partition"));
+ return VERR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ pCP->uIndexWin = uIndexWin;
+ uIndexWin++;
+ }
+ }
+
+ if (uExtended != (unsigned)-1)
+ {
+ unsigned uIndex = 5;
+ uint64_t uStart = pPart->aPartitions[uExtended].uStart;
+ uint64_t uOffset = 0;
+ if (!uStart)
+ {
+ RTMsgError(Internal::tr("Inconsistency for logical partition start"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ do
+ {
+ vrc = RTFileReadAt(File, (uStart + uOffset) * 512, &aBuffer, sizeof(aBuffer), NULL);
+ if (RT_FAILURE(vrc))
+ return vrc;
+
+ if (aBuffer[510] != 0x55 || aBuffer[511] != 0xaa)
+ {
+ RTMsgError(Internal::tr("Logical partition without magic"));
+ return VERR_INVALID_PARAMETER;
+ }
+ uint8_t *p = &aBuffer[0x1be];
+
+ if (p[4] == 0)
+ {
+ RTMsgError(Internal::tr("Logical partition with type 0 encountered"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ PHOSTPARTITION pCP = &pPart->aPartitions[pPart->cPartitions++];
+ pCP->uIndex = uIndex;
+ pCP->uIndexWin = uIndexWin;
+ pCP->uType = p[4];
+ pCP->uStartCylinder = (uint32_t)p[3] + ((uint32_t)(p[2] & 0xc0) << 2);
+ pCP->uStartHead = p[1];
+ pCP->uStartSector = p[2] & 0x3f;
+ pCP->uEndCylinder = (uint32_t)p[7] + ((uint32_t)(p[6] & 0xc0) << 2);
+ pCP->uEndHead = p[5];
+ pCP->uEndSector = p[6] & 0x3f;
+ uint32_t uStartOffset = RT_MAKE_U32_FROM_U8(p[8], p[9], p[10], p[11]);
+ if (!uStartOffset)
+ {
+ RTMsgError(Internal::tr("Invalid partition start offset"));
+ return VERR_INVALID_PARAMETER;
+ }
+ pCP->uStart = uStart + uOffset + uStartOffset;
+ pCP->uSize = RT_MAKE_U32_FROM_U8(p[12], p[13], p[14], p[15]);
+ /* Fill out partitioning location info for EBR. */
+ pCP->uPartDataStart = uStart + uOffset;
+ pCP->cPartDataSectors = uStartOffset;
+ p += 16;
+ if (p[4] == 0)
+ uExtended = (unsigned)-1;
+ else if (PARTTYPE_IS_EXTENDED(p[4]))
+ {
+ uExtended = uIndex;
+ uIndex++;
+ uIndexWin++;
+ uOffset = RT_MAKE_U32_FROM_U8(p[8], p[9], p[10], p[11]);
+ }
+ else
+ {
+ RTMsgError(Internal::tr("Logical partition chain broken"));
+ return VERR_INVALID_PARAMETER;
+ }
+ } while (uExtended != (unsigned)-1);
+ }
+ }
+
+
+ /* Sort partitions in ascending order of start sector, plus a trivial
+ * bit of consistency checking. */
+ for (unsigned i = 0; i < pPart->cPartitions-1; i++)
+ {
+ unsigned uMinIdx = i;
+ uint64_t uMinVal = pPart->aPartitions[i].uStart;
+ for (unsigned j = i + 1; j < pPart->cPartitions; j++)
+ {
+ if (pPart->aPartitions[j].uStart < uMinVal)
+ {
+ uMinIdx = j;
+ uMinVal = pPart->aPartitions[j].uStart;
+ }
+ else if (pPart->aPartitions[j].uStart == uMinVal)
+ {
+ RTMsgError(Internal::tr("Two partitions start at the same place"));
+ return VERR_INVALID_PARAMETER;
+ }
+ else if (pPart->aPartitions[j].uStart == 0)
+ {
+ RTMsgError(Internal::tr("Partition starts at sector 0"));
+ return VERR_INVALID_PARAMETER;
+ }
+ }
+ if (uMinIdx != i)
+ {
+ /* Swap entries at index i and uMinIdx. */
+ memcpy(&pPart->aPartitions[pPart->cPartitions],
+ &pPart->aPartitions[i], sizeof(HOSTPARTITION));
+ memcpy(&pPart->aPartitions[i],
+ &pPart->aPartitions[uMinIdx], sizeof(HOSTPARTITION));
+ memcpy(&pPart->aPartitions[uMinIdx],
+ &pPart->aPartitions[pPart->cPartitions], sizeof(HOSTPARTITION));
+ }
+ }
+
+ /* Fill out partitioning location info for MBR or GPT. */
+ pPart->aPartitions[0].uPartDataStart = 0;
+ pPart->aPartitions[0].cPartDataSectors = pPart->aPartitions[0].uStart;
+
+ /* Fill out partitioning location info for backup GPT. */
+ if (partitioningType == VDISKPARTTYPE_GPT)
+ {
+ pPart->aPartitions[pPart->cPartitions-1].uPartDataStart = lastUsableLBA+1;
+ pPart->aPartitions[pPart->cPartitions-1].cPartDataSectors = 33;
+
+ /* Now do a some partition table consistency checking, to reject the most
+ * obvious garbage which can lead to trouble later. */
+ uint64_t uPrevEnd = 0;
+ for (unsigned i = 0; i < pPart->cPartitions; i++)
+ {
+ if (pPart->aPartitions[i].cPartDataSectors)
+ uPrevEnd = pPart->aPartitions[i].uPartDataStart + pPart->aPartitions[i].cPartDataSectors;
+ if (pPart->aPartitions[i].uStart < uPrevEnd &&
+ pPart->cPartitions-1 != i)
+ {
+ RTMsgError(Internal::tr("Overlapping GPT partitions"));
+ return VERR_INVALID_PARAMETER;
+ }
+ }
+ }
+ else
+ {
+ /* Now do a some partition table consistency checking, to reject the most
+ * obvious garbage which can lead to trouble later. */
+ uint64_t uPrevEnd = 0;
+ for (unsigned i = 0; i < pPart->cPartitions; i++)
+ {
+ if (pPart->aPartitions[i].cPartDataSectors)
+ uPrevEnd = pPart->aPartitions[i].uPartDataStart + pPart->aPartitions[i].cPartDataSectors;
+ if (pPart->aPartitions[i].uStart < uPrevEnd)
+ {
+ RTMsgError(Internal::tr("Overlapping MBR partitions"));
+ return VERR_INVALID_PARAMETER;
+ }
+ if (!PARTTYPE_IS_EXTENDED(pPart->aPartitions[i].uType))
+ uPrevEnd = pPart->aPartitions[i].uStart + pPart->aPartitions[i].uSize;
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+static RTEXITCODE CmdListPartitions(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Utf8Str rawdisk;
+
+ /* let's have a closer look at the arguments */
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-rawdisk") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ rawdisk = argv[i];
+ }
+ else
+ {
+ return errorSyntaxInternal(USAGE_I_LISTPARTITIONS, Internal::tr("Invalid parameter '%s'"), argv[i]);
+ }
+ }
+
+ if (rawdisk.isEmpty())
+ return errorSyntaxInternal(USAGE_I_LISTPARTITIONS, Internal::tr("Mandatory parameter -rawdisk missing"));
+
+ RTFILE hRawFile;
+ int vrc = RTFileOpen(&hRawFile, rawdisk.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot open the raw disk: %Rrc"), vrc);
+
+ HOSTPARTITIONS partitions;
+ vrc = partRead(hRawFile, &partitions);
+ /* Don't bail out on errors, print the table and return the result code. */
+
+ RTPrintf(Internal::tr("Number Type StartCHS EndCHS Size (MiB) Start (Sect)\n"));
+ for (unsigned i = 0; i < partitions.cPartitions; i++)
+ {
+ /* Don't show the extended partition, otherwise users might think they
+ * can add it to the list of partitions for raw partition access. */
+ if (PARTTYPE_IS_EXTENDED(partitions.aPartitions[i].uType))
+ continue;
+
+ RTPrintf("%-7u %#04x %-4u/%-3u/%-2u %-4u/%-3u/%-2u %10llu %10llu\n",
+ partitions.aPartitions[i].uIndex,
+ partitions.aPartitions[i].uType,
+ partitions.aPartitions[i].uStartCylinder,
+ partitions.aPartitions[i].uStartHead,
+ partitions.aPartitions[i].uStartSector,
+ partitions.aPartitions[i].uEndCylinder,
+ partitions.aPartitions[i].uEndHead,
+ partitions.aPartitions[i].uEndSector,
+ partitions.aPartitions[i].uSize / 2048,
+ partitions.aPartitions[i].uStart);
+ }
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aCreateRawVMDKOptions[] =
+{
+ { "--filename", 'f', RTGETOPT_REQ_STRING },
+ { "-filename", 'f', RTGETOPT_REQ_STRING },
+ { "--rawdisk", 'd', RTGETOPT_REQ_STRING },
+ { "-rawdisk", 'd', RTGETOPT_REQ_STRING },
+ { "--partitions", 'p', RTGETOPT_REQ_STRING },
+ { "-partitions", 'p', RTGETOPT_REQ_STRING },
+ { "--mbr", 'm', RTGETOPT_REQ_STRING },
+ { "-mbr", 'm', RTGETOPT_REQ_STRING },
+#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_WINDOWS)
+ { "--relative", 'r', RTGETOPT_REQ_NOTHING },
+ { "-relative", 'r', RTGETOPT_REQ_NOTHING },
+#endif /* RT_OS_LINUX || RT_OS_FREEBSD || RT_OS_WINDOWS */
+};
+
+static RTEXITCODE CmdCreateRawVMDK(int argc, char **argv, HandlerArg *a)
+{
+ const char *pszFilename = NULL;
+ const char *pszRawdisk = NULL;
+ const char *pszPartitions = NULL;
+ const char *pszMbr = NULL;
+ bool fRelative = false;
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, g_aCreateRawVMDKOptions, RT_ELEMENTS(g_aCreateRawVMDKOptions), 0, 0);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'f': // --filename
+ pszFilename = ValueUnion.psz;
+ break;
+
+ case 'd': // --rawdisk
+ pszRawdisk = ValueUnion.psz;
+ break;
+
+ case 'p': // --partitions
+ pszPartitions = ValueUnion.psz;
+ break;
+
+ case 'm': // --mbr
+ pszMbr = ValueUnion.psz;
+ break;
+#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_WINDOWS)
+ case 'r': // --relative
+ fRelative = true;
+ break;
+#endif /* RT_OS_LINUX || RT_OS_FREEBSD || RT_OS_WINDOWS */
+
+ default:
+ return errorGetOptInternal(USAGE_I_CREATERAWVMDK, c, &ValueUnion);
+ }
+ }
+
+ if (!pszFilename || !*pszFilename)
+ return errorSyntaxInternal(USAGE_I_CREATERAWVMDK, Internal::tr("Mandatory parameter --filename missing"));
+ if (!pszRawdisk || !*pszRawdisk)
+ return errorSyntaxInternal(USAGE_I_CREATERAWVMDK, Internal::tr("Mandatory parameter --rawdisk missing"));
+ if (!pszPartitions && pszMbr)
+ return errorSyntaxInternal(USAGE_I_CREATERAWVMDK,
+ Internal::tr("The parameter --mbr is only valid when the parameter -partitions is also present"));
+
+ /* Construct the equivalent 'VBoxManage createmedium disk --variant RawDisk ...' command line. */
+ size_t cMaxArgs = 9; /* all possible 'createmedium' args based on the 'createrawvmdk' options + 1 for NULL */
+ char **papszNewArgv = (char **)RTMemAllocZ(sizeof(papszNewArgv[0]) * cMaxArgs);
+ if (!papszNewArgv)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Failed to allocate memory for argument array"));
+ int cArgs = 0;
+
+ papszNewArgv[cArgs++] = RTStrDup("disk");
+ papszNewArgv[cArgs++] = RTStrDup("--variant=RawDisk");
+ papszNewArgv[cArgs++] = RTStrDup("--format=VMDK");
+
+ for (int i = 0; i < cArgs; i++)
+ if (!papszNewArgv[i])
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Failed to allocate memory for argument array"));
+
+ if ( RTStrAPrintf(&papszNewArgv[cArgs++], "--filename=%s", pszFilename) == -1
+ || RTStrAPrintf(&papszNewArgv[cArgs++], "--property=RawDrive=%s", pszRawdisk) == -1
+ || (pszPartitions && (RTStrAPrintf(&papszNewArgv[cArgs++], "--property=Partitions=%s", pszPartitions) == -1))
+ || (pszMbr && (RTStrAPrintf(&papszNewArgv[cArgs++], "--property-filename=%s", pszMbr) == -1))
+ || (fRelative && (RTStrAPrintf(&papszNewArgv[cArgs++], "--property=Relative=%d", fRelative) == -1)))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Failed to allocate memory for argument array"));
+
+ papszNewArgv[cArgs] = NULL;
+
+ RTStrmPrintf(g_pStdErr,
+ Internal::tr("\nThe 'createrawvdk' subcommand is deprecated. The equivalent functionality is\n"
+ "available using the 'VBoxManage createmedium' command and should be used\n"
+ "instead. See 'VBoxManage help createmedium' for details.\n\n"));
+
+ a->argc = cArgs;
+ a->argv = papszNewArgv;
+ RTEXITCODE rcExit = handleCreateMedium(a);
+
+ for (int i = 0; i < cArgs; i++)
+ RTStrFree(papszNewArgv[i]);
+ RTMemFree(papszNewArgv);
+
+ return rcExit;
+}
+
+static RTEXITCODE CmdRenameVMDK(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Utf8Str src;
+ Utf8Str dst;
+ /* Parse the arguments. */
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-from") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ src = argv[i];
+ }
+ else if (strcmp(argv[i], "-to") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ dst = argv[i];
+ }
+ else
+ {
+ return errorSyntaxInternal(USAGE_I_RENAMEVMDK, Internal::tr("Invalid parameter '%s'"), argv[i]);
+ }
+ }
+
+ if (src.isEmpty())
+ return errorSyntaxInternal(USAGE_I_RENAMEVMDK, Internal::tr("Mandatory parameter -from missing"));
+ if (dst.isEmpty())
+ return errorSyntaxInternal(USAGE_I_RENAMEVMDK, Internal::tr("Mandatory parameter -to missing"));
+
+ PVDISK pDisk = NULL;
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ int vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ vrc = VDCreate(pVDIfs, VDTYPE_HDD, &pDisk);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot create the virtual disk container: %Rrc"), vrc);
+
+ vrc = VDOpen(pDisk, "VMDK", src.c_str(), VD_OPEN_FLAGS_NORMAL, NULL);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = VDCopy(pDisk, 0, pDisk, "VMDK", dst.c_str(), true, 0,
+ VD_IMAGE_FLAGS_NONE, NULL, VD_OPEN_FLAGS_NORMAL,
+ NULL, NULL, NULL);
+ if (RT_FAILURE(vrc))
+ RTMsgError(Internal::tr("Cannot rename the image: %Rrc"), vrc);
+ }
+ else
+ RTMsgError(Internal::tr("Cannot create the source image: %Rrc"), vrc);
+ VDCloseAll(pDisk);
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE CmdConvertToRaw(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Utf8Str srcformat;
+ Utf8Str src;
+ Utf8Str dst;
+ bool fWriteToStdOut = false;
+
+ /* Parse the arguments. */
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-format") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ srcformat = argv[i];
+ }
+ else if (src.isEmpty())
+ {
+ src = argv[i];
+ }
+ else if (dst.isEmpty())
+ {
+ dst = argv[i];
+#ifdef ENABLE_CONVERT_RAW_TO_STDOUT
+ if (!strcmp(argv[i], "stdout"))
+ fWriteToStdOut = true;
+#endif /* ENABLE_CONVERT_RAW_TO_STDOUT */
+ }
+ else
+ {
+ return errorSyntaxInternal(USAGE_I_CONVERTTORAW, Internal::tr("Invalid parameter '%s'"), argv[i]);
+ }
+ }
+
+ if (src.isEmpty())
+ return errorSyntaxInternal(USAGE_I_CONVERTTORAW, Internal::tr("Mandatory filename parameter missing"));
+ if (dst.isEmpty())
+ return errorSyntaxInternal(USAGE_I_CONVERTTORAW, Internal::tr("Mandatory outputfile parameter missing"));
+
+ PVDISK pDisk = NULL;
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ int vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ /** @todo Support convert to raw for floppy and DVD images too. */
+ vrc = VDCreate(pVDIfs, VDTYPE_HDD, &pDisk);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot create the virtual disk container: %Rrc"), vrc);
+
+ /* Open raw output file. */
+ RTFILE outFile;
+ vrc = VINF_SUCCESS;
+ if (fWriteToStdOut)
+ vrc = RTFileFromNative(&outFile, 1);
+ else
+ vrc = RTFileOpen(&outFile, dst.c_str(), RTFILE_O_WRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL);
+ if (RT_FAILURE(vrc))
+ {
+ VDCloseAll(pDisk);
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot create destination file \"%s\": %Rrc"),
+ dst.c_str(), vrc);
+ }
+
+ if (srcformat.isEmpty())
+ {
+ char *pszFormat = NULL;
+ VDTYPE enmType = VDTYPE_INVALID;
+ vrc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
+ src.c_str(), VDTYPE_INVALID, &pszFormat, &enmType);
+ if (RT_FAILURE(vrc) || enmType != VDTYPE_HDD)
+ {
+ VDCloseAll(pDisk);
+ if (!fWriteToStdOut)
+ {
+ RTFileClose(outFile);
+ RTFileDelete(dst.c_str());
+ }
+ if (RT_FAILURE(vrc))
+ RTMsgError(Internal::tr("No file format specified and autodetect failed - please specify format: %Rrc"),
+ vrc);
+ else
+ RTMsgError(Internal::tr("Only converting harddisk images is supported"));
+ return RTEXITCODE_FAILURE;
+ }
+ srcformat = pszFormat;
+ RTStrFree(pszFormat);
+ }
+ vrc = VDOpen(pDisk, srcformat.c_str(), src.c_str(), VD_OPEN_FLAGS_READONLY, NULL);
+ if (RT_FAILURE(vrc))
+ {
+ VDCloseAll(pDisk);
+ if (!fWriteToStdOut)
+ {
+ RTFileClose(outFile);
+ RTFileDelete(dst.c_str());
+ }
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot open the source image: %Rrc"), vrc);
+ }
+
+ uint64_t cbSize = VDGetSize(pDisk, VD_LAST_IMAGE);
+ uint64_t offFile = 0;
+#define RAW_BUFFER_SIZE _128K
+ size_t cbBuf = RAW_BUFFER_SIZE;
+ void *pvBuf = RTMemAlloc(cbBuf);
+ if (pvBuf)
+ {
+ RTStrmPrintf(g_pStdErr, Internal::tr("Converting image \"%s\" with size %RU64 bytes (%RU64MB) to raw...\n", "", cbSize),
+ src.c_str(), cbSize, (cbSize + _1M - 1) / _1M);
+ while (offFile < cbSize)
+ {
+ size_t cb = (size_t)RT_MIN(cbSize - offFile, cbBuf);
+ vrc = VDRead(pDisk, offFile, pvBuf, cb);
+ if (RT_FAILURE(vrc))
+ break;
+ vrc = RTFileWrite(outFile, pvBuf, cb, NULL);
+ if (RT_FAILURE(vrc))
+ break;
+ offFile += cb;
+ }
+ RTMemFree(pvBuf);
+ if (RT_FAILURE(vrc))
+ {
+ VDCloseAll(pDisk);
+ if (!fWriteToStdOut)
+ {
+ RTFileClose(outFile);
+ RTFileDelete(dst.c_str());
+ }
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Cannot copy image data: %Rrc"), vrc);
+ }
+ }
+ else
+ {
+ vrc = VERR_NO_MEMORY;
+ VDCloseAll(pDisk);
+ if (!fWriteToStdOut)
+ {
+ RTFileClose(outFile);
+ RTFileDelete(dst.c_str());
+ }
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Internal::tr("Out of memory allocating read buffer"));
+ }
+
+ if (!fWriteToStdOut)
+ RTFileClose(outFile);
+ VDCloseAll(pDisk);
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE CmdConvertHardDisk(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Utf8Str srcformat;
+ Utf8Str dstformat;
+ Utf8Str src;
+ Utf8Str dst;
+ int vrc;
+ PVDISK pSrcDisk = NULL;
+ PVDISK pDstDisk = NULL;
+ VDTYPE enmSrcType = VDTYPE_INVALID;
+
+ /* Parse the arguments. */
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-srcformat") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ srcformat = argv[i];
+ }
+ else if (strcmp(argv[i], "-dstformat") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ dstformat = argv[i];
+ }
+ else if (src.isEmpty())
+ {
+ src = argv[i];
+ }
+ else if (dst.isEmpty())
+ {
+ dst = argv[i];
+ }
+ else
+ {
+ return errorSyntaxInternal(USAGE_I_CONVERTHD, Internal::tr("Invalid parameter '%s'"), argv[i]);
+ }
+ }
+
+ if (src.isEmpty())
+ return errorSyntaxInternal(USAGE_I_CONVERTHD, Internal::tr("Mandatory input image parameter missing"));
+ if (dst.isEmpty())
+ return errorSyntaxInternal(USAGE_I_CONVERTHD, Internal::tr("Mandatory output image parameter missing"));
+
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ do
+ {
+ /* Try to determine input image format */
+ if (srcformat.isEmpty())
+ {
+ char *pszFormat = NULL;
+ vrc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
+ src.c_str(), VDTYPE_HDD, &pszFormat, &enmSrcType);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("No file format specified and autodetect failed - please specify format: %Rrc"),
+ vrc);
+ break;
+ }
+ srcformat = pszFormat;
+ RTStrFree(pszFormat);
+ }
+
+ vrc = VDCreate(pVDIfs, enmSrcType, &pSrcDisk);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("Cannot create the source virtual disk container: %Rrc"), vrc);
+ break;
+ }
+
+ /* Open the input image */
+ vrc = VDOpen(pSrcDisk, srcformat.c_str(), src.c_str(), VD_OPEN_FLAGS_READONLY, NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("Cannot open the source image: %Rrc"), vrc);
+ break;
+ }
+
+ /* Output format defaults to VDI */
+ if (dstformat.isEmpty())
+ dstformat = "VDI";
+
+ vrc = VDCreate(pVDIfs, enmSrcType, &pDstDisk);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("Cannot create the destination virtual disk container: %Rrc"), vrc);
+ break;
+ }
+
+ uint64_t cbSize = VDGetSize(pSrcDisk, VD_LAST_IMAGE);
+ RTStrmPrintf(g_pStdErr, Internal::tr("Converting image \"%s\" with size %RU64 bytes (%RU64MB)...\n", "", cbSize),
+ src.c_str(), cbSize, (cbSize + _1M - 1) / _1M);
+
+ /* Create the output image */
+ vrc = VDCopy(pSrcDisk, VD_LAST_IMAGE, pDstDisk, dstformat.c_str(),
+ dst.c_str(), false, 0, VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED,
+ NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL, NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Internal::tr("Cannot copy the image: %Rrc"), vrc);
+ break;
+ }
+ }
+ while (0);
+ if (pDstDisk)
+ VDCloseAll(pDstDisk);
+ if (pSrcDisk)
+ VDCloseAll(pSrcDisk);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Tries to repair a corrupted hard disk image.
+ *
+ * @returns VBox status code
+ */
+static RTEXITCODE CmdRepairHardDisk(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+ Utf8Str image;
+ Utf8Str format;
+ int vrc;
+ bool fDryRun = false;
+
+ /* Parse the arguments. */
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-dry-run") == 0)
+ {
+ fDryRun = true;
+ }
+ else if (strcmp(argv[i], "-format") == 0)
+ {
+ if (argc <= i + 1)
+ {
+ return errorArgument(Internal::tr("Missing argument to '%s'"), argv[i]);
+ }
+ i++;
+ format = argv[i];
+ }
+ else if (image.isEmpty())
+ {
+ image = argv[i];
+ }
+ else
+ {
+ return errorSyntaxInternal(USAGE_I_REPAIRHD, Internal::tr("Invalid parameter '%s'"), argv[i]);
+ }
+ }
+
+ if (image.isEmpty())
+ return errorSyntaxInternal(USAGE_I_REPAIRHD, Internal::tr("Mandatory input image parameter missing"));
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = handleVDMessage;
+
+ vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ do
+ {
+ /* Try to determine input image format */
+ if (format.isEmpty())
+ {
+ char *pszFormat = NULL;
+ VDTYPE enmSrcType = VDTYPE_INVALID;
+
+ vrc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
+ image.c_str(), VDTYPE_HDD, &pszFormat, &enmSrcType);
+ if (RT_FAILURE(vrc) && (vrc != VERR_VD_IMAGE_CORRUPTED))
+ {
+ RTMsgError(Internal::tr("No file format specified and autodetect failed - please specify format: %Rrc"),
+ vrc);
+ break;
+ }
+ format = pszFormat;
+ RTStrFree(pszFormat);
+ }
+
+ uint32_t fFlags = 0;
+ if (fDryRun)
+ fFlags |= VD_REPAIR_DRY_RUN;
+
+ vrc = VDRepair(pVDIfs, NULL, image.c_str(), format.c_str(), fFlags);
+ }
+ while (0);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Unloads the necessary driver.
+ *
+ * @returns VBox status code
+ */
+static RTEXITCODE CmdModUninstall(void)
+{
+ int vrc = SUPR3Uninstall();
+ if (RT_SUCCESS(vrc) || vrc == VERR_NOT_IMPLEMENTED)
+ return RTEXITCODE_SUCCESS;
+ return RTEXITCODE_FAILURE;
+}
+
+/**
+ * Loads the necessary driver.
+ *
+ * @returns VBox status code
+ */
+static RTEXITCODE CmdModInstall(void)
+{
+ int vrc = SUPR3Install();
+ if (RT_SUCCESS(vrc) || vrc == VERR_NOT_IMPLEMENTED)
+ return RTEXITCODE_SUCCESS;
+ return RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE CmdDebugLog(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ /*
+ * The first parameter is the name or UUID of a VM with a direct session
+ * that we wish to open.
+ */
+ if (argc < 1)
+ return errorSyntaxInternal(USAGE_I_DEBUGLOG, Internal::tr("Missing VM name/UUID"));
+
+ ComPtr<IMachine> ptrMachine;
+ HRESULT hrc;
+ CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]).raw(),
+ ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR_RET(ptrMachine, LockMachine(aSession, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /*
+ * Get the debugger interface.
+ */
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR_RET(aSession, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IMachineDebugger> ptrDebugger;
+ CHECK_ERROR_RET(ptrConsole, COMGETTER(Debugger)(ptrDebugger.asOutParam()), RTEXITCODE_FAILURE);
+
+ /*
+ * Parse the command.
+ */
+ bool fEnablePresent = false;
+ bool fEnable = false;
+ bool fFlagsPresent = false;
+ RTCString strFlags;
+ bool fGroupsPresent = false;
+ RTCString strGroups;
+ bool fDestsPresent = false;
+ RTCString strDests;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--disable", 'E', RTGETOPT_REQ_NOTHING },
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--flags", 'f', RTGETOPT_REQ_STRING },
+ { "--groups", 'g', RTGETOPT_REQ_STRING },
+ { "--destinations", 'd', RTGETOPT_REQ_STRING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (ch)
+ {
+ case 'e':
+ fEnablePresent = true;
+ fEnable = true;
+ break;
+
+ case 'E':
+ fEnablePresent = true;
+ fEnable = false;
+ break;
+
+ case 'f':
+ fFlagsPresent = true;
+ if (*ValueUnion.psz)
+ {
+ if (strFlags.isNotEmpty())
+ strFlags.append(' ');
+ strFlags.append(ValueUnion.psz);
+ }
+ break;
+
+ case 'g':
+ fGroupsPresent = true;
+ if (*ValueUnion.psz)
+ {
+ if (strGroups.isNotEmpty())
+ strGroups.append(' ');
+ strGroups.append(ValueUnion.psz);
+ }
+ break;
+
+ case 'd':
+ fDestsPresent = true;
+ if (*ValueUnion.psz)
+ {
+ if (strDests.isNotEmpty())
+ strDests.append(' ');
+ strDests.append(ValueUnion.psz);
+ }
+ break;
+
+ default:
+ return errorGetOptInternal(USAGE_I_DEBUGLOG, ch, &ValueUnion);
+ }
+ }
+
+ /*
+ * Do the job.
+ */
+ if (fEnablePresent && !fEnable)
+ CHECK_ERROR_RET(ptrDebugger, COMSETTER(LogEnabled)(FALSE), RTEXITCODE_FAILURE);
+
+ /** @todo flags, groups destination. */
+ if (fFlagsPresent || fGroupsPresent || fDestsPresent)
+ RTMsgWarning(Internal::tr("One or more of the requested features are not implemented! Feel free to do this."));
+
+ if (fEnablePresent && fEnable)
+ CHECK_ERROR_RET(ptrDebugger, COMSETTER(LogEnabled)(TRUE), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Generate a SHA-256 password hash
+ */
+static RTEXITCODE CmdGeneratePasswordHash(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ RT_NOREF(aVirtualBox, aSession);
+
+ /* one parameter, the password to hash */
+ if (argc != 1)
+ return errorSyntaxInternal(USAGE_I_PASSWORDHASH, Internal::tr("password to hash required"));
+
+ uint8_t abDigest[RTSHA256_HASH_SIZE];
+ RTSha256(argv[0], strlen(argv[0]), abDigest);
+ char pszDigest[RTSHA256_DIGEST_LEN + 1];
+ RTSha256ToString(abDigest, pszDigest, sizeof(pszDigest));
+ RTPrintf(Internal::tr("Password hash: %s\n"), pszDigest);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Print internal guest statistics or
+ * set internal guest statistics update interval if specified
+ */
+static RTEXITCODE CmdGuestStats(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
+{
+ /* one parameter, guest name */
+ if (argc < 1)
+ return errorSyntaxInternal(USAGE_I_GUESTSTATS, Internal::tr("Missing VM name/UUID"));
+
+ /*
+ * Parse the command.
+ */
+ ULONG aUpdateInterval = 0;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--interval", 'i', RTGETOPT_REQ_UINT32 }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (ch)
+ {
+ case 'i':
+ aUpdateInterval = ValueUnion.u32;
+ break;
+
+ default:
+ return errorGetOptInternal(USAGE_I_GUESTSTATS, ch, &ValueUnion);
+ }
+ }
+
+ if (argc > 1 && aUpdateInterval == 0)
+ return errorSyntaxInternal(USAGE_I_GUESTSTATS, Internal::tr("Invalid update interval specified"));
+
+ RTPrintf(Internal::tr("argc=%d interval=%u\n"), argc, aUpdateInterval);
+
+ ComPtr<IMachine> ptrMachine;
+ HRESULT hrc;
+ CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[0]).raw(),
+ ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR_RET(ptrMachine, LockMachine(aSession, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /*
+ * Get the guest interface.
+ */
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR_RET(aSession, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IGuest> ptrGuest;
+ CHECK_ERROR_RET(ptrConsole, COMGETTER(Guest)(ptrGuest.asOutParam()), RTEXITCODE_FAILURE);
+
+ if (aUpdateInterval)
+ CHECK_ERROR_RET(ptrGuest, COMSETTER(StatisticsUpdateInterval)(aUpdateInterval), RTEXITCODE_FAILURE);
+ else
+ {
+ ULONG mCpuUser, mCpuKernel, mCpuIdle;
+ ULONG mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache, mPageTotal;
+ ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal;
+
+ CHECK_ERROR_RET(ptrGuest, InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
+ &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
+ &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal,
+ &ulMemBalloonTotal, &ulMemSharedTotal),
+ RTEXITCODE_FAILURE);
+ RTPrintf("mCpuUser=%u mCpuKernel=%u mCpuIdle=%u\n"
+ "mMemTotal=%u mMemFree=%u mMemBalloon=%u mMemShared=%u mMemCache=%u\n"
+ "mPageTotal=%u ulMemAllocTotal=%u ulMemFreeTotal=%u ulMemBalloonTotal=%u ulMemSharedTotal=%u\n",
+ mCpuUser, mCpuKernel, mCpuIdle,
+ mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache,
+ mPageTotal, ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal);
+
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Wrapper for handling internal commands
+ */
+RTEXITCODE handleInternalCommands(HandlerArg *a)
+{
+ /* at least a command is required */
+ if (a->argc < 1)
+ return errorSyntaxInternal(USAGE_I_ALL, Internal::tr("Command missing"));
+
+ /*
+ * The 'string switch' on command name.
+ */
+ const char *pszCmd = a->argv[0];
+ if (!strcmp(pszCmd, "loadmap"))
+ return CmdLoadMap(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "loadsyms"))
+ return CmdLoadSyms(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ //if (!strcmp(pszCmd, "unloadsyms"))
+ // return CmdUnloadSyms(argc - 1, &a->argv[1]);
+ if (!strcmp(pszCmd, "sethduuid") || !strcmp(pszCmd, "sethdparentuuid"))
+ return CmdSetHDUUID(a->argc, &a->argv[0], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "dumphdinfo"))
+ return CmdDumpHDInfo(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "listpartitions"))
+ return CmdListPartitions(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "createrawvmdk"))
+ return CmdCreateRawVMDK(a->argc - 1, &a->argv[1], a);
+ if (!strcmp(pszCmd, "renamevmdk"))
+ return CmdRenameVMDK(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "converttoraw"))
+ return CmdConvertToRaw(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "converthd"))
+ return CmdConvertHardDisk(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "modinstall"))
+ return CmdModInstall();
+ if (!strcmp(pszCmd, "moduninstall"))
+ return CmdModUninstall();
+ if (!strcmp(pszCmd, "debuglog"))
+ return CmdDebugLog(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "passwordhash"))
+ return CmdGeneratePasswordHash(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "gueststats"))
+ return CmdGuestStats(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+ if (!strcmp(pszCmd, "repairhd"))
+ return CmdRepairHardDisk(a->argc - 1, &a->argv[1], a->virtualBox, a->session);
+
+ /* default: */
+ return errorSyntaxInternal(USAGE_I_ALL, Internal::tr("Invalid command '%s'"), a->argv[0]);
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
new file mode 100644
index 00000000..1a59c868
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
@@ -0,0 +1,950 @@
+/* $Id: VBoxManage.cpp $ */
+/** @file
+ * VBoxManage - VirtualBox's command-line interface.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/NativeEventQueue.h>
+
+#include <VBox/com/VirtualBox.h>
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+# include <VBox/com/AutoLock.h>
+# include <VBox/com/listeners.h>
+#endif
+
+#include <VBox/version.h>
+
+#include <iprt/asm.h>
+#include <iprt/buildconfig.h>
+#include <iprt/ctype.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/initterm.h>
+#include <iprt/log.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+
+#include <signal.h>
+
+#include "VBoxManage.h"
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+/** The command doesn't need the COM stuff. */
+#define VBMG_CMD_F_NO_COM RT_BIT_32(0)
+
+#define VBMG_CMD_INTERNAL HELP_CMD_VBOXMANAGE_INVALID
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+
+/**
+ * VBoxManage command descriptor.
+ */
+typedef struct VBMGCMD
+{
+ /** The command. */
+ const char *pszCommand;
+ /** The new help command. */
+ enum HELP_CMD_VBOXMANAGE enmCmdHelp;
+ /** The handler. */
+ RTEXITCODE (*pfnHandler)(HandlerArg *pArg);
+ /** VBMG_CMD_F_XXX, */
+ uint32_t fFlags;
+} VBMGCMD;
+/** Pointer to a const VBoxManage command descriptor. */
+typedef VBMGCMD const *PCVBMGCMD;
+
+
+DECLARE_TRANSLATION_CONTEXT(VBoxManage);
+
+void setBuiltInHelpLanguage(const char *pszLang);
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+/* listener class for language updates */
+class VBoxEventListener
+{
+public:
+ VBoxEventListener()
+ {}
+
+
+ HRESULT init(void *)
+ {
+ return S_OK;
+ }
+
+ HRESULT init()
+ {
+ return S_OK;
+ }
+
+ void uninit()
+ {
+ }
+
+ virtual ~VBoxEventListener()
+ {
+ }
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
+ {
+ switch(aType)
+ {
+ case VBoxEventType_OnLanguageChanged:
+ {
+ /*
+ * Proceed with uttmost care as we might be racing com::Shutdown()
+ * and have the ground open up beneath us.
+ */
+ LogFunc(("VBoxEventType_OnLanguageChanged\n"));
+ VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::tryInstance();
+ if (pTranslator)
+ {
+ ComPtr<ILanguageChangedEvent> pEvent = aEvent;
+ Assert(pEvent);
+
+ /* This call may fail if we're racing COM shutdown. */
+ com::Bstr bstrLanguageId;
+ HRESULT hrc = pEvent->COMGETTER(LanguageId)(bstrLanguageId.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ try
+ {
+ com::Utf8Str strLanguageId(bstrLanguageId);
+ LogFunc(("New language ID: %s\n", strLanguageId.c_str()));
+ pTranslator->i_loadLanguage(strLanguageId.c_str());
+ setBuiltInHelpLanguage(strLanguageId.c_str());
+ }
+ catch (std::bad_alloc &)
+ {
+ LogFunc(("Caught bad_alloc"));
+ }
+ }
+ else
+ LogFunc(("Failed to get new language ID: %Rhrc\n", hrc));
+
+ pTranslator->release();
+ }
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+ }
+};
+
+typedef ListenerImpl<VBoxEventListener> VBoxEventListenerImpl;
+
+VBOX_LISTENER_DECLARE(VBoxEventListenerImpl)
+#endif /* !VBOX_WITH_VBOXMANAGE_NLS */
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/*extern*/ bool g_fDetailedProgress = false;
+/** Set by the signal handler. */
+static volatile bool g_fCanceled = false;
+
+
+/**
+ * All registered command handlers
+ */
+static const VBMGCMD g_aCommands[] =
+{
+ { "internalcommands", VBMG_CMD_INTERNAL, handleInternalCommands, 0 },
+ { "list", HELP_CMD_LIST, handleList, 0 },
+ { "showvminfo", HELP_CMD_SHOWVMINFO, handleShowVMInfo, 0 },
+ { "registervm", HELP_CMD_REGISTERVM, handleRegisterVM, 0 },
+ { "unregistervm", HELP_CMD_UNREGISTERVM, handleUnregisterVM, 0 },
+ { "clonevm", HELP_CMD_CLONEVM, handleCloneVM, 0 },
+ { "movevm", HELP_CMD_MOVEVM, handleMoveVM, 0 },
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ { "encryptvm", HELP_CMD_ENCRYPTVM, handleEncryptVM, 0 },
+#endif
+ { "mediumproperty", HELP_CMD_MEDIUMPROPERTY, handleMediumProperty, 0 },
+ { "hdproperty", HELP_CMD_MEDIUMPROPERTY, handleMediumProperty, 0 }, /* backward compatibility */
+ { "createmedium", HELP_CMD_CREATEMEDIUM, handleCreateMedium, 0 },
+ { "createhd", HELP_CMD_CREATEMEDIUM, handleCreateMedium, 0 }, /* backward compatibility */
+ { "createvdi", HELP_CMD_CREATEMEDIUM, handleCreateMedium, 0 }, /* backward compatibility */
+ { "modifymedium", HELP_CMD_MODIFYMEDIUM, handleModifyMedium, 0 },
+ { "modifyhd", HELP_CMD_MODIFYMEDIUM, handleModifyMedium, 0 }, /* backward compatibility */
+ { "modifyvdi", HELP_CMD_MODIFYMEDIUM, handleModifyMedium, 0 }, /* backward compatibility */
+ { "clonemedium", HELP_CMD_CLONEMEDIUM, handleCloneMedium, 0 },
+ { "clonehd", HELP_CMD_CLONEMEDIUM, handleCloneMedium, 0 }, /* backward compatibility */
+ { "clonevdi", HELP_CMD_CLONEMEDIUM, handleCloneMedium, 0 }, /* backward compatibility */
+ { "encryptmedium", HELP_CMD_ENCRYPTMEDIUM, handleEncryptMedium, 0 },
+ { "checkmediumpwd", HELP_CMD_CHECKMEDIUMPWD, handleCheckMediumPassword, 0 },
+ { "createvm", HELP_CMD_CREATEVM, handleCreateVM, 0 },
+ { "modifyvm", HELP_CMD_MODIFYVM, handleModifyVM, 0 },
+ { "startvm", HELP_CMD_STARTVM, handleStartVM, 0 },
+ { "controlvm", HELP_CMD_CONTROLVM, handleControlVM, 0 },
+ { "unattended", HELP_CMD_UNATTENDED, handleUnattended, 0 },
+ { "discardstate", HELP_CMD_DISCARDSTATE, handleDiscardState, 0 },
+ { "adoptstate", HELP_CMD_ADOPTSTATE, handleAdoptState, 0 },
+ { "snapshot", HELP_CMD_SNAPSHOT, handleSnapshot, 0 },
+ { "closemedium", HELP_CMD_CLOSEMEDIUM, handleCloseMedium, 0 },
+ { "storageattach", HELP_CMD_STORAGEATTACH, handleStorageAttach, 0 },
+ { "storagectl", HELP_CMD_STORAGECTL, handleStorageController, 0 },
+ { "showmediuminfo", HELP_CMD_SHOWMEDIUMINFO, handleShowMediumInfo, 0 },
+ { "showhdinfo", HELP_CMD_SHOWMEDIUMINFO, handleShowMediumInfo, 0 }, /* backward compatibility */
+ { "showvdiinfo", HELP_CMD_SHOWMEDIUMINFO, handleShowMediumInfo, 0 }, /* backward compatibility */
+ { "mediumio", HELP_CMD_MEDIUMIO, handleMediumIO, 0 },
+ { "getextradata", HELP_CMD_GETEXTRADATA, handleGetExtraData, 0 },
+ { "setextradata", HELP_CMD_SETEXTRADATA, handleSetExtraData, 0 },
+ { "setproperty", HELP_CMD_SETPROPERTY, handleSetProperty, 0 },
+ { "usbfilter", HELP_CMD_USBFILTER, handleUSBFilter, 0 },
+ { "sharedfolder", HELP_CMD_SHAREDFOLDER, handleSharedFolder, 0 },
+#ifdef VBOX_WITH_GUEST_PROPS
+ { "guestproperty", HELP_CMD_GUESTPROPERTY, handleGuestProperty, 0 },
+#endif
+#ifdef VBOX_WITH_GUEST_CONTROL
+ { "guestcontrol", HELP_CMD_GUESTCONTROL, handleGuestControl, 0 },
+#endif
+ { "metrics", HELP_CMD_METRICS, handleMetrics, 0 },
+ { "import", HELP_CMD_IMPORT, handleImportAppliance, 0 },
+ { "export", HELP_CMD_EXPORT, handleExportAppliance, 0 },
+ { "signova", HELP_CMD_SIGNOVA, handleSignAppliance, VBMG_CMD_F_NO_COM },
+#ifdef VBOX_WITH_NETFLT
+ { "hostonlyif", HELP_CMD_HOSTONLYIF, handleHostonlyIf, 0 },
+#endif
+#ifdef VBOX_WITH_VMNET
+ { "hostonlynet", HELP_CMD_HOSTONLYNET, handleHostonlyNet, 0 },
+#endif
+ { "dhcpserver", HELP_CMD_DHCPSERVER, handleDHCPServer, 0 },
+#ifdef VBOX_WITH_NAT_SERVICE
+ { "natnetwork", HELP_CMD_NATNETWORK, handleNATNetwork, 0 },
+#endif
+ { "extpack", HELP_CMD_EXTPACK, handleExtPack, 0 },
+ { "bandwidthctl", HELP_CMD_BANDWIDTHCTL, handleBandwidthControl, 0 },
+ { "debugvm", HELP_CMD_DEBUGVM, handleDebugVM, 0 },
+ { "convertfromraw", HELP_CMD_CONVERTFROMRAW, handleConvertFromRaw, VBMG_CMD_F_NO_COM },
+ { "convertdd", HELP_CMD_CONVERTFROMRAW, handleConvertFromRaw, VBMG_CMD_F_NO_COM },
+ { "usbdevsource", HELP_CMD_USBDEVSOURCE, handleUSBDevSource, 0 },
+ { "cloudprofile", HELP_CMD_CLOUDPROFILE, handleCloudProfile, 0 },
+ { "cloud", HELP_CMD_CLOUD, handleCloud, 0 },
+#ifdef VBOX_WITH_UPDATE_AGENT
+ { "updatecheck", HELP_CMD_UPDATECHECK, handleUpdateCheck, 0 },
+#endif
+ { "modifynvram", HELP_CMD_MODIFYNVRAM, handleModifyNvram, 0 },
+};
+
+/**
+ * Looks up a command by name.
+ *
+ * @returns Pointer to the command structure.
+ * @param pszCommand Name of the command.
+ */
+static PCVBMGCMD lookupCommand(const char *pszCommand)
+{
+ if (pszCommand)
+ for (uint32_t i = 0; i < RT_ELEMENTS(g_aCommands); i++)
+ if (!strcmp(g_aCommands[i].pszCommand, pszCommand))
+ return &g_aCommands[i];
+ return NULL;
+}
+
+
+/**
+ * Signal handler that sets g_fCanceled.
+ *
+ * This can be executed on any thread in the process, on Windows it may even be
+ * a thread dedicated to delivering this signal. Do not doing anything
+ * unnecessary here.
+ */
+static void showProgressSignalHandler(int iSignal) RT_NOTHROW_DEF
+{
+ NOREF(iSignal);
+ ASMAtomicWriteBool(&g_fCanceled, true);
+}
+
+/**
+ * Print out progress on the console.
+ *
+ * This runs the main event queue every now and then to prevent piling up
+ * unhandled things (which doesn't cause real problems, just makes things
+ * react a little slower than in the ideal case).
+ */
+HRESULT showProgress(ComPtr<IProgress> progress, uint32_t fFlags)
+{
+ using namespace com;
+ HRESULT hrc;
+
+ AssertReturn(progress.isNotNull(), E_FAIL);
+
+ /* grandfather the old callers */
+ if (g_fDetailedProgress)
+ fFlags = SHOW_PROGRESS_DETAILS;
+
+ const bool fDetailed = RT_BOOL(fFlags & SHOW_PROGRESS_DETAILS);
+ const bool fQuiet = !RT_BOOL(fFlags & (SHOW_PROGRESS | SHOW_PROGRESS_DETAILS));
+
+
+ BOOL fCompleted = FALSE;
+ ULONG ulCurrentPercent = 0;
+ ULONG ulLastPercent = 0;
+
+ ULONG ulLastOperationPercent = (ULONG)-1;
+
+ ULONG ulLastOperation = (ULONG)-1;
+ Bstr bstrOperationDescription;
+
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+
+ ULONG cOperations = 1;
+ hrc = progress->COMGETTER(OperationCount)(&cOperations);
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("Progress object failure: %Rhrc\n"), hrc);
+ RTStrmFlush(g_pStdErr);
+ return hrc;
+ }
+
+ /*
+ * Note: Outputting the progress info to stderr (g_pStdErr) is intentional
+ * to not get intermixed with other (raw) stdout data which might get
+ * written in the meanwhile.
+ */
+
+ if (fFlags & SHOW_PROGRESS_DESC)
+ {
+ com::Bstr bstrDescription;
+ hrc = progress->COMGETTER(Description(bstrDescription.asOutParam()));
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("Failed to get progress description: %Rhrc\n"), hrc);
+ return hrc;
+ }
+
+ const char *pcszDescSep;
+ if (fDetailed) /* multiline output */
+ pcszDescSep = "\n";
+ else /* continues on the same line */
+ pcszDescSep = ": ";
+
+ RTStrmPrintf(g_pStdErr, "%ls%s", bstrDescription.raw(), pcszDescSep);
+ RTStrmFlush(g_pStdErr);
+ }
+
+ if (!fQuiet && !fDetailed)
+ {
+ RTStrmPrintf(g_pStdErr, "0%%...");
+ RTStrmFlush(g_pStdErr);
+ }
+
+ /* setup signal handling if cancelable */
+ bool fCanceledAlready = false;
+ BOOL fCancelable;
+ hrc = progress->COMGETTER(Cancelable)(&fCancelable);
+ if (FAILED(hrc))
+ fCancelable = FALSE;
+ if (fCancelable)
+ {
+ signal(SIGINT, showProgressSignalHandler);
+ signal(SIGTERM, showProgressSignalHandler);
+#ifdef SIGBREAK
+ signal(SIGBREAK, showProgressSignalHandler);
+#endif
+ }
+
+ hrc = progress->COMGETTER(Completed(&fCompleted));
+ while (SUCCEEDED(hrc))
+ {
+ progress->COMGETTER(Percent(&ulCurrentPercent));
+
+ if (fDetailed)
+ {
+ ULONG ulOperation = 1;
+ hrc = progress->COMGETTER(Operation)(&ulOperation);
+ if (FAILED(hrc))
+ break;
+ ULONG ulCurrentOperationPercent = 0;
+ hrc = progress->COMGETTER(OperationPercent(&ulCurrentOperationPercent));
+ if (FAILED(hrc))
+ break;
+
+ if (ulLastOperation != ulOperation)
+ {
+ hrc = progress->COMGETTER(OperationDescription(bstrOperationDescription.asOutParam()));
+ if (FAILED(hrc))
+ break;
+ ulLastPercent = (ULONG)-1; // force print
+ ulLastOperation = ulOperation;
+ }
+
+ if ( ulCurrentPercent != ulLastPercent
+ || ulCurrentOperationPercent != ulLastOperationPercent
+ )
+ {
+ LONG lSecsRem = 0;
+ progress->COMGETTER(TimeRemaining)(&lSecsRem);
+
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("(%u/%u) %ls %02u%% => %02u%% (%d s remaining)\n"), ulOperation + 1, cOperations,
+ bstrOperationDescription.raw(), ulCurrentOperationPercent, ulCurrentPercent, lSecsRem);
+ ulLastPercent = ulCurrentPercent;
+ ulLastOperationPercent = ulCurrentOperationPercent;
+ }
+ }
+ else if (!fQuiet)
+ {
+ /* did we cross a 10% mark? */
+ if (ulCurrentPercent / 10 > ulLastPercent / 10)
+ {
+ /* make sure to also print out missed steps */
+ for (ULONG curVal = (ulLastPercent / 10) * 10 + 10; curVal <= (ulCurrentPercent / 10) * 10; curVal += 10)
+ {
+ if (curVal < 100)
+ {
+ RTStrmPrintf(g_pStdErr, "%u%%...", curVal);
+ RTStrmFlush(g_pStdErr);
+ }
+ }
+ ulLastPercent = (ulCurrentPercent / 10) * 10;
+ }
+ }
+ if (fCompleted)
+ break;
+
+ /* process async cancelation */
+ if (g_fCanceled && !fCanceledAlready)
+ {
+ hrc = progress->Cancel();
+ if (SUCCEEDED(hrc))
+ fCanceledAlready = true;
+ else
+ g_fCanceled = false;
+ }
+
+ /* make sure the loop is not too tight */
+ progress->WaitForCompletion(100);
+
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ hrc = progress->COMGETTER(Completed(&fCompleted));
+ }
+
+ /* undo signal handling */
+ if (fCancelable)
+ {
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+# ifdef SIGBREAK
+ signal(SIGBREAK, SIG_DFL);
+# endif
+ }
+
+ /* complete the line. */
+ LONG iRc = E_FAIL;
+ hrc = progress->COMGETTER(ResultCode)(&iRc);
+ if (SUCCEEDED(hrc))
+ {
+ /* async operation completed successfully */
+ if (SUCCEEDED(iRc))
+ {
+ if (!fDetailed)
+ {
+ if (fFlags == SHOW_PROGRESS_DESC)
+ RTStrmPrintf(g_pStdErr, "ok\n");
+ else if (!fQuiet)
+ RTStrmPrintf(g_pStdErr, "100%%\n");
+ }
+ }
+ else if (g_fCanceled)
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("CANCELED\n"));
+ else
+ {
+ if (fDetailed)
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("Progress state: %Rhrc\n"), iRc);
+ else if (fFlags != SHOW_PROGRESS_NONE)
+ RTStrmPrintf(g_pStdErr, "%Rhrc\n", iRc);
+ }
+ hrc = iRc;
+ }
+ else
+ {
+ if (!fDetailed)
+ RTStrmPrintf(g_pStdErr, "\n");
+ RTStrmPrintf(g_pStdErr, VBoxManage::tr("Progress object failure: %Rhrc\n"), hrc);
+ }
+ RTStrmFlush(g_pStdErr);
+ return hrc;
+}
+
+
+void setBuiltInHelpLanguage(const char *pszLang)
+{
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ if (pszLang == NULL || pszLang[0] == '\0' || (pszLang[0] == 'C' && pszLang[1] == '\0'))
+ pszLang = "en_US";
+
+ /* find language entry matching exactly pszLang */
+ PCHELP_LANG_ENTRY_T pHelpLangEntry = NULL;
+ for (uint32_t i = 0; i < g_cHelpLangEntries; i++)
+ {
+ if (strcmp(g_aHelpLangEntries[i].pszLang, pszLang) == 0)
+ {
+ pHelpLangEntry = &g_aHelpLangEntries[i];
+ break;
+ }
+ }
+
+ /* find first entry containing language specified if pszLang contains only language */
+ if (pHelpLangEntry == NULL)
+ {
+ size_t const cchLang = strlen(pszLang);
+ for (uint32_t i = 0; i < g_cHelpLangEntries; i++)
+ {
+ if ( cchLang < g_aHelpLangEntries[i].cchLang
+ && memcmp(g_aHelpLangEntries[i].pszLang, pszLang, cchLang) == 0)
+ {
+ pHelpLangEntry = &g_aHelpLangEntries[i];
+ break;
+ }
+ }
+ }
+
+ /* set to en_US (i.e. untranslated) if not found */
+ if (pHelpLangEntry == NULL)
+ pHelpLangEntry = &g_aHelpLangEntries[0];
+
+ ASMAtomicWritePtr(&g_pHelpLangEntry, pHelpLangEntry);
+#else
+ NOREF(pszLang);
+#endif
+}
+
+
+int main(int argc, char *argv[])
+{
+ /*
+ * Before we do anything, init the runtime without loading
+ * the support driver.
+ */
+ int vrc = RTR3InitExe(argc, &argv, 0);
+ if (RT_FAILURE(vrc))
+ return RTMsgInitFailure(vrc);
+#if defined(RT_OS_WINDOWS)
+ ATL::CComModule _Module; /* Required internally by ATL (constructor records instance in global variable). */
+#endif
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ /*
+ * Initialize the translator and associated fun.
+ */
+ util::InitAutoLockSystem();
+ ComObjPtr<VBoxEventListenerImpl> ptrEventListner;
+ PTRCOMPONENT pTrComponent = NULL;
+ VirtualBoxTranslator *pTranslator = VirtualBoxTranslator::instance();
+ if (pTranslator != NULL)
+ {
+ char szNlsPath[RTPATH_MAX];
+ vrc = RTPathAppPrivateNoArch(szNlsPath, sizeof(szNlsPath));
+ if (RT_SUCCESS(vrc))
+ vrc = RTPathAppend(szNlsPath, sizeof(szNlsPath), "nls" RTPATH_SLASH_STR "VBoxManageNls");
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = pTranslator->registerTranslation(szNlsPath, true, &pTrComponent);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = pTranslator->i_loadLanguage(NULL);
+ if (RT_SUCCESS(vrc))
+ {
+ com::Utf8Str strLang = pTranslator->language();
+ setBuiltInHelpLanguage(strLang.c_str());
+ }
+ else
+ RTMsgWarning("Load language failed: %Rrc\n", vrc);
+ }
+ else
+ RTMsgWarning("Register translation failed: %Rrc\n", vrc);
+ }
+ else
+ RTMsgWarning("Path constructing failed: %Rrc\n", vrc);
+ }
+#endif
+
+ /*
+ * Parse the global options
+ */
+ bool fShowLogo = false;
+ bool fShowHelp = false;
+ int iCmd = 1;
+ int iCmdArg;
+ const char *pszSettingsPw = NULL;
+ const char *pszSettingsPwFile = NULL;
+ int cResponseFileArgs = 0;
+ char **papszResponseFileArgs = NULL;
+ char **papszNewArgv = NULL;
+
+ for (int i = 1; i < argc || argc <= iCmd; i++)
+ {
+ if ( argc <= iCmd
+ || !strcmp(argv[i], "help")
+ || !strcmp(argv[i], "--help")
+ || !strcmp(argv[i], "-?")
+ || !strcmp(argv[i], "-h")
+ || !strcmp(argv[i], "-help"))
+ {
+ if (i >= argc - 1)
+ {
+ showLogo(g_pStdOut);
+ printUsage(g_pStdOut);
+ return 0;
+ }
+ fShowLogo = true;
+ fShowHelp = true;
+ iCmd++;
+ continue;
+ }
+
+ if ( !strcmp(argv[i], "-V")
+ || !strcmp(argv[i], "--version")
+ || !strcmp(argv[i], "-v") /* deprecated */
+ || !strcmp(argv[i], "-version") /* deprecated */
+ || !strcmp(argv[i], "-Version") /* deprecated */)
+ {
+ /* Print version number, and do nothing else. */
+ RTPrintf("%sr%u\n", VBOX_VERSION_STRING, RTBldCfgRevision());
+ return 0;
+ }
+ if (!strcmp(argv[i], "--dump-build-type"))
+ {
+ /* Print the build type, and do nothing else. (Used by ValKit to detect build type.) */
+ RTPrintf("%s\n", RTBldCfgType());
+ return 0;
+ }
+
+ if ( !strcmp(argv[i], "--dumpopts")
+ || !strcmp(argv[i], "-dumpopts") /* deprecated */)
+ {
+ /* Special option to dump really all commands,
+ * even the ones not understood on this platform. */
+ printUsage(g_pStdOut);
+ return 0;
+ }
+
+ if ( !strcmp(argv[i], "--nologo")
+ || !strcmp(argv[i], "-q")
+ || !strcmp(argv[i], "-nologo") /* deprecated */)
+ {
+ /* suppress the logo */
+ fShowLogo = false;
+ iCmd++;
+ }
+ else if ( !strcmp(argv[i], "--detailed-progress")
+ || !strcmp(argv[i], "-d"))
+ {
+ /* detailed progress report */
+ g_fDetailedProgress = true;
+ iCmd++;
+ }
+ else if (!strcmp(argv[i], "--settingspw"))
+ {
+ if (i >= argc - 1)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, VBoxManage::tr("Password expected"));
+ /* password for certain settings */
+ pszSettingsPw = argv[i + 1];
+ iCmd += 2;
+ }
+ else if (!strcmp(argv[i], "--settingspwfile"))
+ {
+ if (i >= argc-1)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, VBoxManage::tr("No password file specified"));
+ pszSettingsPwFile = argv[i+1];
+ iCmd += 2;
+ }
+ else if (argv[i][0] == '@')
+ {
+ if (papszResponseFileArgs)
+ return RTMsgErrorExitFailure(VBoxManage::tr("Only one response file allowed"));
+
+ /* Load response file, making sure it's valid UTF-8. */
+ char *pszResponseFile;
+ size_t cbResponseFile;
+ vrc = RTFileReadAllEx(&argv[i][1], 0, RTFOFF_MAX, RTFILE_RDALL_O_DENY_NONE | RTFILE_RDALL_F_TRAILING_ZERO_BYTE,
+ (void **)&pszResponseFile, &cbResponseFile);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(VBoxManage::tr("Error reading response file '%s': %Rrc"), &argv[i][1], vrc);
+ vrc = RTStrValidateEncoding(pszResponseFile);
+ if (RT_FAILURE(vrc))
+ {
+ RTFileReadAllFree(pszResponseFile, cbResponseFile);
+ return RTMsgErrorExitFailure(VBoxManage::tr("Invalid response file ('%s') encoding: %Rrc"), &argv[i][1], vrc);
+ }
+
+ /* Parse it. */
+ vrc = RTGetOptArgvFromString(&papszResponseFileArgs, &cResponseFileArgs, pszResponseFile,
+ RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL);
+ RTFileReadAllFree(pszResponseFile, cbResponseFile);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(VBoxManage::tr("Failed to parse response file '%s' (bourne shell style): %Rrc"), &argv[i][1], vrc);
+
+ /* Construct new argv+argc with the response file arguments inserted. */
+ int cNewArgs = argc + cResponseFileArgs;
+ papszNewArgv = (char **)RTMemAllocZ((cNewArgs + 2) * sizeof(papszNewArgv[0]));
+ if (!papszNewArgv)
+ return RTMsgErrorExitFailure(VBoxManage::tr("out of memory"));
+ memcpy(&papszNewArgv[0], &argv[0], sizeof(argv[0]) * (i + 1));
+ memcpy(&papszNewArgv[i + 1], papszResponseFileArgs, sizeof(argv[0]) * cResponseFileArgs);
+ memcpy(&papszNewArgv[i + 1 + cResponseFileArgs], &argv[i + 1], sizeof(argv[0]) * (argc - i - 1 + 1));
+ argv = papszNewArgv;
+ argc = argc + cResponseFileArgs;
+
+ iCmd++;
+ }
+ else
+ break;
+ }
+
+ iCmdArg = iCmd + 1;
+
+ /*
+ * Show the logo and lookup the command and deal with fShowHelp = true.
+ */
+ if (fShowLogo)
+ showLogo(g_pStdOut);
+
+ PCVBMGCMD pCmd = lookupCommand(argv[iCmd]);
+ if (pCmd && pCmd->enmCmdHelp != VBMG_CMD_INTERNAL)
+ setCurrentCommand(pCmd->enmCmdHelp);
+
+ if ( pCmd
+ && ( fShowHelp
+ || argc - iCmdArg == 0))
+ {
+ if (pCmd->enmCmdHelp == VBMG_CMD_INTERNAL)
+ printUsageInternalCmds(g_pStdOut);
+ else if (fShowHelp)
+ printHelp(g_pStdOut);
+ else
+ printUsage(g_pStdOut);
+ return RTEXITCODE_FAILURE; /* error */
+ }
+ if (!pCmd)
+ {
+ if (!strcmp(argv[iCmd], "commands"))
+ {
+ RTPrintf(VBoxManage::tr("commands:\n"));
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aCommands); i++)
+ if ( i == 0 /* skip backwards compatibility entries */
+ || (g_aCommands[i].enmCmdHelp != g_aCommands[i - 1].enmCmdHelp))
+ RTPrintf(" %s\n", g_aCommands[i].pszCommand);
+ return RTEXITCODE_SUCCESS;
+ }
+ return errorSyntax(VBoxManage::tr("Invalid command '%s'"), argv[iCmd]);
+ }
+
+ RTEXITCODE rcExit;
+ if (!(pCmd->fFlags & VBMG_CMD_F_NO_COM))
+ {
+ /*
+ * Initialize COM.
+ */
+ using namespace com;
+ HRESULT hrc = com::Initialize();
+ if (FAILED(hrc))
+ {
+# ifdef VBOX_WITH_XPCOM
+ if (hrc == NS_ERROR_FILE_ACCESS_DENIED)
+ {
+ char szHome[RTPATH_MAX] = "";
+ com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
+ return RTMsgErrorExit(RTEXITCODE_FAILURE,
+ VBoxManage::tr("Failed to initialize COM because the global settings directory '%s' is not accessible!"), szHome);
+ }
+# endif
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, VBoxManage::tr("Failed to initialize COM! (hrc=%Rhrc)"), hrc);
+ }
+
+
+ /*
+ * Get the remote VirtualBox object and create a local session object.
+ */
+ rcExit = RTEXITCODE_FAILURE;
+ ComPtr<IVirtualBoxClient> virtualBoxClient;
+ ComPtr<IVirtualBox> virtualBox;
+ hrc = virtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
+ if (SUCCEEDED(hrc))
+ hrc = virtualBoxClient->COMGETTER(VirtualBox)(virtualBox.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ /* Load language settings from IVirtualBox. */
+ if (pTranslator != NULL)
+ {
+ HRESULT hrc1 = pTranslator->loadLanguage(virtualBox);
+ if (SUCCEEDED(hrc1))
+ {
+ com::Utf8Str strLang = pTranslator->language();
+ setBuiltInHelpLanguage(strLang.c_str());
+ }
+ else
+ RTMsgWarning("Failed to load API language: %Rhrc", hrc1);
+
+ /* VirtualBox language events registration. */
+ ComPtr<IEventSource> pES;
+ hrc1 = virtualBox->COMGETTER(EventSource)(pES.asOutParam());
+ if (SUCCEEDED(hrc1))
+ {
+ hrc1 = ptrEventListner.createObject();
+ if (SUCCEEDED(hrc1))
+ hrc1 = ptrEventListner->init(new VBoxEventListener());
+ if (SUCCEEDED(hrc1))
+ {
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnLanguageChanged);
+ hrc1 = pES->RegisterListener(ptrEventListner, ComSafeArrayAsInParam(eventTypes), true);
+ }
+ if (FAILED(hrc1))
+ {
+ ptrEventListner.setNull();
+ RTMsgWarning("Failed to register event listener: %Rhrc", hrc1);
+ }
+ }
+ }
+#endif
+
+ ComPtr<ISession> session;
+ hrc = session.createInprocObject(CLSID_Session);
+ if (SUCCEEDED(hrc))
+ {
+ /* Session secret. */
+ if (pszSettingsPw)
+ CHECK_ERROR2I_STMT(virtualBox, SetSettingsSecret(Bstr(pszSettingsPw).raw()), rcExit = RTEXITCODE_FAILURE);
+ else if (pszSettingsPwFile)
+ rcExit = settingsPasswordFile(virtualBox, pszSettingsPwFile);
+ else
+ rcExit = RTEXITCODE_SUCCESS;
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Call the handler.
+ */
+ HandlerArg handlerArg = { argc - iCmdArg, &argv[iCmdArg], virtualBox, session };
+ rcExit = pCmd->pfnHandler(&handlerArg);
+
+ /* Although all handlers should always close the session if they open it,
+ * we do it here just in case if some of the handlers contains a bug --
+ * leaving the direct session not closed will turn the machine state to
+ * Aborted which may have unwanted side effects like killing the saved
+ * state file (if the machine was in the Saved state before). */
+ session->UnlockMachine();
+ }
+
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ }
+ else
+ {
+ com::ErrorInfo info;
+ RTMsgError(VBoxManage::tr("Failed to create a session object!"));
+ if (!info.isFullAvailable() && !info.isBasicAvailable())
+ com::GluePrintRCMessage(hrc);
+ else
+ com::GluePrintErrorInfo(info);
+ }
+ }
+ else
+ {
+ com::ErrorInfo info;
+ RTMsgError(VBoxManage::tr("Failed to create the VirtualBox object!"));
+ if (!info.isFullAvailable() && !info.isBasicAvailable())
+ {
+ com::GluePrintRCMessage(hrc);
+ RTMsgError(VBoxManage::tr("Most likely, the VirtualBox COM server is not running or failed to start."));
+ }
+ else
+ com::GluePrintErrorInfo(info);
+ }
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ /* VirtualBox event callback unregistration. */
+ if (ptrEventListner.isNotNull())
+ {
+ ComPtr<IEventSource> pES;
+ HRESULT hrc1 = virtualBox->COMGETTER(EventSource)(pES.asOutParam());
+ if (pES.isNotNull())
+ {
+ hrc1 = pES->UnregisterListener(ptrEventListner);
+ if (FAILED(hrc1))
+ LogRel(("Failed to unregister listener, %Rhrc", hrc1));
+ }
+ ptrEventListner.setNull();
+ }
+#endif
+ /*
+ * Terminate COM, make sure the virtualBox object has been released.
+ */
+ virtualBox.setNull();
+ virtualBoxClient.setNull();
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ com::Shutdown();
+ }
+ else
+ {
+ /*
+ * The command needs no COM.
+ */
+ HandlerArg handlerArg;
+ handlerArg.argc = argc - iCmdArg;
+ handlerArg.argv = &argv[iCmdArg];
+ rcExit = pCmd->pfnHandler(&handlerArg);
+ }
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ if (pTranslator != NULL)
+ {
+ pTranslator->release();
+ pTranslator = NULL;
+ pTrComponent = NULL;
+ }
+#endif
+
+ if (papszResponseFileArgs)
+ {
+ RTGetOptArgvFree(papszResponseFileArgs);
+ RTMemFree(papszNewArgv);
+ }
+
+ return rcExit;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.h b/src/VBox/Frontends/VBoxManage/VBoxManage.h
new file mode 100644
index 00000000..35ab4a15
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.h
@@ -0,0 +1,313 @@
+/* $Id: VBoxManage.h $ */
+/** @file
+ * VBoxManage - VirtualBox command-line interface, internal header file.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_VBoxManage_VBoxManage_h
+#define VBOX_INCLUDED_SRC_VBoxManage_VBoxManage_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/com.h>
+#include <VBox/com/ptr.h>
+#include <VBox/com/VirtualBox.h>
+#include <VBox/com/string.h>
+#include <VBox/com/array.h>
+
+#include <iprt/types.h>
+#include <iprt/message.h>
+#include <iprt/stream.h>
+#include <iprt/getopt.h>
+
+#include "VBoxManageBuiltInHelp.h"
+#include "PasswordInput.h"
+
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+# include "VirtualBoxTranslator.h"
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// definitions
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This defines a a_CtxName::tr function that gives the translator context as
+ * well as providing a shorter way to call VirtualBoxTranslator::translate.
+ */
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+# define DECLARE_TRANSLATION_CONTEXT(a_CtxName) \
+struct a_CtxName \
+{ \
+ static const char *tr(const char *pszSource, const char *pszComment = NULL, const size_t uNum = ~(size_t)0) \
+ { \
+ return VirtualBoxTranslator::translate(NULL, #a_CtxName, pszSource, pszComment, uNum); \
+ } \
+}
+#else
+# define DECLARE_TRANSLATION_CONTEXT(a_CtxName) \
+struct a_CtxName \
+{ \
+ static const char *tr(const char *pszSource, const char *pszComment = NULL, const size_t uNum = ~(size_t)0) \
+ { \
+ RT_NOREF(pszComment, uNum); \
+ return pszSource; \
+ } \
+}
+#endif
+
+/**
+ * Defines an option with two variants, producing two RTGETOPTDEF entries.
+ *
+ * This is mainly for replacing character-soup option names like
+ * --natlocalhostreachable and --biossystemtimeoffset with more easily parsed
+ * ones, like --nat-localhost-reachable and --bios-system-time-offset, without
+ * removing the legacy name.
+ */
+#define OPT2(a_pszWordDashWord, a_pszWordSoup, a_chOptOrValue, a_fFlags) \
+ { a_pszWordDashWord, a_chOptOrValue, a_fFlags }, \
+ { a_pszWordSoup, a_chOptOrValue, a_fFlags }
+
+/** A single option variant of OPT2 for better looking tables. */
+#define OPT1(a_pszOption, a_chOptOrValue, a_fFlags) \
+ { a_pszOption, a_chOptOrValue, a_fFlags }
+
+
+/** command handler argument */
+struct HandlerArg
+{
+ int argc;
+ char **argv;
+
+ ComPtr<IVirtualBox> virtualBox;
+ ComPtr<ISession> session;
+};
+
+
+/** showVMInfo details */
+typedef enum
+{
+ VMINFO_NONE = 0,
+ VMINFO_STANDARD = 1, /**< standard details */
+ VMINFO_FULL = 2, /**< both */
+ VMINFO_MACHINEREADABLE = 3, /**< both, and make it machine readable */
+ VMINFO_COMPACT = 4
+} VMINFO_DETAILS;
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// global variables
+//
+////////////////////////////////////////////////////////////////////////////////
+
+extern bool g_fDetailedProgress; // in VBoxManage.cpp
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// prototypes
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/* VBoxManageHelp.cpp */
+void setCurrentCommand(enum HELP_CMD_VBOXMANAGE enmCommand);
+void setCurrentSubcommand(uint64_t fCurSubcommandScope);
+
+void printUsage(PRTSTREAM pStrm);
+void printHelp(PRTSTREAM pStrm);
+RTEXITCODE errorNoSubcommand(void);
+RTEXITCODE errorUnknownSubcommand(const char *pszSubCmd);
+RTEXITCODE errorTooManyParameters(char **papszArgs);
+RTEXITCODE errorGetOpt(int rcGetOpt, union RTGETOPTUNION const *pValueUnion);
+RTEXITCODE errorFetchValue(int iValueNo, const char *pszOption, int rcGetOptFetchValue, union RTGETOPTUNION const *pValueUnion);
+RTEXITCODE errorSyntax(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+RTEXITCODE errorSyntaxV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+HRESULT errorSyntaxHr(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+RTEXITCODE errorArgument(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+HRESULT errorArgumentHr(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+# define SHOW_PROGRESS_NONE 0
+# define SHOW_PROGRESS_DESC RT_BIT_32(0)
+# define SHOW_PROGRESS RT_BIT_32(1)
+# define SHOW_PROGRESS_DETAILS RT_BIT_32(2)
+HRESULT showProgress(ComPtr<IProgress> progress, uint32_t fFlags = SHOW_PROGRESS);
+
+/* VBoxManage.cpp */
+void showLogo(PRTSTREAM pStrm);
+
+/* VBoxInternalManage.cpp */
+DECLHIDDEN(void) printUsageInternalCmds(PRTSTREAM pStrm);
+RTEXITCODE handleInternalCommands(HandlerArg *a);
+
+/* VBoxManageControlVM.cpp */
+RTEXITCODE handleControlVM(HandlerArg *a);
+
+/* VBoxManageModifyVM.cpp */
+void parseGroups(const char *pcszGroups, com::SafeArray<BSTR> *pGroups);
+#ifdef VBOX_WITH_RECORDING
+int parseScreens(const char *pcszScreens, com::SafeArray<BOOL> *pScreens);
+#endif
+RTEXITCODE handleModifyVM(HandlerArg *a);
+
+/* VBoxManageDebugVM.cpp */
+RTEXITCODE handleDebugVM(HandlerArg *a);
+
+/* VBoxManageGuestProp.cpp */
+RTEXITCODE handleGuestProperty(HandlerArg *a);
+
+/* VBoxManageGuestCtrl.cpp */
+RTEXITCODE handleGuestControl(HandlerArg *a);
+
+/* VBoxManageVMInfo.cpp */
+HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
+ ComPtr<ISnapshot> &currentSnapshot,
+ VMINFO_DETAILS details,
+ const com::Utf8Str &prefix = "",
+ int level = 0);
+RTEXITCODE handleShowVMInfo(HandlerArg *a);
+HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
+ ComPtr<IMachine> pMachine,
+ ComPtr<ISession> pSession,
+ VMINFO_DETAILS details = VMINFO_NONE);
+const char *machineStateToName(MachineState_T machineState, bool fShort);
+HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
+ VMINFO_DETAILS details);
+void outputMachineReadableString(const char *pszName, const char *pszValue, bool fQuoteName = false, bool fNewline = true);
+void outputMachineReadableString(const char *pszName, com::Bstr const *pbstrValue, bool fQuoteName = false, bool fNewline = true);
+void outputMachineReadableStringWithFmtName(const char *pszValue, bool fQuoteName, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+void outputMachineReadableStringWithFmtName(com::Bstr const *pbstrValue, bool fQuoteName, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+void outputMachineReadableBool(const char *pszName, BOOL const *pfValue);
+void outputMachineReadableBool(const char *pszName, bool const *pfValue);
+void outputMachineReadableULong(const char *pszName, ULONG *uValue);
+void outputMachineReadableLong64(const char *pszName, LONG64 *uValue);
+
+/* VBoxManageList.cpp */
+RTEXITCODE handleList(HandlerArg *a);
+
+/* VBoxManageMetrics.cpp */
+RTEXITCODE handleMetrics(HandlerArg *a);
+
+/* VBoxManageMisc.cpp */
+RTEXITCODE handleRegisterVM(HandlerArg *a);
+RTEXITCODE handleUnregisterVM(HandlerArg *a);
+RTEXITCODE handleCreateVM(HandlerArg *a);
+RTEXITCODE handleCloneVM(HandlerArg *a);
+RTEXITCODE handleStartVM(HandlerArg *a);
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+RTEXITCODE handleEncryptVM(HandlerArg *a);
+#endif
+RTEXITCODE handleDiscardState(HandlerArg *a);
+RTEXITCODE handleAdoptState(HandlerArg *a);
+RTEXITCODE handleGetExtraData(HandlerArg *a);
+RTEXITCODE handleSetExtraData(HandlerArg *a);
+RTEXITCODE handleSetProperty(HandlerArg *a);
+RTEXITCODE handleSharedFolder(HandlerArg *a);
+RTEXITCODE handleExtPack(HandlerArg *a);
+RTEXITCODE handleUnattended(HandlerArg *a);
+RTEXITCODE handleMoveVM(HandlerArg *a);
+RTEXITCODE handleCloudProfile(HandlerArg *a);
+
+/* VBoxManageDisk.cpp */
+HRESULT openMedium(HandlerArg *a, const char *pszFilenameOrUuid,
+ DeviceType_T enmDevType, AccessMode_T enmAccessMode,
+ ComPtr<IMedium> &pMedium, bool fForceNewUuidOnOpen,
+ bool fSilent);
+RTEXITCODE handleCreateMedium(HandlerArg *a);
+RTEXITCODE handleModifyMedium(HandlerArg *a);
+RTEXITCODE handleCloneMedium(HandlerArg *a);
+RTEXITCODE handleMediumProperty(HandlerArg *a);
+RTEXITCODE handleEncryptMedium(HandlerArg *a);
+RTEXITCODE handleCheckMediumPassword(HandlerArg *a);
+RTEXITCODE handleConvertFromRaw(HandlerArg *a);
+HRESULT showMediumInfo(const ComPtr<IVirtualBox> &pVirtualBox,
+ const ComPtr<IMedium> &pMedium,
+ const char *pszParentUUID,
+ bool fOptLong);
+RTEXITCODE handleShowMediumInfo(HandlerArg *a);
+RTEXITCODE handleCloseMedium(HandlerArg *a);
+RTEXITCODE handleMediumIO(HandlerArg *a);
+int parseMediumType(const char *psz, MediumType_T *penmMediumType);
+int parseBool(const char *psz, bool *pb);
+
+/* VBoxManageStorageController.cpp */
+RTEXITCODE handleStorageAttach(HandlerArg *a);
+RTEXITCODE handleStorageController(HandlerArg *a);
+
+// VBoxManageAppliance.cpp
+RTEXITCODE handleImportAppliance(HandlerArg *a);
+RTEXITCODE handleExportAppliance(HandlerArg *a);
+RTEXITCODE handleSignAppliance(HandlerArg *a);
+
+// VBoxManageSnapshot.cpp
+RTEXITCODE handleSnapshot(HandlerArg *a);
+
+/* VBoxManageUSB.cpp */
+RTEXITCODE handleUSBFilter(HandlerArg *a);
+RTEXITCODE handleUSBDevSource(HandlerArg *a);
+
+/* VBoxManageHostonly.cpp */
+RTEXITCODE handleHostonlyIf(HandlerArg *a);
+#ifdef VBOX_WITH_VMNET
+RTEXITCODE handleHostonlyNet(HandlerArg *a);
+#endif /* VBOX_WITH_VMNET */
+
+/* VBoxManageDHCPServer.cpp */
+RTEXITCODE handleDHCPServer(HandlerArg *a);
+
+/* VBoxManageNATNetwork.cpp */
+RTEXITCODE handleNATNetwork(HandlerArg *a);
+RTEXITCODE listNATNetworks(bool fLong, bool fSorted,
+ const ComPtr<IVirtualBox> &pVirtualBox);
+
+/* VBoxManageBandwidthControl.cpp */
+RTEXITCODE handleBandwidthControl(HandlerArg *a);
+
+/* VBoxManageCloud.cpp */
+RTEXITCODE handleCloud(HandlerArg *a);
+
+/* VBoxManageCloudMachine.cpp */
+RTEXITCODE handleCloudMachine(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName);
+RTEXITCODE listCloudMachines(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName);
+RTEXITCODE handleCloudShowVMInfo(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName);
+
+#ifdef VBOX_WITH_UPDATE_AGENT
+/* VBoxManageUpdateCheck.cpp */
+RTEXITCODE handleUpdateCheck(HandlerArg *a);
+#endif
+
+/* VBoxManageModifyNvram.cpp */
+RTEXITCODE handleModifyNvram(HandlerArg *a);
+
+#endif /* !VBOX_INCLUDED_SRC_VBoxManage_VBoxManage_h */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.rc b/src/VBox/Frontends/VBoxManage/VBoxManage.rc
new file mode 100644
index 00000000..e2aa3172
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.rc
@@ -0,0 +1,61 @@
+/* $Id: VBoxManage.rc $ */
+/** @file
+ * VBoxManage - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "FileDescription", "VirtualBox Command Line Tool\0"
+ VALUE "InternalName", "VBoxManage\0"
+ VALUE "OriginalFilename", "VBoxManage.exe\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
new file mode 100644
index 00000000..fb44a061
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
@@ -0,0 +1,2916 @@
+/* $Id: VBoxManageAppliance.cpp $ */
+/** @file
+ * VBoxManage - The appliance-related commands.
+ */
+
+/*
+ * Copyright (C) 2009-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+#include <VBox/log.h>
+#include <VBox/param.h>
+
+#include <VBox/version.h>
+
+#include <list>
+#include <map>
+
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+#include <iprt/path.h>
+#include <iprt/file.h>
+#include <iprt/err.h>
+#include <iprt/zip.h>
+#include <iprt/stream.h>
+#include <iprt/vfs.h>
+#include <iprt/manifest.h>
+#include <iprt/crypto/digest.h>
+#include <iprt/crypto/x509.h>
+#include <iprt/crypto/pkcs7.h>
+#include <iprt/crypto/store.h>
+#include <iprt/crypto/spc.h>
+#include <iprt/crypto/key.h>
+#include <iprt/crypto/pkix.h>
+
+
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Appliance);
+
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+typedef std::map<Utf8Str, Utf8Str> ArgsMap; // pairs of strings like "vmname" => "newvmname"
+typedef std::map<uint32_t, ArgsMap> ArgsMapsMap; // map of maps, one for each virtual system, sorted by index
+
+typedef std::map<uint32_t, bool> IgnoresMap; // pairs of numeric description entry indices
+typedef std::map<uint32_t, IgnoresMap> IgnoresMapsMap; // map of maps, one for each virtual system, sorted by index
+
+static bool findArgValue(Utf8Str &strOut,
+ ArgsMap *pmapArgs,
+ const Utf8Str &strKey)
+{
+ if (pmapArgs)
+ {
+ ArgsMap::iterator it;
+ it = pmapArgs->find(strKey);
+ if (it != pmapArgs->end())
+ {
+ strOut = it->second;
+ pmapArgs->erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int parseImportOptions(const char *psz, com::SafeArray<ImportOptions_T> *options)
+{
+ int vrc = VINF_SUCCESS;
+ while (psz && *psz && RT_SUCCESS(vrc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "KeepAllMACs", len))
+ options->push_back(ImportOptions_KeepAllMACs);
+ else if (!RTStrNICmp(psz, "KeepNATMACs", len))
+ options->push_back(ImportOptions_KeepNATMACs);
+ else if (!RTStrNICmp(psz, "ImportToVDI", len))
+ options->push_back(ImportOptions_ImportToVDI);
+ else
+ vrc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ return vrc;
+}
+
+/**
+ * Helper routine to parse the ExtraData Utf8Str for a storage controller's
+ * value or channel value.
+ *
+ * @param aExtraData The ExtraData string which can have a format of
+ * either 'controller=13;channel=3' or '11'.
+ * @param pszKey The string being looked up, usually either 'controller'
+ * or 'channel' but can be NULL or empty.
+ * @param puVal The integer value of the 'controller=' or 'channel='
+ * key (or the controller number when there is no key) in
+ * the ExtraData string.
+ * @returns COM status code.
+ */
+static int getStorageControllerDetailsFromStr(const com::Utf8Str &aExtraData, const char *pszKey, uint32_t *puVal)
+{
+ int vrc;
+
+ if (pszKey && *pszKey)
+ {
+ size_t posKey = aExtraData.find(pszKey);
+ if (posKey == Utf8Str::npos)
+ return VERR_INVALID_PARAMETER;
+ vrc = RTStrToUInt32Ex(aExtraData.c_str() + posKey + strlen(pszKey), NULL, 0, puVal);
+ }
+ else
+ {
+ vrc = RTStrToUInt32Ex(aExtraData.c_str(), NULL, 0, puVal);
+ }
+
+ if (vrc == VWRN_NUMBER_TOO_BIG || vrc == VWRN_NEGATIVE_UNSIGNED)
+ return VERR_INVALID_PARAMETER;
+
+ return vrc;
+}
+
+static bool isStorageControllerType(VirtualSystemDescriptionType_T avsdType)
+{
+ switch (avsdType)
+ {
+ case VirtualSystemDescriptionType_HardDiskControllerIDE:
+ case VirtualSystemDescriptionType_HardDiskControllerSATA:
+ case VirtualSystemDescriptionType_HardDiskControllerSCSI:
+ case VirtualSystemDescriptionType_HardDiskControllerSAS:
+ case VirtualSystemDescriptionType_HardDiskControllerVirtioSCSI:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const RTGETOPTDEF g_aImportApplianceOptions[] =
+{
+ { "--dry-run", 'n', RTGETOPT_REQ_NOTHING },
+ { "-dry-run", 'n', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--dryrun", 'n', RTGETOPT_REQ_NOTHING },
+ { "-dryrun", 'n', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--detailed-progress", 'P', RTGETOPT_REQ_NOTHING },
+ { "-detailed-progress", 'P', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--vsys", 's', RTGETOPT_REQ_UINT32 },
+ { "-vsys", 's', RTGETOPT_REQ_UINT32 }, // deprecated
+ { "--ostype", 'o', RTGETOPT_REQ_STRING },
+ { "-ostype", 'o', RTGETOPT_REQ_STRING }, // deprecated
+ { "--vmname", 'V', RTGETOPT_REQ_STRING },
+ { "-vmname", 'V', RTGETOPT_REQ_STRING }, // deprecated
+ { "--settingsfile", 'S', RTGETOPT_REQ_STRING },
+ { "--basefolder", 'p', RTGETOPT_REQ_STRING },
+ { "--group", 'g', RTGETOPT_REQ_STRING },
+ { "--memory", 'm', RTGETOPT_REQ_STRING },
+ { "-memory", 'm', RTGETOPT_REQ_STRING }, // deprecated
+ { "--cpus", 'c', RTGETOPT_REQ_STRING },
+ { "--description", 'd', RTGETOPT_REQ_STRING },
+ { "--eula", 'L', RTGETOPT_REQ_STRING },
+ { "-eula", 'L', RTGETOPT_REQ_STRING }, // deprecated
+ { "--unit", 'u', RTGETOPT_REQ_UINT32 },
+ { "-unit", 'u', RTGETOPT_REQ_UINT32 }, // deprecated
+ { "--ignore", 'x', RTGETOPT_REQ_NOTHING },
+ { "-ignore", 'x', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--scsitype", 'T', RTGETOPT_REQ_UINT32 },
+ { "-scsitype", 'T', RTGETOPT_REQ_UINT32 }, // deprecated
+ { "--type", 'T', RTGETOPT_REQ_UINT32 }, // deprecated
+ { "-type", 'T', RTGETOPT_REQ_UINT32 }, // deprecated
+ { "--controller", 'C', RTGETOPT_REQ_STRING },
+ { "--port", 'E', RTGETOPT_REQ_STRING },
+ { "--disk", 'D', RTGETOPT_REQ_STRING },
+ { "--options", 'O', RTGETOPT_REQ_STRING },
+
+ { "--cloud", 'j', RTGETOPT_REQ_NOTHING},
+ { "--cloudprofile", 'k', RTGETOPT_REQ_STRING },
+ { "--cloudinstanceid", 'l', RTGETOPT_REQ_STRING },
+ { "--cloudbucket", 'B', RTGETOPT_REQ_STRING }
+};
+
+typedef enum APPLIANCETYPE
+{
+ NOT_SET, LOCAL, CLOUD
+} APPLIANCETYPE;
+
+RTEXITCODE handleImportAppliance(HandlerArg *arg)
+{
+ HRESULT hrc = S_OK;
+ APPLIANCETYPE enmApplType = NOT_SET;
+ Utf8Str strOvfFilename;
+ bool fExecute = true; // if true, then we actually do the import
+ com::SafeArray<ImportOptions_T> options;
+ uint32_t ulCurVsys = (uint32_t)-1;
+ uint32_t ulCurUnit = (uint32_t)-1;
+ // for each --vsys X command, maintain a map of command line items
+ // (we'll parse them later after interpreting the OVF, when we can
+ // actually check whether they make sense semantically)
+ ArgsMapsMap mapArgsMapsPerVsys;
+ IgnoresMapsMap mapIgnoresMapsPerVsys;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, arg->argc, arg->argv, g_aImportApplianceOptions, RT_ELEMENTS(g_aImportApplianceOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n': // --dry-run
+ fExecute = false;
+ break;
+
+ case 'P': // --detailed-progress
+ g_fDetailedProgress = true;
+ break;
+
+ case 's': // --vsys
+ if (enmApplType == NOT_SET)
+ enmApplType = LOCAL;
+
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" can't be used together with \"--cloud\" option."),
+ GetState.pDef->pszLong);
+ if (ValueUnion.u32 == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Value of option \"%s\" is out of range."),
+ GetState.pDef->pszLong);
+
+ ulCurVsys = ValueUnion.u32;
+ ulCurUnit = (uint32_t)-1;
+ break;
+
+ case 'o': // --ostype
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["ostype"] = ValueUnion.psz;
+ break;
+
+ case 'V': // --vmname
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["vmname"] = ValueUnion.psz;
+ break;
+
+ case 'S': // --settingsfile
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["settingsfile"] = ValueUnion.psz;
+ break;
+
+ case 'p': // --basefolder
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["basefolder"] = ValueUnion.psz;
+ break;
+
+ case 'g': // --group
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["group"] = ValueUnion.psz;
+ break;
+
+ case 'd': // --description
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
+ break;
+
+ case 'L': // --eula
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
+ break;
+
+ case 'm': // --memory
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["memory"] = ValueUnion.psz;
+ break;
+
+ case 'c': // --cpus
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cpus"] = ValueUnion.psz;
+ break;
+
+ case 'u': // --unit
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ValueUnion.u32 == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Value of option \"%s\" is out of range."),
+ GetState.pDef->pszLong);
+
+ ulCurUnit = ValueUnion.u32;
+ break;
+
+ case 'x': // --ignore
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ulCurUnit == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --unit option."),
+ GetState.pDef->pszLong);
+ mapIgnoresMapsPerVsys[ulCurVsys][ulCurUnit] = true;
+ break;
+
+ case 'T': // --scsitype
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ulCurUnit == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --unit option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys][Utf8StrFmt("scsitype%u", ulCurUnit)] = ValueUnion.psz;
+ break;
+
+ case 'C': // --controller
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ulCurUnit == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --unit option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys][Utf8StrFmt("controller%u", ulCurUnit)] = ValueUnion.psz;
+ break;
+
+ case 'E': // --port
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ulCurUnit == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --unit option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys][Utf8StrFmt("port%u", ulCurUnit)] = ValueUnion.psz;
+ break;
+
+ case 'D': // --disk
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ if (ulCurUnit == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --unit option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys][Utf8StrFmt("disk%u", ulCurUnit)] = ValueUnion.psz;
+ break;
+
+ case 'O': // --options
+ if (RT_FAILURE(parseImportOptions(ValueUnion.psz, &options)))
+ return errorArgument(Appliance::tr("Invalid import options '%s'\n"), ValueUnion.psz);
+ break;
+
+ /*--cloud and --vsys are orthogonal, only one must be presented*/
+ case 'j': // --cloud
+ if (enmApplType == NOT_SET)
+ enmApplType = CLOUD;
+
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" can't be used together with \"--vsys\" option."),
+ GetState.pDef->pszLong);
+
+ ulCurVsys = 0;
+ break;
+
+ /* Cloud export settings */
+ case 'k': // --cloudprofile
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"] = ValueUnion.psz;
+ break;
+
+ case 'l': // --cloudinstanceid
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"] = ValueUnion.psz;
+ break;
+
+ case 'B': // --cloudbucket
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudbucket"] = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (strOvfFilename.isEmpty())
+ strOvfFilename = ValueUnion.psz;
+ else
+ return errorSyntax(Appliance::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Appliance::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Appliance::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Appliance::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Appliance::tr("error: %Rrs"), c);
+ }
+ }
+
+ /* Last check after parsing all arguments */
+ if (strOvfFilename.isEmpty())
+ return errorSyntax(Appliance::tr("Not enough arguments for \"import\" command."));
+
+ if (enmApplType == NOT_SET)
+ enmApplType = LOCAL;
+
+ do
+ {
+ ComPtr<IAppliance> pAppliance;
+ CHECK_ERROR_BREAK(arg->virtualBox, CreateAppliance(pAppliance.asOutParam()));
+ //in the case of Cloud, append the instance id here because later it's harder to do
+ if (enmApplType == CLOUD)
+ {
+ try
+ {
+ /* Check presence of cloudprofile and cloudinstanceid in the map.
+ * If there isn't the exception is triggered. It's standard std:map logic.*/
+ ArgsMap a = mapArgsMapsPerVsys[ulCurVsys];
+ (void)a.at("cloudprofile");
+ (void)a.at("cloudinstanceid");
+ }
+ catch (...)
+ {
+ return errorSyntax(Appliance::tr("Not enough arguments for import from the Cloud."));
+ }
+
+ strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"]);
+ strOvfFilename.append("/");
+ strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"]);
+ }
+
+ char *pszAbsFilePath;
+ if (strOvfFilename.startsWith("S3://", RTCString::CaseInsensitive) ||
+ strOvfFilename.startsWith("SunCloud://", RTCString::CaseInsensitive) ||
+ strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive) ||
+ strOvfFilename.startsWith("OCI://", RTCString::CaseInsensitive))
+ pszAbsFilePath = RTStrDup(strOvfFilename.c_str());
+ else
+ pszAbsFilePath = RTPathAbsDup(strOvfFilename.c_str());
+
+ ComPtr<IProgress> progressRead;
+ CHECK_ERROR_BREAK(pAppliance, Read(Bstr(pszAbsFilePath).raw(),
+ progressRead.asOutParam()));
+ RTStrFree(pszAbsFilePath);
+
+ hrc = showProgress(progressRead);
+ CHECK_PROGRESS_ERROR_RET(progressRead, (Appliance::tr("Appliance read failed")), RTEXITCODE_FAILURE);
+
+ Bstr path; /* fetch the path, there is stuff like username/password removed if any */
+ CHECK_ERROR_BREAK(pAppliance, COMGETTER(Path)(path.asOutParam()));
+
+ size_t cVirtualSystemDescriptions = 0;
+ com::SafeIfaceArray<IVirtualSystemDescription> aVirtualSystemDescriptions;
+
+ if (enmApplType == LOCAL)
+ {
+ // call interpret(); this can yield both warnings and errors, so we need
+ // to tinker with the error info a bit
+ RTStrmPrintf(g_pStdErr, Appliance::tr("Interpreting %ls...\n"), path.raw());
+ hrc = pAppliance->Interpret();
+ com::ErrorInfoKeeper eik;
+
+ /** @todo r=klaus Eliminate this special way of signalling
+ * warnings which should be part of the ErrorInfo. */
+ com::SafeArray<BSTR> aWarnings;
+ if (SUCCEEDED(pAppliance->GetWarnings(ComSafeArrayAsOutParam(aWarnings))))
+ {
+ size_t cWarnings = aWarnings.size();
+ for (unsigned i = 0; i < cWarnings; ++i)
+ {
+ Bstr bstrWarning(aWarnings[i]);
+ RTMsgWarning("%ls", bstrWarning.raw());
+ }
+ }
+
+ eik.restore();
+ if (FAILED(hrc)) // during interpret, after printing warnings
+ {
+ com::GlueHandleComError(pAppliance, "Interpret()", hrc, __FILE__, __LINE__);
+ break;
+ }
+
+ RTStrmPrintf(g_pStdErr, "OK.\n");
+
+ // fetch all disks
+ com::SafeArray<BSTR> retDisks;
+ CHECK_ERROR_BREAK(pAppliance,
+ COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));
+ if (retDisks.size() > 0)
+ {
+ RTPrintf(Appliance::tr("Disks:\n"));
+ for (unsigned i = 0; i < retDisks.size(); i++)
+ RTPrintf(" %ls\n", retDisks[i]);
+ RTPrintf("\n");
+ }
+
+ // fetch virtual system descriptions
+ CHECK_ERROR_BREAK(pAppliance,
+ COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(aVirtualSystemDescriptions)));
+
+ cVirtualSystemDescriptions = aVirtualSystemDescriptions.size();
+
+ // match command line arguments with virtual system descriptions;
+ // this is only to sort out invalid indices at this time
+ ArgsMapsMap::const_iterator it;
+ for (it = mapArgsMapsPerVsys.begin();
+ it != mapArgsMapsPerVsys.end();
+ ++it)
+ {
+ uint32_t ulVsys = it->first;
+ if (ulVsys >= cVirtualSystemDescriptions)
+ return errorSyntax(Appliance::tr("Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).",
+ "", cVirtualSystemDescriptions),
+ ulVsys, cVirtualSystemDescriptions);
+ }
+ }
+ else if (enmApplType == CLOUD)
+ {
+ /* In the Cloud case the call of interpret() isn't needed because there isn't any OVF XML file.
+ * All info is got from the Cloud and VSD is filled inside IAppliance::read(). */
+ // fetch virtual system descriptions
+ CHECK_ERROR_BREAK(pAppliance,
+ COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(aVirtualSystemDescriptions)));
+
+ cVirtualSystemDescriptions = aVirtualSystemDescriptions.size();
+ }
+
+ uint32_t cLicensesInTheWay = 0;
+
+ // dump virtual system descriptions and match command-line arguments
+ if (cVirtualSystemDescriptions > 0)
+ {
+ for (unsigned i = 0; i < cVirtualSystemDescriptions; ++i)
+ {
+ com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
+ com::SafeArray<BSTR> aRefs;
+ com::SafeArray<BSTR> aOvfValues;
+ com::SafeArray<BSTR> aVBoxValues;
+ com::SafeArray<BSTR> aExtraConfigValues;
+ CHECK_ERROR_BREAK(aVirtualSystemDescriptions[i],
+ GetDescription(ComSafeArrayAsOutParam(retTypes),
+ ComSafeArrayAsOutParam(aRefs),
+ ComSafeArrayAsOutParam(aOvfValues),
+ ComSafeArrayAsOutParam(aVBoxValues),
+ ComSafeArrayAsOutParam(aExtraConfigValues)));
+
+ RTPrintf(Appliance::tr("Virtual system %u:\n"), i);
+
+ // look up the corresponding command line options, if any
+ ArgsMap *pmapArgs = NULL;
+ ArgsMapsMap::iterator itm = mapArgsMapsPerVsys.find(i);
+ if (itm != mapArgsMapsPerVsys.end())
+ pmapArgs = &itm->second;
+
+ // this collects the final values for setFinalValues()
+ com::SafeArray<BOOL> aEnabled(retTypes.size());
+ com::SafeArray<BSTR> aFinalValues(retTypes.size());
+
+ for (unsigned a = 0; a < retTypes.size(); ++a)
+ {
+ VirtualSystemDescriptionType_T t = retTypes[a];
+
+ Utf8Str strOverride;
+
+ Bstr bstrFinalValue = aVBoxValues[a];
+
+ bool fIgnoreThis = mapIgnoresMapsPerVsys[i][a];
+
+ aEnabled[a] = true;
+
+ switch (t)
+ {
+ case VirtualSystemDescriptionType_OS:
+ if (findArgValue(strOverride, pmapArgs, "ostype"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: OS type specified with --ostype: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested OS type: \"%ls\"\n"
+ " (change with \"--vsys %u --ostype <type>\"; use \"list ostypes\" to list all possible values)\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_Name:
+ if (findArgValue(strOverride, pmapArgs, "vmname"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: VM name specified with --vmname: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested VM name \"%ls\"\n"
+ " (change with \"--vsys %u --vmname <name>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_Product:
+ RTPrintf(Appliance::tr("%2u: Product (ignored): %ls\n"),
+ a, aVBoxValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_ProductUrl:
+ RTPrintf(Appliance::tr("%2u: ProductUrl (ignored): %ls\n"),
+ a, aVBoxValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_Vendor:
+ RTPrintf(Appliance::tr("%2u: Vendor (ignored): %ls\n"),
+ a, aVBoxValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_VendorUrl:
+ RTPrintf(Appliance::tr("%2u: VendorUrl (ignored): %ls\n"),
+ a, aVBoxValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_Version:
+ RTPrintf(Appliance::tr("%2u: Version (ignored): %ls\n"),
+ a, aVBoxValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_Description:
+ if (findArgValue(strOverride, pmapArgs, "description"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: Description specified with --description: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Description \"%ls\"\n"
+ " (change with \"--vsys %u --description <desc>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_License:
+ ++cLicensesInTheWay;
+ if (findArgValue(strOverride, pmapArgs, "eula"))
+ {
+ if (strOverride == "show")
+ {
+ RTPrintf(Appliance::tr("%2u: End-user license agreement\n"
+ " (accept with \"--vsys %u --eula accept\"):\n"
+ "\n%ls\n\n"),
+ a, i, bstrFinalValue.raw());
+ }
+ else if (strOverride == "accept")
+ {
+ RTPrintf(Appliance::tr("%2u: End-user license agreement (accepted)\n"),
+ a);
+ --cLicensesInTheWay;
+ }
+ else
+ return errorSyntax(Appliance::tr("Argument to --eula must be either \"show\" or \"accept\"."));
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: End-user license agreement\n"
+ " (display with \"--vsys %u --eula show\";\n"
+ " accept with \"--vsys %u --eula accept\")\n"),
+ a, i, i);
+ break;
+
+ case VirtualSystemDescriptionType_CPU:
+ if (findArgValue(strOverride, pmapArgs, "cpus"))
+ {
+ uint32_t cCPUs;
+ if ( strOverride.toInt(cCPUs) == VINF_SUCCESS
+ && cCPUs >= VMM_MIN_CPU_COUNT
+ && cCPUs <= VMM_MAX_CPU_COUNT
+ )
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: No. of CPUs specified with --cpus: %ls\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ return errorSyntax(Appliance::tr("Argument to --cpus option must be a number greater than %d and less than %d."),
+ VMM_MIN_CPU_COUNT - 1, VMM_MAX_CPU_COUNT + 1);
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Number of CPUs: %ls\n (change with \"--vsys %u --cpus <n>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_Memory:
+ {
+ if (findArgValue(strOverride, pmapArgs, "memory"))
+ {
+ uint32_t ulMemMB;
+ if (VINF_SUCCESS == strOverride.toInt(ulMemMB))
+ {
+ /* 'VBoxManage import --memory' size is in megabytes */
+ RTPrintf(Appliance::tr("%2u: Guest memory specified with --memory: %RU32 MB\n"),
+ a, ulMemMB);
+
+ /* IVirtualSystemDescription guest memory size is in bytes.
+ It's always stored in bytes in VSD according to the old internal agreement within the team */
+ uint64_t ullMemBytes = (uint64_t)ulMemMB * _1M;
+ strOverride = Utf8StrFmt("%RU64", ullMemBytes);
+ bstrFinalValue = strOverride;
+ }
+ else
+ return errorSyntax(Appliance::tr("Argument to --memory option must be a non-negative number."));
+ }
+ else
+ {
+ strOverride = aVBoxValues[a];
+ uint64_t ullMemMB = strOverride.toUInt64() / _1M;
+ RTPrintf(Appliance::tr("%2u: Guest memory: %RU64 MB\n (change with \"--vsys %u --memory <MB>\")\n"),
+ a, ullMemMB, i);
+ }
+ break;
+ }
+
+ case VirtualSystemDescriptionType_HardDiskControllerIDE:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: IDE controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: IDE controller, type %ls\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a);
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskControllerSATA:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: SATA controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: SATA controller, type %ls\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a);
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskControllerSAS:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: SAS controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: SAS controller, type %ls\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a);
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskControllerSCSI:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: SCSI controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ {
+ Utf8StrFmt strTypeArg("scsitype%u", a);
+ if (findArgValue(strOverride, pmapArgs, strTypeArg))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: SCSI controller, type set with --unit %u --scsitype: \"%ls\"\n"),
+ a,
+ a,
+ bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: SCSI controller, type %ls\n"
+ " (change with \"--vsys %u --unit %u --scsitype {BusLogic|LsiLogic}\";\n"
+ " disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a, i, a);
+ }
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskControllerVirtioSCSI:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: VirtioSCSI controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: VirtioSCSI controller, type %ls\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a);
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskControllerNVMe:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: NVMe controller, type %ls -- disabled\n"),
+ a,
+ aVBoxValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: NVMe controller, type %ls\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aVBoxValues[a],
+ i, a);
+ break;
+
+ case VirtualSystemDescriptionType_HardDiskImage:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image: source image=%ls -- disabled\n"),
+ a,
+ aOvfValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ {
+ Utf8StrFmt strTypeArg("disk%u", a);
+ bool fDiskChanged = false;
+ int vrc;
+ RTCList<ImportOptions_T> optionsList = options.toList();
+
+ if (findArgValue(strOverride, pmapArgs, strTypeArg))
+ {
+ if (optionsList.contains(ImportOptions_ImportToVDI))
+ return errorSyntax(Appliance::tr("Option --ImportToVDI can not be used together with a manually set target path."));
+ RTUUID uuid;
+ /* Check if this is a uuid. If so, don't touch. */
+ vrc = RTUuidFromStr(&uuid, strOverride.c_str());
+ if (vrc != VINF_SUCCESS)
+ {
+ /* Make the path absolute. */
+ if (!RTPathStartsWithRoot(strOverride.c_str()))
+ {
+ char pszPwd[RTPATH_MAX];
+ vrc = RTPathGetCurrent(pszPwd, RTPATH_MAX);
+ if (RT_SUCCESS(vrc))
+ strOverride = Utf8Str(pszPwd).append(RTPATH_SLASH).append(strOverride);
+ }
+ }
+ bstrFinalValue = strOverride;
+ fDiskChanged = true;
+ }
+
+ strTypeArg.printf("controller%u", a);
+ bool fControllerChanged = false;
+ uint32_t uTargetController = (uint32_t)-1;
+ VirtualSystemDescriptionType_T vsdControllerType = VirtualSystemDescriptionType_Ignore;
+ Utf8Str strExtraConfigValue;
+ if (findArgValue(strOverride, pmapArgs, strTypeArg))
+ {
+ vrc = getStorageControllerDetailsFromStr(strOverride, NULL, &uTargetController);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Appliance::tr("Invalid controller value: '%s'"),
+ strOverride.c_str());
+
+ vsdControllerType = retTypes[uTargetController];
+ if (!isStorageControllerType(vsdControllerType))
+ return errorSyntax(Appliance::tr("Invalid storage controller specified: %u"),
+ uTargetController);
+
+ fControllerChanged = true;
+ }
+
+ strTypeArg.printf("port%u", a);
+ bool fControllerPortChanged = false;
+ uint32_t uTargetControllerPort = (uint32_t)-1;;
+ if (findArgValue(strOverride, pmapArgs, strTypeArg))
+ {
+ vrc = getStorageControllerDetailsFromStr(strOverride, NULL, &uTargetControllerPort);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Appliance::tr("Invalid port value: '%s'"),
+ strOverride.c_str());
+
+ fControllerPortChanged = true;
+ }
+
+ /*
+ * aExtraConfigValues[a] has a format of 'controller=12;channel=0' and is set by
+ * Appliance::interpret() so any parsing errors here aren't due to user-supplied
+ * values so different error messages here.
+ */
+ uint32_t uOrigController;
+ Utf8Str strOrigController(Bstr(aExtraConfigValues[a]).raw());
+ vrc = getStorageControllerDetailsFromStr(strOrigController, "controller=", &uOrigController);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Appliance::tr("Failed to extract controller value from ExtraConfig: '%s'"),
+ strOrigController.c_str());
+
+ uint32_t uOrigControllerPort;
+ vrc = getStorageControllerDetailsFromStr(strOrigController, "channel=", &uOrigControllerPort);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Appliance::tr("Failed to extract channel value from ExtraConfig: '%s'"),
+ strOrigController.c_str());
+
+ /*
+ * The 'strExtraConfigValue' string is used to display the storage controller and
+ * port details for each virtual hard disk using the more accurate 'controller=' and
+ * 'port=' labels. The aExtraConfigValues[a] string has a format of
+ * 'controller=%u;channel=%u' from Appliance::interpret() which is required as per
+ * the API but for consistency and clarity with the CLI options --controller and
+ * --port we instead use strExtraConfigValue in the output below.
+ */
+ strExtraConfigValue = Utf8StrFmt("controller=%u;port=%u", uOrigController, uOrigControllerPort);
+
+ if (fControllerChanged || fControllerPortChanged)
+ {
+ /*
+ * Verify that the new combination of controller and controller port is valid.
+ * cf. StorageController::i_checkPortAndDeviceValid()
+ */
+ if (uTargetControllerPort == (uint32_t)-1)
+ uTargetControllerPort = uOrigControllerPort;
+ if (uTargetController == (uint32_t)-1)
+ uTargetController = uOrigController;
+
+ if ( uOrigController == uTargetController
+ && uOrigControllerPort == uTargetControllerPort)
+ return errorSyntax(Appliance::tr("Device already attached to controller %u at this port (%u) location."),
+ uTargetController,
+ uTargetControllerPort);
+
+ if (vsdControllerType == VirtualSystemDescriptionType_Ignore)
+ vsdControllerType = retTypes[uOrigController];
+ if (!isStorageControllerType(vsdControllerType))
+ return errorSyntax(Appliance::tr("Invalid storage controller specified: %u"),
+ uOrigController);
+
+ ComPtr<IVirtualBox> pVirtualBox = arg->virtualBox;
+ ComPtr<ISystemProperties> systemProperties;
+ CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()));
+ ULONG maxPorts = 0;
+ StorageBus_T enmStorageBus = StorageBus_Null;;
+ switch (vsdControllerType)
+ {
+ case VirtualSystemDescriptionType_HardDiskControllerIDE:
+ enmStorageBus = StorageBus_IDE;
+ break;
+ case VirtualSystemDescriptionType_HardDiskControllerSATA:
+ enmStorageBus = StorageBus_SATA;
+ break;
+ case VirtualSystemDescriptionType_HardDiskControllerSCSI:
+ enmStorageBus = StorageBus_SCSI;
+ break;
+ case VirtualSystemDescriptionType_HardDiskControllerSAS:
+ enmStorageBus = StorageBus_SAS;
+ break;
+ case VirtualSystemDescriptionType_HardDiskControllerVirtioSCSI:
+ enmStorageBus = StorageBus_VirtioSCSI;
+ break;
+ default: // Not reached since vsdControllerType validated above but silence gcc.
+ break;
+ }
+ CHECK_ERROR_RET(systemProperties, GetMaxPortCountForStorageBus(enmStorageBus, &maxPorts),
+ RTEXITCODE_FAILURE);
+ if (uTargetControllerPort >= maxPorts)
+ return errorSyntax(Appliance::tr("Illegal port value: %u. For %ls controllers the only valid values are 0 to %lu (inclusive)"),
+ uTargetControllerPort,
+ aVBoxValues[uTargetController],
+ maxPorts);
+
+ /*
+ * The 'strOverride' string will be mapped to the strExtraConfigCurrent value in
+ * VirtualSystemDescription::setFinalValues() which is then used in the appliance
+ * import routines i_importVBoxMachine()/i_importMachineGeneric() later. This
+ * aExtraConfigValues[] array entry must have a format of
+ * 'controller=<index>;channel=<c>' as per the API documentation.
+ */
+ strExtraConfigValue = Utf8StrFmt("controller=%u;port=%u", uTargetController,
+ uTargetControllerPort);
+ strOverride = Utf8StrFmt("controller=%u;channel=%u", uTargetController,
+ uTargetControllerPort);
+ Bstr bstrExtraConfigValue = strOverride;
+ bstrExtraConfigValue.detachTo(&aExtraConfigValues[a]);
+ }
+
+ if (fDiskChanged && !fControllerChanged && !fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --disk: source image=%ls, target path=%ls, %s\n"
+ " (change controller with \"--vsys %u --unit %u --controller <index>\";\n"
+ " change controller port with \"--vsys %u --unit %u --port <n>\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a,
+ i, a);
+ }
+ else if (fDiskChanged && fControllerChanged && !fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --disk and --controller: source image=%ls, target path=%ls, %s\n"
+ " (change controller port with \"--vsys %u --unit %u --port <n>\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a);
+ }
+ else if (fDiskChanged && !fControllerChanged && fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --disk and --port: source image=%ls, target path=%ls, %s\n"
+ " (change controller with \"--vsys %u --unit %u --controller <index>\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a);
+ }
+ else if (!fDiskChanged && fControllerChanged && fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --controller and --port: source image=%ls, target path=%ls, %s\n"
+ " (change target path with \"--vsys %u --unit %u --disk path\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a);
+ }
+ else if (!fDiskChanged && !fControllerChanged && fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --port: source image=%ls, target path=%ls, %s\n"
+ " (change target path with \"--vsys %u --unit %u --disk path\";\n"
+ " change controller with \"--vsys %u --unit %u --controller <index>\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a,
+ i, a);
+ }
+ else if (!fDiskChanged && fControllerChanged && !fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --controller: source image=%ls, target path=%ls, %s\n"
+ " (change target path with \"--vsys %u --unit %u --disk path\";\n"
+ " change controller port with \"--vsys %u --unit %u --port <n>\")\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str(),
+ i, a,
+ i, a);
+ }
+ else if (fDiskChanged && fControllerChanged && fControllerPortChanged)
+ {
+ RTPrintf(Appliance::tr("%2u: Hard disk image specified with --disk and --controller and --port: source image=%ls, target path=%ls, %s\n"),
+ a,
+ aOvfValues[a],
+ bstrFinalValue.raw(),
+ strExtraConfigValue.c_str());
+ }
+ else
+ {
+ strOverride = aVBoxValues[a];
+
+ /*
+ * Current solution isn't optimal.
+ * Better way is to provide API call for function
+ * Appliance::i_findMediumFormatFromDiskImage()
+ * and creating one new function which returns
+ * struct ovf::DiskImage for currently processed disk.
+ */
+
+ /*
+ * if user wants to convert all imported disks to VDI format
+ * we need to replace files extensions to "vdi"
+ * except CD/DVD disks
+ */
+ if (optionsList.contains(ImportOptions_ImportToVDI))
+ {
+ ComPtr<IVirtualBox> pVirtualBox = arg->virtualBox;
+ ComPtr<ISystemProperties> systemProperties;
+ com::SafeIfaceArray<IMediumFormat> mediumFormats;
+ Bstr bstrFormatName;
+
+ CHECK_ERROR(pVirtualBox,
+ COMGETTER(SystemProperties)(systemProperties.asOutParam()));
+
+ CHECK_ERROR(systemProperties,
+ COMGETTER(MediumFormats)(ComSafeArrayAsOutParam(mediumFormats)));
+
+ /* go through all supported media formats and store files extensions only for RAW */
+ com::SafeArray<BSTR> extensions;
+
+ for (unsigned j = 0; j < mediumFormats.size(); ++j)
+ {
+ com::SafeArray<DeviceType_T> deviceType;
+ ComPtr<IMediumFormat> mediumFormat = mediumFormats[j];
+ CHECK_ERROR(mediumFormat, COMGETTER(Name)(bstrFormatName.asOutParam()));
+ Utf8Str strFormatName = Utf8Str(bstrFormatName);
+
+ if (strFormatName.compare("RAW", Utf8Str::CaseInsensitive) == 0)
+ {
+ /* getting files extensions for "RAW" format */
+ CHECK_ERROR(mediumFormat,
+ DescribeFileExtensions(ComSafeArrayAsOutParam(extensions),
+ ComSafeArrayAsOutParam(deviceType)));
+ break;
+ }
+ }
+
+ /* go through files extensions for RAW format and compare them with
+ * extension of current file
+ */
+ bool fReplace = true;
+
+ const char *pszExtension = RTPathSuffix(strOverride.c_str());
+ if (pszExtension)
+ pszExtension++;
+
+ for (unsigned j = 0; j < extensions.size(); ++j)
+ {
+ Bstr bstrExt(extensions[j]);
+ Utf8Str strExtension(bstrExt);
+ if(strExtension.compare(pszExtension, Utf8Str::CaseInsensitive) == 0)
+ {
+ fReplace = false;
+ break;
+ }
+ }
+
+ if (fReplace)
+ {
+ strOverride = strOverride.stripSuffix();
+ strOverride = strOverride.append(".").append("vdi");
+ }
+ }
+
+ bstrFinalValue = strOverride;
+
+ RTPrintf(Appliance::tr("%2u: Hard disk image: source image=%ls, target path=%ls, %s\n"
+ " (change target path with \"--vsys %u --unit %u --disk path\";\n"
+ " change controller with \"--vsys %u --unit %u --controller <index>\";\n"
+ " change controller port with \"--vsys %u --unit %u --port <n>\";\n"
+ " disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a, aOvfValues[a], bstrFinalValue.raw(), strExtraConfigValue.c_str(),
+ i, a,
+ i, a,
+ i, a,
+ i, a);
+ }
+ }
+ break;
+
+ case VirtualSystemDescriptionType_CDROM:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: CD-ROM -- disabled\n"),
+ a);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: CD-ROM\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a, i, a);
+ break;
+
+ case VirtualSystemDescriptionType_Floppy:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: Floppy -- disabled\n"),
+ a);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Floppy\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a, i, a);
+ break;
+
+ case VirtualSystemDescriptionType_NetworkAdapter:
+ RTPrintf(Appliance::tr("%2u: Network adapter: orig %ls, config %ls, extra %ls\n"), /// @todo implement once we have a plan for the back-end
+ a,
+ aOvfValues[a],
+ aVBoxValues[a],
+ aExtraConfigValues[a]);
+ break;
+
+ case VirtualSystemDescriptionType_USBController:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: USB controller -- disabled\n"),
+ a);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: USB controller\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a, i, a);
+ break;
+
+ case VirtualSystemDescriptionType_SoundCard:
+ if (fIgnoreThis)
+ {
+ RTPrintf(Appliance::tr("%2u: Sound card \"%ls\" -- disabled\n"),
+ a,
+ aOvfValues[a]);
+ aEnabled[a] = false;
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Sound card (appliance expects \"%ls\", can change on import)\n"
+ " (disable with \"--vsys %u --unit %u --ignore\")\n"),
+ a,
+ aOvfValues[a],
+ i,
+ a);
+ break;
+
+ case VirtualSystemDescriptionType_SettingsFile:
+ if (findArgValue(strOverride, pmapArgs, "settingsfile"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: VM settings file name specified with --settingsfile: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested VM settings file name \"%ls\"\n"
+ " (change with \"--vsys %u --settingsfile <filename>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_BaseFolder:
+ if (findArgValue(strOverride, pmapArgs, "basefolder"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: VM base folder specified with --basefolder: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested VM base folder \"%ls\"\n"
+ " (change with \"--vsys %u --basefolder <path>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_PrimaryGroup:
+ if (findArgValue(strOverride, pmapArgs, "group"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: VM group specified with --group: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested VM group \"%ls\"\n"
+ " (change with \"--vsys %u --group <group>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_CloudInstanceShape:
+ RTPrintf(Appliance::tr("%2u: Suggested cloud shape \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ break;
+
+ case VirtualSystemDescriptionType_CloudBucket:
+ if (findArgValue(strOverride, pmapArgs, "cloudbucket"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: Cloud bucket id specified with --cloudbucket: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested cloud bucket id \"%ls\"\n"
+ " (change with \"--cloud %u --cloudbucket <id>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_CloudProfileName:
+ if (findArgValue(strOverride, pmapArgs, "cloudprofile"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: Cloud profile name specified with --cloudprofile: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested cloud profile name \"%ls\"\n"
+ " (change with \"--cloud %u --cloudprofile <id>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_CloudInstanceId:
+ if (findArgValue(strOverride, pmapArgs, "cloudinstanceid"))
+ {
+ bstrFinalValue = strOverride;
+ RTPrintf(Appliance::tr("%2u: Cloud instance id specified with --cloudinstanceid: \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ }
+ else
+ RTPrintf(Appliance::tr("%2u: Suggested cloud instance id \"%ls\"\n"
+ " (change with \"--cloud %u --cloudinstanceid <id>\")\n"),
+ a, bstrFinalValue.raw(), i);
+ break;
+
+ case VirtualSystemDescriptionType_CloudImageId:
+ RTPrintf(Appliance::tr("%2u: Suggested cloud base image id \"%ls\"\n"),
+ a, bstrFinalValue.raw());
+ break;
+ case VirtualSystemDescriptionType_CloudDomain:
+ case VirtualSystemDescriptionType_CloudBootDiskSize:
+ case VirtualSystemDescriptionType_CloudOCIVCN:
+ case VirtualSystemDescriptionType_CloudPublicIP:
+ case VirtualSystemDescriptionType_CloudOCISubnet:
+ case VirtualSystemDescriptionType_CloudKeepObject:
+ case VirtualSystemDescriptionType_CloudLaunchInstance:
+ case VirtualSystemDescriptionType_CloudInstanceState:
+ case VirtualSystemDescriptionType_CloudImageState:
+ case VirtualSystemDescriptionType_Miscellaneous:
+ case VirtualSystemDescriptionType_CloudInstanceDisplayName:
+ case VirtualSystemDescriptionType_CloudImageDisplayName:
+ case VirtualSystemDescriptionType_CloudOCILaunchMode:
+ case VirtualSystemDescriptionType_CloudPrivateIP:
+ case VirtualSystemDescriptionType_CloudBootVolumeId:
+ case VirtualSystemDescriptionType_CloudOCIVCNCompartment:
+ case VirtualSystemDescriptionType_CloudOCISubnetCompartment:
+ case VirtualSystemDescriptionType_CloudPublicSSHKey:
+ case VirtualSystemDescriptionType_BootingFirmware:
+ case VirtualSystemDescriptionType_CloudInitScriptPath:
+ case VirtualSystemDescriptionType_CloudCompartmentId:
+ case VirtualSystemDescriptionType_CloudShapeCpus:
+ case VirtualSystemDescriptionType_CloudShapeMemory:
+ case VirtualSystemDescriptionType_CloudInstanceMetadata:
+ case VirtualSystemDescriptionType_CloudInstanceFreeFormTags:
+ case VirtualSystemDescriptionType_CloudImageFreeFormTags:
+ /** @todo VirtualSystemDescriptionType_Miscellaneous? */
+ break;
+
+ case VirtualSystemDescriptionType_Ignore:
+#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
+ case VirtualSystemDescriptionType_32BitHack:
+#endif
+ break;
+ }
+
+ bstrFinalValue.detachTo(&aFinalValues[a]);
+ }
+
+ if (fExecute)
+ CHECK_ERROR_BREAK(aVirtualSystemDescriptions[i],
+ SetFinalValues(ComSafeArrayAsInParam(aEnabled),
+ ComSafeArrayAsInParam(aFinalValues),
+ ComSafeArrayAsInParam(aExtraConfigValues)));
+
+ } // for (unsigned i = 0; i < cVirtualSystemDescriptions; ++i)
+
+ if (cLicensesInTheWay == 1)
+ RTMsgError(Appliance::tr("Cannot import until the license agreement listed above is accepted."));
+ else if (cLicensesInTheWay > 1)
+ RTMsgError(Appliance::tr("Cannot import until the %c license agreements listed above are accepted."),
+ cLicensesInTheWay);
+
+ if (!cLicensesInTheWay && fExecute)
+ {
+ // go!
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_BREAK(pAppliance,
+ ImportMachines(ComSafeArrayAsInParam(options), progress.asOutParam()));
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Appliance::tr("Appliance import failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Appliance::tr("Successfully imported the appliance.\n"));
+ }
+ } // end if (aVirtualSystemDescriptions.size() > 0)
+ } while (0);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static int parseExportOptions(const char *psz, com::SafeArray<ExportOptions_T> *options)
+{
+ int vrc = VINF_SUCCESS;
+ while (psz && *psz && RT_SUCCESS(vrc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "CreateManifest", len))
+ options->push_back(ExportOptions_CreateManifest);
+ else if (!RTStrNICmp(psz, "manifest", len))
+ options->push_back(ExportOptions_CreateManifest);
+ else if (!RTStrNICmp(psz, "ExportDVDImages", len))
+ options->push_back(ExportOptions_ExportDVDImages);
+ else if (!RTStrNICmp(psz, "iso", len))
+ options->push_back(ExportOptions_ExportDVDImages);
+ else if (!RTStrNICmp(psz, "StripAllMACs", len))
+ options->push_back(ExportOptions_StripAllMACs);
+ else if (!RTStrNICmp(psz, "nomacs", len))
+ options->push_back(ExportOptions_StripAllMACs);
+ else if (!RTStrNICmp(psz, "StripAllNonNATMACs", len))
+ options->push_back(ExportOptions_StripAllNonNATMACs);
+ else if (!RTStrNICmp(psz, "nomacsbutnat", len))
+ options->push_back(ExportOptions_StripAllNonNATMACs);
+ else
+ vrc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ return vrc;
+}
+
+static const RTGETOPTDEF g_aExportOptions[] =
+{
+ { "--output", 'o', RTGETOPT_REQ_STRING },
+ { "--legacy09", 'l', RTGETOPT_REQ_NOTHING },
+ { "--ovf09", 'l', RTGETOPT_REQ_NOTHING },
+ { "--ovf10", '1', RTGETOPT_REQ_NOTHING },
+ { "--ovf20", '2', RTGETOPT_REQ_NOTHING },
+ { "--opc10", 'c', RTGETOPT_REQ_NOTHING },
+ { "--manifest", 'm', RTGETOPT_REQ_NOTHING }, // obsoleted by --options
+ { "--vsys", 's', RTGETOPT_REQ_UINT32 },
+ { "--vmname", 'V', RTGETOPT_REQ_STRING },
+ { "--product", 'p', RTGETOPT_REQ_STRING },
+ { "--producturl", 'P', RTGETOPT_REQ_STRING },
+ { "--vendor", 'n', RTGETOPT_REQ_STRING },
+ { "--vendorurl", 'N', RTGETOPT_REQ_STRING },
+ { "--version", 'v', RTGETOPT_REQ_STRING },
+ { "--description", 'd', RTGETOPT_REQ_STRING },
+ { "--eula", 'e', RTGETOPT_REQ_STRING },
+ { "--eulafile", 'E', RTGETOPT_REQ_STRING },
+ { "--options", 'O', RTGETOPT_REQ_STRING },
+ { "--cloud", 'C', RTGETOPT_REQ_UINT32 },
+ { "--cloudshape", 'S', RTGETOPT_REQ_STRING },
+ { "--clouddomain", 'D', RTGETOPT_REQ_STRING },
+ { "--clouddisksize", 'R', RTGETOPT_REQ_STRING },
+ { "--cloudbucket", 'B', RTGETOPT_REQ_STRING },
+ { "--cloudocivcn", 'Q', RTGETOPT_REQ_STRING },
+ { "--cloudpublicip", 'A', RTGETOPT_REQ_STRING },
+ { "--cloudprofile", 'F', RTGETOPT_REQ_STRING },
+ { "--cloudocisubnet", 'T', RTGETOPT_REQ_STRING },
+ { "--cloudkeepobject", 'K', RTGETOPT_REQ_STRING },
+ { "--cloudlaunchinstance", 'L', RTGETOPT_REQ_STRING },
+ { "--cloudlaunchmode", 'M', RTGETOPT_REQ_STRING },
+ { "--cloudprivateip", 'i', RTGETOPT_REQ_STRING },
+ { "--cloudinitscriptpath", 'I', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleExportAppliance(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ Utf8Str strOutputFile;
+ Utf8Str strOvfFormat("ovf-1.0"); // the default export version
+ bool fManifest = false; // the default
+ APPLIANCETYPE enmApplType = NOT_SET;
+ bool fExportISOImages = false; // the default
+ com::SafeArray<ExportOptions_T> options;
+ std::list< ComPtr<IMachine> > llMachines;
+
+ uint32_t ulCurVsys = (uint32_t)-1;
+ // for each --vsys X command, maintain a map of command line items
+ ArgsMapsMap mapArgsMapsPerVsys;
+ do
+ {
+ int c;
+
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aExportOptions,
+ RT_ELEMENTS(g_aExportOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ Utf8Str strProductUrl;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'o': // --output
+ if (strOutputFile.length())
+ return errorSyntax(Appliance::tr("You can only specify --output once."));
+ else
+ strOutputFile = ValueUnion.psz;
+ break;
+
+ case 'l': // --legacy09/--ovf09
+ strOvfFormat = "ovf-0.9";
+ break;
+
+ case '1': // --ovf10
+ strOvfFormat = "ovf-1.0";
+ break;
+
+ case '2': // --ovf20
+ strOvfFormat = "ovf-2.0";
+ break;
+
+ case 'c': // --opc
+ strOvfFormat = "opc-1.0";
+ break;
+
+// case 'I': // --iso
+// fExportISOImages = true;
+// break;
+
+ case 'm': // --manifest
+ fManifest = true;
+ break;
+
+ case 's': // --vsys
+ if (enmApplType == NOT_SET)
+ enmApplType = LOCAL;
+
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" can't be used together with \"--cloud\" option."),
+ GetState.pDef->pszLong);
+ if (ValueUnion.u32 == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Value of option \"%s\" is out of range."),
+ GetState.pDef->pszLong);
+
+ ulCurVsys = ValueUnion.u32;
+ break;
+
+ case 'V': // --vmname
+ if (enmApplType == NOT_SET)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys or --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["vmname"] = ValueUnion.psz;
+ break;
+
+ case 'p': // --product
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["product"] = ValueUnion.psz;
+ break;
+
+ case 'P': // --producturl
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["producturl"] = ValueUnion.psz;
+ break;
+
+ case 'n': // --vendor
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["vendor"] = ValueUnion.psz;
+ break;
+
+ case 'N': // --vendorurl
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["vendorurl"] = ValueUnion.psz;
+ break;
+
+ case 'v': // --version
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["version"] = ValueUnion.psz;
+ break;
+
+ case 'd': // --description
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz;
+ break;
+
+ case 'e': // --eula
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz;
+ break;
+
+ case 'E': // --eulafile
+ if (enmApplType != LOCAL)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --vsys option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["eulafile"] = ValueUnion.psz;
+ break;
+
+ case 'O': // --options
+ if (RT_FAILURE(parseExportOptions(ValueUnion.psz, &options)))
+ return errorArgument(Appliance::tr("Invalid export options '%s'\n"), ValueUnion.psz);
+ break;
+
+ /*--cloud and --vsys are orthogonal, only one must be presented*/
+ case 'C': // --cloud
+ if (enmApplType == NOT_SET)
+ enmApplType = CLOUD;
+
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" can't be used together with \"--vsys\" option."),
+ GetState.pDef->pszLong);
+ if (ValueUnion.u32 == (uint32_t)-1)
+ return errorSyntax(Appliance::tr("Value of option \"%s\" is out of range."),
+ GetState.pDef->pszLong);
+
+ ulCurVsys = ValueUnion.u32;
+ break;
+
+ /* Cloud export settings */
+ case 'S': // --cloudshape
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudshape"] = ValueUnion.psz;
+ break;
+
+ case 'D': // --clouddomain
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["clouddomain"] = ValueUnion.psz;
+ break;
+
+ case 'R': // --clouddisksize
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["clouddisksize"] = ValueUnion.psz;
+ break;
+
+ case 'B': // --cloudbucket
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudbucket"] = ValueUnion.psz;
+ break;
+
+ case 'Q': // --cloudocivcn
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudocivcn"] = ValueUnion.psz;
+ break;
+
+ case 'A': // --cloudpublicip
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudpublicip"] = ValueUnion.psz;
+ break;
+
+ case 'i': /* --cloudprivateip */
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudprivateip"] = ValueUnion.psz;
+ break;
+
+ case 'F': // --cloudprofile
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"] = ValueUnion.psz;
+ break;
+
+ case 'T': // --cloudocisubnet
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudocisubnet"] = ValueUnion.psz;
+ break;
+
+ case 'K': // --cloudkeepobject
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudkeepobject"] = ValueUnion.psz;
+ break;
+
+ case 'L': // --cloudlaunchinstance
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudlaunchinstance"] = ValueUnion.psz;
+ break;
+
+ case 'M': /* --cloudlaunchmode */
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudlaunchmode"] = ValueUnion.psz;
+ break;
+
+ case 'I': // --cloudinitscriptpath
+ if (enmApplType != CLOUD)
+ return errorSyntax(Appliance::tr("Option \"%s\" requires preceding --cloud option."),
+ GetState.pDef->pszLong);
+ mapArgsMapsPerVsys[ulCurVsys]["cloudinitscriptpath"] = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ Utf8Str strMachine(ValueUnion.psz);
+ // must be machine: try UUID or name
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_BREAK(a->virtualBox, FindMachine(Bstr(strMachine).raw(),
+ machine.asOutParam()));
+ if (machine)
+ llMachines.push_back(machine);
+ break;
+ }
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_GRAPH(c))
+ return errorSyntax(Appliance::tr("unhandled option: -%c"), c);
+ else
+ return errorSyntax(Appliance::tr("unhandled option: %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Appliance::tr("unknown option: %s"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax("%Rrs", c);
+ }
+
+ if (FAILED(hrc))
+ break;
+ }
+
+ if (FAILED(hrc))
+ break;
+
+ if (llMachines.empty())
+ return errorSyntax(Appliance::tr("At least one machine must be specified with the export command."));
+
+ /* Last check after parsing all arguments */
+ if (strOutputFile.isEmpty())
+ return errorSyntax(Appliance::tr("Missing --output argument with export command."));
+
+ if (enmApplType == NOT_SET)
+ enmApplType = LOCAL;
+
+ // match command line arguments with the machines count
+ // this is only to sort out invalid indices at this time
+ ArgsMapsMap::const_iterator it;
+ for (it = mapArgsMapsPerVsys.begin();
+ it != mapArgsMapsPerVsys.end();
+ ++it)
+ {
+ uint32_t ulVsys = it->first;
+ if (ulVsys >= llMachines.size())
+ return errorSyntax(Appliance::tr("Invalid index %RI32 with -vsys option; you specified only %zu virtual system(s).",
+ "", llMachines.size()),
+ ulVsys, llMachines.size());
+ }
+
+ ComPtr<IAppliance> pAppliance;
+ CHECK_ERROR_BREAK(a->virtualBox, CreateAppliance(pAppliance.asOutParam()));
+
+ char *pszAbsFilePath = 0;
+ if (strOutputFile.startsWith("S3://", RTCString::CaseInsensitive) ||
+ strOutputFile.startsWith("SunCloud://", RTCString::CaseInsensitive) ||
+ strOutputFile.startsWith("webdav://", RTCString::CaseInsensitive) ||
+ strOutputFile.startsWith("OCI://", RTCString::CaseInsensitive))
+ pszAbsFilePath = RTStrDup(strOutputFile.c_str());
+ else
+ pszAbsFilePath = RTPathAbsDup(strOutputFile.c_str());
+
+ /*
+ * The first stage - export machine/s to the Cloud or into the
+ * OVA/OVF format on the local host.
+ */
+
+ /* VSDList is needed for the second stage where we launch the cloud instances if it was requested by user */
+ std::list< ComPtr<IVirtualSystemDescription> > VSDList;
+ std::list< ComPtr<IMachine> >::iterator itM;
+ uint32_t i=0;
+ for (itM = llMachines.begin();
+ itM != llMachines.end();
+ ++itM, ++i)
+ {
+ ComPtr<IMachine> pMachine = *itM;
+ ComPtr<IVirtualSystemDescription> pVSD;
+ CHECK_ERROR_BREAK(pMachine, ExportTo(pAppliance, Bstr(pszAbsFilePath).raw(), pVSD.asOutParam()));
+
+ // Add additional info to the virtual system description if the user wants so
+ ArgsMap *pmapArgs = NULL;
+ ArgsMapsMap::iterator itm = mapArgsMapsPerVsys.find(i);
+ if (itm != mapArgsMapsPerVsys.end())
+ pmapArgs = &itm->second;
+ if (pmapArgs)
+ {
+ ArgsMap::iterator itD;
+ for (itD = pmapArgs->begin();
+ itD != pmapArgs->end();
+ ++itD)
+ {
+ if (itD->first == "vmname")
+ {
+ //remove default value if user has specified new name (default value is set in the ExportTo())
+// pVSD->RemoveDescriptionByType(VirtualSystemDescriptionType_Name);
+ pVSD->AddDescription(VirtualSystemDescriptionType_Name,
+ Bstr(itD->second).raw(), NULL);
+ }
+ else if (itD->first == "product")
+ pVSD->AddDescription(VirtualSystemDescriptionType_Product,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "producturl")
+ pVSD->AddDescription(VirtualSystemDescriptionType_ProductUrl,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "vendor")
+ pVSD->AddDescription(VirtualSystemDescriptionType_Vendor,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "vendorurl")
+ pVSD->AddDescription(VirtualSystemDescriptionType_VendorUrl,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "version")
+ pVSD->AddDescription(VirtualSystemDescriptionType_Version,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "description")
+ pVSD->AddDescription(VirtualSystemDescriptionType_Description,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "eula")
+ pVSD->AddDescription(VirtualSystemDescriptionType_License,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "eulafile")
+ {
+ Utf8Str strContent;
+ void *pvFile;
+ size_t cbFile;
+ int irc = RTFileReadAll(itD->second.c_str(), &pvFile, &cbFile);
+ if (RT_SUCCESS(irc))
+ {
+ Bstr bstrContent((char*)pvFile, cbFile);
+ pVSD->AddDescription(VirtualSystemDescriptionType_License,
+ bstrContent.raw(), NULL);
+ RTFileReadAllFree(pvFile, cbFile);
+ }
+ else
+ {
+ RTMsgError(Appliance::tr("Cannot read license file \"%s\" which should be included in the virtual system %u."),
+ itD->second.c_str(), i);
+ return RTEXITCODE_FAILURE;
+ }
+ }
+ /* add cloud export settings */
+ else if (itD->first == "cloudshape")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudInstanceShape,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "clouddomain")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudDomain,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "clouddisksize")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudBootDiskSize,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudbucket")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudBucket,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudocivcn")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudOCIVCN,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudpublicip")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudPublicIP,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudprivateip")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudPrivateIP,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudprofile")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudProfileName,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudocisubnet")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudOCISubnet,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudkeepobject")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudKeepObject,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudlaunchmode")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudOCILaunchMode,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudlaunchinstance")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudLaunchInstance,
+ Bstr(itD->second).raw(), NULL);
+ else if (itD->first == "cloudinitscriptpath")
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudInitScriptPath,
+ Bstr(itD->second).raw(), NULL);
+
+ }
+ }
+
+ VSDList.push_back(pVSD);//store vsd for the possible second stage
+ }
+
+ if (FAILED(hrc))
+ break;
+
+ /* Query required passwords and supply them to the appliance. */
+ com::SafeArray<BSTR> aIdentifiers;
+
+ CHECK_ERROR_BREAK(pAppliance, GetPasswordIds(ComSafeArrayAsOutParam(aIdentifiers)));
+
+ if (aIdentifiers.size() > 0)
+ {
+ com::SafeArray<BSTR> aPasswords(aIdentifiers.size());
+ RTPrintf(Appliance::tr("Enter the passwords for the following identifiers to export the apppliance:\n"));
+ for (unsigned idxId = 0; idxId < aIdentifiers.size(); idxId++)
+ {
+ com::Utf8Str strPassword;
+ Bstr bstrPassword;
+ Bstr bstrId = aIdentifiers[idxId];
+
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, Appliance::tr("Password ID %s:"),
+ Utf8Str(bstrId).c_str());
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTStrFree(pszAbsFilePath);
+ return rcExit;
+ }
+
+ bstrPassword = strPassword;
+ bstrPassword.detachTo(&aPasswords[idxId]);
+ }
+
+ CHECK_ERROR_BREAK(pAppliance, AddPasswords(ComSafeArrayAsInParam(aIdentifiers),
+ ComSafeArrayAsInParam(aPasswords)));
+ }
+
+ if (fManifest)
+ options.push_back(ExportOptions_CreateManifest);
+
+ if (fExportISOImages)
+ options.push_back(ExportOptions_ExportDVDImages);
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_BREAK(pAppliance, Write(Bstr(strOvfFormat).raw(),
+ ComSafeArrayAsInParam(options),
+ Bstr(pszAbsFilePath).raw(),
+ progress.asOutParam()));
+ RTStrFree(pszAbsFilePath);
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Appliance::tr("Appliance write failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Appliance::tr("Successfully exported %d machine(s).\n", "", llMachines.size()), llMachines.size());
+
+ /*
+ * The second stage for the cloud case
+ */
+ if (enmApplType == CLOUD)
+ {
+ /* Launch the exported VM if the appropriate flag had been set on the first stage */
+ for (std::list< ComPtr<IVirtualSystemDescription> >::iterator itVSD = VSDList.begin();
+ itVSD != VSDList.end();
+ ++itVSD)
+ {
+ ComPtr<IVirtualSystemDescription> pVSD = *itVSD;
+
+ com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
+ com::SafeArray<BSTR> aRefs;
+ com::SafeArray<BSTR> aOvfValues;
+ com::SafeArray<BSTR> aVBoxValues;
+ com::SafeArray<BSTR> aExtraConfigValues;
+
+ CHECK_ERROR_BREAK(pVSD, GetDescriptionByType(VirtualSystemDescriptionType_CloudLaunchInstance,
+ ComSafeArrayAsOutParam(retTypes),
+ ComSafeArrayAsOutParam(aRefs),
+ ComSafeArrayAsOutParam(aOvfValues),
+ ComSafeArrayAsOutParam(aVBoxValues),
+ ComSafeArrayAsOutParam(aExtraConfigValues)));
+
+ Utf8Str flagCloudLaunchInstance(Bstr(aVBoxValues[0]).raw());
+ retTypes.setNull(); aRefs.setNull(); aOvfValues.setNull(); aVBoxValues.setNull(); aExtraConfigValues.setNull();
+
+ if (flagCloudLaunchInstance.equals("true"))
+ {
+ /* Getting the short provider name */
+ Bstr bstrCloudProviderShortName(strOutputFile.c_str(), strOutputFile.find("://"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR_BREAK(pVirtualBox, COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()));
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR_BREAK(pCloudProviderManager,
+ GetProviderByShortName(bstrCloudProviderShortName.raw(), pCloudProvider.asOutParam()));
+
+ CHECK_ERROR_BREAK(pVSD, GetDescriptionByType(VirtualSystemDescriptionType_CloudProfileName,
+ ComSafeArrayAsOutParam(retTypes),
+ ComSafeArrayAsOutParam(aRefs),
+ ComSafeArrayAsOutParam(aOvfValues),
+ ComSafeArrayAsOutParam(aVBoxValues),
+ ComSafeArrayAsOutParam(aExtraConfigValues)));
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ CHECK_ERROR_BREAK(pCloudProvider, GetProfileByName(Bstr(aVBoxValues[0]).raw(), pCloudProfile.asOutParam()));
+ retTypes.setNull(); aRefs.setNull(); aOvfValues.setNull(); aVBoxValues.setNull(); aExtraConfigValues.setNull();
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR_BREAK(pCloudProfile, CreateCloudClient(oCloudClient.asOutParam()));
+ RTPrintf(Appliance::tr("Creating a cloud instance...\n"));
+
+ ComPtr<IProgress> progress1;
+ CHECK_ERROR_BREAK(oCloudClient, LaunchVM(pVSD, progress1.asOutParam()));
+ hrc = showProgress(progress1);
+ CHECK_PROGRESS_ERROR_RET(progress1, (Appliance::tr("Creating the cloud instance failed")),
+ RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR_BREAK(pVSD, GetDescriptionByType(VirtualSystemDescriptionType_CloudInstanceId,
+ ComSafeArrayAsOutParam(retTypes),
+ ComSafeArrayAsOutParam(aRefs),
+ ComSafeArrayAsOutParam(aOvfValues),
+ ComSafeArrayAsOutParam(aVBoxValues),
+ ComSafeArrayAsOutParam(aExtraConfigValues)));
+
+ RTPrintf(Appliance::tr("A cloud instance with id '%s' (provider '%s') was created\n"),
+ Utf8Str(Bstr(aVBoxValues[0]).raw()).c_str(),
+ Utf8Str(bstrCloudProviderShortName.raw()).c_str());
+ retTypes.setNull(); aRefs.setNull(); aOvfValues.setNull(); aVBoxValues.setNull(); aExtraConfigValues.setNull();
+ }
+ }
+ }
+ }
+ } while (0);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*********************************************************************************************************************************
+* signova *
+*********************************************************************************************************************************/
+
+/**
+ * Reads the OVA and saves the manifest and signed status.
+ *
+ * @returns VBox status code (fully messaged).
+ * @param pszOva The name of the OVA.
+ * @param iVerbosity The noise level.
+ * @param fReSign Whether it is acceptable to have an existing signature
+ * in the OVA or not.
+ * @param phVfsFssOva Where to return the OVA file system stream handle.
+ * This has been opened for updating and we're positioned
+ * at the end of the stream.
+ * @param pStrManifestName Where to return the manifest name.
+ * @param phVfsManifest Where to return the manifest file handle (copy in mem).
+ * @param phVfsOldSignature Where to return the handle to the old signature object.
+ *
+ * @note Caller must clean up return values on failure too!
+ */
+static int openOvaAndGetManifestAndOldSignature(const char *pszOva, unsigned iVerbosity, bool fReSign,
+ PRTVFSFSSTREAM phVfsFssOva, Utf8Str *pStrManifestName,
+ PRTVFSFILE phVfsManifest, PRTVFSOBJ phVfsOldSignature)
+{
+ /*
+ * Clear return values.
+ */
+ *phVfsFssOva = NIL_RTVFSFSSTREAM;
+ pStrManifestName->setNull();
+ *phVfsManifest = NIL_RTVFSFILE;
+ *phVfsOldSignature = NIL_RTVFSOBJ;
+
+ /*
+ * Open the file as a tar file system stream.
+ */
+ RTVFSFILE hVfsFileOva;
+ int vrc = RTVfsFileOpenNormal(pszOva, RTFILE_O_OPEN | RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE, &hVfsFileOva);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Appliance::tr("Failed to open OVA '%s' for updating: %Rrc"), pszOva, vrc);
+
+ RTVFSFSSTREAM hVfsFssOva;
+ vrc = RTZipTarFsStreamForFile(hVfsFileOva, RTZIPTARFORMAT_DEFAULT, RTZIPTAR_C_UPDATE, &hVfsFssOva);
+ RTVfsFileRelease(hVfsFileOva);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Appliance::tr("Failed to open OVA '%s' as a TAR file: %Rrc"), pszOva, vrc);
+ *phVfsFssOva = hVfsFssOva;
+
+ /*
+ * Scan the objects in the stream and locate the manifest and any existing cert file.
+ */
+ if (iVerbosity >= 2)
+ RTMsgInfo(Appliance::tr("Scanning OVA '%s' for a manifest and signature..."), pszOva);
+ char *pszSignatureName = NULL;
+ for (;;)
+ {
+ /*
+ * Retrive the next object.
+ */
+ char *pszName;
+ RTVFSOBJTYPE enmType;
+ RTVFSOBJ hVfsObj;
+ vrc = RTVfsFsStrmNext(hVfsFssOva, &pszName, &enmType, &hVfsObj);
+ if (RT_FAILURE(vrc))
+ {
+ if (vrc == VERR_EOF)
+ vrc = VINF_SUCCESS;
+ else
+ RTMsgError(Appliance::tr("RTVfsFsStrmNext returned %Rrc"), vrc);
+ break;
+ }
+
+ if (iVerbosity > 2)
+ RTMsgInfo(" %s %s\n", RTVfsTypeName(enmType), pszName);
+
+ /*
+ * Should we process this entry?
+ */
+ const char *pszSuffix = RTPathSuffix(pszName);
+ if ( pszSuffix
+ && RTStrICmpAscii(pszSuffix, ".mf") == 0
+ && (enmType == RTVFSOBJTYPE_IO_STREAM || enmType == RTVFSOBJTYPE_FILE))
+ {
+ if (*phVfsManifest != NIL_RTVFSFILE)
+ vrc = RTMsgErrorRc(VERR_DUPLICATE, Appliance::tr("OVA contains multiple manifests! first: %s second: %s"),
+ pStrManifestName->c_str(), pszName);
+ else if (pszSignatureName)
+ vrc = RTMsgErrorRc(VERR_WRONG_ORDER,
+ Appliance::tr("Unsupported OVA file ordering! Signature file ('%s') as succeeded by '%s'."),
+ pszSignatureName, pszName);
+ else
+ {
+ if (iVerbosity >= 2)
+ RTMsgInfo(Appliance::tr("Found manifest file: %s"), pszName);
+ vrc = pStrManifestName->assignNoThrow(pszName);
+ if (RT_SUCCESS(vrc))
+ {
+ RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj);
+ Assert(hVfsIos != NIL_RTVFSIOSTREAM);
+ vrc = RTVfsMemorizeIoStreamAsFile(hVfsIos, RTFILE_O_READ, phVfsManifest);
+ RTVfsIoStrmRelease(hVfsIos); /* consumes stream handle. */
+ if (RT_FAILURE(vrc))
+ vrc = RTMsgErrorRc(VERR_DUPLICATE, Appliance::tr("Failed to memorize the manifest: %Rrc"), vrc);
+ }
+ else
+ RTMsgError(Appliance::tr("Out of memory!"));
+ }
+ }
+ else if ( pszSuffix
+ && RTStrICmpAscii(pszSuffix, ".cert") == 0
+ && (enmType == RTVFSOBJTYPE_IO_STREAM || enmType == RTVFSOBJTYPE_FILE))
+ {
+ if (*phVfsOldSignature != NIL_RTVFSOBJ)
+ vrc = RTMsgErrorRc(VERR_WRONG_ORDER, Appliance::tr("Multiple signature files! (%s)"), pszName);
+ else
+ {
+ if (iVerbosity >= 2)
+ RTMsgInfo(Appliance::tr("Found existing signature file: %s"), pszName);
+ pszSignatureName = pszName;
+ *phVfsOldSignature = hVfsObj;
+ pszName = NULL;
+ hVfsObj = NIL_RTVFSOBJ;
+ }
+ }
+ else if (pszSignatureName)
+ vrc = RTMsgErrorRc(VERR_WRONG_ORDER,
+ Appliance::tr("Unsupported OVA file ordering! Signature file ('%s') as succeeded by '%s'."),
+ pszSignatureName, pszName);
+
+ /*
+ * Release the current object and string.
+ */
+ RTVfsObjRelease(hVfsObj);
+ RTStrFree(pszName);
+ if (RT_FAILURE(vrc))
+ break;
+ }
+
+ /*
+ * Complain if no manifest.
+ */
+ if (RT_SUCCESS(vrc) && *phVfsManifest == NIL_RTVFSFILE)
+ vrc = RTMsgErrorRc(VERR_NOT_FOUND, Appliance::tr("The OVA contains no manifest and cannot be signed!"));
+ else if (RT_SUCCESS(vrc) && *phVfsOldSignature != NIL_RTVFSOBJ && !fReSign)
+ vrc = RTMsgErrorRc(VERR_ALREADY_EXISTS,
+ Appliance::tr("The OVA is already signed ('%s')! (Use the --force option to force re-signing it.)"),
+ pszSignatureName);
+
+ RTStrFree(pszSignatureName);
+ return vrc;
+}
+
+
+/**
+ * Continues where openOvaAndGetManifestAndOldSignature() left off and writes
+ * the signature file to the OVA.
+ *
+ * When @a hVfsOldSignature isn't NIL, the old signature it represent will be
+ * replaced. The open function has already made sure there isn't anything
+ * following the .cert file in that case.
+ */
+static int updateTheOvaSignature(RTVFSFSSTREAM hVfsFssOva, const char *pszOva, const char *pszSignatureName,
+ RTVFSFILE hVfsFileSignature, RTVFSOBJ hVfsOldSignature, unsigned iVerbosity)
+{
+ if (iVerbosity > 1)
+ RTMsgInfo(Appliance::tr("Writing '%s' to the OVA..."), pszSignatureName);
+
+ /*
+ * Truncate the file at the old signature, if present.
+ */
+ int vrc;
+ if (hVfsOldSignature != NIL_RTVFSOBJ)
+ {
+ vrc = RTZipTarFsStreamTruncate(hVfsFssOva, hVfsOldSignature, false /*fAfter*/);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, Appliance::tr("RTZipTarFsStreamTruncate failed on '%s': %Rrc"), pszOva, vrc);
+ }
+
+ /*
+ * Append the signature file. We have to rewind it first or
+ * we'll end up with VERR_EOF, probably not a great idea...
+ */
+ vrc = RTVfsFileSeek(hVfsFileSignature, 0, RTFILE_SEEK_BEGIN, NULL);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, Appliance::tr("RTVfsFileSeek(hVfsFileSignature) failed: %Rrc"), vrc);
+
+ RTVFSOBJ hVfsObj = RTVfsObjFromFile(hVfsFileSignature);
+ vrc = RTVfsFsStrmAdd(hVfsFssOva, pszSignatureName, hVfsObj, 0 /*fFlags*/);
+ RTVfsObjRelease(hVfsObj);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, Appliance::tr("RTVfsFsStrmAdd('%s') failed on '%s': %Rrc"), pszSignatureName, pszOva, vrc);
+
+ /*
+ * Terminate the file system stream.
+ */
+ vrc = RTVfsFsStrmEnd(hVfsFssOva);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, Appliance::tr("RTVfsFsStrmEnd failed on '%s': %Rrc"), pszOva, vrc);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for doCheckPkcs7Signature.
+ */
+static int doCheckPkcs7SignatureWorker(PRTCRPKCS7CONTENTINFO pContentInfo, void const *pvManifest, size_t cbManifest,
+ unsigned iVerbosity, const char *pszTag, PRTERRINFOSTATIC pErrInfo)
+{
+ int vrc;
+
+ /*
+ * It must be signedData.
+ */
+ if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo))
+ {
+ PRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData;
+
+ /*
+ * Inside the signedData there must be just 'data'.
+ */
+ if (!strcmp(pSignedData->ContentInfo.ContentType.szObjId, RTCR_PKCS7_DATA_OID))
+ {
+ /*
+ * Check that things add up.
+ */
+ vrc = RTCrPkcs7SignedData_CheckSanity(pSignedData,
+ RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
+ | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
+ RTErrInfoInitStatic(pErrInfo), "SD");
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 2 && pszTag == NULL)
+ RTMsgInfo(Appliance::tr(" Successfully decoded the PKCS#7/CMS signature..."));
+
+ /*
+ * Check that we can verify the signed data, but skip certificate validate as
+ * we probably don't necessarily have the correct root certs handy here.
+ */
+ RTTIMESPEC Now;
+ vrc = RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo, RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS,
+ NIL_RTCRSTORE /*hAdditionalCerts*/,
+ NIL_RTCRSTORE /*hTrustedCerts*/,
+ RTTimeNow(&Now),
+ NULL /*pfnVerifyCert*/, NULL /*pvUser*/,
+ pvManifest, cbManifest, RTErrInfoInitStatic(pErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 1 && pszTag != NULL)
+ RTMsgInfo(Appliance::tr(" Successfully verified the PKCS#7/CMS signature"));
+ }
+ else
+ vrc = RTMsgErrorRc(vrc, Appliance::tr("Failed to verify the PKCS#7/CMS signature: %Rrc%RTeim"),
+ vrc, &pErrInfo->Core);
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrPkcs7SignedData_CheckSanity failed on PKCS#7/CMS signature: %Rrc%RTeim"),
+ vrc, &pErrInfo->Core);
+
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_WRONG_TYPE, Appliance::tr("PKCS#7/CMS signature inner ContentType isn't 'data' but: %s"),
+ pSignedData->ContentInfo.ContentType.szObjId);
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_WRONG_TYPE, Appliance::tr("PKCS#7/CMD signature is not 'signedData': %s"),
+ pContentInfo->ContentType.szObjId);
+ return vrc;
+}
+
+/**
+ * For testing the decoding side.
+ */
+static int doCheckPkcs7Signature(void const *pvSignature, size_t cbSignature, PCRTCRX509CERTIFICATE pCertificate,
+ RTCRSTORE hIntermediateCerts, void const *pvManifest, size_t cbManifest,
+ unsigned iVerbosity, PRTERRINFOSTATIC pErrInfo)
+{
+ RT_NOREF(pCertificate, hIntermediateCerts);
+
+ RTASN1CURSORPRIMARY PrimaryCursor;
+ RTAsn1CursorInitPrimary(&PrimaryCursor, pvSignature, (uint32_t)cbSignature, RTErrInfoInitStatic(pErrInfo),
+ &g_RTAsn1DefaultAllocator, 0, "Signature");
+
+ RTCRPKCS7CONTENTINFO ContentInfo;
+ RT_ZERO(ContentInfo);
+ int vrc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &ContentInfo, "CI");
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 5)
+ RTAsn1Dump(&ContentInfo.SeqCore.Asn1Core, 0 /*fFlags*/, 0 /*uLevel*/, RTStrmDumpPrintfV, g_pStdOut);
+
+ vrc = doCheckPkcs7SignatureWorker(&ContentInfo, pvManifest, cbManifest, iVerbosity, NULL, pErrInfo);
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Clone it and repeat. This is to catch IPRT paths assuming
+ * that encoded data is always on hand.
+ */
+ RTCRPKCS7CONTENTINFO ContentInfo2;
+ vrc = RTCrPkcs7ContentInfo_Clone(&ContentInfo2, &ContentInfo, &g_RTAsn1DefaultAllocator);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = doCheckPkcs7SignatureWorker(&ContentInfo2, pvManifest, cbManifest, iVerbosity, "cloned", pErrInfo);
+ RTCrPkcs7ContentInfo_Delete(&ContentInfo2);
+ }
+ else
+ vrc = RTMsgErrorRc(vrc, Appliance::tr("RTCrPkcs7ContentInfo_Clone failed: %Rrc"), vrc);
+ }
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrPkcs7ContentInfo_DecodeAsn1 failed to decode PKCS#7/CMS signature: %Rrc%RTemi"),
+ vrc, &pErrInfo->Core);
+
+ RTCrPkcs7ContentInfo_Delete(&ContentInfo);
+ return vrc;
+}
+
+
+/**
+ * Creates a PKCS\#7 signature and appends it to the signature file in PEM
+ * format.
+ */
+static int doAddPkcs7Signature(PCRTCRX509CERTIFICATE pCertificate, RTCRKEY hPrivateKey, RTDIGESTTYPE enmDigestType,
+ unsigned cIntermediateCerts, const char **papszIntermediateCerts, RTVFSFILE hVfsFileManifest,
+ unsigned iVerbosity, PRTERRINFOSTATIC pErrInfo, RTVFSFILE hVfsFileSignature)
+{
+ /*
+ * Add a blank line, just for good measure.
+ */
+ int vrc = RTVfsFileWrite(hVfsFileSignature, "\n", 1, NULL);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, "RTVfsFileWrite/signature: %Rrc", vrc);
+
+ /*
+ * Read the manifest into a single memory block.
+ */
+ uint64_t cbManifest;
+ vrc = RTVfsFileQuerySize(hVfsFileManifest, &cbManifest);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, "RTVfsFileQuerySize/manifest: %Rrc", vrc);
+ if (cbManifest > _4M)
+ return RTMsgErrorRc(VERR_OUT_OF_RANGE, Appliance::tr("Manifest is too big: %#RX64 bytes, max 4MiB", "", cbManifest),
+ cbManifest);
+
+ void *pvManifest = RTMemAllocZ(cbManifest + 1);
+ if (!pvManifest)
+ return RTMsgErrorRc(VERR_NO_MEMORY, Appliance::tr("Out of memory!"));
+
+ vrc = RTVfsFileReadAt(hVfsFileManifest, 0, pvManifest, (size_t)cbManifest, NULL);
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Load intermediate certificates.
+ */
+ RTCRSTORE hIntermediateCerts = NIL_RTCRSTORE;
+ if (cIntermediateCerts)
+ {
+ vrc = RTCrStoreCreateInMem(&hIntermediateCerts, cIntermediateCerts);
+ if (RT_SUCCESS(vrc))
+ {
+ for (unsigned i = 0; i < cIntermediateCerts; i++)
+ {
+ const char *pszFile = papszIntermediateCerts[i];
+ vrc = RTCrStoreCertAddFromFile(hIntermediateCerts, 0 /*fFlags*/, pszFile, &pErrInfo->Core);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Appliance::tr("RTCrStoreCertAddFromFile failed on '%s': %Rrc%#RTeim"),
+ pszFile, vrc, &pErrInfo->Core);
+ break;
+ }
+ }
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrStoreCreateInMem failed: %Rrc"), vrc);
+ }
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Do a dry run to determin the size of the signed data.
+ */
+ size_t cbResult = 0;
+ vrc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_DEATCHED | RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP,
+ pCertificate, hPrivateKey, pvManifest, (size_t)cbManifest, enmDigestType,
+ hIntermediateCerts, NULL /*pAdditionalAuthenticatedAttribs*/,
+ NULL /*pvResult*/, &cbResult, RTErrInfoInitStatic(pErrInfo));
+ if (vrc == VERR_BUFFER_OVERFLOW)
+ {
+ /*
+ * Allocate a buffer of the right size and do the real run.
+ */
+ void *pvResult = RTMemAllocZ(cbResult);
+ if (pvResult)
+ {
+ vrc = RTCrPkcs7SimpleSignSignedData(RTCRPKCS7SIGN_SD_F_DEATCHED | RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP,
+ pCertificate, hPrivateKey, pvManifest, (size_t)cbManifest, enmDigestType,
+ hIntermediateCerts, NULL /*pAdditionalAuthenticatedAttribs*/,
+ pvResult, &cbResult, RTErrInfoInitStatic(pErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Add it to the signature file in PEM format.
+ */
+ vrc = (int)RTCrPemWriteBlobToVfsFile(hVfsFileSignature, pvResult, cbResult, "CMS");
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 1)
+ RTMsgInfo(Appliance::tr("Created PKCS#7/CMS signature: %zu bytes, %s.", "", cbResult),
+ cbResult, RTCrDigestTypeToName(enmDigestType));
+ if (enmDigestType == RTDIGESTTYPE_SHA1)
+ RTMsgWarning(Appliance::tr("Using SHA-1 instead of SHA-3 for the PKCS#7/CMS signature."));
+
+ /*
+ * Try decode and verify the signature.
+ */
+ vrc = doCheckPkcs7Signature(pvResult, cbResult, pCertificate, hIntermediateCerts,
+ pvManifest, (size_t)cbManifest, iVerbosity, pErrInfo);
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrPemWriteBlobToVfsFile failed: %Rrc"), vrc);
+ }
+ RTMemFree(pvResult);
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_NO_MEMORY, Appliance::tr("Out of memory!"));
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim"), vrc, &pErrInfo->Core);
+ }
+ }
+ else
+ RTMsgError(Appliance::tr("RTVfsFileReadAt failed: %Rrc"), vrc);
+ RTMemFree(pvManifest);
+ return vrc;
+}
+
+
+/**
+ * Performs the OVA signing, producing an in-memory cert-file.
+ */
+static int doTheOvaSigning(PRTCRX509CERTIFICATE pCertificate, RTCRKEY hPrivateKey, RTDIGESTTYPE enmDigestType,
+ const char *pszManifestName, RTVFSFILE hVfsFileManifest,
+ bool fPkcs7, unsigned cIntermediateCerts, const char **papszIntermediateCerts, unsigned iVerbosity,
+ PRTERRINFOSTATIC pErrInfo, PRTVFSFILE phVfsFileSignature)
+{
+ /*
+ * Determine the digest types, preferring SHA-256 for the OVA signature
+ * and SHA-512 for the PKCS#7/CMS one. Try use different hashes for the two.
+ */
+ if (enmDigestType == RTDIGESTTYPE_UNKNOWN)
+ {
+ if (RTCrPkixCanCertHandleDigestType(pCertificate, RTDIGESTTYPE_SHA256, NULL))
+ enmDigestType = RTDIGESTTYPE_SHA256;
+ else
+ enmDigestType = RTDIGESTTYPE_SHA1;
+ }
+
+ /* Try SHA-3 for better diversity, only fall back on SHA1 if the private
+ key doesn't have enough bits (we skip SHA2 as it has the same variants
+ and key size requirements as SHA-3). */
+ RTDIGESTTYPE enmPkcs7DigestType;
+ if (RTCrPkixCanCertHandleDigestType(pCertificate, RTDIGESTTYPE_SHA3_512, NULL))
+ enmPkcs7DigestType = RTDIGESTTYPE_SHA3_512;
+ else if (RTCrPkixCanCertHandleDigestType(pCertificate, RTDIGESTTYPE_SHA3_384, NULL))
+ enmPkcs7DigestType = RTDIGESTTYPE_SHA3_384;
+ else if (RTCrPkixCanCertHandleDigestType(pCertificate, RTDIGESTTYPE_SHA3_256, NULL))
+ enmPkcs7DigestType = RTDIGESTTYPE_SHA3_256;
+ else if (RTCrPkixCanCertHandleDigestType(pCertificate, RTDIGESTTYPE_SHA3_224, NULL))
+ enmPkcs7DigestType = RTDIGESTTYPE_SHA3_224;
+ else
+ enmPkcs7DigestType = RTDIGESTTYPE_SHA1;
+
+ /*
+ * Figure the string name for the .cert file.
+ */
+ const char *pszDigestType;
+ switch (enmDigestType)
+ {
+ case RTDIGESTTYPE_SHA1: pszDigestType = "SHA1"; break;
+ case RTDIGESTTYPE_SHA256: pszDigestType = "SHA256"; break;
+ case RTDIGESTTYPE_SHA224: pszDigestType = "SHA224"; break;
+ case RTDIGESTTYPE_SHA512: pszDigestType = "SHA512"; break;
+ default:
+ return RTMsgErrorRc(VERR_INVALID_PARAMETER,
+ Appliance::tr("Unsupported digest type: %s"), RTCrDigestTypeToName(enmDigestType));
+ }
+
+ /*
+ * Digest the manifest file.
+ */
+ RTCRDIGEST hDigest = NIL_RTCRDIGEST;
+ int vrc = RTCrDigestCreateByType(&hDigest, enmDigestType);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorRc(vrc, Appliance::tr("Failed to create digest for %s: %Rrc"), RTCrDigestTypeToName(enmDigestType), vrc);
+
+ vrc = RTCrDigestUpdateFromVfsFile(hDigest, hVfsFileManifest, true /*fRewindFile*/);
+ if (RT_SUCCESS(vrc))
+ vrc = RTCrDigestFinal(hDigest, NULL, 0);
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Sign the digest. Two passes, first to figure the signature size, the
+ * second to do the actual signing.
+ */
+ PCRTASN1OBJID const pAlgorithm = &pCertificate->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm;
+ PCRTASN1DYNTYPE const pAlgoParams = &pCertificate->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Parameters;
+ size_t cbSignature = 0;
+ vrc = RTCrPkixPubKeySignDigest(pAlgorithm, hPrivateKey, pAlgoParams, hDigest, 0 /*fFlags*/,
+ NULL /*pvSignature*/, &cbSignature, RTErrInfoInitStatic(pErrInfo));
+ if (vrc == VERR_BUFFER_OVERFLOW)
+ {
+ void *pvSignature = RTMemAllocZ(cbSignature);
+ if (pvSignature)
+ {
+ vrc = RTCrPkixPubKeySignDigest(pAlgorithm, hPrivateKey, pAlgoParams, hDigest, 0,
+ pvSignature, &cbSignature, RTErrInfoInitStatic(pErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 1)
+ RTMsgInfo(Appliance::tr("Created OVA signature: %zu bytes, %s", "", cbSignature), cbSignature,
+ RTCrDigestTypeToName(enmDigestType));
+
+ /*
+ * Verify the signature using the certificate to make sure we've
+ * been given the right private key.
+ */
+ vrc = RTCrPkixPubKeyVerifySignedDigestByCertPubKeyInfo(&pCertificate->TbsCertificate.SubjectPublicKeyInfo,
+ pvSignature, cbSignature, hDigest,
+ RTErrInfoInitStatic(pErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 2)
+ RTMsgInfo(Appliance::tr(" Successfully decoded and verified the OVA signature.\n"));
+
+ /*
+ * Create the output file.
+ */
+ RTVFSFILE hVfsFileSignature;
+ vrc = RTVfsMemFileCreate(NIL_RTVFSIOSTREAM, _8K, &hVfsFileSignature);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = (int)RTVfsFilePrintf(hVfsFileSignature, "%s(%s) = %#.*Rhxs\n\n",
+ pszDigestType, pszManifestName, cbSignature, pvSignature);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = (int)RTCrX509Certificate_WriteToVfsFile(hVfsFileSignature, pCertificate,
+ RTErrInfoInitStatic(pErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ if (fPkcs7)
+ vrc = doAddPkcs7Signature(pCertificate, hPrivateKey, enmPkcs7DigestType,
+ cIntermediateCerts, papszIntermediateCerts, hVfsFileManifest,
+ iVerbosity, pErrInfo, hVfsFileSignature);
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Success.
+ */
+ *phVfsFileSignature = hVfsFileSignature;
+ hVfsFileSignature = NIL_RTVFSFILE;
+ }
+ }
+ else
+ RTMsgError(Appliance::tr("Failed to write certificate to signature file: %Rrc%#RTeim"),
+ vrc, &pErrInfo->Core);
+ }
+ else
+ RTMsgError(Appliance::tr("Failed to produce signature file: %Rrc"), vrc);
+ RTVfsFileRelease(hVfsFileSignature);
+ }
+ else
+ RTMsgError(Appliance::tr("RTVfsMemFileCreate failed: %Rrc"), vrc);
+ }
+ else
+ RTMsgError(Appliance::tr("Encountered a problem when validating the signature we just created: %Rrc%#RTeim\n"
+ "Please make sure the certificate and private key matches."),
+ vrc, &pErrInfo->Core);
+ }
+ else
+ RTMsgError(Appliance::tr("2nd RTCrPkixPubKeySignDigest call failed: %Rrc%#RTeim"), vrc, pErrInfo->Core);
+ RTMemFree(pvSignature);
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_NO_MEMORY, Appliance::tr("Out of memory!"));
+ }
+ else
+ RTMsgError(Appliance::tr("RTCrPkixPubKeySignDigest failed: %Rrc%#RTeim"), vrc, pErrInfo->Core);
+ }
+ else
+ RTMsgError(Appliance::tr("Failed to create digest %s: %Rrc"), RTCrDigestTypeToName(enmDigestType), vrc);
+ RTCrDigestRelease(hDigest);
+ return vrc;
+}
+
+
+/**
+ * Handles the 'ovasign' command.
+ */
+RTEXITCODE handleSignAppliance(HandlerArg *arg)
+{
+ /*
+ * Parse arguments.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--certificate", 'c', RTGETOPT_REQ_STRING },
+ { "--private-key", 'k', RTGETOPT_REQ_STRING },
+ { "--private-key-password", 'p', RTGETOPT_REQ_STRING },
+ { "--private-key-password-file",'P', RTGETOPT_REQ_STRING },
+ { "--digest-type", 'd', RTGETOPT_REQ_STRING },
+ { "--pkcs7", '7', RTGETOPT_REQ_NOTHING },
+ { "--cms", '7', RTGETOPT_REQ_NOTHING },
+ { "--no-pkcs7", 'n', RTGETOPT_REQ_NOTHING },
+ { "--no-cms", 'n', RTGETOPT_REQ_NOTHING },
+ { "--intermediate-cert-file", 'i', RTGETOPT_REQ_STRING },
+ { "--force", 'f', RTGETOPT_REQ_NOTHING },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+ { "--quiet", 'q', RTGETOPT_REQ_NOTHING },
+ { "--dry-run", 'D', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, arg->argc, arg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ const char *pszOva = NULL;
+ const char *pszCertificate = NULL;
+ const char *pszPrivateKey = NULL;
+ Utf8Str strPrivateKeyPassword;
+ RTDIGESTTYPE enmDigestType = RTDIGESTTYPE_UNKNOWN;
+ bool fPkcs7 = true;
+ unsigned cIntermediateCerts = 0;
+ const char *apszIntermediateCerts[32];
+ bool fReSign = false;
+ unsigned iVerbosity = 1;
+ bool fDryRun = false;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'c':
+ pszCertificate = ValueUnion.psz;
+ break;
+
+ case 'k':
+ pszPrivateKey = ValueUnion.psz;
+ break;
+
+ case 'p':
+ if (strPrivateKeyPassword.isNotEmpty())
+ RTMsgWarning(Appliance::tr("Password is given more than once."));
+ strPrivateKeyPassword = ValueUnion.psz;
+ break;
+
+ case 'P':
+ {
+ if (strPrivateKeyPassword.isNotEmpty())
+ RTMsgWarning(Appliance::tr("Password is given more than once."));
+ RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &strPrivateKeyPassword);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ break;
+ return rcExit;
+ }
+
+ case 'd':
+ if ( RTStrICmp(ValueUnion.psz, "sha1") == 0
+ || RTStrICmp(ValueUnion.psz, "sha-1") == 0)
+ enmDigestType = RTDIGESTTYPE_SHA1;
+ else if ( RTStrICmp(ValueUnion.psz, "sha256") == 0
+ || RTStrICmp(ValueUnion.psz, "sha-256") == 0)
+ enmDigestType = RTDIGESTTYPE_SHA256;
+ else if ( RTStrICmp(ValueUnion.psz, "sha512") == 0
+ || RTStrICmp(ValueUnion.psz, "sha-512") == 0)
+ enmDigestType = RTDIGESTTYPE_SHA512;
+ else
+ return RTMsgErrorExitFailure(Appliance::tr("Unknown digest type: %s"), ValueUnion.psz);
+ break;
+
+ case '7':
+ fPkcs7 = true;
+ break;
+
+ case 'n':
+ fPkcs7 = false;
+ break;
+
+ case 'i':
+ if (cIntermediateCerts >= RT_ELEMENTS(apszIntermediateCerts))
+ return RTMsgErrorExitFailure(Appliance::tr("Too many intermediate certificates: max %zu"),
+ RT_ELEMENTS(apszIntermediateCerts));
+ apszIntermediateCerts[cIntermediateCerts++] = ValueUnion.psz;
+ fPkcs7 = true;
+ break;
+
+ case 'f':
+ fReSign = true;
+ break;
+
+ case 'v':
+ iVerbosity++;
+ break;
+
+ case 'q':
+ iVerbosity = 0;
+ break;
+
+ case 'D':
+ fDryRun = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszOva)
+ {
+ pszOva = ValueUnion.psz;
+ break;
+ }
+ RT_FALL_THRU();
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Required paramaters: */
+ if (!pszOva || !*pszOva)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Appliance::tr("No OVA file was specified!"));
+ if (!pszCertificate || !*pszCertificate)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Appliance::tr("No signing certificate (--certificate=<file>) was specified!"));
+ if (!pszPrivateKey || !*pszPrivateKey)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, Appliance::tr("No signing private key (--private-key=<file>) was specified!"));
+
+ /* Check that input files exists before we commence: */
+ if (!RTFileExists(pszOva))
+ return RTMsgErrorExitFailure(Appliance::tr("The specified OVA file was not found: %s"), pszOva);
+ if (!RTFileExists(pszCertificate))
+ return RTMsgErrorExitFailure(Appliance::tr("The specified certificate file was not found: %s"), pszCertificate);
+ if (!RTFileExists(pszPrivateKey))
+ return RTMsgErrorExitFailure(Appliance::tr("The specified private key file was not found: %s"), pszPrivateKey);
+
+ /*
+ * Open the OVA, read the manifest and look for any existing signature.
+ */
+ RTVFSFSSTREAM hVfsFssOva = NIL_RTVFSFSSTREAM;
+ RTVFSOBJ hVfsOldSignature = NIL_RTVFSOBJ;
+ RTVFSFILE hVfsFileManifest = NIL_RTVFSFILE;
+ Utf8Str strManifestName;
+ vrc = openOvaAndGetManifestAndOldSignature(pszOva, iVerbosity, fReSign,
+ &hVfsFssOva, &strManifestName, &hVfsFileManifest, &hVfsOldSignature);
+ if (RT_SUCCESS(vrc))
+ {
+ /*
+ * Read the certificate and private key.
+ */
+ RTERRINFOSTATIC ErrInfo;
+ RTCRX509CERTIFICATE Certificate;
+ vrc = RTCrX509Certificate_ReadFromFile(&Certificate, pszCertificate, 0, &g_RTAsn1DefaultAllocator,
+ RTErrInfoInitStatic(&ErrInfo));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Appliance::tr("Error reading certificate from '%s': %Rrc%#RTeim"),
+ pszCertificate, vrc, &ErrInfo.Core);
+
+ RTCRKEY hPrivateKey = NIL_RTCRKEY;
+ vrc = RTCrKeyCreateFromFile(&hPrivateKey, 0 /*fFlags*/, pszPrivateKey, strPrivateKeyPassword.c_str(),
+ RTErrInfoInitStatic(&ErrInfo));
+ if (RT_SUCCESS(vrc))
+ {
+ if (iVerbosity > 1)
+ RTMsgInfo(Appliance::tr("Successfully read the certificate and private key."));
+
+ /*
+ * Do the signing and create the signature file.
+ */
+ RTVFSFILE hVfsFileSignature = NIL_RTVFSFILE;
+ vrc = doTheOvaSigning(&Certificate, hPrivateKey, enmDigestType, strManifestName.c_str(), hVfsFileManifest,
+ fPkcs7, cIntermediateCerts, apszIntermediateCerts, iVerbosity, &ErrInfo, &hVfsFileSignature);
+
+ /*
+ * Construct the signature filename:
+ */
+ if (RT_SUCCESS(vrc))
+ {
+ Utf8Str strSignatureName;
+ vrc = strSignatureName.assignNoThrow(strManifestName);
+ if (RT_SUCCESS(vrc))
+ vrc = strSignatureName.stripSuffix().appendNoThrow(".cert");
+ if (RT_SUCCESS(vrc) && !fDryRun)
+ {
+ /*
+ * Update the OVA.
+ */
+ vrc = updateTheOvaSignature(hVfsFssOva, pszOva, strSignatureName.c_str(),
+ hVfsFileSignature, hVfsOldSignature, iVerbosity);
+ if (RT_SUCCESS(vrc) && iVerbosity > 0)
+ RTMsgInfo(Appliance::tr("Successfully signed '%s'."), pszOva);
+ }
+ }
+ RTCrKeyRelease(hPrivateKey);
+ }
+ else
+ RTPrintf(Appliance::tr("Error reading the private key from %s: %Rrc%#RTeim"), pszPrivateKey, vrc, &ErrInfo.Core);
+ RTCrX509Certificate_Delete(&Certificate);
+ }
+
+ RTVfsObjRelease(hVfsOldSignature);
+ RTVfsFileRelease(hVfsFileManifest);
+ RTVfsFsStrmRelease(hVfsFssOva);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
new file mode 100644
index 00000000..910f5ad5
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
@@ -0,0 +1,384 @@
+/* $Id: VBoxManageBandwidthControl.cpp $ */
+/** @file
+ * VBoxManage - The bandwidth control related commands.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/err.h>
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#include <iprt/stream.h>
+#include <iprt/getopt.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(BWControl);
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Parses a string in the following format "n[k|m|g|K|M|G]". Stores the value
+ * of n expressed in bytes to *pLimit. k meas kilobit, while K means kilobyte.
+ *
+ * @returns Error message or NULL if successful.
+ * @param pcszLimit The string to parse.
+ * @param pLimit Where to store the result.
+ */
+static const char *parseLimit(const char *pcszLimit, int64_t *pLimit)
+{
+ int iMultiplier = _1M;
+ char *pszNext = NULL;
+ int vrc = RTStrToInt64Ex(pcszLimit, &pszNext, 10, pLimit);
+
+ switch (vrc)
+ {
+ case VINF_SUCCESS:
+ break;
+ case VWRN_NUMBER_TOO_BIG:
+ return BWControl::tr("Limit is too big\n");
+ case VWRN_TRAILING_CHARS:
+ switch (*pszNext)
+ {
+ case 'G': iMultiplier = _1G; break;
+ case 'M': iMultiplier = _1M; break;
+ case 'K': iMultiplier = _1K; break;
+ case 'g': iMultiplier = 125000000; break;
+ case 'm': iMultiplier = 125000; break;
+ case 'k': iMultiplier = 125; break;
+ default: return BWControl::tr("Invalid unit suffix. Valid suffixes are: k, m, g, K, M, G\n");
+ }
+ break;
+ case VWRN_TRAILING_SPACES:
+ return BWControl::tr("Trailing spaces in limit!\n");
+ case VERR_NO_DIGITS:
+ return BWControl::tr("No digits in limit specifier\n");
+ default:
+ return BWControl::tr("Invalid limit specifier\n");
+ }
+ if (*pLimit < 0)
+ return BWControl::tr("Limit cannot be negative\n");
+ if (*pLimit > INT64_MAX / iMultiplier)
+ return BWControl::tr("Limit is too big\n");
+ *pLimit *= iMultiplier;
+
+ return NULL;
+}
+
+/**
+ * Handles the 'bandwidthctl myvm add' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param bwCtrl Reference to the bandwidth control interface.
+ */
+static RTEXITCODE handleBandwidthControlAdd(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
+{
+ HRESULT hrc = S_OK;
+ static const RTGETOPTDEF g_aBWCtlAddOptions[] =
+ {
+ { "--type", 't', RTGETOPT_REQ_STRING },
+ { "--limit", 'l', RTGETOPT_REQ_STRING }
+ };
+
+ setCurrentSubcommand(HELP_SCOPE_BANDWIDTHCTL_ADD);
+
+ Bstr name(a->argv[2]);
+ if (name.isEmpty())
+ {
+ errorArgument(BWControl::tr("Bandwidth group name must not be empty!\n"));
+ return RTEXITCODE_FAILURE;
+ }
+
+ const char *pszType = NULL;
+ int64_t cMaxBytesPerSec = INT64_MAX;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
+ RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ while ( SUCCEEDED(hrc)
+ && (c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 't': // bandwidth group type
+ {
+ if (ValueUnion.psz)
+ pszType = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'l': // limit
+ {
+ if (ValueUnion.psz)
+ {
+ const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
+ if (pcszError)
+ {
+ errorArgument(pcszError);
+ return RTEXITCODE_FAILURE;
+ }
+ }
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ default:
+ {
+ errorGetOpt(c, &ValueUnion);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ }
+
+ BandwidthGroupType_T enmType;
+
+ if (!RTStrICmp(pszType, "disk"))
+ enmType = BandwidthGroupType_Disk;
+ else if (!RTStrICmp(pszType, "network"))
+ enmType = BandwidthGroupType_Network;
+ else
+ {
+ errorArgument(BWControl::tr("Invalid bandwidth group type\n"));
+ return RTEXITCODE_FAILURE;
+ }
+
+ CHECK_ERROR2I_RET(bwCtrl, CreateBandwidthGroup(name.raw(), enmType, (LONG64)cMaxBytesPerSec), RTEXITCODE_FAILURE);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the 'bandwidthctl myvm set' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param bwCtrl Reference to the bandwidth control interface.
+ */
+static RTEXITCODE handleBandwidthControlSet(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
+{
+ HRESULT hrc = S_OK;
+ static const RTGETOPTDEF g_aBWCtlAddOptions[] =
+ {
+ { "--limit", 'l', RTGETOPT_REQ_STRING }
+ };
+
+ setCurrentSubcommand(HELP_SCOPE_BANDWIDTHCTL_SET);
+
+ Bstr name(a->argv[2]);
+ int64_t cMaxBytesPerSec = INT64_MAX;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
+ RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ while ( SUCCEEDED(hrc)
+ && (c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'l': // limit
+ {
+ if (ValueUnion.psz)
+ {
+ const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
+ if (pcszError)
+ {
+ errorArgument(pcszError);
+ return RTEXITCODE_FAILURE;
+ }
+ }
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ default:
+ {
+ errorGetOpt(c, &ValueUnion);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ }
+
+
+ if (cMaxBytesPerSec != INT64_MAX)
+ {
+ ComPtr<IBandwidthGroup> bwGroup;
+ CHECK_ERROR2I_RET(bwCtrl, GetBandwidthGroup(name.raw(), bwGroup.asOutParam()), RTEXITCODE_FAILURE);
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR2I_RET(bwGroup, COMSETTER(MaxBytesPerSec)((LONG64)cMaxBytesPerSec), RTEXITCODE_FAILURE);
+ }
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the 'bandwidthctl myvm remove' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param bwCtrl Reference to the bandwidth control interface.
+ */
+static RTEXITCODE handleBandwidthControlRemove(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
+{
+ setCurrentSubcommand(HELP_SCOPE_BANDWIDTHCTL_REMOVE);
+
+ Bstr name(a->argv[2]);
+ CHECK_ERROR2I_RET(bwCtrl, DeleteBandwidthGroup(name.raw()), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the 'bandwidthctl myvm list' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param bwCtrl Reference to the bandwidth control interface.
+ */
+static RTEXITCODE handleBandwidthControlList(HandlerArg *pArgs, ComPtr<IBandwidthControl> &rptrBWControl)
+{
+ static const RTGETOPTDEF g_aOptions[] =
+ {
+ { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
+ };
+
+ setCurrentSubcommand(HELP_SCOPE_BANDWIDTHCTL_LIST);
+ VMINFO_DETAILS enmDetails = VMINFO_STANDARD;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, g_aOptions, RT_ELEMENTS(g_aOptions), 2 /*iArg*/, 0 /*fFlags*/);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'M':
+ enmDetails = VMINFO_MACHINEREADABLE;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (FAILED(showBandwidthGroups(rptrBWControl, enmDetails)))
+ return RTEXITCODE_FAILURE;
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the 'bandwidthctl' command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ */
+RTEXITCODE handleBandwidthControl(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<IMachine> machine;
+ ComPtr<IBandwidthControl> bwCtrl;
+
+ if (a->argc < 2)
+ return errorSyntax(BWControl::tr("Too few parameters"));
+ else if (a->argc > 7)
+ return errorSyntax(BWControl::tr("Too many parameters"));
+
+ /* try to find the given machine */
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /* open a session for the VM (new or shared) */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ SessionType_T st;
+ CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), RTEXITCODE_FAILURE);
+ bool fRunTime = (st == SessionType_Shared);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+ hrc = machine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam());
+ if (FAILED(hrc)) goto leave; /** @todo r=andy Argh!! */
+
+ if (!strcmp(a->argv[1], "add"))
+ {
+ if (fRunTime)
+ {
+ errorArgument(BWControl::tr("Bandwidth groups cannot be created while the VM is running\n"));
+ goto leave;
+ }
+ hrc = handleBandwidthControlAdd(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "remove"))
+ {
+ if (fRunTime)
+ {
+ errorArgument(BWControl::tr("Bandwidth groups cannot be deleted while the VM is running\n"));
+ goto leave;
+ }
+ hrc = handleBandwidthControlRemove(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "set"))
+ hrc = handleBandwidthControlSet(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ else if (!strcmp(a->argv[1], "list"))
+ hrc = handleBandwidthControlList(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ else
+ {
+ errorSyntax(BWControl::tr("Invalid parameter '%s'"), a->argv[1]);
+ hrc = E_FAIL;
+ }
+
+ /* commit changes */
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+
+leave:
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp
new file mode 100644
index 00000000..690cb7d9
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp
@@ -0,0 +1,2654 @@
+/* $Id: VBoxManageCloud.cpp $ */
+/** @file
+ * VBoxManageCloud - The cloud related commands.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/ctype.h>
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/uuid.h>
+#include <iprt/file.h>
+#include <iprt/http.h>
+#include <VBox/log.h>
+
+#include <iprt/cpp/path.h>
+
+#include "VBoxManage.h"
+
+#include <list>
+
+using namespace com;//at least for Bstr
+
+DECLARE_TRANSLATION_CONTEXT(Cloud);
+
+
+/**
+ * Common Cloud options.
+ */
+typedef struct
+{
+ struct {
+ const char *pszProviderName;
+ ComPtr<ICloudProvider> pCloudProvider;
+ }provider;
+ struct {
+ const char *pszProfileName;
+ ComPtr<ICloudProfile> pCloudProfile;
+ }profile;
+
+} CLOUDCOMMONOPT;
+typedef CLOUDCOMMONOPT *PCLOUDCOMMONOPT;
+
+static HRESULT checkAndSetCommonOptions(HandlerArg *a, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
+ Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
+
+ /* check for required options */
+ if (bstrProvider.isEmpty())
+ {
+ errorSyntax(Cloud::tr("Parameter --provider is required"));
+ return E_FAIL;
+ }
+ if (bstrProfile.isEmpty())
+ {
+ errorSyntax(Cloud::tr("Parameter --profile is required"));
+ return E_FAIL;
+ }
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+ pCommonOpts->provider.pCloudProvider = pCloudProvider;
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(bstrProfile.raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+ pCommonOpts->profile.pCloudProfile = pCloudProfile;
+
+ return hrc;
+}
+
+
+/**
+ * List all available cloud instances for the specified cloud provider.
+ * Available cloud instance is one which state whether "running" or "stopped".
+ *
+ * @returns RTEXITCODE
+ * @param a is the list of passed arguments
+ * @param iFirst is the position of the first unparsed argument in the arguments list
+ * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
+ * arguments which have been already parsed before
+ */
+static RTEXITCODE listCloudInstances(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
+ { "--state", 's', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Utf8Str strCompartmentId;
+ com::SafeArray<CloudMachineState_T> machineStates;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'c':
+ strCompartmentId = ValueUnion.psz;
+ break;
+
+ case 's':
+ {
+ const char * const pszState = ValueUnion.psz;
+
+ if (RTStrICmp(pszState, "creatingimage") == 0)
+ machineStates.push_back(CloudMachineState_CreatingImage);
+ else if (RTStrICmp(pszState, "paused") == 0) /* XXX */
+ machineStates.push_back(CloudMachineState_Stopped);
+ else if (RTStrICmp(pszState, "provisioning") == 0)
+ machineStates.push_back(CloudMachineState_Provisioning);
+ else if (RTStrICmp(pszState, "running") == 0)
+ machineStates.push_back(CloudMachineState_Running);
+ else if (RTStrICmp(pszState, "starting") == 0)
+ machineStates.push_back(CloudMachineState_Starting);
+ else if (RTStrICmp(pszState, "stopped") == 0)
+ machineStates.push_back(CloudMachineState_Stopped);
+ else if (RTStrICmp(pszState, "stopping") == 0)
+ machineStates.push_back(CloudMachineState_Stopping);
+ else if (RTStrICmp(pszState, "terminated") == 0)
+ machineStates.push_back(CloudMachineState_Terminated);
+ else if (RTStrICmp(pszState, "terminating") == 0)
+ machineStates.push_back(CloudMachineState_Terminating);
+ else
+ return errorArgument(Cloud::tr("Unknown cloud instance state \"%s\""), pszState);
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ HRESULT hrc = S_OK;
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ if (strCompartmentId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),
+ RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ RTPrintf(Cloud::tr("Parameter \'compartment\' is empty or absent.\n"
+ "Trying to get the compartment from the passed cloud profile \'%s\'\n"),
+ pCommonOpts->profile.pszProfileName);
+ Bstr bStrCompartmentId;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
+ RTEXITCODE_FAILURE);
+ strCompartmentId = bStrCompartmentId;
+ if (strCompartmentId.isNotEmpty())
+ RTPrintf(Cloud::tr("Found the compartment \'%s\':\n"), strCompartmentId.c_str());
+ else
+ return errorSyntax(Cloud::tr("Parameter --compartment-id is required"));
+ }
+
+ Bstr bstrProfileName;
+ pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IStringArray> pVMNamesHolder;
+ ComPtr<IStringArray> pVMIdsHolder;
+ com::SafeArray<BSTR> arrayVMNames;
+ com::SafeArray<BSTR> arrayVMIds;
+ ComPtr<IProgress> pProgress;
+
+ RTPrintf(Cloud::tr("Reply is in the form \'instance name\' = \'instance id\'\n"));
+
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ListInstances(ComSafeArrayAsInParam(machineStates),
+ pVMNamesHolder.asOutParam(),
+ pVMIdsHolder.asOutParam(),
+ pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Failed to list instances")), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc,
+ pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc,
+ pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("The list of the instances for the cloud profile \'%ls\'\nand compartment \'%s\':\n"),
+ bstrProfileName.raw(), strCompartmentId.c_str());
+ size_t cIds = arrayVMIds.size();
+ size_t cNames = arrayVMNames.size();
+ for (size_t k = 0; k < cNames; k++)
+ {
+ Bstr value;
+ if (k < cIds)
+ value = arrayVMIds[k];
+ RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * List all available cloud images for the specified cloud provider.
+ *
+ * @returns RTEXITCODE
+ * @param a is the list of passed arguments
+ * @param iFirst is the position of the first unparsed argument in the arguments list
+ * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
+ * arguments which have been already parsed before
+ */
+static RTEXITCODE listCloudImages(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
+ { "--state", 's', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Utf8Str strCompartmentId;
+ com::SafeArray<CloudImageState_T> imageStates;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'c':
+ strCompartmentId = ValueUnion.psz;
+ break;
+
+ case 's':
+ {
+ const char * const pszState = ValueUnion.psz;
+
+ if (RTStrICmp(pszState, "available") == 0)
+ imageStates.push_back(CloudImageState_Available);
+ else if (RTStrICmp(pszState, "deleted") == 0)
+ imageStates.push_back(CloudImageState_Deleted);
+ else if (RTStrICmp(pszState, "disabled") == 0)
+ imageStates.push_back(CloudImageState_Disabled);
+ else if (RTStrICmp(pszState, "exporting") == 0)
+ imageStates.push_back(CloudImageState_Exporting);
+ else if (RTStrICmp(pszState, "importing") == 0)
+ imageStates.push_back(CloudImageState_Importing);
+ else if (RTStrICmp(pszState, "provisioning") == 0)
+ imageStates.push_back(CloudImageState_Provisioning);
+ else
+ return errorArgument(Cloud::tr("Unknown cloud image state \"%s\""), pszState);
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+
+ HRESULT hrc = S_OK;
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ if (strCompartmentId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
+ RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ RTPrintf(Cloud::tr("Parameter \'compartment\' is empty or absent.\n"
+ "Trying to get the compartment from the passed cloud profile \'%s\'\n"),
+ pCommonOpts->profile.pszProfileName);
+ Bstr bStrCompartmentId;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
+ RTEXITCODE_FAILURE);
+ strCompartmentId = bStrCompartmentId;
+ if (strCompartmentId.isNotEmpty())
+ RTPrintf(Cloud::tr("Found the compartment \'%s\':\n"), strCompartmentId.c_str());
+ else
+ return errorSyntax(Cloud::tr("Parameter --compartment-id is required"));
+ }
+
+ Bstr bstrProfileName;
+ pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IStringArray> pVMNamesHolder;
+ ComPtr<IStringArray> pVMIdsHolder;
+ com::SafeArray<BSTR> arrayVMNames;
+ com::SafeArray<BSTR> arrayVMIds;
+ ComPtr<IProgress> pProgress;
+
+ RTPrintf(Cloud::tr("Reply is in the form \'image name\' = \'image id\'\n"));
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ListImages(ComSafeArrayAsInParam(imageStates),
+ pVMNamesHolder.asOutParam(),
+ pVMIdsHolder.asOutParam(),
+ pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Failed to list images")), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc,
+ pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc,
+ pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("The list of the images for the cloud profile \'%ls\'\nand compartment \'%s\':\n"),
+ bstrProfileName.raw(), strCompartmentId.c_str());
+ size_t cNames = arrayVMNames.size();
+ size_t cIds = arrayVMIds.size();
+ for (size_t k = 0; k < cNames; k++)
+ {
+ Bstr value;
+ if (k < cIds)
+ value = arrayVMIds[k];
+ RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * List all available cloud vnic attachments for the specified cloud provider.
+ *
+ * @returns RTEXITCODE
+ * @param a is the list of passed arguments
+ * @param iFirst is the position of the first unparsed argument in the arguments list
+ * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
+ * arguments which have been already parsed before
+ */
+static RTEXITCODE listCloudVnicAttachments(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
+ { "--filter", 'f', RTGETOPT_REQ_STRING },/*instanceId=<id>, vnicId=<id>, domainName=<name>*/
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ com::SafeArray<BSTR> parameters;
+ Utf8Str strCompartmentId;
+ Utf8Str filterList;
+ HRESULT hrc = S_OK;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'c':
+ strCompartmentId = ValueUnion.psz;
+ Bstr(Utf8Str("compartmentId=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+
+ case 'f':
+ filterList.append(ValueUnion.psz).append(",");
+ Bstr(Utf8Str(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ RTPrintf(Cloud::tr("Filters: \'%s\' \n"), filterList.c_str());
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ if (strCompartmentId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
+ RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ RTPrintf(Cloud::tr("Parameter \'compartment\' is empty or absent.\n"
+ "Trying to get the compartment from the passed cloud profile \'%s\'\n"), pCommonOpts->profile.pszProfileName);
+ Bstr bStrCompartmentId;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
+ RTEXITCODE_FAILURE);
+ strCompartmentId = bStrCompartmentId;
+ if (strCompartmentId.isNotEmpty())
+ RTPrintf(Cloud::tr("Found the compartment \'%s\':\n"), strCompartmentId.c_str());
+ else
+ return errorArgument(Cloud::tr("Parameter --compartment-id is required."));
+ }
+
+ Bstr bstrProfileName;
+ pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IStringArray> pVnicAttachmentIdsHolder;
+ ComPtr<IStringArray> pVnicIdsHolder;
+ com::SafeArray<BSTR> arrayVnicAttachmentIds;
+ com::SafeArray<BSTR> arrayVnicIds;
+ ComPtr<IProgress> pProgress;
+
+ RTPrintf(Cloud::tr("Reply is in the form \'Vnic attachment <id>\': \n\t \'Vnic <id>\'\n"));
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ListVnicAttachments(ComSafeArrayAsInParam(parameters),
+ pVnicAttachmentIdsHolder.asOutParam(),
+ pVnicIdsHolder.asOutParam(),
+ pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Failed to list Vnic attachments")), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc,
+ pVnicAttachmentIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVnicAttachmentIds)),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc,
+ pVnicIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVnicIds)),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("The list of the Vnic attachments:\n"));
+ size_t cVnicAttchIds = arrayVnicAttachmentIds.size();
+ size_t cVnicIds = arrayVnicIds.size();
+
+ if (cVnicAttchIds == 0)
+ RTPrintf(Cloud::tr("\tEmpty\n"));
+ else
+ {
+ Bstr value;
+ for (size_t k = 0; k < cVnicAttchIds; k++)
+ {
+ if (k < cVnicIds)
+ value = arrayVnicIds[k];
+ RTPrintf(Cloud::tr("Vnic attachment id [%ls]:\n\t Vnic id - %ls\n"), arrayVnicAttachmentIds[k], value.raw());
+ }
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * General function which handles the "list" commands
+ *
+ * @returns RTEXITCODE
+ * @param a is the list of passed arguments
+ * @param iFirst is the position of the first unparsed argument in the arguments list
+ * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
+ * arguments which have been already parsed before
+ */
+static RTEXITCODE handleCloudLists(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ enum
+ {
+ kCloudListIota = 1000,
+ kCloudList_Images,
+ kCloudList_Instances,
+ kCloudList_Machines,
+ kCloudList_Networks,
+ kCloudList_Objects,
+ kCloudList_Subnets,
+ kCloudList_Vcns,
+ kCloudList_VnicAttachments,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "images", kCloudList_Images, RTGETOPT_REQ_NOTHING },
+ { "instances", kCloudList_Instances, RTGETOPT_REQ_NOTHING },
+ { "machines", kCloudList_Machines, RTGETOPT_REQ_NOTHING },
+ { "networks", kCloudList_Networks, RTGETOPT_REQ_NOTHING },
+ { "objects", kCloudList_Objects, RTGETOPT_REQ_NOTHING },
+ { "subnets", kCloudList_Subnets, RTGETOPT_REQ_NOTHING },
+ { "vcns", kCloudList_Vcns, RTGETOPT_REQ_NOTHING },
+ { "vms", kCloudList_Machines, RTGETOPT_REQ_NOTHING },
+ { "vnicattachments", kCloudList_VnicAttachments, RTGETOPT_REQ_NOTHING },
+
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "-?", 'h', RTGETOPT_REQ_NOTHING },
+ { "-help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING },
+ };
+
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case kCloudList_Images:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDLIST_IMAGES);
+ return listCloudImages(a, GetState.iNext, pCommonOpts);
+
+ case kCloudList_Instances:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDLIST_INSTANCES);
+ return listCloudInstances(a, GetState.iNext, pCommonOpts);
+ case kCloudList_Machines:
+ return listCloudMachines(a, GetState.iNext,
+ pCommonOpts->provider.pszProviderName,
+ pCommonOpts->profile.pszProfileName);
+
+ case kCloudList_VnicAttachments:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDLIST_VNICATTACHMENTS);
+ return listCloudVnicAttachments(a, GetState.iNext, pCommonOpts);
+
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
+
+
+static RTEXITCODE createCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ enum
+ {
+ kInstanceIota = 1000,
+ kInstance_ShapeCpu,
+ kInstance_ShapeMemory,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--image-id", 'i', RTGETOPT_REQ_STRING },
+ { "--boot-volume-id", 'v', RTGETOPT_REQ_STRING },
+ { "--display-name", 'n', RTGETOPT_REQ_STRING },
+ { "--launch-mode", 'm', RTGETOPT_REQ_STRING },
+ { "--shape", 's', RTGETOPT_REQ_STRING },
+ { "--shape-cpus", kInstance_ShapeCpu, RTGETOPT_REQ_UINT32 },
+ { "--shape-memory", kInstance_ShapeMemory, RTGETOPT_REQ_UINT32 },
+ { "--domain-name", 'd', RTGETOPT_REQ_STRING },
+ { "--boot-disk-size", 'b', RTGETOPT_REQ_STRING },
+ { "--publicip", 'p', RTGETOPT_REQ_STRING },
+ { "--subnet", 't', RTGETOPT_REQ_STRING },
+ { "--privateip", 'P', RTGETOPT_REQ_STRING },
+ { "--launch", 'l', RTGETOPT_REQ_STRING },
+ { "--public-ssh-key", 'k', RTGETOPT_REQ_STRING },
+ { "--cloud-init-script-path", 'c', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ ComPtr<IAppliance> pAppliance;
+ CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
+ ULONG vsdNum = 1;
+ CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(1, &vsdNum), RTEXITCODE_FAILURE);
+ com::SafeIfaceArray<IVirtualSystemDescription> virtualSystemDescriptions;
+ CHECK_ERROR2_RET(hrc, pAppliance,
+ COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(virtualSystemDescriptions)),
+ RTEXITCODE_FAILURE);
+ ComPtr<IVirtualSystemDescription> pVSD = virtualSystemDescriptions[0];
+
+ Utf8Str strDisplayName, strImageId, strBootVolumeId, strPublicSSHKey;
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ strImageId = ValueUnion.psz;
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudImageId,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+
+ case 'v':
+ strBootVolumeId = ValueUnion.psz;
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudBootVolumeId,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'n':
+ strDisplayName = ValueUnion.psz;
+ pVSD->AddDescription(VirtualSystemDescriptionType_Name,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'm':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudOCILaunchMode,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+
+ case 's':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudInstanceShape,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+
+ case kInstance_ShapeCpu:
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudShapeCpus,
+ BstrFmt("%RI32", ValueUnion.u32).raw(), NULL);
+ break;
+
+ case kInstance_ShapeMemory:
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudShapeMemory,
+ BstrFmt("%RI32", ValueUnion.u32).raw(), NULL);
+ break;
+
+ case 'd':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudDomain,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'b':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudBootDiskSize,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'p':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudPublicIP,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'P':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudPrivateIP,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 't':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudOCISubnet,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'l':
+ {
+ Utf8Str strLaunch(ValueUnion.psz);
+ if (strLaunch.isNotEmpty() && (strLaunch.equalsIgnoreCase("true") || strLaunch.equalsIgnoreCase("false")))
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudLaunchInstance,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ }
+ case 'k':
+ strPublicSSHKey = ValueUnion.psz;
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudPublicSSHKey,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'c':
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudInitScriptPath,
+ Bstr(ValueUnion.psz).raw(), NULL);
+ break;
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strPublicSSHKey.isEmpty())
+ RTPrintf(Cloud::tr("Warning!!! Public SSH key doesn't present in the passed arguments...\n"));
+
+ if (strImageId.isNotEmpty() && strBootVolumeId.isNotEmpty())
+ return errorArgument(Cloud::tr("Parameters --image-id and --boot-volume-id are mutually exclusive. "
+ "Only one of them must be presented."));
+
+ if (strImageId.isEmpty() && strBootVolumeId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter --image-id or --boot-volume-id. One of them must be presented."));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ pVSD->AddDescription(VirtualSystemDescriptionType_CloudProfileName,
+ Bstr(pCommonOpts->profile.pszProfileName).raw(),
+ NULL);
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IStringArray> infoArray;
+ com::SafeArray<BSTR> pStrInfoArray;
+ ComPtr<IProgress> pProgress;
+
+#if 0
+ /*
+ * OCI API returns an error during an instance creation if the image isn't available
+ * or in the inappropriate state. So the check can be omitted.
+ */
+ RTPrintf(Cloud::tr("Checking the cloud image with id \'%s\'...\n"), strImageId.c_str());
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ GetImageInfo(Bstr(strImageId).raw(),
+ infoArray.asOutParam(),
+ pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Checking the cloud image failed")), RTEXITCODE_FAILURE);
+
+ pProgress.setNull();
+#endif
+
+ if (strImageId.isNotEmpty())
+ RTPrintf(Cloud::tr("Creating cloud instance with name \'%s\' from the image \'%s\'...\n"),
+ strDisplayName.c_str(), strImageId.c_str());
+ else
+ RTPrintf(Cloud::tr("Creating cloud instance with name \'%s\' from the boot volume \'%s\'...\n"),
+ strDisplayName.c_str(), strBootVolumeId.c_str());
+
+ CHECK_ERROR2_RET(hrc, oCloudClient, LaunchVM(pVSD, pProgress.asOutParam()), RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Creating cloud instance failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud instance was created successfully\n"));
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE updateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ RT_NOREF(a);
+ RT_NOREF(iFirst);
+ RT_NOREF(pCommonOpts);
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE showCloudInstanceInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strInstanceId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strInstanceId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strInstanceId = ValueUnion.psz;
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Getting information about cloud instance with id %s...\n"), strInstanceId.c_str());
+ RTPrintf(Cloud::tr("Reply is in the form \'setting name\' = \'value\'\n"));
+
+ ComPtr<IAppliance> pAppliance;
+ CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
+
+ com::SafeIfaceArray<IVirtualSystemDescription> vsdArray;
+ ULONG requestedVSDnums = 1;
+ ULONG newVSDnums = 0;
+ CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(requestedVSDnums, &newVSDnums), RTEXITCODE_FAILURE);
+ if (requestedVSDnums != newVSDnums)
+ return RTEXITCODE_FAILURE;
+
+ CHECK_ERROR2_RET(hrc, pAppliance, COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(vsdArray)), RTEXITCODE_FAILURE);
+ ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ GetInstanceInfo(Bstr(strInstanceId).raw(), instanceDescription, progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Getting information about cloud instance failed")), RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("Cloud instance info (provider '%s'):\n"),
+ pCommonOpts->provider.pszProviderName);
+
+ struct vsdHReadable {
+ VirtualSystemDescriptionType_T vsdType;
+ Utf8Str strFound;
+ Utf8Str strNotFound;
+ };
+
+ const size_t vsdHReadableArraySize = 15;//the number of items in the vsdHReadableArray
+ vsdHReadable vsdHReadableArray[vsdHReadableArraySize] = {
+ {VirtualSystemDescriptionType_CloudDomain, Cloud::tr("Availability domain = %ls\n"), Cloud::tr("Availability domain wasn't found\n")},
+ {VirtualSystemDescriptionType_Name, Cloud::tr("Instance displayed name = %ls\n"), Cloud::tr("Instance displayed name wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceState, Cloud::tr("Instance state = %ls\n"), Cloud::tr("Instance state wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceId, Cloud::tr("Instance Id = %ls\n"), Cloud::tr("Instance Id wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceDisplayName, Cloud::tr("Instance name = %ls\n"), Cloud::tr("Instance name wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudImageId, Cloud::tr("Bootable image Id = %ls\n"),
+ Cloud::tr("Image Id whom the instance is booted up wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceShape, Cloud::tr("Shape of the instance = %ls\n"),
+ Cloud::tr("The shape of the instance wasn't found\n")},
+ {VirtualSystemDescriptionType_OS, Cloud::tr("Type of guest OS = %ls\n"), Cloud::tr("Type of guest OS wasn't found\n")},
+ {VirtualSystemDescriptionType_Memory, Cloud::tr("RAM = %ls MB\n"), Cloud::tr("Value for RAM wasn't found\n")},
+ {VirtualSystemDescriptionType_CPU, Cloud::tr("CPUs = %ls\n"), Cloud::tr("Numbers of CPUs weren't found\n")},
+ {VirtualSystemDescriptionType_CloudPublicIP, Cloud::tr("Instance public IP = %ls\n"), Cloud::tr("Public IP wasn't found\n")},
+ {VirtualSystemDescriptionType_Miscellaneous, "%ls\n", Cloud::tr("Miscellanious wasn't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceFreeFormTags, "%ls\n", Cloud::tr("Free-form tags weren't found\n")},
+ {VirtualSystemDescriptionType_CloudInstanceMetadata, "%ls\n", Cloud::tr("Metadata was't found\n")},
+ {VirtualSystemDescriptionType_CloudInitScriptPath, "Cloud-init script: \n\t%ls\n", Cloud::tr("Cloud-init script wasn't found\n")}
+ };
+
+ com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
+ com::SafeArray<BSTR> aRefs;
+ com::SafeArray<BSTR> aOvfValues;
+ com::SafeArray<BSTR> aVBoxValues;
+ com::SafeArray<BSTR> aExtraConfigValues;
+
+ for (size_t i=0; i<vsdHReadableArraySize ; ++i)
+ {
+ hrc = instanceDescription->GetDescriptionByType(vsdHReadableArray[i].vsdType,
+ ComSafeArrayAsOutParam(retTypes),
+ ComSafeArrayAsOutParam(aRefs),
+ ComSafeArrayAsOutParam(aOvfValues),
+ ComSafeArrayAsOutParam(aVBoxValues),
+ ComSafeArrayAsOutParam(aExtraConfigValues));
+ if (FAILED(hrc) || aVBoxValues.size() == 0)
+ LogRel((vsdHReadableArray[i].strNotFound.c_str()));
+ else
+ {
+ LogRel(("Size is %d", aVBoxValues.size()));
+ for (size_t j = 0; j<aVBoxValues.size(); ++j)
+ {
+ RTPrintf(vsdHReadableArray[i].strFound.c_str(), aVBoxValues[j]);
+ }
+ }
+
+ retTypes.setNull();
+ aRefs.setNull();
+ aOvfValues.setNull();
+ aVBoxValues.setNull();
+ aExtraConfigValues.setNull();
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strInstanceId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strInstanceId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strInstanceId = ValueUnion.psz;
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Starting cloud instance with id %s...\n"), strInstanceId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ StartInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Starting the cloud instance failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud instance with id %s (provider = '%s', profile = '%s') was started\n"),
+ strInstanceId.c_str(),
+ pCommonOpts->provider.pszProviderName,
+ pCommonOpts->profile.pszProfileName);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE pauseCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strInstanceId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strInstanceId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strInstanceId = ValueUnion.psz;
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Pausing cloud instance with id %s...\n"), strInstanceId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ PauseInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Pause the cloud instance failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud instance with id %s (provider = '%s', profile = '%s') was paused\n"),
+ strInstanceId.c_str(),
+ pCommonOpts->provider.pszProviderName,
+ pCommonOpts->profile.pszProfileName);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE terminateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strInstanceId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strInstanceId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strInstanceId = ValueUnion.psz;
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Terminating cloud instance with id %s...\n"), strInstanceId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ TerminateInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Termination the cloud instance failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud instance with id %s (provider = '%s', profile = '%s') was terminated\n"),
+ strInstanceId.c_str(),
+ pCommonOpts->provider.pszProviderName,
+ pCommonOpts->profile.pszProfileName);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE resetCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strInstanceId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strInstanceId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strInstanceId = ValueUnion.psz;
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Reset cloud instance with id %s...\n"), strInstanceId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ResetInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Reset the cloud instance failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud instance with id %s (provider = '%s', profile = '%s') was reset\n"),
+ strInstanceId.c_str(),
+ pCommonOpts->provider.pszProviderName,
+ pCommonOpts->profile.pszProfileName);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE handleCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ enum
+ {
+ kCloudInstanceIota = 1000,
+ kCloudInstance_Create,
+ kCloudInstance_Info,
+ kCloudInstance_Pause,
+ kCloudInstance_Start,
+ kCloudInstance_Terminate,
+ kCloudInstance_Update,
+ kCloudInstance_Reset,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "create", kCloudInstance_Create, RTGETOPT_REQ_NOTHING },
+ { "info", kCloudInstance_Info, RTGETOPT_REQ_NOTHING },
+ { "pause", kCloudInstance_Pause, RTGETOPT_REQ_NOTHING },
+ { "start", kCloudInstance_Start, RTGETOPT_REQ_NOTHING },
+ { "terminate", kCloudInstance_Terminate, RTGETOPT_REQ_NOTHING },
+ { "update", kCloudInstance_Update, RTGETOPT_REQ_NOTHING },
+ { "reset", kCloudInstance_Reset, RTGETOPT_REQ_NOTHING },
+
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "-?", 'h', RTGETOPT_REQ_NOTHING },
+ { "-help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING },
+ };
+
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ /* Sub-commands: */
+ case kCloudInstance_Create:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_CREATE);
+ return createCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Start:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_START);
+ return startCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Pause:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_PAUSE);
+ return pauseCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Info:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_INFO);
+ return showCloudInstanceInfo(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Update:
+// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_UPDATE);
+ return updateCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Terminate:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_TERMINATE);
+ return terminateCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case kCloudInstance_Reset:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_RESET);
+ return resetCloudInstance(a, GetState.iNext, pCommonOpts);
+
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
+
+
+static RTEXITCODE createCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--object-name", 'o', RTGETOPT_REQ_STRING },
+ { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
+ { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
+ { "--instance-id", 'i', RTGETOPT_REQ_STRING },
+ { "--display-name", 'd', RTGETOPT_REQ_STRING },
+ { "--launch-mode", 'm', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strCompartmentId;
+ Utf8Str strInstanceId;
+ Utf8Str strDisplayName;
+ Utf8Str strBucketName;
+ Utf8Str strObjectName;
+ com::SafeArray<BSTR> parameters;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'c':
+ strCompartmentId=ValueUnion.psz;
+ Bstr(Utf8Str("compartment-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'i':
+ strInstanceId=ValueUnion.psz;
+ Bstr(Utf8Str("instance-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'd':
+ strDisplayName=ValueUnion.psz;
+ Bstr(Utf8Str("display-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'o':
+ strObjectName=ValueUnion.psz;
+ Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'b':
+ strBucketName=ValueUnion.psz;
+ Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'm':
+ strBucketName=ValueUnion.psz;
+ Bstr(Utf8Str("launch-mode=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strInstanceId.isNotEmpty() && strObjectName.isNotEmpty())
+ return errorArgument(Cloud::tr("Conflicting parameters: --instance-id and --object-name can't be used together. Choose one."));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ if (strInstanceId.isNotEmpty())
+ RTPrintf(Cloud::tr("Creating cloud image with name \'%s\' from the instance \'%s\'...\n"),
+ strDisplayName.c_str(), strInstanceId.c_str());
+ else
+ RTPrintf(Cloud::tr("Creating cloud image with name \'%s\' from the object \'%s\' in the bucket \'%s\'...\n"),
+ strDisplayName.c_str(), strObjectName.c_str(), strBucketName.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ CreateImage(ComSafeArrayAsInParam(parameters), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Creating cloud image failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud image was created successfully\n"));
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static RTEXITCODE exportCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
+ { "--object-name", 'o', RTGETOPT_REQ_STRING },
+ { "--display-name", 'd', RTGETOPT_REQ_STRING },
+ { "--launch-mode", 'm', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strImageId; /* XXX: this is vbox "image", i.e. medium */
+ Utf8Str strBucketName;
+ Utf8Str strObjectName;
+ Utf8Str strDisplayName;
+ Utf8Str strLaunchMode;
+ com::SafeArray<BSTR> parameters;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'b': /* --bucket-name */
+ {
+ if (strBucketName.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --bucket-name"));
+
+ strBucketName = ValueUnion.psz;
+ if (strBucketName.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --bucket-name"));
+
+ break;
+ }
+
+ case 'o': /* --object-name */
+ {
+ if (strObjectName.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --object-name"));
+
+ strObjectName = ValueUnion.psz;
+ if (strObjectName.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --object-name"));
+
+ break;
+ }
+
+ case 'i': /* --id */
+ {
+ if (strImageId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strImageId = ValueUnion.psz;
+ if (strImageId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+
+ case 'd': /* --display-name */
+ {
+ if (strDisplayName.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --display-name"));
+
+ strDisplayName = ValueUnion.psz;
+ if (strDisplayName.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --display-name"));
+
+ break;
+ }
+
+ case 'm': /* --launch-mode */
+ {
+ if (strLaunchMode.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --launch-mode"));
+
+ strLaunchMode = ValueUnion.psz;
+ if (strLaunchMode.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --launch-mode"));
+
+ break;
+ }
+
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strImageId.isNotEmpty())
+ BstrFmt("image-id=%s", strImageId.c_str()).detachTo(parameters.appendedRaw());
+ else
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+ if (strBucketName.isNotEmpty())
+ BstrFmt("bucket-name=%s", strBucketName.c_str()).detachTo(parameters.appendedRaw());
+ else
+ return errorArgument(Cloud::tr("Missing parameter: --bucket-name"));
+
+ if (strObjectName.isNotEmpty())
+ BstrFmt("object-name=%s", strObjectName.c_str()).detachTo(parameters.appendedRaw());
+
+ if (strDisplayName.isNotEmpty())
+ BstrFmt("display-name=%s", strDisplayName.c_str()).detachTo(parameters.appendedRaw());
+
+ if (strLaunchMode.isNotEmpty())
+ BstrFmt("launch-mode=%s", strLaunchMode.c_str()).detachTo(parameters.appendedRaw());
+
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ if (strObjectName.isNotEmpty())
+ RTPrintf(Cloud::tr("Exporting image \'%s\' to the Cloud with name \'%s\'...\n"),
+ strImageId.c_str(), strObjectName.c_str());
+ else
+ RTPrintf(Cloud::tr("Exporting image \'%s\' to the Cloud with default name\n"),
+ strImageId.c_str());
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ SafeIfaceArray<IMedium> aImageList;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(HardDisks)(ComSafeArrayAsOutParam(aImageList)),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IMedium> pImage;
+ size_t cImages = aImageList.size();
+ bool fFound = false;
+ for (size_t i = 0; i < cImages; ++i)
+ {
+ pImage = aImageList[i];
+ Bstr bstrImageId;
+ hrc = pImage->COMGETTER(Id)(bstrImageId.asOutParam());
+ if (FAILED(hrc))
+ continue;
+
+ com::Guid imageId(bstrImageId);
+
+ if (!imageId.isValid() || imageId.isZero())
+ continue;
+
+ if (!strImageId.compare(imageId.toString()))
+ {
+ fFound = true;
+ RTPrintf(Cloud::tr("Image %s was found\n"), strImageId.c_str());
+ break;
+ }
+ }
+
+ if (!fFound)
+ {
+ RTPrintf(Cloud::tr("Process of exporting the image to the Cloud was interrupted. The image wasn't found.\n"));
+ return RTEXITCODE_FAILURE;
+ }
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ExportImage(pImage, ComSafeArrayAsInParam(parameters), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Export the image to the Cloud failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Export the image to the Cloud was successfull\n"));
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE importCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
+ { "--object-name", 'o', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strImageId;
+ Utf8Str strCompartmentId;
+ Utf8Str strBucketName;
+ Utf8Str strObjectName;
+ Utf8Str strDisplayName;
+ com::SafeArray<BSTR> parameters;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ strImageId=ValueUnion.psz;
+ break;
+ case 'b':
+ strBucketName=ValueUnion.psz;
+ Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'o':
+ strObjectName=ValueUnion.psz;
+ Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
+ break;
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Creating an object \'%s\' from the cloud image \'%s\'...\n"), strObjectName.c_str(), strImageId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ ImportImage(Bstr(strImageId).raw(), ComSafeArrayAsInParam(parameters), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Cloud image import failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ {
+ RTPrintf(Cloud::tr("Cloud image was imported successfully. Find the downloaded object with the name %s "
+ "in the system temp folder (find the possible environment variables like TEMP, TMP and etc.)\n"),
+ strObjectName.c_str());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE showCloudImageInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strImageId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ strImageId = ValueUnion.psz;
+ break;
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Getting information about the cloud image with id \'%s\'...\n"), strImageId.c_str());
+
+ ComPtr<IStringArray> infoArray;
+ com::SafeArray<BSTR> pStrInfoArray;
+ ComPtr<IProgress> pProgress;
+
+ RTPrintf(Cloud::tr("Reply is in the form \'image property\' = \'value\'\n"));
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ GetImageInfo(Bstr(strImageId).raw(),
+ infoArray.asOutParam(),
+ pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Cloud::tr("Getting information about the cloud image failed")), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc,
+ infoArray, COMGETTER(Values)(ComSafeArrayAsOutParam(pStrInfoArray)),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("General information about the image:\n"));
+ size_t cParamNames = pStrInfoArray.size();
+ for (size_t k = 0; k < cParamNames; k++)
+ {
+ Utf8Str data(pStrInfoArray[k]);
+ RTPrintf("\t%s\n", data.c_str());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE updateCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ RT_NOREF(a);
+ RT_NOREF(iFirst);
+ RT_NOREF(pCommonOpts);
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE deleteCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ Utf8Str strImageId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ {
+ if (strImageId.isNotEmpty())
+ return errorArgument(Cloud::tr("Duplicate parameter: --id"));
+
+ strImageId = ValueUnion.psz;
+ if (strImageId.isEmpty())
+ return errorArgument(Cloud::tr("Empty parameter: --id"));
+
+ break;
+ }
+
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (strImageId.isEmpty())
+ return errorArgument(Cloud::tr("Missing parameter: --id"));
+
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+ RTPrintf(Cloud::tr("Deleting cloud image with id %s...\n"), strImageId.c_str());
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ DeleteImage(Bstr(strImageId).raw(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Deleting cloud image failed")), RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud image was deleted successfully\n"));
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE handleCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ enum
+ {
+ kCloudImageIota = 1000,
+ kCloudImage_Create,
+ kCloudImage_Delete,
+ kCloudImage_Export,
+ kCloudImage_Import,
+ kCloudImage_Info,
+ kCloudImage_Update,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "create", kCloudImage_Create, RTGETOPT_REQ_NOTHING },
+ { "delete", kCloudImage_Delete, RTGETOPT_REQ_NOTHING },
+ { "export", kCloudImage_Export, RTGETOPT_REQ_NOTHING },
+ { "import", kCloudImage_Import, RTGETOPT_REQ_NOTHING },
+ { "info", kCloudImage_Info, RTGETOPT_REQ_NOTHING },
+ { "update", kCloudImage_Update, RTGETOPT_REQ_NOTHING },
+
+ { "help", 'h', RTGETOPT_REQ_NOTHING },
+ { "-?", 'h', RTGETOPT_REQ_NOTHING },
+ { "-help", 'h', RTGETOPT_REQ_NOTHING },
+ { "--help", 'h', RTGETOPT_REQ_NOTHING },
+ };
+
+ if (a->argc == iFirst)
+ {
+ RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ /* Sub-commands: */
+ case kCloudImage_Create:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_CREATE);
+ return createCloudImage(a, GetState.iNext, pCommonOpts);
+
+ case kCloudImage_Export:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_EXPORT);
+ return exportCloudImage(a, GetState.iNext, pCommonOpts);
+
+ case kCloudImage_Import:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_IMPORT);
+ return importCloudImage(a, GetState.iNext, pCommonOpts);
+
+ case kCloudImage_Info:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_INFO);
+ return showCloudImageInfo(a, GetState.iNext, pCommonOpts);
+
+ case kCloudImage_Update:
+// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_UPDATE);
+ return updateCloudImage(a, GetState.iNext, pCommonOpts);
+
+ case kCloudImage_Delete:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_DELETE);
+ return deleteCloudImage(a, GetState.iNext, pCommonOpts);
+
+ case 'h':
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
+
+#ifdef VBOX_WITH_CLOUD_NET
+struct CloudNetworkOptions
+{
+ BOOL fEnable;
+ BOOL fDisable;
+ Bstr strNetworkId;
+ Bstr strNetworkName;
+};
+typedef struct CloudNetworkOptions CLOUDNETOPT;
+typedef CLOUDNETOPT *PCLOUDNETOPT;
+
+static RTEXITCODE createUpdateCloudNetworkCommon(ComPtr<ICloudNetwork> cloudNetwork, CLOUDNETOPT& options, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ Bstr strProvider = pCommonOpts->provider.pszProviderName;
+ Bstr strProfile = pCommonOpts->profile.pszProfileName;
+
+ if (options.fEnable)
+ {
+ CHECK_ERROR2_RET(hrc, cloudNetwork, COMSETTER(Enabled)(TRUE), RTEXITCODE_FAILURE);
+ }
+ if (options.fDisable)
+ {
+ CHECK_ERROR2_RET(hrc, cloudNetwork, COMSETTER(Enabled)(FALSE), RTEXITCODE_FAILURE);
+ }
+ if (options.strNetworkId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, cloudNetwork, COMSETTER(NetworkId)(options.strNetworkId.raw()), RTEXITCODE_FAILURE);
+ }
+ if (strProvider.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, cloudNetwork, COMSETTER(Provider)(strProvider.raw()), RTEXITCODE_FAILURE);
+ }
+ if (strProfile.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, cloudNetwork, COMSETTER(Profile)(strProfile.raw()), RTEXITCODE_FAILURE);
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE createCloudNetwork(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ /* Required parameters, the rest is handled in update */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--network-id", 'i', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ };
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ CLOUDNETOPT options;
+ options.fEnable = FALSE;
+ options.fDisable = FALSE;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'd':
+ options.fDisable = TRUE;
+ break;
+ case 'e':
+ options.fEnable = TRUE;
+ break;
+ case 'i':
+ options.strNetworkId=ValueUnion.psz;
+ break;
+ case 'n':
+ options.strNetworkName=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (options.strNetworkName.isEmpty())
+ return errorArgument(Cloud::tr("Missing --name parameter"));
+ if (options.strNetworkId.isEmpty())
+ return errorArgument(Cloud::tr("Missing --network-id parameter"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudNetwork> cloudNetwork;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ CreateCloudNetwork(options.strNetworkName.raw(), cloudNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ /* Fill out the created network */
+ RTEXITCODE rc = createUpdateCloudNetworkCommon(cloudNetwork, options, pCommonOpts);
+ if (RT_SUCCESS(rc))
+ RTPrintf(Cloud::tr("Cloud network was created successfully\n"));
+
+ return rc;
+}
+
+
+static RTEXITCODE showCloudNetworkInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ RT_NOREF(pCommonOpts);
+ HRESULT hrc = S_OK;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Bstr strNetworkName;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ strNetworkName=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (strNetworkName.isEmpty())
+ return errorArgument(Cloud::tr("Missing --name parameter"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudNetwork> cloudNetwork;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindCloudNetworkByName(strNetworkName.raw(), cloudNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Cloud::tr("Name: %ls\n"), strNetworkName.raw());
+ BOOL fEnabled = FALSE;
+ cloudNetwork->COMGETTER(Enabled)(&fEnabled);
+ RTPrintf(Cloud::tr("State: %s\n"), fEnabled ? Cloud::tr("Enabled") : Cloud::tr("Disabled"));
+ Bstr Provider;
+ cloudNetwork->COMGETTER(Provider)(Provider.asOutParam());
+ RTPrintf(Cloud::tr("CloudProvider: %ls\n"), Provider.raw());
+ Bstr Profile;
+ cloudNetwork->COMGETTER(Profile)(Profile.asOutParam());
+ RTPrintf(Cloud::tr("CloudProfile: %ls\n"), Profile.raw());
+ Bstr NetworkId;
+ cloudNetwork->COMGETTER(NetworkId)(NetworkId.asOutParam());
+ RTPrintf(Cloud::tr("CloudNetworkId: %ls\n"), NetworkId.raw());
+ Bstr netName = BstrFmt("cloud-%ls", strNetworkName.raw());
+ RTPrintf(Cloud::tr("VBoxNetworkName: %ls\n\n"), netName.raw());
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE updateCloudNetwork(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--network-id", 'i', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ };
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ CLOUDNETOPT options;
+ options.fEnable = FALSE;
+ options.fDisable = FALSE;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'd':
+ options.fDisable = TRUE;
+ break;
+ case 'e':
+ options.fEnable = TRUE;
+ break;
+ case 'i':
+ options.strNetworkId=ValueUnion.psz;
+ break;
+ case 'n':
+ options.strNetworkName=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (options.strNetworkName.isEmpty())
+ return errorArgument(Cloud::tr("Missing --name parameter"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudNetwork> cloudNetwork;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindCloudNetworkByName(options.strNetworkName.raw(), cloudNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ RTEXITCODE rc = createUpdateCloudNetworkCommon(cloudNetwork, options, pCommonOpts);
+ if (RT_SUCCESS(rc))
+ RTPrintf(Cloud::tr("Cloud network %ls was updated successfully\n"), options.strNetworkName.raw());
+
+ return rc;
+}
+
+
+static RTEXITCODE deleteCloudNetwork(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ RT_NOREF(pCommonOpts);
+ HRESULT hrc = S_OK;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Bstr strNetworkName;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ strNetworkName=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (strNetworkName.isEmpty())
+ return errorArgument(Cloud::tr("Missing --name parameter"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudNetwork> cloudNetwork;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindCloudNetworkByName(strNetworkName.raw(), cloudNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ RemoveCloudNetwork(cloudNetwork),
+ RTEXITCODE_FAILURE);
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Cloud::tr("Cloud network %ls was deleted successfully\n"), strNetworkName.raw());
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static RTEXITCODE setupCloudNetworkEnv(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ RT_NOREF(pCommonOpts);
+ HRESULT hrc = S_OK;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--gateway-os-name", 'n', RTGETOPT_REQ_STRING },
+ { "--gateway-os-version", 'v', RTGETOPT_REQ_STRING },
+ { "--gateway-shape", 's', RTGETOPT_REQ_STRING },
+ { "--tunnel-network-name", 't', RTGETOPT_REQ_STRING },
+ { "--tunnel-network-range", 'r', RTGETOPT_REQ_STRING },
+ { "--compartment-id", 'c', RTGETOPT_REQ_STRING }
+ };
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Bstr strGatewayOsName;
+ Bstr strGatewayOsVersion;
+ Bstr strGatewayShape;
+ Bstr strTunnelNetworkName;
+ Bstr strTunnelNetworkRange;
+ Bstr strCompartmentId;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ strGatewayOsName=ValueUnion.psz;
+ break;
+ case 'v':
+ strGatewayOsVersion=ValueUnion.psz;
+ break;
+ case 's':
+ strGatewayShape=ValueUnion.psz;
+ break;
+ case 't':
+ strTunnelNetworkName=ValueUnion.psz;
+ break;
+ case 'r':
+ strTunnelNetworkRange=ValueUnion.psz;
+ break;
+ case 'c':
+ strCompartmentId=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Delayed check. It allows us to print help information.*/
+ hrc = checkAndSetCommonOptions(a, pCommonOpts);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ RTPrintf(Cloud::tr("Setting up tunnel network in the cloud...\n"));
+
+ ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
+
+ /* Use user-specified profile instead of default one. */
+ if (strCompartmentId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),
+ RTEXITCODE_FAILURE);
+ }
+
+ ComObjPtr<ICloudClient> oCloudClient;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ CreateCloudClient(oCloudClient.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudNetworkEnvironmentInfo> cloudNetworkEnv;
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2_RET(hrc, oCloudClient,
+ SetupCloudNetworkEnvironment(strTunnelNetworkName.raw(), strTunnelNetworkRange.raw(),
+ strGatewayOsName.raw(), strGatewayOsVersion.raw(), strGatewayShape.raw(),
+ cloudNetworkEnv.asOutParam(), progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Setting up cloud network environment failed")), RTEXITCODE_FAILURE);
+
+ Bstr tunnelNetworkId;
+ hrc = cloudNetworkEnv->COMGETTER(TunnelNetworkId)(tunnelNetworkId.asOutParam());
+ RTPrintf(Cloud::tr("Cloud network environment was set up successfully. Tunnel network id is: %ls\n"), tunnelNetworkId.raw());
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static RTEXITCODE handleCloudNetwork(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
+{
+ enum
+ {
+ kCloudNetworkIota = 1000,
+ kCloudNetwork_Create,
+ kCloudNetwork_Delete,
+ kCloudNetwork_Info,
+ kCloudNetwork_Setup,
+ kCloudNetwork_Update,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "create", kCloudNetwork_Create, RTGETOPT_REQ_NOTHING },
+ { "delete", kCloudNetwork_Delete, RTGETOPT_REQ_NOTHING },
+ { "info", kCloudNetwork_Info, RTGETOPT_REQ_NOTHING },
+ { "setup", kCloudNetwork_Setup, RTGETOPT_REQ_NOTHING },
+ { "update", kCloudNetwork_Update, RTGETOPT_REQ_NOTHING },
+ };
+
+ if (a->argc < 1)
+ return errorNoSubcommand();
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ /* Sub-commands: */
+ case kCloudNetwork_Create:
+ return createCloudNetwork(a, GetState.iNext, pCommonOpts);
+
+ case kCloudNetwork_Info:
+ return showCloudNetworkInfo(a, GetState.iNext, pCommonOpts);
+
+ case kCloudNetwork_Update:
+ return updateCloudNetwork(a, GetState.iNext, pCommonOpts);
+
+ case kCloudNetwork_Delete:
+ return deleteCloudNetwork(a, GetState.iNext, pCommonOpts);
+
+ case kCloudNetwork_Setup:
+ return setupCloudNetworkEnv(a, GetState.iNext, pCommonOpts);
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
+#endif /* VBOX_WITH_CLOUD_NET */
+
+
+RTEXITCODE handleCloud(HandlerArg *a)
+{
+ enum
+ {
+ kCloudIota = 1000,
+ kCloud_Image,
+ kCloud_Instance,
+ kCloud_List,
+ kCloud_Machine,
+ kCloud_Network,
+ kCloud_Object,
+ kCloud_ShowVMInfo,
+ kCloud_Volume,
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--provider", 'v', RTGETOPT_REQ_STRING },
+ { "--profile", 'f', RTGETOPT_REQ_STRING },
+
+ { "image", kCloud_Image, RTGETOPT_REQ_NOTHING },
+ { "instance", kCloud_Instance, RTGETOPT_REQ_NOTHING },
+ { "list", kCloud_List, RTGETOPT_REQ_NOTHING },
+ { "machine", kCloud_Machine, RTGETOPT_REQ_NOTHING },
+ { "network", kCloud_Network, RTGETOPT_REQ_NOTHING },
+ { "object", kCloud_Object, RTGETOPT_REQ_NOTHING },
+ { "showvminfo", kCloud_ShowVMInfo, RTGETOPT_REQ_NOTHING },
+ { "volume", kCloud_Volume, RTGETOPT_REQ_NOTHING },
+ };
+
+ if (a->argc < 1)
+ return errorNoSubcommand();
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ CLOUDCOMMONOPT commonOpts = { {NULL, NULL}, {NULL, NULL} };
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'v': // --provider
+ commonOpts.provider.pszProviderName = ValueUnion.psz;
+ break;
+
+ case 'f': // --profile
+ commonOpts.profile.pszProfileName = ValueUnion.psz;
+ break;
+
+ /* Sub-commands: */
+ case kCloud_List:
+ return handleCloudLists(a, GetState.iNext, &commonOpts);
+
+ case kCloud_Image:
+ return handleCloudImage(a, GetState.iNext, &commonOpts);
+
+ case kCloud_Instance:
+ return handleCloudInstance(a, GetState.iNext, &commonOpts);
+
+#ifdef VBOX_WITH_CLOUD_NET
+ case kCloud_Network:
+ return handleCloudNetwork(a, GetState.iNext, &commonOpts);
+#endif /* VBOX_WITH_CLOUD_NET */
+
+ /* "cloud machine ..." handling is in VBoxManageCloudMachine.cpp */
+ case kCloud_Machine:
+ return handleCloudMachine(a, GetState.iNext,
+ commonOpts.provider.pszProviderName,
+ commonOpts.profile.pszProfileName);
+
+ /* ... including aliases that mimic the local vm commands */
+ case kCloud_ShowVMInfo:
+ return handleCloudShowVMInfo(a, GetState.iNext,
+ commonOpts.provider.pszProviderName,
+ commonOpts.profile.pszProfileName);
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageCloudMachine.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageCloudMachine.cpp
new file mode 100644
index 00000000..78223337
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageCloudMachine.cpp
@@ -0,0 +1,1482 @@
+/* $Id: VBoxManageCloudMachine.cpp $ */
+/** @file
+ * VBoxManageCloudMachine - The cloud machine related commands.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "VBoxManage.h"
+
+#include <VBox/log.h>
+
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/errorprint.h>
+
+#include <algorithm>
+#include <vector>
+
+DECLARE_TRANSLATION_CONTEXT(CloudMachine);
+
+
+struct CMachineHandlerArg
+ : public HandlerArg
+{
+ ComPtr<ICloudClient> pClient;
+
+ const char *pcszSpec; /* RTGETOPTUNION::psz, points inside argv */
+ enum { GUESS, ID, NAME } enmSpecKind;
+ ComPtr<ICloudMachine> pMachine;
+
+ explicit CMachineHandlerArg(const HandlerArg &a)
+ : HandlerArg(a), pcszSpec(NULL), enmSpecKind(GUESS) {}
+};
+
+
+static int selectCloudProvider(ComPtr<ICloudProvider> &pProvider,
+ const ComPtr<IVirtualBox> &pVirtualBox,
+ const char *pszProviderName);
+static int selectCloudProfile(ComPtr<ICloudProfile> &pProfile,
+ const ComPtr<ICloudProvider> &pProvider,
+ const char *pszProviderName);
+static int getCloudClient(CMachineHandlerArg &a,
+ const char *pcszProviderName,
+ const char *pcszProfileName);
+
+static HRESULT getMachineList(com::SafeIfaceArray<ICloudMachine> &aMachines,
+ const ComPtr<ICloudClient> &pClient);
+
+static HRESULT getMachineBySpec(CMachineHandlerArg *a);
+static HRESULT getMachineById(CMachineHandlerArg *a);
+static HRESULT getMachineByName(CMachineHandlerArg *a);
+static HRESULT getMachineByGuess(CMachineHandlerArg *a);
+
+static int checkMachineSpecArgument(CMachineHandlerArg *a,
+ int ch, const RTGETOPTUNION &Val);
+
+
+static RTEXITCODE handleCloudMachineImpl(CMachineHandlerArg *a, int iFirst);
+
+static RTEXITCODE handleCloudMachineStart(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachineReboot(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachineReset(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachineShutdown(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachinePowerdown(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachineTerminate(CMachineHandlerArg *a, int iFirst);
+
+static RTEXITCODE handleCloudMachineConsoleHistory(CMachineHandlerArg *a, int iFirst);
+
+static RTEXITCODE listCloudMachinesImpl(CMachineHandlerArg *a, int iFirst);
+static RTEXITCODE handleCloudMachineInfo(CMachineHandlerArg *a, int iFirst);
+
+static HRESULT printMachineInfo(const ComPtr<ICloudMachine> &pMachine);
+static HRESULT printFormValue(const ComPtr<IFormValue> &pValue);
+
+
+
+/*
+ * This is a temporary hack as I don't want to refactor "cloud"
+ * handling right now, as it's not yet clear to me what is the
+ * direction that we want to take with it.
+ *
+ * The problem with the way "cloud" command handling is currently
+ * written is that it's a bit schizophrenic about whether we have
+ * multiple cloud providers or not. OTOH it insists on --provider
+ * being mandatory, on the other it hardcodes the list of available
+ * subcommands, though in principle those can vary from provider to
+ * provider. If we do want to support multiple providers we might
+ * need to come up with a way to allow an extpack provider to supply
+ * its own VBoxManage command handler for "cloud" based on --provider
+ * as the selector.
+ *
+ * Processing of --provider and --profile should not be postponed
+ * until the leaf command handler, but rather happen immediately, so
+ * do this here at our earliest opportunity (without actually doing it
+ * in handleCloud).
+ */
+RTEXITCODE
+handleCloudMachine(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName)
+{
+ CMachineHandlerArg handlerArg(*a);
+ int vrc = getCloudClient(handlerArg, pcszProviderName, pcszProfileName);
+ if (RT_FAILURE(vrc))
+ return RTEXITCODE_FAILURE;
+
+ return handleCloudMachineImpl(&handlerArg, iFirst);
+}
+
+
+/*
+ * Select cloud provider to use based on the --provider option to the
+ * "cloud" command. The option is not mandatory if only a single
+ * provider is available.
+ */
+static int
+selectCloudProvider(ComPtr<ICloudProvider> &pProvider,
+ const ComPtr<IVirtualBox> &pVirtualBox,
+ const char *pcszProviderName)
+{
+ HRESULT hrc;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ VERR_GENERAL_FAILURE);
+
+
+ /*
+ * If the provider is explicitly specified, just look it up and
+ * return.
+ */
+ if (pcszProviderName != NULL)
+ {
+ /*
+ * Should we also provide a way to specify the provider also
+ * by its id? Is it even useful? If so, should we use a
+ * different option or check if the provider name looks like
+ * an id and used a different getter?
+ */
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(com::Bstr(pcszProviderName).raw(),
+ pProvider.asOutParam()),
+ VERR_NOT_FOUND);
+
+ return VINF_SUCCESS;
+ }
+
+
+ /*
+ * We have only one provider and it's not clear if we will ever
+ * have more than one. Forcing the user to explicitly specify the
+ * only provider available is not very nice. So try to be
+ * friendly.
+ */
+ com::SafeIfaceArray<ICloudProvider> aProviders;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ COMGETTER(Providers)(ComSafeArrayAsOutParam(aProviders)),
+ VERR_GENERAL_FAILURE);
+
+ if (aProviders.size() == 0)
+ {
+ RTMsgError(CloudMachine::tr("cloud: no providers available"));
+ return VERR_NOT_FOUND;
+ }
+
+ if (aProviders.size() > 1)
+ {
+ RTMsgError(CloudMachine::tr("cloud: multiple providers available,"
+ " '--provider' option is required"));
+ return VERR_MISSING;
+ }
+
+ /* Do RTMsgInfo telling the user which one was selected? */
+ pProvider = aProviders[0];
+ return VINF_SUCCESS;
+}
+
+
+/*
+ * Select cloud profile to use based on the --profile option to the
+ * "cloud" command. The option is not mandatory if only a single
+ * profile exists.
+ */
+static int
+selectCloudProfile(ComPtr<ICloudProfile> &pProfile,
+ const ComPtr<ICloudProvider> &pProvider,
+ const char *pcszProfileName)
+{
+ HRESULT hrc;
+
+ /*
+ * If the profile is explicitly specified, just look it up and
+ * return.
+ */
+ if (pcszProfileName != NULL)
+ {
+ CHECK_ERROR2_RET(hrc, pProvider,
+ GetProfileByName(com::Bstr(pcszProfileName).raw(),
+ pProfile.asOutParam()),
+ VERR_NOT_FOUND);
+
+ return VINF_SUCCESS;
+ }
+
+
+ /*
+ * If the user has just one profile for this provider, don't force
+ * them to specify it. I'm not entirely sure about this one,
+ * actually. It's nice for interactive use, but it might be not
+ * forward compatible if used in a script and then when another
+ * profile is created the script starts failing. I'd say, give
+ * them enough rope...
+ */
+ com::SafeIfaceArray<ICloudProfile> aProfiles;
+ CHECK_ERROR2_RET(hrc, pProvider,
+ COMGETTER(Profiles)(ComSafeArrayAsOutParam(aProfiles)),
+ VERR_GENERAL_FAILURE);
+
+ if (aProfiles.size() == 0)
+ {
+ RTMsgError(CloudMachine::tr("cloud: no profiles exist"));
+ return VERR_NOT_FOUND;
+ }
+
+ if (aProfiles.size() > 1)
+ {
+ RTMsgError(CloudMachine::tr("cloud: multiple profiles exist, '--profile' option is required"));
+ return VERR_MISSING;
+ }
+
+ /* Do RTMsgInfo telling the user which one was selected? */
+ pProfile = aProfiles[0];
+ return VINF_SUCCESS;
+}
+
+
+static int
+getCloudClient(CMachineHandlerArg &a,
+ const char *pcszProviderName,
+ const char *pcszProfileName)
+{
+ ComPtr<ICloudProvider> pProvider;
+ int vrc = selectCloudProvider(pProvider, a.virtualBox, pcszProviderName);
+ if (RT_FAILURE(vrc))
+ return vrc;
+
+ ComPtr<ICloudProfile> pProfile;
+ vrc = selectCloudProfile(pProfile, pProvider, pcszProfileName);
+ if (RT_FAILURE(vrc))
+ return vrc;
+
+ ComPtr<ICloudClient> pCloudClient;
+ CHECK_ERROR2I_RET(pProfile, CreateCloudClient(pCloudClient.asOutParam()), VERR_GENERAL_FAILURE);
+
+ a.pClient = pCloudClient;
+ return VINF_SUCCESS;
+}
+
+
+static HRESULT
+getMachineList(com::SafeIfaceArray<ICloudMachine> &aMachines,
+ const ComPtr<ICloudClient> &pClient)
+{
+ HRESULT hrc;
+
+ ComPtr<IProgress> pListProgress;
+ CHECK_ERROR2_RET(hrc, pClient,
+ ReadCloudMachineList(pListProgress.asOutParam()),
+ hrc);
+
+ hrc = showProgress(pListProgress, SHOW_PROGRESS_NONE);
+ if (FAILED(hrc))
+ return hrc;
+
+ CHECK_ERROR2_RET(hrc, pClient,
+ COMGETTER(CloudMachineList)(ComSafeArrayAsOutParam(aMachines)),
+ hrc);
+
+ return S_OK;
+}
+
+
+static HRESULT
+getMachineById(CMachineHandlerArg *a)
+{
+ HRESULT hrc;
+
+ ComPtr<ICloudMachine> pMachine;
+ CHECK_ERROR2_RET(hrc, a->pClient,
+ GetCloudMachine(com::Bstr(a->pcszSpec).raw(),
+ pMachine.asOutParam()), hrc);
+
+ ComPtr<IProgress> pRefreshProgress;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ Refresh(pRefreshProgress.asOutParam()), hrc);
+
+ hrc = showProgress(pRefreshProgress, SHOW_PROGRESS_NONE);
+ if (FAILED(hrc))
+ return hrc;
+
+ a->pMachine = pMachine;
+ return S_OK;
+}
+
+
+static HRESULT
+getMachineByName(CMachineHandlerArg *a)
+{
+ HRESULT hrc;
+
+ com::SafeIfaceArray<ICloudMachine> aMachines;
+ hrc = getMachineList(aMachines, a->pClient);
+ if (FAILED(hrc))
+ return hrc;
+
+ const size_t cMachines = aMachines.size();
+ if (cMachines == 0)
+ return VBOX_E_OBJECT_NOT_FOUND;
+
+ ComPtr<ICloudMachine> pMachineFound;
+ for (size_t i = 0; i < cMachines; ++i)
+ {
+ const ComPtr<ICloudMachine> pMachine = aMachines[i];
+
+ com::Bstr bstrName;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(Name)(bstrName.asOutParam()),
+ hrc);
+
+ if (!bstrName.equals(a->pcszSpec))
+ continue;
+
+ if (pMachineFound.isNull())
+ pMachineFound = pMachine;
+ else
+ {
+ com::Bstr bstrId1, bstrId2;
+ CHECK_ERROR2_RET(hrc, pMachineFound,
+ COMGETTER(Id)(bstrId1.asOutParam()),
+ hrc);
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(Id)(bstrId2.asOutParam()),
+ hrc);
+
+ RTMsgError(CloudMachine::tr("ambiguous name: %ls and %ls"), bstrId1.raw(), bstrId2.raw());
+ return VBOX_E_OBJECT_NOT_FOUND;
+ }
+ }
+
+ if (pMachineFound.isNull())
+ return VBOX_E_OBJECT_NOT_FOUND;
+
+ a->pMachine = pMachineFound;
+ return S_OK;
+}
+
+
+/*
+ * Try to find the machine refered by pcszWhatever. If the look up by
+ * id fails we might want to fallback to look up by name, b/c someone
+ * might want to use a uuid as a display name of a machine. But cloud
+ * lookups are not fast, so that would be incurring performance
+ * penalty for typos or for machines that are gone. Should provide
+ * explicit --id/--name options instead.
+ */
+static HRESULT
+getMachineByGuess(CMachineHandlerArg *a)
+{
+ HRESULT hrc;
+
+ RTUUID Uuid;
+ int vrc = RTUuidFromStr(&Uuid, a->pcszSpec);
+ if (RT_SUCCESS(vrc))
+ hrc = getMachineById(a);
+ else
+ hrc = getMachineByName(a);
+
+ if (FAILED(hrc))
+ return hrc;
+
+ return S_OK;
+}
+
+
+
+/*
+ * RTGETOPTINIT_FLAGS_NO_STD_OPTS recognizes both --help and --version
+ * and we don't want the latter. It's easier to add one line of this
+ * macro to the s_aOptions initializers than to filter out --version.
+ */
+#define CLOUD_MACHINE_RTGETOPTDEF_HELP \
+ { "--help", 'h', RTGETOPT_REQ_NOTHING }, \
+ { "-help", 'h', RTGETOPT_REQ_NOTHING }, \
+ { "help", 'h', RTGETOPT_REQ_NOTHING }, \
+ { "-?", 'h', RTGETOPT_REQ_NOTHING }
+
+static RTEXITCODE
+errThereCanBeOnlyOne()
+{
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ CloudMachine::tr("only one machine can be specified"));
+}
+
+
+#define CLOUD_MACHINE_RTGETOPTDEF_MACHINE \
+ { "--id", 'i', RTGETOPT_REQ_STRING }, \
+ { "--name", 'n', RTGETOPT_REQ_STRING }
+
+
+/*
+ * Almost all the cloud machine commands take a machine argument, so
+ * factor out the code to fish it out from the command line.
+ *
+ * ch - option should be processed by the caller.
+ * VINF_SUCCESS - option was processed.
+ * VERR_PARSE_ERROR - RTEXITCODE_SYNTAX
+ * Other IPRT errors - RTEXITCODE_FAILURE
+ */
+static int
+checkMachineSpecArgument(CMachineHandlerArg *a,
+ int ch, const RTGETOPTUNION &Val)
+{
+ int vrc;
+
+ switch (ch)
+ {
+ /*
+ * Note that we don't used RTGETOPT_REQ_UUID here as it would
+ * be too limiting. First, we need the original string for
+ * the API call, not the UUID, and second, if the UUID has bad
+ * forward RTGetOptPrintError doesn't have access to the
+ * option argument for the error message. So do the format
+ * check ourselves.
+ */
+ case 'i': /* --id */
+ {
+ const char *pcszId = Val.psz;
+
+ if (a->pcszSpec != NULL)
+ {
+ errThereCanBeOnlyOne();
+ return VERR_PARSE_ERROR;
+ }
+
+ RTUUID Uuid;
+ vrc = RTUuidFromStr(&Uuid, pcszId);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(CloudMachine::tr("not a valid uuid: %s"), pcszId);
+ return VERR_PARSE_ERROR;
+ }
+
+ a->pcszSpec = pcszId;
+ a->enmSpecKind = CMachineHandlerArg::ID;
+ return VINF_SUCCESS;
+ }
+
+ case 'n': /* --name */
+ {
+ const char *pcszName = Val.psz;
+
+ if (a->pcszSpec != NULL)
+ {
+ errThereCanBeOnlyOne();
+ return VERR_PARSE_ERROR;
+ }
+
+ a->pcszSpec = pcszName;
+ a->enmSpecKind = CMachineHandlerArg::NAME;
+ return VINF_SUCCESS;
+ }
+
+ /*
+ * Plain word (no dash/es). This must name a machine, though
+ * we have to guess whether it's an id or a name.
+ */
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ const char *pcszNameOrId = Val.psz;
+
+ if (a->pcszSpec != NULL)
+ {
+ errThereCanBeOnlyOne();
+ return VERR_PARSE_ERROR;
+ }
+
+ a->pcszSpec = pcszNameOrId;
+ a->enmSpecKind = CMachineHandlerArg::GUESS;
+ return VINF_SUCCESS;
+ }
+
+ /* might as well do it here */
+ case 'h': /* --help */
+ {
+ printHelp(g_pStdOut);
+ return VINF_CALLBACK_RETURN;
+ }
+ }
+
+ /* let the caller deal with it */
+ return VINF_NOT_SUPPORTED;
+}
+
+
+static HRESULT
+getMachineBySpec(CMachineHandlerArg *a)
+{
+ HRESULT hrc = E_FAIL;
+
+ if (a->pcszSpec == NULL)
+ {
+ RTMsgErrorExit(RTEXITCODE_SYNTAX, CloudMachine::tr("machine not specified"));
+ return E_FAIL;
+ }
+
+ if (a->pcszSpec[0] == '\0')
+ {
+ RTMsgError(CloudMachine::tr("machine name is empty"));
+ return E_FAIL;
+ }
+
+ switch (a->enmSpecKind)
+ {
+ case CMachineHandlerArg::ID:
+ hrc = getMachineById(a);
+ if (FAILED(hrc))
+ {
+ if (hrc == VBOX_E_OBJECT_NOT_FOUND)
+ RTMsgError(CloudMachine::tr("unable to find machine with id %s"), a->pcszSpec);
+ return hrc;
+ }
+ break;
+
+ case CMachineHandlerArg::NAME:
+ hrc = getMachineByName(a);
+ if (FAILED(hrc))
+ {
+ if (hrc == VBOX_E_OBJECT_NOT_FOUND)
+ RTMsgError(CloudMachine::tr("unable to find machine with name %s"), a->pcszSpec);
+ return hrc;
+ }
+ break;
+
+ case CMachineHandlerArg::GUESS:
+ hrc = getMachineByGuess(a);
+ if (FAILED(hrc))
+ {
+ if (hrc == VBOX_E_OBJECT_NOT_FOUND)
+ RTMsgError(CloudMachine::tr("unable to find machine %s"), a->pcszSpec);
+ return hrc;
+ }
+ break;
+ }
+
+ /* switch was exhaustive (and successful) */
+ AssertReturn(SUCCEEDED(hrc), E_FAIL);
+ return S_OK;
+}
+
+
+
+
+/*
+ * cloud machine [--id id | --name name] command ...
+ *
+ * We allow machine to be specified after "machine" but only with an
+ * explicit option for the obvious reason. We will also check for
+ * these options and machine spec as a plain words argument after the
+ * command word, so user can use either of:
+ *
+ * cloud machine --name foo start
+ * cloud machine start --name foo
+ * cloud machine start foo
+ *
+ * This will accept e.g. cloud machine --name foo list ... b/c we
+ * don't yet know that it's "list" that is coming, so commands that
+ * don't take machine argument check that separately when called. One
+ * side effect of this is that specifying several machines or using a
+ * syntactically invalid id will be reported as such, not as an
+ * unknown option, but that's a relatively minor nit.
+ */
+static RTEXITCODE
+handleCloudMachineImpl(CMachineHandlerArg *a, int iFirst)
+{
+ enum
+ {
+ kMachineIota = 1000,
+ kMachine_ConsoleHistory,
+ kMachine_Info,
+ kMachine_List,
+ kMachine_Powerdown,
+ kMachine_Reboot,
+ kMachine_Reset,
+ kMachine_Shutdown,
+ kMachine_Start,
+ kMachine_Terminate,
+ };
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE);
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "console-history", kMachine_ConsoleHistory, RTGETOPT_REQ_NOTHING },
+ { "consolehistory", kMachine_ConsoleHistory, RTGETOPT_REQ_NOTHING },
+ { "info", kMachine_Info, RTGETOPT_REQ_NOTHING },
+ { "list", kMachine_List, RTGETOPT_REQ_NOTHING },
+ { "powerdown", kMachine_Powerdown, RTGETOPT_REQ_NOTHING },
+ { "reboot", kMachine_Reboot, RTGETOPT_REQ_NOTHING },
+ { "reset", kMachine_Reset, RTGETOPT_REQ_NOTHING },
+ { "shutdown", kMachine_Shutdown, RTGETOPT_REQ_NOTHING },
+ { "start", kMachine_Start, RTGETOPT_REQ_NOTHING },
+ { "terminate", kMachine_Terminate, RTGETOPT_REQ_NOTHING },
+ CLOUD_MACHINE_RTGETOPTDEF_MACHINE,
+ CLOUD_MACHINE_RTGETOPTDEF_HELP
+ };
+
+ RTGETOPTSTATE OptState;
+ int vrc = RTGetOptInit(&OptState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions),
+ iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTMsgErrorExit(RTEXITCODE_INIT, CloudMachine::tr("cloud machine: RTGetOptInit: %Rra"), vrc));
+
+ int ch;
+ RTGETOPTUNION Val;
+ while ((ch = RTGetOpt(&OptState, &Val)) != 0)
+ {
+ if (RT_FAILURE(ch))
+ return RTGetOptPrintError(ch, &Val);
+
+ /*
+ * Check for an unknown word first: checkMachineSpecArgument()
+ * would try to interpret that as a machine id/name.
+ */
+ if (ch == VINF_GETOPT_NOT_OPTION)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ CloudMachine::tr("Invalid sub-command: %s"), Val.psz);
+
+ /*
+ * Allow --id/--name after "machine", before the command.
+ * Also handles --help.
+ */
+ vrc = checkMachineSpecArgument(a, ch, Val);
+ if (vrc == VINF_SUCCESS)
+ continue;
+ if (vrc == VINF_CALLBACK_RETURN)
+ return RTEXITCODE_SUCCESS;
+ if (vrc == VERR_PARSE_ERROR)
+ return RTEXITCODE_SYNTAX;
+
+ /*
+ * Dispatch to command implementation ([ab]use getopt to do
+ * string comparisons for us).
+ */
+ switch (ch)
+ {
+ case kMachine_ConsoleHistory:
+ return handleCloudMachineConsoleHistory(a, OptState.iNext);
+
+ case kMachine_Info:
+ return handleCloudMachineInfo(a, OptState.iNext);
+
+ case kMachine_List:
+ return listCloudMachinesImpl(a, OptState.iNext);
+
+ case kMachine_Powerdown:
+ return handleCloudMachinePowerdown(a, OptState.iNext);
+
+ case kMachine_Reboot:
+ return handleCloudMachineReboot(a, OptState.iNext);
+
+ case kMachine_Reset:
+ return handleCloudMachineReset(a, OptState.iNext);
+
+ case kMachine_Shutdown:
+ return handleCloudMachineShutdown(a, OptState.iNext);
+
+ case kMachine_Start:
+ return handleCloudMachineStart(a, OptState.iNext);
+
+ case kMachine_Terminate:
+ return handleCloudMachineTerminate(a, OptState.iNext);
+
+ default: /* should never happen */
+ return RTMsgErrorExit(RTEXITCODE_INIT,
+ CloudMachine::tr("cloud machine: internal error: %d"), ch);
+ }
+ }
+
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ CloudMachine::tr("cloud machine: command required\n"
+ "Try '--help' for more information."));
+}
+
+
+/*
+ * cloud list machines
+ *
+ * The "cloud list" prefix handling is in VBoxManageCloud.cpp, so this
+ * function is not static. See handleCloudMachine() for the
+ * explanation early provider/profile lookup.
+ */
+RTEXITCODE
+listCloudMachines(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName)
+{
+ CMachineHandlerArg handlerArg(*a);
+ int vrc = getCloudClient(handlerArg, pcszProviderName, pcszProfileName);
+ if (RT_FAILURE(vrc))
+ return RTEXITCODE_FAILURE;
+
+ return listCloudMachinesImpl(&handlerArg, iFirst);
+}
+
+
+/*
+ * cloud machine list # convenience alias
+ * cloud list machines # see above
+ */
+static RTEXITCODE
+listCloudMachinesImpl(CMachineHandlerArg *a, int iFirst)
+{
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_LIST);
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--long", 'l', RTGETOPT_REQ_NOTHING },
+ { "--sort", 's', RTGETOPT_REQ_NOTHING },
+ CLOUD_MACHINE_RTGETOPTDEF_HELP
+ };
+
+ enum kFormatEnum { kFormat_Short, kFormat_Long };
+ kFormatEnum enmFormat = kFormat_Short;
+
+ enum kSortOrderEnum { kSortOrder_None, kSortOrder_Name, kSortOrder_Id };
+ kSortOrderEnum enmSortOrder = kSortOrder_None;
+
+ if (a->pcszSpec != NULL)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ CloudMachine::tr("cloud machine list: unexpected machine argument"));
+
+
+ RTGETOPTSTATE OptState;
+ int vrc = RTGetOptInit(&OptState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions),
+ iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTMsgErrorExit(RTEXITCODE_INIT, CloudMachine::tr("cloud machine list: RTGetOptInit: %Rra"), vrc));
+
+ int ch;
+ RTGETOPTUNION Val;
+ while ((ch = RTGetOpt(&OptState, &Val)) != 0)
+ {
+ switch (ch)
+ {
+ case 'l':
+ enmFormat = kFormat_Long;
+ break;
+
+ case 's':
+ /** @todo optional argument to select the sort key? */
+ enmSortOrder = kSortOrder_Name;
+ break;
+
+ case 'h': /* --help */
+ printHelp(g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+
+
+ case VINF_GETOPT_NOT_OPTION:
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX,
+ CloudMachine::tr("Invalid sub-command: %s"), Val.psz);
+
+ default:
+ return RTGetOptPrintError(ch, &Val);
+ }
+ }
+
+ com::SafeIfaceArray<ICloudMachine> aMachines;
+ HRESULT hrc = getMachineList(aMachines, a->pClient);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ const size_t cMachines = aMachines.size();
+ if (cMachines == 0)
+ return RTEXITCODE_SUCCESS;
+
+
+ /*
+ * Get names/ids that we need for the short output and to sort the
+ * list.
+ */
+ std::vector<ComPtr<ICloudMachine> > vMachines(cMachines);
+ std::vector<com::Bstr> vBstrNames(cMachines);
+ std::vector<com::Bstr> vBstrIds(cMachines);
+ for (size_t i = 0; i < cMachines; ++i)
+ {
+ vMachines[i] = aMachines[i];
+
+ CHECK_ERROR2_RET(hrc, vMachines[i],
+ COMGETTER(Name)(vBstrNames[i].asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc, vMachines[i],
+ COMGETTER(Id)(vBstrIds[i].asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+
+
+ /*
+ * Sort the list if necessary. The sort is indirect via an
+ * intermediate array of indexes.
+ */
+ std::vector<size_t> vIndexes(cMachines);
+ for (size_t i = 0; i < cMachines; ++i)
+ vIndexes[i] = i;
+
+ if (enmSortOrder != kSortOrder_None)
+ {
+ struct SortBy {
+ const std::vector<com::Bstr> &ks;
+ SortBy(const std::vector<com::Bstr> &aKeys) : ks(aKeys) {}
+ bool operator() (size_t l, size_t r) { return ks[l] < ks[r]; }
+ };
+
+ std::sort(vIndexes.begin(), vIndexes.end(),
+ SortBy(enmSortOrder == kSortOrder_Name
+ ? vBstrNames : vBstrIds));
+ }
+
+
+ if (enmFormat == kFormat_Short)
+ {
+ for (size_t i = 0; i < cMachines; ++i)
+ {
+ const size_t idx = vIndexes[i];
+ const com::Bstr &bstrId = vBstrIds[idx];
+ const com::Bstr &bstrName = vBstrNames[idx];
+
+ RTPrintf("%ls %ls\n", bstrId.raw(), bstrName.raw());
+ }
+ }
+ else // kFormat_Long
+ {
+ for (size_t i = 0; i < cMachines; ++i)
+ {
+ const size_t idx = vIndexes[i];
+ const ComPtr<ICloudMachine> &pMachine = vMachines[idx];
+
+ if (i != 0)
+ RTPrintf("\n");
+ printMachineInfo(pMachine);
+ }
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/*
+ * cloud showvminfo "id"
+ *
+ * Alias for "cloud machine info" that tries to match the local vm
+ * counterpart.
+ */
+RTEXITCODE
+handleCloudShowVMInfo(HandlerArg *a, int iFirst,
+ const char *pcszProviderName,
+ const char *pcszProfileName)
+{
+ CMachineHandlerArg handlerArg(*a);
+ int vrc = getCloudClient(handlerArg, pcszProviderName, pcszProfileName);
+ if (RT_FAILURE(vrc))
+ return RTEXITCODE_FAILURE;
+
+ return handleCloudMachineInfo(&handlerArg, iFirst);
+}
+
+
+/*
+ * cloud machine info "id" ...
+ */
+static RTEXITCODE
+handleCloudMachineInfo(CMachineHandlerArg *a, int iFirst)
+{
+ enum
+ {
+ kMachineInfoIota = 1000,
+ kMachineInfo_Details,
+ };
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_INFO);
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--details", kMachineInfo_Details, RTGETOPT_REQ_NOTHING },
+ CLOUD_MACHINE_RTGETOPTDEF_MACHINE,
+ CLOUD_MACHINE_RTGETOPTDEF_HELP
+ };
+
+ RTGETOPTSTATE OptState;
+ int vrc = RTGetOptInit(&OptState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions),
+ iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTMsgErrorExit(RTEXITCODE_INIT, "RTGetOptInit: %Rra", vrc));
+
+ int ch;
+ RTGETOPTUNION Val;
+ while ((ch = RTGetOpt(&OptState, &Val)) != 0)
+ {
+ vrc = checkMachineSpecArgument(a, ch, Val);
+ if (vrc == VINF_SUCCESS)
+ continue;
+ if (vrc == VINF_CALLBACK_RETURN)
+ return RTEXITCODE_SUCCESS;
+ if (vrc == VERR_PARSE_ERROR)
+ return RTEXITCODE_SYNTAX;
+
+ switch (ch)
+ {
+ case kMachineInfo_Details:
+ /* currently no-op */
+ break;
+
+ default:
+ return RTGetOptPrintError(ch, &Val);
+ }
+ }
+
+ HRESULT hrc = getMachineBySpec(a);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ /* end of boilerplate */
+
+
+ hrc = printMachineInfo(a->pMachine);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+static HRESULT
+printMachineInfo(const ComPtr<ICloudMachine> &pMachine)
+{
+ HRESULT hrc;
+
+ com::Bstr bstrId;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(Id)(bstrId.asOutParam()),
+ hrc);
+ RTPrintf("UUID: %ls\n", bstrId.raw());
+
+
+ /*
+ * Check if the machine is accessible and print the error
+ * message if not.
+ */
+ BOOL fAccessible = FALSE;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(Accessible)(&fAccessible), hrc);
+
+ if (!fAccessible)
+ {
+ RTMsgError(CloudMachine::tr("machine is not accessible")); // XXX: Id?
+
+ ComPtr<IVirtualBoxErrorInfo> pErrorInfo;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(AccessError)(pErrorInfo.asOutParam()), hrc);
+
+ while (!pErrorInfo.isNull())
+ {
+ com::Bstr bstrText;
+ CHECK_ERROR2_RET(hrc, pErrorInfo,
+ COMGETTER(Text)(bstrText.asOutParam()), hrc);
+ RTStrmPrintf(g_pStdErr, "%ls\n", bstrText.raw());
+
+ CHECK_ERROR2_RET(hrc, pErrorInfo,
+ COMGETTER(Next)(pErrorInfo.asOutParam()), hrc);
+ }
+
+ return E_FAIL;
+ }
+
+
+ /*
+ * The machine seems to be ok, print its details.
+ */
+ CloudMachineState_T enmState;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ COMGETTER(State)(&enmState),
+ hrc);
+ switch (enmState) {
+ case CloudMachineState_Invalid:
+ RTPrintf(CloudMachine::tr("State: Invalid (%RU32)\n"), CloudMachineState_Invalid);
+ break;
+
+ case CloudMachineState_Provisioning:
+ RTPrintf(CloudMachine::tr("State: Provisioning (%RU32)\n"), CloudMachineState_Provisioning);
+ break;
+
+ case CloudMachineState_Running:
+ RTPrintf(CloudMachine::tr("State: Running (%RU32)\n"), CloudMachineState_Running);
+ break;
+
+ case CloudMachineState_Starting:
+ RTPrintf(CloudMachine::tr("State: Starting (%RU32)\n"), CloudMachineState_Starting);
+ break;
+
+ case CloudMachineState_Stopping:
+ RTPrintf(CloudMachine::tr("State: Stopping (%RU32)\n"), CloudMachineState_Stopping);
+ break;
+
+ case CloudMachineState_Stopped:
+ RTPrintf(CloudMachine::tr("State: Stopped (%RU32)\n"), CloudMachineState_Stopped);
+ break;
+
+ case CloudMachineState_CreatingImage:
+ RTPrintf(CloudMachine::tr("State: CreatingImage (%RU32)\n"), CloudMachineState_CreatingImage);
+ break;
+
+ case CloudMachineState_Terminating:
+ RTPrintf(CloudMachine::tr("State: Terminating (%RU32)\n"), CloudMachineState_Terminating);
+ break;
+
+ case CloudMachineState_Terminated:
+ RTPrintf(CloudMachine::tr("State: Terminated (%RU32)\n"), CloudMachineState_Terminated);
+ break;
+
+ default:
+ RTPrintf(CloudMachine::tr("State: Unknown state (%RU32)\n"), enmState);
+ }
+
+ ComPtr<IForm> pDetails;
+ CHECK_ERROR2_RET(hrc, pMachine,
+ GetDetailsForm(pDetails.asOutParam()), hrc);
+
+ if (RT_UNLIKELY(pDetails.isNull()))
+ {
+ RTMsgError(CloudMachine::tr("null details")); /* better error message? */
+ return E_FAIL;
+ }
+
+ com::SafeIfaceArray<IFormValue> aValues;
+ CHECK_ERROR2_RET(hrc, pDetails,
+ COMGETTER(Values)(ComSafeArrayAsOutParam(aValues)), hrc);
+ for (size_t i = 0; i < aValues.size(); ++i)
+ {
+ hrc = printFormValue(aValues[i]);
+ if (FAILED(hrc))
+ return hrc;
+ }
+
+ return S_OK;
+}
+
+
+static HRESULT
+printFormValue(const ComPtr<IFormValue> &pValue)
+{
+ HRESULT hrc;
+
+ BOOL fVisible = FALSE;
+ CHECK_ERROR2_RET(hrc, pValue,
+ COMGETTER(Visible)(&fVisible), hrc);
+ if (!fVisible)
+ return S_OK;
+
+
+ com::Bstr bstrLabel;
+ CHECK_ERROR2_RET(hrc, pValue,
+ COMGETTER(Label)(bstrLabel.asOutParam()), hrc);
+
+ FormValueType_T enmType;
+ CHECK_ERROR2_RET(hrc, pValue,
+ COMGETTER(Type)(&enmType), hrc);
+
+ switch (enmType)
+ {
+ case FormValueType_Boolean:
+ {
+ ComPtr<IBooleanFormValue> pBoolValue;
+ hrc = pValue.queryInterfaceTo(pBoolValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr,
+ CloudMachine::tr("%ls: unable to convert to boolean value\n"),
+ bstrLabel.raw());
+ break;
+ }
+
+ BOOL fSelected;
+ hrc = pBoolValue->GetSelected(&fSelected);
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ "%ls: %Rhra", bstrLabel.raw(), hrc);
+ break;
+ }
+
+ RTPrintf("%ls: %RTbool\n",
+ bstrLabel.raw(), RT_BOOL(fSelected));
+ break;
+ }
+
+ case FormValueType_String:
+ {
+ ComPtr<IStringFormValue> pStrValue;
+ hrc = pValue.queryInterfaceTo(pStrValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr,
+ CloudMachine::tr("%ls: unable to convert to string value\n"),
+ bstrLabel.raw());
+ break;
+ }
+
+ /*
+ * GUI hack: if clipboard string is set, it contains
+ * untruncated long value, usually full OCID, so check it
+ * first. Make this selectable with an option?
+ */
+ com::Bstr bstrValue;
+ hrc = pStrValue->COMGETTER(ClipboardString)(bstrValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ "%ls: %Rhra", bstrLabel.raw(), hrc);
+ break;
+ }
+
+ if (bstrValue.isEmpty())
+ {
+ hrc = pStrValue->GetString(bstrValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ "%ls: %Rhra", bstrLabel.raw(), hrc);
+ break;
+ }
+ }
+
+ RTPrintf("%ls: %ls\n",
+ bstrLabel.raw(), bstrValue.raw());
+ break;
+ }
+
+ case FormValueType_RangedInteger:
+ {
+ ComPtr<IRangedIntegerFormValue> pIntValue;
+ hrc = pValue.queryInterfaceTo(pIntValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr,
+ CloudMachine::tr("%ls: unable to convert to integer value\n"),
+ bstrLabel.raw());
+ break;
+ }
+
+ LONG lValue;
+ hrc = pIntValue->GetInteger(&lValue);
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ "%ls: %Rhra", bstrLabel.raw(), hrc);
+ break;
+ }
+
+ RTPrintf("%ls: %RI64\n",
+ bstrLabel.raw(), (int64_t)lValue);
+ break;
+ }
+
+ case FormValueType_Choice:
+ {
+ ComPtr<IChoiceFormValue> pChoiceValue;
+ hrc = pValue.queryInterfaceTo(pChoiceValue.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdErr,
+ CloudMachine::tr("%ls: unable to convert to choice value\n"),
+ bstrLabel.raw());
+ break;
+ }
+
+ com::SafeArray<BSTR> aValues;
+ hrc = pChoiceValue->COMGETTER(Values)(ComSafeArrayAsOutParam(aValues));
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ CloudMachine::tr("%ls: values: %Rhra"),
+ bstrLabel.raw(), hrc);
+ break;
+ }
+
+ LONG idxSelected = -1;
+ hrc = pChoiceValue->GetSelectedIndex(&idxSelected);
+ if (FAILED(hrc))
+ {
+ RTStrmPrintf(g_pStdOut,
+ CloudMachine::tr("%ls: selectedIndex: %Rhra"),
+ bstrLabel.raw(), hrc);
+ break;
+ }
+
+ if (idxSelected < 0 || (size_t)idxSelected > aValues.size())
+ {
+ RTStrmPrintf(g_pStdOut,
+ CloudMachine::tr("%ls: selected index %RI64 out of range [0, %zu)\n"),
+ bstrLabel.raw(), (int64_t)idxSelected, aValues.size());
+ break;
+ }
+
+ RTPrintf("%ls: %ls\n",
+ bstrLabel.raw(), aValues[idxSelected]);
+ break;
+ }
+
+ default:
+ {
+ RTStrmPrintf(g_pStdOut, CloudMachine::tr("unknown value type %RU32\n"), enmType);
+ break;
+ }
+ }
+
+ return S_OK;
+}
+
+
+/*
+ * Boilerplate code to get machine by name/id from the arguments.
+ * Shared by action subcommands b/c they currently don't have any
+ * extra options (but we can't use this for e.g. "info" that has
+ * --details).
+ */
+static RTEXITCODE
+getMachineFromArgs(CMachineHandlerArg *a, int iFirst)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ CLOUD_MACHINE_RTGETOPTDEF_MACHINE,
+ CLOUD_MACHINE_RTGETOPTDEF_HELP
+ };
+
+ RTGETOPTSTATE OptState;
+ int vrc = RTGetOptInit(&OptState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions),
+ iFirst, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTMsgErrorExit(RTEXITCODE_INIT, /* internal error */ "RTGetOptInit: %Rra", vrc));
+
+ int ch;
+ RTGETOPTUNION Val;
+ while ((ch = RTGetOpt(&OptState, &Val)) != 0)
+ {
+ vrc = checkMachineSpecArgument(a, ch, Val);
+ if (vrc == VINF_SUCCESS)
+ continue;
+ if (vrc == VINF_CALLBACK_RETURN)
+ return RTEXITCODE_SUCCESS;
+ if (vrc == VERR_PARSE_ERROR)
+ return RTEXITCODE_SYNTAX;
+
+ switch (ch)
+ {
+ /* no other options currently */
+ default:
+ return RTGetOptPrintError(ch, &Val);
+ }
+ }
+
+ HRESULT hrc = getMachineBySpec(a);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/*
+ * cloud machine start "id"
+ */
+static RTEXITCODE
+handleCloudMachineStart(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_START);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ PowerUp(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine reboot "id"
+ * "Press" ACPI power button, then power the instance back up.
+ */
+static RTEXITCODE
+handleCloudMachineReboot(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_REBOOT);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ Reboot(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine reset "id"
+ * Force power down machine, then power the instance back up.
+ */
+static RTEXITCODE
+handleCloudMachineReset(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_RESET);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ Reset(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine shutdown "id"
+ * "Press" ACPI power button.
+ */
+static RTEXITCODE
+handleCloudMachineShutdown(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_SHUTDOWN);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ Shutdown(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine powerdown "id"
+ * Yank the power cord.
+ */
+static RTEXITCODE
+handleCloudMachinePowerdown(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_POWERDOWN);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ PowerDown(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine terminate "id"
+ * Discard the instance running this machine.
+ */
+static RTEXITCODE
+handleCloudMachineTerminate(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_TERMINATE);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ Terminate(pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress, SHOW_PROGRESS_NONE);
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*
+ * cloud machine console-history "id"
+ */
+static RTEXITCODE
+handleCloudMachineConsoleHistory(CMachineHandlerArg *a, int iFirst)
+{
+ HRESULT hrc;
+
+ // setCurrentSubcommand(HELP_SCOPE_CLOUD_MACHINE_CONSOLEHISTORY);
+ RTEXITCODE status = getMachineFromArgs(a, iFirst);
+ if (status != RTEXITCODE_SUCCESS)
+ return status;
+
+
+ ComPtr<IDataStream> pHistoryStream;
+ ComPtr<IProgress> pHistoryProgress;
+ CHECK_ERROR2_RET(hrc, a->pMachine,
+ GetConsoleHistory(pHistoryStream.asOutParam(),
+ pHistoryProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pHistoryProgress, SHOW_PROGRESS_NONE);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ bool fEOF = false;
+ while (!fEOF)
+ {
+ com::SafeArray<BYTE> aChunk;
+ CHECK_ERROR2_RET(hrc, pHistoryStream,
+ Read(64 *_1K, 0, ComSafeArrayAsOutParam(aChunk)),
+ RTEXITCODE_FAILURE);
+ if (aChunk.size() == 0)
+ break;
+
+ RTStrmWrite(g_pStdOut, aChunk.raw(), aChunk.size());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
new file mode 100644
index 00000000..98a3f8f2
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
@@ -0,0 +1,2287 @@
+/* $Id: VBoxManageControlVM.cpp $ */
+/** @file
+ * VBoxManage - Implementation of the controlvm 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/ctype.h>
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/uuid.h>
+#include <iprt/file.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+#include "VBoxManageUtils.h"
+
+#include <list>
+
+DECLARE_TRANSLATION_CONTEXT(ControlVM);
+
+VMProcPriority_T nameToVMProcPriority(const char *pszName);
+
+/**
+ * Parses a number.
+ *
+ * @returns Valid number on success.
+ * @returns 0 if invalid number. All necessary bitching has been done.
+ * @param psz Pointer to the nic number.
+ */
+static unsigned parseNum(const char *psz, unsigned cMaxNum, const char *name)
+{
+ uint32_t u32;
+ char *pszNext;
+ int vrc = RTStrToUInt32Ex(psz, &pszNext, 10, &u32);
+ if ( RT_SUCCESS(vrc)
+ && *pszNext == '\0'
+ && u32 >= 1
+ && u32 <= cMaxNum)
+ return (unsigned)u32;
+ errorArgument(ControlVM::tr("Invalid %s number '%s'."), name, psz);
+ return 0;
+}
+
+#define KBDCHARDEF_MOD_NONE 0x00
+#define KBDCHARDEF_MOD_SHIFT 0x01
+
+typedef struct KBDCHARDEF
+{
+ uint8_t u8Scancode;
+ uint8_t u8Modifiers;
+} KBDCHARDEF;
+
+static const KBDCHARDEF g_aASCIIChars[0x80] =
+{
+ /* 0x00 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x01 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x02 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x03 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x04 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x05 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x06 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x07 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x08 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x09 ' ' */ {0x0f, KBDCHARDEF_MOD_NONE},
+ /* 0x0A ' ' */ {0x1c, KBDCHARDEF_MOD_NONE},
+ /* 0x0B ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x0C ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x0D ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x0E ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x0F ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x10 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x11 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x12 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x13 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x14 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x15 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x16 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x17 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x18 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x19 ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1A ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1B ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1C ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1D ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1E ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x1F ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+ /* 0x20 ' ' */ {0x39, KBDCHARDEF_MOD_NONE},
+ /* 0x21 '!' */ {0x02, KBDCHARDEF_MOD_SHIFT},
+ /* 0x22 '"' */ {0x28, KBDCHARDEF_MOD_SHIFT},
+ /* 0x23 '#' */ {0x04, KBDCHARDEF_MOD_SHIFT},
+ /* 0x24 '$' */ {0x05, KBDCHARDEF_MOD_SHIFT},
+ /* 0x25 '%' */ {0x06, KBDCHARDEF_MOD_SHIFT},
+ /* 0x26 '&' */ {0x08, KBDCHARDEF_MOD_SHIFT},
+ /* 0x27 ''' */ {0x28, KBDCHARDEF_MOD_NONE},
+ /* 0x28 '(' */ {0x0a, KBDCHARDEF_MOD_SHIFT},
+ /* 0x29 ')' */ {0x0b, KBDCHARDEF_MOD_SHIFT},
+ /* 0x2A '*' */ {0x09, KBDCHARDEF_MOD_SHIFT},
+ /* 0x2B '+' */ {0x0d, KBDCHARDEF_MOD_SHIFT},
+ /* 0x2C ',' */ {0x33, KBDCHARDEF_MOD_NONE},
+ /* 0x2D '-' */ {0x0c, KBDCHARDEF_MOD_NONE},
+ /* 0x2E '.' */ {0x34, KBDCHARDEF_MOD_NONE},
+ /* 0x2F '/' */ {0x35, KBDCHARDEF_MOD_NONE},
+ /* 0x30 '0' */ {0x0b, KBDCHARDEF_MOD_NONE},
+ /* 0x31 '1' */ {0x02, KBDCHARDEF_MOD_NONE},
+ /* 0x32 '2' */ {0x03, KBDCHARDEF_MOD_NONE},
+ /* 0x33 '3' */ {0x04, KBDCHARDEF_MOD_NONE},
+ /* 0x34 '4' */ {0x05, KBDCHARDEF_MOD_NONE},
+ /* 0x35 '5' */ {0x06, KBDCHARDEF_MOD_NONE},
+ /* 0x36 '6' */ {0x07, KBDCHARDEF_MOD_NONE},
+ /* 0x37 '7' */ {0x08, KBDCHARDEF_MOD_NONE},
+ /* 0x38 '8' */ {0x09, KBDCHARDEF_MOD_NONE},
+ /* 0x39 '9' */ {0x0a, KBDCHARDEF_MOD_NONE},
+ /* 0x3A ':' */ {0x27, KBDCHARDEF_MOD_SHIFT},
+ /* 0x3B ';' */ {0x27, KBDCHARDEF_MOD_NONE},
+ /* 0x3C '<' */ {0x33, KBDCHARDEF_MOD_SHIFT},
+ /* 0x3D '=' */ {0x0d, KBDCHARDEF_MOD_NONE},
+ /* 0x3E '>' */ {0x34, KBDCHARDEF_MOD_SHIFT},
+ /* 0x3F '?' */ {0x35, KBDCHARDEF_MOD_SHIFT},
+ /* 0x40 '@' */ {0x03, KBDCHARDEF_MOD_SHIFT},
+ /* 0x41 'A' */ {0x1e, KBDCHARDEF_MOD_SHIFT},
+ /* 0x42 'B' */ {0x30, KBDCHARDEF_MOD_SHIFT},
+ /* 0x43 'C' */ {0x2e, KBDCHARDEF_MOD_SHIFT},
+ /* 0x44 'D' */ {0x20, KBDCHARDEF_MOD_SHIFT},
+ /* 0x45 'E' */ {0x12, KBDCHARDEF_MOD_SHIFT},
+ /* 0x46 'F' */ {0x21, KBDCHARDEF_MOD_SHIFT},
+ /* 0x47 'G' */ {0x22, KBDCHARDEF_MOD_SHIFT},
+ /* 0x48 'H' */ {0x23, KBDCHARDEF_MOD_SHIFT},
+ /* 0x49 'I' */ {0x17, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4A 'J' */ {0x24, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4B 'K' */ {0x25, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4C 'L' */ {0x26, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4D 'M' */ {0x32, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4E 'N' */ {0x31, KBDCHARDEF_MOD_SHIFT},
+ /* 0x4F 'O' */ {0x18, KBDCHARDEF_MOD_SHIFT},
+ /* 0x50 'P' */ {0x19, KBDCHARDEF_MOD_SHIFT},
+ /* 0x51 'Q' */ {0x10, KBDCHARDEF_MOD_SHIFT},
+ /* 0x52 'R' */ {0x13, KBDCHARDEF_MOD_SHIFT},
+ /* 0x53 'S' */ {0x1f, KBDCHARDEF_MOD_SHIFT},
+ /* 0x54 'T' */ {0x14, KBDCHARDEF_MOD_SHIFT},
+ /* 0x55 'U' */ {0x16, KBDCHARDEF_MOD_SHIFT},
+ /* 0x56 'V' */ {0x2f, KBDCHARDEF_MOD_SHIFT},
+ /* 0x57 'W' */ {0x11, KBDCHARDEF_MOD_SHIFT},
+ /* 0x58 'X' */ {0x2d, KBDCHARDEF_MOD_SHIFT},
+ /* 0x59 'Y' */ {0x15, KBDCHARDEF_MOD_SHIFT},
+ /* 0x5A 'Z' */ {0x2c, KBDCHARDEF_MOD_SHIFT},
+ /* 0x5B '[' */ {0x1a, KBDCHARDEF_MOD_NONE},
+ /* 0x5C '\' */ {0x2b, KBDCHARDEF_MOD_NONE},
+ /* 0x5D ']' */ {0x1b, KBDCHARDEF_MOD_NONE},
+ /* 0x5E '^' */ {0x07, KBDCHARDEF_MOD_SHIFT},
+ /* 0x5F '_' */ {0x0c, KBDCHARDEF_MOD_SHIFT},
+ /* 0x60 '`' */ {0x28, KBDCHARDEF_MOD_NONE},
+ /* 0x61 'a' */ {0x1e, KBDCHARDEF_MOD_NONE},
+ /* 0x62 'b' */ {0x30, KBDCHARDEF_MOD_NONE},
+ /* 0x63 'c' */ {0x2e, KBDCHARDEF_MOD_NONE},
+ /* 0x64 'd' */ {0x20, KBDCHARDEF_MOD_NONE},
+ /* 0x65 'e' */ {0x12, KBDCHARDEF_MOD_NONE},
+ /* 0x66 'f' */ {0x21, KBDCHARDEF_MOD_NONE},
+ /* 0x67 'g' */ {0x22, KBDCHARDEF_MOD_NONE},
+ /* 0x68 'h' */ {0x23, KBDCHARDEF_MOD_NONE},
+ /* 0x69 'i' */ {0x17, KBDCHARDEF_MOD_NONE},
+ /* 0x6A 'j' */ {0x24, KBDCHARDEF_MOD_NONE},
+ /* 0x6B 'k' */ {0x25, KBDCHARDEF_MOD_NONE},
+ /* 0x6C 'l' */ {0x26, KBDCHARDEF_MOD_NONE},
+ /* 0x6D 'm' */ {0x32, KBDCHARDEF_MOD_NONE},
+ /* 0x6E 'n' */ {0x31, KBDCHARDEF_MOD_NONE},
+ /* 0x6F 'o' */ {0x18, KBDCHARDEF_MOD_NONE},
+ /* 0x70 'p' */ {0x19, KBDCHARDEF_MOD_NONE},
+ /* 0x71 'q' */ {0x10, KBDCHARDEF_MOD_NONE},
+ /* 0x72 'r' */ {0x13, KBDCHARDEF_MOD_NONE},
+ /* 0x73 's' */ {0x1f, KBDCHARDEF_MOD_NONE},
+ /* 0x74 't' */ {0x14, KBDCHARDEF_MOD_NONE},
+ /* 0x75 'u' */ {0x16, KBDCHARDEF_MOD_NONE},
+ /* 0x76 'v' */ {0x2f, KBDCHARDEF_MOD_NONE},
+ /* 0x77 'w' */ {0x11, KBDCHARDEF_MOD_NONE},
+ /* 0x78 'x' */ {0x2d, KBDCHARDEF_MOD_NONE},
+ /* 0x79 'y' */ {0x15, KBDCHARDEF_MOD_NONE},
+ /* 0x7A 'z' */ {0x2c, KBDCHARDEF_MOD_NONE},
+ /* 0x7B '{' */ {0x1a, KBDCHARDEF_MOD_SHIFT},
+ /* 0x7C '|' */ {0x2b, KBDCHARDEF_MOD_SHIFT},
+ /* 0x7D '}' */ {0x1b, KBDCHARDEF_MOD_SHIFT},
+ /* 0x7E '~' */ {0x29, KBDCHARDEF_MOD_SHIFT},
+ /* 0x7F ' ' */ {0x00, KBDCHARDEF_MOD_NONE},
+};
+
+static HRESULT keyboardPutScancodes(IKeyboard *pKeyboard, const std::list<LONG> &llScancodes)
+{
+ /* Send scancodes to the VM. */
+ com::SafeArray<LONG> saScancodes(llScancodes);
+
+ HRESULT hrc = S_OK;
+ size_t i;
+ for (i = 0; i < saScancodes.size(); ++i)
+ {
+ hrc = pKeyboard->PutScancode(saScancodes[i]);
+ if (FAILED(hrc))
+ {
+ RTMsgError(ControlVM::tr("Failed to send a scancode."));
+ break;
+ }
+
+ RTThreadSleep(10); /* "Typing" too fast causes lost characters. */
+ }
+
+ return hrc;
+}
+
+static void keyboardCharsToScancodes(const char *pch, size_t cchMax, std::list<LONG> &llScancodes, bool *pfShift)
+{
+ size_t cchProcessed = 0;
+ const char *p = pch;
+ while (cchProcessed < cchMax)
+ {
+ ++cchProcessed;
+ const uint8_t c = (uint8_t)*p++;
+ if (c < RT_ELEMENTS(g_aASCIIChars))
+ {
+ const KBDCHARDEF *d = &g_aASCIIChars[c];
+ if (d->u8Scancode)
+ {
+ const bool fNeedShift = RT_BOOL(d->u8Modifiers & KBDCHARDEF_MOD_SHIFT);
+ if (*pfShift != fNeedShift)
+ {
+ *pfShift = fNeedShift;
+ /* Press or release the SHIFT key. */
+ llScancodes.push_back(0x2a | (fNeedShift? 0x00: 0x80));
+ }
+
+ llScancodes.push_back(d->u8Scancode);
+ llScancodes.push_back(d->u8Scancode | 0x80);
+ }
+ }
+ }
+}
+
+static HRESULT keyboardPutString(IKeyboard *pKeyboard, int argc, char **argv)
+{
+ std::list<LONG> llScancodes;
+ bool fShift = false;
+
+ /* Convert command line string(s) to the en-us keyboard scancodes. */
+ int i;
+ for (i = 1 + 1; i < argc; ++i)
+ {
+ if (!llScancodes.empty())
+ {
+ /* Insert a SPACE before the next string. */
+ llScancodes.push_back(0x39);
+ llScancodes.push_back(0x39 | 0x80);
+ }
+
+ keyboardCharsToScancodes(argv[i], strlen(argv[i]), llScancodes, &fShift);
+ }
+
+ /* Release SHIFT if pressed. */
+ if (fShift)
+ llScancodes.push_back(0x2a | 0x80);
+
+ return keyboardPutScancodes(pKeyboard, llScancodes);
+}
+
+static HRESULT keyboardPutFile(IKeyboard *pKeyboard, const char *pszFilename)
+{
+ std::list<LONG> llScancodes;
+ bool fShift = false;
+
+ RTFILE File = NIL_RTFILE;
+ int vrc = RTFileOpen(&File, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_SUCCESS(vrc))
+ {
+ uint64_t cbFile = 0;
+ vrc = RTFileQuerySize(File, &cbFile);
+ if (RT_SUCCESS(vrc))
+ {
+ const uint64_t cbFileMax = _64K;
+ if (cbFile <= cbFileMax)
+ {
+ const size_t cbBuffer = _4K;
+ char *pchBuf = (char *)RTMemAlloc(cbBuffer);
+ if (pchBuf)
+ {
+ size_t cbRemaining = (size_t)cbFile;
+ while (cbRemaining > 0)
+ {
+ const size_t cbToRead = cbRemaining > cbBuffer ? cbBuffer : cbRemaining;
+
+ size_t cbRead = 0;
+ vrc = RTFileRead(File, pchBuf, cbToRead, &cbRead);
+ if (RT_FAILURE(vrc) || cbRead == 0)
+ break;
+
+ keyboardCharsToScancodes(pchBuf, cbRead, llScancodes, &fShift);
+ cbRemaining -= cbRead;
+ }
+
+ RTMemFree(pchBuf);
+ }
+ else
+ RTMsgError(ControlVM::tr("Out of memory allocating %d bytes.", "", cbBuffer), cbBuffer);
+ }
+ else
+ RTMsgError(ControlVM::tr("File size %RI64 is greater than %RI64: '%s'."), cbFile, cbFileMax, pszFilename);
+ }
+ else
+ RTMsgError(ControlVM::tr("Cannot get size of file '%s': %Rrc."), pszFilename, vrc);
+
+ RTFileClose(File);
+ }
+ else
+ RTMsgError(ControlVM::tr("Cannot open file '%s': %Rrc."), pszFilename, vrc);
+
+ /* Release SHIFT if pressed. */
+ if (fShift)
+ llScancodes.push_back(0x2a | 0x80);
+
+ return keyboardPutScancodes(pKeyboard, llScancodes);
+}
+
+
+RTEXITCODE handleControlVM(HandlerArg *a)
+{
+ using namespace com;
+ bool fNeedsSaving = false;
+ HRESULT hrc;
+
+ if (a->argc < 2)
+ return errorSyntax(ControlVM::tr("Not enough parameters."));
+
+ /* try to find the given machine */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ /* open a session for the VM */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ ComPtr<IConsole> console;
+ ComPtr<IMachine> sessionMachine;
+
+ do
+ {
+ /* get the associated console */
+ CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
+ if (!console)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, ControlVM::tr("Machine '%s' is not currently running."), a->argv[0]);
+
+ /* ... and session machine */
+ CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+
+ /* which command? */
+ if (!strcmp(a->argv[1], "pause"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_PAUSE);
+ CHECK_ERROR_BREAK(console, Pause());
+ }
+ else if (!strcmp(a->argv[1], "resume"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RESUME);
+ CHECK_ERROR_BREAK(console, Resume());
+ }
+ else if (!strcmp(a->argv[1], "reset"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RESET);
+ CHECK_ERROR_BREAK(console, Reset());
+ }
+ else if (!strcmp(a->argv[1], "unplugcpu"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_UNPLUGCPU);
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ unsigned n = parseNum(a->argv[2], 32, "CPU");
+
+ CHECK_ERROR_BREAK(sessionMachine, HotUnplugCPU(n));
+ }
+ else if (!strcmp(a->argv[1], "plugcpu"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_PLUGCPU);
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ unsigned n = parseNum(a->argv[2], 32, "CPU");
+
+ CHECK_ERROR_BREAK(sessionMachine, HotPlugCPU(n));
+ }
+ else if (!strcmp(a->argv[1], "cpuexecutioncap"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_CPUEXECUTIONCAP);
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ unsigned n = parseNum(a->argv[2], 100, "ExecutionCap");
+
+ CHECK_ERROR_BREAK(sessionMachine, COMSETTER(CPUExecutionCap)(n));
+ }
+ else if (!strcmp(a->argv[1], "audioin"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_AUDIOIN);
+
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> adapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(adapter.asOutParam()));
+ if (adapter)
+ {
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid value '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(EnabledIn)(fEnabled), RTEXITCODE_FAILURE);
+ fNeedsSaving = true;
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Audio adapter not enabled in VM configuration."));
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ else if (!strcmp(a->argv[1], "audioout"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_AUDIOOUT);
+
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> adapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(adapter.asOutParam()));
+ if (adapter)
+ {
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid value '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(EnabledOut)(fEnabled), RTEXITCODE_FAILURE);
+ fNeedsSaving = true;
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Audio adapter not enabled in VM configuration."));
+ hrc = E_FAIL;
+ break;
+ }
+ }
+#ifdef VBOX_WITH_SHARED_CLIPBOARD
+ else if (!strcmp(a->argv[1], "clipboard"))
+ {
+ if (a->argc <= 1 + 1)
+ {
+ errorArgument(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ ClipboardMode_T mode = ClipboardMode_Disabled; /* Shut up MSC */
+ if (!strcmp(a->argv[2], "mode"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_CLIPBOARD_MODE);
+ if (a->argc <= 1 + 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s %s'."), a->argv[1], a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (!strcmp(a->argv[3], "disabled"))
+ mode = ClipboardMode_Disabled;
+ else if (!strcmp(a->argv[3], "hosttoguest"))
+ mode = ClipboardMode_HostToGuest;
+ else if (!strcmp(a->argv[3], "guesttohost"))
+ mode = ClipboardMode_GuestToHost;
+ else if (!strcmp(a->argv[3], "bidirectional"))
+ mode = ClipboardMode_Bidirectional;
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid '%s %s' argument '%s'."), a->argv[1], a->argv[2], a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ CHECK_ERROR_BREAK(sessionMachine, COMSETTER(ClipboardMode)(mode));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+ else if (!strcmp(a->argv[2], "filetransfers"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_CLIPBOARD_FILETRANSFERS);
+ if (a->argc <= 1 + 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s %s'."), a->argv[1], a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[3], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid '%s %s' argument '%s'."), a->argv[1], a->argv[2], a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ CHECK_ERROR_BREAK(sessionMachine, COMSETTER(ClipboardFileTransfersEnabled)(fEnabled));
+ fNeedsSaving = true;
+ }
+# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
+ else
+ {
+ errorArgument(ControlVM::tr("Invalid '%s' argument '%s'."), a->argv[1], a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+#endif /* VBOX_WITH_SHARED_CLIPBOARD */
+ else if (!strcmp(a->argv[1], "draganddrop"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_DRAGANDDROP);
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ DnDMode_T mode = DnDMode_Disabled; /* Shup up MSC. */
+ if (!strcmp(a->argv[2], "disabled"))
+ mode = DnDMode_Disabled;
+ else if (!strcmp(a->argv[2], "hosttoguest"))
+ mode = DnDMode_HostToGuest;
+ else if (!strcmp(a->argv[2], "guesttohost"))
+ mode = DnDMode_GuestToHost;
+ else if (!strcmp(a->argv[2], "bidirectional"))
+ mode = DnDMode_Bidirectional;
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid '%s' argument '%s'."), a->argv[1], a->argv[2]);
+ hrc = E_FAIL;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR_BREAK(sessionMachine, COMSETTER(DnDMode)(mode));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ }
+ else if (!strcmp(a->argv[1], "poweroff"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_POWEROFF);
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_BREAK(console, PowerDown(progress.asOutParam()));
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR(progress, (ControlVM::tr("Failed to power off machine.")));
+ }
+ else if (!strcmp(a->argv[1], "savestate"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SAVESTATE);
+ /* first pause so we don't trigger a live save which needs more time/resources */
+ bool fPaused = false;
+ hrc = console->Pause();
+ if (FAILED(hrc))
+ {
+ bool fError = true;
+ if (hrc == VBOX_E_INVALID_VM_STATE)
+ {
+ /* check if we are already paused */
+ MachineState_T machineState;
+ CHECK_ERROR_BREAK(console, COMGETTER(State)(&machineState));
+ /* the error code was lost by the previous instruction */
+ hrc = VBOX_E_INVALID_VM_STATE;
+ if (machineState != MachineState_Paused)
+ {
+ RTMsgError(ControlVM::tr("Machine in invalid state %d -- %s."),
+ machineState, machineStateToName(machineState, false));
+ }
+ else
+ {
+ fError = false;
+ fPaused = true;
+ }
+ }
+ if (fError)
+ break;
+ }
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(sessionMachine, SaveState(progress.asOutParam()));
+ if (FAILED(hrc))
+ {
+ if (!fPaused)
+ console->Resume();
+ break;
+ }
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR(progress, (ControlVM::tr("Failed to save machine state.")));
+ if (FAILED(hrc))
+ {
+ if (!fPaused)
+ console->Resume();
+ }
+ }
+ else if (!strcmp(a->argv[1], "acpipowerbutton"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_ACPIPOWERBUTTON);
+ CHECK_ERROR_BREAK(console, PowerButton());
+ }
+ else if (!strcmp(a->argv[1], "acpisleepbutton"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_ACPISLEEPBUTTON);
+ CHECK_ERROR_BREAK(console, SleepButton());
+ }
+#ifdef VBOX_WITH_GUEST_CONTROL
+ else if ( !strcmp(a->argv[1], "reboot")
+ || !strcmp(a->argv[1], "shutdown")) /* With shutdown we mean gracefully powering off the VM by letting the guest OS do its thing. */
+ {
+ const bool fReboot = !strcmp(a->argv[1], "reboot");
+ if (fReboot)
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_REBOOT);
+ else
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SHUTDOWN);
+
+ ComPtr<IGuest> pGuest;
+ CHECK_ERROR_BREAK(console, COMGETTER(Guest)(pGuest.asOutParam()));
+ if (!pGuest)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ com::SafeArray<GuestShutdownFlag_T> aShutdownFlags;
+ if (fReboot)
+ aShutdownFlags.push_back(GuestShutdownFlag_Reboot);
+ else
+ aShutdownFlags.push_back(GuestShutdownFlag_PowerOff);
+
+ if ( a->argc >= 3
+ && !strcmp(a->argv[2], "--force"))
+ aShutdownFlags.push_back(GuestShutdownFlag_Force);
+
+ CHECK_ERROR(pGuest, Shutdown(ComSafeArrayAsInParam(aShutdownFlags)));
+ if (FAILED(hrc))
+ {
+ if (hrc == VBOX_E_NOT_SUPPORTED)
+ {
+ if (fReboot)
+ RTMsgError(ControlVM::tr("Current installed Guest Additions don't support rebooting the guest."));
+ else
+ RTMsgError(ControlVM::tr("Current installed Guest Additions don't support shutting down the guest."));
+ }
+ }
+ }
+#endif
+ else if (!strcmp(a->argv[1], "keyboardputscancode"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_KEYBOARDPUTSCANCODE);
+ ComPtr<IKeyboard> pKeyboard;
+ CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(pKeyboard.asOutParam()));
+ if (!pKeyboard)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'. Expected IBM PC AT set 2 keyboard scancode(s)."),
+ a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ std::list<LONG> llScancodes;
+
+ /* Process the command line. */
+ int i;
+ for (i = 1 + 1; i < a->argc; i++)
+ {
+ if ( RT_C_IS_XDIGIT (a->argv[i][0])
+ && RT_C_IS_XDIGIT (a->argv[i][1])
+ && a->argv[i][2] == 0)
+ {
+ uint8_t u8Scancode;
+ int vrc = RTStrToUInt8Ex(a->argv[i], NULL, 16, &u8Scancode);
+ if (RT_FAILURE (vrc))
+ {
+ RTMsgError(ControlVM::tr("Converting '%s' returned %Rrc!"), a->argv[i], vrc);
+ hrc = E_FAIL;
+ break;
+ }
+
+ llScancodes.push_back(u8Scancode);
+ }
+ else
+ {
+ RTMsgError(ControlVM::tr("'%s' is not a hex byte!"), a->argv[i]);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+
+ if (FAILED(hrc))
+ break;
+
+ hrc = keyboardPutScancodes(pKeyboard, llScancodes);
+ }
+ else if (!strcmp(a->argv[1], "keyboardputstring"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_KEYBOARDPUTSTRING);
+ ComPtr<IKeyboard> pKeyboard;
+ CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(pKeyboard.asOutParam()));
+ if (!pKeyboard)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'. Expected ASCII string(s)."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ hrc = keyboardPutString(pKeyboard, a->argc, a->argv);
+ }
+ else if (!strcmp(a->argv[1], "keyboardputfile"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_KEYBOARDPUTFILE);
+ ComPtr<IKeyboard> pKeyboard;
+ CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(pKeyboard.asOutParam()));
+ if (!pKeyboard)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ hrc = keyboardPutFile(pKeyboard, a->argv[2]);
+ }
+ else if (!strncmp(a->argv[1], "setlinkstate", 12))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SETLINKSTATE);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][12], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid link state '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_BREAK(adapter, COMSETTER(CableConnected)(fEnabled));
+ fNeedsSaving = true;
+ }
+ }
+ /* here the order in which strncmp is called is important
+ * cause nictracefile can be very well compared with
+ * nictrace and nic and thus everything will always fail
+ * if the order is changed
+ */
+ else if (!strncmp(a->argv[1], "nictracefile", 12))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NICTRACEFILE);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][12], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ if (a->argv[2])
+ {
+ CHECK_ERROR_RET(adapter, COMSETTER(TraceFile)(Bstr(a->argv[2]).raw()), RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Filename not specified for NIC %lu."), n);
+ hrc = E_FAIL;
+ break;
+ }
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else
+ RTMsgError(ControlVM::tr("The NIC %d is currently disabled and thus its tracefile can't be changed."), n);
+ }
+ }
+ else if (!strncmp(a->argv[1], "nictrace", 8))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NICTRACE);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][8], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ bool fTraceEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fTraceEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid nictrace%lu argument '%s'."), n, a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(TraceEnabled)(fTraceEnabled), RTEXITCODE_FAILURE);
+ fNeedsSaving = true;
+ }
+ else
+ RTMsgError(ControlVM::tr("The NIC %d is currently disabled and thus its trace flag can't be changed."), n);
+ }
+ }
+ else if( a->argc > 2
+ && !strncmp(a->argv[1], "natpf", 5))
+ {
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][5], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorArgument(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (!adapter)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(adapter, COMGETTER(NATEngine)(engine.asOutParam()));
+ if (!engine)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (!strcmp(a->argv[2], "delete"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NATPF_DELETE);
+ if (a->argc >= 3)
+ CHECK_ERROR(engine, RemoveRedirect(Bstr(a->argv[3]).raw()));
+ }
+ else
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NATPF);
+#define ITERATE_TO_NEXT_TERM(ch) \
+ do { \
+ while (*ch != ',') \
+ { \
+ if (*ch == 0) \
+ { \
+ return errorSyntax(ControlVM::tr("Missing or invalid argument to '%s'."), \
+ a->argv[1]); \
+ } \
+ ch++; \
+ } \
+ *ch = '\0'; \
+ ch++; \
+ } while(0)
+
+ char *strName;
+ char *strProto;
+ char *strHostIp;
+ char *strHostPort;
+ char *strGuestIp;
+ char *strGuestPort;
+ char *strRaw = RTStrDup(a->argv[2]);
+ char *ch = strRaw;
+ strName = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strProto = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strHostIp = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strHostPort = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strGuestIp = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strGuestPort = RTStrStrip(ch);
+ NATProtocol_T proto;
+ if (RTStrICmp(strProto, "udp") == 0)
+ proto = NATProtocol_UDP;
+ else if (RTStrICmp(strProto, "tcp") == 0)
+ proto = NATProtocol_TCP;
+ else
+ {
+ return errorSyntax(ControlVM::tr("Wrong rule proto '%s' specified -- only 'udp' and 'tcp' are allowed."),
+ strProto);
+ }
+ CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto, Bstr(strHostIp).raw(),
+ RTStrToUInt16(strHostPort), Bstr(strGuestIp).raw(), RTStrToUInt16(strGuestPort)));
+#undef ITERATE_TO_NEXT_TERM
+ }
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else if (!strncmp(a->argv[1], "nicproperty", 11))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NICPROPERTY);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][11], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(a->argv[2]);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(adapter, SetProperty(bstrName.raw(), bstrValue.raw()));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid nicproperty%d argument '%s'."), n, a->argv[2]);
+ hrc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTMsgError(ControlVM::tr("Failed to allocate memory for nicproperty%d '%s'."),
+ n, a->argv[2]);
+ hrc = E_FAIL;
+ }
+ if (FAILED(hrc))
+ break;
+ }
+ else
+ RTMsgError(ControlVM::tr("The NIC %d is currently disabled and thus its properties can't be changed."), n);
+ }
+ }
+ else if (!strncmp(a->argv[1], "nicpromisc", 10))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NICPROMISC);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][10], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ if (!strcmp(a->argv[2], "deny"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
+ else if ( !strcmp(a->argv[2], "allow-vms")
+ || !strcmp(a->argv[2], "allow-network"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
+ else if (!strcmp(a->argv[2], "allow-all"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
+ else
+ {
+ errorSyntax(ControlVM::tr("Unknown promiscuous mode policy '%s'."), a->argv[2]);
+ hrc = E_INVALIDARG;
+ break;
+ }
+
+ CHECK_ERROR(adapter, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else
+ RTMsgError(ControlVM::tr("The NIC %d is currently disabled and thus its promiscuous mode can't be changed."), n);
+ }
+ }
+ else if (!strncmp(a->argv[1], "nic", 3))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_NIC);
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, sessionMachine);
+ unsigned n = parseNum(&a->argv[1][3], NetworkAdapterCount, "NIC");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc <= 2)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* get the corresponding network adapter */
+ ComPtr<INetworkAdapter> adapter;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
+ if (adapter)
+ {
+ BOOL fEnabled;
+ adapter->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ if (!strcmp(a->argv[2], "null"))
+ {
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Null), RTEXITCODE_FAILURE);
+ }
+ else if (!strcmp(a->argv[2], "nat"))
+ {
+ if (a->argc == 4)
+ CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT), RTEXITCODE_FAILURE);
+ }
+ else if ( !strcmp(a->argv[2], "bridged")
+ || !strcmp(a->argv[2], "hostif")) /* backward compatibility */
+ {
+ if (a->argc <= 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(BridgedInterface)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ verifyHostNetworkInterfaceName(a->virtualBox, a->argv[3], HostNetworkInterfaceType_Bridged);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged), RTEXITCODE_FAILURE);
+ }
+ else if (!strcmp(a->argv[2], "intnet"))
+ {
+ if (a->argc <= 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(InternalNetwork)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal), RTEXITCODE_FAILURE);
+ }
+#if defined(VBOX_WITH_NETFLT)
+ else if (!strcmp(a->argv[2], "hostonly"))
+ {
+ if (a->argc <= 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(HostOnlyInterface)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ verifyHostNetworkInterfaceName(a->virtualBox, a->argv[3], HostNetworkInterfaceType_HostOnly);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly), RTEXITCODE_FAILURE);
+ }
+#endif
+ else if (!strcmp(a->argv[2], "generic"))
+ {
+ if (a->argc <= 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(GenericDriver)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic), RTEXITCODE_FAILURE);
+ }
+ else if (!strcmp(a->argv[2], "natnetwork"))
+ {
+ if (a->argc <= 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_RET(adapter, COMSETTER(NATNetwork)(Bstr(a->argv[3]).raw()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(adapter, COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork), RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid type '%s' specfied for NIC %lu."), a->argv[2], n);
+ hrc = E_FAIL;
+ break;
+ }
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else
+ RTMsgError(ControlVM::tr("The NIC %d is currently disabled and thus its attachment type can't be changed."), n);
+ }
+ }
+ else if ( !strcmp(a->argv[1], "vrde")
+ || !strcmp(a->argv[1], "vrdp"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_VRDE);
+ if (!strcmp(a->argv[1], "vrdp"))
+ RTMsgWarning(ControlVM::tr("'vrdp' is deprecated. Use 'vrde'."));
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+ if (vrdeServer)
+ {
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid remote desktop server state '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_BREAK(vrdeServer, COMSETTER(Enabled)(fEnabled));
+ fNeedsSaving = true;
+ }
+ }
+ else if ( !strcmp(a->argv[1], "vrdeport")
+ || !strcmp(a->argv[1], "vrdpport"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_VRDEPORT);
+ if (!strcmp(a->argv[1], "vrdpport"))
+ RTMsgWarning(ControlVM::tr("'vrdpport' is deprecated. Use 'vrdeport'."));
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+ if (vrdeServer)
+ {
+ Bstr ports;
+
+ if (!strcmp(a->argv[2], "default"))
+ ports = "0";
+ else
+ ports = a->argv[2];
+
+ CHECK_ERROR_BREAK(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), ports.raw()));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ }
+ else if ( !strcmp(a->argv[1], "vrdevideochannelquality")
+ || !strcmp(a->argv[1], "vrdpvideochannelquality"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_VRDEVIDEOCHANNELQUALITY);
+ if (!strcmp(a->argv[1], "vrdpvideochannelquality"))
+ RTMsgWarning(ControlVM::tr("'vrdpvideochannelquality' is deprecated. Use 'vrdevideochannelquality'."));
+
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+ if (vrdeServer)
+ {
+ Bstr value = a->argv[2];
+
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Quality").raw(), value.raw()));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ }
+ else if (!strcmp(a->argv[1], "vrdeproperty"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_VRDEPROPERTY);
+ if (a->argc <= 1 + 1)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+ if (vrdeServer)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(a->argv[2]);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(bstrName.raw(), bstrValue.raw()));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid vrdeproperty argument '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTMsgError(ControlVM::tr("Failed to allocate memory for VRDE property '%s'."),
+ a->argv[2]);
+ hrc = E_FAIL;
+ }
+ }
+ if (FAILED(hrc))
+ {
+ break;
+ }
+ }
+ else if ( !strcmp(a->argv[1], "usbattach")
+ || !strcmp(a->argv[1], "usbdetach"))
+ {
+ bool attach = !strcmp(a->argv[1], "usbattach");
+ if (attach)
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_USBATTACH);
+ else
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_USBDETACH);
+
+ if (a->argc < 3)
+ {
+ errorSyntax(ControlVM::tr("Not enough parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ else if (a->argc == 4 || a->argc > 5)
+ {
+ errorSyntax(ControlVM::tr("Wrong number of arguments."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ Bstr usbId = a->argv[2];
+ Bstr captureFilename;
+
+ if (a->argc == 5)
+ {
+ if (!strcmp(a->argv[3], "--capturefile"))
+ captureFilename = a->argv[4];
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid parameter '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+
+ Guid guid(usbId);
+ if (!guid.isValid())
+ {
+ // assume address
+ if (attach)
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR_BREAK(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
+ SafeIfaceArray <IHostUSBDevice> coll;
+ CHECK_ERROR_BREAK(host, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)));
+ ComPtr<IHostUSBDevice> dev;
+ CHECK_ERROR_BREAK(host, FindUSBDeviceByAddress(Bstr(a->argv[2]).raw(),
+ dev.asOutParam()));
+ CHECK_ERROR_BREAK(dev, COMGETTER(Id)(usbId.asOutParam()));
+ }
+ else
+ {
+ SafeIfaceArray <IUSBDevice> coll;
+ CHECK_ERROR_BREAK(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)));
+ ComPtr<IUSBDevice> dev;
+ CHECK_ERROR_BREAK(console, FindUSBDeviceByAddress(Bstr(a->argv[2]).raw(),
+ dev.asOutParam()));
+ CHECK_ERROR_BREAK(dev, COMGETTER(Id)(usbId.asOutParam()));
+ }
+ }
+ else if (guid.isZero())
+ {
+ errorSyntax(ControlVM::tr("Zero UUID argument '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (attach)
+ CHECK_ERROR_BREAK(console, AttachUSBDevice(usbId.raw(), captureFilename.raw()));
+ else
+ {
+ ComPtr<IUSBDevice> dev;
+ CHECK_ERROR_BREAK(console, DetachUSBDevice(usbId.raw(),
+ dev.asOutParam()));
+ }
+ }
+ else if (!strcmp(a->argv[1], "setvideomodehint"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SETVIDEOMODEHINT);
+ if (a->argc != 5 && a->argc != 6 && a->argc != 7 && a->argc != 9)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ bool fEnabled = true;
+ uint32_t uXRes = RTStrToUInt32(a->argv[2]);
+ uint32_t uYRes = RTStrToUInt32(a->argv[3]);
+ uint32_t uBpp = RTStrToUInt32(a->argv[4]);
+ uint32_t uDisplayIdx = 0;
+ bool fChangeOrigin = false;
+ int32_t iOriginX = 0;
+ int32_t iOriginY = 0;
+ if (a->argc >= 6)
+ uDisplayIdx = RTStrToUInt32(a->argv[5]);
+ if (a->argc >= 7)
+ {
+ if (RT_FAILURE(parseBool(a->argv[6], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Either \"yes\" or \"no\" is expected."));
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ if (a->argc == 9)
+ {
+ iOriginX = RTStrToInt32(a->argv[7]);
+ iOriginY = RTStrToInt32(a->argv[8]);
+ fChangeOrigin = true;
+ }
+
+ ComPtr<IDisplay> pDisplay;
+ CHECK_ERROR_BREAK(console, COMGETTER(Display)(pDisplay.asOutParam()));
+ if (!pDisplay)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_BREAK(pDisplay, SetVideoModeHint(uDisplayIdx, fEnabled,
+ fChangeOrigin, iOriginX, iOriginY,
+ uXRes, uYRes, uBpp, true));
+ }
+ else if (!strcmp(a->argv[1], "setscreenlayout"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SETSCREENLAYOUT);
+ if (a->argc < 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<IDisplay> pDisplay;
+ CHECK_ERROR_BREAK(console, COMGETTER(Display)(pDisplay.asOutParam()));
+ if (!pDisplay)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ com::SafeIfaceArray<IGuestScreenInfo> aGuestScreenInfos;
+
+ /* Parse "<display> on|primary <xorigin> <yorigin> <xres> <yres> <bpp> | off" sequences. */
+ int argc = a->argc - 2;
+ char **argv = &a->argv[2];
+ while (argc >= 2)
+ {
+ ULONG aDisplay = RTStrToUInt32(argv[0]);
+ BOOL aPrimary = FALSE;
+
+ GuestMonitorStatus_T aStatus;
+ if (RTStrICmp(argv[1], "primary") == 0)
+ {
+ aStatus = GuestMonitorStatus_Enabled;
+ aPrimary = TRUE;
+ }
+ else if (RTStrICmp(argv[1], "on") == 0)
+ aStatus = GuestMonitorStatus_Enabled;
+ else if (RTStrICmp(argv[1], "off") == 0)
+ aStatus = GuestMonitorStatus_Disabled;
+ else
+ {
+ errorSyntax(ControlVM::tr("Display status must be <on> or <off>."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ BOOL aChangeOrigin = FALSE;
+ LONG aOriginX = 0;
+ LONG aOriginY = 0;
+ ULONG aWidth = 0;
+ ULONG aHeight = 0;
+ ULONG aBitsPerPixel = 0;
+ if (aStatus == GuestMonitorStatus_Enabled)
+ {
+ if (argc < 7)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ aChangeOrigin = TRUE;
+ aOriginX = RTStrToUInt32(argv[2]);
+ aOriginY = RTStrToUInt32(argv[3]);
+ aWidth = RTStrToUInt32(argv[4]);
+ aHeight = RTStrToUInt32(argv[5]);
+ aBitsPerPixel = RTStrToUInt32(argv[6]);
+
+ argc -= 7;
+ argv += 7;
+ }
+ else
+ {
+ argc -= 2;
+ argv += 2;
+ }
+
+ ComPtr<IGuestScreenInfo> pInfo;
+ CHECK_ERROR_BREAK(pDisplay, CreateGuestScreenInfo(aDisplay, aStatus, aPrimary, aChangeOrigin,
+ aOriginX, aOriginY, aWidth, aHeight, aBitsPerPixel,
+ pInfo.asOutParam()));
+ aGuestScreenInfos.push_back(pInfo);
+ }
+
+ if (FAILED(hrc))
+ break;
+
+ CHECK_ERROR_BREAK(pDisplay, SetScreenLayout(ScreenLayoutMode_Apply, ComSafeArrayAsInParam(aGuestScreenInfos)));
+ }
+ else if (!strcmp(a->argv[1], "setcredentials"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SETCREDENTIALS);
+ bool fAllowLocalLogon = true;
+ if ( a->argc == 7
+ || ( a->argc == 8
+ && ( !strcmp(a->argv[3], "-p")
+ || !strcmp(a->argv[3], "--passwordfile"))))
+ {
+ if ( strcmp(a->argv[5 + (a->argc - 7)], "--allowlocallogon")
+ && strcmp(a->argv[5 + (a->argc - 7)], "-allowlocallogon"))
+ {
+ errorSyntax(ControlVM::tr("Invalid parameter '%s'."), a->argv[5]);
+ hrc = E_FAIL;
+ break;
+ }
+ if (!strcmp(a->argv[6 + (a->argc - 7)], "no"))
+ fAllowLocalLogon = false;
+ }
+ else if ( a->argc != 5
+ && ( a->argc != 6
+ || ( strcmp(a->argv[3], "-p")
+ && strcmp(a->argv[3], "--passwordfile"))))
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ Utf8Str passwd, domain;
+ if (a->argc == 5 || a->argc == 7)
+ {
+ passwd = a->argv[3];
+ domain = a->argv[4];
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(a->argv[4], &passwd);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ domain = a->argv[5];
+ }
+
+ ComPtr<IGuest> pGuest;
+ CHECK_ERROR_BREAK(console, COMGETTER(Guest)(pGuest.asOutParam()));
+ if (!pGuest)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR_BREAK(pGuest, SetCredentials(Bstr(a->argv[2]).raw(),
+ Bstr(passwd).raw(),
+ Bstr(domain).raw(),
+ fAllowLocalLogon));
+ }
+ else if (!strcmp(a->argv[1], "guestmemoryballoon"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_GUESTMEMORYBALLOON);
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ uint32_t uVal;
+ int vrc;
+ vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
+ if (vrc != VINF_SUCCESS)
+ {
+ errorSyntax(ControlVM::tr("Error parsing guest memory balloon size '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ /* guest is running; update IGuest */
+ ComPtr<IGuest> pGuest;
+ hrc = console->COMGETTER(Guest)(pGuest.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ if (!pGuest)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(pGuest, COMSETTER(MemoryBalloonSize)(uVal));
+ }
+ }
+ else if (!strcmp(a->argv[1], "teleport"))
+ {
+ Bstr bstrHostname;
+ uint32_t uMaxDowntime = 250 /*ms*/;
+ uint32_t uPort = UINT32_MAX;
+ uint32_t cMsTimeout = 0;
+ Utf8Str strPassword;
+ static const RTGETOPTDEF s_aTeleportOptions[] =
+ {
+ { "--host", 'h', RTGETOPT_REQ_STRING }, /** @todo RTGETOPT_FLAG_MANDATORY */
+ { "--maxdowntime", 'd', RTGETOPT_REQ_UINT32 },
+ { "--port", 'P', RTGETOPT_REQ_UINT32 }, /** @todo RTGETOPT_FLAG_MANDATORY */
+ { "--passwordfile", 'p', RTGETOPT_REQ_STRING },
+ { "--password", 'W', RTGETOPT_REQ_STRING },
+ { "--timeout", 't', RTGETOPT_REQ_UINT32 },
+ { "--detailed-progress", 'D', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetOptState;
+ RTGetOptInit(&GetOptState, a->argc, a->argv, s_aTeleportOptions, RT_ELEMENTS(s_aTeleportOptions), 2, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_TELEPORT);
+ int ch;
+ RTGETOPTUNION Value;
+ while ( SUCCEEDED(hrc)
+ && (ch = RTGetOpt(&GetOptState, &Value)))
+ {
+ switch (ch)
+ {
+ case 'h': bstrHostname = Value.psz; break;
+ case 'd': uMaxDowntime = Value.u32; break;
+ case 'D': g_fDetailedProgress = true; break;
+ case 'P': uPort = Value.u32; break;
+ case 'p':
+ {
+ RTEXITCODE rcExit = readPasswordFile(Value.psz, &strPassword);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ hrc = E_FAIL;
+ break;
+ }
+ case 'W': strPassword = Value.psz; break;
+ case 't': cMsTimeout = Value.u32; break;
+ default:
+ errorGetOpt(ch, &Value);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ if (FAILED(hrc))
+ break;
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_BREAK(console, Teleport(bstrHostname.raw(), uPort,
+ Bstr(strPassword).raw(),
+ uMaxDowntime,
+ progress.asOutParam()));
+
+ if (cMsTimeout)
+ {
+ hrc = progress->COMSETTER(Timeout)(cMsTimeout);
+ if (FAILED(hrc) && hrc != VBOX_E_INVALID_OBJECT_STATE)
+ CHECK_ERROR_BREAK(progress, COMSETTER(Timeout)(cMsTimeout)); /* lazyness */
+ }
+
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR(progress, (ControlVM::tr("Teleportation failed")));
+ }
+ else if (!strcmp(a->argv[1], "screenshotpng"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_SCREENSHOTPNG);
+ if (a->argc <= 2 || a->argc > 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ int vrc;
+ uint32_t iScreen = 0;
+ if (a->argc == 4)
+ {
+ vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &iScreen);
+ if (vrc != VINF_SUCCESS)
+ {
+ errorSyntax(ControlVM::tr("Error parsing display number '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ ComPtr<IDisplay> pDisplay;
+ CHECK_ERROR_BREAK(console, COMGETTER(Display)(pDisplay.asOutParam()));
+ if (!pDisplay)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+ ULONG width, height, bpp;
+ LONG xOrigin, yOrigin;
+ GuestMonitorStatus_T monitorStatus;
+ CHECK_ERROR_BREAK(pDisplay, GetScreenResolution(iScreen, &width, &height, &bpp, &xOrigin, &yOrigin, &monitorStatus));
+ com::SafeArray<BYTE> saScreenshot;
+ CHECK_ERROR_BREAK(pDisplay, TakeScreenShotToArray(iScreen, width, height, BitmapFormat_PNG, ComSafeArrayAsOutParam(saScreenshot)));
+ RTFILE pngFile = NIL_RTFILE;
+ vrc = RTFileOpen(&pngFile, a->argv[2], RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_TRUNCATE | RTFILE_O_DENY_ALL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(ControlVM::tr("Failed to create file '%s' (%Rrc)."), a->argv[2], vrc);
+ hrc = E_FAIL;
+ break;
+ }
+ vrc = RTFileWrite(pngFile, saScreenshot.raw(), saScreenshot.size(), NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(ControlVM::tr("Failed to write screenshot to file '%s' (%Rrc)."), a->argv[2], vrc);
+ hrc = E_FAIL;
+ }
+ RTFileClose(pngFile);
+ }
+#ifdef VBOX_WITH_RECORDING
+ else if ( !strcmp(a->argv[1], "recording")
+ || !strcmp(a->argv[1], "videocap") /* legacy command */)
+ {
+ if (a->argc < 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<IRecordingSettings> recordingSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()));
+
+ SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
+ CHECK_ERROR_BREAK(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)));
+
+ ComPtr<IGraphicsAdapter> pGraphicsAdapter;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam()));
+
+ /* Note: For now all screens have the same configuration. */
+
+ /*
+ * Note: Commands starting with "vcp" are the deprecated versions and are
+ * kept to ensure backwards compatibility.
+ */
+ bool fEnabled;
+ if (RT_SUCCESS(parseBool(a->argv[2], &fEnabled)))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING);
+ CHECK_ERROR_RET(recordingSettings, COMSETTER(Enabled)(fEnabled), RTEXITCODE_FAILURE);
+ }
+ else if (!strcmp(a->argv[2], "screens"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_SCREENS);
+ ULONG cMonitors = 64;
+ CHECK_ERROR_BREAK(pGraphicsAdapter, COMGETTER(MonitorCount)(&cMonitors));
+ com::SafeArray<BOOL> saScreens(cMonitors);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+ if (RT_FAILURE(parseScreens(a->argv[3], &saScreens)))
+ {
+ errorSyntax(ControlVM::tr("Error parsing list of screen IDs '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Enabled)(saScreens[i]));
+ }
+ else if (!strcmp(a->argv[2], "filename"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_FILENAME);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Filename)(Bstr(a->argv[3]).raw()));
+ }
+ else if ( !strcmp(a->argv[2], "videores")
+ || !strcmp(a->argv[2], "videoresolution"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_VIDEORES);
+ if (a->argc != 5)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uWidth;
+ int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uWidth);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing video width '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uHeight;
+ vrc = RTStrToUInt32Ex(a->argv[4], NULL, 0, &uHeight);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing video height '%s'."), a->argv[4]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ {
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(uWidth));
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(uHeight));
+ }
+ }
+ else if (!strcmp(a->argv[2], "videorate"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_VIDEORATE);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uRate;
+ int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uRate);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing video rate '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(VideoRate)(uRate));
+ }
+ else if (!strcmp(a->argv[2], "videofps"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_VIDEOFPS);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uFPS;
+ int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uFPS);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing video FPS '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(VideoFPS)(uFPS));
+ }
+ else if (!strcmp(a->argv[2], "maxtime"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_MAXTIME);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uMaxTime;
+ int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uMaxTime);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing maximum time '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(MaxTime)(uMaxTime));
+ }
+ else if (!strcmp(a->argv[2], "maxfilesize"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_MAXFILESIZE);
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ uint32_t uMaxFileSize;
+ int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uMaxFileSize);
+ if (RT_FAILURE(vrc))
+ {
+ errorSyntax(ControlVM::tr("Error parsing maximum file size '%s'."), a->argv[3]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(MaxFileSize)(uMaxFileSize));
+ }
+ else if (!strcmp(a->argv[2], "opts"))
+ {
+#if 0 /* Add when the corresponding documentation is enabled. */
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_RECORDING_OPTS);
+#endif
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Options)(Bstr(a->argv[3]).raw()));
+ }
+ }
+#endif /* VBOX_WITH_RECORDING */
+ else if (!strcmp(a->argv[1], "webcam"))
+ {
+ if (a->argc < 3)
+ {
+ errorArgument(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<IEmulatedUSB> pEmulatedUSB;
+ CHECK_ERROR_BREAK(console, COMGETTER(EmulatedUSB)(pEmulatedUSB.asOutParam()));
+ if (!pEmulatedUSB)
+ {
+ RTMsgError(ControlVM::tr("Guest not running."));
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (!strcmp(a->argv[2], "attach"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_WEBCAM_ATTACH);
+ Bstr path("");
+ if (a->argc >= 4)
+ path = a->argv[3];
+ Bstr settings("");
+ if (a->argc >= 5)
+ settings = a->argv[4];
+ CHECK_ERROR_BREAK(pEmulatedUSB, WebcamAttach(path.raw(), settings.raw()));
+ }
+ else if (!strcmp(a->argv[2], "detach"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_WEBCAM_DETACH);
+ Bstr path("");
+ if (a->argc >= 4)
+ path = a->argv[3];
+ CHECK_ERROR_BREAK(pEmulatedUSB, WebcamDetach(path.raw()));
+ }
+ else if (!strcmp(a->argv[2], "list"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_WEBCAM_LIST);
+ com::SafeArray <BSTR> webcams;
+ CHECK_ERROR_BREAK(pEmulatedUSB, COMGETTER(Webcams)(ComSafeArrayAsOutParam(webcams)));
+ for (size_t i = 0; i < webcams.size(); ++i)
+ {
+ RTPrintf("%ls\n", webcams[i][0]? webcams[i]: Bstr("default").raw());
+ }
+ }
+ else
+ {
+ errorArgument(ControlVM::tr("Invalid argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ else if (!strcmp(a->argv[1], "addencpassword"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_ADDENCPASSWORD);
+ if ( a->argc != 4
+ && a->argc != 6)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ break;
+ }
+
+ BOOL fRemoveOnSuspend = FALSE;
+ if (a->argc == 6)
+ {
+ if ( strcmp(a->argv[4], "--removeonsuspend")
+ || ( strcmp(a->argv[5], "yes")
+ && strcmp(a->argv[5], "no")))
+ {
+ errorSyntax(ControlVM::tr("Invalid parameters."));
+ break;
+ }
+ if (!strcmp(a->argv[5], "yes"))
+ fRemoveOnSuspend = TRUE;
+ }
+
+ Bstr bstrPwId(a->argv[2]);
+ Utf8Str strPassword;
+
+ if (!RTStrCmp(a->argv[3], "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, ControlVM::tr("Enter password:"));
+ if (rcExit == RTEXITCODE_FAILURE)
+ break;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(a->argv[3], &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError(ControlVM::tr("Failed to read new password from file."));
+ break;
+ }
+ }
+
+ CHECK_ERROR_BREAK(console, AddEncryptionPassword(bstrPwId.raw(), Bstr(strPassword).raw(), fRemoveOnSuspend));
+ }
+ else if (!strcmp(a->argv[1], "removeencpassword"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_REMOVEENCPASSWORD);
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect number of parameters."));
+ break;
+ }
+ Bstr bstrPwId(a->argv[2]);
+ CHECK_ERROR_BREAK(console, RemoveEncryptionPassword(bstrPwId.raw()));
+ }
+ else if (!strcmp(a->argv[1], "removeallencpasswords"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_REMOVEALLENCPASSWORDS);
+ CHECK_ERROR_BREAK(console, ClearAllEncryptionPasswords());
+ }
+ else if (!strncmp(a->argv[1], "changeuartmode", 14))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_CHANGEUARTMODE);
+ unsigned n = parseNum(&a->argv[1][14], 4, "UART");
+ if (!n)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ if (a->argc < 3)
+ {
+ errorSyntax(ControlVM::tr("Missing argument to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<ISerialPort> uart;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(n - 1, uart.asOutParam()));
+ ASSERT(uart);
+
+ if (!RTStrICmp(a->argv[2], "disconnected"))
+ {
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
+ }
+ else if ( !RTStrICmp(a->argv[2], "server")
+ || !RTStrICmp(a->argv[2], "client")
+ || !RTStrICmp(a->argv[2], "tcpserver")
+ || !RTStrICmp(a->argv[2], "tcpclient")
+ || !RTStrICmp(a->argv[2], "file"))
+ {
+ const char *pszMode = a->argv[2];
+ if (a->argc != 4)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+
+ CHECK_ERROR(uart, COMSETTER(Path)(Bstr(a->argv[3]).raw()));
+
+ /*
+ * Change to disconnected first to get changes in just a parameter causing
+ * the correct changes later on.
+ */
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
+ if (!RTStrICmp(pszMode, "server"))
+ {
+ CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
+ }
+ else if (!RTStrICmp(pszMode, "client"))
+ {
+ CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
+ }
+ else if (!RTStrICmp(pszMode, "tcpserver"))
+ {
+ CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+ }
+ else if (!RTStrICmp(pszMode, "tcpclient"))
+ {
+ CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+ }
+ else if (!RTStrICmp(pszMode, "file"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile));
+ }
+ }
+ else
+ {
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(uart, COMSETTER(Path)(Bstr(a->argv[2]).raw()));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostDevice));
+ }
+ }
+ else if (!strncmp(a->argv[1], "vm-process-priority", 14))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_VM_PROCESS_PRIORITY);
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ VMProcPriority_T enmPriority = nameToVMProcPriority(a->argv[2]);
+ if (enmPriority == VMProcPriority_Invalid)
+ {
+ errorSyntax(ControlVM::tr("Invalid vm-process-priority '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(VMProcessPriority)(enmPriority));
+ }
+ break;
+ }
+ else if (!strncmp(a->argv[1], "autostart-enabled", 17))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_AUTOSTART_ENABLED);
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ bool fEnabled;
+ if (RT_FAILURE(parseBool(a->argv[2], &fEnabled)))
+ {
+ errorSyntax(ControlVM::tr("Invalid value '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(TRUE));
+ fNeedsSaving = true;
+ break;
+ }
+ else if (!strncmp(a->argv[1], "autostart-delay", 15))
+ {
+ setCurrentSubcommand(HELP_SCOPE_CONTROLVM_AUTOSTART_DELAY);
+ if (a->argc != 3)
+ {
+ errorSyntax(ControlVM::tr("Incorrect arguments to '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ break;
+ }
+ uint32_t u32;
+ char *pszNext;
+ int vrc = RTStrToUInt32Ex(a->argv[2], &pszNext, 10, &u32);
+ if (RT_FAILURE(vrc) || *pszNext != '\0')
+ {
+ errorSyntax(ControlVM::tr("Invalid autostart delay number '%s'."), a->argv[2]);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(u32));
+ if (SUCCEEDED(hrc))
+ fNeedsSaving = true;
+ break;
+ }
+ else
+ {
+ errorSyntax(ControlVM::tr("Invalid parameter '%s'."), a->argv[1]);
+ hrc = E_FAIL;
+ }
+ } while (0);
+
+ /* The client has to trigger saving the state explicitely. */
+ if (fNeedsSaving)
+ CHECK_ERROR(sessionMachine, SaveSettings());
+
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
new file mode 100644
index 00000000..c7b420ac
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
@@ -0,0 +1,1343 @@
+/* $Id: VBoxManageDHCPServer.cpp $ */
+/** @file
+ * VBoxManage - Implementation of dhcpserver 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/cidr.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/net.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+
+#include <vector>
+#include <map>
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(DHCPServer);
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#define DHCPD_CMD_COMMON_OPT_NETWORK 999 /**< The --network / --netname option number. */
+#define DHCPD_CMD_COMMON_OPT_INTERFACE 998 /**< The --interface / --ifname option number. */
+/** Common option definitions. */
+#define DHCPD_CMD_COMMON_OPTION_DEFS() \
+ { "--network", DHCPD_CMD_COMMON_OPT_NETWORK, RTGETOPT_REQ_STRING }, \
+ { "--netname", DHCPD_CMD_COMMON_OPT_NETWORK, RTGETOPT_REQ_STRING }, /* legacy */ \
+ { "--interface", DHCPD_CMD_COMMON_OPT_INTERFACE, RTGETOPT_REQ_STRING }, \
+ { "--ifname", DHCPD_CMD_COMMON_OPT_INTERFACE, RTGETOPT_REQ_STRING } /* legacy */
+
+/** Handles common options in the typical option parsing switch. */
+#define DHCPD_CMD_COMMON_OPTION_CASES(a_pCtx, a_ch, a_pValueUnion) \
+ case DHCPD_CMD_COMMON_OPT_NETWORK: \
+ if ((a_pCtx)->pszInterface != NULL) \
+ return errorSyntax(DHCPServer::tr("Either --network or --interface, not both")); \
+ (a_pCtx)->pszNetwork = ValueUnion.psz; \
+ break; \
+ case DHCPD_CMD_COMMON_OPT_INTERFACE: \
+ if ((a_pCtx)->pszNetwork != NULL) \
+ return errorSyntax(DHCPServer::tr("Either --interface or --network, not both")); \
+ (a_pCtx)->pszInterface = ValueUnion.psz; \
+ break
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+/** Pointer to a dhcpserver command context. */
+typedef struct DHCPDCMDCTX *PDHCPDCMDCTX;
+
+/**
+ * Definition of a dhcpserver command, with handler and various flags.
+ */
+typedef struct DHCPDCMDDEF
+{
+ /** The command name. */
+ const char *pszName;
+
+ /**
+ * Actual command handler callback.
+ *
+ * @param pCtx Pointer to command context to use.
+ */
+ DECLR3CALLBACKMEMBER(RTEXITCODE, pfnHandler, (PDHCPDCMDCTX pCtx, int argc, char **argv));
+
+ /** The sub-command scope flags. */
+ uint64_t fSubcommandScope;
+} DHCPDCMDDEF;
+/** Pointer to a const dhcpserver command definition. */
+typedef DHCPDCMDDEF const *PCDHCPDCMDDEF;
+
+/**
+ * dhcpserver command context (mainly for carrying common options and such).
+ */
+typedef struct DHCPDCMDCTX
+{
+ /** The handler arguments from the main() function. */
+ HandlerArg *pArg;
+ /** Pointer to the command definition. */
+ PCDHCPDCMDDEF pCmdDef;
+ /** The network name. */
+ const char *pszNetwork;
+ /** The (trunk) interface name. */
+ const char *pszInterface;
+} DHCPDCMDCTX;
+
+typedef std::pair<DHCPOption_T, Utf8Str> DhcpOptSpec;
+typedef std::vector<DhcpOptSpec> DhcpOpts;
+typedef DhcpOpts::iterator DhcpOptIterator;
+
+typedef std::vector<DHCPOption_T> DhcpOptIds;
+typedef DhcpOptIds::iterator DhcpOptIdIterator;
+
+struct VmNameSlotKey
+{
+ const Utf8Str VmName;
+ uint8_t u8Slot;
+
+ VmNameSlotKey(const Utf8Str &aVmName, uint8_t aSlot)
+ : VmName(aVmName)
+ , u8Slot(aSlot)
+ {}
+
+ bool operator<(const VmNameSlotKey& that) const
+ {
+ if (VmName == that.VmName)
+ return u8Slot < that.u8Slot;
+ return VmName < that.VmName;
+ }
+};
+
+typedef std::map<VmNameSlotKey, DhcpOpts> VmSlot2OptionsM;
+typedef VmSlot2OptionsM::iterator VmSlot2OptionsIterator;
+typedef VmSlot2OptionsM::value_type VmSlot2OptionsPair;
+
+typedef std::map<VmNameSlotKey, DhcpOptIds> VmSlot2OptionIdsM;
+typedef VmSlot2OptionIdsM::iterator VmSlot2OptionIdsIterator;
+
+
+
+/**
+ * Helper that find the DHCP server instance.
+ *
+ * @returns The DHCP server instance. NULL if failed (complaining done).
+ * @param pCtx The DHCP server command context.
+ */
+static ComPtr<IDHCPServer> dhcpdFindServer(PDHCPDCMDCTX pCtx)
+{
+ ComPtr<IDHCPServer> ptrRet;
+ if (pCtx->pszNetwork || pCtx->pszInterface)
+ {
+ Assert(pCtx->pszNetwork == NULL || pCtx->pszInterface == NULL);
+
+ /*
+ * We need a network name to find the DHCP server. So, if interface is
+ * given we have to look it up.
+ */
+ HRESULT hrc;
+ Bstr bstrNetName(pCtx->pszNetwork);
+ if (!pCtx->pszNetwork)
+ {
+ ComPtr<IHost> ptrIHost;
+ CHECK_ERROR2_RET(hrc, pCtx->pArg->virtualBox, COMGETTER(Host)(ptrIHost.asOutParam()), ptrRet);
+
+ Bstr bstrInterface(pCtx->pszInterface);
+ ComPtr<IHostNetworkInterface> ptrIHostIf;
+ CHECK_ERROR2(hrc, ptrIHost, FindHostNetworkInterfaceByName(bstrInterface.raw(), ptrIHostIf.asOutParam()));
+ if (FAILED(hrc))
+ {
+ errorArgument(DHCPServer::tr("Failed to locate host-only interface '%s'"), pCtx->pszInterface);
+ return ptrRet;
+ }
+
+ CHECK_ERROR2_RET(hrc, ptrIHostIf, COMGETTER(NetworkName)(bstrNetName.asOutParam()), ptrRet);
+ }
+
+ /*
+ * Now, try locate the server
+ */
+ hrc = pCtx->pArg->virtualBox->FindDHCPServerByNetworkName(bstrNetName.raw(), ptrRet.asOutParam());
+ if (SUCCEEDED(hrc))
+ return ptrRet;
+ if (pCtx->pszNetwork)
+ errorArgument(DHCPServer::tr("Failed to find DHCP server for network '%s'"), pCtx->pszNetwork);
+ else
+ errorArgument(DHCPServer::tr("Failed to find DHCP server for host-only interface '%s' (network '%ls')"),
+ pCtx->pszInterface, bstrNetName.raw());
+ }
+ else
+ errorSyntax(DHCPServer::tr("You need to specify either --network or --interface to identify the DHCP server"));
+ return ptrRet;
+}
+
+
+/**
+ * Helper class for dhcpdHandleAddAndModify
+ */
+class DHCPCmdScope
+{
+ DHCPConfigScope_T m_enmScope;
+ const char *m_pszName;
+ uint8_t m_uSlot;
+ ComPtr<IDHCPConfig> m_ptrConfig;
+ ComPtr<IDHCPGlobalConfig> m_ptrGlobalConfig;
+ ComPtr<IDHCPGroupConfig> m_ptrGroupConfig;
+ ComPtr<IDHCPIndividualConfig> m_ptrIndividualConfig;
+
+public:
+ DHCPCmdScope()
+ : m_enmScope(DHCPConfigScope_Global)
+ , m_pszName(NULL)
+ , m_uSlot(0)
+ {
+ }
+
+ void setGlobal()
+ {
+ m_enmScope = DHCPConfigScope_Global;
+ m_pszName = NULL;
+ m_uSlot = 0;
+ resetPointers();
+ }
+
+ void setGroup(const char *pszGroup)
+ {
+ m_enmScope = DHCPConfigScope_Group;
+ m_pszName = pszGroup;
+ m_uSlot = 0;
+ resetPointers();
+ }
+
+ void setMachineNIC(const char *pszMachine)
+ {
+ m_enmScope = DHCPConfigScope_MachineNIC;
+ m_pszName = pszMachine;
+ m_uSlot = 0;
+ resetPointers();
+ }
+
+ void setMachineSlot(uint8_t uSlot)
+ {
+ Assert(m_enmScope == DHCPConfigScope_MachineNIC);
+ m_uSlot = uSlot;
+ resetPointers();
+ }
+
+ void setMACAddress(const char *pszMACAddress)
+ {
+ m_enmScope = DHCPConfigScope_MAC;
+ m_pszName = pszMACAddress;
+ m_uSlot = 0;
+ resetPointers();
+ }
+
+ ComPtr<IDHCPConfig> &getConfig(ComPtr<IDHCPServer> const &ptrDHCPServer)
+ {
+ if (m_ptrConfig.isNull())
+ {
+ CHECK_ERROR2I_STMT(ptrDHCPServer, GetConfig(m_enmScope, Bstr(m_pszName).raw(), m_uSlot, TRUE /*mayAdd*/,
+ m_ptrConfig.asOutParam()), m_ptrConfig.setNull());
+ }
+ return m_ptrConfig;
+ }
+
+ ComPtr<IDHCPIndividualConfig> &getIndividual(ComPtr<IDHCPServer> const &ptrDHCPServer)
+ {
+ getConfig(ptrDHCPServer);
+ if (m_ptrIndividualConfig.isNull() && m_ptrConfig.isNotNull())
+ {
+ HRESULT hrc = m_ptrConfig.queryInterfaceTo(m_ptrIndividualConfig.asOutParam());
+ if (FAILED(hrc))
+ {
+ com::GlueHandleComError(m_ptrConfig, "queryInterface", hrc, __FILE__, __LINE__);
+ m_ptrIndividualConfig.setNull();
+ }
+ }
+ return m_ptrIndividualConfig;
+ }
+
+ ComPtr<IDHCPGroupConfig> &getGroup(ComPtr<IDHCPServer> const &ptrDHCPServer)
+ {
+ getConfig(ptrDHCPServer);
+ if (m_ptrGroupConfig.isNull() && m_ptrConfig.isNotNull())
+ {
+ HRESULT hrc = m_ptrConfig.queryInterfaceTo(m_ptrGroupConfig.asOutParam());
+ if (FAILED(hrc))
+ {
+ com::GlueHandleComError(m_ptrConfig, "queryInterface", hrc, __FILE__, __LINE__);
+ m_ptrGroupConfig.setNull();
+ }
+ }
+ return m_ptrGroupConfig;
+ }
+
+ DHCPConfigScope_T getScope() const { return m_enmScope; }
+
+private:
+ void resetPointers()
+ {
+ m_ptrConfig.setNull();
+ m_ptrGlobalConfig.setNull();
+ m_ptrIndividualConfig.setNull();
+ m_ptrGroupConfig.setNull();
+ }
+};
+
+enum
+{
+ DHCP_ADDMOD = 1000,
+ DHCP_ADDMOD_FORCE_OPTION,
+ DHCP_ADDMOD_UNFORCE_OPTION,
+ DHCP_ADDMOD_SUPPRESS_OPTION,
+ DHCP_ADDMOD_UNSUPPRESS_OPTION,
+ DHCP_ADDMOD_ZAP_OPTIONS,
+ DHCP_ADDMOD_INCL_MAC,
+ DHCP_ADDMOD_EXCL_MAC,
+ DHCP_ADDMOD_DEL_MAC,
+ DHCP_ADDMOD_INCL_MAC_WILD,
+ DHCP_ADDMOD_EXCL_MAC_WILD,
+ DHCP_ADDMOD_DEL_MAC_WILD,
+ DHCP_ADDMOD_INCL_VENDOR,
+ DHCP_ADDMOD_EXCL_VENDOR,
+ DHCP_ADDMOD_DEL_VENDOR,
+ DHCP_ADDMOD_INCL_VENDOR_WILD,
+ DHCP_ADDMOD_EXCL_VENDOR_WILD,
+ DHCP_ADDMOD_DEL_VENDOR_WILD,
+ DHCP_ADDMOD_INCL_USER,
+ DHCP_ADDMOD_EXCL_USER,
+ DHCP_ADDMOD_DEL_USER,
+ DHCP_ADDMOD_INCL_USER_WILD,
+ DHCP_ADDMOD_EXCL_USER_WILD,
+ DHCP_ADDMOD_DEL_USER_WILD,
+ DHCP_ADDMOD_ZAP_CONDITIONS
+};
+
+/**
+ * Handles the 'add' and 'modify' subcommands.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleAddAndModify(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ { "--server-ip", 'a', RTGETOPT_REQ_STRING },
+ { "--ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
+ { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
+ { "--netmask", 'm', RTGETOPT_REQ_STRING },
+ { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated
+ { "--lower-ip", 'l', RTGETOPT_REQ_STRING },
+ { "--lowerip", 'l', RTGETOPT_REQ_STRING },
+ { "-lowerip", 'l', RTGETOPT_REQ_STRING }, // deprecated
+ { "--upper-ip", 'u', RTGETOPT_REQ_STRING },
+ { "--upperip", 'u', RTGETOPT_REQ_STRING },
+ { "-upperip", 'u', RTGETOPT_REQ_STRING }, // deprecated
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "-enable", 'e', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ { "-disable", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--global", 'g', RTGETOPT_REQ_NOTHING },
+ { "--group", 'G', RTGETOPT_REQ_STRING },
+ { "--mac-address", 'E', RTGETOPT_REQ_MACADDR },
+ { "--vm", 'M', RTGETOPT_REQ_STRING },
+ { "--nic", 'n', RTGETOPT_REQ_UINT8 },
+ { "--set-opt", 's', RTGETOPT_REQ_UINT8 },
+ { "--set-opt-hex", 'x', RTGETOPT_REQ_UINT8 },
+ { "--del-opt", 'D', RTGETOPT_REQ_UINT8 },
+ { "--force-opt", DHCP_ADDMOD_FORCE_OPTION, RTGETOPT_REQ_UINT8 },
+ { "--unforce-opt", DHCP_ADDMOD_UNFORCE_OPTION, RTGETOPT_REQ_UINT8 },
+ { "--suppress-opt", DHCP_ADDMOD_SUPPRESS_OPTION, RTGETOPT_REQ_UINT8 },
+ { "--unsuppress-opt", DHCP_ADDMOD_UNSUPPRESS_OPTION, RTGETOPT_REQ_UINT8 },
+ { "--zap-options", DHCP_ADDMOD_ZAP_OPTIONS, RTGETOPT_REQ_NOTHING },
+ { "--min-lease-time", 'q' , RTGETOPT_REQ_UINT32 },
+ { "--default-lease-time", 'L' , RTGETOPT_REQ_UINT32 },
+ { "--max-lease-time", 'Q' , RTGETOPT_REQ_UINT32 },
+ { "--remove-config", 'R', RTGETOPT_REQ_NOTHING },
+ { "--fixed-address", 'f', RTGETOPT_REQ_STRING },
+ /* group conditions: */
+ { "--incl-mac", DHCP_ADDMOD_INCL_MAC, RTGETOPT_REQ_STRING },
+ { "--excl-mac", DHCP_ADDMOD_EXCL_MAC, RTGETOPT_REQ_STRING },
+ { "--del-mac", DHCP_ADDMOD_DEL_MAC, RTGETOPT_REQ_STRING },
+ { "--incl-mac-wild", DHCP_ADDMOD_INCL_MAC_WILD, RTGETOPT_REQ_STRING },
+ { "--excl-mac-wild", DHCP_ADDMOD_EXCL_MAC_WILD, RTGETOPT_REQ_STRING },
+ { "--del-mac-wild", DHCP_ADDMOD_DEL_MAC_WILD, RTGETOPT_REQ_STRING },
+ { "--incl-vendor", DHCP_ADDMOD_INCL_VENDOR, RTGETOPT_REQ_STRING },
+ { "--excl-vendor", DHCP_ADDMOD_EXCL_VENDOR, RTGETOPT_REQ_STRING },
+ { "--del-vendor", DHCP_ADDMOD_DEL_VENDOR, RTGETOPT_REQ_STRING },
+ { "--incl-vendor-wild", DHCP_ADDMOD_INCL_VENDOR_WILD, RTGETOPT_REQ_STRING },
+ { "--excl-vendor-wild", DHCP_ADDMOD_EXCL_VENDOR_WILD, RTGETOPT_REQ_STRING },
+ { "--del-vendor-wild", DHCP_ADDMOD_DEL_VENDOR_WILD, RTGETOPT_REQ_STRING },
+ { "--incl-user", DHCP_ADDMOD_INCL_USER, RTGETOPT_REQ_STRING },
+ { "--excl-user", DHCP_ADDMOD_EXCL_USER, RTGETOPT_REQ_STRING },
+ { "--del-user", DHCP_ADDMOD_DEL_USER, RTGETOPT_REQ_STRING },
+ { "--incl-user-wild", DHCP_ADDMOD_INCL_USER_WILD, RTGETOPT_REQ_STRING },
+ { "--excl-user-wild", DHCP_ADDMOD_EXCL_USER_WILD, RTGETOPT_REQ_STRING },
+ { "--del-user-wild", DHCP_ADDMOD_DEL_USER_WILD, RTGETOPT_REQ_STRING },
+ { "--zap-conditions", DHCP_ADDMOD_ZAP_CONDITIONS, RTGETOPT_REQ_NOTHING },
+ /* obsolete, to be removed: */
+ { "--id", 'i', RTGETOPT_REQ_UINT8 }, // obsolete, backwards compatibility only.
+ { "--value", 'p', RTGETOPT_REQ_STRING }, // obsolete, backwards compatibility only.
+ { "--remove", 'r', RTGETOPT_REQ_NOTHING }, // obsolete, backwards compatibility only.
+ { "--options", 'o', RTGETOPT_REQ_NOTHING }, // obsolete legacy, ignored
+
+ };
+
+ /*
+ * Parse the arguments in two passes:
+ *
+ * 1. Validate the command line and establish the IDHCPServer settings.
+ * 2. Execute the various IDHCPConfig settings changes.
+ *
+ * This is considered simpler than duplicating the command line instructions
+ * into elaborate structures and executing these.
+ */
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ ComPtr<IDHCPServer> ptrDHCPServer;
+ for (size_t iPass = 0; iPass < 2; iPass++)
+ {
+ const char *pszServerIp = NULL;
+ const char *pszNetmask = NULL;
+ const char *pszLowerIp = NULL;
+ const char *pszUpperIp = NULL;
+ int fEnabled = -1;
+
+ DHCPCmdScope Scope;
+ char szMACAddress[32];
+
+ bool fNeedValueOrRemove = false; /* Only used with --id; remove in 6.1+ */
+ uint8_t u8OptId = 0; /* Only used too keep --id for following --value/--remove. remove in 6.1+ */
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+ case 'a': // --server-ip
+ pszServerIp = ValueUnion.psz;
+ break;
+ case 'm': // --netmask
+ pszNetmask = ValueUnion.psz;
+ break;
+ case 'l': // --lower-ip
+ pszLowerIp = ValueUnion.psz;
+ break;
+ case 'u': // --upper-ip
+ pszUpperIp = ValueUnion.psz;
+ break;
+ case 'e': // --enable
+ fEnabled = 1;
+ break;
+ case 'd': // --disable
+ fEnabled = 0;
+ break;
+
+ /*
+ * Configuration selection:
+ */
+ case 'g': // --global Sets the option scope to 'global'.
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--global'"));
+ Scope.setGlobal();
+ break;
+
+ case 'G': // --group
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--group'"));
+ if (!*ValueUnion.psz)
+ return errorSyntax(DHCPServer::tr("Group name cannot be empty"));
+ Scope.setGroup(ValueUnion.psz);
+ break;
+
+ case 'E': // --mac-address
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--mac-address'"));
+ RTStrPrintf(szMACAddress, sizeof(szMACAddress), "%RTmac", &ValueUnion.MacAddr);
+ Scope.setMACAddress(szMACAddress);
+ break;
+
+ case 'M': // --vm Sets the option scope to ValueUnion.psz + 0.
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--vm'"));
+ Scope.setMachineNIC(ValueUnion.psz);
+ break;
+
+ case 'n': // --nic Sets the option scope to pszVmName + (ValueUnion.u8 - 1).
+ if (Scope.getScope() != DHCPConfigScope_MachineNIC)
+ return errorSyntax(DHCPServer::tr("--nic option requires a --vm preceeding selecting the VM it should apply to"));
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--nic=%u"), ValueUnion.u8);
+ if (ValueUnion.u8 < 1)
+ return errorSyntax(DHCPServer::tr("invalid NIC number: %u"), ValueUnion.u8);
+ Scope.setMachineSlot(ValueUnion.u8 - 1);
+ break;
+
+ /*
+ * Modify configuration:
+ */
+ case 's': // --set-opt num stringvalue
+ {
+ uint8_t const idAddOpt = ValueUnion.u8;
+ vrc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorFetchValue(1, "--set-opt", vrc, &ValueUnion);
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, SetOption((DHCPOption_T)idAddOpt, DHCPOptionEncoding_Normal,
+ Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+ }
+
+ case 'x': // --set-opt-hex num hex-string
+ {
+ uint8_t const idAddOpt = ValueUnion.u8;
+ vrc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorFetchValue(1, "--set-opt-hex", vrc, &ValueUnion);
+ uint8_t abBuf[256];
+ size_t cbRet;
+ vrc = RTStrConvertHexBytesEx(ValueUnion.psz, abBuf, sizeof(abBuf), RTSTRCONVERTHEXBYTES_F_SEP_COLON,
+ NULL, &cbRet);
+ if (RT_FAILURE(vrc))
+ return errorArgument(DHCPServer::tr("Malformed hex string given to --set-opt-hex %u: %s\n"),
+ idAddOpt, ValueUnion.psz);
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, SetOption((DHCPOption_T)idAddOpt, DHCPOptionEncoding_Hex,
+ Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+ }
+
+ case 'D': // --del-opt num
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--del-opt does not apply to the 'add' subcommand"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, RemoveOption((DHCPOption_T)ValueUnion.u8), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case DHCP_ADDMOD_UNFORCE_OPTION: // --unforce-opt
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--unforce-opt does not apply to the 'add' subcommand"));
+ RT_FALL_THROUGH();
+ case DHCP_ADDMOD_UNSUPPRESS_OPTION: // --unsupress-opt
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--unsuppress-opt does not apply to the 'add' subcommand"));
+ RT_FALL_THROUGH();
+ case DHCP_ADDMOD_FORCE_OPTION: // --force-opt
+ case DHCP_ADDMOD_SUPPRESS_OPTION: // --suppress-opt
+ if (iPass == 1)
+ {
+ DHCPOption_T const enmOption = (DHCPOption_T)ValueUnion.u8;
+ bool const fForced = vrc == DHCP_ADDMOD_FORCE_OPTION || vrc == DHCP_ADDMOD_UNFORCE_OPTION;
+
+ /* Get the current option list: */
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ com::SafeArray<DHCPOption_T> Options;
+ if (fForced)
+ CHECK_ERROR2I_STMT(ptrConfig, COMGETTER(ForcedOptions)(ComSafeArrayAsOutParam(Options)),
+ rcExit = RTEXITCODE_FAILURE; break);
+ else
+ CHECK_ERROR2I_STMT(ptrConfig, COMGETTER(SuppressedOptions)(ComSafeArrayAsOutParam(Options)),
+ rcExit = RTEXITCODE_FAILURE; break);
+ if (vrc == DHCP_ADDMOD_FORCE_OPTION || vrc == DHCP_ADDMOD_SUPPRESS_OPTION)
+ {
+ /* Add if not present. */
+ size_t iSrc;
+ for (iSrc = 0; iSrc < Options.size(); iSrc++)
+ if (Options[iSrc] == enmOption)
+ break;
+ if (iSrc < Options.size())
+ break; /* already present */
+ Options.push_back(enmOption);
+ }
+ else
+ {
+ /* Remove */
+ size_t iDst = 0;
+ for (size_t iSrc = 0; iSrc < Options.size(); iSrc++)
+ {
+ DHCPOption_T enmCurOpt = Options[iSrc];
+ if (enmCurOpt != enmOption)
+ Options[iDst++] = enmCurOpt;
+ }
+ if (iDst == Options.size())
+ break; /* Not found. */
+ Options.resize(iDst);
+ }
+
+ /* Update the option list: */
+ if (fForced)
+ CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(ForcedOptions)(ComSafeArrayAsInParam(Options)),
+ rcExit = RTEXITCODE_FAILURE);
+ else
+ CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(SuppressedOptions)(ComSafeArrayAsInParam(Options)),
+ rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case DHCP_ADDMOD_ZAP_OPTIONS:
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--zap-options does not apply to the 'add' subcommand"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, RemoveAllOptions(), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case 'q': // --min-lease-time
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(MinLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case 'L': // --default-lease-time
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(DefaultLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case 'Q': // --max-lease-time
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, COMSETTER(MaxLeaseTime)(ValueUnion.u32), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ case 'R': // --remove-config
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--remove-config does not apply to the 'add' subcommand"));
+ if (Scope.getScope() == DHCPConfigScope_Global)
+ return errorSyntax(DHCPServer::tr("--remove-config cannot be applied to the global config"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, Remove(), rcExit = RTEXITCODE_FAILURE);
+ }
+ Scope.setGlobal();
+ break;
+
+ case 'f': // --fixed-address
+ if (Scope.getScope() != DHCPConfigScope_MachineNIC && Scope.getScope() != DHCPConfigScope_MAC)
+ return errorSyntax(DHCPServer::tr("--fixed-address can only be applied to a VM NIC or an MAC address"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPIndividualConfig> &ptrIndividualConfig = Scope.getIndividual(ptrDHCPServer);
+ if (ptrIndividualConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrIndividualConfig, COMSETTER(FixedAddress)(Bstr(ValueUnion.psz).raw()),
+ rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ /*
+ * Group conditions:
+ */
+ case DHCP_ADDMOD_INCL_MAC:
+ case DHCP_ADDMOD_EXCL_MAC:
+ case DHCP_ADDMOD_DEL_MAC:
+ case DHCP_ADDMOD_INCL_MAC_WILD:
+ case DHCP_ADDMOD_EXCL_MAC_WILD:
+ case DHCP_ADDMOD_DEL_MAC_WILD:
+ case DHCP_ADDMOD_INCL_VENDOR:
+ case DHCP_ADDMOD_EXCL_VENDOR:
+ case DHCP_ADDMOD_DEL_VENDOR:
+ case DHCP_ADDMOD_INCL_VENDOR_WILD:
+ case DHCP_ADDMOD_EXCL_VENDOR_WILD:
+ case DHCP_ADDMOD_DEL_VENDOR_WILD:
+ case DHCP_ADDMOD_INCL_USER:
+ case DHCP_ADDMOD_EXCL_USER:
+ case DHCP_ADDMOD_DEL_USER:
+ case DHCP_ADDMOD_INCL_USER_WILD:
+ case DHCP_ADDMOD_EXCL_USER_WILD:
+ case DHCP_ADDMOD_DEL_USER_WILD:
+ {
+ if (Scope.getScope() != DHCPConfigScope_Group)
+ return errorSyntax(DHCPServer::tr("A group must be selected to perform condition alterations."));
+ if (!*ValueUnion.psz)
+ return errorSyntax(DHCPServer::tr("Condition value cannot be empty")); /* or can it? */
+ if (iPass != 1)
+ break;
+
+ DHCPGroupConditionType_T enmType;
+ switch (vrc)
+ {
+ case DHCP_ADDMOD_INCL_MAC: case DHCP_ADDMOD_EXCL_MAC: case DHCP_ADDMOD_DEL_MAC:
+ enmType = DHCPGroupConditionType_MAC;
+ break;
+ case DHCP_ADDMOD_INCL_MAC_WILD: case DHCP_ADDMOD_EXCL_MAC_WILD: case DHCP_ADDMOD_DEL_MAC_WILD:
+ enmType = DHCPGroupConditionType_MACWildcard;
+ break;
+ case DHCP_ADDMOD_INCL_VENDOR: case DHCP_ADDMOD_EXCL_VENDOR: case DHCP_ADDMOD_DEL_VENDOR:
+ enmType = DHCPGroupConditionType_vendorClassID;
+ break;
+ case DHCP_ADDMOD_INCL_VENDOR_WILD: case DHCP_ADDMOD_EXCL_VENDOR_WILD: case DHCP_ADDMOD_DEL_VENDOR_WILD:
+ enmType = DHCPGroupConditionType_vendorClassIDWildcard;
+ break;
+ case DHCP_ADDMOD_INCL_USER: case DHCP_ADDMOD_EXCL_USER: case DHCP_ADDMOD_DEL_USER:
+ enmType = DHCPGroupConditionType_userClassID;
+ break;
+ case DHCP_ADDMOD_INCL_USER_WILD: case DHCP_ADDMOD_EXCL_USER_WILD: case DHCP_ADDMOD_DEL_USER_WILD:
+ enmType = DHCPGroupConditionType_userClassIDWildcard;
+ break;
+ default:
+ AssertFailedReturn(RTEXITCODE_FAILURE);
+ }
+
+ int fInclusive;
+ switch (vrc)
+ {
+ case DHCP_ADDMOD_DEL_MAC:
+ case DHCP_ADDMOD_DEL_MAC_WILD:
+ case DHCP_ADDMOD_DEL_USER:
+ case DHCP_ADDMOD_DEL_USER_WILD:
+ case DHCP_ADDMOD_DEL_VENDOR:
+ case DHCP_ADDMOD_DEL_VENDOR_WILD:
+ fInclusive = -1;
+ break;
+ case DHCP_ADDMOD_EXCL_MAC:
+ case DHCP_ADDMOD_EXCL_MAC_WILD:
+ case DHCP_ADDMOD_EXCL_USER:
+ case DHCP_ADDMOD_EXCL_USER_WILD:
+ case DHCP_ADDMOD_EXCL_VENDOR:
+ case DHCP_ADDMOD_EXCL_VENDOR_WILD:
+ fInclusive = 0;
+ break;
+ case DHCP_ADDMOD_INCL_MAC:
+ case DHCP_ADDMOD_INCL_MAC_WILD:
+ case DHCP_ADDMOD_INCL_USER:
+ case DHCP_ADDMOD_INCL_USER_WILD:
+ case DHCP_ADDMOD_INCL_VENDOR:
+ case DHCP_ADDMOD_INCL_VENDOR_WILD:
+ fInclusive = 1;
+ break;
+ default:
+ AssertFailedReturn(RTEXITCODE_FAILURE);
+ }
+
+ ComPtr<IDHCPGroupConfig> &ptrGroupConfig = Scope.getGroup(ptrDHCPServer);
+ if (ptrGroupConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ if (fInclusive >= 0)
+ {
+ ComPtr<IDHCPGroupCondition> ptrCondition;
+ CHECK_ERROR2I_STMT(ptrGroupConfig, AddCondition((BOOL)fInclusive, enmType, Bstr(ValueUnion.psz).raw(),
+ ptrCondition.asOutParam()), rcExit = RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ com::SafeIfaceArray<IDHCPGroupCondition> Conditions;
+ CHECK_ERROR2I_STMT(ptrGroupConfig, COMGETTER(Conditions)(ComSafeArrayAsOutParam(Conditions)),
+ rcExit = RTEXITCODE_FAILURE; break);
+ bool fFound = false;
+ for (size_t iCond = 0; iCond < Conditions.size(); iCond++)
+ {
+ DHCPGroupConditionType_T enmCurType = DHCPGroupConditionType_MAC;
+ CHECK_ERROR2I_STMT(Conditions[iCond], COMGETTER(Type)(&enmCurType),
+ rcExit = RTEXITCODE_FAILURE; continue);
+ if (enmCurType == enmType)
+ {
+ Bstr bstrValue;
+ CHECK_ERROR2I_STMT(Conditions[iCond], COMGETTER(Value)(bstrValue.asOutParam()),
+ rcExit = RTEXITCODE_FAILURE; continue);
+ if (RTUtf16CmpUtf8(bstrValue.raw(), ValueUnion.psz) == 0)
+ {
+ CHECK_ERROR2I_STMT(Conditions[iCond], Remove(), rcExit = RTEXITCODE_FAILURE);
+ fFound = true;
+ }
+ }
+ }
+ if (!fFound)
+ rcExit = RTMsgErrorExitFailure(DHCPServer::tr("Could not find any condition of type %d with value '%s' to delete"),
+ enmType, ValueUnion.psz);
+ }
+ break;
+ }
+
+ case DHCP_ADDMOD_ZAP_CONDITIONS:
+ if (Scope.getScope() != DHCPConfigScope_Group)
+ return errorSyntax(DHCPServer::tr("--zap-conditions can only be with a group selected"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPGroupConfig> &ptrGroupConfig = Scope.getGroup(ptrDHCPServer);
+ if (ptrGroupConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrGroupConfig, RemoveAllConditions(), rcExit = RTEXITCODE_FAILURE);
+ }
+ break;
+
+ /*
+ * For backwards compatibility. Remove in 6.1 or later.
+ */
+
+ case 'o': // --options - obsolete, ignored.
+ break;
+
+ case 'i': // --id
+ if (fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("Incomplete option sequence preseeding '--id=%u"), ValueUnion.u8);
+ u8OptId = ValueUnion.u8;
+ fNeedValueOrRemove = true;
+ break;
+
+ case 'p': // --value
+ if (!fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("--value without --id=dhcp-opt-no"));
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, SetOption((DHCPOption_T)u8OptId, DHCPOptionEncoding_Normal,
+ Bstr(ValueUnion.psz).raw()), rcExit = RTEXITCODE_FAILURE);
+ }
+ fNeedValueOrRemove = false;
+ break;
+
+ case 'r': // --remove
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ return errorSyntax(DHCPServer::tr("--remove does not apply to the 'add' subcommand"));
+ if (!fNeedValueOrRemove)
+ return errorSyntax(DHCPServer::tr("--remove without --id=dhcp-opt-no"));
+
+ if (iPass == 1)
+ {
+ ComPtr<IDHCPConfig> &ptrConfig = Scope.getConfig(ptrDHCPServer);
+ if (ptrConfig.isNull())
+ return RTEXITCODE_FAILURE;
+ CHECK_ERROR2I_STMT(ptrConfig, RemoveOption((DHCPOption_T)u8OptId), rcExit = RTEXITCODE_FAILURE);
+ }
+ fNeedValueOrRemove = false;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (iPass != 0)
+ break;
+
+ /*
+ * Ensure we've got mandatory options and supply defaults
+ * where needed (modify case)
+ */
+ if (!pCtx->pszNetwork && !pCtx->pszInterface)
+ return errorSyntax(DHCPServer::tr("You need to specify either --network or --interface to identify the DHCP server"));
+
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ {
+ if (!pszServerIp)
+ rcExit = errorSyntax(DHCPServer::tr("Missing required option: --ip"));
+ if (!pszNetmask)
+ rcExit = errorSyntax(DHCPServer::tr("Missing required option: --netmask"));
+ if (!pszLowerIp)
+ rcExit = errorSyntax(DHCPServer::tr("Missing required option: --lowerip"));
+ if (!pszUpperIp)
+ rcExit = errorSyntax(DHCPServer::tr("Missing required option: --upperip"));
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ }
+
+ /*
+ * Find or create the server.
+ */
+ HRESULT hrc;
+ Bstr NetName;
+ if (!pCtx->pszNetwork)
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR(pCtx->pArg->virtualBox, COMGETTER(Host)(host.asOutParam()));
+
+ ComPtr<IHostNetworkInterface> hif;
+ CHECK_ERROR(host, FindHostNetworkInterfaceByName(Bstr(pCtx->pszInterface).mutableRaw(), hif.asOutParam()));
+ if (FAILED(hrc))
+ return errorArgument(DHCPServer::tr("Could not find interface '%s'"), pCtx->pszInterface);
+
+ CHECK_ERROR(hif, COMGETTER(NetworkName) (NetName.asOutParam()));
+ if (FAILED(hrc))
+ return errorArgument(DHCPServer::tr("Could not get network name for the interface '%s'"), pCtx->pszInterface);
+ }
+ else
+ {
+ NetName = Bstr(pCtx->pszNetwork);
+ }
+
+ hrc = pCtx->pArg->virtualBox->FindDHCPServerByNetworkName(NetName.mutableRaw(), ptrDHCPServer.asOutParam());
+ if (pCtx->pCmdDef->fSubcommandScope == HELP_SCOPE_DHCPSERVER_ADD)
+ {
+ if (SUCCEEDED(hrc))
+ return errorArgument(DHCPServer::tr("DHCP server already exists"));
+
+ CHECK_ERROR(pCtx->pArg->virtualBox, CreateDHCPServer(NetName.mutableRaw(), ptrDHCPServer.asOutParam()));
+ if (FAILED(hrc))
+ return errorArgument(DHCPServer::tr("Failed to create the DHCP server"));
+ }
+ else if (FAILED(hrc))
+ return errorArgument(DHCPServer::tr("DHCP server does not exist"));
+
+ /*
+ * Apply IDHCPServer settings:
+ */
+ if (pszServerIp || pszNetmask || pszLowerIp || pszUpperIp)
+ {
+ Bstr bstrServerIp(pszServerIp);
+ Bstr bstrNetmask(pszNetmask);
+ Bstr bstrLowerIp(pszLowerIp);
+ Bstr bstrUpperIp(pszUpperIp);
+
+ if (!pszServerIp)
+ {
+ CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(IPAddress)(bstrServerIp.asOutParam()), RTEXITCODE_FAILURE);
+ }
+ if (!pszNetmask)
+ {
+ CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(NetworkMask)(bstrNetmask.asOutParam()), RTEXITCODE_FAILURE);
+ }
+ if (!pszLowerIp)
+ {
+ CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(LowerIP)(bstrLowerIp.asOutParam()), RTEXITCODE_FAILURE);
+ }
+ if (!pszUpperIp)
+ {
+ CHECK_ERROR2_RET(hrc, ptrDHCPServer, COMGETTER(UpperIP)(bstrUpperIp.asOutParam()), RTEXITCODE_FAILURE);
+ }
+
+ CHECK_ERROR2_STMT(hrc, ptrDHCPServer, SetConfiguration(bstrServerIp.raw(), bstrNetmask.raw(),
+ bstrLowerIp.raw(), bstrUpperIp.raw()),
+ rcExit = errorArgument(DHCPServer::tr("Failed to set configuration (%ls, %ls, %ls, %ls)"), bstrServerIp.raw(),
+ bstrNetmask.raw(), bstrLowerIp.raw(), bstrUpperIp.raw()));
+ }
+
+ if (fEnabled >= 0)
+ {
+ CHECK_ERROR2_STMT(hrc, ptrDHCPServer, COMSETTER(Enabled)((BOOL)fEnabled), rcExit = RTEXITCODE_FAILURE);
+ }
+ }
+
+ return rcExit;
+}
+
+
+/**
+ * Handles the 'remove' subcommand.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleRemove(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ /*
+ * Parse the command line.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Locate the server and perform the requested operation.
+ */
+ ComPtr<IDHCPServer> ptrDHCPServer = dhcpdFindServer(pCtx);
+ if (ptrDHCPServer.isNotNull())
+ {
+ HRESULT hrc;
+ CHECK_ERROR2(hrc, pCtx->pArg->virtualBox, RemoveDHCPServer(ptrDHCPServer));
+ if (SUCCEEDED(hrc))
+ return RTEXITCODE_SUCCESS;
+ errorArgument(DHCPServer::tr("Failed to remove server"));
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'start' subcommand.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleStart(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ /*
+ * Parse the command line.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Locate the server.
+ */
+ ComPtr<IDHCPServer> ptrDHCPServer = dhcpdFindServer(pCtx);
+ if (ptrDHCPServer.isNotNull())
+ {
+ /*
+ * We have to figure out the trunk name and type here, which is silly to
+ * leave to the API client as it's a pain to get right. But here we go...
+ */
+ static char const s_szHostOnlyPrefix[] = "HostInterfaceNetworking-";
+ bool fHostOnly = true;
+ Bstr strTrunkName;
+ if (pCtx->pszInterface)
+ strTrunkName = pCtx->pszInterface;
+ else if (RTStrStartsWith(pCtx->pszNetwork, s_szHostOnlyPrefix))
+ strTrunkName = &pCtx->pszNetwork[sizeof(s_szHostOnlyPrefix) - 1];
+ else
+ fHostOnly = false;
+
+ Bstr strTrunkType;
+ if (fHostOnly)
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_DARWIN)
+ strTrunkType = "netadp";
+#else /* lazy implementations: */
+ strTrunkType = "netflt";
+#endif
+ else
+ strTrunkType = "whatever";
+
+ HRESULT hrc = ptrDHCPServer->Start(strTrunkName.raw(), strTrunkType.raw());
+ if (SUCCEEDED(hrc))
+ return RTEXITCODE_SUCCESS;
+ errorArgument(DHCPServer::tr("Failed to start the server"));
+ GlueHandleComErrorNoCtx(ptrDHCPServer, hrc);
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'restart' subcommand.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleRestart(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ /*
+ * Parse the command line.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Locate the server and perform the requested operation.
+ */
+ ComPtr<IDHCPServer> ptrDHCPServer = dhcpdFindServer(pCtx);
+ if (ptrDHCPServer.isNotNull())
+ {
+ HRESULT hrc = ptrDHCPServer->Restart();
+ if (SUCCEEDED(hrc))
+ return RTEXITCODE_SUCCESS;
+ errorArgument(DHCPServer::tr("Failed to restart the server"));
+ GlueHandleComErrorNoCtx(ptrDHCPServer, hrc);
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'stop' subcommand.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleStop(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ /*
+ * Parse the command line.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Locate the server and perform the requested operation.
+ */
+ ComPtr<IDHCPServer> ptrDHCPServer = dhcpdFindServer(pCtx);
+ if (ptrDHCPServer.isNotNull())
+ {
+ HRESULT hrc = ptrDHCPServer->Stop();
+ if (SUCCEEDED(hrc))
+ return RTEXITCODE_SUCCESS;
+ errorArgument(DHCPServer::tr("Failed to stop the server"));
+ GlueHandleComErrorNoCtx(ptrDHCPServer, hrc);
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'findlease' subcommand.
+ */
+static DECLCALLBACK(RTEXITCODE) dhcpdHandleFindLease(PDHCPDCMDCTX pCtx, int argc, char **argv)
+{
+ /*
+ * Parse the command line.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ DHCPD_CMD_COMMON_OPTION_DEFS(),
+ { "--mac-address", 'm', RTGETOPT_REQ_MACADDR },
+
+ };
+
+ bool fHaveMacAddress = false;
+ RTMAC MacAddress = { { 0, 0, 0, 0, 0, 0 } };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(pCtx, vrc, &ValueUnion);
+
+ case 'm': // --mac-address
+ fHaveMacAddress = true;
+ MacAddress = ValueUnion.MacAddr;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!fHaveMacAddress)
+ return errorSyntax(DHCPServer::tr("You need to specify a MAC address too look for"));
+
+ /*
+ * Locate the server and perform the requested operation.
+ */
+ ComPtr<IDHCPServer> ptrDHCPServer = dhcpdFindServer(pCtx);
+ if (ptrDHCPServer.isNull())
+ return RTEXITCODE_FAILURE;
+
+ char szMac[32];
+ RTStrPrintf(szMac, sizeof(szMac), "%RTmac", &MacAddress);
+ Bstr bstrAddress;
+ Bstr bstrState;
+ LONG64 secIssued = 0;
+ LONG64 secExpire = 0;
+ HRESULT hrc;
+ CHECK_ERROR2(hrc, ptrDHCPServer, FindLeaseByMAC(Bstr(szMac).raw(), 0 /*type*/,
+ bstrAddress.asOutParam(), bstrState.asOutParam(), &secIssued, &secExpire));
+ if (SUCCEEDED(hrc))
+ {
+ RTTIMESPEC TimeSpec;
+ int64_t cSecLeftToLive = secExpire - RTTimeSpecGetSeconds(RTTimeNow(&TimeSpec));
+ RTTIME Time;
+ char szIssued[RTTIME_STR_LEN];
+ RTTimeToStringEx(RTTimeExplode(&Time, RTTimeSpecSetSeconds(&TimeSpec, secIssued)), szIssued, sizeof(szIssued), 0);
+ char szExpire[RTTIME_STR_LEN];
+ RTTimeToStringEx(RTTimeExplode(&Time, RTTimeSpecSetSeconds(&TimeSpec, secExpire)), szExpire, sizeof(szExpire), 0);
+
+ RTPrintf(DHCPServer::tr("IP Address: %ls\n"
+ "MAC Address: %RTmac\n"
+ "State: %ls\n"
+ "Issued: %s (%RU64)\n"
+ "Expire: %s (%RU64)\n"
+ "TTL: %RU64 sec, currently %RU64 sec left\n"),
+ bstrAddress.raw(),
+ &MacAddress,
+ bstrState.raw(),
+ szIssued, secIssued,
+ szExpire, secExpire,
+ secExpire >= secIssued ? secExpire - secIssued : 0, cSecLeftToLive > 0 ? cSecLeftToLive : 0);
+ return RTEXITCODE_SUCCESS;
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'dhcpserver' command.
+ */
+RTEXITCODE handleDHCPServer(HandlerArg *pArg)
+{
+ /*
+ * Command definitions.
+ */
+ static const DHCPDCMDDEF s_aCmdDefs[] =
+ {
+ { "add", dhcpdHandleAddAndModify, HELP_SCOPE_DHCPSERVER_ADD },
+ { "modify", dhcpdHandleAddAndModify, HELP_SCOPE_DHCPSERVER_MODIFY },
+ { "remove", dhcpdHandleRemove, HELP_SCOPE_DHCPSERVER_REMOVE },
+ { "start", dhcpdHandleStart, HELP_SCOPE_DHCPSERVER_START },
+ { "restart", dhcpdHandleRestart, HELP_SCOPE_DHCPSERVER_RESTART },
+ { "stop", dhcpdHandleStop, HELP_SCOPE_DHCPSERVER_STOP },
+ { "findlease", dhcpdHandleFindLease, HELP_SCOPE_DHCPSERVER_FINDLEASE },
+ };
+
+ /*
+ * VBoxManage dhcpserver [common-options] subcommand ...
+ */
+ DHCPDCMDCTX CmdCtx;
+ CmdCtx.pArg = pArg;
+ CmdCtx.pCmdDef = NULL;
+ CmdCtx.pszInterface = NULL;
+ CmdCtx.pszNetwork = NULL;
+
+ static const RTGETOPTDEF s_CommonOptions[] = { DHCPD_CMD_COMMON_OPTION_DEFS() };
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_CommonOptions, RT_ELEMENTS(s_CommonOptions), 0,
+ 0 /* No sorting! */);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ DHCPD_CMD_COMMON_OPTION_CASES(&CmdCtx, vrc, &ValueUnion);
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ const char *pszCmd = ValueUnion.psz;
+ uint32_t iCmd;
+ for (iCmd = 0; iCmd < RT_ELEMENTS(s_aCmdDefs); iCmd++)
+ if (strcmp(s_aCmdDefs[iCmd].pszName, pszCmd) == 0)
+ {
+ CmdCtx.pCmdDef = &s_aCmdDefs[iCmd];
+ setCurrentSubcommand(s_aCmdDefs[iCmd].fSubcommandScope);
+ return s_aCmdDefs[iCmd].pfnHandler(&CmdCtx, pArg->argc - GetState.iNext + 1,
+ &pArg->argv[GetState.iNext - 1]);
+ }
+ return errorUnknownSubcommand(pszCmd);
+ }
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+ return errorNoSubcommand();
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
new file mode 100644
index 00000000..39c0866e
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
@@ -0,0 +1,976 @@
+/* $Id: VBoxManageDebugVM.cpp $ */
+/** @file
+ * VBoxManage - Implementation of the debugvm command.
+ */
+
+/*
+ * Copyright (C) 2012-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <VBox/types.h>
+#include <iprt/ctype.h>
+#include <iprt/getopt.h>
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/uuid.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+
+DECLARE_TRANSLATION_CONTEXT(DebugVM);
+
+
+/**
+ * Handles the getregisters sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_GetRegisters(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * We take a list of register names (case insensitive). If 'all' is
+ * encountered we'll dump all registers.
+ */
+ ULONG idCpu = 0;
+ unsigned cRegisters = 0;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--cpu", 'c', RTGETOPT_REQ_UINT32 },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'c':
+ idCpu = ValueUnion.u32;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!RTStrICmp(ValueUnion.psz, "all"))
+ {
+ com::SafeArray<BSTR> aBstrNames;
+ com::SafeArray<BSTR> aBstrValues;
+ CHECK_ERROR2I_RET(pDebugger, GetRegisters(idCpu, ComSafeArrayAsOutParam(aBstrNames),
+ ComSafeArrayAsOutParam(aBstrValues)),
+ RTEXITCODE_FAILURE);
+ Assert(aBstrNames.size() == aBstrValues.size());
+
+ size_t cchMaxName = 8;
+ for (size_t i = 0; i < aBstrNames.size(); i++)
+ {
+ size_t cchName = RTUtf16Len(aBstrNames[i]);
+ if (cchName > cchMaxName)
+ cchMaxName = cchName;
+ }
+
+ for (size_t i = 0; i < aBstrNames.size(); i++)
+ RTPrintf("%-*ls = %ls\n", cchMaxName, aBstrNames[i], aBstrValues[i]);
+ }
+ else
+ {
+ com::Bstr bstrName = ValueUnion.psz;
+ com::Bstr bstrValue;
+ CHECK_ERROR2I_RET(pDebugger, GetRegister(idCpu, bstrName.raw(), bstrValue.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf("%s = %ls\n", ValueUnion.psz, bstrValue.raw());
+ }
+ cRegisters++;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!cRegisters)
+ return errorSyntax(DebugVM::tr("The getregisters sub-command takes at least one register name"));
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the info sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_Info(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments.
+ */
+ const char *pszInfo = NULL;
+ const char *pszArgs = NULL;
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, NULL, 0, 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszInfo)
+ pszInfo = ValueUnion.psz;
+ else if (!pszArgs)
+ pszArgs = ValueUnion.psz;
+ else
+ return errorTooManyParameters(&pArgs->argv[GetState.iNext - 1]);
+ break;
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!pszInfo)
+ return errorSyntax(DebugVM::tr("Must specify info item to display"));
+
+ /*
+ * Do the work.
+ */
+ com::Bstr bstrName(pszInfo);
+ com::Bstr bstrArgs(pszArgs);
+ com::Bstr bstrInfo;
+ CHECK_ERROR2I_RET(pDebugger, Info(bstrName.raw(), bstrArgs.raw(), bstrInfo.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf("%ls", bstrInfo.raw());
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the inject sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param a The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_InjectNMI(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+ if (a->argc != 2)
+ return errorTooManyParameters(&a->argv[1]);
+ CHECK_ERROR2I_RET(pDebugger, InjectNMI(), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the log sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ * @param pszSubCmd The sub command.
+ */
+static RTEXITCODE handleDebugVM_LogXXXX(HandlerArg *pArgs, IMachineDebugger *pDebugger, const char *pszSubCmd)
+{
+ /*
+ * Parse arguments.
+ */
+ bool fRelease = false;
+ com::Utf8Str strSettings;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+
+ /*
+ * NB: don't use short options to prevent log specifications like
+ * "-drv_foo" from being interpreted as options.
+ */
+# define DEBUGVM_LOG_DEBUG (VINF_GETOPT_NOT_OPTION + 'd')
+# define DEBUGVM_LOG_RELEASE (VINF_GETOPT_NOT_OPTION + 'r')
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--debug", DEBUGVM_LOG_DEBUG, RTGETOPT_REQ_NOTHING },
+ { "--release", DEBUGVM_LOG_RELEASE, RTGETOPT_REQ_NOTHING }
+ };
+ /*
+ * Note: RTGETOPTINIT_FLAGS_NO_STD_OPTS is needed to not get into an infinite hang in the following
+ * while-loop when processing log groups starting with "h",
+ * e.g. "VBoxManage debugvm <VM Name> log --debug -hex".
+ */
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2,
+ RTGETOPTINIT_FLAGS_OPTS_FIRST | RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case DEBUGVM_LOG_RELEASE:
+ fRelease = true;
+ break;
+
+ case DEBUGVM_LOG_DEBUG:
+ fRelease = false;
+ break;
+
+ /* Because log strings can start with "-" (like "-all+dev_foo")
+ * we have to take everything we got as a setting and apply it.
+ * IPRT will take care of the validation afterwards. */
+ default:
+ if (strSettings.length() == 0)
+ strSettings = ValueUnion.psz;
+ else
+ {
+ strSettings.append(' ');
+ strSettings.append(ValueUnion.psz);
+ }
+ break;
+ }
+ }
+
+ if (fRelease)
+ {
+ com::Utf8Str strTmp(strSettings);
+ strSettings = "release:";
+ strSettings.append(strTmp);
+ }
+
+ com::Bstr bstrSettings(strSettings);
+ if (!strcmp(pszSubCmd, "log"))
+ CHECK_ERROR2I_RET(pDebugger, ModifyLogGroups(bstrSettings.raw()), RTEXITCODE_FAILURE);
+ else if (!strcmp(pszSubCmd, "logdest"))
+ CHECK_ERROR2I_RET(pDebugger, ModifyLogDestinations(bstrSettings.raw()), RTEXITCODE_FAILURE);
+ else if (!strcmp(pszSubCmd, "logflags"))
+ CHECK_ERROR2I_RET(pDebugger, ModifyLogFlags(bstrSettings.raw()), RTEXITCODE_FAILURE);
+ else
+ AssertFailedReturn(RTEXITCODE_FAILURE);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the inject sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_DumpVMCore(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments.
+ */
+ const char *pszFilename = NULL;
+ const char *pszCompression = NULL;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--filename", 'f', RTGETOPT_REQ_STRING },
+ { "--compression", 'c', RTGETOPT_REQ_STRING }
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'c':
+ if (pszCompression)
+ return errorSyntax(DebugVM::tr("The --compression option has already been given"));
+ pszCompression = ValueUnion.psz;
+ break;
+ case 'f':
+ if (pszFilename)
+ return errorSyntax(DebugVM::tr("The --filename option has already been given"));
+ pszFilename = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!pszFilename)
+ return errorSyntax(DebugVM::tr("The --filename option is required"));
+
+ /*
+ * Make the filename absolute before handing it on to the API.
+ */
+ char szAbsFilename[RTPATH_MAX];
+ vrc = RTPathAbs(pszFilename, szAbsFilename, sizeof(szAbsFilename));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, DebugVM::tr("RTPathAbs failed on '%s': %Rrc"), pszFilename, vrc);
+
+ com::Bstr bstrFilename(szAbsFilename);
+ com::Bstr bstrCompression(pszCompression);
+ CHECK_ERROR2I_RET(pDebugger, DumpGuestCore(bstrFilename.raw(), bstrCompression.raw()), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the osdetect sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param a The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_OSDetect(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+ if (a->argc != 2)
+ return errorTooManyParameters(&a->argv[1]);
+
+ com::Bstr bstrIgnore;
+ com::Bstr bstrAll("all");
+ CHECK_ERROR2I_RET(pDebugger, LoadPlugIn(bstrAll.raw(), bstrIgnore.asOutParam()), RTEXITCODE_FAILURE);
+
+ com::Bstr bstrName;
+ CHECK_ERROR2I_RET(pDebugger, DetectOS(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf(DebugVM::tr("Detected: %ls\n"), bstrName.raw());
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the osinfo sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param a The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_OSInfo(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+ if (a->argc != 2)
+ return errorTooManyParameters(&a->argv[1]);
+
+ com::Bstr bstrName;
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(OSName)(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+ com::Bstr bstrVersion;
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(OSVersion)(bstrVersion.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf(DebugVM::tr("Name: %ls\n"), bstrName.raw());
+ RTPrintf(DebugVM::tr("Version: %ls\n"), bstrVersion.raw());
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the osdmsg sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_OSDmesg(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse argument.
+ */
+ uint32_t uMaxMessages = 0;
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--lines", 'n', RTGETOPT_REQ_UINT32 },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ switch (vrc)
+ {
+ case 'n': uMaxMessages = ValueUnion.u32; break;
+ default: return errorGetOpt(vrc, &ValueUnion);
+ }
+
+ /*
+ * Do it.
+ */
+ com::Bstr bstrDmesg;
+ CHECK_ERROR2I_RET(pDebugger, QueryOSKernelLog(uMaxMessages, bstrDmesg.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf("%ls\n", bstrDmesg.raw());
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the setregisters sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_SetRegisters(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * We take a list of register assignments, that is register=value.
+ */
+ ULONG idCpu = 0;
+ com::SafeArray<IN_BSTR> aBstrNames;
+ com::SafeArray<IN_BSTR> aBstrValues;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--cpu", 'c', RTGETOPT_REQ_UINT32 },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'c':
+ idCpu = ValueUnion.u32;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ const char *pszEqual = strchr(ValueUnion.psz, '=');
+ if (!pszEqual)
+ return errorSyntax(DebugVM::tr("setregisters expects input on the form 'register=value' got '%s'"),
+ ValueUnion.psz);
+ try
+ {
+ com::Bstr bstrName(ValueUnion.psz, pszEqual - ValueUnion.psz);
+ com::Bstr bstrValue(pszEqual + 1);
+ if ( !aBstrNames.push_back(bstrName.raw())
+ || !aBstrValues.push_back(bstrValue.raw()))
+ throw std::bad_alloc();
+ }
+ catch (std::bad_alloc &)
+ {
+ RTMsgError(DebugVM::tr("Out of memory\n"));
+ return RTEXITCODE_FAILURE;
+ }
+ break;
+ }
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!aBstrNames.size())
+ return errorSyntax(DebugVM::tr("The setregisters sub-command takes at least one register name"));
+
+ /*
+ * If it is only one register, use the single register method just so
+ * we expose it and can test it from the command line.
+ */
+ if (aBstrNames.size() == 1)
+ {
+ CHECK_ERROR2I_RET(pDebugger, SetRegister(idCpu, aBstrNames[0], aBstrValues[0]), RTEXITCODE_FAILURE);
+ RTPrintf(DebugVM::tr("Successfully set %ls\n"), aBstrNames[0]);
+ }
+ else
+ {
+ CHECK_ERROR2I_RET(pDebugger, SetRegisters(idCpu, ComSafeArrayAsInParam(aBstrNames), ComSafeArrayAsInParam(aBstrValues)),
+ RTEXITCODE_FAILURE);
+ RTPrintf(DebugVM::tr("Successfully set %u registers\n", "", aBstrNames.size()), aBstrNames.size());
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/** @name debugvm show flags
+ * @{ */
+#define DEBUGVM_SHOW_FLAGS_HUMAN_READABLE UINT32_C(0x00000000)
+#define DEBUGVM_SHOW_FLAGS_SH_EXPORT UINT32_C(0x00000001)
+#define DEBUGVM_SHOW_FLAGS_SH_EVAL UINT32_C(0x00000002)
+#define DEBUGVM_SHOW_FLAGS_CMD_SET UINT32_C(0x00000003)
+#define DEBUGVM_SHOW_FLAGS_FMT_MASK UINT32_C(0x00000003)
+/** @} */
+
+/**
+ * Prints a variable according to the @a fFlags.
+ *
+ * @param pszVar The variable name.
+ * @param pbstrValue The variable value.
+ * @param fFlags The debugvm show flags.
+ */
+static void handleDebugVM_Show_PrintVar(const char *pszVar, com::Bstr const *pbstrValue, uint32_t fFlags)
+{
+ switch (fFlags & DEBUGVM_SHOW_FLAGS_FMT_MASK)
+ {
+ case DEBUGVM_SHOW_FLAGS_HUMAN_READABLE: RTPrintf(" %27s=%ls\n", pszVar, pbstrValue->raw()); break;
+ case DEBUGVM_SHOW_FLAGS_SH_EXPORT: RTPrintf(DebugVM::tr("export %s='%ls'\n"), pszVar, pbstrValue->raw()); break;
+ case DEBUGVM_SHOW_FLAGS_SH_EVAL: RTPrintf("%s='%ls'\n", pszVar, pbstrValue->raw()); break;
+ case DEBUGVM_SHOW_FLAGS_CMD_SET: RTPrintf(DebugVM::tr("set %s=%ls\n"), pszVar, pbstrValue->raw()); break;
+ default: AssertFailed();
+ }
+}
+
+/**
+ * Handles logdbg-settings.
+ *
+ * @returns Exit code.
+ * @param pDebugger The debugger interface.
+ * @param fFlags The debugvm show flags.
+ */
+static RTEXITCODE handleDebugVM_Show_LogDbgSettings(IMachineDebugger *pDebugger, uint32_t fFlags)
+{
+ if ((fFlags & DEBUGVM_SHOW_FLAGS_FMT_MASK) == DEBUGVM_SHOW_FLAGS_HUMAN_READABLE)
+ RTPrintf(DebugVM::tr("Debug logger settings:\n"));
+
+ com::Bstr bstr;
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogDbgGroups)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_LOG", &bstr, fFlags);
+
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogDbgFlags)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_LOG_FLAGS", &bstr, fFlags);
+
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogDbgDestinations)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_LOG_DEST", &bstr, fFlags);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles logrel-settings.
+ *
+ * @returns Exit code.
+ * @param pDebugger The debugger interface.
+ * @param fFlags The debugvm show flags.
+ */
+static RTEXITCODE handleDebugVM_Show_LogRelSettings(IMachineDebugger *pDebugger, uint32_t fFlags)
+{
+ if ((fFlags & DEBUGVM_SHOW_FLAGS_FMT_MASK) == DEBUGVM_SHOW_FLAGS_HUMAN_READABLE)
+ RTPrintf(DebugVM::tr("Release logger settings:\n"));
+
+ com::Bstr bstr;
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogRelGroups)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_RELEASE_LOG", &bstr, fFlags);
+
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogRelFlags)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_RELEASE_LOG_FLAGS", &bstr, fFlags);
+
+ CHECK_ERROR2I_RET(pDebugger, COMGETTER(LogRelDestinations)(bstr.asOutParam()), RTEXITCODE_FAILURE);
+ handleDebugVM_Show_PrintVar("VBOX_RELEASE_LOG_DEST", &bstr, fFlags);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the show sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_Show(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments and what to show. Order dependent.
+ */
+ uint32_t fFlags = DEBUGVM_SHOW_FLAGS_HUMAN_READABLE;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--human-readable", 'H', RTGETOPT_REQ_NOTHING },
+ { "--sh-export", 'e', RTGETOPT_REQ_NOTHING },
+ { "--sh-eval", 'E', RTGETOPT_REQ_NOTHING },
+ { "--cmd-set", 's', RTGETOPT_REQ_NOTHING },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'H':
+ fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_HUMAN_READABLE;
+ break;
+
+ case 'e':
+ fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_SH_EXPORT;
+ break;
+
+ case 'E':
+ fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_SH_EVAL;
+ break;
+
+ case 's':
+ fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_CMD_SET;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ RTEXITCODE rcExit;
+ if (!strcmp(ValueUnion.psz, "log-settings"))
+ {
+ rcExit = handleDebugVM_Show_LogDbgSettings(pDebugger, fFlags);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ rcExit = handleDebugVM_Show_LogRelSettings(pDebugger, fFlags);
+ }
+ else if (!strcmp(ValueUnion.psz, "logdbg-settings"))
+ rcExit = handleDebugVM_Show_LogDbgSettings(pDebugger, fFlags);
+ else if (!strcmp(ValueUnion.psz, "logrel-settings"))
+ rcExit = handleDebugVM_Show_LogRelSettings(pDebugger, fFlags);
+ else
+ rcExit = errorSyntax(DebugVM::tr("The show sub-command has no idea what '%s' might be"), ValueUnion.psz);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ break;
+ }
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the stack sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_Stack(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments.
+ */
+ VMCPUID idCpu = VMCPUID_ALL;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--cpu", 'c', RTGETOPT_REQ_UINT32 },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'c':
+ idCpu = ValueUnion.u32;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Dump stack.
+ */
+ com::Bstr bstrGuestStack;
+ if (idCpu != VMCPUID_ALL)
+ {
+ /* Single CPU */
+ CHECK_ERROR2I_RET(pDebugger, DumpGuestStack(idCpu, bstrGuestStack.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf("%ls\n", bstrGuestStack.raw());
+ }
+ else
+ {
+ /* All CPUs. */
+ ComPtr<IMachine> ptrMachine;
+ CHECK_ERROR2I_RET(pArgs->session, COMGETTER(Machine)(ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+ ULONG cCpus;
+ CHECK_ERROR2I_RET(ptrMachine, COMGETTER(CPUCount)(&cCpus), RTEXITCODE_FAILURE);
+
+ for (idCpu = 0; idCpu < (VMCPUID)cCpus; idCpu++)
+ {
+ CHECK_ERROR2I_RET(pDebugger, DumpGuestStack(idCpu, bstrGuestStack.asOutParam()), RTEXITCODE_FAILURE);
+ if (cCpus > 1)
+ {
+ if (idCpu > 0)
+ RTPrintf("\n");
+ RTPrintf(DebugVM::tr("====================== CPU #%u ======================\n"), idCpu);
+ }
+ RTPrintf("%ls\n", bstrGuestStack.raw());
+ }
+ }
+
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the statistics sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_Statistics(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments.
+ */
+ bool fWithDescriptions = false;
+ const char *pszPattern = NULL; /* all */
+ bool fReset = false;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--descriptions", 'd', RTGETOPT_REQ_NOTHING },
+ { "--pattern", 'p', RTGETOPT_REQ_STRING },
+ { "--reset", 'r', RTGETOPT_REQ_NOTHING },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'd':
+ fWithDescriptions = true;
+ break;
+
+ case 'p':
+ if (pszPattern)
+ return errorSyntax(DebugVM::tr("Multiple --pattern options are not permitted"));
+ pszPattern = ValueUnion.psz;
+ break;
+
+ case 'r':
+ fReset = true;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (fReset && fWithDescriptions)
+ return errorSyntax(DebugVM::tr("The --reset and --descriptions options does not mix"));
+
+ /*
+ * Execute the order.
+ */
+ com::Bstr bstrPattern(pszPattern);
+ if (fReset)
+ CHECK_ERROR2I_RET(pDebugger, ResetStats(bstrPattern.raw()), RTEXITCODE_FAILURE);
+ else
+ {
+ com::Bstr bstrStats;
+ CHECK_ERROR2I_RET(pDebugger, GetStats(bstrPattern.raw(), fWithDescriptions, bstrStats.asOutParam()),
+ RTEXITCODE_FAILURE);
+ /* if (fFormatted)
+ { big mess }
+ else
+ */
+ RTPrintf("%ls\n", bstrStats.raw());
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the guestsample sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param pArgs The handler arguments.
+ * @param pDebugger Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_GuestSample(HandlerArg *pArgs, IMachineDebugger *pDebugger)
+{
+ /*
+ * Parse arguments.
+ */
+ const char *pszFilename = NULL;
+ uint32_t cSampleIntervalUs = 1000;
+ uint64_t cSampleTimeUs = 1000*1000;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--filename", 'f', RTGETOPT_REQ_STRING },
+ { "--sample-interval-us", 'i', RTGETOPT_REQ_UINT32 },
+ { "--sample-time-us", 't', RTGETOPT_REQ_UINT64 },
+ };
+ int vrc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 'f':
+ pszFilename = ValueUnion.psz;
+ break;
+ case 'i':
+ cSampleIntervalUs = ValueUnion.u32;
+ break;
+ case 't':
+ cSampleTimeUs = ValueUnion.u64;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ if (!pszFilename)
+ return errorSyntax(DebugVM::tr("The --filename is missing"));
+
+ /*
+ * Execute the order.
+ */
+ ComPtr<IProgress> ptrProgress;
+ com::Bstr bstrFilename(pszFilename);
+ CHECK_ERROR2I_RET(pDebugger, TakeGuestSample(bstrFilename.raw(), cSampleIntervalUs, cSampleTimeUs, ptrProgress.asOutParam()), RTEXITCODE_FAILURE);
+ showProgress(ptrProgress);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+RTEXITCODE handleDebugVM(HandlerArg *pArgs)
+{
+ RTEXITCODE rcExit = RTEXITCODE_FAILURE;
+
+ /*
+ * The first argument is the VM name or UUID. Open a session to it.
+ */
+ if (pArgs->argc < 2)
+ return errorNoSubcommand();
+ ComPtr<IMachine> ptrMachine;
+ CHECK_ERROR2I_RET(pArgs->virtualBox, FindMachine(com::Bstr(pArgs->argv[0]).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2I_RET(ptrMachine, LockMachine(pArgs->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /*
+ * Get the associated console and machine debugger.
+ */
+ HRESULT hrc;
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR2(hrc, pArgs->session, COMGETTER(Console)(ptrConsole.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ if (ptrConsole.isNotNull())
+ {
+ ComPtr<IMachineDebugger> ptrDebugger;
+ CHECK_ERROR2(hrc, ptrConsole, COMGETTER(Debugger)(ptrDebugger.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ /*
+ * String switch on the sub-command.
+ */
+ const char *pszSubCmd = pArgs->argv[1];
+ if (!strcmp(pszSubCmd, "dumpvmcore"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_DUMPVMCORE);
+ rcExit = handleDebugVM_DumpVMCore(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "getregisters"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_GETREGISTERS);
+ rcExit = handleDebugVM_GetRegisters(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "info"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_INFO);
+ rcExit = handleDebugVM_Info(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "injectnmi"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_INJECTNMI);
+ rcExit = handleDebugVM_InjectNMI(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "log"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_LOG);
+ rcExit = handleDebugVM_LogXXXX(pArgs, ptrDebugger, pszSubCmd);
+ }
+ else if (!strcmp(pszSubCmd, "logdest"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_LOGDEST);
+ rcExit = handleDebugVM_LogXXXX(pArgs, ptrDebugger, pszSubCmd);
+ }
+ else if (!strcmp(pszSubCmd, "logflags"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_LOGFLAGS);
+ rcExit = handleDebugVM_LogXXXX(pArgs, ptrDebugger, pszSubCmd);
+ }
+ else if (!strcmp(pszSubCmd, "osdetect"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_OSDETECT);
+ rcExit = handleDebugVM_OSDetect(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "osinfo"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_OSINFO);
+ rcExit = handleDebugVM_OSInfo(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "osdmesg"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_OSDMESG);
+ rcExit = handleDebugVM_OSDmesg(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "setregisters"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_SETREGISTERS);
+ rcExit = handleDebugVM_SetRegisters(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "show"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_SHOW);
+ rcExit = handleDebugVM_Show(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "stack"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_STACK);
+ rcExit = handleDebugVM_Stack(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "statistics"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_STATISTICS);
+ rcExit = handleDebugVM_Statistics(pArgs, ptrDebugger);
+ }
+ else if (!strcmp(pszSubCmd, "guestsample"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_DEBUGVM_GUESTSAMPLE);
+ rcExit = handleDebugVM_GuestSample(pArgs, ptrDebugger);
+ }
+ else
+ errorUnknownSubcommand(pszSubCmd);
+ }
+ }
+ else
+ RTMsgError(DebugVM::tr("Machine '%s' is not currently running.\n"), pArgs->argv[0]);
+ }
+
+ pArgs->session->UnlockMachine();
+
+ return rcExit;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
new file mode 100644
index 00000000..1e2d8845
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
@@ -0,0 +1,2753 @@
+/* $Id: VBoxManageDisk.cpp $ */
+/** @file
+ * VBoxManage - The disk/medium related commands.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/asm.h>
+#include <iprt/base64.h>
+#include <iprt/file.h>
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#include <iprt/getopt.h>
+#include <VBox/log.h>
+#include <VBox/vd.h>
+
+#include <list>
+
+#include "VBoxManage.h"
+using namespace com;
+
+/** Medium category. */
+typedef enum MEDIUMCATEGORY
+{
+ MEDIUMCATEGORY_NONE = 0,
+ MEDIUMCATEGORY_DISK,
+ MEDIUMCATEGORY_DVD,
+ MEDIUMCATEGORY_FLOPPY
+} MEDIUMCATEGORY;
+
+DECLARE_TRANSLATION_CONTEXT(Disk);
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+
+static DECLCALLBACK(void) handleVDError(void *pvUser, int vrc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+ RT_NOREF(pvUser);
+ RTMsgErrorV(pszFormat, va);
+ RTMsgError(Disk::tr("Error code %Rrc at %s(%u) in function %s"), vrc, RT_SRC_POS_ARGS);
+}
+
+static int parseMediumVariant(const char *psz, MediumVariant_T *pMediumVariant)
+{
+ int vrc = VINF_SUCCESS;
+ unsigned uMediumVariant = (unsigned)(*pMediumVariant);
+ while (psz && *psz && RT_SUCCESS(vrc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ // Parsing is intentionally inconsistent: "standard" resets the
+ // variant, whereas the other flags are cumulative.
+ if (!RTStrNICmp(psz, "standard", len))
+ uMediumVariant = MediumVariant_Standard;
+ else if ( !RTStrNICmp(psz, "fixed", len)
+ || !RTStrNICmp(psz, "static", len))
+ uMediumVariant |= MediumVariant_Fixed;
+ else if (!RTStrNICmp(psz, "Diff", len))
+ uMediumVariant |= MediumVariant_Diff;
+ else if (!RTStrNICmp(psz, "split2g", len))
+ uMediumVariant |= MediumVariant_VmdkSplit2G;
+ else if ( !RTStrNICmp(psz, "stream", len)
+ || !RTStrNICmp(psz, "streamoptimized", len))
+ uMediumVariant |= MediumVariant_VmdkStreamOptimized;
+ else if (!RTStrNICmp(psz, "esx", len))
+ uMediumVariant |= MediumVariant_VmdkESX;
+ else if (!RTStrNICmp(psz, "formatted", len))
+ uMediumVariant |= MediumVariant_Formatted;
+ else if ( !RTStrNICmp(psz, "raw", len)
+ || !RTStrNICmp(psz, "rawdisk", len))
+ uMediumVariant |= MediumVariant_VmdkRawDisk;
+ else
+ vrc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ if (RT_SUCCESS(vrc))
+ *pMediumVariant = (MediumVariant_T)uMediumVariant;
+ return vrc;
+}
+
+int parseMediumType(const char *psz, MediumType_T *penmMediumType)
+{
+ int vrc = VINF_SUCCESS;
+ MediumType_T enmMediumType = MediumType_Normal;
+ if (!RTStrICmp(psz, "normal"))
+ enmMediumType = MediumType_Normal;
+ else if (!RTStrICmp(psz, "immutable"))
+ enmMediumType = MediumType_Immutable;
+ else if (!RTStrICmp(psz, "writethrough"))
+ enmMediumType = MediumType_Writethrough;
+ else if (!RTStrICmp(psz, "shareable"))
+ enmMediumType = MediumType_Shareable;
+ else if (!RTStrICmp(psz, "readonly"))
+ enmMediumType = MediumType_Readonly;
+ else if (!RTStrICmp(psz, "multiattach"))
+ enmMediumType = MediumType_MultiAttach;
+ else
+ vrc = VERR_PARSE_ERROR;
+
+ if (RT_SUCCESS(vrc))
+ *penmMediumType = enmMediumType;
+ return vrc;
+}
+
+/** @todo move this into getopt, as getting bool values is generic */
+int parseBool(const char *psz, bool *pb)
+{
+ int vrc = VINF_SUCCESS;
+ if ( !RTStrICmp(psz, "on")
+ || !RTStrICmp(psz, "yes")
+ || !RTStrICmp(psz, "true")
+ || !RTStrCmp(psz, "1")
+ || !RTStrICmp(psz, "enable")
+ || !RTStrICmp(psz, "enabled"))
+ *pb = true;
+ else if ( !RTStrICmp(psz, "off")
+ || !RTStrICmp(psz, "no")
+ || !RTStrICmp(psz, "false")
+ || !RTStrCmp(psz, "0")
+ || !RTStrICmp(psz, "disable")
+ || !RTStrICmp(psz, "disabled"))
+ *pb = false;
+ else
+ vrc = VERR_PARSE_ERROR;
+
+ return vrc;
+}
+
+HRESULT openMedium(HandlerArg *a, const char *pszFilenameOrUuid,
+ DeviceType_T enmDevType, AccessMode_T enmAccessMode,
+ ComPtr<IMedium> &pMedium, bool fForceNewUuidOnOpen,
+ bool fSilent)
+{
+ HRESULT hrc;
+ Guid id(pszFilenameOrUuid);
+ char szFilenameAbs[RTPATH_MAX] = "";
+
+ /* If it is no UUID, convert the filename to an absolute one. */
+ if (!id.isValid())
+ {
+ int irc = RTPathAbs(pszFilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
+ if (RT_FAILURE(irc))
+ {
+ if (!fSilent)
+ RTMsgError(Disk::tr("Cannot convert filename \"%s\" to absolute path"), pszFilenameOrUuid);
+ return E_FAIL;
+ }
+ pszFilenameOrUuid = szFilenameAbs;
+ }
+
+ if (!fSilent)
+ CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
+ enmDevType,
+ enmAccessMode,
+ fForceNewUuidOnOpen,
+ pMedium.asOutParam()));
+ else
+ hrc = a->virtualBox->OpenMedium(Bstr(pszFilenameOrUuid).raw(),
+ enmDevType,
+ enmAccessMode,
+ fForceNewUuidOnOpen,
+ pMedium.asOutParam());
+
+ return hrc;
+}
+
+static HRESULT createMedium(HandlerArg *a, const char *pszFormat,
+ const char *pszFilename, DeviceType_T enmDevType,
+ AccessMode_T enmAccessMode, ComPtr<IMedium> &pMedium)
+{
+ HRESULT hrc;
+ char szFilenameAbs[RTPATH_MAX] = "";
+
+ /** @todo laziness shortcut. should really check the MediumFormatCapabilities */
+ if (RTStrICmp(pszFormat, "iSCSI"))
+ {
+ int irc = RTPathAbs(pszFilename, szFilenameAbs, sizeof(szFilenameAbs));
+ if (RT_FAILURE(irc))
+ {
+ RTMsgError(Disk::tr("Cannot convert filename \"%s\" to absolute path"), pszFilename);
+ return E_FAIL;
+ }
+ pszFilename = szFilenameAbs;
+ }
+
+ CHECK_ERROR(a->virtualBox, CreateMedium(Bstr(pszFormat).raw(),
+ Bstr(pszFilename).raw(),
+ enmAccessMode,
+ enmDevType,
+ pMedium.asOutParam()));
+ return hrc;
+}
+
+static const RTGETOPTDEF g_aCreateMediumOptions[] =
+{
+ { "disk", 'H', RTGETOPT_REQ_NOTHING },
+ { "dvd", 'D', RTGETOPT_REQ_NOTHING },
+ { "floppy", 'L', RTGETOPT_REQ_NOTHING },
+ { "--filename", 'f', RTGETOPT_REQ_STRING },
+ { "-filename", 'f', RTGETOPT_REQ_STRING }, // deprecated
+ { "--diffparent", 'd', RTGETOPT_REQ_STRING },
+ { "--size", 's', RTGETOPT_REQ_UINT64 },
+ { "-size", 's', RTGETOPT_REQ_UINT64 }, // deprecated
+ { "--sizebyte", 'S', RTGETOPT_REQ_UINT64 },
+ { "--format", 'o', RTGETOPT_REQ_STRING },
+ { "-format", 'o', RTGETOPT_REQ_STRING }, // deprecated
+ { "--static", 'F', RTGETOPT_REQ_NOTHING },
+ { "-static", 'F', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--variant", 'm', RTGETOPT_REQ_STRING },
+ { "-variant", 'm', RTGETOPT_REQ_STRING }, // deprecated
+ { "--property", 'p', RTGETOPT_REQ_STRING },
+ { "--property-file",'P', RTGETOPT_REQ_STRING },
+};
+
+class MediumProperty
+{
+public:
+ const char *m_pszKey;
+ const char *m_pszValue; /**< Can be binary too. */
+ size_t m_cbValue;
+ char *m_pszFreeValue;
+ MediumProperty() : m_pszKey(NULL), m_pszValue(NULL), m_cbValue(0), m_pszFreeValue(NULL) { }
+ MediumProperty(MediumProperty const &a_rThat)
+ : m_pszKey(a_rThat.m_pszKey)
+ , m_pszValue(a_rThat.m_pszValue)
+ , m_cbValue(a_rThat.m_cbValue)
+ , m_pszFreeValue(NULL)
+ {
+ Assert(a_rThat.m_pszFreeValue == NULL); /* not expected here! */
+ }
+ ~MediumProperty()
+ {
+ RTMemFree(m_pszFreeValue);
+ m_pszFreeValue = NULL;
+ }
+
+private:
+ MediumProperty &operator=(MediumProperty const &a_rThat)
+ {
+ m_pszKey = a_rThat.m_pszKey;
+ m_pszValue = a_rThat.m_pszValue;
+ m_cbValue = a_rThat.m_cbValue;
+ m_pszFreeValue = a_rThat.m_pszFreeValue;
+ if (a_rThat.m_pszFreeValue != NULL)
+ {
+ m_pszFreeValue = (char *)RTMemDup(m_pszValue, m_cbValue + 1);
+ if (!m_pszFreeValue)
+ {
+ RTMsgError(Disk::tr("Out of memory copying '%s'"), m_pszValue);
+ throw std::bad_alloc();
+ }
+ }
+ return *this;
+ }
+};
+
+RTEXITCODE handleCreateMedium(HandlerArg *a)
+{
+ std::list<MediumProperty> lstProperties;
+
+ HRESULT hrc;
+ int vrc;
+ const char *filename = NULL;
+ const char *diffparent = NULL;
+ uint64_t size = 0;
+ enum
+ {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ const char *format = NULL;
+ bool fBase = true;
+ MediumVariant_T enmMediumVariant = MediumVariant_Standard;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateMediumOptions, RT_ELEMENTS(g_aCreateMediumOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'H': // disk
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DISK;
+ break;
+
+ case 'D': // DVD
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DVD;
+ break;
+
+ case 'L': // floppy
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_FLOPPY;
+ break;
+
+ case 'f': // --filename
+ filename = ValueUnion.psz;
+ break;
+
+ case 'd': // --diffparent
+ diffparent = ValueUnion.psz;
+ fBase = false;
+ break;
+
+ case 's': // --size
+ size = ValueUnion.u64 * _1M;
+ break;
+
+ case 'S': // --sizebyte
+ size = ValueUnion.u64;
+ break;
+
+ case 'o': // --format
+ format = ValueUnion.psz;
+ break;
+
+ case 'p': // --property
+ case 'P': // --property-file
+ {
+ /* allocate property kvp, parse, and append to end of singly linked list */
+ char *pszValue = (char *)strchr(ValueUnion.psz, '=');
+ if (!pszValue)
+ return RTMsgErrorExitFailure(Disk::tr("Invalid key value pair: No '='."));
+
+ lstProperties.push_back(MediumProperty());
+ MediumProperty &rNewProp = lstProperties.back();
+ *pszValue++ = '\0'; /* Warning! Modifies argument string. */
+ rNewProp.m_pszKey = ValueUnion.psz;
+ if (c == 'p')
+ {
+ rNewProp.m_pszValue = pszValue;
+ rNewProp.m_cbValue = strlen(pszValue);
+ }
+ else // 'P'
+ {
+ RTFILE hValueFile = NIL_RTFILE;
+ vrc = RTFileOpen(&hValueFile, pszValue, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Disk::tr("Cannot open replacement value file '%s': %Rrc"), pszValue, vrc);
+
+ uint64_t cbValue = 0;
+ vrc = RTFileQuerySize(hValueFile, &cbValue);
+ if (RT_SUCCESS(vrc))
+ {
+ if (cbValue <= _16M)
+ {
+ rNewProp.m_cbValue = (size_t)cbValue;
+ rNewProp.m_pszValue = rNewProp.m_pszFreeValue = (char *)RTMemAlloc(rNewProp.m_cbValue + 1);
+ if (rNewProp.m_pszFreeValue)
+ {
+ vrc = RTFileReadAt(hValueFile, 0, rNewProp.m_pszFreeValue, cbValue, NULL);
+ if (RT_SUCCESS(vrc))
+ rNewProp.m_pszFreeValue[rNewProp.m_cbValue] = '\0';
+ else
+ RTMsgError(Disk::tr("Error reading replacement MBR file '%s': %Rrc"), pszValue, vrc);
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_NO_MEMORY, Disk::tr("Out of memory reading '%s': %Rrc"), pszValue, vrc);
+ }
+ else
+ vrc = RTMsgErrorRc(VERR_OUT_OF_RANGE,
+ Disk::tr("Replacement value file '%s' is to big: %Rhcb, max 16MiB"),
+ pszValue, cbValue);
+ }
+ else
+ RTMsgError(Disk::tr("Cannot get the size of the value file '%s': %Rrc"), pszValue, vrc);
+ RTFileClose(hValueFile);
+ if (RT_FAILURE(vrc))
+ return RTEXITCODE_FAILURE;
+ }
+ break;
+ }
+
+ case 'F': // --static ("fixed"/"flat")
+ {
+ unsigned uMediumVariant = (unsigned)enmMediumVariant;
+ uMediumVariant |= MediumVariant_Fixed;
+ enmMediumVariant = (MediumVariant_T)uMediumVariant;
+ break;
+ }
+
+ case 'm': // --variant
+ vrc = parseMediumVariant(ValueUnion.psz, &enmMediumVariant);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid medium variant '%s'"), ValueUnion.psz);
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Disk::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Disk::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ /* check the outcome */
+ if (cmd == CMD_NONE)
+ cmd = CMD_DISK;
+ ComPtr<IMedium> pParentMedium;
+ if (fBase)
+ {
+ if (!filename || !*filename)
+ return errorSyntax(Disk::tr("Parameter --filename is required"));
+ if ((enmMediumVariant & MediumVariant_VmdkRawDisk) == 0 && size == 0)
+ return errorSyntax(Disk::tr("Parameter --size is required"));
+ if (!format || !*format)
+ {
+ if (cmd == CMD_DISK)
+ format = "VDI";
+ else if (cmd == CMD_DVD || cmd == CMD_FLOPPY)
+ {
+ format = "RAW";
+ unsigned uMediumVariant = (unsigned)enmMediumVariant;
+ uMediumVariant |= MediumVariant_Fixed;
+ enmMediumVariant = (MediumVariant_T)uMediumVariant;
+ }
+ }
+ if ((enmMediumVariant & MediumVariant_VmdkRawDisk) && strcmp(format, "VMDK"))
+ return errorSyntax(Disk::tr("Variant 'Rawdisk' requires '--format=VMDK'"));
+ }
+ else
+ {
+ if ( !filename
+ || !*filename)
+ return errorSyntax(Disk::tr("Parameter --filename is required"));
+ size = 0;
+ if (cmd != CMD_DISK)
+ return errorSyntax(Disk::tr("Creating a differencing medium is only supported for hard disks"));
+ enmMediumVariant = MediumVariant_Diff;
+ if (!format || !*format)
+ {
+ const char *pszExt = RTPathSuffix(filename);
+ /* Skip over . if there is an extension. */
+ if (pszExt)
+ pszExt++;
+ if (!pszExt || !*pszExt)
+ format = "VDI";
+ else
+ format = pszExt;
+ }
+ hrc = openMedium(a, diffparent, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pParentMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (pParentMedium.isNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Disk::tr("Invalid parent hard disk reference, avoiding crash"));
+ MediumState_T state;
+ CHECK_ERROR(pParentMedium, COMGETTER(State)(&state));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (state == MediumState_Inaccessible)
+ {
+ CHECK_ERROR(pParentMedium, RefreshState(&state));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ }
+ }
+ /* check for filename extension */
+ /** @todo use IMediumFormat to cover all extensions generically */
+ Utf8Str strName(filename);
+ if (!RTPathHasSuffix(strName.c_str()))
+ {
+ Utf8Str strFormat(format);
+ if (cmd == CMD_DISK)
+ {
+ if (strFormat.compare("vmdk", RTCString::CaseInsensitive) == 0)
+ strName.append(".vmdk");
+ else if (strFormat.compare("vhd", RTCString::CaseInsensitive) == 0)
+ strName.append(".vhd");
+ else
+ strName.append(".vdi");
+ }
+ else if (cmd == CMD_DVD)
+ strName.append(".iso");
+ else if (cmd == CMD_FLOPPY)
+ strName.append(".img");
+ filename = strName.c_str();
+ }
+
+ ComPtr<IMedium> pMedium;
+ if (cmd == CMD_DISK)
+ hrc = createMedium(a, format, filename, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pMedium);
+ else if (cmd == CMD_DVD)
+ hrc = createMedium(a, format, filename, DeviceType_DVD,
+ AccessMode_ReadOnly, pMedium);
+ else if (cmd == CMD_FLOPPY)
+ hrc = createMedium(a, format, filename, DeviceType_Floppy,
+ AccessMode_ReadWrite, pMedium);
+ else
+ hrc = E_INVALIDARG; /* cannot happen but make gcc happy */
+
+
+ if (SUCCEEDED(hrc) && pMedium)
+ {
+ if (lstProperties.size() > 0)
+ {
+ ComPtr<IMediumFormat> pMediumFormat;
+ CHECK_ERROR2I_RET(pMedium, COMGETTER(MediumFormat)(pMediumFormat.asOutParam()), RTEXITCODE_FAILURE);
+ com::SafeArray<BSTR> propertyNames;
+ com::SafeArray<BSTR> propertyDescriptions;
+ com::SafeArray<DataType_T> propertyTypes;
+ com::SafeArray<ULONG> propertyFlags;
+ com::SafeArray<BSTR> propertyDefaults;
+ CHECK_ERROR2I_RET(pMediumFormat,
+ DescribeProperties(ComSafeArrayAsOutParam(propertyNames),
+ ComSafeArrayAsOutParam(propertyDescriptions),
+ ComSafeArrayAsOutParam(propertyTypes),
+ ComSafeArrayAsOutParam(propertyFlags),
+ ComSafeArrayAsOutParam(propertyDefaults)),
+ RTEXITCODE_FAILURE);
+
+ for (std::list<MediumProperty>::iterator it = lstProperties.begin();
+ it != lstProperties.end();
+ ++it)
+ {
+ const char * const pszKey = it->m_pszKey;
+ bool fBinary = true;
+ bool fPropertyFound = false;
+ for (size_t i = 0; i < propertyNames.size(); ++i)
+ if (RTUtf16CmpUtf8(propertyNames[i], pszKey) == 0)
+ {
+ fBinary = propertyTypes[i] == DataType_Int8;
+ fPropertyFound = true;
+ break;
+ }
+ if (!fPropertyFound)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE,
+ Disk::tr("Property '%s' was not found in the list of medium properties for the requested medium format (%s)."),
+ pszKey, format);
+ if (!fBinary)
+ CHECK_ERROR2I_RET(pMedium, SetProperty(Bstr(pszKey).raw(), Bstr(it->m_pszValue).raw()),
+ RTEXITCODE_FAILURE);
+ else
+ {
+ com::Bstr bstrBase64Value;
+ hrc = bstrBase64Value.base64Encode(it->m_pszValue, it->m_cbValue);
+ if (FAILED(hrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Disk::tr("Base64 encoding of the property %s failed. (%Rhrc)"),
+ pszKey, hrc);
+ CHECK_ERROR2I_RET(pMedium, SetProperty(Bstr(pszKey).raw(), bstrBase64Value.raw()), RTEXITCODE_FAILURE);
+ }
+ }
+ }
+
+ ComPtr<IProgress> pProgress;
+ com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+ for (ULONG i = 0; i < l_variants.size(); ++i)
+ {
+ ULONG temp = enmMediumVariant;
+ temp &= 1<<i;
+ l_variants [i] = (MediumVariant_T)temp;
+ }
+
+ if (fBase)
+ CHECK_ERROR(pMedium, CreateBaseStorage(size, ComSafeArrayAsInParam(l_variants), pProgress.asOutParam()));
+ else
+ CHECK_ERROR(pParentMedium, CreateDiffStorage(pMedium, ComSafeArrayAsInParam(l_variants), pProgress.asOutParam()));
+ if (SUCCEEDED(hrc) && pProgress)
+ {
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR(pProgress, (Disk::tr("Failed to create medium")));
+ }
+ }
+
+ if (SUCCEEDED(hrc) && pMedium)
+ {
+ Bstr uuid;
+ CHECK_ERROR(pMedium, COMGETTER(Id)(uuid.asOutParam()));
+ RTPrintf(Disk::tr("Medium created. UUID: %s\n"), Utf8Str(uuid).c_str());
+
+ //CHECK_ERROR(pMedium, Close());
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aModifyMediumOptions[] =
+{
+ { "disk", 'H', RTGETOPT_REQ_NOTHING },
+ { "dvd", 'D', RTGETOPT_REQ_NOTHING },
+ { "floppy", 'L', RTGETOPT_REQ_NOTHING },
+ { "--type", 't', RTGETOPT_REQ_STRING },
+ { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
+ { "settype", 't', RTGETOPT_REQ_STRING }, // deprecated
+ { "--autoreset", 'z', RTGETOPT_REQ_STRING },
+ { "-autoreset", 'z', RTGETOPT_REQ_STRING }, // deprecated
+ { "autoreset", 'z', RTGETOPT_REQ_STRING }, // deprecated
+ { "--property", 'p', RTGETOPT_REQ_STRING },
+ { "--compact", 'c', RTGETOPT_REQ_NOTHING },
+ { "-compact", 'c', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "compact", 'c', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--resize", 'r', RTGETOPT_REQ_UINT64 },
+ { "--resizebyte", 'R', RTGETOPT_REQ_UINT64 },
+ { "--move", 'm', RTGETOPT_REQ_STRING },
+ { "--setlocation", 'l', RTGETOPT_REQ_STRING },
+ { "--description", 'd', RTGETOPT_REQ_STRING }
+};
+
+RTEXITCODE handleModifyMedium(HandlerArg *a)
+{
+ HRESULT hrc;
+ int vrc;
+ enum {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ ComPtr<IMedium> pMedium;
+ MediumType_T enmMediumType = MediumType_Normal; /* Shut up MSC */
+ bool AutoReset = false;
+ SafeArray<BSTR> mediumPropNames;
+ SafeArray<BSTR> mediumPropValues;
+ bool fModifyMediumType = false;
+ bool fModifyAutoReset = false;
+ bool fModifyProperties = false;
+ bool fModifyCompact = false;
+ bool fModifyResize = false;
+ bool fModifyResizeMB = false;
+ bool fMoveMedium = false;
+ bool fModifyDescription = false;
+ bool fSetNewLocation = false;
+ uint64_t cbResize = 0;
+ const char *pszFilenameOrUuid = NULL;
+ char *pszNewLocation = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aModifyMediumOptions, RT_ELEMENTS(g_aModifyMediumOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'H': // disk
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DISK;
+ break;
+
+ case 'D': // DVD
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DVD;
+ break;
+
+ case 'L': // floppy
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_FLOPPY;
+ break;
+
+ case 't': // --type
+ vrc = parseMediumType(ValueUnion.psz, &enmMediumType);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid medium type '%s'"), ValueUnion.psz);
+ fModifyMediumType = true;
+ break;
+
+ case 'z': // --autoreset
+ vrc = parseBool(ValueUnion.psz, &AutoReset);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid autoreset parameter '%s'"), ValueUnion.psz);
+ fModifyAutoReset = true;
+ break;
+
+ case 'p': // --property
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(ValueUnion.psz);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName(pszProperty);
+ Bstr bstrValue(&pDelimiter[1]);
+ bstrName.detachTo(mediumPropNames.appendedRaw());
+ bstrValue.detachTo(mediumPropValues.appendedRaw());
+ fModifyProperties = true;
+ }
+ else
+ {
+ errorArgument(Disk::tr("Invalid --property argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, Disk::tr("Error: Failed to allocate memory for medium property '%s'\n"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case 'c': // --compact
+ fModifyCompact = true;
+ break;
+
+ case 'r': // --resize
+ cbResize = ValueUnion.u64 * _1M;
+ fModifyResize = true;
+ fModifyResizeMB = true; // do sanity check!
+ break;
+
+ case 'R': // --resizebyte
+ cbResize = ValueUnion.u64;
+ fModifyResize = true;
+ break;
+
+ case 'm': // --move
+ /* Get a new location */
+ pszNewLocation = RTPathAbsDup(ValueUnion.psz);
+ fMoveMedium = true;
+ break;
+
+ case 'l': // --setlocation
+ /* Get a new location */
+ pszNewLocation = RTPathAbsDup(ValueUnion.psz);
+ fSetNewLocation = true;
+ break;
+
+ case 'd': // --description
+ /* Get a new description */
+ pszNewLocation = RTStrDup(ValueUnion.psz);
+ fModifyDescription = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszFilenameOrUuid)
+ pszFilenameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Disk::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Disk::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (cmd == CMD_NONE)
+ cmd = CMD_DISK;
+
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Disk::tr("Medium name or UUID required"));
+
+ if (!fModifyMediumType
+ && !fModifyAutoReset
+ && !fModifyProperties
+ && !fModifyCompact
+ && !fModifyResize
+ && !fMoveMedium
+ && !fSetNewLocation
+ && !fModifyDescription
+ )
+ return errorSyntax(Disk::tr("No operation specified"));
+
+ /* Always open the medium if necessary, there is no other way. */
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_DVD,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_Floppy,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else
+ hrc = E_INVALIDARG; /* cannot happen but make gcc happy */
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (pMedium.isNull())
+ {
+ RTMsgError(Disk::tr("Invalid medium reference, avoiding crash"));
+ return RTEXITCODE_FAILURE;
+ }
+
+ if ( fModifyResize
+ && fModifyResizeMB)
+ {
+ // Sanity check
+ //
+ // In general users should know what they do but in this case users have no
+ // alternative to VBoxManage. If happens that one wants to resize the disk
+ // and uses --resize and does not consider that this parameter expects the
+ // new medium size in MB not Byte. If the operation is started and then
+ // aborted by the user, the result is most likely a medium which doesn't
+ // work anymore.
+ MediumState_T state;
+ pMedium->RefreshState(&state);
+ LONG64 logicalSize;
+ pMedium->COMGETTER(LogicalSize)(&logicalSize);
+ if (cbResize > (uint64_t)logicalSize * 1000)
+ {
+ RTMsgError(Disk::tr("Error: Attempt to resize the medium from %RU64.%RU64 MB to %RU64.%RU64 MB. Use --resizebyte if this is intended!\n"),
+ logicalSize / _1M, (logicalSize % _1M) / (_1M / 10), cbResize / _1M, (cbResize % _1M) / (_1M / 10));
+ return RTEXITCODE_FAILURE;
+ }
+ }
+
+ if (fModifyMediumType)
+ {
+ MediumType_T enmCurrMediumType;
+ CHECK_ERROR(pMedium, COMGETTER(Type)(&enmCurrMediumType));
+
+ if (enmCurrMediumType != enmMediumType)
+ CHECK_ERROR(pMedium, COMSETTER(Type)(enmMediumType));
+ }
+
+ if (fModifyAutoReset)
+ {
+ CHECK_ERROR(pMedium, COMSETTER(AutoReset)(AutoReset));
+ }
+
+ if (fModifyProperties)
+ {
+ CHECK_ERROR(pMedium, SetProperties(ComSafeArrayAsInParam(mediumPropNames), ComSafeArrayAsInParam(mediumPropValues)));
+ }
+
+ if (fModifyCompact)
+ {
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR(pMedium, Compact(pProgress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ hrc = showProgress(pProgress);
+ if (FAILED(hrc))
+ {
+ if (hrc == E_NOTIMPL)
+ RTMsgError(Disk::tr("Compact medium operation is not implemented!"));
+ else if (hrc == VBOX_E_NOT_SUPPORTED)
+ RTMsgError(Disk::tr("Compact medium operation for this format is not implemented yet!"));
+ else if (!pProgress.isNull())
+ CHECK_PROGRESS_ERROR(pProgress, (Disk::tr("Failed to compact medium")));
+ else
+ RTMsgError(Disk::tr("Failed to compact medium!"));
+ }
+ }
+
+ if (fModifyResize)
+ {
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR(pMedium, Resize(cbResize, pProgress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ hrc = showProgress(pProgress);
+ if (FAILED(hrc))
+ {
+ if (!pProgress.isNull())
+ CHECK_PROGRESS_ERROR(pProgress, (Disk::tr("Failed to resize medium")));
+ else if (hrc == E_NOTIMPL)
+ RTMsgError(Disk::tr("Resize medium operation is not implemented!"));
+ else if (hrc == VBOX_E_NOT_SUPPORTED)
+ RTMsgError(Disk::tr("Resize medium operation for this format is not implemented yet!"));
+ else
+ RTMsgError(Disk::tr("Failed to resize medium!"));
+ }
+ }
+
+ if (fMoveMedium)
+ {
+ do
+ {
+ ComPtr<IProgress> pProgress;
+ Utf8Str strLocation(pszNewLocation);
+ RTStrFree(pszNewLocation);
+ CHECK_ERROR(pMedium, MoveTo(Bstr(strLocation).raw(), pProgress.asOutParam()));
+
+ if (SUCCEEDED(hrc) && !pProgress.isNull())
+ {
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR(pProgress, (Disk::tr("Failed to move medium")));
+ }
+
+ Bstr uuid;
+ CHECK_ERROR_BREAK(pMedium, COMGETTER(Id)(uuid.asOutParam()));
+
+ RTPrintf(Disk::tr("Move medium with UUID %s finished\n"), Utf8Str(uuid).c_str());
+ }
+ while (0);
+ }
+
+ if (fSetNewLocation)
+ {
+ Utf8Str strLocation(pszNewLocation);
+ RTStrFree(pszNewLocation);
+ CHECK_ERROR(pMedium, COMSETTER(Location)(Bstr(strLocation).raw()));
+
+ Bstr uuid;
+ CHECK_ERROR(pMedium, COMGETTER(Id)(uuid.asOutParam()));
+ RTPrintf(Disk::tr("Set new location of medium with UUID %s finished\n"), Utf8Str(uuid).c_str());
+ }
+
+ if (fModifyDescription)
+ {
+ CHECK_ERROR(pMedium, COMSETTER(Description)(Bstr(pszNewLocation).raw()));
+
+ RTPrintf(Disk::tr("Medium description has been changed.\n"));
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aCloneMediumOptions[] =
+{
+ { "disk", 'd', RTGETOPT_REQ_NOTHING },
+ { "dvd", 'D', RTGETOPT_REQ_NOTHING },
+ { "floppy", 'f', RTGETOPT_REQ_NOTHING },
+ { "--format", 'o', RTGETOPT_REQ_STRING },
+ { "-format", 'o', RTGETOPT_REQ_STRING },
+ { "--static", 'F', RTGETOPT_REQ_NOTHING },
+ { "-static", 'F', RTGETOPT_REQ_NOTHING },
+ { "--existing", 'E', RTGETOPT_REQ_NOTHING },
+ { "--variant", 'm', RTGETOPT_REQ_STRING },
+ { "-variant", 'm', RTGETOPT_REQ_STRING },
+ { "--resize", 'r', RTGETOPT_REQ_UINT64 },
+};
+
+RTEXITCODE handleCloneMedium(HandlerArg *a)
+{
+ HRESULT hrc;
+ int vrc;
+ enum {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ const char *pszSrc = NULL;
+ const char *pszDst = NULL;
+ Bstr format;
+ MediumVariant_T enmMediumVariant = MediumVariant_Standard;
+ bool fExisting = false;
+ bool fNeedResize = false;
+ uint64_t cbResize = 0;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneMediumOptions, RT_ELEMENTS(g_aCloneMediumOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'd': // disk
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DISK;
+ break;
+
+ case 'D': // DVD
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DVD;
+ break;
+
+ case 'f': // floppy
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_FLOPPY;
+ break;
+
+ case 'o': // --format
+ format = ValueUnion.psz;
+ break;
+
+ case 'F': // --static
+ {
+ unsigned uMediumVariant = (unsigned)enmMediumVariant;
+ uMediumVariant |= MediumVariant_Fixed;
+ enmMediumVariant = (MediumVariant_T)uMediumVariant;
+ break;
+ }
+
+ case 'E': // --existing
+ fExisting = true;
+ break;
+
+ case 'm': // --variant
+ vrc = parseMediumVariant(ValueUnion.psz, &enmMediumVariant);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid medium variant '%s'"), ValueUnion.psz);
+ break;
+
+ case 'r': // --resize
+ fNeedResize = true;
+ cbResize = ValueUnion.u64 * _1M;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszSrc)
+ pszSrc = ValueUnion.psz;
+ else if (!pszDst)
+ pszDst = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_GRAPH(c))
+ return errorSyntax(Disk::tr("unhandled option: -%c"), c);
+ else
+ return errorSyntax(Disk::tr("unhandled option: %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (cmd == CMD_NONE)
+ cmd = CMD_DISK;
+ if (!pszSrc)
+ return errorSyntax(Disk::tr("Mandatory UUID or input file parameter missing"));
+ if (!pszDst)
+ return errorSyntax(Disk::tr("Mandatory output file parameter missing"));
+ if (fExisting && (!format.isEmpty() || enmMediumVariant != MediumVariant_Standard))
+ return errorSyntax(Disk::tr("Specified options which cannot be used with --existing"));
+
+ ComPtr<IMedium> pSrcMedium;
+ ComPtr<IMedium> pDstMedium;
+
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszSrc, DeviceType_HardDisk, AccessMode_ReadOnly, pSrcMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszSrc, DeviceType_DVD, AccessMode_ReadOnly, pSrcMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszSrc, DeviceType_Floppy, AccessMode_ReadOnly, pSrcMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else
+ hrc = E_INVALIDARG; /* cannot happen but make gcc happy */
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ do
+ {
+ /* open/create destination medium */
+ if (fExisting)
+ {
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszDst, DeviceType_HardDisk, AccessMode_ReadWrite, pDstMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszDst, DeviceType_DVD, AccessMode_ReadOnly, pDstMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszDst, DeviceType_Floppy, AccessMode_ReadWrite, pDstMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(hrc))
+ break;
+
+ /* Perform accessibility check now. */
+ MediumState_T state;
+ CHECK_ERROR_BREAK(pDstMedium, RefreshState(&state));
+ CHECK_ERROR_BREAK(pDstMedium, COMGETTER(Format)(format.asOutParam()));
+ }
+ else
+ {
+ /*
+ * In case the format is unspecified check that the source medium supports
+ * image creation and use the same format for the destination image.
+ * Use the default image format if it is not supported.
+ */
+ if (format.isEmpty())
+ {
+ ComPtr<IMediumFormat> pMediumFmt;
+ com::SafeArray<MediumFormatCapabilities_T> l_caps;
+ CHECK_ERROR_BREAK(pSrcMedium, COMGETTER(MediumFormat)(pMediumFmt.asOutParam()));
+ CHECK_ERROR_BREAK(pMediumFmt, COMGETTER(Capabilities)(ComSafeArrayAsOutParam(l_caps)));
+ ULONG caps=0;
+ for (size_t i = 0; i < l_caps.size(); i++)
+ caps |= l_caps[i];
+ if (caps & ( MediumFormatCapabilities_CreateDynamic
+ | MediumFormatCapabilities_CreateFixed))
+ CHECK_ERROR_BREAK(pMediumFmt, COMGETTER(Id)(format.asOutParam()));
+ }
+ Utf8Str strFormat(format);
+ if (cmd == CMD_DISK)
+ hrc = createMedium(a, strFormat.c_str(), pszDst, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pDstMedium);
+ else if (cmd == CMD_DVD)
+ hrc = createMedium(a, strFormat.c_str(), pszDst, DeviceType_DVD,
+ AccessMode_ReadOnly, pDstMedium);
+ else if (cmd == CMD_FLOPPY)
+ hrc = createMedium(a, strFormat.c_str(), pszDst, DeviceType_Floppy,
+ AccessMode_ReadWrite, pDstMedium);
+ if (FAILED(hrc))
+ break;
+ }
+
+ ComPtr<IProgress> pProgress;
+ com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+ for (ULONG i = 0; i < l_variants.size(); ++i)
+ {
+ ULONG temp = enmMediumVariant;
+ temp &= 1<<i;
+ l_variants [i] = (MediumVariant_T)temp;
+ }
+
+ if (fNeedResize)
+ {
+ CHECK_ERROR_BREAK(pSrcMedium, ResizeAndCloneTo(pDstMedium, cbResize, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam()));
+ }
+ else
+ {
+ CHECK_ERROR_BREAK(pSrcMedium, CloneTo(pDstMedium, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam()));
+ }
+
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_BREAK(pProgress, (Disk::tr("Failed to clone medium")));
+
+ Bstr uuid;
+ CHECK_ERROR_BREAK(pDstMedium, COMGETTER(Id)(uuid.asOutParam()));
+
+ RTPrintf(Disk::tr("Clone medium created in format '%ls'. UUID: %s\n"),
+ format.raw(), Utf8Str(uuid).c_str());
+ }
+ while (0);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aConvertFromRawHardDiskOptions[] =
+{
+ { "--format", 'o', RTGETOPT_REQ_STRING },
+ { "-format", 'o', RTGETOPT_REQ_STRING },
+ { "--static", 'F', RTGETOPT_REQ_NOTHING },
+ { "-static", 'F', RTGETOPT_REQ_NOTHING },
+ { "--variant", 'm', RTGETOPT_REQ_STRING },
+ { "-variant", 'm', RTGETOPT_REQ_STRING },
+ { "--uuid", 'u', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleConvertFromRaw(HandlerArg *a)
+{
+ bool fReadFromStdIn = false;
+ const char *format = "VDI";
+ const char *srcfilename = NULL;
+ const char *dstfilename = NULL;
+ const char *filesize = NULL;
+ unsigned uImageFlags = VD_IMAGE_FLAGS_NONE;
+ void *pvBuf = NULL;
+ RTUUID uuid;
+ PCRTUUID pUuid = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv,
+ g_aConvertFromRawHardDiskOptions, RT_ELEMENTS(g_aConvertFromRawHardDiskOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'u': // --uuid
+ if (RT_FAILURE(RTUuidFromStr(&uuid, ValueUnion.psz)))
+ return errorSyntax(Disk::tr("Invalid UUID '%s'"), ValueUnion.psz);
+ pUuid = &uuid;
+ break;
+ case 'o': // --format
+ format = ValueUnion.psz;
+ break;
+
+ case 'm': // --variant
+ {
+ MediumVariant_T enmMediumVariant = MediumVariant_Standard;
+ vrc = parseMediumVariant(ValueUnion.psz, &enmMediumVariant);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid medium variant '%s'"), ValueUnion.psz);
+ /// @todo cleaner solution than assuming 1:1 mapping?
+ uImageFlags = (unsigned)enmMediumVariant;
+ break;
+ }
+ case VINF_GETOPT_NOT_OPTION:
+ if (!srcfilename)
+ {
+ srcfilename = ValueUnion.psz;
+ fReadFromStdIn = !strcmp(srcfilename, "stdin");
+ }
+ else if (!dstfilename)
+ dstfilename = ValueUnion.psz;
+ else if (fReadFromStdIn && !filesize)
+ filesize = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!srcfilename || !dstfilename || (fReadFromStdIn && !filesize))
+ return errorSyntax(Disk::tr("Incorrect number of parameters"));
+ RTStrmPrintf(g_pStdErr, Disk::tr("Converting from raw image file=\"%s\" to file=\"%s\"...\n"),
+ srcfilename, dstfilename);
+
+ PVDISK pDisk = NULL;
+
+ PVDINTERFACE pVDIfs = NULL;
+ VDINTERFACEERROR vdInterfaceError;
+ vdInterfaceError.pfnError = handleVDError;
+ vdInterfaceError.pfnMessage = NULL;
+
+ vrc = VDInterfaceAdd(&vdInterfaceError.Core, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
+ NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
+ AssertRC(vrc);
+
+ /* open raw image file. */
+ RTFILE File;
+ if (fReadFromStdIn)
+ vrc = RTFileFromNative(&File, RTFILE_NATIVE_STDIN);
+ else
+ vrc = RTFileOpen(&File, srcfilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Disk::tr("Cannot open file \"%s\": %Rrc"), srcfilename, vrc);
+ goto out;
+ }
+
+ uint64_t cbFile;
+ /* get image size. */
+ if (fReadFromStdIn)
+ cbFile = RTStrToUInt64(filesize);
+ else
+ vrc = RTFileQuerySize(File, &cbFile);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Disk::tr("Cannot get image size for file \"%s\": %Rrc"), srcfilename, vrc);
+ goto out;
+ }
+
+ RTStrmPrintf(g_pStdErr, Disk::tr("Creating %s image with size %RU64 bytes (%RU64MB)...\n", "", cbFile),
+ (uImageFlags & VD_IMAGE_FLAGS_FIXED) ? Disk::tr("fixed", "adjective") : Disk::tr("dynamic", "adjective"),
+ cbFile, (cbFile + _1M - 1) / _1M);
+ char pszComment[256];
+ RTStrPrintf(pszComment, sizeof(pszComment), Disk::tr("Converted image from %s"), srcfilename);
+ vrc = VDCreate(pVDIfs, VDTYPE_HDD, &pDisk);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Disk::tr("Cannot create the virtual disk container: %Rrc"), vrc);
+ goto out;
+ }
+
+ Assert(RT_MIN(cbFile / 512 / 16 / 63, 16383) -
+ (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383) == 0);
+ VDGEOMETRY PCHS, LCHS;
+ PCHS.cCylinders = (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383);
+ PCHS.cHeads = 16;
+ PCHS.cSectors = 63;
+ LCHS.cCylinders = 0;
+ LCHS.cHeads = 0;
+ LCHS.cSectors = 0;
+ vrc = VDCreateBase(pDisk, format, dstfilename, cbFile,
+ uImageFlags, pszComment, &PCHS, &LCHS, pUuid,
+ VD_OPEN_FLAGS_NORMAL, NULL, NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Disk::tr("Cannot create the disk image \"%s\": %Rrc"), dstfilename, vrc);
+ goto out;
+ }
+
+ size_t cbBuffer;
+ cbBuffer = _1M;
+ pvBuf = RTMemAlloc(cbBuffer);
+ if (!pvBuf)
+ {
+ vrc = VERR_NO_MEMORY;
+ RTMsgError(Disk::tr("Out of memory allocating buffers for image \"%s\": %Rrc"), dstfilename, vrc);
+ goto out;
+ }
+
+ uint64_t offFile;
+ offFile = 0;
+ while (offFile < cbFile)
+ {
+ size_t cbRead;
+ size_t cbToRead;
+ cbRead = 0;
+ cbToRead = cbFile - offFile >= (uint64_t)cbBuffer ?
+ cbBuffer : (size_t)(cbFile - offFile);
+ vrc = RTFileRead(File, pvBuf, cbToRead, &cbRead);
+ if (RT_FAILURE(vrc) || !cbRead)
+ break;
+ vrc = VDWrite(pDisk, offFile, pvBuf, cbRead);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(Disk::tr("Failed to write to disk image \"%s\": %Rrc"), dstfilename, vrc);
+ goto out;
+ }
+ offFile += cbRead;
+ }
+
+out:
+ if (pvBuf)
+ RTMemFree(pvBuf);
+ if (pDisk)
+ VDClose(pDisk, RT_FAILURE(vrc));
+ if (File != NIL_RTFILE)
+ RTFileClose(File);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+HRESULT showMediumInfo(const ComPtr<IVirtualBox> &pVirtualBox,
+ const ComPtr<IMedium> &pMedium,
+ const char *pszParentUUID,
+ bool fOptLong)
+{
+ HRESULT hrc = S_OK;
+ do
+ {
+ Bstr uuid;
+ pMedium->COMGETTER(Id)(uuid.asOutParam());
+ RTPrintf("UUID: %ls\n", uuid.raw());
+ if (pszParentUUID)
+ RTPrintf(Disk::tr("Parent UUID: %s\n"), pszParentUUID);
+
+ /* check for accessibility */
+ MediumState_T enmState;
+ CHECK_ERROR_BREAK(pMedium, RefreshState(&enmState));
+ const char *pszState = Disk::tr("unknown");
+ switch (enmState)
+ {
+ case MediumState_NotCreated:
+ pszState = Disk::tr("not created");
+ break;
+ case MediumState_Created:
+ pszState = Disk::tr("created");
+ break;
+ case MediumState_LockedRead:
+ pszState = Disk::tr("locked read");
+ break;
+ case MediumState_LockedWrite:
+ pszState = Disk::tr("locked write");
+ break;
+ case MediumState_Inaccessible:
+ pszState = Disk::tr("inaccessible");
+ break;
+ case MediumState_Creating:
+ pszState = Disk::tr("creating");
+ break;
+ case MediumState_Deleting:
+ pszState = Disk::tr("deleting");
+ break;
+#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
+ case MediumState_32BitHack: break; /* Shut up compiler warnings. */
+#endif
+ }
+ RTPrintf(Disk::tr("State: %s\n"), pszState);
+
+ if (fOptLong && enmState == MediumState_Inaccessible)
+ {
+ Bstr err;
+ CHECK_ERROR_BREAK(pMedium, COMGETTER(LastAccessError)(err.asOutParam()));
+ RTPrintf(Disk::tr("Access Error: %ls\n"), err.raw());
+ }
+
+ if (fOptLong)
+ {
+ Bstr description;
+ pMedium->COMGETTER(Description)(description.asOutParam());
+ if (!description.isEmpty())
+ RTPrintf(Disk::tr("Description: %ls\n"), description.raw());
+ }
+
+ MediumType_T type;
+ pMedium->COMGETTER(Type)(&type);
+ const char *typeStr = Disk::tr("unknown");
+ switch (type)
+ {
+ case MediumType_Normal:
+ if (pszParentUUID && Guid(pszParentUUID).isValid())
+ typeStr = Disk::tr("normal (differencing)");
+ else
+ typeStr = Disk::tr("normal (base)");
+ break;
+ case MediumType_Immutable:
+ typeStr = Disk::tr("immutable");
+ break;
+ case MediumType_Writethrough:
+ typeStr = Disk::tr("writethrough");
+ break;
+ case MediumType_Shareable:
+ typeStr = Disk::tr("shareable");
+ break;
+ case MediumType_Readonly:
+ typeStr = Disk::tr("readonly");
+ break;
+ case MediumType_MultiAttach:
+ typeStr = Disk::tr("multiattach");
+ break;
+#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
+ case MediumType_32BitHack: break; /* Shut up compiler warnings. */
+#endif
+ }
+ RTPrintf(Disk::tr("Type: %s\n"), typeStr);
+
+ /* print out information specific for differencing media */
+ if (fOptLong && pszParentUUID && Guid(pszParentUUID).isValid())
+ {
+ BOOL autoReset = FALSE;
+ pMedium->COMGETTER(AutoReset)(&autoReset);
+ RTPrintf(Disk::tr("Auto-Reset: %s\n"), autoReset ? Disk::tr("on") : Disk::tr("off"));
+ }
+
+ Bstr loc;
+ pMedium->COMGETTER(Location)(loc.asOutParam());
+ RTPrintf(Disk::tr("Location: %ls\n"), loc.raw());
+
+ Bstr format;
+ pMedium->COMGETTER(Format)(format.asOutParam());
+ RTPrintf(Disk::tr("Storage format: %ls\n"), format.raw());
+
+ if (fOptLong)
+ {
+ com::SafeArray<MediumVariant_T> safeArray_variant;
+
+ pMedium->COMGETTER(Variant)(ComSafeArrayAsOutParam(safeArray_variant));
+ ULONG variant=0;
+ for (size_t i = 0; i < safeArray_variant.size(); i++)
+ variant |= safeArray_variant[i];
+
+ const char *variantStr = Disk::tr("unknown");
+ switch (variant & ~(MediumVariant_Fixed | MediumVariant_Diff))
+ {
+ case MediumVariant_VmdkSplit2G:
+ variantStr = Disk::tr("split2G");
+ break;
+ case MediumVariant_VmdkStreamOptimized:
+ variantStr = Disk::tr("streamOptimized");
+ break;
+ case MediumVariant_VmdkESX:
+ variantStr = Disk::tr("ESX");
+ break;
+ case MediumVariant_Standard:
+ variantStr = Disk::tr("default");
+ break;
+ }
+ const char *variantTypeStr = Disk::tr("dynamic");
+ if (variant & MediumVariant_Fixed)
+ variantTypeStr = Disk::tr("fixed");
+ else if (variant & MediumVariant_Diff)
+ variantTypeStr = Disk::tr("differencing");
+ RTPrintf(Disk::tr("Format variant: %s %s\n"), variantTypeStr, variantStr);
+ }
+
+ LONG64 logicalSize;
+ pMedium->COMGETTER(LogicalSize)(&logicalSize);
+ RTPrintf(Disk::tr("Capacity: %lld MBytes\n"), logicalSize >> 20);
+ if (fOptLong)
+ {
+ LONG64 actualSize;
+ pMedium->COMGETTER(Size)(&actualSize);
+ RTPrintf(Disk::tr("Size on disk: %lld MBytes\n"), actualSize >> 20);
+ }
+
+ Bstr strCipher;
+ Bstr strPasswordId;
+ HRESULT hrc2 = pMedium->GetEncryptionSettings(strCipher.asOutParam(), strPasswordId.asOutParam());
+ if (SUCCEEDED(hrc2))
+ {
+ RTPrintf(Disk::tr("Encryption: enabled\n"));
+ if (fOptLong)
+ {
+ RTPrintf(Disk::tr("Cipher: %ls\n"), strCipher.raw());
+ RTPrintf(Disk::tr("Password ID: %ls\n"), strPasswordId.raw());
+ }
+ }
+ else
+ RTPrintf(Disk::tr("Encryption: disabled\n"));
+
+ if (fOptLong)
+ {
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+ pMedium->GetProperties(Bstr().raw(), ComSafeArrayAsOutParam(names), ComSafeArrayAsOutParam(values));
+ size_t cNames = names.size();
+ size_t cValues = values.size();
+ bool fFirst = true;
+ for (size_t i = 0; i < cNames; i++)
+ {
+ Bstr value;
+ if (i < cValues)
+ value = values[i];
+ RTPrintf("%s%ls=%ls\n",
+ fFirst ? Disk::tr("Property: ") : " ",
+ names[i], value.raw());
+ fFirst = false;
+ }
+ }
+
+ if (fOptLong)
+ {
+ bool fFirst = true;
+ com::SafeArray<BSTR> machineIds;
+ pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
+ for (size_t i = 0; i < machineIds.size(); i++)
+ {
+ ComPtr<IMachine> pMachine;
+ CHECK_ERROR(pVirtualBox, FindMachine(machineIds[i], pMachine.asOutParam()));
+ if (pMachine)
+ {
+ Bstr name;
+ pMachine->COMGETTER(Name)(name.asOutParam());
+ pMachine->COMGETTER(Id)(uuid.asOutParam());
+ RTPrintf("%s%ls (UUID: %ls)",
+ fFirst ? Disk::tr("In use by VMs: ") : " ",
+ name.raw(), machineIds[i]);
+ fFirst = false;
+ com::SafeArray<BSTR> snapshotIds;
+ pMedium->GetSnapshotIds(machineIds[i],
+ ComSafeArrayAsOutParam(snapshotIds));
+ for (size_t j = 0; j < snapshotIds.size(); j++)
+ {
+ ComPtr<ISnapshot> pSnapshot;
+ pMachine->FindSnapshot(snapshotIds[j], pSnapshot.asOutParam());
+ if (pSnapshot)
+ {
+ Bstr snapshotName;
+ pSnapshot->COMGETTER(Name)(snapshotName.asOutParam());
+ RTPrintf(" [%ls (UUID: %ls)]", snapshotName.raw(), snapshotIds[j]);
+ }
+ }
+ RTPrintf("\n");
+ }
+ }
+ }
+
+ if (fOptLong)
+ {
+ com::SafeIfaceArray<IMedium> children;
+ pMedium->COMGETTER(Children)(ComSafeArrayAsOutParam(children));
+ bool fFirst = true;
+ for (size_t i = 0; i < children.size(); i++)
+ {
+ ComPtr<IMedium> pChild(children[i]);
+ if (pChild)
+ {
+ Bstr childUUID;
+ pChild->COMGETTER(Id)(childUUID.asOutParam());
+ RTPrintf("%s%ls\n",
+ fFirst ? Disk::tr("Child UUIDs: ") : " ",
+ childUUID.raw());
+ fFirst = false;
+ }
+ }
+ }
+ }
+ while (0);
+
+ return hrc;
+}
+
+static const RTGETOPTDEF g_aShowMediumInfoOptions[] =
+{
+ { "disk", 'd', RTGETOPT_REQ_NOTHING },
+ { "dvd", 'D', RTGETOPT_REQ_NOTHING },
+ { "floppy", 'f', RTGETOPT_REQ_NOTHING },
+};
+
+RTEXITCODE handleShowMediumInfo(HandlerArg *a)
+{
+ enum {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ const char *pszFilenameOrUuid = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aShowMediumInfoOptions, RT_ELEMENTS(g_aShowMediumInfoOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'd': // disk
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DISK;
+ break;
+
+ case 'D': // DVD
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DVD;
+ break;
+
+ case 'f': // floppy
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_FLOPPY;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszFilenameOrUuid)
+ pszFilenameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Disk::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Disk::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (cmd == CMD_NONE)
+ cmd = CMD_DISK;
+
+ /* check for required options */
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Disk::tr("Medium name or UUID required"));
+
+ HRESULT hrc = S_OK; /* Prevents warning. */
+
+ ComPtr<IMedium> pMedium;
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_DVD,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_Floppy,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ Utf8Str strParentUUID(Disk::tr("base"));
+ ComPtr<IMedium> pParent;
+ pMedium->COMGETTER(Parent)(pParent.asOutParam());
+ if (!pParent.isNull())
+ {
+ Bstr bstrParentUUID;
+ pParent->COMGETTER(Id)(bstrParentUUID.asOutParam());
+ strParentUUID = bstrParentUUID;
+ }
+
+ hrc = showMediumInfo(a->virtualBox, pMedium, strParentUUID.c_str(), true);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aCloseMediumOptions[] =
+{
+ { "disk", 'd', RTGETOPT_REQ_NOTHING },
+ { "dvd", 'D', RTGETOPT_REQ_NOTHING },
+ { "floppy", 'f', RTGETOPT_REQ_NOTHING },
+ { "--delete", 'r', RTGETOPT_REQ_NOTHING },
+};
+
+RTEXITCODE handleCloseMedium(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ enum {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ const char *pszFilenameOrUuid = NULL;
+ bool fDelete = false;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCloseMediumOptions, RT_ELEMENTS(g_aCloseMediumOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'd': // disk
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DISK;
+ break;
+
+ case 'D': // DVD
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_DVD;
+ break;
+
+ case 'f': // floppy
+ if (cmd != CMD_NONE)
+ return errorSyntax(Disk::tr("Only one command can be specified: '%s'"), ValueUnion.psz);
+ cmd = CMD_FLOPPY;
+ break;
+
+ case 'r': // --delete
+ fDelete = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszFilenameOrUuid)
+ pszFilenameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Disk::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Disk::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ /* check for required options */
+ if (cmd == CMD_NONE)
+ cmd = CMD_DISK;
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Disk::tr("Medium name or UUID required"));
+
+ ComPtr<IMedium> pMedium;
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_DVD,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_Floppy,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+
+ if (SUCCEEDED(hrc) && pMedium)
+ {
+ if (fDelete)
+ {
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR(pMedium, DeleteStorage(pProgress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR(pProgress, (Disk::tr("Failed to delete medium")));
+ }
+ else
+ RTMsgError(Disk::tr("Failed to delete medium. Error code %Rhrc"), hrc);
+ }
+ CHECK_ERROR(pMedium, Close());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleMediumProperty(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ const char *pszCmd = NULL;
+ enum {
+ CMD_NONE,
+ CMD_DISK,
+ CMD_DVD,
+ CMD_FLOPPY
+ } cmd = CMD_NONE;
+ const char *pszAction = NULL;
+ const char *pszFilenameOrUuid = NULL;
+ const char *pszProperty = NULL;
+ ComPtr<IMedium> pMedium;
+
+ pszCmd = (a->argc > 0) ? a->argv[0] : "";
+ if ( !RTStrICmp(pszCmd, "disk")
+ || !RTStrICmp(pszCmd, "dvd")
+ || !RTStrICmp(pszCmd, "floppy"))
+ {
+ if (!RTStrICmp(pszCmd, "disk"))
+ cmd = CMD_DISK;
+ else if (!RTStrICmp(pszCmd, "dvd"))
+ cmd = CMD_DVD;
+ else if (!RTStrICmp(pszCmd, "floppy"))
+ cmd = CMD_FLOPPY;
+ else
+ {
+ AssertMsgFailed((Disk::tr("unexpected parameter %s\n"), pszCmd));
+ cmd = CMD_DISK;
+ }
+ a->argv++;
+ a->argc--;
+ }
+ else
+ {
+ pszCmd = NULL;
+ cmd = CMD_DISK;
+ }
+
+ if (a->argc == 0)
+ return errorSyntax(Disk::tr("Missing action"));
+
+ pszAction = a->argv[0];
+ if ( RTStrICmp(pszAction, "set")
+ && RTStrICmp(pszAction, "get")
+ && RTStrICmp(pszAction, "delete"))
+ return errorSyntax(Disk::tr("Invalid action given: %s"), pszAction);
+
+ if ( ( !RTStrICmp(pszAction, "set")
+ && a->argc != 4)
+ || ( RTStrICmp(pszAction, "set")
+ && a->argc != 3))
+ return errorSyntax(Disk::tr("Invalid number of arguments given for action: %s"), pszAction);
+
+ pszFilenameOrUuid = a->argv[1];
+ pszProperty = a->argv[2];
+
+ if (cmd == CMD_DISK)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_DVD)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_DVD,
+ AccessMode_ReadOnly, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ else if (cmd == CMD_FLOPPY)
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_Floppy,
+ AccessMode_ReadWrite, pMedium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (SUCCEEDED(hrc) && !pMedium.isNull())
+ {
+ if (!RTStrICmp(pszAction, "set"))
+ {
+ const char *pszValue = a->argv[3];
+ CHECK_ERROR(pMedium, SetProperty(Bstr(pszProperty).raw(), Bstr(pszValue).raw()));
+ }
+ else if (!RTStrICmp(pszAction, "get"))
+ {
+ /*
+ * Trigger a call to Medium::i_queryInfo()->VDOpen()->pfnOpen() to
+ * open the virtual device and populate its properties for
+ * Medium::getProperty() to retrieve.
+ */
+ MediumState_T state;
+ CHECK_ERROR(pMedium, RefreshState(&state));
+
+ Bstr strVal;
+ CHECK_ERROR(pMedium, GetProperty(Bstr(pszProperty).raw(), strVal.asOutParam()));
+ if (SUCCEEDED(hrc))
+ RTPrintf("%s=%ls\n", pszProperty, strVal.raw());
+ }
+ else if (!RTStrICmp(pszAction, "delete"))
+ {
+ CHECK_ERROR(pMedium, SetProperty(Bstr(pszProperty).raw(), Bstr().raw()));
+ /** @todo */
+ }
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aEncryptMediumOptions[] =
+{
+ { "--newpassword", 'n', RTGETOPT_REQ_STRING },
+ { "--oldpassword", 'o', RTGETOPT_REQ_STRING },
+ { "--cipher", 'c', RTGETOPT_REQ_STRING },
+ { "--newpasswordid", 'i', RTGETOPT_REQ_STRING }
+};
+
+RTEXITCODE handleEncryptMedium(HandlerArg *a)
+{
+ HRESULT hrc;
+ ComPtr<IMedium> hardDisk;
+ const char *pszPasswordNew = NULL;
+ const char *pszPasswordOld = NULL;
+ const char *pszCipher = NULL;
+ const char *pszFilenameOrUuid = NULL;
+ const char *pszNewPasswordId = NULL;
+ Utf8Str strPasswordNew;
+ Utf8Str strPasswordOld;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aEncryptMediumOptions, RT_ELEMENTS(g_aEncryptMediumOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n': // --newpassword
+ pszPasswordNew = ValueUnion.psz;
+ break;
+
+ case 'o': // --oldpassword
+ pszPasswordOld = ValueUnion.psz;
+ break;
+
+ case 'c': // --cipher
+ pszCipher = ValueUnion.psz;
+ break;
+
+ case 'i': // --newpasswordid
+ pszNewPasswordId = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszFilenameOrUuid)
+ pszFilenameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(Disk::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Disk::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Disk::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Disk::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Disk::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Disk::tr("Disk name or UUID required"));
+
+ if (!pszPasswordNew && !pszPasswordOld)
+ return errorSyntax(Disk::tr("No password specified"));
+
+ if ( (pszPasswordNew && !pszNewPasswordId)
+ || (!pszPasswordNew && pszNewPasswordId))
+ return errorSyntax(Disk::tr("A new password must always have a valid identifier set at the same time"));
+
+ if (pszPasswordNew)
+ {
+ if (!RTStrCmp(pszPasswordNew, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordNew, Disk::tr("Enter new password:"));
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPasswordNew, &strPasswordNew);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError(Disk::tr("Failed to read new password from file"));
+ return rcExit;
+ }
+ }
+ }
+
+ if (pszPasswordOld)
+ {
+ if (!RTStrCmp(pszPasswordOld, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordOld, Disk::tr("Enter old password:"));
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPasswordOld, &strPasswordOld);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError(Disk::tr("Failed to read old password from file"));
+ return rcExit;
+ }
+ }
+ }
+
+ /* Always open the medium if necessary, there is no other way. */
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, hardDisk,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (hardDisk.isNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Disk::tr("Invalid hard disk reference, avoiding crash"));
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(hardDisk, ChangeEncryption(Bstr(strPasswordOld).raw(), Bstr(pszCipher).raw(),
+ Bstr(strPasswordNew).raw(), Bstr(pszNewPasswordId).raw(),
+ progress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ hrc = showProgress(progress);
+ if (FAILED(hrc))
+ {
+ if (hrc == E_NOTIMPL)
+ RTMsgError(Disk::tr("Encrypt hard disk operation is not implemented!"));
+ else if (hrc == VBOX_E_NOT_SUPPORTED)
+ RTMsgError(Disk::tr("Encrypt hard disk operation for this cipher is not implemented yet!"));
+ else if (!progress.isNull())
+ CHECK_PROGRESS_ERROR(progress, (Disk::tr("Failed to encrypt hard disk")));
+ else
+ RTMsgError(Disk::tr("Failed to encrypt hard disk!"));
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleCheckMediumPassword(HandlerArg *a)
+{
+ HRESULT hrc;
+ ComPtr<IMedium> hardDisk;
+ const char *pszFilenameOrUuid = NULL;
+ Utf8Str strPassword;
+
+ if (a->argc != 2)
+ return errorSyntax(Disk::tr("Invalid number of arguments: %d"), a->argc);
+
+ pszFilenameOrUuid = a->argv[0];
+
+ if (!RTStrCmp(a->argv[1], "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, Disk::tr("Enter password:"));
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(a->argv[1], &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError(Disk::tr("Failed to read password from file"));
+ return rcExit;
+ }
+ }
+
+ /* Always open the medium if necessary, there is no other way. */
+ hrc = openMedium(a, pszFilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, hardDisk,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (hardDisk.isNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Disk::tr("Invalid hard disk reference, avoiding crash"));
+
+ CHECK_ERROR(hardDisk, CheckEncryptionPassword(Bstr(strPassword).raw()));
+ if (SUCCEEDED(hrc))
+ RTPrintf(Disk::tr("The given password is correct\n"));
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/*********************************************************************************************************************************
+* The mediumio command *
+*********************************************************************************************************************************/
+
+/**
+ * Common MediumIO options.
+ */
+typedef struct MEDIUMIOCOMMONOPT
+{
+ const char *pszFilenameOrUuid;
+ DeviceType_T enmDeviceType;
+ const char *pszPasswordFile;
+} MEDIUMIOCOMMONOPT;
+typedef MEDIUMIOCOMMONOPT *PMEDIUMIOCOMMONOPT;
+typedef MEDIUMIOCOMMONOPT const *PCMEDIUMIOCOMMONOPT;
+
+/* For RTGETOPTDEF array initializer. */
+#define MEDIUMIOCOMMONOPT_DEFS() \
+ { "--disk", 'd', RTGETOPT_REQ_STRING }, \
+ { "--harddisk", 'd', RTGETOPT_REQ_STRING }, \
+ { "disk", 'd', RTGETOPT_REQ_STRING }, \
+ { "harddisk", 'd', RTGETOPT_REQ_STRING }, \
+ { "--dvd", 'D', RTGETOPT_REQ_STRING }, \
+ { "--iso", 'D', RTGETOPT_REQ_STRING }, \
+ { "dvd", 'D', RTGETOPT_REQ_STRING }, \
+ { "iso", 'D', RTGETOPT_REQ_STRING }, \
+ { "--floppy", 'f', RTGETOPT_REQ_STRING }, \
+ { "floppy", 'f', RTGETOPT_REQ_STRING }, \
+ { "--password-file", 'P', RTGETOPT_REQ_STRING }
+
+/* For option switch. */
+#define MEDIUMIOCOMMONOPT_CASES(a_pCommonOpts) \
+ case 'd': \
+ (a_pCommonOpts)->enmDeviceType = DeviceType_HardDisk; \
+ (a_pCommonOpts)->pszFilenameOrUuid = ValueUnion.psz; \
+ break; \
+ case 'D': \
+ (a_pCommonOpts)->enmDeviceType = DeviceType_DVD; \
+ (a_pCommonOpts)->pszFilenameOrUuid = ValueUnion.psz; \
+ break; \
+ case 'f': \
+ (a_pCommonOpts)->enmDeviceType = DeviceType_Floppy; \
+ (a_pCommonOpts)->pszFilenameOrUuid = ValueUnion.psz; \
+ break; \
+ case 'P': \
+ (a_pCommonOpts)->pszPasswordFile = ValueUnion.psz; \
+ break
+
+
+/**
+ * Worker for mediumio operations that returns a IMediumIO for the specified
+ * medium.
+ *
+ * @returns Exit code.
+ * @param pHandler The handler state structure (for IVirtualBox).
+ * @param pCommonOpts Common mediumio options.
+ * @param fWritable Whether to open writable (true) or read only
+ * (false).
+ * @param rPtrMediumIO Where to return the IMediumIO pointer.
+ * @param pcbMedium Where to return the meidum size. Optional.
+ */
+static RTEXITCODE mediumIOOpenMediumForIO(HandlerArg *pHandler, PCMEDIUMIOCOMMONOPT pCommonOpts, bool fWritable,
+ ComPtr<IMediumIO> &rPtrMediumIO, uint64_t *pcbMedium = NULL)
+{
+ /* Clear returns. */
+ if (pcbMedium)
+ *pcbMedium = 0;
+ rPtrMediumIO.setNull();
+
+ /*
+ * Make sure a medium was specified already.
+ */
+ if (pCommonOpts->enmDeviceType == DeviceType_Null)
+ return errorSyntax(Disk::tr("No medium specified!"));
+
+ /*
+ * Read the password.
+ */
+ Bstr bstrPassword;
+ if (pCommonOpts->pszPasswordFile)
+ {
+ Utf8Str strPassword;
+ RTEXITCODE rcExit;
+ if (pCommonOpts->pszPasswordFile[0] == '-' && pCommonOpts->pszPasswordFile[1] == '\0')
+ rcExit = readPasswordFromConsole(&strPassword, Disk::tr("Enter encryption password:"));
+ else
+ rcExit = readPasswordFile(pCommonOpts->pszPasswordFile, &strPassword);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ bstrPassword = strPassword;
+ strPassword.assign(strPassword.length(), '*');
+ }
+
+ /*
+ * Open the medium and then get I/O access to it.
+ */
+ ComPtr<IMedium> ptrMedium;
+ HRESULT hrc = openMedium(pHandler, pCommonOpts->pszFilenameOrUuid, pCommonOpts->enmDeviceType,
+ fWritable ? AccessMode_ReadWrite : AccessMode_ReadOnly,
+ ptrMedium, false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR2I_STMT(ptrMedium, OpenForIO(fWritable, bstrPassword.raw(), rPtrMediumIO.asOutParam()), hrc = hrcCheck);
+
+ /*
+ * If the size is requested get it after we've opened it.
+ */
+ if (pcbMedium && SUCCEEDED(hrc))
+ {
+ LONG64 cbLogical = 0;
+ CHECK_ERROR2I_STMT(ptrMedium, COMGETTER(LogicalSize)(&cbLogical), hrc = hrcCheck);
+ *pcbMedium = cbLogical;
+ if (!SUCCEEDED(hrc))
+ rPtrMediumIO.setNull();
+ }
+ }
+
+ if (bstrPassword.isNotEmpty())
+ memset(bstrPassword.mutableRaw(), '*', bstrPassword.length() * sizeof(RTUTF16));
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * mediumio formatfat
+ */
+static RTEXITCODE handleMediumIOFormatFat(HandlerArg *a, int iFirst, PMEDIUMIOCOMMONOPT pCommonOpts)
+{
+ /*
+ * Parse the options.
+ */
+ bool fQuick = false;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ MEDIUMIOCOMMONOPT_DEFS(),
+ { "--quick", 'q', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ MEDIUMIOCOMMONOPT_CASES(pCommonOpts);
+
+ case 'q':
+ fQuick = true;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Open the medium for I/O and format it.
+ */
+ ComPtr<IMediumIO> ptrMediumIO;
+ RTEXITCODE rcExit = mediumIOOpenMediumForIO(a, pCommonOpts, true /*fWritable*/, ptrMediumIO);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ CHECK_ERROR2I_RET(ptrMediumIO, FormatFAT(fQuick), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * mediumio cat
+ */
+static RTEXITCODE handleMediumIOCat(HandlerArg *a, int iFirst, PMEDIUMIOCOMMONOPT pCommonOpts)
+{
+ /*
+ * Parse the options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ MEDIUMIOCOMMONOPT_DEFS(),
+ { "--hex", 'H', RTGETOPT_REQ_NOTHING },
+ { "--offset", 'o', RTGETOPT_REQ_UINT64 },
+ { "--output", 'O', RTGETOPT_REQ_STRING },
+ { "--size", 's', RTGETOPT_REQ_UINT64 },
+ };
+ bool fHex = false;
+ uint64_t off = 0;
+ const char *pszOutput = NULL;
+ uint64_t cb = UINT64_MAX;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ MEDIUMIOCOMMONOPT_CASES(pCommonOpts);
+
+ case 'H':
+ fHex = true;
+ break;
+
+ case 'o':
+ off = ValueUnion.u64;
+ break;
+
+ case 'O':
+ pszOutput = ValueUnion.psz;
+ break;
+
+ case 's':
+ cb = ValueUnion.u64;
+ break;
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Open the medium for I/O.
+ */
+ ComPtr<IMediumIO> ptrMediumIO;
+ uint64_t cbMedium;
+ RTEXITCODE rcExit = mediumIOOpenMediumForIO(a, pCommonOpts, false /*fWritable*/, ptrMediumIO, &cbMedium);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Do we have an output file or do we write to stdout?
+ */
+ PRTSTREAM pOut = NULL;
+ if (pszOutput && (pszOutput[0] != '-' || pszOutput[1] != '\0'))
+ {
+ vrc = RTStrmOpen(pszOutput, fHex ? "wt" : "wb", &pOut);
+ if (RT_FAILURE(vrc))
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error opening '%s' for writing: %Rrc"), pszOutput, vrc);
+ }
+ else
+ {
+ pOut = g_pStdOut;
+ if (!fHex)
+ RTStrmSetMode(pOut, true, -1);
+ }
+
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Adjust 'cb' now that we've got the medium size.
+ */
+ if (off >= cbMedium)
+ {
+ RTMsgWarning(Disk::tr("Specified offset (%#RX64) is beyond the end of the medium (%#RX64)"), off, cbMedium);
+ cb = 0;
+ }
+ else if ( cb > cbMedium
+ || cb + off > cbMedium)
+ cb = cbMedium - off;
+
+ /*
+ * Hex dump preps. (The duplication detection is making ASSUMPTIONS about
+ * all the reads being a multiple of cchWidth, except for the final one.)
+ */
+ char abHexBuf[16] = { 0 };
+ size_t cbHexBuf = 0;
+ unsigned const cchWidth = RT_ELEMENTS(abHexBuf);
+ uint64_t const offEndDupCheck = cb - cchWidth;
+ uint64_t cDuplicates = 0;
+
+ /*
+ * Do the reading.
+ */
+ while (cb > 0)
+ {
+ char szLine[32 + cchWidth * 4 + 32];
+
+ /* Do the reading. */
+ uint32_t const cbToRead = (uint32_t)RT_MIN(cb, _128K);
+ SafeArray<BYTE> SafeArrayBuf;
+ HRESULT hrc = ptrMediumIO->Read(off, cbToRead, ComSafeArrayAsOutParam(SafeArrayBuf));
+ if (FAILED(hrc))
+ {
+ RTStrPrintf(szLine, sizeof(szLine), Disk::tr("Read(%zu bytes at %#RX64)", "", cbToRead), cbToRead, off);
+ com::GlueHandleComError(ptrMediumIO, szLine, hrc, __FILE__, __LINE__);
+ break;
+ }
+
+ /* Output the data. */
+ size_t const cbReturned = SafeArrayBuf.size();
+ if (cbReturned)
+ {
+ BYTE const *pbBuf = SafeArrayBuf.raw();
+ if (!fHex)
+ vrc = RTStrmWrite(pOut, pbBuf, cbReturned);
+ else
+ {
+ /* hexdump -C */
+ vrc = VINF_SUCCESS;
+ uint64_t offHex = off;
+ uint64_t const offHexEnd = off + cbReturned;
+ while (offHex < offHexEnd)
+ {
+ if ( offHex >= offEndDupCheck
+ || cbHexBuf == 0
+ || memcmp(pbBuf, abHexBuf, cchWidth) != 0
+ || ( cDuplicates == 0
+ && ( offHex + cchWidth >= offEndDupCheck
+ || memcmp(pbBuf + cchWidth, pbBuf, cchWidth) != 0)) )
+ {
+ if (cDuplicates > 0)
+ {
+ RTStrmPrintf(pOut, Disk::tr("********** <ditto x %RU64>\n"), cDuplicates);
+ cDuplicates = 0;
+ }
+
+ size_t cch = RTStrPrintf(szLine, sizeof(szLine), "%012RX64:", offHex);
+ unsigned i;
+ for (i = 0; i < cchWidth && offHex + i < offHexEnd; i++)
+ {
+ static const char s_szHexDigits[17] = "0123456789abcdef";
+ szLine[cch++] = (i & 7) || i == 0 ? ' ' : '-';
+ uint8_t const u8 = pbBuf[i];
+ szLine[cch++] = s_szHexDigits[u8 >> 4];
+ szLine[cch++] = s_szHexDigits[u8 & 0xf];
+ }
+ while (i++ < cchWidth)
+ {
+ szLine[cch++] = ' ';
+ szLine[cch++] = ' ';
+ szLine[cch++] = ' ';
+ }
+ szLine[cch++] = ' ';
+
+ for (i = 0; i < cchWidth && offHex + i < offHexEnd; i++)
+ {
+ uint8_t const u8 = pbBuf[i];
+ szLine[cch++] = u8 < 127 && u8 >= 32 ? u8 : '.';
+ }
+ szLine[cch++] = '\n';
+ szLine[cch] = '\0';
+
+ vrc = RTStrmWrite(pOut, szLine, cch);
+ if (RT_FAILURE(vrc))
+ break;
+
+
+ /* copy bytes over to the duplication detection buffer. */
+ cbHexBuf = (size_t)RT_MIN(cchWidth, offHexEnd - offHex);
+ memcpy(abHexBuf, pbBuf, cbHexBuf);
+ }
+ else
+ cDuplicates++;
+
+ /* Advance to next line. */
+ pbBuf += cchWidth;
+ offHex += cchWidth;
+ }
+ }
+ if (RT_FAILURE(vrc))
+ {
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error writing to '%s': %Rrc"), pszOutput, vrc);
+ break;
+ }
+ }
+
+ /* Advance. */
+ if (cbReturned != cbToRead)
+ {
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Expected read() at offset %RU64 (%#RX64) to return %#zx bytes, only got %#zx!\n",
+ "", cbReturned),
+ off, off, cbReturned, cbToRead);
+ break;
+ }
+ off += cbReturned;
+ cb -= cbReturned;
+ }
+
+ /*
+ * Close output.
+ */
+ if (pOut != g_pStdOut)
+ {
+ vrc = RTStrmClose(pOut);
+ if (RT_FAILURE(vrc))
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error closing '%s': %Rrc"), pszOutput, vrc);
+ }
+ else if (!fHex)
+ RTStrmSetMode(pOut, false, -1);
+ }
+ }
+ return rcExit;
+}
+
+/**
+ * mediumio stream
+ */
+static RTEXITCODE handleMediumIOStream(HandlerArg *a, int iFirst, PMEDIUMIOCOMMONOPT pCommonOpts)
+{
+ /*
+ * Parse the options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ MEDIUMIOCOMMONOPT_DEFS(),
+ { "--output", 'O', RTGETOPT_REQ_STRING },
+ { "--format", 'F', RTGETOPT_REQ_STRING },
+ { "--variant", 'v', RTGETOPT_REQ_STRING }
+ };
+ const char *pszOutput = NULL;
+ MediumVariant_T enmMediumVariant = MediumVariant_Standard;
+ Bstr strFormat;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ MEDIUMIOCOMMONOPT_CASES(pCommonOpts);
+
+ case 'O':
+ pszOutput = ValueUnion.psz;
+ break;
+ case 'F':
+ strFormat = ValueUnion.psz;
+ break;
+ case 'v': // --variant
+ {
+ vrc = parseMediumVariant(ValueUnion.psz, &enmMediumVariant);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Disk::tr("Invalid medium variant '%s'"), ValueUnion.psz);
+ break;
+ }
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ /*
+ * Open the medium for I/O.
+ */
+ ComPtr<IMediumIO> ptrMediumIO;
+ uint64_t cbMedium;
+ RTEXITCODE rcExit = mediumIOOpenMediumForIO(a, pCommonOpts, false /*fWritable*/, ptrMediumIO, &cbMedium);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Do we have an output file or do we write to stdout?
+ */
+ PRTSTREAM pOut = NULL;
+ if (pszOutput && (pszOutput[0] != '-' || pszOutput[1] != '\0'))
+ {
+ vrc = RTStrmOpen(pszOutput, "wb", &pOut);
+ if (RT_FAILURE(vrc))
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error opening '%s' for writing: %Rrc"), pszOutput, vrc);
+ }
+ else
+ {
+ pOut = g_pStdOut;
+ RTStrmSetMode(pOut, true, -1);
+ }
+
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ ComPtr<IDataStream> ptrDataStream;
+ ComPtr<IProgress> ptrProgress;
+
+ com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+ for (ULONG i = 0; i < l_variants.size(); ++i)
+ {
+ ULONG temp = enmMediumVariant;
+ temp &= 1<<i;
+ l_variants [i] = (MediumVariant_T)temp;
+ }
+
+ HRESULT hrc = ptrMediumIO->ConvertToStream(strFormat.raw(), ComSafeArrayAsInParam(l_variants), 10 * _1M, ptrDataStream.asOutParam(), ptrProgress.asOutParam());
+ if (hrc == S_OK)
+ {
+ /* Read until we reached the end of the stream. */
+ for (;;)
+ {
+ SafeArray<BYTE> SafeArrayBuf;
+
+ hrc = ptrDataStream->Read(_64K, 0 /*Infinite wait*/, ComSafeArrayAsOutParam(SafeArrayBuf));
+ if ( FAILED(hrc)
+ || SafeArrayBuf.size() == 0)
+ break;
+
+ /* Output the data. */
+ size_t const cbReturned = SafeArrayBuf.size();
+ if (cbReturned)
+ {
+ BYTE const *pbBuf = SafeArrayBuf.raw();
+ vrc = RTStrmWrite(pOut, pbBuf, cbReturned);
+ if (RT_FAILURE(vrc))
+ {
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error writing to '%s': %Rrc"), pszOutput, vrc);
+ break;
+ }
+ }
+
+ /** @todo Check progress. */
+ }
+ }
+ else
+ {
+ com::GlueHandleComError(ptrMediumIO, "ConvertToStream()", hrc, __FILE__, __LINE__);
+ rcExit = RTEXITCODE_FAILURE;
+ }
+
+ /*
+ * Close output.
+ */
+ if (pOut != g_pStdOut)
+ {
+ vrc = RTStrmClose(pOut);
+ if (RT_FAILURE(vrc))
+ rcExit = RTMsgErrorExitFailure(Disk::tr("Error closing '%s': %Rrc"), pszOutput, vrc);
+ }
+ else
+ RTStrmSetMode(pOut, false, -1);
+ }
+ }
+ return rcExit;
+}
+
+
+RTEXITCODE handleMediumIO(HandlerArg *a)
+{
+ /*
+ * Parse image-option and sub-command.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ MEDIUMIOCOMMONOPT_DEFS(),
+ /* sub-commands */
+ { "formatfat", 1000, RTGETOPT_REQ_NOTHING },
+ { "cat", 1001, RTGETOPT_REQ_NOTHING },
+ { "stream", 1002, RTGETOPT_REQ_NOTHING },
+ };
+ MEDIUMIOCOMMONOPT CommonOpts = { NULL, DeviceType_Null, NULL };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+ RTGETOPTUNION ValueUnion;
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ MEDIUMIOCOMMONOPT_CASES(&CommonOpts);
+
+ /* Sub-commands: */
+ case 1000:
+ setCurrentSubcommand(HELP_SCOPE_MEDIUMIO_FORMATFAT);
+ return handleMediumIOFormatFat(a, GetState.iNext, &CommonOpts);
+ case 1001:
+ setCurrentSubcommand(HELP_SCOPE_MEDIUMIO_CAT);
+ return handleMediumIOCat(a, GetState.iNext, &CommonOpts);
+ case 1002:
+ setCurrentSubcommand(HELP_SCOPE_MEDIUMIO_STREAM);
+ return handleMediumIOStream(a, GetState.iNext, &CommonOpts);
+
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+ return errorNoSubcommand();
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
new file mode 100644
index 00000000..f5a1e446
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
@@ -0,0 +1,3707 @@
+/* $Id: VBoxManageGuestCtrl.cpp $ */
+/** @file
+ * VBoxManage - Implementation of guestcontrol command.
+ */
+
+/*
+ * Copyright (C) 2010-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "VBoxManage.h"
+#include "VBoxManageGuestCtrl.h"
+
+#include <VBox/com/array.h>
+#include <VBox/com/com.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/listeners.h>
+#include <VBox/com/NativeEventQueue.h>
+#include <VBox/com/string.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <VBox/err.h>
+#include <VBox/log.h>
+
+#include <iprt/asm.h>
+#include <iprt/dir.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/list.h>
+#include <iprt/path.h>
+#include <iprt/process.h> /* For RTProcSelf(). */
+#include <iprt/semaphore.h>
+#include <iprt/thread.h>
+#include <iprt/vfs.h>
+
+#include <iprt/cpp/path.h>
+
+#include <map>
+#include <vector>
+
+#ifdef USE_XPCOM_QUEUE
+# include <sys/select.h>
+# include <errno.h>
+#endif
+
+#include <signal.h>
+
+#ifdef RT_OS_DARWIN
+# include <CoreFoundation/CFRunLoop.h>
+#endif
+
+using namespace com;
+
+
+/*********************************************************************************************************************************
+ * Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+#define GCTLCMD_COMMON_OPT_USER 999 /**< The --username option number. */
+#define GCTLCMD_COMMON_OPT_PASSWORD 998 /**< The --password option number. */
+#define GCTLCMD_COMMON_OPT_PASSWORD_FILE 997 /**< The --password-file option number. */
+#define GCTLCMD_COMMON_OPT_DOMAIN 996 /**< The --domain option number. */
+/** Common option definitions. */
+#define GCTLCMD_COMMON_OPTION_DEFS() \
+ { "--user", GCTLCMD_COMMON_OPT_USER, RTGETOPT_REQ_STRING }, \
+ { "--username", GCTLCMD_COMMON_OPT_USER, RTGETOPT_REQ_STRING }, \
+ { "--passwordfile", GCTLCMD_COMMON_OPT_PASSWORD_FILE, RTGETOPT_REQ_STRING }, \
+ { "--password", GCTLCMD_COMMON_OPT_PASSWORD, RTGETOPT_REQ_STRING }, \
+ { "--domain", GCTLCMD_COMMON_OPT_DOMAIN, RTGETOPT_REQ_STRING }, \
+ { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, \
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+
+/** Handles common options in the typical option parsing switch. */
+#define GCTLCMD_COMMON_OPTION_CASES(a_pCtx, a_ch, a_pValueUnion) \
+ case 'v': \
+ case 'q': \
+ case GCTLCMD_COMMON_OPT_USER: \
+ case GCTLCMD_COMMON_OPT_DOMAIN: \
+ case GCTLCMD_COMMON_OPT_PASSWORD: \
+ case GCTLCMD_COMMON_OPT_PASSWORD_FILE: \
+ { \
+ RTEXITCODE rcExitCommon = gctlCtxSetOption(a_pCtx, a_ch, a_pValueUnion); \
+ if (RT_UNLIKELY(rcExitCommon != RTEXITCODE_SUCCESS)) \
+ return rcExitCommon; \
+ } break
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/** Set by the signal handler when current guest control
+ * action shall be aborted. */
+static volatile bool g_fGuestCtrlCanceled = false;
+/** Event semaphore used for wait notifications.
+ * Also being used for the listener implementations in VBoxManageGuestCtrlListener.cpp. */
+ RTSEMEVENT g_SemEventGuestCtrlCanceled = NIL_RTSEMEVENT;
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+/**
+ * Listener declarations.
+ */
+VBOX_LISTENER_DECLARE(GuestFileEventListenerImpl)
+VBOX_LISTENER_DECLARE(GuestProcessEventListenerImpl)
+VBOX_LISTENER_DECLARE(GuestSessionEventListenerImpl)
+VBOX_LISTENER_DECLARE(GuestEventListenerImpl)
+VBOX_LISTENER_DECLARE(GuestAdditionsRunlevelListener)
+
+/**
+ * Definition of a guestcontrol command, with handler and various flags.
+ */
+typedef struct GCTLCMDDEF
+{
+ /** The command name. */
+ const char *pszName;
+
+ /**
+ * Actual command handler callback.
+ *
+ * @param pCtx Pointer to command context to use.
+ */
+ DECLR3CALLBACKMEMBER(RTEXITCODE, pfnHandler, (struct GCTLCMDCTX *pCtx, int argc, char **argv));
+
+ /** The sub-command scope flags. */
+ uint64_t fSubcommandScope;
+ /** Command context flags (GCTLCMDCTX_F_XXX). */
+ uint32_t fCmdCtx;
+} GCTLCMD;
+/** Pointer to a const guest control command definition. */
+typedef GCTLCMDDEF const *PCGCTLCMDDEF;
+
+/** @name GCTLCMDCTX_F_XXX - Command context flags.
+ * @{
+ */
+/** No flags set. */
+#define GCTLCMDCTX_F_NONE 0
+/** Don't install a signal handler (CTRL+C trap). */
+#define GCTLCMDCTX_F_NO_SIGNAL_HANDLER RT_BIT(0)
+/** No guest session needed. */
+#define GCTLCMDCTX_F_SESSION_ANONYMOUS RT_BIT(1)
+/** @} */
+
+/**
+ * Context for handling a specific command.
+ */
+typedef struct GCTLCMDCTX
+{
+ HandlerArg *pArg;
+
+ /** Pointer to the command definition. */
+ PCGCTLCMDDEF pCmdDef;
+ /** The VM name or UUID. */
+ const char *pszVmNameOrUuid;
+
+ /** Whether we've done the post option parsing init already. */
+ bool fPostOptionParsingInited;
+ /** Whether we've locked the VM session. */
+ bool fLockedVmSession;
+ /** Whether to detach (@c true) or close the session. */
+ bool fDetachGuestSession;
+ /** Set if we've installed the signal handler. */
+ bool fInstalledSignalHandler;
+ /** The verbosity level. */
+ uint32_t cVerbose;
+ /** User name. */
+ Utf8Str strUsername;
+ /** Password. */
+ Utf8Str strPassword;
+ /** Domain. */
+ Utf8Str strDomain;
+ /** Pointer to the IGuest interface. */
+ ComPtr<IGuest> pGuest;
+ /** Pointer to the to be used guest session. */
+ ComPtr<IGuestSession> pGuestSession;
+ /** The guest session ID. */
+ ULONG uSessionID;
+
+} GCTLCMDCTX, *PGCTLCMDCTX;
+
+
+/**
+ * An entry for an element which needs to be copied/created to/on the guest.
+ */
+typedef struct DESTFILEENTRY
+{
+ DESTFILEENTRY(Utf8Str strFilename) : mFilename(strFilename) {}
+ Utf8Str mFilename;
+} DESTFILEENTRY, *PDESTFILEENTRY;
+/*
+ * Map for holding destination entries, whereas the key is the destination
+ * directory and the mapped value is a vector holding all elements for this directory.
+ */
+typedef std::map< Utf8Str, std::vector<DESTFILEENTRY> > DESTDIRMAP, *PDESTDIRMAP;
+typedef std::map< Utf8Str, std::vector<DESTFILEENTRY> >::iterator DESTDIRMAPITER, *PDESTDIRMAPITER;
+
+
+enum kStreamTransform
+{
+ kStreamTransform_None = 0,
+ kStreamTransform_Dos2Unix,
+ kStreamTransform_Unix2Dos
+};
+
+
+DECLARE_TRANSLATION_CONTEXT(GuestCtrl);
+
+
+#ifdef RT_OS_WINDOWS
+static BOOL WINAPI gctlSignalHandler(DWORD dwCtrlType) RT_NOTHROW_DEF
+{
+ bool fEventHandled = FALSE;
+ switch (dwCtrlType)
+ {
+ /* User pressed CTRL+C or CTRL+BREAK or an external event was sent
+ * via GenerateConsoleCtrlEvent(). */
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_C_EVENT:
+ ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true);
+ RTSemEventSignal(g_SemEventGuestCtrlCanceled);
+ fEventHandled = TRUE;
+ break;
+ default:
+ break;
+ /** @todo Add other events here. */
+ }
+
+ return fEventHandled;
+}
+#else /* !RT_OS_WINDOWS */
+/**
+ * Signal handler that sets g_fGuestCtrlCanceled.
+ *
+ * This can be executed on any thread in the process, on Windows it may even be
+ * a thread dedicated to delivering this signal. Don't do anything
+ * unnecessary here.
+ */
+static void gctlSignalHandler(int iSignal) RT_NOTHROW_DEF
+{
+ RT_NOREF(iSignal);
+ ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true);
+ RTSemEventSignal(g_SemEventGuestCtrlCanceled);
+}
+#endif
+
+
+/**
+ * Installs a custom signal handler to get notified
+ * whenever the user wants to intercept the program.
+ *
+ * @todo Make this handler available for all VBoxManage modules?
+ */
+static int gctlSignalHandlerInstall(void)
+{
+ g_fGuestCtrlCanceled = false;
+
+ int vrc = VINF_SUCCESS;
+#ifdef RT_OS_WINDOWS
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)gctlSignalHandler, TRUE /* Add handler */))
+ {
+ vrc = RTErrConvertFromWin32(GetLastError());
+ RTMsgError(GuestCtrl::tr("Unable to install console control handler, vrc=%Rrc\n"), vrc);
+ }
+#else
+ signal(SIGINT, gctlSignalHandler);
+ signal(SIGTERM, gctlSignalHandler);
+# ifdef SIGBREAK
+ signal(SIGBREAK, gctlSignalHandler);
+# endif
+#endif
+
+ if (RT_SUCCESS(vrc))
+ vrc = RTSemEventCreate(&g_SemEventGuestCtrlCanceled);
+
+ return vrc;
+}
+
+
+/**
+ * Uninstalls a previously installed signal handler.
+ */
+static int gctlSignalHandlerUninstall(void)
+{
+ int vrc = VINF_SUCCESS;
+#ifdef RT_OS_WINDOWS
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))
+ {
+ vrc = RTErrConvertFromWin32(GetLastError());
+ RTMsgError(GuestCtrl::tr("Unable to uninstall console control handler, vrc=%Rrc\n"), vrc);
+ }
+#else
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+# ifdef SIGBREAK
+ signal(SIGBREAK, SIG_DFL);
+# endif
+#endif
+
+ if (g_SemEventGuestCtrlCanceled != NIL_RTSEMEVENT)
+ {
+ RTSemEventDestroy(g_SemEventGuestCtrlCanceled);
+ g_SemEventGuestCtrlCanceled = NIL_RTSEMEVENT;
+ }
+ return vrc;
+}
+
+
+/**
+ * Translates a process status to a human readable string.
+ *
+ * @sa GuestProcess::i_statusToString()
+ */
+const char *gctlProcessStatusToText(ProcessStatus_T enmStatus)
+{
+ switch (enmStatus)
+ {
+ case ProcessStatus_Starting:
+ return GuestCtrl::tr("starting");
+ case ProcessStatus_Started:
+ return GuestCtrl::tr("started");
+ case ProcessStatus_Paused:
+ return GuestCtrl::tr("paused");
+ case ProcessStatus_Terminating:
+ return GuestCtrl::tr("terminating");
+ case ProcessStatus_TerminatedNormally:
+ return GuestCtrl::tr("successfully terminated");
+ case ProcessStatus_TerminatedSignal:
+ return GuestCtrl::tr("terminated by signal");
+ case ProcessStatus_TerminatedAbnormally:
+ return GuestCtrl::tr("abnormally aborted");
+ case ProcessStatus_TimedOutKilled:
+ return GuestCtrl::tr("timed out");
+ case ProcessStatus_TimedOutAbnormally:
+ return GuestCtrl::tr("timed out, hanging");
+ case ProcessStatus_Down:
+ return GuestCtrl::tr("killed");
+ case ProcessStatus_Error:
+ return GuestCtrl::tr("error");
+ default:
+ break;
+ }
+ return GuestCtrl::tr("unknown");
+}
+
+/**
+ * Translates a guest process wait result to a human readable string.
+ */
+static const char *gctlProcessWaitResultToText(ProcessWaitResult_T enmWaitResult)
+{
+ switch (enmWaitResult)
+ {
+ case ProcessWaitResult_Start:
+ return GuestCtrl::tr("started");
+ case ProcessWaitResult_Terminate:
+ return GuestCtrl::tr("terminated");
+ case ProcessWaitResult_Status:
+ return GuestCtrl::tr("status changed");
+ case ProcessWaitResult_Error:
+ return GuestCtrl::tr("error");
+ case ProcessWaitResult_Timeout:
+ return GuestCtrl::tr("timed out");
+ case ProcessWaitResult_StdIn:
+ return GuestCtrl::tr("stdin ready");
+ case ProcessWaitResult_StdOut:
+ return GuestCtrl::tr("data on stdout");
+ case ProcessWaitResult_StdErr:
+ return GuestCtrl::tr("data on stderr");
+ case ProcessWaitResult_WaitFlagNotSupported:
+ return GuestCtrl::tr("waiting flag not supported");
+ default:
+ break;
+ }
+ return GuestCtrl::tr("unknown");
+}
+
+/**
+ * Translates a guest session status to a human readable string.
+ */
+const char *gctlGuestSessionStatusToText(GuestSessionStatus_T enmStatus)
+{
+ switch (enmStatus)
+ {
+ case GuestSessionStatus_Starting:
+ return GuestCtrl::tr("starting");
+ case GuestSessionStatus_Started:
+ return GuestCtrl::tr("started");
+ case GuestSessionStatus_Terminating:
+ return GuestCtrl::tr("terminating");
+ case GuestSessionStatus_Terminated:
+ return GuestCtrl::tr("terminated");
+ case GuestSessionStatus_TimedOutKilled:
+ return GuestCtrl::tr("timed out");
+ case GuestSessionStatus_TimedOutAbnormally:
+ return GuestCtrl::tr("timed out, hanging");
+ case GuestSessionStatus_Down:
+ return GuestCtrl::tr("killed");
+ case GuestSessionStatus_Error:
+ return GuestCtrl::tr("error");
+ default:
+ break;
+ }
+ return GuestCtrl::tr("unknown");
+}
+
+/**
+ * Translates a guest file status to a human readable string.
+ */
+const char *gctlFileStatusToText(FileStatus_T enmStatus)
+{
+ switch (enmStatus)
+ {
+ case FileStatus_Opening:
+ return GuestCtrl::tr("opening");
+ case FileStatus_Open:
+ return GuestCtrl::tr("open");
+ case FileStatus_Closing:
+ return GuestCtrl::tr("closing");
+ case FileStatus_Closed:
+ return GuestCtrl::tr("closed");
+ case FileStatus_Down:
+ return GuestCtrl::tr("killed");
+ case FileStatus_Error:
+ return GuestCtrl::tr("error");
+ default:
+ break;
+ }
+ return GuestCtrl::tr("unknown");
+}
+
+/**
+ * Translates a file system objec type to a string.
+ */
+const char *gctlFsObjTypeToName(FsObjType_T enmType)
+{
+ switch (enmType)
+ {
+ case FsObjType_Unknown: return GuestCtrl::tr("unknown");
+ case FsObjType_Fifo: return GuestCtrl::tr("fifo");
+ case FsObjType_DevChar: return GuestCtrl::tr("char-device");
+ case FsObjType_Directory: return GuestCtrl::tr("directory");
+ case FsObjType_DevBlock: return GuestCtrl::tr("block-device");
+ case FsObjType_File: return GuestCtrl::tr("file");
+ case FsObjType_Symlink: return GuestCtrl::tr("symlink");
+ case FsObjType_Socket: return GuestCtrl::tr("socket");
+ case FsObjType_WhiteOut: return GuestCtrl::tr("white-out");
+#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
+ case FsObjType_32BitHack: break;
+#endif
+ }
+ return GuestCtrl::tr("unknown");
+}
+
+static int gctlPrintError(com::ErrorInfo &errorInfo)
+{
+ if ( errorInfo.isFullAvailable()
+ || errorInfo.isBasicAvailable())
+ {
+ /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
+ * because it contains more accurate info about what went wrong. */
+ if (errorInfo.getResultCode() == VBOX_E_IPRT_ERROR)
+ RTMsgError("%ls.", errorInfo.getText().raw());
+ else
+ {
+ RTMsgError(GuestCtrl::tr("Error details:"));
+ GluePrintErrorInfo(errorInfo);
+ }
+ return VERR_GENERAL_FAILURE; /** @todo */
+ }
+ AssertMsgFailedReturn((GuestCtrl::tr("Object has indicated no error (%Rhrc)!?\n"), errorInfo.getResultCode()),
+ VERR_INVALID_PARAMETER);
+}
+
+static int gctlPrintError(IUnknown *pObj, const GUID &aIID)
+{
+ com::ErrorInfo ErrInfo(pObj, aIID);
+ return gctlPrintError(ErrInfo);
+}
+
+static int gctlPrintProgressError(ComPtr<IProgress> pProgress)
+{
+ int vrc = VINF_SUCCESS;
+ HRESULT hrc;
+
+ do
+ {
+ BOOL fCanceled;
+ CHECK_ERROR_BREAK(pProgress, COMGETTER(Canceled)(&fCanceled));
+ if (!fCanceled)
+ {
+ LONG rcProc;
+ CHECK_ERROR_BREAK(pProgress, COMGETTER(ResultCode)(&rcProc));
+ if (FAILED(rcProc))
+ {
+ com::ProgressErrorInfo ErrInfo(pProgress);
+ vrc = gctlPrintError(ErrInfo);
+ }
+ }
+
+ } while(0);
+
+ AssertMsgStmt(SUCCEEDED(hrc), (GuestCtrl::tr("Could not lookup progress information\n")), vrc = VERR_COM_UNEXPECTED);
+
+ return vrc;
+}
+
+
+
+/*
+ *
+ *
+ * Guest Control Command Context
+ * Guest Control Command Context
+ * Guest Control Command Context
+ * Guest Control Command Context
+ *
+ *
+ *
+ */
+
+
+/**
+ * Initializes a guest control command context structure.
+ *
+ * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE on failure (after
+ * informing the user of course).
+ * @param pCtx The command context to init.
+ * @param pArg The handle argument package.
+ */
+static RTEXITCODE gctrCmdCtxInit(PGCTLCMDCTX pCtx, HandlerArg *pArg)
+{
+ pCtx->pArg = pArg;
+ pCtx->pCmdDef = NULL;
+ pCtx->pszVmNameOrUuid = NULL;
+ pCtx->fPostOptionParsingInited = false;
+ pCtx->fLockedVmSession = false;
+ pCtx->fDetachGuestSession = false;
+ pCtx->fInstalledSignalHandler = false;
+ pCtx->cVerbose = 0;
+ pCtx->strUsername.setNull();
+ pCtx->strPassword.setNull();
+ pCtx->strDomain.setNull();
+ pCtx->pGuest.setNull();
+ pCtx->pGuestSession.setNull();
+ pCtx->uSessionID = 0;
+
+ /*
+ * The user name defaults to the host one, if we can get at it.
+ */
+ char szUser[1024];
+ int vrc = RTProcQueryUsername(RTProcSelf(), szUser, sizeof(szUser), NULL);
+ if ( RT_SUCCESS(vrc)
+ && RTStrIsValidEncoding(szUser)) /* paranoia was required on posix at some point, not needed any more! */
+ {
+ try
+ {
+ pCtx->strUsername = szUser;
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory"));
+ }
+ }
+ /* else: ignore this failure. */
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Worker for GCTLCMD_COMMON_OPTION_CASES.
+ *
+ * @returns RTEXITCODE_SUCCESS if the option was handled successfully. If not,
+ * an error message is printed and an appropriate failure exit code is
+ * returned.
+ * @param pCtx The guest control command context.
+ * @param ch The option char or ordinal.
+ * @param pValueUnion The option value union.
+ */
+static RTEXITCODE gctlCtxSetOption(PGCTLCMDCTX pCtx, int ch, PRTGETOPTUNION pValueUnion)
+{
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ switch (ch)
+ {
+ case GCTLCMD_COMMON_OPT_USER: /* User name */
+ if (!pCtx->pCmdDef || !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS))
+ pCtx->strUsername = pValueUnion->psz;
+ else
+ RTMsgWarning(GuestCtrl::tr("The --username|-u option is ignored by '%s'"), pCtx->pCmdDef->pszName);
+ break;
+
+ case GCTLCMD_COMMON_OPT_PASSWORD: /* Password */
+ if (!pCtx->pCmdDef || !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS))
+ {
+ if (pCtx->strPassword.isNotEmpty())
+ RTMsgWarning(GuestCtrl::tr("Password is given more than once."));
+ pCtx->strPassword = pValueUnion->psz;
+ }
+ else
+ RTMsgWarning(GuestCtrl::tr("The --password option is ignored by '%s'"), pCtx->pCmdDef->pszName);
+ break;
+
+ case GCTLCMD_COMMON_OPT_PASSWORD_FILE: /* Password file */
+ if (!pCtx->pCmdDef || !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS))
+ rcExit = readPasswordFile(pValueUnion->psz, &pCtx->strPassword);
+ else
+ RTMsgWarning(GuestCtrl::tr("The --password-file|-p option is ignored by '%s'"), pCtx->pCmdDef->pszName);
+ break;
+
+ case GCTLCMD_COMMON_OPT_DOMAIN: /* domain */
+ if (!pCtx->pCmdDef || !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS))
+ pCtx->strDomain = pValueUnion->psz;
+ else
+ RTMsgWarning(GuestCtrl::tr("The --domain option is ignored by '%s'"), pCtx->pCmdDef->pszName);
+ break;
+
+ case 'v': /* --verbose */
+ pCtx->cVerbose++;
+ break;
+
+ case 'q': /* --quiet */
+ if (pCtx->cVerbose)
+ pCtx->cVerbose--;
+ break;
+
+ default:
+ AssertFatalMsgFailed(("ch=%d (%c)\n", ch, ch));
+ }
+ return rcExit;
+}
+
+
+/**
+ * Initializes the VM for IGuest operation.
+ *
+ * This opens a shared session to a running VM and gets hold of IGuest.
+ *
+ * @returns RTEXITCODE_SUCCESS on success. RTEXITCODE_FAILURE and user message
+ * on failure.
+ * @param pCtx The guest control command context.
+ * GCTLCMDCTX::pGuest will be set on success.
+ */
+static RTEXITCODE gctlCtxInitVmSession(PGCTLCMDCTX pCtx)
+{
+ HRESULT hrc;
+ AssertPtr(pCtx);
+ AssertPtr(pCtx->pArg);
+
+ /*
+ * Find the VM and check if it's running.
+ */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(pCtx->pArg->virtualBox, FindMachine(Bstr(pCtx->pszVmNameOrUuid).raw(), machine.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ MachineState_T enmMachineState;
+ CHECK_ERROR(machine, COMGETTER(State)(&enmMachineState));
+ if ( SUCCEEDED(hrc)
+ && enmMachineState == MachineState_Running)
+ {
+ /*
+ * It's running. So, open a session to it and get the IGuest interface.
+ */
+ CHECK_ERROR(machine, LockMachine(pCtx->pArg->session, LockType_Shared));
+ if (SUCCEEDED(hrc))
+ {
+ pCtx->fLockedVmSession = true;
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR(pCtx->pArg->session, COMGETTER(Console)(ptrConsole.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ if (ptrConsole.isNotNull())
+ {
+ CHECK_ERROR(ptrConsole, COMGETTER(Guest)(pCtx->pGuest.asOutParam()));
+ if (SUCCEEDED(hrc))
+ return RTEXITCODE_SUCCESS;
+ }
+ else
+ RTMsgError(GuestCtrl::tr("Failed to get a IConsole pointer for the machine. Is it still running?\n"));
+ }
+ }
+ }
+ else if (SUCCEEDED(hrc))
+ RTMsgError(GuestCtrl::tr("Machine \"%s\" is not running (currently %s)!\n"),
+ pCtx->pszVmNameOrUuid, machineStateToName(enmMachineState, false));
+ }
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Creates a guest session with the VM.
+ *
+ * @retval RTEXITCODE_SUCCESS on success.
+ * @retval RTEXITCODE_FAILURE and user message on failure.
+ * @param pCtx The guest control command context.
+ * GCTCMDCTX::pGuestSession and GCTLCMDCTX::uSessionID
+ * will be set.
+ */
+static RTEXITCODE gctlCtxInitGuestSession(PGCTLCMDCTX pCtx)
+{
+ HRESULT hrc;
+ AssertPtr(pCtx);
+ Assert(!(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS));
+ Assert(pCtx->pGuest.isNotNull());
+
+ /*
+ * Build up a reasonable guest session name. Useful for identifying
+ * a specific session when listing / searching for them.
+ */
+ char *pszSessionName;
+ if (RTStrAPrintf(&pszSessionName,
+ GuestCtrl::tr("[%RU32] VBoxManage Guest Control [%s] - %s"),
+ RTProcSelf(), pCtx->pszVmNameOrUuid, pCtx->pCmdDef->pszName) < 0)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("No enough memory for session name"));
+
+ /*
+ * Create a guest session.
+ */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Creating guest session as user '%s'...\n"), pCtx->strUsername.c_str());
+ try
+ {
+ CHECK_ERROR(pCtx->pGuest, CreateSession(Bstr(pCtx->strUsername).raw(),
+ Bstr(pCtx->strPassword).raw(),
+ Bstr(pCtx->strDomain).raw(),
+ Bstr(pszSessionName).raw(),
+ pCtx->pGuestSession.asOutParam()));
+ }
+ catch (std::bad_alloc &)
+ {
+ RTMsgError(GuestCtrl::tr("Out of memory setting up IGuest::CreateSession call"));
+ hrc = E_OUTOFMEMORY;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ /*
+ * Wait for guest session to start.
+ */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Waiting for guest session to start...\n"));
+ GuestSessionWaitResult_T enmWaitResult = GuestSessionWaitResult_None; /* Shut up MSC */
+ try
+ {
+ com::SafeArray<GuestSessionWaitForFlag_T> aSessionWaitFlags;
+ aSessionWaitFlags.push_back(GuestSessionWaitForFlag_Start);
+ CHECK_ERROR(pCtx->pGuestSession, WaitForArray(ComSafeArrayAsInParam(aSessionWaitFlags),
+ /** @todo Make session handling timeouts configurable. */
+ 30 * 1000, &enmWaitResult));
+ }
+ catch (std::bad_alloc &)
+ {
+ RTMsgError(GuestCtrl::tr("Out of memory setting up IGuestSession::WaitForArray call"));
+ hrc = E_OUTOFMEMORY;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ /* The WaitFlagNotSupported result may happen with GAs older than 4.3. */
+ if ( enmWaitResult == GuestSessionWaitResult_Start
+ || enmWaitResult == GuestSessionWaitResult_WaitFlagNotSupported)
+ {
+ /*
+ * Get the session ID and we're ready to rumble.
+ */
+ CHECK_ERROR(pCtx->pGuestSession, COMGETTER(Id)(&pCtx->uSessionID));
+ if (SUCCEEDED(hrc))
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Successfully started guest session (ID %RU32)\n"), pCtx->uSessionID);
+ RTStrFree(pszSessionName);
+ return RTEXITCODE_SUCCESS;
+ }
+ }
+ else
+ {
+ GuestSessionStatus_T enmSessionStatus;
+ CHECK_ERROR(pCtx->pGuestSession, COMGETTER(Status)(&enmSessionStatus));
+ RTMsgError(GuestCtrl::tr("Error starting guest session (current status is: %s)\n"),
+ SUCCEEDED(hrc) ? gctlGuestSessionStatusToText(enmSessionStatus) : GuestCtrl::tr("<unknown>"));
+ }
+ }
+ }
+
+ RTStrFree(pszSessionName);
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Completes the guest control context initialization after parsing arguments.
+ *
+ * Will validate common arguments, open a VM session, and if requested open a
+ * guest session and install the CTRL-C signal handler.
+ *
+ * It is good to validate all the options and arguments you can before making
+ * this call. However, the VM session, IGuest and IGuestSession interfaces are
+ * not availabe till after this call, so take care.
+ *
+ * @retval RTEXITCODE_SUCCESS on success.
+ * @retval RTEXITCODE_FAILURE and user message on failure.
+ * @param pCtx The guest control command context.
+ * GCTCMDCTX::pGuestSession and GCTLCMDCTX::uSessionID
+ * will be set.
+ * @remarks Can safely be called multiple times, will only do work once.
+ */
+static RTEXITCODE gctlCtxPostOptionParsingInit(PGCTLCMDCTX pCtx)
+{
+ if (pCtx->fPostOptionParsingInited)
+ return RTEXITCODE_SUCCESS;
+
+ /*
+ * Check that the user name isn't empty when we need it.
+ */
+ RTEXITCODE rcExit;
+ if ( (pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS)
+ || pCtx->strUsername.isNotEmpty())
+ {
+ /*
+ * Open the VM session and if required, a guest session.
+ */
+ rcExit = gctlCtxInitVmSession(pCtx);
+ if ( rcExit == RTEXITCODE_SUCCESS
+ && !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS))
+ rcExit = gctlCtxInitGuestSession(pCtx);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ /*
+ * Install signal handler if requested (errors are ignored).
+ */
+ if (!(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_NO_SIGNAL_HANDLER))
+ {
+ int vrc = gctlSignalHandlerInstall();
+ pCtx->fInstalledSignalHandler = RT_SUCCESS(vrc);
+ }
+ }
+ }
+ else
+ rcExit = errorSyntax(GuestCtrl::tr("No user name specified!"));
+
+ pCtx->fPostOptionParsingInited = rcExit == RTEXITCODE_SUCCESS;
+ return rcExit;
+}
+
+
+/**
+ * Cleans up the context when the command returns.
+ *
+ * This will close any open guest session, unless the DETACH flag is set.
+ * It will also close any VM session that may be been established. Any signal
+ * handlers we've installed will also be removed.
+ *
+ * Un-initializes the VM after guest control usage.
+ * @param pCmdCtx Pointer to command context.
+ */
+static void gctlCtxTerm(PGCTLCMDCTX pCtx)
+{
+ HRESULT hrc;
+ AssertPtr(pCtx);
+
+ /*
+ * Uninstall signal handler.
+ */
+ if (pCtx->fInstalledSignalHandler)
+ {
+ gctlSignalHandlerUninstall();
+ pCtx->fInstalledSignalHandler = false;
+ }
+
+ /*
+ * Close, or at least release, the guest session.
+ */
+ if (pCtx->pGuestSession.isNotNull())
+ {
+ if ( !(pCtx->pCmdDef->fCmdCtx & GCTLCMDCTX_F_SESSION_ANONYMOUS)
+ && !pCtx->fDetachGuestSession)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Closing guest session ...\n"));
+
+ CHECK_ERROR(pCtx->pGuestSession, Close());
+ }
+ else if ( pCtx->fDetachGuestSession
+ && pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Guest session detached\n"));
+
+ pCtx->pGuestSession.setNull();
+ }
+
+ /*
+ * Close the VM session.
+ */
+ if (pCtx->fLockedVmSession)
+ {
+ Assert(pCtx->pArg->session.isNotNull());
+ CHECK_ERROR(pCtx->pArg->session, UnlockMachine());
+ pCtx->fLockedVmSession = false;
+ }
+}
+
+
+
+
+
+/*
+ *
+ *
+ * Guest Control Command Handling.
+ * Guest Control Command Handling.
+ * Guest Control Command Handling.
+ * Guest Control Command Handling.
+ * Guest Control Command Handling.
+ *
+ *
+ */
+
+
+/** @name EXITCODEEXEC_XXX - Special run exit codes.
+ *
+ * Special exit codes for returning errors/information of a started guest
+ * process to the command line VBoxManage was started from. Useful for e.g.
+ * scripting.
+ *
+ * ASSUMING that all platforms have at least 7-bits for the exit code we can do
+ * the following mapping:
+ * - Guest exit code 0 is mapped to 0 on the host.
+ * - Guest exit codes 1 thru 93 (0x5d) are displaced by 32, so that 1
+ * becomes 33 (0x21) on the host and 93 becomes 125 (0x7d) on the host.
+ * - Guest exit codes 94 (0x5e) and above are mapped to 126 (0x5e).
+ *
+ * We ASSUME that all VBoxManage status codes are in the range 0 thru 32.
+ *
+ * @note These are frozen as of 4.1.0.
+ * @note The guest exit code mappings was introduced with 5.0 and the 'run'
+ * command, they are/was not supported by 'exec'.
+ * @sa gctlRunCalculateExitCode
+ */
+/** Process exited normally but with an exit code <> 0. */
+#define EXITCODEEXEC_CODE ((RTEXITCODE)16)
+#define EXITCODEEXEC_FAILED ((RTEXITCODE)17)
+#define EXITCODEEXEC_TERM_SIGNAL ((RTEXITCODE)18)
+#define EXITCODEEXEC_TERM_ABEND ((RTEXITCODE)19)
+#define EXITCODEEXEC_TIMEOUT ((RTEXITCODE)20)
+#define EXITCODEEXEC_DOWN ((RTEXITCODE)21)
+/** Execution was interrupt by user (ctrl-c). */
+#define EXITCODEEXEC_CANCELED ((RTEXITCODE)22)
+/** The first mapped guest (non-zero) exit code. */
+#define EXITCODEEXEC_MAPPED_FIRST 33
+/** The last mapped guest (non-zero) exit code value (inclusive). */
+#define EXITCODEEXEC_MAPPED_LAST 125
+/** The number of exit codes from EXITCODEEXEC_MAPPED_FIRST to
+ * EXITCODEEXEC_MAPPED_LAST. This is also the highest guest exit code number
+ * we're able to map. */
+#define EXITCODEEXEC_MAPPED_RANGE (93)
+/** The guest exit code displacement value. */
+#define EXITCODEEXEC_MAPPED_DISPLACEMENT 32
+/** The guest exit code was too big to be mapped. */
+#define EXITCODEEXEC_MAPPED_BIG ((RTEXITCODE)126)
+/** @} */
+
+/**
+ * Calculates the exit code of VBoxManage.
+ *
+ * @returns The exit code to return.
+ * @param enmStatus The guest process status.
+ * @param uExitCode The associated guest process exit code (where
+ * applicable).
+ * @param fReturnExitCodes Set if we're to use the 32-126 range for guest
+ * exit codes.
+ */
+static RTEXITCODE gctlRunCalculateExitCode(ProcessStatus_T enmStatus, ULONG uExitCode, bool fReturnExitCodes)
+{
+ switch (enmStatus)
+ {
+ case ProcessStatus_TerminatedNormally:
+ if (uExitCode == 0)
+ return RTEXITCODE_SUCCESS;
+ if (!fReturnExitCodes)
+ return EXITCODEEXEC_CODE;
+ if (uExitCode <= EXITCODEEXEC_MAPPED_RANGE)
+ return (RTEXITCODE) (uExitCode + EXITCODEEXEC_MAPPED_DISPLACEMENT);
+ return EXITCODEEXEC_MAPPED_BIG;
+
+ case ProcessStatus_TerminatedAbnormally:
+ return EXITCODEEXEC_TERM_ABEND;
+ case ProcessStatus_TerminatedSignal:
+ return EXITCODEEXEC_TERM_SIGNAL;
+
+#if 0 /* see caller! */
+ case ProcessStatus_TimedOutKilled:
+ return EXITCODEEXEC_TIMEOUT;
+ case ProcessStatus_Down:
+ return EXITCODEEXEC_DOWN; /* Service/OS is stopping, process was killed. */
+ case ProcessStatus_Error:
+ return EXITCODEEXEC_FAILED;
+
+ /* The following is probably for detached? */
+ case ProcessStatus_Starting:
+ return RTEXITCODE_SUCCESS;
+ case ProcessStatus_Started:
+ return RTEXITCODE_SUCCESS;
+ case ProcessStatus_Paused:
+ return RTEXITCODE_SUCCESS;
+ case ProcessStatus_Terminating:
+ return RTEXITCODE_SUCCESS; /** @todo ???? */
+#endif
+
+ default:
+ AssertMsgFailed(("Unknown exit status (%u/%u) from guest process returned!\n", enmStatus, uExitCode));
+ return RTEXITCODE_FAILURE;
+ }
+}
+
+
+/**
+ * Pumps guest output to the host.
+ *
+ * @return IPRT status code.
+ * @param pProcess Pointer to appropriate process object.
+ * @param hVfsIosDst Where to write the data. Can be the bit bucket or a (valid [std]) handle.
+ * @param uHandle Handle where to read the data from.
+ * @param cMsTimeout Timeout (in ms) to wait for the operation to
+ * complete.
+ */
+static int gctlRunPumpOutput(IProcess *pProcess, RTVFSIOSTREAM hVfsIosDst, ULONG uHandle, RTMSINTERVAL cMsTimeout)
+{
+ AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
+ Assert(hVfsIosDst != NIL_RTVFSIOSTREAM);
+
+ int vrc;
+
+ SafeArray<BYTE> aOutputData;
+ HRESULT hrc = pProcess->Read(uHandle, _64K, RT_MAX(cMsTimeout, 1), ComSafeArrayAsOutParam(aOutputData));
+ if (SUCCEEDED(hrc))
+ {
+ size_t cbOutputData = aOutputData.size();
+ if (cbOutputData == 0)
+ vrc = VINF_SUCCESS;
+ else
+ {
+ BYTE const *pbBuf = aOutputData.raw();
+ AssertPtr(pbBuf);
+
+ vrc = RTVfsIoStrmWrite(hVfsIosDst, pbBuf, cbOutputData, true /*fBlocking*/, NULL);
+ if (RT_FAILURE(vrc))
+ RTMsgError(GuestCtrl::tr("Unable to write output, vrc=%Rrc\n"), vrc);
+ }
+ }
+ else
+ vrc = gctlPrintError(pProcess, COM_IIDOF(IProcess));
+ return vrc;
+}
+
+
+/**
+ * Configures a host handle for pumping guest bits.
+ *
+ * @returns true if enabled and we successfully configured it.
+ * @param fEnabled Whether pumping this pipe is configured to std handles,
+ * or going to the bit bucket instead.
+ * @param enmHandle The IPRT standard handle designation.
+ * @param pszName The name for user messages.
+ * @param enmTransformation The transformation to apply.
+ * @param phVfsIos Where to return the resulting I/O stream handle.
+ */
+static bool gctlRunSetupHandle(bool fEnabled, RTHANDLESTD enmHandle, const char *pszName,
+ kStreamTransform enmTransformation, PRTVFSIOSTREAM phVfsIos)
+{
+ if (fEnabled)
+ {
+ int vrc = RTVfsIoStrmFromStdHandle(enmHandle, 0, true /*fLeaveOpen*/, phVfsIos);
+ if (RT_SUCCESS(vrc))
+ {
+ if (enmTransformation != kStreamTransform_None)
+ {
+ RTMsgWarning(GuestCtrl::tr("Unsupported %s line ending conversion"), pszName);
+ /** @todo Implement dos2unix and unix2dos stream filters. */
+ }
+ return true;
+ }
+ RTMsgWarning(GuestCtrl::tr("Error getting %s handle: %Rrc"), pszName, vrc);
+ }
+ else /* If disabled, all goes to / gets fed to/from the bit bucket. */
+ {
+ RTFILE hFile;
+ int vrc = RTFileOpenBitBucket(&hFile, enmHandle == RTHANDLESTD_INPUT ? RTFILE_O_READ : RTFILE_O_WRITE);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = RTVfsIoStrmFromRTFile(hFile, 0 /* fOpen */, false /* fLeaveOpen */, phVfsIos);
+ if (RT_SUCCESS(vrc))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**
+ * Returns the remaining time (in ms) based on the start time and a set
+ * timeout value. Returns RT_INDEFINITE_WAIT if no timeout was specified.
+ *
+ * @return RTMSINTERVAL Time left (in ms).
+ * @param u64StartMs Start time (in ms).
+ * @param cMsTimeout Timeout value (in ms).
+ */
+static RTMSINTERVAL gctlRunGetRemainingTime(uint64_t u64StartMs, RTMSINTERVAL cMsTimeout)
+{
+ if (!cMsTimeout || cMsTimeout == RT_INDEFINITE_WAIT) /* If no timeout specified, wait forever. */
+ return RT_INDEFINITE_WAIT;
+
+ uint64_t u64ElapsedMs = RTTimeMilliTS() - u64StartMs;
+ if (u64ElapsedMs >= cMsTimeout)
+ return 0;
+
+ return cMsTimeout - (RTMSINTERVAL)u64ElapsedMs;
+}
+
+/**
+ * Common handler for the 'run' and 'start' commands.
+ *
+ * @returns Command exit code.
+ * @param pCtx Guest session context.
+ * @param argc The argument count.
+ * @param argv The argument vector for this command.
+ * @param fRunCmd Set if it's 'run' clear if 'start'.
+ */
+static RTEXITCODE gctlHandleRunCommon(PGCTLCMDCTX pCtx, int argc, char **argv, bool fRunCmd)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ /*
+ * Parse arguments.
+ */
+ enum kGstCtrlRunOpt
+ {
+ kGstCtrlRunOpt_IgnoreOrphanedProcesses = 1000,
+ kGstCtrlRunOpt_NoProfile, /** @todo Deprecated and will be removed soon; use kGstCtrlRunOpt_Profile instead, if needed. */
+ kGstCtrlRunOpt_Profile,
+ kGstCtrlRunOpt_Dos2Unix,
+ kGstCtrlRunOpt_Unix2Dos,
+ kGstCtrlRunOpt_WaitForStdOut,
+ kGstCtrlRunOpt_NoWaitForStdOut,
+ kGstCtrlRunOpt_WaitForStdErr,
+ kGstCtrlRunOpt_NoWaitForStdErr
+ };
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--arg0", '0', RTGETOPT_REQ_STRING },
+ { "--putenv", 'E', RTGETOPT_REQ_STRING },
+ { "--exe", 'e', RTGETOPT_REQ_STRING },
+ { "--timeout", 't', RTGETOPT_REQ_UINT32 },
+ { "--unquoted-args", 'u', RTGETOPT_REQ_NOTHING },
+ { "--ignore-orphaned-processes", kGstCtrlRunOpt_IgnoreOrphanedProcesses, RTGETOPT_REQ_NOTHING },
+ { "--no-profile", kGstCtrlRunOpt_NoProfile, RTGETOPT_REQ_NOTHING }, /** @todo Deprecated. */
+ { "--profile", kGstCtrlRunOpt_Profile, RTGETOPT_REQ_NOTHING },
+ /* run only: 6 - options */
+ { "--dos2unix", kGstCtrlRunOpt_Dos2Unix, RTGETOPT_REQ_NOTHING },
+ { "--unix2dos", kGstCtrlRunOpt_Unix2Dos, RTGETOPT_REQ_NOTHING },
+ { "--no-wait-stdout", kGstCtrlRunOpt_NoWaitForStdOut, RTGETOPT_REQ_NOTHING },
+ { "--wait-stdout", kGstCtrlRunOpt_WaitForStdOut, RTGETOPT_REQ_NOTHING },
+ { "--no-wait-stderr", kGstCtrlRunOpt_NoWaitForStdErr, RTGETOPT_REQ_NOTHING },
+ { "--wait-stderr", kGstCtrlRunOpt_WaitForStdErr, RTGETOPT_REQ_NOTHING },
+ };
+
+ /** @todo stdin handling. */
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions) - (fRunCmd ? 0 : 6),
+ 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRC(vrc);
+
+ com::SafeArray<ProcessCreateFlag_T> aCreateFlags;
+ com::SafeArray<ProcessWaitForFlag_T> aWaitFlags;
+ com::SafeArray<IN_BSTR> aArgs;
+ com::SafeArray<IN_BSTR> aEnv;
+ const char * pszImage = NULL;
+ const char * pszArg0 = NULL; /* Argument 0 to use. pszImage will be used if not specified. */
+ bool fWaitForStdOut = fRunCmd;
+ bool fWaitForStdErr = fRunCmd;
+ RTVFSIOSTREAM hVfsStdOut = NIL_RTVFSIOSTREAM;
+ RTVFSIOSTREAM hVfsStdErr = NIL_RTVFSIOSTREAM;
+ enum kStreamTransform enmStdOutTransform = kStreamTransform_None;
+ enum kStreamTransform enmStdErrTransform = kStreamTransform_None;
+ RTMSINTERVAL cMsTimeout = 0;
+
+ try
+ {
+ /* Wait for process start in any case. This is useful for scripting VBoxManage
+ * when relying on its overall exit code. */
+ aWaitFlags.push_back(ProcessWaitForFlag_Start);
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'E':
+ if ( ValueUnion.psz[0] == '\0'
+ || ValueUnion.psz[0] == '=')
+ return errorSyntax(GuestCtrl::tr("Invalid argument variable[=value]: '%s'"), ValueUnion.psz);
+ aEnv.push_back(Bstr(ValueUnion.psz).raw());
+ break;
+
+ case kGstCtrlRunOpt_IgnoreOrphanedProcesses:
+ aCreateFlags.push_back(ProcessCreateFlag_IgnoreOrphanedProcesses);
+ break;
+
+ case kGstCtrlRunOpt_NoProfile:
+ /** @todo Deprecated, will be removed. */
+ RTPrintf(GuestCtrl::tr("Warning: Deprecated option \"--no-profile\" specified\n"));
+ break;
+
+ case kGstCtrlRunOpt_Profile:
+ aCreateFlags.push_back(ProcessCreateFlag_Profile);
+ break;
+
+ case '0':
+ pszArg0 = ValueUnion.psz;
+ break;
+
+ case 'e':
+ pszImage = ValueUnion.psz;
+ break;
+
+ case 'u':
+ aCreateFlags.push_back(ProcessCreateFlag_UnquotedArguments);
+ break;
+
+ /** @todo Add a hidden flag. */
+
+ case 't': /* Timeout */
+ cMsTimeout = ValueUnion.u32;
+ break;
+
+ /* run only options: */
+ case kGstCtrlRunOpt_Dos2Unix:
+ Assert(fRunCmd);
+ enmStdErrTransform = enmStdOutTransform = kStreamTransform_Dos2Unix;
+ break;
+ case kGstCtrlRunOpt_Unix2Dos:
+ Assert(fRunCmd);
+ enmStdErrTransform = enmStdOutTransform = kStreamTransform_Unix2Dos;
+ break;
+
+ case kGstCtrlRunOpt_WaitForStdOut:
+ Assert(fRunCmd);
+ fWaitForStdOut = true;
+ break;
+ case kGstCtrlRunOpt_NoWaitForStdOut:
+ Assert(fRunCmd);
+ fWaitForStdOut = false;
+ break;
+
+ case kGstCtrlRunOpt_WaitForStdErr:
+ Assert(fRunCmd);
+ fWaitForStdErr = true;
+ break;
+ case kGstCtrlRunOpt_NoWaitForStdErr:
+ Assert(fRunCmd);
+ fWaitForStdErr = false;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ /* VINF_GETOPT_NOT_OPTION comes after all options have been specified;
+ * so if pszImage still is zero at this stage, we use the first non-option found
+ * as the image being executed. */
+ if (!pszImage)
+ pszImage = ValueUnion.psz;
+ else /* Add anything else to the arguments vector. */
+ aArgs.push_back(Bstr(ValueUnion.psz).raw());
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+
+ } /* switch */
+ } /* while RTGetOpt */
+
+ /* Must have something to execute. */
+ if (!pszImage || !*pszImage)
+ return errorSyntax(GuestCtrl::tr("No executable specified!"));
+
+ /* Set the arg0 argument (descending precedence):
+ * - If an argument 0 is explicitly specified (via "--arg0"), use this as argument 0.
+ * - When an image is specified explicitly (via "--exe <image>"), use <image> as argument 0.
+ * Note: This is (and ever was) the default behavior users expect, so don't change this! */
+ if (pszArg0)
+ aArgs.push_front(Bstr(pszArg0).raw());
+ else
+ aArgs.push_front(Bstr(pszImage).raw());
+
+ if (pCtx->cVerbose) /* Print the final execution parameters in verbose mode. */
+ {
+ RTPrintf(GuestCtrl::tr("Executing:\n Image : %s\n"), pszImage);
+ for (size_t i = 0; i < aArgs.size(); i++)
+ RTPrintf(GuestCtrl::tr(" arg[%d]: %ls\n"), i, aArgs[i]);
+ }
+ /* No altering of aArgs and/or pszImage after this point! */
+
+ /*
+ * Finalize process creation and wait flags and input/output streams.
+ */
+ if (!fRunCmd)
+ {
+ aCreateFlags.push_back(ProcessCreateFlag_WaitForProcessStartOnly);
+ Assert(!fWaitForStdOut);
+ Assert(!fWaitForStdErr);
+ }
+ else
+ {
+ aWaitFlags.push_back(ProcessWaitForFlag_Terminate);
+ fWaitForStdOut = gctlRunSetupHandle(fWaitForStdOut, RTHANDLESTD_OUTPUT, "stdout", enmStdOutTransform, &hVfsStdOut);
+ if (fWaitForStdOut)
+ {
+ aCreateFlags.push_back(ProcessCreateFlag_WaitForStdOut);
+ aWaitFlags.push_back(ProcessWaitForFlag_StdOut);
+ }
+ fWaitForStdErr = gctlRunSetupHandle(fWaitForStdErr, RTHANDLESTD_ERROR, "stderr", enmStdErrTransform, &hVfsStdErr);
+ if (fWaitForStdErr)
+ {
+ aCreateFlags.push_back(ProcessCreateFlag_WaitForStdErr);
+ aWaitFlags.push_back(ProcessWaitForFlag_StdErr);
+ }
+ }
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "VERR_NO_MEMORY\n");
+ }
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ HRESULT hrc;
+
+ try
+ {
+ do
+ {
+ /* Get current time stamp to later calculate rest of timeout left. */
+ uint64_t msStart = RTTimeMilliTS();
+
+ /*
+ * Create the process.
+ */
+ if (pCtx->cVerbose)
+ {
+ if (cMsTimeout == 0)
+ RTPrintf(GuestCtrl::tr("Starting guest process ...\n"));
+ else
+ RTPrintf(GuestCtrl::tr("Starting guest process (within %ums)\n"), cMsTimeout);
+ }
+ ComPtr<IGuestProcess> pProcess;
+ CHECK_ERROR_BREAK(pCtx->pGuestSession, ProcessCreate(Bstr(pszImage).raw(),
+ ComSafeArrayAsInParam(aArgs),
+ ComSafeArrayAsInParam(aEnv),
+ ComSafeArrayAsInParam(aCreateFlags),
+ gctlRunGetRemainingTime(msStart, cMsTimeout),
+ pProcess.asOutParam()));
+
+ /*
+ * Explicitly wait for the guest process to be in a started state.
+ */
+ com::SafeArray<ProcessWaitForFlag_T> aWaitStartFlags;
+ aWaitStartFlags.push_back(ProcessWaitForFlag_Start);
+ ProcessWaitResult_T waitResult;
+ CHECK_ERROR_BREAK(pProcess, WaitForArray(ComSafeArrayAsInParam(aWaitStartFlags),
+ gctlRunGetRemainingTime(msStart, cMsTimeout), &waitResult));
+
+ ULONG uPID = 0;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID));
+ if (fRunCmd && pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process '%s' (PID %RU32) started\n"), pszImage, uPID);
+ else if (!fRunCmd && pCtx->cVerbose)
+ {
+ /* Just print plain PID to make it easier for scripts
+ * invoking VBoxManage. */
+ RTPrintf(GuestCtrl::tr("[%RU32 - Session %RU32]\n"), uPID, pCtx->uSessionID);
+ }
+
+ /*
+ * Wait for process to exit/start...
+ */
+ RTMSINTERVAL cMsTimeLeft = 1; /* Will be calculated. */
+ bool fReadStdOut = false;
+ bool fReadStdErr = false;
+ bool fCompleted = false;
+ bool fCompletedStartCmd = false;
+
+ vrc = VINF_SUCCESS;
+ while ( !fCompleted
+ && cMsTimeLeft > 0)
+ {
+ cMsTimeLeft = gctlRunGetRemainingTime(msStart, cMsTimeout);
+ CHECK_ERROR_BREAK(pProcess, WaitForArray(ComSafeArrayAsInParam(aWaitFlags),
+ RT_MIN(500 /*ms*/, RT_MAX(cMsTimeLeft, 1 /*ms*/)),
+ &waitResult));
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Wait result is '%s' (%d)\n"), gctlProcessWaitResultToText(waitResult), waitResult);
+ switch (waitResult)
+ {
+ case ProcessWaitResult_Start: /** @todo you always wait for 'start', */
+ fCompletedStartCmd = fCompleted = !fRunCmd; /* Only wait for startup if the 'start' command. */
+ if (!fCompleted && aWaitFlags[0] == ProcessWaitForFlag_Start)
+ aWaitFlags[0] = ProcessWaitForFlag_Terminate;
+ break;
+ case ProcessWaitResult_StdOut:
+ fReadStdOut = true;
+ break;
+ case ProcessWaitResult_StdErr:
+ fReadStdErr = true;
+ break;
+ case ProcessWaitResult_Terminate:
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process terminated\n"));
+ /* Process terminated, we're done. */
+ fCompleted = true;
+ break;
+ case ProcessWaitResult_WaitFlagNotSupported:
+ /* The guest does not support waiting for stdout/err, so
+ * yield to reduce the CPU load due to busy waiting. */
+ RTThreadYield();
+ fReadStdOut = fReadStdErr = true;
+ /* Note: In case the user specified explicitly not wanting to wait for stdout / stderr,
+ * the configured VFS handle goes to / will be fed from the bit bucket. */
+ break;
+ case ProcessWaitResult_Timeout:
+ {
+ /** @todo It is really unclear whether we will get stuck with the timeout
+ * result here if the guest side times out the process and fails to
+ * kill the process... To be on the save side, double the IPC and
+ * check the process status every time we time out. */
+ ProcessStatus_T enmProcStatus;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(Status)(&enmProcStatus));
+ if ( enmProcStatus == ProcessStatus_TimedOutKilled
+ || enmProcStatus == ProcessStatus_TimedOutAbnormally)
+ fCompleted = true;
+ fReadStdOut = fReadStdErr = true;
+ break;
+ }
+ case ProcessWaitResult_Status:
+ /* ignore. */
+ break;
+ case ProcessWaitResult_Error:
+ /* waitFor is dead in the water, I think, so better leave the loop. */
+ vrc = VERR_CALLBACK_RETURN;
+ break;
+
+ case ProcessWaitResult_StdIn: AssertFailed(); /* did ask for this! */ break;
+ case ProcessWaitResult_None: AssertFailed(); /* used. */ break;
+ default: AssertFailed(); /* huh? */ break;
+ }
+
+ if (g_fGuestCtrlCanceled)
+ break;
+
+ /*
+ * Pump output as needed.
+ */
+ if (fReadStdOut)
+ {
+ cMsTimeLeft = gctlRunGetRemainingTime(msStart, cMsTimeout);
+ int vrc2 = gctlRunPumpOutput(pProcess, hVfsStdOut, 1 /* StdOut */, cMsTimeLeft);
+ if (RT_FAILURE(vrc2) && RT_SUCCESS(vrc))
+ vrc = vrc2;
+ fReadStdOut = false;
+ }
+ if (fReadStdErr)
+ {
+ cMsTimeLeft = gctlRunGetRemainingTime(msStart, cMsTimeout);
+ int vrc2 = gctlRunPumpOutput(pProcess, hVfsStdErr, 2 /* StdErr */, cMsTimeLeft);
+ if (RT_FAILURE(vrc2) && RT_SUCCESS(vrc))
+ vrc = vrc2;
+ fReadStdErr = false;
+ }
+ if ( RT_FAILURE(vrc)
+ || g_fGuestCtrlCanceled)
+ break;
+
+ /*
+ * Process events before looping.
+ */
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ } /* while */
+
+ /*
+ * Report status back to the user.
+ */
+ if (g_fGuestCtrlCanceled)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process execution aborted!\n"));
+ rcExit = EXITCODEEXEC_CANCELED;
+ }
+ else if (fCompletedStartCmd)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process successfully started!\n"));
+ rcExit = RTEXITCODE_SUCCESS;
+ }
+ else if (fCompleted)
+ {
+ ProcessStatus_T procStatus;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(Status)(&procStatus));
+ if ( procStatus == ProcessStatus_TerminatedNormally
+ || procStatus == ProcessStatus_TerminatedAbnormally
+ || procStatus == ProcessStatus_TerminatedSignal)
+ {
+ LONG lExitCode;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(ExitCode)(&lExitCode));
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Exit code=%u (Status=%u [%s])\n"),
+ lExitCode, procStatus, gctlProcessStatusToText(procStatus));
+
+ rcExit = gctlRunCalculateExitCode(procStatus, lExitCode, true /*fReturnExitCodes*/);
+ }
+ else if ( procStatus == ProcessStatus_TimedOutKilled
+ || procStatus == ProcessStatus_TimedOutAbnormally)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process timed out (guest side) and %s\n"),
+ procStatus == ProcessStatus_TimedOutAbnormally
+ ? GuestCtrl::tr("failed to terminate so far") : GuestCtrl::tr("was terminated"));
+ rcExit = EXITCODEEXEC_TIMEOUT;
+ }
+ else
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process now is in status [%s] (unexpected)\n"),
+ gctlProcessStatusToText(procStatus));
+ rcExit = RTEXITCODE_FAILURE;
+ }
+ }
+ else if (RT_FAILURE_NP(vrc))
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process monitor loop quit with vrc=%Rrc\n"), vrc);
+ rcExit = RTEXITCODE_FAILURE;
+ }
+ else
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Process monitor loop timed out\n"));
+ rcExit = EXITCODEEXEC_TIMEOUT;
+ }
+
+ } while (0);
+ }
+ catch (std::bad_alloc &)
+ {
+ hrc = E_OUTOFMEMORY;
+ }
+
+ /*
+ * Decide what to do with the guest session.
+ *
+ * If it's the 'start' command where detach the guest process after
+ * starting, don't close the guest session it is part of, except on
+ * failure or ctrl-c.
+ *
+ * For the 'run' command the guest process quits with us.
+ */
+ if (!fRunCmd && SUCCEEDED(hrc) && !g_fGuestCtrlCanceled)
+ pCtx->fDetachGuestSession = true;
+
+ /* Make sure we return failure on failure. */
+ if (FAILED(hrc) && rcExit == RTEXITCODE_SUCCESS)
+ rcExit = RTEXITCODE_FAILURE;
+ return rcExit;
+}
+
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleRun(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ return gctlHandleRunCommon(pCtx, argc, argv, true /*fRunCmd*/);
+}
+
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleStart(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ return gctlHandleRunCommon(pCtx, argc, argv, false /*fRunCmd*/);
+}
+
+
+static RTEXITCODE gctlHandleCopy(PGCTLCMDCTX pCtx, int argc, char **argv, bool fHostToGuest)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ /*
+ * IGuest::CopyToGuest is kept as simple as possible to let the developer choose
+ * what and how to implement the file enumeration/recursive lookup, like VBoxManage
+ * does in here.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--follow", 'L', RTGETOPT_REQ_NOTHING }, /* Kept for backwards-compatibility (VBox < 7.0). */
+ { "--dereference", 'L', RTGETOPT_REQ_NOTHING },
+ { "--no-replace", 'n', RTGETOPT_REQ_NOTHING }, /* like "-n" via cp. */
+ { "--recursive", 'R', RTGETOPT_REQ_NOTHING },
+ { "--target-directory", 't', RTGETOPT_REQ_STRING },
+ { "--update", 'u', RTGETOPT_REQ_NOTHING } /* like "-u" via cp. */
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ bool fDstMustBeDir = false;
+ const char *pszDst = NULL;
+ bool fFollow = false;
+ bool fRecursive = false;
+ bool fUpdate = false; /* Whether to copy the file only if it's newer than the target. */
+ bool fNoReplace = false; /* Only copy the file if it does not exist yet. */
+
+ int vrc = VINF_SUCCESS;
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion)) != 0
+ && ch != VINF_GETOPT_NOT_OPTION)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'L':
+ if (!RTStrICmp(ValueUnion.pDef->pszLong, "--follow"))
+ RTMsgWarning("--follow is deprecated; use --dereference instead.");
+ fFollow = true;
+ break;
+
+ case 'n':
+ fNoReplace = true;
+ break;
+
+ case 'R':
+ fRecursive = true;
+ break;
+
+ case 't':
+ pszDst = ValueUnion.psz;
+ fDstMustBeDir = true;
+ break;
+
+ case 'u':
+ fUpdate = true;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ char **papszSources = RTGetOptNonOptionArrayPtr(&GetState);
+ size_t cSources = &argv[argc] - papszSources;
+
+ if (!cSources)
+ return errorSyntax(GuestCtrl::tr("No sources specified!"));
+
+ /* Unless a --target-directory is given, the last argument is the destination, so
+ bump it from the source list. */
+ if (pszDst == NULL && cSources >= 2)
+ pszDst = papszSources[--cSources];
+
+ if (pszDst == NULL)
+ return errorSyntax(GuestCtrl::tr("No destination specified!"));
+
+ char szAbsDst[RTPATH_MAX];
+ if (!fHostToGuest)
+ {
+ vrc = RTPathAbs(pszDst, szAbsDst, sizeof(szAbsDst));
+ if (RT_SUCCESS(vrc))
+ pszDst = szAbsDst;
+ else
+ return RTMsgErrorExitFailure(GuestCtrl::tr("RTPathAbs failed on '%s': %Rrc"), pszDst, vrc);
+ }
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ /*
+ * Done parsing arguments, do some more preparations.
+ */
+ if (pCtx->cVerbose)
+ {
+ if (fHostToGuest)
+ RTPrintf(GuestCtrl::tr("Copying from host to guest ...\n"));
+ else
+ RTPrintf(GuestCtrl::tr("Copying from guest to host ...\n"));
+ }
+
+ HRESULT hrc = S_OK;
+
+ com::SafeArray<IN_BSTR> aSources;
+ com::SafeArray<IN_BSTR> aFilters; /** @todo Populate those? For now we use caller-based globbing. */
+ com::SafeArray<IN_BSTR> aCopyFlags;
+
+ size_t iSrc = 0;
+ for (; iSrc < cSources; iSrc++)
+ {
+ aSources.push_back(Bstr(papszSources[iSrc]).raw());
+ aFilters.push_back(Bstr("").raw()); /* Empty for now. See @todo above. */
+
+ /* Compile the comma-separated list of flags.
+ * Certain flags are only available for specific file system objects, e.g. directories. */
+ bool fIsDir = false;
+ if (fHostToGuest)
+ {
+ RTFSOBJINFO ObjInfo;
+ vrc = RTPathQueryInfo(papszSources[iSrc], &ObjInfo, RTFSOBJATTRADD_NOTHING);
+ if (RT_SUCCESS(vrc))
+ fIsDir = RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
+
+ if (RT_FAILURE(vrc))
+ break;
+ }
+ else /* Guest to host. */
+ {
+ ComPtr<IGuestFsObjInfo> pFsObjInfo;
+ hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(papszSources[iSrc]).raw(), RT_BOOL(fFollow) /* fFollowSymlinks */,
+ pFsObjInfo.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ FsObjType_T enmObjType;
+ CHECK_ERROR(pFsObjInfo,COMGETTER(Type)(&enmObjType));
+ if (SUCCEEDED(hrc))
+ {
+ /* Take action according to source file. */
+ fIsDir = enmObjType == FsObjType_Directory;
+ }
+ }
+
+ if (FAILED(hrc))
+ {
+ vrc = gctlPrintError(pCtx->pGuestSession, COM_IIDOF(IGuestSession));
+ break;
+ }
+ }
+
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Source '%s' is a %s\n"), papszSources[iSrc], fIsDir ? "directory" : "file");
+
+ Utf8Str strCopyFlags;
+ if (fRecursive && fIsDir) /* Only available for directories. Just ignore otherwise. */
+ strCopyFlags += "Recursive,";
+ if (fFollow)
+ strCopyFlags += "FollowLinks,";
+ if (fUpdate) /* Only copy source files which are newer than the destination file. */
+ strCopyFlags += "Update,";
+ if (fNoReplace) /* Do not overwrite files. */
+ strCopyFlags += "NoReplace,";
+ else if (!fNoReplace && fIsDir)
+ strCopyFlags += "CopyIntoExisting,"; /* Only copy into existing directories if "--no-replace" isn't specified. */
+ aCopyFlags.push_back(Bstr(strCopyFlags).raw());
+ }
+
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(GuestCtrl::tr("Error looking file system information for source '%s', vrc=%Rrc"),
+ papszSources[iSrc], vrc);
+
+ ComPtr<IProgress> pProgress;
+ if (fHostToGuest)
+ {
+ hrc = pCtx->pGuestSession->CopyToGuest(ComSafeArrayAsInParam(aSources),
+ ComSafeArrayAsInParam(aFilters), ComSafeArrayAsInParam(aCopyFlags),
+ Bstr(pszDst).raw(), pProgress.asOutParam());
+ }
+ else /* Guest to host. */
+ {
+ hrc = pCtx->pGuestSession->CopyFromGuest(ComSafeArrayAsInParam(aSources),
+ ComSafeArrayAsInParam(aFilters), ComSafeArrayAsInParam(aCopyFlags),
+ Bstr(pszDst).raw(), pProgress.asOutParam());
+ }
+
+ if (FAILED(hrc))
+ {
+ vrc = gctlPrintError(pCtx->pGuestSession, COM_IIDOF(IGuestSession));
+ }
+ else if (pProgress.isNotNull())
+ {
+ if (pCtx->cVerbose)
+ hrc = showProgress(pProgress);
+ else
+ hrc = pProgress->WaitForCompletion(-1 /* No timeout */);
+ if (SUCCEEDED(hrc))
+ CHECK_PROGRESS_ERROR(pProgress, (GuestCtrl::tr("File copy failed")));
+ vrc = gctlPrintProgressError(pProgress);
+ }
+
+ if (RT_FAILURE(vrc))
+ rcExit = RTEXITCODE_FAILURE;
+
+ return rcExit;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleCopyFrom(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ return gctlHandleCopy(pCtx, argc, argv, false /* Guest to host */);
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleCopyTo(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ return gctlHandleCopy(pCtx, argc, argv, true /* Host to guest */);
+}
+
+static DECLCALLBACK(RTEXITCODE) gctrlHandleMkDir(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--mode", 'm', RTGETOPT_REQ_UINT32 },
+ { "--parents", 'P', RTGETOPT_REQ_NOTHING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ SafeArray<DirectoryCreateFlag_T> aDirCreateFlags;
+ uint32_t fDirMode = 0; /* Default mode. */
+ uint32_t cDirsCreated = 0;
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'm': /* Mode */
+ fDirMode = ValueUnion.u32;
+ break;
+
+ case 'P': /* Create parents */
+ aDirCreateFlags.push_back(DirectoryCreateFlag_Parents);
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (cDirsCreated == 0)
+ {
+ /*
+ * First non-option - no more options now.
+ */
+ rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Creating %RU32 directories...\n", "", argc - GetState.iNext + 1),
+ argc - GetState.iNext + 1);
+ }
+ if (g_fGuestCtrlCanceled)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("mkdir was interrupted by Ctrl-C (%u left)\n"),
+ argc - GetState.iNext + 1);
+
+ /*
+ * Create the specified directory.
+ *
+ * On failure we'll change the exit status to failure and
+ * continue with the next directory that needs creating. We do
+ * this because we only create new things, and because this is
+ * how /bin/mkdir works on unix.
+ */
+ cDirsCreated++;
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Creating directory \"%s\" ...\n"), ValueUnion.psz);
+ try
+ {
+ HRESULT hrc;
+ CHECK_ERROR(pCtx->pGuestSession, DirectoryCreate(Bstr(ValueUnion.psz).raw(),
+ fDirMode, ComSafeArrayAsInParam(aDirCreateFlags)));
+ if (FAILED(hrc))
+ rcExit = RTEXITCODE_FAILURE;
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory\n"));
+ }
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (!cDirsCreated)
+ return errorSyntax(GuestCtrl::tr("No directory to create specified!"));
+ return rcExit;
+}
+
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleRmDir(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--recursive", 'R', RTGETOPT_REQ_NOTHING },
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ bool fRecursive = false;
+ uint32_t cDirRemoved = 0;
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'R':
+ fRecursive = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ if (cDirRemoved == 0)
+ {
+ /*
+ * First non-option - no more options now.
+ */
+ rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ if (pCtx->cVerbose)
+ {
+ if (fRecursive)
+ RTPrintf(GuestCtrl::tr("Removing %RU32 directory tree(s)...\n", "", argc - GetState.iNext + 1),
+ argc - GetState.iNext + 1);
+ else
+ RTPrintf(GuestCtrl::tr("Removing %RU32 directorie(s)...\n", "", argc - GetState.iNext + 1),
+ argc - GetState.iNext + 1);
+ }
+ }
+ if (g_fGuestCtrlCanceled)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("rmdir was interrupted by Ctrl-C (%u left)\n"),
+ argc - GetState.iNext + 1);
+
+ cDirRemoved++;
+ HRESULT hrc;
+ if (!fRecursive)
+ {
+ /*
+ * Remove exactly one directory.
+ */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Removing directory \"%s\" ...\n"), ValueUnion.psz);
+ try
+ {
+ CHECK_ERROR(pCtx->pGuestSession, DirectoryRemove(Bstr(ValueUnion.psz).raw()));
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory\n"));
+ }
+ }
+ else
+ {
+ /*
+ * Remove the directory and anything under it, that means files
+ * and everything. This is in the tradition of the Windows NT
+ * CMD.EXE "rmdir /s" operation, a tradition which jpsoft's TCC
+ * strongly warns against (and half-ways questions the sense of).
+ */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Recursively removing directory \"%s\" ...\n"), ValueUnion.psz);
+ try
+ {
+ /** @todo Make flags configurable. */
+ com::SafeArray<DirectoryRemoveRecFlag_T> aRemRecFlags;
+ aRemRecFlags.push_back(DirectoryRemoveRecFlag_ContentAndDir);
+
+ ComPtr<IProgress> ptrProgress;
+ CHECK_ERROR(pCtx->pGuestSession, DirectoryRemoveRecursive(Bstr(ValueUnion.psz).raw(),
+ ComSafeArrayAsInParam(aRemRecFlags),
+ ptrProgress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ if (pCtx->cVerbose)
+ hrc = showProgress(ptrProgress);
+ else
+ hrc = ptrProgress->WaitForCompletion(-1 /* indefinitely */);
+ if (SUCCEEDED(hrc))
+ CHECK_PROGRESS_ERROR(ptrProgress, (GuestCtrl::tr("Directory deletion failed")));
+ ptrProgress.setNull();
+ }
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory during recursive rmdir\n"));
+ }
+ }
+
+ /*
+ * This command returns immediately on failure since it's destructive in nature.
+ */
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ break;
+ }
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (!cDirRemoved)
+ return errorSyntax(GuestCtrl::tr("No directory to remove specified!"));
+ return rcExit;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleRm(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--force", 'f', RTGETOPT_REQ_NOTHING, },
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ uint32_t cFilesDeleted = 0;
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ bool fForce = true;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (cFilesDeleted == 0)
+ {
+ /*
+ * First non-option - no more options now.
+ */
+ rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Removing %RU32 file(s)...\n", "", argc - GetState.iNext + 1),
+ argc - GetState.iNext + 1);
+ }
+ if (g_fGuestCtrlCanceled)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("rm was interrupted by Ctrl-C (%u left)\n"),
+ argc - GetState.iNext + 1);
+
+ /*
+ * Remove the specified file.
+ *
+ * On failure we will by default stop, however, the force option will
+ * by unix traditions force us to ignore errors and continue.
+ */
+ cFilesDeleted++;
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Removing file \"%s\" ...\n", ValueUnion.psz));
+ try
+ {
+ /** @todo How does IGuestSession::FsObjRemove work with read-only files? Do we
+ * need to do some chmod or whatever to better emulate the --force flag? */
+ HRESULT hrc;
+ CHECK_ERROR(pCtx->pGuestSession, FsObjRemove(Bstr(ValueUnion.psz).raw()));
+ if (FAILED(hrc) && !fForce)
+ return RTEXITCODE_FAILURE;
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory\n"));
+ }
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (!cFilesDeleted && !fForce)
+ return errorSyntax(GuestCtrl::tr("No file to remove specified!"));
+ return rcExit;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleMv(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+/** @todo Missing --force/-f flag. */
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ int vrc = VINF_SUCCESS;
+
+ bool fDryrun = false;
+ std::vector< Utf8Str > vecSources;
+ const char *pszDst = NULL;
+ com::SafeArray<FsObjRenameFlag_T> aRenameFlags;
+
+ try
+ {
+ /** @todo Make flags configurable. */
+ aRenameFlags.push_back(FsObjRenameFlag_NoReplace);
+
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(vrc))
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ /** @todo Implement a --dryrun command. */
+ /** @todo Implement rename flags. */
+
+ case VINF_GETOPT_NOT_OPTION:
+ vecSources.push_back(Utf8Str(ValueUnion.psz));
+ pszDst = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+ }
+ catch (std::bad_alloc &)
+ {
+ vrc = VERR_NO_MEMORY;
+ }
+
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Failed to initialize, vrc=%Rrc\n"), vrc);
+
+ size_t cSources = vecSources.size();
+ if (!cSources)
+ return errorSyntax(GuestCtrl::tr("No source(s) to move specified!"));
+ if (cSources < 2)
+ return errorSyntax(GuestCtrl::tr("No destination specified!"));
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ /* Delete last element, which now is the destination. */
+ vecSources.pop_back();
+ cSources = vecSources.size();
+
+ HRESULT hrc = S_OK;
+
+ /* Destination must be a directory when specifying multiple sources. */
+ if (cSources > 1)
+ {
+ ComPtr<IGuestFsObjInfo> pFsObjInfo;
+ hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(pszDst).raw(), FALSE /*followSymlinks*/, pFsObjInfo.asOutParam());
+ if (FAILED(hrc))
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Destination does not exist\n"));
+ }
+ else
+ {
+ FsObjType_T enmObjType = FsObjType_Unknown; /* Shut up MSC */
+ hrc = pFsObjInfo->COMGETTER(Type)(&enmObjType);
+ if (SUCCEEDED(hrc))
+ {
+ if (enmObjType != FsObjType_Directory)
+ return RTMsgErrorExit(RTEXITCODE_FAILURE,
+ GuestCtrl::tr("Destination must be a directory when specifying multiple sources\n"));
+ }
+ else
+ return RTMsgErrorExit(RTEXITCODE_FAILURE,
+ GuestCtrl::tr("Unable to determine destination type: %Rhrc\n"),
+ hrc);
+ }
+ }
+
+ /*
+ * Rename (move) the entries.
+ */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Renaming %RU32 %s ...\n"), cSources,
+ cSources > 1 ? GuestCtrl::tr("sources", "", cSources) : GuestCtrl::tr("source"));
+
+ std::vector< Utf8Str >::iterator it = vecSources.begin();
+ while ( it != vecSources.end()
+ && !g_fGuestCtrlCanceled)
+ {
+ Utf8Str strSrcCur = (*it);
+
+ ComPtr<IGuestFsObjInfo> pFsObjInfo;
+ FsObjType_T enmObjType = FsObjType_Unknown; /* Shut up MSC */
+ hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(strSrcCur).raw(), FALSE /*followSymlinks*/, pFsObjInfo.asOutParam());
+ if (SUCCEEDED(hrc))
+ hrc = pFsObjInfo->COMGETTER(Type)(&enmObjType);
+ if (FAILED(hrc))
+ {
+ RTPrintf(GuestCtrl::tr("Cannot stat \"%s\": No such file or directory\n"), strSrcCur.c_str());
+ ++it;
+ continue; /* Skip. */
+ }
+
+ char *pszDstCur = NULL;
+
+ if (cSources > 1)
+ {
+ pszDstCur = RTPathJoinA(pszDst, RTPathFilename(strSrcCur.c_str()));
+ }
+ else
+ pszDstCur = RTStrDup(pszDst);
+
+ AssertPtrBreakStmt(pszDstCur, VERR_NO_MEMORY);
+
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Renaming %s \"%s\" to \"%s\" ...\n"),
+ enmObjType == FsObjType_Directory ? GuestCtrl::tr("directory", "object") : GuestCtrl::tr("file","object"),
+ strSrcCur.c_str(), pszDstCur);
+
+ if (!fDryrun)
+ {
+ CHECK_ERROR(pCtx->pGuestSession, FsObjRename(Bstr(strSrcCur).raw(),
+ Bstr(pszDstCur).raw(),
+ ComSafeArrayAsInParam(aRenameFlags)));
+ /* Keep going with next item in case of errors. */
+ }
+
+ RTStrFree(pszDstCur);
+
+ ++it;
+ }
+
+ if ( (it != vecSources.end())
+ && pCtx->cVerbose)
+ {
+ RTPrintf(GuestCtrl::tr("Warning: Not all sources were renamed\n"));
+ }
+
+ return FAILED(hrc) ? RTEXITCODE_FAILURE : RTEXITCODE_SUCCESS;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleMkTemp(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--mode", 'm', RTGETOPT_REQ_UINT32 },
+ { "--directory", 'D', RTGETOPT_REQ_NOTHING },
+ { "--secure", 's', RTGETOPT_REQ_NOTHING },
+ { "--tmpdir", 't', RTGETOPT_REQ_STRING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ Utf8Str strTemplate;
+ uint32_t fMode = 0; /* Default mode. */
+ bool fDirectory = false;
+ bool fSecure = false;
+ Utf8Str strTempDir;
+
+ DESTDIRMAP mapDirs;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'm': /* Mode */
+ fMode = ValueUnion.u32;
+ break;
+
+ case 'D': /* Create directory */
+ fDirectory = true;
+ break;
+
+ case 's': /* Secure */
+ fSecure = true;
+ break;
+
+ case 't': /* Temp directory */
+ strTempDir = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (strTemplate.isEmpty())
+ strTemplate = ValueUnion.psz;
+ else
+ return errorSyntax(GuestCtrl::tr("More than one template specified!\n"));
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (strTemplate.isEmpty())
+ return errorSyntax(GuestCtrl::tr("No template specified!"));
+
+ if (!fDirectory)
+ return errorSyntax(GuestCtrl::tr("Creating temporary files is currently not supported!"));
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ /*
+ * Create the directories.
+ */
+ if (pCtx->cVerbose)
+ {
+ if (fDirectory && !strTempDir.isEmpty())
+ RTPrintf(GuestCtrl::tr("Creating temporary directory from template '%s' in directory '%s' ...\n"),
+ strTemplate.c_str(), strTempDir.c_str());
+ else if (fDirectory)
+ RTPrintf(GuestCtrl::tr("Creating temporary directory from template '%s' in default temporary directory ...\n"),
+ strTemplate.c_str());
+ else if (!fDirectory && !strTempDir.isEmpty())
+ RTPrintf(GuestCtrl::tr("Creating temporary file from template '%s' in directory '%s' ...\n"),
+ strTemplate.c_str(), strTempDir.c_str());
+ else if (!fDirectory)
+ RTPrintf(GuestCtrl::tr("Creating temporary file from template '%s' in default temporary directory ...\n"),
+ strTemplate.c_str());
+ }
+
+ HRESULT hrc = S_OK;
+ if (fDirectory)
+ {
+ Bstr bstrDirectory;
+ CHECK_ERROR(pCtx->pGuestSession, DirectoryCreateTemp(Bstr(strTemplate).raw(),
+ fMode, Bstr(strTempDir).raw(),
+ fSecure,
+ bstrDirectory.asOutParam()));
+ if (SUCCEEDED(hrc))
+ RTPrintf(GuestCtrl::tr("Directory name: %ls\n"), bstrDirectory.raw());
+ }
+ else
+ {
+ // else - temporary file not yet implemented
+ /** @todo implement temporary file creation (we fend it off above, no
+ * worries). */
+ hrc = E_FAIL;
+ }
+
+ return FAILED(hrc) ? RTEXITCODE_FAILURE : RTEXITCODE_SUCCESS;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleStat(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--dereference", 'L', RTGETOPT_REQ_NOTHING },
+ { "--file-system", 'f', RTGETOPT_REQ_NOTHING },
+ { "--format", 'c', RTGETOPT_REQ_STRING },
+ { "--terse", 't', RTGETOPT_REQ_NOTHING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion)) != 0
+ && ch != VINF_GETOPT_NOT_OPTION)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'L': /* Dereference */
+ case 'f': /* File-system */
+ case 'c': /* Format */
+ case 't': /* Terse */
+ return errorSyntax(GuestCtrl::tr("Command \"%s\" not implemented yet!"), ValueUnion.psz);
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (ch != VINF_GETOPT_NOT_OPTION)
+ return errorSyntax(GuestCtrl::tr("Nothing to stat!"));
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+
+ /*
+ * Do the file stat'ing.
+ */
+ while (ch == VINF_GETOPT_NOT_OPTION)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Checking for element \"%s\" ...\n"), ValueUnion.psz);
+
+ ComPtr<IGuestFsObjInfo> pFsObjInfo;
+ HRESULT hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(ValueUnion.psz).raw(), FALSE /*followSymlinks*/,
+ pFsObjInfo.asOutParam());
+ if (FAILED(hrc))
+ {
+ /** @todo r=bird: There might be other reasons why we end up here than
+ * non-existing "element" (object or file, please, nobody calls it elements). */
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Failed to stat '%s': No such file\n"), ValueUnion.psz);
+ rcExit = RTEXITCODE_FAILURE;
+ }
+ else
+ {
+ RTPrintf(GuestCtrl::tr(" File: '%s'\n"), ValueUnion.psz); /** @todo escape this name. */
+
+ FsObjType_T enmType = FsObjType_Unknown;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(Type)(&enmType));
+ LONG64 cbObject = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(ObjectSize)(&cbObject));
+ LONG64 cbAllocated = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(AllocatedSize)(&cbAllocated));
+ LONG uid = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(UID)(&uid));
+ LONG gid = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(GID)(&gid));
+ Bstr bstrUsername;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(UserName)(bstrUsername.asOutParam()));
+ Bstr bstrGroupName;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(GroupName)(bstrGroupName.asOutParam()));
+ Bstr bstrAttribs;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(FileAttributes)(bstrAttribs.asOutParam()));
+ LONG64 idNode = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(NodeId)(&idNode));
+ ULONG uDevNode = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(NodeIdDevice)(&uDevNode));
+ ULONG uDeviceNo = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(DeviceNumber)(&uDeviceNo));
+ ULONG cHardLinks = 1;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(HardLinks)(&cHardLinks));
+ LONG64 nsBirthTime = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(BirthTime)(&nsBirthTime));
+ LONG64 nsChangeTime = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(ChangeTime)(&nsChangeTime));
+ LONG64 nsModificationTime = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(ModificationTime)(&nsModificationTime));
+ LONG64 nsAccessTime = 0;
+ CHECK_ERROR2I(pFsObjInfo, COMGETTER(AccessTime)(&nsAccessTime));
+
+ RTPrintf(GuestCtrl::tr(" Size: %-17RU64 Alloc: %-19RU64 Type: %s\n"),
+ cbObject, cbAllocated, gctlFsObjTypeToName(enmType));
+ RTPrintf(GuestCtrl::tr("Device: %#-17RX32 INode: %-18RU64 Links: %u\n"), uDevNode, idNode, cHardLinks);
+
+ Utf8Str strAttrib(bstrAttribs);
+ char *pszMode = strAttrib.mutableRaw();
+ char *pszAttribs = strchr(pszMode, ' ');
+ if (pszAttribs)
+ do *pszAttribs++ = '\0';
+ while (*pszAttribs == ' ');
+ else
+ pszAttribs = strchr(pszMode, '\0');
+ if (uDeviceNo != 0)
+ RTPrintf(GuestCtrl::tr(" Mode: %-16s Attrib: %-17s Dev ID: %#RX32\n"), pszMode, pszAttribs, uDeviceNo);
+ else
+ RTPrintf(GuestCtrl::tr(" Mode: %-16s Attrib: %s\n"), pszMode, pszAttribs);
+
+ RTPrintf(GuestCtrl::tr(" Owner: %4d/%-12ls Group: %4d/%ls\n"), uid, bstrUsername.raw(), gid, bstrGroupName.raw());
+
+ RTTIMESPEC TimeSpec;
+ char szTmp[RTTIME_STR_LEN];
+ RTPrintf(GuestCtrl::tr(" Birth: %s\n"), RTTimeSpecToString(RTTimeSpecSetNano(&TimeSpec, nsBirthTime),
+ szTmp, sizeof(szTmp)));
+ RTPrintf(GuestCtrl::tr("Change: %s\n"), RTTimeSpecToString(RTTimeSpecSetNano(&TimeSpec, nsChangeTime),
+ szTmp, sizeof(szTmp)));
+ RTPrintf(GuestCtrl::tr("Modify: %s\n"), RTTimeSpecToString(RTTimeSpecSetNano(&TimeSpec, nsModificationTime),
+ szTmp, sizeof(szTmp)));
+ RTPrintf(GuestCtrl::tr("Access: %s\n"), RTTimeSpecToString(RTTimeSpecSetNano(&TimeSpec, nsAccessTime),
+ szTmp, sizeof(szTmp)));
+
+ /* Skiping: Generation ID - only the ISO9660 VFS sets this. FreeBSD user flags. */
+ }
+
+ /* Next file. */
+ ch = RTGetOpt(&GetState, &ValueUnion);
+ }
+
+ return rcExit;
+}
+
+/**
+ * Waits for a Guest Additions run level being reached.
+ *
+ * @returns VBox status code.
+ * Returns VERR_CANCELLED if waiting for cancelled due to signal handling, e.g. when CTRL+C or some sort was pressed.
+ * @param pCtx The guest control command context.
+ * @param enmRunLevel Run level to wait for.
+ * @param cMsTimeout Timeout (in ms) for waiting.
+ */
+static int gctlWaitForRunLevel(PGCTLCMDCTX pCtx, AdditionsRunLevelType_T enmRunLevel, RTMSINTERVAL cMsTimeout)
+{
+ int vrc = VINF_SUCCESS; /* Shut up MSVC. */
+
+ try
+ {
+ HRESULT hrc = S_OK;
+ /** Whether we need to actually wait for the run level or if we already reached it. */
+ bool fWait = false;
+
+ /* Install an event handler first to catch any runlevel changes. */
+ ComObjPtr<GuestAdditionsRunlevelListenerImpl> pGuestListener;
+ do
+ {
+ /* Listener creation. */
+ pGuestListener.createObject();
+ pGuestListener->init(new GuestAdditionsRunlevelListener(enmRunLevel));
+
+ /* Register for IGuest events. */
+ ComPtr<IEventSource> es;
+ CHECK_ERROR_BREAK(pCtx->pGuest, COMGETTER(EventSource)(es.asOutParam()));
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnGuestAdditionsStatusChanged);
+ CHECK_ERROR_BREAK(es, RegisterListener(pGuestListener, ComSafeArrayAsInParam(eventTypes),
+ true /* Active listener */));
+
+ AdditionsRunLevelType_T enmRunLevelCur = AdditionsRunLevelType_None;
+ CHECK_ERROR_BREAK(pCtx->pGuest, COMGETTER(AdditionsRunLevel)(&enmRunLevelCur));
+ fWait = enmRunLevelCur != enmRunLevel;
+
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Current run level is %RU32\n"), enmRunLevelCur);
+
+ } while (0);
+
+ if (fWait)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Waiting for run level %RU32 ...\n"), enmRunLevel);
+
+ RTMSINTERVAL tsStart = RTTimeMilliTS();
+ while (RTTimeMilliTS() - tsStart < cMsTimeout)
+ {
+ /* Wait for the global signal semaphore getting signalled. */
+ vrc = RTSemEventWait(g_SemEventGuestCtrlCanceled, 100 /* ms */);
+ if (RT_FAILURE(vrc))
+ {
+ if (vrc == VERR_TIMEOUT)
+ continue;
+ else
+ {
+ RTPrintf(GuestCtrl::tr("Waiting failed with %Rrc\n"), vrc);
+ break;
+ }
+ }
+ else if (pCtx->cVerbose)
+ {
+ RTPrintf(GuestCtrl::tr("Run level %RU32 reached\n"), enmRunLevel);
+ break;
+ }
+
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ }
+
+ if ( vrc == VERR_TIMEOUT
+ && pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Run level %RU32 not reached within time\n"), enmRunLevel);
+ }
+
+ if (!pGuestListener.isNull())
+ {
+ /* Guest callback unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR(pCtx->pGuest, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR(pES, UnregisterListener(pGuestListener));
+ pGuestListener.setNull();
+ }
+
+ if (g_fGuestCtrlCanceled)
+ vrc = VERR_CANCELLED;
+ }
+ catch (std::bad_alloc &)
+ {
+ vrc = VERR_NO_MEMORY;
+ }
+
+ return vrc;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleUpdateAdditions(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ /** Timeout to wait for the whole updating procedure to complete. */
+ uint32_t cMsTimeout = RT_INDEFINITE_WAIT;
+ /** Source path to .ISO Guest Additions file to use. */
+ Utf8Str strSource;
+ com::SafeArray<IN_BSTR> aArgs;
+ /** Whether to reboot the guest automatically when the update process has finished successfully. */
+ bool fRebootOnFinish = false;
+ /** Whether to only wait for getting the update process started instead of waiting until it finishes. */
+ bool fWaitStartOnly = false;
+ /** Whether to wait for the VM being ready to start the update. Needs Guest Additions facility reporting. */
+ bool fWaitReady = false;
+ /** Whether to verify if the Guest Additions were successfully updated on the guest. */
+ bool fVerify = false;
+
+ /*
+ * Parse arguments.
+ */
+ enum KGSTCTRLUPDATEADDITIONSOPT
+ {
+ KGSTCTRLUPDATEADDITIONSOPT_REBOOT = 1000,
+ KGSTCTRLUPDATEADDITIONSOPT_SOURCE,
+ KGSTCTRLUPDATEADDITIONSOPT_TIMEOUT,
+ KGSTCTRLUPDATEADDITIONSOPT_VERIFY,
+ KGSTCTRLUPDATEADDITIONSOPT_WAITREADY,
+ KGSTCTRLUPDATEADDITIONSOPT_WAITSTART
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--reboot", KGSTCTRLUPDATEADDITIONSOPT_REBOOT, RTGETOPT_REQ_NOTHING },
+ { "--source", KGSTCTRLUPDATEADDITIONSOPT_SOURCE, RTGETOPT_REQ_STRING },
+ { "--timeout", KGSTCTRLUPDATEADDITIONSOPT_TIMEOUT, RTGETOPT_REQ_UINT32 },
+ { "--verify", KGSTCTRLUPDATEADDITIONSOPT_VERIFY, RTGETOPT_REQ_NOTHING },
+ { "--wait-ready", KGSTCTRLUPDATEADDITIONSOPT_WAITREADY, RTGETOPT_REQ_NOTHING },
+ { "--wait-start", KGSTCTRLUPDATEADDITIONSOPT_WAITSTART, RTGETOPT_REQ_NOTHING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ int vrc = VINF_SUCCESS;
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(vrc))
+ {
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case KGSTCTRLUPDATEADDITIONSOPT_REBOOT:
+ fRebootOnFinish = true;
+ break;
+
+ case KGSTCTRLUPDATEADDITIONSOPT_SOURCE:
+ vrc = RTPathAbsCxx(strSource, ValueUnion.psz);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(GuestCtrl::tr("RTPathAbsCxx failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ break;
+
+ case KGSTCTRLUPDATEADDITIONSOPT_WAITSTART:
+ fWaitStartOnly = true;
+ break;
+
+ case KGSTCTRLUPDATEADDITIONSOPT_WAITREADY:
+ fWaitReady = true;
+ break;
+
+ case KGSTCTRLUPDATEADDITIONSOPT_VERIFY:
+ fVerify = true;
+ fRebootOnFinish = true; /* Verification needs a mandatory reboot after successful update. */
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (aArgs.size() == 0 && strSource.isEmpty())
+ strSource = ValueUnion.psz;
+ else
+ aArgs.push_back(Bstr(ValueUnion.psz).raw());
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Updating Guest Additions ...\n"));
+
+ HRESULT hrc = S_OK;
+ while (strSource.isEmpty())
+ {
+ ComPtr<ISystemProperties> pProperties;
+ CHECK_ERROR_BREAK(pCtx->pArg->virtualBox, COMGETTER(SystemProperties)(pProperties.asOutParam()));
+ Bstr strISO;
+ CHECK_ERROR_BREAK(pProperties, COMGETTER(DefaultAdditionsISO)(strISO.asOutParam()));
+ strSource = strISO;
+ break;
+ }
+
+ /* Determine source if not set yet. */
+ if (strSource.isEmpty())
+ {
+ RTMsgError(GuestCtrl::tr("No Guest Additions source found or specified, aborting\n"));
+ vrc = VERR_FILE_NOT_FOUND;
+ }
+ else if (!RTFileExists(strSource.c_str()))
+ {
+ RTMsgError(GuestCtrl::tr("Source \"%s\" does not exist!\n"), strSource.c_str());
+ vrc = VERR_FILE_NOT_FOUND;
+ }
+
+
+
+#if 0
+ ComPtr<IGuest> guest;
+ HRESULT hrc = pConsole->COMGETTER(Guest)(guest.asOutParam());
+ if (SUCCEEDED(hrc) && !guest.isNull())
+ {
+ SHOW_STRING_PROP_NOT_EMPTY(guest, OSTypeId, "GuestOSType", GuestCtrl::tr("OS type:"));
+
+ AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
+ hrc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
+ if (SUCCEEDED(hrc))
+ SHOW_ULONG_VALUE("GuestAdditionsRunLevel", GuestCtrl::tr("Additions run level:"), (ULONG)guestRunLevel, "");
+
+ Bstr guestString;
+ hrc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
+ if ( SUCCEEDED(hrc)
+ && !guestString.isEmpty())
+ {
+ ULONG uRevision;
+ hrc = guest->COMGETTER(AdditionsRevision)(&uRevision);
+ if (FAILED(hrc))
+ uRevision = 0;
+ RTStrPrintf(szValue, sizeof(szValue), "%ls r%u", guestString.raw(), uRevision);
+ SHOW_UTF8_STRING("GuestAdditionsVersion", GuestCtrl::tr("Additions version:"), szValue);
+ }
+ }
+#endif
+
+ if (RT_SUCCESS(vrc))
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Using source: %s\n"), strSource.c_str());
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ if (fWaitReady)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Waiting for current Guest Additions inside VM getting ready for updating ...\n"));
+
+ const uint64_t uTsStart = RTTimeMilliTS();
+ vrc = gctlWaitForRunLevel(pCtx, AdditionsRunLevelType_Userland, cMsTimeout);
+ if (RT_SUCCESS(vrc))
+ cMsTimeout = cMsTimeout != RT_INDEFINITE_WAIT ? cMsTimeout - (RTTimeMilliTS() - uTsStart) : cMsTimeout;
+ }
+
+ if (RT_SUCCESS(vrc))
+ {
+ /* Get current Guest Additions version / revision. */
+ Bstr strGstVerCur;
+ ULONG uGstRevCur = 0;
+ hrc = pCtx->pGuest->COMGETTER(AdditionsVersion)(strGstVerCur.asOutParam());
+ if ( SUCCEEDED(hrc)
+ && !strGstVerCur.isEmpty())
+ {
+ hrc = pCtx->pGuest->COMGETTER(AdditionsRevision)(&uGstRevCur);
+ if (SUCCEEDED(hrc))
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Guest Additions %lsr%RU64 currently installed, waiting for Guest Additions installer to start ...\n"),
+ strGstVerCur.raw(), uGstRevCur);
+ }
+ }
+
+ com::SafeArray<AdditionsUpdateFlag_T> aUpdateFlags;
+ if (fWaitStartOnly)
+ aUpdateFlags.push_back(AdditionsUpdateFlag_WaitForUpdateStartOnly);
+
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR(pCtx->pGuest, UpdateGuestAdditions(Bstr(strSource).raw(),
+ ComSafeArrayAsInParam(aArgs),
+ ComSafeArrayAsInParam(aUpdateFlags),
+ pProgress.asOutParam()));
+ if (FAILED(hrc))
+ vrc = gctlPrintError(pCtx->pGuest, COM_IIDOF(IGuest));
+ else
+ {
+ if (pCtx->cVerbose)
+ hrc = showProgress(pProgress);
+ else
+ hrc = pProgress->WaitForCompletion((int32_t)cMsTimeout);
+
+ if (SUCCEEDED(hrc))
+ CHECK_PROGRESS_ERROR(pProgress, (GuestCtrl::tr("Guest Additions update failed")));
+ vrc = gctlPrintProgressError(pProgress);
+ if (RT_SUCCESS(vrc))
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Guest Additions update successful.\n"));
+
+ if (fRebootOnFinish)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Rebooting guest ...\n"));
+ com::SafeArray<GuestShutdownFlag_T> aShutdownFlags;
+ aShutdownFlags.push_back(GuestShutdownFlag_Reboot);
+ CHECK_ERROR(pCtx->pGuest, Shutdown(ComSafeArrayAsInParam(aShutdownFlags)));
+ if (FAILED(hrc))
+ {
+ if (hrc == VBOX_E_NOT_SUPPORTED)
+ {
+ RTPrintf(GuestCtrl::tr("Current installed Guest Additions don't support automatic rebooting. "
+ "Please reboot manually.\n"));
+ vrc = VERR_NOT_SUPPORTED;
+ }
+ else
+ vrc = gctlPrintError(pCtx->pGuest, COM_IIDOF(IGuest));
+ }
+ else
+ {
+ if (fWaitReady)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Waiting for new Guest Additions inside VM getting ready ...\n"));
+
+ vrc = gctlWaitForRunLevel(pCtx, AdditionsRunLevelType_Userland, cMsTimeout);
+ if (RT_SUCCESS(vrc))
+ {
+ if (fVerify)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Verifying Guest Additions update ...\n"));
+
+ /* Get new Guest Additions version / revision. */
+ Bstr strGstVerNew;
+ ULONG uGstRevNew = 0;
+ hrc = pCtx->pGuest->COMGETTER(AdditionsVersion)(strGstVerNew.asOutParam());
+ if ( SUCCEEDED(hrc)
+ && !strGstVerNew.isEmpty())
+ {
+ hrc = pCtx->pGuest->COMGETTER(AdditionsRevision)(&uGstRevNew);
+ if (FAILED(hrc))
+ uGstRevNew = 0;
+ }
+
+ /** @todo Do more verification here. */
+ vrc = uGstRevNew > uGstRevCur ? VINF_SUCCESS : VERR_NO_CHANGE;
+
+ if (pCtx->cVerbose)
+ {
+ RTPrintf(GuestCtrl::tr("Old Guest Additions: %ls%RU64\n"), strGstVerCur.raw(),
+ uGstRevCur);
+ RTPrintf(GuestCtrl::tr("New Guest Additions: %ls%RU64\n"), strGstVerNew.raw(),
+ uGstRevNew);
+
+ if (RT_FAILURE(vrc))
+ {
+ RTPrintf(GuestCtrl::tr("\nError updating Guest Additions, please check guest installer log\n"));
+ }
+ else
+ {
+ if (uGstRevNew < uGstRevCur)
+ RTPrintf(GuestCtrl::tr("\nWARNING: Guest Additions were downgraded\n"));
+ }
+ }
+ }
+ }
+ }
+ else if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("The guest needs to be restarted in order to make use of the updated Guest Additions.\n"));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Returns a Guest Additions run level from a string.
+ *
+ * @returns Run level if found, or AdditionsRunLevelType_None if not found / invalid.
+ * @param pcszStr String to return run level for.
+ */
+static AdditionsRunLevelType_T gctlGetRunLevelFromStr(const char *pcszStr)
+{
+ AssertPtrReturn(pcszStr, AdditionsRunLevelType_None);
+
+ if (RTStrICmp(pcszStr, "system") == 0) return AdditionsRunLevelType_System;
+ else if (RTStrICmp(pcszStr, "userland") == 0) return AdditionsRunLevelType_Userland;
+ else if (RTStrICmp(pcszStr, "desktop") == 0) return AdditionsRunLevelType_Desktop;
+
+ return AdditionsRunLevelType_None;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleWaitRunLevel(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ /** Timeout to wait for run level being reached.
+ * By default we wait until it's reached. */
+ uint32_t cMsTimeout = RT_INDEFINITE_WAIT;
+
+ /*
+ * Parse arguments.
+ */
+ enum KGSTCTRLWAITRUNLEVELOPT
+ {
+ KGSTCTRLWAITRUNLEVELOPT_TIMEOUT = 1000
+ };
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--timeout", KGSTCTRLWAITRUNLEVELOPT_TIMEOUT, RTGETOPT_REQ_UINT32 }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ AdditionsRunLevelType_T enmRunLevel = AdditionsRunLevelType_None;
+
+ int vrc = VINF_SUCCESS;
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(vrc))
+ {
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case KGSTCTRLWAITRUNLEVELOPT_TIMEOUT:
+ cMsTimeout = ValueUnion.u32;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ enmRunLevel = gctlGetRunLevelFromStr(ValueUnion.psz);
+ if (enmRunLevel == AdditionsRunLevelType_None)
+ return errorSyntax(GuestCtrl::tr("Invalid run level specified. Valid values are: system, userland, desktop"));
+ break;
+ }
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ if (enmRunLevel == AdditionsRunLevelType_None)
+ return errorSyntax(GuestCtrl::tr("Missing run level to wait for"));
+
+ vrc = gctlWaitForRunLevel(pCtx, enmRunLevel, cMsTimeout);
+
+ return RT_SUCCESS(vrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleList(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ bool fSeenListArg = false;
+ bool fListAll = false;
+ bool fListSessions = false;
+ bool fListProcesses = false;
+ bool fListFiles = false;
+
+ int vrc = VINF_SUCCESS;
+ while ( (ch = RTGetOpt(&GetState, &ValueUnion))
+ && RT_SUCCESS(vrc))
+ {
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case VINF_GETOPT_NOT_OPTION:
+ if ( !RTStrICmp(ValueUnion.psz, "sessions")
+ || !RTStrICmp(ValueUnion.psz, "sess"))
+ fListSessions = true;
+ else if ( !RTStrICmp(ValueUnion.psz, "processes")
+ || !RTStrICmp(ValueUnion.psz, "procs"))
+ fListSessions = fListProcesses = true; /* Showing processes implies showing sessions. */
+ else if (!RTStrICmp(ValueUnion.psz, "files"))
+ fListSessions = fListFiles = true; /* Showing files implies showing sessions. */
+ else if (!RTStrICmp(ValueUnion.psz, "all"))
+ fListAll = true;
+ else
+ return errorSyntax(GuestCtrl::tr("Unknown list: '%s'"), ValueUnion.psz);
+ fSeenListArg = true;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (!fSeenListArg)
+ return errorSyntax(GuestCtrl::tr("Missing list name"));
+ Assert(fListAll || fListSessions);
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+
+ /** @todo Do we need a machine-readable output here as well? */
+
+ HRESULT hrc;
+ size_t cTotalProcs = 0;
+ size_t cTotalFiles = 0;
+
+ SafeIfaceArray <IGuestSession> collSessions;
+ CHECK_ERROR(pCtx->pGuest, COMGETTER(Sessions)(ComSafeArrayAsOutParam(collSessions)));
+ if (SUCCEEDED(hrc))
+ {
+ size_t const cSessions = collSessions.size();
+ if (cSessions)
+ {
+ RTPrintf(GuestCtrl::tr("Active guest sessions:\n"));
+
+ /** @todo Make this output a bit prettier. No time now. */
+
+ for (size_t i = 0; i < cSessions; i++)
+ {
+ ComPtr<IGuestSession> pCurSession = collSessions[i];
+ if (!pCurSession.isNull())
+ {
+ do
+ {
+ ULONG uID;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(Id)(&uID));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(Name)(strName.asOutParam()));
+ Bstr strUser;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(User)(strUser.asOutParam()));
+ GuestSessionStatus_T sessionStatus;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(Status)(&sessionStatus));
+ RTPrintf(GuestCtrl::tr("\n\tSession #%-3zu ID=%-3RU32 User=%-16ls Status=[%s] Name=%ls"),
+ i, uID, strUser.raw(), gctlGuestSessionStatusToText(sessionStatus), strName.raw());
+ } while (0);
+
+ if ( fListAll
+ || fListProcesses)
+ {
+ SafeIfaceArray <IGuestProcess> collProcesses;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(Processes)(ComSafeArrayAsOutParam(collProcesses)));
+ for (size_t a = 0; a < collProcesses.size(); a++)
+ {
+ ComPtr<IGuestProcess> pCurProcess = collProcesses[a];
+ if (!pCurProcess.isNull())
+ {
+ do
+ {
+ ULONG uPID;
+ CHECK_ERROR_BREAK(pCurProcess, COMGETTER(PID)(&uPID));
+ Bstr strExecPath;
+ CHECK_ERROR_BREAK(pCurProcess, COMGETTER(ExecutablePath)(strExecPath.asOutParam()));
+ ProcessStatus_T procStatus;
+ CHECK_ERROR_BREAK(pCurProcess, COMGETTER(Status)(&procStatus));
+
+ RTPrintf(GuestCtrl::tr("\n\t\tProcess #%-03zu PID=%-6RU32 Status=[%s] Command=%ls"),
+ a, uPID, gctlProcessStatusToText(procStatus), strExecPath.raw());
+ } while (0);
+ }
+ }
+
+ cTotalProcs += collProcesses.size();
+ }
+
+ if ( fListAll
+ || fListFiles)
+ {
+ SafeIfaceArray <IGuestFile> collFiles;
+ CHECK_ERROR_BREAK(pCurSession, COMGETTER(Files)(ComSafeArrayAsOutParam(collFiles)));
+ for (size_t a = 0; a < collFiles.size(); a++)
+ {
+ ComPtr<IGuestFile> pCurFile = collFiles[a];
+ if (!pCurFile.isNull())
+ {
+ do
+ {
+ ULONG idFile;
+ CHECK_ERROR_BREAK(pCurFile, COMGETTER(Id)(&idFile));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pCurFile, COMGETTER(Filename)(strName.asOutParam()));
+ FileStatus_T fileStatus;
+ CHECK_ERROR_BREAK(pCurFile, COMGETTER(Status)(&fileStatus));
+
+ RTPrintf(GuestCtrl::tr("\n\t\tFile #%-03zu ID=%-6RU32 Status=[%s] Name=%ls"),
+ a, idFile, gctlFileStatusToText(fileStatus), strName.raw());
+ } while (0);
+ }
+ }
+
+ cTotalFiles += collFiles.size();
+ }
+ }
+ }
+
+ RTPrintf(GuestCtrl::tr("\n\nTotal guest sessions: %zu\n"), collSessions.size());
+ if (fListAll || fListProcesses)
+ RTPrintf(GuestCtrl::tr("Total guest processes: %zu\n"), cTotalProcs);
+ if (fListAll || fListFiles)
+ RTPrintf(GuestCtrl::tr("Total guest files: %zu\n"), cTotalFiles);
+ }
+ else
+ RTPrintf(GuestCtrl::tr("No active guest sessions found\n"));
+ }
+
+ if (FAILED(hrc)) /** @todo yeah, right... Only the last error? */
+ rcExit = RTEXITCODE_FAILURE;
+
+ return rcExit;
+}
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleCloseProcess(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--session-id", 'i', RTGETOPT_REQ_UINT32 },
+ { "--session-name", 'n', RTGETOPT_REQ_STRING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ std::vector < uint32_t > vecPID;
+ ULONG idSession = UINT32_MAX;
+ Utf8Str strSessionName;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'n': /* Session name (or pattern) */
+ strSessionName = ValueUnion.psz;
+ break;
+
+ case 'i': /* Session ID */
+ idSession = ValueUnion.u32;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ {
+ /* Treat every else specified as a PID to kill. */
+ uint32_t uPid;
+ vrc = RTStrToUInt32Ex(ValueUnion.psz, NULL, 0, &uPid);
+ if ( RT_SUCCESS(vrc)
+ && vrc != VWRN_TRAILING_CHARS
+ && vrc != VWRN_NUMBER_TOO_BIG
+ && vrc != VWRN_NEGATIVE_UNSIGNED)
+ {
+ if (uPid != 0)
+ {
+ try
+ {
+ vecPID.push_back(uPid);
+ }
+ catch (std::bad_alloc &)
+ {
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, GuestCtrl::tr("Out of memory"));
+ }
+ }
+ else
+ return errorSyntax(GuestCtrl::tr("Invalid PID value: 0"));
+ }
+ else
+ return errorSyntax(GuestCtrl::tr("Error parsing PID value: %Rrc"), vrc);
+ break;
+ }
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if (vecPID.empty())
+ return errorSyntax(GuestCtrl::tr("At least one PID must be specified to kill!"));
+
+ if ( strSessionName.isEmpty()
+ && idSession == UINT32_MAX)
+ return errorSyntax(GuestCtrl::tr("No session ID specified!"));
+
+ if ( strSessionName.isNotEmpty()
+ && idSession != UINT32_MAX)
+ return errorSyntax(GuestCtrl::tr("Either session ID or name (pattern) must be specified"));
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ HRESULT hrc = S_OK;
+
+ ComPtr<IGuestSession> pSession;
+ ComPtr<IGuestProcess> pProcess;
+ do
+ {
+ uint32_t uProcsTerminated = 0;
+
+ SafeIfaceArray <IGuestSession> collSessions;
+ CHECK_ERROR_BREAK(pCtx->pGuest, COMGETTER(Sessions)(ComSafeArrayAsOutParam(collSessions)));
+ size_t cSessions = collSessions.size();
+
+ uint32_t cSessionsHandled = 0;
+ for (size_t i = 0; i < cSessions; i++)
+ {
+ pSession = collSessions[i];
+ Assert(!pSession.isNull());
+
+ ULONG uID; /* Session ID */
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
+ Utf8Str strNameUtf8(strName); /* Session name */
+
+ bool fSessionFound;
+ if (strSessionName.isEmpty()) /* Search by ID. Slow lookup. */
+ fSessionFound = uID == idSession;
+ else /* ... or by naming pattern. */
+ fSessionFound = RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str());
+ if (fSessionFound)
+ {
+ AssertStmt(!pSession.isNull(), break);
+ cSessionsHandled++;
+
+ SafeIfaceArray <IGuestProcess> collProcs;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Processes)(ComSafeArrayAsOutParam(collProcs)));
+
+ size_t cProcs = collProcs.size();
+ for (size_t p = 0; p < cProcs; p++)
+ {
+ pProcess = collProcs[p];
+ Assert(!pProcess.isNull());
+
+ ULONG uPID; /* Process ID */
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID));
+
+ bool fProcFound = false;
+ for (size_t a = 0; a < vecPID.size(); a++) /* Slow, but works. */
+ {
+ fProcFound = vecPID[a] == uPID;
+ if (fProcFound)
+ break;
+ }
+
+ if (fProcFound)
+ {
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Terminating process (PID %RU32) (session ID %RU32) ...\n"),
+ uPID, uID);
+ CHECK_ERROR_BREAK(pProcess, Terminate());
+ uProcsTerminated++;
+ }
+ else
+ {
+ if (idSession != UINT32_MAX)
+ RTPrintf(GuestCtrl::tr("No matching process(es) for session ID %RU32 found\n"),
+ idSession);
+ }
+
+ pProcess.setNull();
+ }
+
+ pSession.setNull();
+ }
+ }
+
+ if (!cSessionsHandled)
+ RTPrintf(GuestCtrl::tr("No matching session(s) found\n"));
+
+ if (uProcsTerminated)
+ RTPrintf(GuestCtrl::tr("%RU32 process(es) terminated\n", "", uProcsTerminated), uProcsTerminated);
+
+ } while (0);
+
+ pProcess.setNull();
+ pSession.setNull();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleCloseSession(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ enum GETOPTDEF_SESSIONCLOSE
+ {
+ GETOPTDEF_SESSIONCLOSE_ALL = 2000
+ };
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--all", GETOPTDEF_SESSIONCLOSE_ALL, RTGETOPT_REQ_NOTHING },
+ { "--session-id", 'i', RTGETOPT_REQ_UINT32 },
+ { "--session-name", 'n', RTGETOPT_REQ_STRING }
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ ULONG idSession = UINT32_MAX;
+ Utf8Str strSessionName;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 'n': /* Session name pattern */
+ strSessionName = ValueUnion.psz;
+ break;
+
+ case 'i': /* Session ID */
+ idSession = ValueUnion.u32;
+ break;
+
+ case GETOPTDEF_SESSIONCLOSE_ALL:
+ strSessionName = "*";
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ /** @todo Supply a CSV list of IDs or patterns to close?
+ * break; */
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ if ( strSessionName.isEmpty()
+ && idSession == UINT32_MAX)
+ return errorSyntax(GuestCtrl::tr("No session ID specified!"));
+
+ if ( !strSessionName.isEmpty()
+ && idSession != UINT32_MAX)
+ return errorSyntax(GuestCtrl::tr("Either session ID or name (pattern) must be specified"));
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ HRESULT hrc = S_OK;
+
+ do
+ {
+ size_t cSessionsHandled = 0;
+
+ SafeIfaceArray <IGuestSession> collSessions;
+ CHECK_ERROR_BREAK(pCtx->pGuest, COMGETTER(Sessions)(ComSafeArrayAsOutParam(collSessions)));
+ size_t cSessions = collSessions.size();
+
+ for (size_t i = 0; i < cSessions; i++)
+ {
+ ComPtr<IGuestSession> pSession = collSessions[i];
+ Assert(!pSession.isNull());
+
+ ULONG uID; /* Session ID */
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
+ Utf8Str strNameUtf8(strName); /* Session name */
+
+ bool fSessionFound;
+ if (strSessionName.isEmpty()) /* Search by ID. Slow lookup. */
+ fSessionFound = uID == idSession;
+ else /* ... or by naming pattern. */
+ fSessionFound = RTStrSimplePatternMatch(strSessionName.c_str(), strNameUtf8.c_str());
+ if (fSessionFound)
+ {
+ cSessionsHandled++;
+
+ Assert(!pSession.isNull());
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Closing guest session ID=#%RU32 \"%s\" ...\n"),
+ uID, strNameUtf8.c_str());
+ CHECK_ERROR_BREAK(pSession, Close());
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Guest session successfully closed\n"));
+
+ pSession.setNull();
+ }
+ }
+
+ if (!cSessionsHandled)
+ {
+ RTPrintf(GuestCtrl::tr("No guest session(s) found\n"));
+ hrc = E_ABORT; /* To set exit code accordingly. */
+ }
+
+ } while (0);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static DECLCALLBACK(RTEXITCODE) gctlHandleWatch(PGCTLCMDCTX pCtx, int argc, char **argv)
+{
+ AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);
+
+ /*
+ * Parse arguments.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ GCTLCMD_COMMON_OPTION_DEFS()
+ { "--timeout", 't', RTGETOPT_REQ_UINT32 }
+ };
+
+ uint32_t cMsTimeout = RT_INDEFINITE_WAIT;
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);
+
+ case 't': /* Timeout */
+ cMsTimeout = ValueUnion.u32;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ /** @todo Specify categories to watch for. */
+
+ RTEXITCODE rcExit = gctlCtxPostOptionParsingInit(pCtx);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+
+ HRESULT hrc;
+
+ try
+ {
+ ComObjPtr<GuestEventListenerImpl> pGuestListener;
+ do
+ {
+ /* Listener creation. */
+ pGuestListener.createObject();
+ pGuestListener->init(new GuestEventListener());
+
+ /* Register for IGuest events. */
+ ComPtr<IEventSource> es;
+ CHECK_ERROR_BREAK(pCtx->pGuest, COMGETTER(EventSource)(es.asOutParam()));
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnGuestSessionRegistered);
+ /** @todo Also register for VBoxEventType_OnGuestUserStateChanged on demand? */
+ CHECK_ERROR_BREAK(es, RegisterListener(pGuestListener, ComSafeArrayAsInParam(eventTypes),
+ true /* Active listener */));
+ /* Note: All other guest control events have to be registered
+ * as their corresponding objects appear. */
+
+ } while (0);
+
+ if (pCtx->cVerbose)
+ RTPrintf(GuestCtrl::tr("Waiting for events ...\n"));
+
+ RTMSINTERVAL tsStart = RTTimeMilliTS();
+ while (RTTimeMilliTS() - tsStart < cMsTimeout)
+ {
+ /* Wait for the global signal semaphore getting signalled. */
+ int vrc = RTSemEventWait(g_SemEventGuestCtrlCanceled, 100 /* ms */);
+ if (RT_FAILURE(vrc))
+ {
+ if (vrc != VERR_TIMEOUT)
+ {
+ RTPrintf(GuestCtrl::tr("Waiting failed with %Rrc\n"), vrc);
+ break;
+ }
+ }
+ else
+ break;
+
+ /* We need to process the event queue, otherwise our registered listeners won't get any events. */
+ NativeEventQueue::getMainEventQueue()->processEventQueue(0);
+ }
+
+ if (!pGuestListener.isNull())
+ {
+ /* Guest callback unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR(pCtx->pGuest, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR(pES, UnregisterListener(pGuestListener));
+ pGuestListener.setNull();
+ }
+ }
+ catch (std::bad_alloc &)
+ {
+ hrc = E_OUTOFMEMORY;
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Access the guest control store.
+ *
+ * @returns program exit code.
+ * @note see the command line API description for parameters
+ */
+RTEXITCODE handleGuestControl(HandlerArg *pArg)
+{
+ AssertPtr(pArg);
+
+ /*
+ * Command definitions.
+ */
+ static const GCTLCMDDEF s_aCmdDefs[] =
+ {
+ { "run", gctlHandleRun, HELP_SCOPE_GUESTCONTROL_RUN, 0 },
+ { "start", gctlHandleStart, HELP_SCOPE_GUESTCONTROL_START, 0 },
+ { "copyfrom", gctlHandleCopyFrom, HELP_SCOPE_GUESTCONTROL_COPYFROM, 0 },
+ { "copyto", gctlHandleCopyTo, HELP_SCOPE_GUESTCONTROL_COPYTO, 0 },
+
+ { "mkdir", gctrlHandleMkDir, HELP_SCOPE_GUESTCONTROL_MKDIR, 0 },
+ { "md", gctrlHandleMkDir, HELP_SCOPE_GUESTCONTROL_MKDIR, 0 },
+ { "createdirectory", gctrlHandleMkDir, HELP_SCOPE_GUESTCONTROL_MKDIR, 0 },
+ { "createdir", gctrlHandleMkDir, HELP_SCOPE_GUESTCONTROL_MKDIR, 0 },
+
+ { "rmdir", gctlHandleRmDir, HELP_SCOPE_GUESTCONTROL_RMDIR, 0 },
+ { "removedir", gctlHandleRmDir, HELP_SCOPE_GUESTCONTROL_RMDIR, 0 },
+ { "removedirectory", gctlHandleRmDir, HELP_SCOPE_GUESTCONTROL_RMDIR, 0 },
+
+ { "rm", gctlHandleRm, HELP_SCOPE_GUESTCONTROL_RM, 0 },
+ { "removefile", gctlHandleRm, HELP_SCOPE_GUESTCONTROL_RM, 0 },
+ { "erase", gctlHandleRm, HELP_SCOPE_GUESTCONTROL_RM, 0 },
+ { "del", gctlHandleRm, HELP_SCOPE_GUESTCONTROL_RM, 0 },
+ { "delete", gctlHandleRm, HELP_SCOPE_GUESTCONTROL_RM, 0 },
+
+ { "mv", gctlHandleMv, HELP_SCOPE_GUESTCONTROL_MV, 0 },
+ { "move", gctlHandleMv, HELP_SCOPE_GUESTCONTROL_MV, 0 },
+ { "ren", gctlHandleMv, HELP_SCOPE_GUESTCONTROL_MV, 0 },
+ { "rename", gctlHandleMv, HELP_SCOPE_GUESTCONTROL_MV, 0 },
+
+ { "mktemp", gctlHandleMkTemp, HELP_SCOPE_GUESTCONTROL_MKTEMP, 0 },
+ { "createtemp", gctlHandleMkTemp, HELP_SCOPE_GUESTCONTROL_MKTEMP, 0 },
+ { "createtemporary", gctlHandleMkTemp, HELP_SCOPE_GUESTCONTROL_MKTEMP, 0 },
+
+ { "stat", gctlHandleStat, HELP_SCOPE_GUESTCONTROL_STAT, 0 },
+
+ { "closeprocess", gctlHandleCloseProcess, HELP_SCOPE_GUESTCONTROL_CLOSEPROCESS, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER },
+ { "closesession", gctlHandleCloseSession, HELP_SCOPE_GUESTCONTROL_CLOSESESSION, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER },
+ { "list", gctlHandleList, HELP_SCOPE_GUESTCONTROL_LIST, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER },
+ { "watch", gctlHandleWatch, HELP_SCOPE_GUESTCONTROL_WATCH, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+
+ {"updateguestadditions",gctlHandleUpdateAdditions, HELP_SCOPE_GUESTCONTROL_UPDATEGA, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+ { "updateadditions", gctlHandleUpdateAdditions, HELP_SCOPE_GUESTCONTROL_UPDATEGA, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+ { "updatega", gctlHandleUpdateAdditions, HELP_SCOPE_GUESTCONTROL_UPDATEGA, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+
+ { "waitrunlevel", gctlHandleWaitRunLevel, HELP_SCOPE_GUESTCONTROL_WAITRUNLEVEL, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+ { "waitforrunlevel", gctlHandleWaitRunLevel, HELP_SCOPE_GUESTCONTROL_WAITRUNLEVEL, GCTLCMDCTX_F_SESSION_ANONYMOUS },
+ };
+
+ /*
+ * VBoxManage guestcontrol [common-options] <VM> [common-options] <sub-command> ...
+ *
+ * Parse common options and VM name until we find a sub-command. Allowing
+ * the user to put the user and password related options before the
+ * sub-command makes it easier to edit the command line when doing several
+ * operations with the same guest user account. (Accidentally, it also
+ * makes the syntax diagram shorter and easier to read.)
+ */
+ GCTLCMDCTX CmdCtx;
+ RTEXITCODE rcExit = gctrCmdCtxInit(&CmdCtx, pArg);
+ if (rcExit == RTEXITCODE_SUCCESS)
+ {
+ static const RTGETOPTDEF s_CommonOptions[] = { GCTLCMD_COMMON_OPTION_DEFS() };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_CommonOptions, RT_ELEMENTS(s_CommonOptions), 0, 0 /* No sorting! */);
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (ch)
+ {
+ GCTLCMD_COMMON_OPTION_CASES(&CmdCtx, ch, &ValueUnion);
+
+ case VINF_GETOPT_NOT_OPTION:
+ /* First comes the VM name or UUID. */
+ if (!CmdCtx.pszVmNameOrUuid)
+ CmdCtx.pszVmNameOrUuid = ValueUnion.psz;
+ /*
+ * The sub-command is next. Look it up and invoke it.
+ * Note! Currently no warnings about user/password options (like we'll do later on)
+ * for GCTLCMDCTX_F_SESSION_ANONYMOUS commands. No reason to be too pedantic.
+ */
+ else
+ {
+ const char *pszCmd = ValueUnion.psz;
+ uint32_t iCmd;
+ for (iCmd = 0; iCmd < RT_ELEMENTS(s_aCmdDefs); iCmd++)
+ if (strcmp(s_aCmdDefs[iCmd].pszName, pszCmd) == 0)
+ {
+ CmdCtx.pCmdDef = &s_aCmdDefs[iCmd];
+
+ setCurrentSubcommand(s_aCmdDefs[iCmd].fSubcommandScope);
+ rcExit = s_aCmdDefs[iCmd].pfnHandler(&CmdCtx, pArg->argc - GetState.iNext + 1,
+ &pArg->argv[GetState.iNext - 1]);
+
+ gctlCtxTerm(&CmdCtx);
+ return rcExit;
+ }
+ return errorSyntax(GuestCtrl::tr("Unknown sub-command: '%s'"), pszCmd);
+ }
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+ if (CmdCtx.pszVmNameOrUuid)
+ rcExit = errorSyntax(GuestCtrl::tr("Missing sub-command"));
+ else
+ rcExit = errorSyntax(GuestCtrl::tr("Missing VM name and sub-command"));
+ }
+ return rcExit;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.h b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.h
new file mode 100644
index 00000000..c98cad06
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.h
@@ -0,0 +1,270 @@
+/* $Id: VBoxManageGuestCtrl.h $ */
+/** @file
+ * VBoxManageGuestCtrl.h - Definitions for guest control.
+ */
+
+/*
+ * Copyright (C) 2013-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_VBoxManage_VBoxManageGuestCtrl_h
+#define VBOX_INCLUDED_SRC_VBoxManage_VBoxManageGuestCtrl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/com.h>
+#include <VBox/com/listeners.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/semaphore.h>
+#include <iprt/time.h>
+
+#include <map>
+
+const char *gctlFileStatusToText(FileStatus_T enmStatus);
+const char *gctlProcessStatusToText(ProcessStatus_T enmStatus);
+const char *gctlGuestSessionStatusToText(GuestSessionStatus_T enmStatus);
+
+using namespace com;
+
+class GuestFileEventListener;
+typedef ListenerImpl<GuestFileEventListener> GuestFileEventListenerImpl;
+
+class GuestProcessEventListener;
+typedef ListenerImpl<GuestProcessEventListener> GuestProcessEventListenerImpl;
+
+class GuestSessionEventListener;
+typedef ListenerImpl<GuestSessionEventListener> GuestSessionEventListenerImpl;
+
+class GuestEventListener;
+typedef ListenerImpl<GuestEventListener> GuestEventListenerImpl;
+
+class GuestAdditionsRunlevelListener;
+typedef ListenerImpl<GuestAdditionsRunlevelListener> GuestAdditionsRunlevelListenerImpl;
+
+/** Simple statistics class for binding locally
+ * held data to a specific guest object. */
+class GuestEventStats
+{
+
+public:
+
+ GuestEventStats(void)
+ : uLastUpdatedMS(RTTimeMilliTS())
+ {
+ }
+
+ /** @todo Make this more a class than a structure. */
+public:
+
+ uint64_t uLastUpdatedMS;
+};
+
+class GuestFileStats : public GuestEventStats
+{
+
+public:
+
+ GuestFileStats(void) { }
+
+ GuestFileStats(ComObjPtr<GuestFileEventListenerImpl> pListenerImpl)
+ : mListener(pListenerImpl)
+ {
+ }
+
+public: /** @todo */
+
+ ComObjPtr<GuestFileEventListenerImpl> mListener;
+};
+
+class GuestProcStats : public GuestEventStats
+{
+
+public:
+
+ GuestProcStats(void) { }
+
+ GuestProcStats(ComObjPtr<GuestProcessEventListenerImpl> pListenerImpl)
+ : mListener(pListenerImpl)
+ {
+ }
+
+public: /** @todo */
+
+ ComObjPtr<GuestProcessEventListenerImpl> mListener;
+};
+
+class GuestSessionStats : public GuestEventStats
+{
+
+public:
+
+ GuestSessionStats(void) { }
+
+ GuestSessionStats(ComObjPtr<GuestSessionEventListenerImpl> pListenerImpl)
+ : mListener(pListenerImpl)
+ {
+ }
+
+public: /** @todo */
+
+ ComObjPtr<GuestSessionEventListenerImpl> mListener;
+};
+
+/** Map containing all watched guest files. */
+typedef std::map< ComPtr<IGuestFile>, GuestFileStats > GuestEventFiles;
+/** Map containing all watched guest processes. */
+typedef std::map< ComPtr<IGuestProcess>, GuestProcStats > GuestEventProcs;
+/** Map containing all watched guest sessions. */
+typedef std::map< ComPtr<IGuestSession>, GuestSessionStats > GuestEventSessions;
+
+class GuestListenerBase
+{
+public:
+
+ GuestListenerBase(void);
+
+ virtual ~GuestListenerBase(void);
+
+public:
+
+ HRESULT init(bool fVerbose = false);
+
+protected:
+
+ /** Verbose flag. */
+ bool mfVerbose;
+};
+
+/**
+ * Handler for guest process events.
+ */
+class GuestFileEventListener : public GuestListenerBase
+{
+public:
+
+ GuestFileEventListener(void);
+
+ virtual ~GuestFileEventListener(void);
+
+public:
+
+ void uninit(void);
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent);
+
+protected:
+
+};
+
+/**
+ * Handler for guest process events.
+ */
+class GuestProcessEventListener : public GuestListenerBase
+{
+public:
+
+ GuestProcessEventListener(void);
+
+ virtual ~GuestProcessEventListener(void);
+
+public:
+
+ void uninit(void);
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent);
+
+protected:
+
+};
+
+/**
+ * Handler for guest session events.
+ */
+class GuestSessionEventListener : public GuestListenerBase
+{
+public:
+
+ GuestSessionEventListener(void);
+
+ virtual ~GuestSessionEventListener(void);
+
+public:
+
+ void uninit(void);
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent);
+
+protected:
+
+ GuestEventFiles mFiles;
+ GuestEventProcs mProcs;
+};
+
+/**
+ * Handler for guest events.
+ */
+class GuestEventListener : public GuestListenerBase
+{
+
+public:
+
+ GuestEventListener(void);
+
+ virtual ~GuestEventListener(void);
+
+public:
+
+ void uninit(void);
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent);
+
+protected:
+
+ GuestEventSessions mSessions;
+};
+
+/**
+ * Handler for Guest Additions runlevel change events.
+ */
+class GuestAdditionsRunlevelListener : public GuestListenerBase
+{
+
+public:
+
+ GuestAdditionsRunlevelListener(AdditionsRunLevelType_T enmRunLevel);
+
+ virtual ~GuestAdditionsRunlevelListener(void);
+
+public:
+
+ void uninit(void);
+
+ STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent);
+
+protected:
+
+ /** The run level target we're waiting for. */
+ AdditionsRunLevelType_T mRunLevelTarget;
+};
+
+#endif /* !VBOX_INCLUDED_SRC_VBoxManage_VBoxManageGuestCtrl_h */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrlListener.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrlListener.cpp
new file mode 100644
index 00000000..0fada6d0
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrlListener.cpp
@@ -0,0 +1,578 @@
+/* $Id: VBoxManageGuestCtrlListener.cpp $ */
+/** @file
+ * VBoxManage - Guest control listener implementations.
+ */
+
+/*
+ * Copyright (C) 2013-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "VBoxManage.h"
+#include "VBoxManageGuestCtrl.h"
+
+#include <VBox/com/com.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+
+#include <iprt/semaphore.h>
+#include <iprt/time.h>
+
+#include <map>
+#include <vector>
+
+DECLARE_TRANSLATION_CONTEXT(GuestCtrlLsnr);
+
+
+/** Event semaphore we're using for notification. */
+extern RTSEMEVENT g_SemEventGuestCtrlCanceled;
+
+
+/*
+ * GuestListenerBase
+ * GuestListenerBase
+ * GuestListenerBase
+ */
+
+GuestListenerBase::GuestListenerBase(void)
+ : mfVerbose(false)
+{
+}
+
+GuestListenerBase::~GuestListenerBase(void)
+{
+}
+
+HRESULT GuestListenerBase::init(bool fVerbose)
+{
+ mfVerbose = fVerbose;
+ return S_OK;
+}
+
+
+
+/*
+ * GuestFileEventListener
+ * GuestFileEventListener
+ * GuestFileEventListener
+ */
+
+GuestFileEventListener::GuestFileEventListener(void)
+{
+}
+
+GuestFileEventListener::~GuestFileEventListener(void)
+{
+}
+
+void GuestFileEventListener::uninit(void)
+{
+
+}
+
+STDMETHODIMP GuestFileEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
+{
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestFileStateChanged:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestFileStateChangedEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ ComPtr<IGuestFile> pProcess;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pProcess.asOutParam()));
+ AssertBreak(!pProcess.isNull());
+ FileStatus_T fileSts;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&fileSts));
+ Bstr strPath;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(Filename)(strPath.asOutParam()));
+ ULONG uID;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(Id)(&uID));
+
+ RTPrintf(GuestCtrlLsnr::tr("File ID=%RU32 \"%s\" changed status to [%s]\n"),
+ uID, Utf8Str(strPath).c_str(), gctlFileStatusToText(fileSts));
+
+ } while (0);
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+}
+
+
+/*
+ * GuestProcessEventListener
+ * GuestProcessEventListener
+ * GuestProcessEventListener
+ */
+
+GuestProcessEventListener::GuestProcessEventListener(void)
+{
+}
+
+GuestProcessEventListener::~GuestProcessEventListener(void)
+{
+}
+
+void GuestProcessEventListener::uninit(void)
+{
+
+}
+
+STDMETHODIMP GuestProcessEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
+{
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestProcessStateChanged:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestProcessStateChangedEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ ComPtr<IGuestProcess> pProcess;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam()));
+ AssertBreak(!pProcess.isNull());
+ ProcessStatus_T procSts;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Status)(&procSts));
+ Bstr strPath;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam()));
+ ULONG uPID;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID));
+
+ RTPrintf(GuestCtrlLsnr::tr("Process PID=%RU32 \"%s\" changed status to [%s]\n"),
+ uPID, Utf8Str(strPath).c_str(), gctlProcessStatusToText(procSts));
+
+ } while (0);
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+}
+
+
+/*
+ * GuestSessionEventListener
+ * GuestSessionEventListener
+ * GuestSessionEventListener
+ */
+
+GuestSessionEventListener::GuestSessionEventListener(void)
+{
+}
+
+GuestSessionEventListener::~GuestSessionEventListener(void)
+{
+}
+
+void GuestSessionEventListener::uninit(void)
+{
+ GuestEventProcs::iterator itProc = mProcs.begin();
+ while (itProc != mProcs.end())
+ {
+ if (!itProc->first.isNull())
+ {
+ HRESULT hrc;
+ do
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR_BREAK(itProc->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR_BREAK(pES, UnregisterListener(itProc->second.mListener));
+ } while (0);
+ }
+
+ ++itProc;
+ }
+ mProcs.clear();
+
+ GuestEventFiles::iterator itFile = mFiles.begin();
+ while (itFile != mFiles.end())
+ {
+ if (!itFile->first.isNull())
+ {
+ HRESULT hrc;
+ do
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR_BREAK(itFile->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR_BREAK(pES, UnregisterListener(itFile->second.mListener));
+ } while (0);
+ }
+
+ ++itFile;
+ }
+ mFiles.clear();
+}
+
+STDMETHODIMP GuestSessionEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
+{
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestFileRegistered:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ ComPtr<IGuestFile> pFile;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam()));
+ AssertBreak(!pFile.isNull());
+ BOOL fRegistered;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
+ Bstr strPath;
+ CHECK_ERROR_BREAK(pFile, COMGETTER(Filename)(strPath.asOutParam()));
+
+ RTPrintf(GuestCtrlLsnr::tr("File \"%s\" %s\n"),
+ Utf8Str(strPath).c_str(),
+ fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
+ if (fRegistered)
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
+
+ /* Register for IGuestFile events. */
+ ComObjPtr<GuestFileEventListenerImpl> pListener;
+ pListener.createObject();
+ CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener()));
+
+ ComPtr<IEventSource> es;
+ CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam()));
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
+ CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
+ true /* Active listener */));
+
+ GuestFileStats fileStats(pListener);
+ mFiles[pFile] = fileStats;
+ }
+ else
+ {
+ GuestEventFiles::iterator itFile = mFiles.find(pFile);
+ if (itFile != mFiles.end())
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Unregistering file ...\n"));
+
+ if (!itFile->first.isNull())
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener));
+ }
+
+ mFiles.erase(itFile);
+ }
+ }
+
+ } while (0);
+ break;
+ }
+
+ case VBoxEventType_OnGuestProcessRegistered:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ ComPtr<IGuestProcess> pProcess;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam()));
+ AssertBreak(!pProcess.isNull());
+ BOOL fRegistered;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
+ Bstr strPath;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam()));
+
+ RTPrintf(GuestCtrlLsnr::tr("Process \"%s\" %s\n"),
+ Utf8Str(strPath).c_str(),
+ fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
+ if (fRegistered)
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
+
+ /* Register for IGuestProcess events. */
+ ComObjPtr<GuestProcessEventListenerImpl> pListener;
+ pListener.createObject();
+ CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener()));
+
+ ComPtr<IEventSource> es;
+ CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam()));
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged);
+ CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
+ true /* Active listener */));
+
+ GuestProcStats procStats(pListener);
+ mProcs[pProcess] = procStats;
+ }
+ else
+ {
+ GuestEventProcs::iterator itProc = mProcs.find(pProcess);
+ if (itProc != mProcs.end())
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Unregistering process ...\n"));
+
+ if (!itProc->first.isNull())
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener));
+ }
+
+ mProcs.erase(itProc);
+ }
+ }
+
+ } while (0);
+ break;
+ }
+
+ case VBoxEventType_OnGuestSessionStateChanged:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+ ComPtr<IGuestSession> pSession;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam()));
+ AssertBreak(!pSession.isNull());
+
+ GuestSessionStatus_T sessSts;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts));
+ ULONG uID;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
+
+ RTPrintf(GuestCtrlLsnr::tr("Session ID=%RU32 \"%s\" changed status to [%s]\n"),
+ uID, Utf8Str(strName).c_str(), gctlGuestSessionStatusToText(sessSts));
+
+ } while (0);
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+}
+
+
+/*
+ * GuestEventListener
+ * GuestEventListener
+ * GuestEventListener
+ */
+
+GuestEventListener::GuestEventListener(void)
+{
+}
+
+GuestEventListener::~GuestEventListener(void)
+{
+}
+
+void GuestEventListener::uninit(void)
+{
+ GuestEventSessions::iterator itSession = mSessions.begin();
+ while (itSession != mSessions.end())
+ {
+ if (!itSession->first.isNull())
+ {
+ HRESULT hrc;
+ do
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener));
+
+ } while (0);
+ }
+
+ ++itSession;
+ }
+ mSessions.clear();
+}
+
+STDMETHODIMP GuestEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
+{
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestSessionRegistered:
+ {
+ HRESULT hrc;
+ do
+ {
+ ComPtr<IGuestSessionRegisteredEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ ComPtr<IGuestSession> pSession;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam()));
+ AssertBreak(!pSession.isNull());
+ BOOL fRegistered;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
+ Bstr strName;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));
+ ULONG uID;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
+
+ RTPrintf(GuestCtrlLsnr::tr("Session ID=%RU32 \"%s\" %s\n"),
+ uID, Utf8Str(strName).c_str(),
+ fRegistered ? GuestCtrlLsnr::tr("registered") : GuestCtrlLsnr::tr("unregistered"));
+ if (fRegistered)
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Registering ...\n"));
+
+ /* Register for IGuestSession events. */
+ ComObjPtr<GuestSessionEventListenerImpl> pListener;
+ pListener.createObject();
+ CHECK_ERROR_BREAK(pListener, init(new GuestSessionEventListener()));
+
+ ComPtr<IEventSource> es;
+ CHECK_ERROR_BREAK(pSession, COMGETTER(EventSource)(es.asOutParam()));
+ com::SafeArray<VBoxEventType_T> eventTypes;
+ eventTypes.push_back(VBoxEventType_OnGuestFileRegistered);
+ eventTypes.push_back(VBoxEventType_OnGuestProcessRegistered);
+ eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged);
+ CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
+ true /* Active listener */));
+
+ GuestSessionStats sessionStats(pListener);
+ mSessions[pSession] = sessionStats;
+ }
+ else
+ {
+ GuestEventSessions::iterator itSession = mSessions.find(pSession);
+ if (itSession != mSessions.end())
+ {
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Unregistering ...\n"));
+
+ if (!itSession->first.isNull())
+ {
+ /* Listener unregistration. */
+ ComPtr<IEventSource> pES;
+ CHECK_ERROR_BREAK(itSession->first, COMGETTER(EventSource)(pES.asOutParam()));
+ if (!pES.isNull())
+ CHECK_ERROR_BREAK(pES, UnregisterListener(itSession->second.mListener));
+ }
+
+ mSessions.erase(itSession);
+ }
+ }
+
+ } while (0);
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+}
+
+/*
+ * GuestAdditionsRunlevelListener
+ * GuestAdditionsRunlevelListener
+ * GuestAdditionsRunlevelListener
+ */
+
+GuestAdditionsRunlevelListener::GuestAdditionsRunlevelListener(AdditionsRunLevelType_T enmRunLevel)
+ : mRunLevelTarget(enmRunLevel)
+{
+}
+
+GuestAdditionsRunlevelListener::~GuestAdditionsRunlevelListener(void)
+{
+}
+
+void GuestAdditionsRunlevelListener::uninit(void)
+{
+}
+
+STDMETHODIMP GuestAdditionsRunlevelListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
+{
+ Assert(mRunLevelTarget != AdditionsRunLevelType_None);
+
+ HRESULT hrc;
+
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestAdditionsStatusChanged:
+ {
+ ComPtr<IGuestAdditionsStatusChangedEvent> pEvent = aEvent;
+ Assert(!pEvent.isNull());
+
+ AdditionsRunLevelType_T RunLevelCur = AdditionsRunLevelType_None;
+ CHECK_ERROR_BREAK(pEvent, COMGETTER(RunLevel)(&RunLevelCur));
+
+ if (mfVerbose)
+ RTPrintf(GuestCtrlLsnr::tr("Reached run level %RU32\n"), RunLevelCur);
+
+ if (RunLevelCur == mRunLevelTarget)
+ {
+ int vrc = RTSemEventSignal(g_SemEventGuestCtrlCanceled);
+ AssertRC(vrc);
+ }
+
+ break;
+ }
+
+ default:
+ AssertFailed();
+ }
+
+ return S_OK;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
new file mode 100644
index 00000000..bed0edea
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
@@ -0,0 +1,601 @@
+/* $Id: VBoxManageGuestProp.cpp $ */
+/** @file
+ * VBoxManage - Implementation of guestproperty 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "VBoxManage.h"
+
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <VBox/log.h>
+#include <iprt/asm.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+#include <iprt/thread.h>
+
+#ifdef USE_XPCOM_QUEUE
+# include <sys/select.h>
+# include <errno.h>
+#endif
+
+#ifdef RT_OS_DARWIN
+# include <CoreFoundation/CFRunLoop.h>
+#endif
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(GuestProp);
+
+
+static RTEXITCODE handleGetGuestProperty(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ setCurrentSubcommand(HELP_SCOPE_GUESTPROPERTY_GET);
+
+ bool verbose = false;
+ if ( a->argc == 3
+ && ( !strcmp(a->argv[2], "--verbose")
+ || !strcmp(a->argv[2], "-verbose")))
+ verbose = true;
+ else if (a->argc != 2)
+ return errorSyntax(GuestProp::tr("Incorrect parameters"));
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ /* open a session for the VM - new or existing */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ Bstr value;
+ LONG64 i64Timestamp;
+ Bstr flags;
+ CHECK_ERROR(machine, GetGuestProperty(Bstr(a->argv[1]).raw(),
+ value.asOutParam(),
+ &i64Timestamp, flags.asOutParam()));
+ if (value.isEmpty())
+ RTPrintf(GuestProp::tr("No value set!\n"));
+ else
+ RTPrintf(GuestProp::tr("Value: %ls\n"), value.raw());
+ if (!value.isEmpty() && verbose)
+ {
+ RTPrintf(GuestProp::tr("Timestamp: %lld\n"), i64Timestamp);
+ RTPrintf(GuestProp::tr("Flags: %ls\n"), flags.raw());
+ }
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE handleSetGuestProperty(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ setCurrentSubcommand(HELP_SCOPE_GUESTPROPERTY_SET);
+
+ /*
+ * Check the syntax. We can deduce the correct syntax from the number of
+ * arguments.
+ */
+ bool usageOK = true;
+ const char *pszName = NULL;
+ const char *pszValue = NULL;
+ const char *pszFlags = NULL;
+ if (a->argc == 3)
+ pszValue = a->argv[2];
+ else if (a->argc == 4)
+ usageOK = false;
+ else if (a->argc == 5)
+ {
+ pszValue = a->argv[2];
+ if ( strcmp(a->argv[3], "--flags")
+ && strcmp(a->argv[3], "-flags"))
+ usageOK = false;
+ pszFlags = a->argv[4];
+ }
+ else if (a->argc != 2)
+ usageOK = false;
+ if (!usageOK)
+ return errorSyntax(GuestProp::tr("Incorrect parameters"));
+ /* This is always needed. */
+ pszName = a->argv[1];
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ /* open a session for the VM - new or existing */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ if (!pszFlags)
+ CHECK_ERROR(machine, SetGuestPropertyValue(Bstr(pszName).raw(),
+ Bstr(pszValue).raw()));
+ else
+ CHECK_ERROR(machine, SetGuestProperty(Bstr(pszName).raw(),
+ Bstr(pszValue).raw(),
+ Bstr(pszFlags).raw()));
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+
+ a->session->UnlockMachine();
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE handleDeleteGuestProperty(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ setCurrentSubcommand(HELP_SCOPE_GUESTPROPERTY_UNSET);
+
+ /*
+ * Check the syntax. We can deduce the correct syntax from the number of
+ * arguments.
+ */
+ bool usageOK = true;
+ const char *pszName = NULL;
+ if (a->argc != 2)
+ usageOK = false;
+ if (!usageOK)
+ return errorSyntax(GuestProp::tr("Incorrect parameters"));
+ /* This is always needed. */
+ pszName = a->argv[1];
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ /* open a session for the VM - new or existing */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ CHECK_ERROR(machine, DeleteGuestProperty(Bstr(pszName).raw()));
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+
+ a->session->UnlockMachine();
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Enumerates the properties in the guest property store.
+ *
+ * @returns 0 on success, 1 on failure
+ * @note see the command line API description for parameters
+ */
+static RTEXITCODE handleEnumGuestProperty(HandlerArg *a)
+{
+ setCurrentSubcommand(HELP_SCOPE_GUESTPROPERTY_ENUMERATE);
+
+ /*
+ * Parse arguments.
+ *
+ * The old syntax was a little boinkers. The --patterns argument just
+ * indicates that the rest of the arguments are options. Sort of like '--'.
+ * This has been normalized a little now, by accepting patterns w/o a
+ * preceding --pattern argument via the VINF_GETOPT_NOT_OPTION.
+ * Though, the first non-option is always the VM name.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--old-format", 'o', RTGETOPT_REQ_NOTHING },
+ { "--sort", 's', RTGETOPT_REQ_NOTHING },
+ { "--unsort", 'u', RTGETOPT_REQ_NOTHING },
+ { "--timestamp", 't', RTGETOPT_REQ_NOTHING },
+ { "--ts", 't', RTGETOPT_REQ_NOTHING },
+ { "--no-timestamp", 'T', RTGETOPT_REQ_NOTHING },
+ { "--abs", 'a', RTGETOPT_REQ_NOTHING },
+ { "--absolute", 'a', RTGETOPT_REQ_NOTHING },
+ { "--rel", 'r', RTGETOPT_REQ_NOTHING },
+ { "--relative", 'r', RTGETOPT_REQ_NOTHING },
+ { "--no-ts", 'T', RTGETOPT_REQ_NOTHING },
+ { "--flags", 'f', RTGETOPT_REQ_NOTHING },
+ { "--no-flags", 'F', RTGETOPT_REQ_NOTHING },
+ /* unnecessary legacy: */
+ { "--patterns", 'p', RTGETOPT_REQ_STRING },
+ { "-patterns", 'p', RTGETOPT_REQ_STRING },
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+
+ const char *pszVmNameOrUuid = NULL;
+ Utf8Str strPatterns;
+ bool fSort = true;
+ bool fNewStyle = true;
+ bool fTimestamp = true;
+ bool fAbsTime = true;
+ bool fFlags = true;
+
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ /* For options that require an argument, ValueUnion has received the value. */
+ switch (ch)
+ {
+ case VINF_GETOPT_NOT_OPTION:
+ /* The first one is the VM name. */
+ if (!pszVmNameOrUuid)
+ {
+ pszVmNameOrUuid = ValueUnion.psz;
+ break;
+ }
+ /* Everything else would be patterns by the new syntax. */
+ RT_FALL_THROUGH();
+ case 'p':
+ if (strPatterns.isNotEmpty())
+ if (RT_FAILURE(strPatterns.appendNoThrow(',')))
+ return RTMsgErrorExitFailure("out of memory!");
+ if (RT_FAILURE(strPatterns.appendNoThrow(ValueUnion.psz)))
+ return RTMsgErrorExitFailure("out of memory!");
+ break;
+
+ case 'o':
+ fNewStyle = false;
+ break;
+
+ case 's':
+ fSort = true;
+ break;
+ case 'u':
+ fSort = false;
+ break;
+
+ case 't':
+ fTimestamp = true;
+ break;
+ case 'T':
+ fTimestamp = false;
+ break;
+
+ case 'a':
+ fAbsTime = true;
+ break;
+ case 'r':
+ fAbsTime = false;
+ break;
+
+ case 'f':
+ fFlags = true;
+ break;
+ case 'F':
+ fFlags = false;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+
+ /* Only the VM name is required. */
+ if (!pszVmNameOrUuid)
+ return errorSyntax(GuestProp::tr("No VM name or UUID was specified"));
+
+ /*
+ * Make the actual call to Main.
+ */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszVmNameOrUuid).raw(), machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /* open a session for the VM - new or existing */
+ CHECK_ERROR2I_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+ com::SafeArray<LONG64> timestamps;
+ com::SafeArray<BSTR> flags;
+ CHECK_ERROR2I_RET(machine, EnumerateGuestProperties(Bstr(strPatterns).raw(),
+ ComSafeArrayAsOutParam(names),
+ ComSafeArrayAsOutParam(values),
+ ComSafeArrayAsOutParam(timestamps),
+ ComSafeArrayAsOutParam(flags)),
+ RTEXITCODE_FAILURE);
+
+ size_t const cEntries = names.size();
+ if (cEntries == 0)
+ RTPrintf(GuestProp::tr("No properties found.\n"));
+ else
+ {
+ /* Whether we sort it or not, we work it via a indirect index: */
+ size_t *paidxSorted = (size_t *)RTMemAlloc(sizeof(paidxSorted[0]) * cEntries);
+ if (!paidxSorted)
+ return RTMsgErrorExitFailure("out of memory!");
+ for (size_t i = 0; i < cEntries; i++)
+ paidxSorted[i] = i;
+
+ /* Do the sorting: */
+ if (fSort && cEntries > 1)
+ for (size_t i = 0; i < cEntries - 1; i++)
+ for (size_t j = 0; j < cEntries - i - 1; j++)
+ if (RTUtf16Cmp(names[paidxSorted[j]], names[paidxSorted[j + 1]]) > 0)
+ {
+ size_t iTmp = paidxSorted[j];
+ paidxSorted[j] = paidxSorted[j + 1];
+ paidxSorted[j + 1] = iTmp;
+ }
+
+ if (fNewStyle)
+ {
+ /* figure the width of the main columns: */
+ size_t cwcMaxName = 1;
+ size_t cwcMaxValue = 1;
+ for (size_t i = 0; i < cEntries; ++i)
+ {
+ size_t cwcName = RTUtf16Len(names[i]);
+ cwcMaxName = RT_MAX(cwcMaxName, cwcName);
+ size_t cwcValue = RTUtf16Len(values[i]);
+ cwcMaxValue = RT_MAX(cwcMaxValue, cwcValue);
+ }
+ cwcMaxName = RT_MIN(cwcMaxName, 48);
+ cwcMaxValue = RT_MIN(cwcMaxValue, 28);
+
+ /* Get the current time for relative time formatting: */
+ RTTIMESPEC Now;
+ RTTimeNow(&Now);
+
+ /* Print the table: */
+ for (size_t iSorted = 0; iSorted < cEntries; ++iSorted)
+ {
+ size_t const i = paidxSorted[iSorted];
+ char szTime[80];
+ if (fTimestamp)
+ {
+ RTTIMESPEC TimestampTS;
+ RTTimeSpecSetNano(&TimestampTS, timestamps[i]);
+ if (fAbsTime)
+ {
+ RTTIME Timestamp;
+ RTTimeToStringEx(RTTimeExplode(&Timestamp, &TimestampTS), &szTime[2], sizeof(szTime) - 2, 3);
+ }
+ else
+ {
+ RTTIMESPEC DurationTS = Now;
+ RTTimeFormatDurationEx(&szTime[2], sizeof(szTime) - 2, RTTimeSpecSub(&DurationTS, &TimestampTS), 3);
+ }
+ szTime[0] = '@';
+ szTime[1] = ' ';
+ }
+ else
+ szTime[0] = '\0';
+
+ static RTUTF16 s_wszEmpty[] = { 0 };
+ PCRTUTF16 const pwszFlags = fFlags ? flags[i] : s_wszEmpty;
+
+ int cchOut = RTPrintf("%-*ls = '%ls'", cwcMaxName, names[i], values[i]);
+ if (fTimestamp || *pwszFlags)
+ {
+ size_t const cwcWidth = cwcMaxName + cwcMaxValue + 6;
+ size_t const cwcValPadding = (unsigned)cchOut < cwcWidth ? cwcWidth - (unsigned)cchOut : 1;
+ RTPrintf("%*s%s%s%ls\n", cwcValPadding, "", szTime, *pwszFlags ? " " : "", pwszFlags);
+ }
+ else
+ RTPrintf("\n");
+ }
+ }
+ else
+ for (size_t iSorted = 0; iSorted < cEntries; ++iSorted)
+ {
+ size_t const i = paidxSorted[iSorted];
+ RTPrintf(GuestProp::tr("Name: %ls, value: %ls, timestamp: %lld, flags: %ls\n"),
+ names[i], values[i], timestamps[i], flags[i]);
+ }
+ RTMemFree(paidxSorted);
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Enumerates the properties in the guest property store.
+ *
+ * @returns 0 on success, 1 on failure
+ * @note see the command line API description for parameters
+ */
+static RTEXITCODE handleWaitGuestProperty(HandlerArg *a)
+{
+ setCurrentSubcommand(HELP_SCOPE_GUESTPROPERTY_WAIT);
+
+ /*
+ * Handle arguments
+ */
+ bool fFailOnTimeout = false;
+ const char *pszPatterns = NULL;
+ uint32_t cMsTimeout = RT_INDEFINITE_WAIT;
+ bool usageOK = true;
+ if (a->argc < 2)
+ usageOK = false;
+ else
+ pszPatterns = a->argv[1];
+ ComPtr<IMachine> machine;
+ HRESULT hrc;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (!machine)
+ usageOK = false;
+ for (int i = 2; usageOK && i < a->argc; ++i)
+ {
+ if ( !strcmp(a->argv[i], "--timeout")
+ || !strcmp(a->argv[i], "-timeout"))
+ {
+ if ( i + 1 >= a->argc
+ || RTStrToUInt32Full(a->argv[i + 1], 10, &cMsTimeout) != VINF_SUCCESS)
+ usageOK = false;
+ else
+ ++i;
+ }
+ else if (!strcmp(a->argv[i], "--fail-on-timeout"))
+ fFailOnTimeout = true;
+ else
+ usageOK = false;
+ }
+ if (!usageOK)
+ return errorSyntax(GuestProp::tr("Incorrect parameters"));
+
+ /*
+ * Set up the event listener and wait until found match or timeout.
+ */
+ Bstr aMachStrGuid;
+ machine->COMGETTER(Id)(aMachStrGuid.asOutParam());
+ Guid aMachGuid(aMachStrGuid);
+ ComPtr<IEventSource> es;
+ CHECK_ERROR(a->virtualBox, COMGETTER(EventSource)(es.asOutParam()));
+ ComPtr<IEventListener> listener;
+ CHECK_ERROR(es, CreateListener(listener.asOutParam()));
+ com::SafeArray <VBoxEventType_T> eventTypes(1);
+ eventTypes.push_back(VBoxEventType_OnGuestPropertyChanged);
+ CHECK_ERROR(es, RegisterListener(listener, ComSafeArrayAsInParam(eventTypes), false));
+
+ uint64_t u64Started = RTTimeMilliTS();
+ bool fSignalled = false;
+ do
+ {
+ unsigned cMsWait;
+ if (cMsTimeout == RT_INDEFINITE_WAIT)
+ cMsWait = 1000;
+ else
+ {
+ uint64_t cMsElapsed = RTTimeMilliTS() - u64Started;
+ if (cMsElapsed >= cMsTimeout)
+ break; /* timed out */
+ cMsWait = RT_MIN(1000, cMsTimeout - (uint32_t)cMsElapsed);
+ }
+
+ ComPtr<IEvent> ev;
+ hrc = es->GetEvent(listener, cMsWait, ev.asOutParam());
+ if (ev) /** @todo r=andy Why not using SUCCEEDED(hrc) here? */
+ {
+ VBoxEventType_T aType;
+ hrc = ev->COMGETTER(Type)(&aType);
+ switch (aType)
+ {
+ case VBoxEventType_OnGuestPropertyChanged:
+ {
+ ComPtr<IGuestPropertyChangedEvent> gpcev = ev;
+ Assert(gpcev);
+ Bstr aNextStrGuid;
+ gpcev->COMGETTER(MachineId)(aNextStrGuid.asOutParam());
+ if (aMachGuid != Guid(aNextStrGuid))
+ continue;
+ Bstr aNextName;
+ gpcev->COMGETTER(Name)(aNextName.asOutParam());
+ if (RTStrSimplePatternMultiMatch(pszPatterns, RTSTR_MAX,
+ Utf8Str(aNextName).c_str(), RTSTR_MAX, NULL))
+ {
+ Bstr aNextValue, aNextFlags;
+ BOOL aNextWasDeleted;
+ gpcev->COMGETTER(Value)(aNextValue.asOutParam());
+ gpcev->COMGETTER(Flags)(aNextFlags.asOutParam());
+ gpcev->COMGETTER(FWasDeleted)(&aNextWasDeleted);
+ if (aNextWasDeleted)
+ RTPrintf(GuestProp::tr("Property %ls was deleted\n"), aNextName.raw());
+ else
+ RTPrintf(GuestProp::tr("Name: %ls, value: %ls, flags: %ls\n"),
+ aNextName.raw(), aNextValue.raw(), aNextFlags.raw());
+ fSignalled = true;
+ }
+ break;
+ }
+ default:
+ AssertFailed();
+ }
+ }
+ } while (!fSignalled);
+
+ es->UnregisterListener(listener);
+
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ if (!fSignalled)
+ {
+ RTMsgError(GuestProp::tr("Time out or interruption while waiting for a notification."));
+ if (fFailOnTimeout)
+ /* Hysterical rasins: We always returned 2 here, which now translates to syntax error... Which is bad. */
+ rcExit = RTEXITCODE_SYNTAX;
+ }
+ return rcExit;
+}
+
+/**
+ * Access the guest property store.
+ *
+ * @returns 0 on success, 1 on failure
+ * @note see the command line API description for parameters
+ */
+RTEXITCODE handleGuestProperty(HandlerArg *a)
+{
+ if (a->argc == 0)
+ return errorNoSubcommand();
+
+ /** @todo This command does not follow the syntax where the <uuid|vmname>
+ * comes between the command and subcommand. The commands controlvm,
+ * snapshot and debugvm puts it between.
+ */
+
+ const char * const pszSubCmd = a->argv[0];
+ a->argc -= 1;
+ a->argv += 1;
+
+ /* switch (cmd) */
+ if (strcmp(pszSubCmd, "get") == 0)
+ return handleGetGuestProperty(a);
+ if (strcmp(pszSubCmd, "set") == 0)
+ return handleSetGuestProperty(a);
+ if (strcmp(pszSubCmd, "delete") == 0 || strcmp(pszSubCmd, "unset") == 0)
+ return handleDeleteGuestProperty(a);
+ if (strcmp(pszSubCmd, "enumerate") == 0 || strcmp(pszSubCmd, "enum") == 0)
+ return handleEnumGuestProperty(a);
+ if (strcmp(pszSubCmd, "wait") == 0)
+ return handleWaitGuestProperty(a);
+
+ /* default: */
+ return errorUnknownSubcommand(pszSubCmd);
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
new file mode 100644
index 00000000..0b6f39b1
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
@@ -0,0 +1,513 @@
+/* $Id: VBoxManageHelp.cpp $ */
+/** @file
+ * VBoxManage - help and other message output.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/version.h>
+
+#include <iprt/asm.h>
+#include <iprt/buildconfig.h>
+#include <iprt/ctype.h>
+#include <iprt/assert.h>
+#include <iprt/env.h>
+#include <iprt/err.h>
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/message.h>
+#include <iprt/uni.h>
+
+#include "VBoxManage.h"
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+/** If the usage is the given number of length long or longer, the error is
+ * repeated so the user can actually see it. */
+#define ERROR_REPEAT_AFTER_USAGE_LENGTH 16
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+DECLARE_TRANSLATION_CONTEXT(Help);
+
+static enum HELP_CMD_VBOXMANAGE g_enmCurCommand = HELP_CMD_COMMON;
+/** The scope mask for the current subcommand. */
+static uint64_t g_fCurSubcommandScope = RTMSGREFENTRYSTR_SCOPE_GLOBAL;
+
+/**
+ * Sets the current command.
+ *
+ * This affects future calls to error and help functions.
+ *
+ * @param enmCommand The command.
+ */
+void setCurrentCommand(enum HELP_CMD_VBOXMANAGE enmCommand)
+{
+ Assert(g_enmCurCommand == HELP_CMD_COMMON);
+ g_enmCurCommand = enmCommand;
+ g_fCurSubcommandScope = RTMSGREFENTRYSTR_SCOPE_GLOBAL;
+}
+
+
+/**
+ * Sets the current subcommand.
+ *
+ * This affects future calls to error and help functions.
+ *
+ * @param fSubcommandScope The subcommand scope.
+ */
+void setCurrentSubcommand(uint64_t fSubcommandScope)
+{
+ g_fCurSubcommandScope = fSubcommandScope;
+}
+
+
+/**
+ * Takes first char and make it uppercase.
+ *
+ * @returns pointer to string starting from next char.
+ * @param pszSrc Source string.
+ * @param pszDst Pointer to buffer to place first char uppercase.
+ */
+static const char *captialize(const char *pszSrc, char *pszDst)
+{
+ *RTStrPutCp(pszDst, RTUniCpToUpper(RTStrGetCp(pszSrc))) = '\0';
+ return RTStrNextCp(pszSrc);
+}
+
+
+/**
+ * Prints brief help for a command or subcommand.
+ *
+ * @returns Number of lines written.
+ * @param enmCommand The command.
+ * @param fSubcommandScope The subcommand scope, REFENTRYSTR_SCOPE_GLOBAL
+ * for all.
+ * @param pStrm The output stream.
+ */
+static uint32_t printBriefCommandOrSubcommandHelp(enum HELP_CMD_VBOXMANAGE enmCommand, uint64_t fSubcommandScope, PRTSTREAM pStrm)
+{
+ /*
+ * Try to find translated, falling back untranslated.
+ */
+ uint32_t cLinesWritten = 0;
+ uint32_t cPendingBlankLines = 0;
+ uint32_t cFound = 0;
+ PCHELP_LANG_ENTRY_T const apHelpLangEntries[] =
+ {
+ ASMAtomicUoReadPtrT(&g_pHelpLangEntry, PCHELP_LANG_ENTRY_T),
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ &g_aHelpLangEntries[0]
+#endif
+ };
+ for (uint32_t k = 0; k < RT_ELEMENTS(apHelpLangEntries) && cFound == 0; k++)
+ {
+ /* skip if english is used */
+ if (k > 0 && apHelpLangEntries[k] == apHelpLangEntries[0])
+ break;
+ uint32_t const cHelpEntries = *apHelpLangEntries[k]->pcHelpEntries;
+ for (uint32_t i = 0; i < cHelpEntries; i++)
+ {
+ PCRTMSGREFENTRY pHelp = apHelpLangEntries[k]->papHelpEntries[i];
+ if ( pHelp->idInternal == (int64_t)enmCommand
+ || enmCommand == HELP_CMD_COMMON)
+ {
+ cFound++;
+ if (cFound == 1)
+ {
+ if (fSubcommandScope == RTMSGREFENTRYSTR_SCOPE_GLOBAL)
+ {
+ char szFirstChar[8];
+ RTStrmPrintf(pStrm, Help::tr("Usage - %s%s:\n"), szFirstChar, captialize(pHelp->pszBrief, szFirstChar));
+ }
+ else
+ RTStrmPrintf(pStrm, Help::tr("Usage:\n"));
+ }
+ RTMsgRefEntryPrintStringTable(pStrm, &pHelp->Synopsis, fSubcommandScope, &cPendingBlankLines, &cLinesWritten);
+ if (!cPendingBlankLines)
+ cPendingBlankLines = 1;
+ }
+ }
+ }
+ Assert(cFound > 0);
+ return cLinesWritten;
+}
+
+
+/**
+ * Prints the brief usage information for the current (sub)command.
+ *
+ * @param pStrm The output stream.
+ */
+void printUsage(PRTSTREAM pStrm)
+{
+ printBriefCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, pStrm);
+}
+
+
+/**
+ * Prints full help for a command or subcommand.
+ *
+ * @param enmCommand The command.
+ * @param fSubcommandScope The subcommand scope, REFENTRYSTR_SCOPE_GLOBAL
+ * for all.
+ * @param pStrm The output stream.
+ */
+static void printFullCommandOrSubcommandHelp(enum HELP_CMD_VBOXMANAGE enmCommand, uint64_t fSubcommandScope, PRTSTREAM pStrm)
+{
+ /* Try to find translated, then untranslated */
+ uint32_t cPendingBlankLines = 0;
+ uint32_t cFound = 0;
+ PCHELP_LANG_ENTRY_T const apHelpLangEntries[] =
+ {
+ ASMAtomicUoReadPtrT(&g_pHelpLangEntry, PCHELP_LANG_ENTRY_T),
+#ifdef VBOX_WITH_VBOXMANAGE_NLS
+ &g_aHelpLangEntries[0]
+#endif
+ };
+ for (uint32_t k = 0; k < RT_ELEMENTS(apHelpLangEntries) && cFound == 0; k++)
+ {
+ /* skip if english is used */
+ if (k > 0 && apHelpLangEntries[k] == apHelpLangEntries[0])
+ break;
+ uint32_t const cHelpEntries = *apHelpLangEntries[k]->pcHelpEntries;
+ for (uint32_t i = 0; i < cHelpEntries; i++)
+ {
+ PCRTMSGREFENTRY pHelp = apHelpLangEntries[k]->papHelpEntries[i];
+
+ if ( pHelp->idInternal == (int64_t)enmCommand
+ || enmCommand == HELP_CMD_COMMON)
+ {
+ cFound++;
+ RTMsgRefEntryPrintStringTable(pStrm, &pHelp->Help, fSubcommandScope, &cPendingBlankLines, NULL /*pcLinesWritten*/);
+ if (cPendingBlankLines < 2)
+ cPendingBlankLines = 2;
+ }
+ }
+ }
+ Assert(cFound > 0);
+}
+
+
+/**
+ * Prints the full help for the current (sub)command.
+ *
+ * @param pStrm The output stream.
+ */
+void printHelp(PRTSTREAM pStrm)
+{
+ printFullCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, pStrm);
+}
+
+
+/**
+ * Display no subcommand error message and current command usage.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ */
+RTEXITCODE errorNoSubcommand(void)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+ Assert(g_fCurSubcommandScope == RTMSGREFENTRYSTR_SCOPE_GLOBAL);
+
+ return errorSyntax(Help::tr("No subcommand specified"));
+}
+
+
+/**
+ * Display unknown subcommand error message and current command usage.
+ *
+ * May show full command help instead if the subcommand is a common help option.
+ *
+ * @returns RTEXITCODE_SYNTAX, or RTEXITCODE_SUCCESS if common help option.
+ * @param pszSubcommand The name of the alleged subcommand.
+ */
+RTEXITCODE errorUnknownSubcommand(const char *pszSubcommand)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+ Assert(g_fCurSubcommandScope == RTMSGREFENTRYSTR_SCOPE_GLOBAL);
+
+ /* check if help was requested. */
+ if ( strcmp(pszSubcommand, "--help") == 0
+ || strcmp(pszSubcommand, "-h") == 0
+ || strcmp(pszSubcommand, "-?") == 0)
+ {
+ printFullCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ return errorSyntax(Help::tr("Unknown subcommand: %s"), pszSubcommand);
+}
+
+
+/**
+ * Display too many parameters error message and current command usage.
+ *
+ * May show full command help instead if the subcommand is a common help option.
+ *
+ * @returns RTEXITCODE_SYNTAX, or RTEXITCODE_SUCCESS if common help option.
+ * @param papszArgs The first unwanted parameter. Terminated by
+ * NULL entry.
+ */
+RTEXITCODE errorTooManyParameters(char **papszArgs)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+ Assert(g_fCurSubcommandScope != RTMSGREFENTRYSTR_SCOPE_GLOBAL);
+
+ /* check if help was requested. */
+ if (papszArgs)
+ {
+ for (uint32_t i = 0; papszArgs[i]; i++)
+ if ( strcmp(papszArgs[i], "--help") == 0
+ || strcmp(papszArgs[i], "-h") == 0
+ || strcmp(papszArgs[i], "-?") == 0)
+ {
+ printFullCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+ else if (!strcmp(papszArgs[i], "--"))
+ break;
+ }
+
+ return errorSyntax(Help::tr("Too many parameters"));
+}
+
+
+/**
+ * Display current (sub)command usage and the custom error message.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ * @param pszFormat Custom error message format string.
+ * @param va Format arguments.
+ */
+RTEXITCODE errorSyntaxV(const char *pszFormat, va_list va)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+
+ showLogo(g_pStdErr);
+
+ va_list vaCopy;
+ va_copy(vaCopy, va);
+ RTMsgErrorV(pszFormat, vaCopy);
+ va_end(vaCopy);
+
+ RTStrmPutCh(g_pStdErr, '\n');
+ if ( printBriefCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, g_pStdErr)
+ >= ERROR_REPEAT_AFTER_USAGE_LENGTH)
+ {
+ /* Usage was very long, repeat the error message. */
+ RTStrmPutCh(g_pStdErr, '\n');
+ RTMsgErrorV(pszFormat, va);
+ }
+ return RTEXITCODE_SYNTAX;
+}
+
+
+/**
+ * Display current (sub)command usage and the custom error message.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ * @param pszFormat Custom error message format string.
+ * @param ... Format arguments.
+ */
+RTEXITCODE errorSyntax(const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTEXITCODE rcExit = errorSyntaxV(pszFormat, va);
+ va_end(va);
+ return rcExit;
+}
+
+
+/**
+ * Display current (sub)command usage and the custom error message.
+ *
+ * @returns E_INVALIDARG
+ * @param pszFormat Custom error message format string.
+ * @param ... Format arguments.
+ */
+HRESULT errorSyntaxHr(const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ errorSyntaxV(pszFormat, va);
+ va_end(va);
+ return E_INVALIDARG;
+}
+
+
+/**
+ * Print an error message without the syntax stuff.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ */
+RTEXITCODE errorArgument(const char *pszFormat, ...)
+{
+ va_list args;
+ va_start(args, pszFormat);
+ RTMsgErrorV(pszFormat, args);
+ va_end(args);
+ return RTEXITCODE_SYNTAX;
+}
+
+
+/**
+ * Print an error message without the syntax stuff.
+ *
+ * @returns E_INVALIDARG.
+ */
+HRESULT errorArgumentHr(const char *pszFormat, ...)
+{
+ va_list args;
+ va_start(args, pszFormat);
+ RTMsgErrorV(pszFormat, args);
+ va_end(args);
+ return E_INVALIDARG;
+}
+
+
+/**
+ * Worker for errorGetOpt.
+ *
+ * @param rcGetOpt The RTGetOpt return value.
+ * @param pValueUnion The value union returned by RTGetOpt.
+ */
+static void errorGetOptWorker(int rcGetOpt, union RTGETOPTUNION const *pValueUnion)
+{
+ if (rcGetOpt == VINF_GETOPT_NOT_OPTION)
+ RTMsgError(Help::tr("Invalid parameter '%s'"), pValueUnion->psz);
+ else if (rcGetOpt > 0)
+ {
+ if (RT_C_IS_PRINT(rcGetOpt))
+ RTMsgError(Help::tr("Invalid option -%c"), rcGetOpt);
+ else
+ RTMsgError(Help::tr("Invalid option case %i"), rcGetOpt);
+ }
+ else if (rcGetOpt == VERR_GETOPT_UNKNOWN_OPTION)
+ RTMsgError(Help::tr("Unknown option: %s"), pValueUnion->psz);
+ else if (rcGetOpt == VERR_GETOPT_INVALID_ARGUMENT_FORMAT)
+ RTMsgError(Help::tr("Invalid argument format: %s"), pValueUnion->psz);
+ else if (pValueUnion->pDef)
+ RTMsgError("%s: %Rrs", pValueUnion->pDef->pszLong, rcGetOpt);
+ else
+ RTMsgError("%Rrs", rcGetOpt);
+}
+
+
+/**
+ * For use to deal with RTGetOptFetchValue failures.
+ *
+ * @retval RTEXITCODE_SYNTAX
+ * @param iValueNo The value number being fetched, counting the
+ * RTGetOpt value as zero and the first
+ * RTGetOptFetchValue call as one.
+ * @param pszOption The option being parsed.
+ * @param rcGetOptFetchValue The status returned by RTGetOptFetchValue.
+ * @param pValueUnion The value union returned by the fetch.
+ */
+RTEXITCODE errorFetchValue(int iValueNo, const char *pszOption, int rcGetOptFetchValue, union RTGETOPTUNION const *pValueUnion)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+ showLogo(g_pStdErr);
+ if (rcGetOptFetchValue == VERR_GETOPT_REQUIRED_ARGUMENT_MISSING)
+ RTMsgError(Help::tr("Missing the %u%s value for option %s"),
+ iValueNo,
+ iValueNo == 1 ? Help::tr("st")
+ : iValueNo == 2 ? Help::tr("nd")
+ : iValueNo == 3 ? Help::tr("rd")
+ : Help::tr("th"),
+ pszOption);
+ else
+ errorGetOptWorker(rcGetOptFetchValue, pValueUnion);
+ return RTEXITCODE_SYNTAX;
+
+}
+
+
+/**
+ * Handled an RTGetOpt error or common option.
+ *
+ * This implements the 'V' and 'h' cases. It reports appropriate syntax errors
+ * for other @a rcGetOpt values.
+ *
+ * @retval RTEXITCODE_SUCCESS if help or version request.
+ * @retval RTEXITCODE_SYNTAX if not help or version request.
+ * @param rcGetOpt The RTGetOpt return value.
+ * @param pValueUnion The value union returned by RTGetOpt.
+ */
+RTEXITCODE errorGetOpt(int rcGetOpt, union RTGETOPTUNION const *pValueUnion)
+{
+ Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
+
+ /*
+ * Check if it is an unhandled standard option.
+ */
+ if (rcGetOpt == 'V')
+ {
+ RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
+ return RTEXITCODE_SUCCESS;
+ }
+
+ if (rcGetOpt == 'h')
+ {
+ printFullCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, g_pStdOut);
+ return RTEXITCODE_SUCCESS;
+ }
+
+ /*
+ * We failed.
+ */
+ showLogo(g_pStdErr);
+ errorGetOptWorker(rcGetOpt, pValueUnion);
+ if ( printBriefCommandOrSubcommandHelp(g_enmCurCommand, g_fCurSubcommandScope, g_pStdErr)
+ >= ERROR_REPEAT_AFTER_USAGE_LENGTH)
+ {
+ /* Usage was very long, repeat the error message. */
+ RTStrmPutCh(g_pStdErr, '\n');
+ errorGetOptWorker(rcGetOpt, pValueUnion);
+ }
+ return RTEXITCODE_SYNTAX;
+}
+
+
+void showLogo(PRTSTREAM pStrm)
+{
+ static bool s_fShown; /* show only once */
+
+ if (!s_fShown)
+ {
+ RTStrmPrintf(pStrm, VBOX_PRODUCT " Command Line Management Interface Version "
+ VBOX_VERSION_STRING "\n"
+ "Copyright (C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n\n");
+ s_fShown = true;
+ }
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp
new file mode 100644
index 00000000..d5b2444d
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageHostonly.cpp
@@ -0,0 +1,546 @@
+/* $Id: VBoxManageHostonly.cpp $ */
+/** @file
+ * VBoxManage - Implementation of hostonlyif 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/cidr.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/net.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+
+DECLARE_TRANSLATION_CONTEXT(HostOnly);
+
+
+using namespace com;
+
+static const RTGETOPTDEF g_aHostOnlyCreateOptions[] =
+{
+ { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
+};
+
+#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
+static RTEXITCODE handleCreate(HandlerArg *a)
+{
+ /*
+ * Parse input.
+ */
+ bool fMachineReadable = false;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aHostOnlyCreateOptions,
+ RT_ELEMENTS(g_aHostOnlyCreateOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'M': // --machinereadable
+ fMachineReadable = true;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /*
+ * Do the work.
+ */
+ ComPtr<IHost> host;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IHostNetworkInterface> hif;
+ ComPtr<IProgress> progress;
+
+ CHECK_ERROR2I_RET(host, CreateHostOnlyNetworkInterface(hif.asOutParam(), progress.asOutParam()), RTEXITCODE_FAILURE);
+
+ if (fMachineReadable)
+ {
+ progress->WaitForCompletion(10000); /* Ten seconds should probably be enough. */
+ CHECK_PROGRESS_ERROR_RET(progress, (""), RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ /*HRESULT hrc =*/ showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (HostOnly::tr("Failed to create the host-only adapter")), RTEXITCODE_FAILURE);
+ }
+
+ Bstr bstrName;
+ CHECK_ERROR2I(hif, COMGETTER(Name)(bstrName.asOutParam()));
+
+ if (fMachineReadable)
+ RTPrintf("%ls", bstrName.raw());
+ else
+ RTPrintf(HostOnly::tr("Interface '%ls' was successfully created\n"), bstrName.raw());
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE handleRemove(HandlerArg *a)
+{
+ /*
+ * Parse input.
+ */
+ const char *pszName = NULL;
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, NULL, 0, 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ switch (ch)
+ {
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszName)
+ return errorSyntax(HostOnly::tr("Only one interface name can be specified"));
+ pszName = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ if (!pszName)
+ return errorSyntax(HostOnly::tr("No interface name was specified"));
+
+ /*
+ * Do the work.
+ */
+ ComPtr<IHost> host;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IHostNetworkInterface> hif;
+ CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE);
+
+ Bstr guid;
+ CHECK_ERROR2I_RET(hif, COMGETTER(Id)(guid.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IProgress> progress;
+ CHECK_ERROR2I_RET(host, RemoveHostOnlyNetworkInterface(guid.raw(), progress.asOutParam()), RTEXITCODE_FAILURE);
+
+ /*HRESULT hrc =*/ showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (HostOnly::tr("Failed to remove the host-only adapter")), RTEXITCODE_FAILURE);
+
+ return RTEXITCODE_SUCCESS;
+}
+#endif
+
+static const RTGETOPTDEF g_aHostOnlyIPOptions[]
+ = {
+ { "--dhcp", 'd', RTGETOPT_REQ_NOTHING },
+ { "-dhcp", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--ip", 'a', RTGETOPT_REQ_STRING },
+ { "-ip", 'a', RTGETOPT_REQ_STRING }, // deprecated
+ { "--netmask", 'm', RTGETOPT_REQ_STRING },
+ { "-netmask", 'm', RTGETOPT_REQ_STRING }, // deprecated
+ { "--ipv6", 'b', RTGETOPT_REQ_STRING },
+ { "-ipv6", 'b', RTGETOPT_REQ_STRING }, // deprecated
+ { "--netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 },
+ { "-netmasklengthv6", 'l', RTGETOPT_REQ_UINT8 } // deprecated
+ };
+
+static RTEXITCODE handleIpConfig(HandlerArg *a)
+{
+ bool fDhcp = false;
+ bool fNetmasklengthv6 = false;
+ uint32_t uNetmasklengthv6 = UINT32_MAX;
+ const char *pszIpv6 = NULL;
+ const char *pszIp = NULL;
+ const char *pszNetmask = NULL;
+ const char *pszName = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aHostOnlyIPOptions, RT_ELEMENTS(g_aHostOnlyIPOptions),
+ 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'd': // --dhcp
+ fDhcp = true;
+ break;
+ case 'a': // --ip
+ if (pszIp)
+ RTMsgWarning(HostOnly::tr("The --ip option is specified more than once"));
+ pszIp = ValueUnion.psz;
+ break;
+ case 'm': // --netmask
+ if (pszNetmask)
+ RTMsgWarning(HostOnly::tr("The --netmask option is specified more than once"));
+ pszNetmask = ValueUnion.psz;
+ break;
+ case 'b': // --ipv6
+ if (pszIpv6)
+ RTMsgWarning(HostOnly::tr("The --ipv6 option is specified more than once"));
+ pszIpv6 = ValueUnion.psz;
+ break;
+ case 'l': // --netmasklengthv6
+ if (fNetmasklengthv6)
+ RTMsgWarning(HostOnly::tr("The --netmasklengthv6 option is specified more than once"));
+ fNetmasklengthv6 = true;
+ uNetmasklengthv6 = ValueUnion.u8;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszName)
+ return errorSyntax(HostOnly::tr("Only one interface name can be specified"));
+ pszName = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* parameter sanity check */
+ if (fDhcp && (fNetmasklengthv6 || pszIpv6 || pszIp || pszNetmask))
+ return errorSyntax(HostOnly::tr("You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6."));
+ if ((pszIp || pszNetmask) && (fNetmasklengthv6 || pszIpv6))
+ return errorSyntax(HostOnly::tr("You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously."));
+
+ ComPtr<IHost> host;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IHostNetworkInterface> hif;
+ CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE);
+ if (hif.isNull())
+ return errorArgument(HostOnly::tr("Could not find interface '%s'"), pszName);
+
+ if (fDhcp)
+ CHECK_ERROR2I_RET(hif, EnableDynamicIPConfig(), RTEXITCODE_FAILURE);
+ else if (pszIp)
+ {
+ if (!pszNetmask)
+ pszNetmask = "255.255.255.0"; /* ?? */
+ CHECK_ERROR2I_RET(hif, EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw()), RTEXITCODE_FAILURE);
+ }
+ else if (pszIpv6)
+ {
+ BOOL fIpV6Supported;
+ CHECK_ERROR2I_RET(hif, COMGETTER(IPV6Supported)(&fIpV6Supported), RTEXITCODE_FAILURE);
+ if (!fIpV6Supported)
+ {
+ RTMsgError(HostOnly::tr("IPv6 setting is not supported for this adapter"));
+ return RTEXITCODE_FAILURE;
+ }
+
+ if (uNetmasklengthv6 == UINT32_MAX)
+ uNetmasklengthv6 = 64; /* ?? */
+ CHECK_ERROR2I_RET(hif, EnableStaticIPConfigV6(Bstr(pszIpv6).raw(), (ULONG)uNetmasklengthv6), RTEXITCODE_FAILURE);
+ }
+ else
+ return errorSyntax(HostOnly::tr("Neither -dhcp nor -ip nor -ipv6 was specfified"));
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+RTEXITCODE handleHostonlyIf(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorSyntax(HostOnly::tr("No sub-command specified"));
+
+ RTEXITCODE rcExit;
+ if (!strcmp(a->argv[0], "ipconfig"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYIF_IPCONFIG);
+ rcExit = handleIpConfig(a);
+ }
+#if defined(VBOX_WITH_NETFLT) && !defined(RT_OS_SOLARIS)
+ else if (!strcmp(a->argv[0], "create"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYIF_CREATE);
+ rcExit = handleCreate(a);
+ }
+ else if (!strcmp(a->argv[0], "remove"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYIF_REMOVE);
+ rcExit = handleRemove(a);
+ }
+#endif
+ else
+ rcExit = errorSyntax(HostOnly::tr("Unknown sub-command '%s'"), a->argv[0]);
+ return rcExit;
+}
+
+#ifdef VBOX_WITH_VMNET
+struct HostOnlyNetworkOptions
+{
+ bool fEnable;
+ bool fDisable;
+ Bstr bstrNetworkId;
+ Bstr bstrNetworkName;
+ Bstr bstrNetworkMask;
+ Bstr bstrLowerIp;
+ Bstr bstrUpperIp;
+ /* Initialize fEnable and fDisable */
+ HostOnlyNetworkOptions() : fEnable(false), fDisable(false) {};
+};
+typedef struct HostOnlyNetworkOptions HOSTONLYNETOPT;
+
+static RTEXITCODE createUpdateHostOnlyNetworkParse(HandlerArg *a, HOSTONLYNETOPT& options)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--netmask", 'm', RTGETOPT_REQ_STRING },
+ { "--lower-ip", 'l', RTGETOPT_REQ_STRING },
+ { "--lowerip", 'l', RTGETOPT_REQ_STRING },
+ { "--upper-ip", 'u', RTGETOPT_REQ_STRING },
+ { "--upperip", 'u', RTGETOPT_REQ_STRING },
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* iFirst */, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ options.bstrNetworkId = ValueUnion.psz;
+ break;
+ case 'n':
+ options.bstrNetworkName = ValueUnion.psz;
+ break;
+ case 'm':
+ options.bstrNetworkMask = ValueUnion.psz;
+ break;
+ case 'l':
+ options.bstrLowerIp = ValueUnion.psz;
+ break;
+ case 'u':
+ options.bstrUpperIp = ValueUnion.psz;
+ break;
+ case 'e':
+ options.fEnable = true;
+ break;
+ case 'd':
+ options.fDisable = true;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE createUpdateHostOnlyNetworkCommon(ComPtr<IHostOnlyNetwork> hostOnlyNetwork, HOSTONLYNETOPT& options)
+{
+ HRESULT hrc = S_OK;
+
+ if (options.bstrNetworkId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(Id)(options.bstrNetworkId.raw()), RTEXITCODE_FAILURE);
+ }
+ if (options.bstrNetworkName.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(NetworkName)(options.bstrNetworkName.raw()), RTEXITCODE_FAILURE);
+ }
+ if (options.bstrNetworkMask.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(NetworkMask)(options.bstrNetworkMask.raw()), RTEXITCODE_FAILURE);
+ }
+ if (options.bstrLowerIp.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(LowerIP)(options.bstrLowerIp.raw()), RTEXITCODE_FAILURE);
+ }
+ if (options.bstrUpperIp.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(UpperIP)(options.bstrUpperIp.raw()), RTEXITCODE_FAILURE);
+ }
+ if (options.fEnable)
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(Enabled)(TRUE), RTEXITCODE_FAILURE);
+ }
+ if (options.fDisable)
+ {
+ CHECK_ERROR2_RET(hrc, hostOnlyNetwork, COMSETTER(Enabled)(FALSE), RTEXITCODE_FAILURE);
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE handleNetAdd(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ HOSTONLYNETOPT options;
+ hrc = createUpdateHostOnlyNetworkParse(a, options);
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<IHostOnlyNetwork> hostOnlyNetwork;
+
+ if (options.bstrNetworkName.isEmpty())
+ return errorArgument(HostOnly::tr("The --name parameter must be specified"));
+ if (options.bstrNetworkMask.isEmpty())
+ return errorArgument(HostOnly::tr("The --netmask parameter must be specified"));
+ if (options.bstrLowerIp.isEmpty())
+ return errorArgument(HostOnly::tr("The --lower-ip parameter must be specified"));
+ if (options.bstrUpperIp.isEmpty())
+ return errorArgument(HostOnly::tr("The --upper-ip parameter must be specified"));
+
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ CreateHostOnlyNetwork(options.bstrNetworkName.raw(), hostOnlyNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+ return createUpdateHostOnlyNetworkCommon(hostOnlyNetwork, options);
+}
+
+static RTEXITCODE handleNetModify(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ HOSTONLYNETOPT options;
+ hrc = createUpdateHostOnlyNetworkParse(a, options);
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<IHostOnlyNetwork> hostOnlyNetwork;
+
+ if (options.bstrNetworkName.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindHostOnlyNetworkByName(options.bstrNetworkName.raw(), hostOnlyNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+ else if (options.bstrNetworkId.isNotEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindHostOnlyNetworkById(options.bstrNetworkId.raw(), hostOnlyNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+ else
+ return errorArgument(HostOnly::tr("Either --name or --id parameter must be specified"));
+
+ return createUpdateHostOnlyNetworkCommon(hostOnlyNetwork, options);
+}
+
+static RTEXITCODE handleNetRemove(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--id", 'i', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ };
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1 /* iFirst */, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ Bstr strNetworkId, strNetworkName;
+
+ int c;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i':
+ strNetworkId=ValueUnion.psz;
+ break;
+ case 'n':
+ strNetworkName=ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<IHostOnlyNetwork> hostOnlyNetwork;
+
+ if (!strNetworkName.isEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindHostOnlyNetworkByName(strNetworkName.raw(), hostOnlyNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+ else if (!strNetworkId.isEmpty())
+ {
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ FindHostOnlyNetworkById(strNetworkId.raw(), hostOnlyNetwork.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+ else
+ return errorArgument(HostOnly::tr("Either --name or --id parameter must be specified"));
+
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ RemoveHostOnlyNetwork(hostOnlyNetwork),
+ RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+RTEXITCODE handleHostonlyNet(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorSyntax(HostOnly::tr("No sub-command specified"));
+
+ RTEXITCODE rcExit;
+ if (!strcmp(a->argv[0], "add"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYNET_ADD);
+ rcExit = handleNetAdd(a);
+ }
+ else if (!strcmp(a->argv[0], "modify"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYNET_MODIFY);
+ rcExit = handleNetModify(a);
+ }
+ else if (!strcmp(a->argv[0], "remove"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_HOSTONLYNET_REMOVE);
+ rcExit = handleNetRemove(a);
+ }
+ else
+ rcExit = errorSyntax(HostOnly::tr("Unknown sub-command '%s'"), a->argv[0]);
+ return rcExit;
+}
+#endif /* VBOX_WITH_VMNET */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
new file mode 100644
index 00000000..524c1be2
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
@@ -0,0 +1,3231 @@
+/* $Id: VBoxManageInfo.cpp $ */
+/** @file
+ * VBoxManage - The 'showvminfo' command and helper routines.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+
+#include <VBox/com/VirtualBox.h>
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+#include <VBox/pci.h>
+#endif
+
+#include <VBox/log.h>
+#include <VBox/version.h>
+#include <iprt/stream.h>
+#include <iprt/time.h>
+#include <iprt/string.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+
+#include "VBoxManage.h"
+#include "VBoxManageUtils.h"
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Info);
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#define SHOW_UTF8_STRING(a_pszMachine, a_pszHuman, a_szValue) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, a_szValue); \
+ else \
+ RTPrintf("%-28s %s\n", a_pszHuman, a_szValue); \
+ } while (0)
+
+#define SHOW_BSTR_STRING(a_pszMachine, a_pszHuman, a_bstrValue) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, &a_bstrValue); \
+ else \
+ RTPrintf("%-28s %ls\n", a_pszHuman, a_bstrValue.raw()); \
+ } while (0)
+
+#define SHOW_BOOL_VALUE_EX(a_pszMachine, a_pszHuman, a_fValue, a_szTrue, a_szFalse) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, a_fValue ? "on" : "off"); \
+ else \
+ RTPrintf("%-28s %s\n", a_pszHuman, a_fValue ? a_szTrue: a_szFalse); \
+ } while (0)
+
+#define SHOW_BOOL_VALUE(a_pszMachine, a_pszHuman, a_fValue) \
+ SHOW_BOOL_VALUE_EX(a_pszMachine, a_pszHuman, a_fValue, Info::tr("enabled"), Info::tr("disabled"))
+
+#define SHOW_ULONG_VALUE(a_pszMachine, a_pszHuman, a_uValue, a_pszUnit) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ RTPrintf("%s=%u\n", a_pszMachine, a_uValue); \
+ else \
+ RTPrintf("%-28s %u%s\n", a_pszHuman, a_uValue, a_pszUnit); \
+ } while (0)
+
+#define SHOW_LONG64_VALUE(a_pszMachine, a_pszHuman, a_llValue, a_pszUnit) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ RTPrintf("%s=%lld\n", a_pszMachine, a_llValue); \
+ else \
+ RTPrintf("%-28s %lld%s\n", a_pszHuman, a_llValue, a_pszUnit); \
+ } while (0)
+
+#define SHOW_BOOLEAN_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
+ SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_pszMachine, a_pszHuman, Info::tr("enabled"), Info::tr("disabled"))
+
+#define SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_szTrue, a_szFalse) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ BOOL f; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&f), hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, f ? "on" : "off"); \
+ else \
+ RTPrintf("%-28s %s\n", a_pszHuman, f ? a_szTrue : a_szFalse); \
+ } while (0)
+
+#define SHOW_BOOLEAN_METHOD(a_pObj, a_Invocation, a_pszMachine, a_pszHuman) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ BOOL f; \
+ CHECK_ERROR2I_RET(a_pObj, a_Invocation, hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, f ? "on" : "off"); \
+ else \
+ RTPrintf("%-28s %s\n", a_pszHuman, f ? Info::tr("enabled") : Info::tr("disabled")); \
+ } while (0)
+
+#define SHOW_STRING_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ Bstr bstr; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, &bstr); \
+ else \
+ RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
+ } while (0)
+
+#define SHOW_STRING_PROP_NOT_EMPTY(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ Bstr bstr; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
+ if (bstr.isNotEmpty()) \
+ { \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, &bstr); \
+ else \
+ RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
+ } \
+ } while (0)
+
+ /** @def SHOW_STRING_PROP_MAJ
+ * For not breaking the output in a dot release we don't show default values. */
+#define SHOW_STRING_PROP_MAJ(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnless, a_uMajorVer) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ Bstr bstr; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
+ if ((a_uMajorVer) <= VBOX_VERSION_MAJOR || !bstr.equals(a_pszUnless)) \
+ { \
+ if (details == VMINFO_MACHINEREADABLE)\
+ outputMachineReadableString(a_pszMachine, &bstr); \
+ else \
+ RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
+ } \
+ } while (0)
+
+#define SHOW_STRINGARRAY_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ SafeArray<BSTR> array; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(ComSafeArrayAsOutParam(array)), hrcCheck); \
+ Utf8Str str; \
+ for (size_t i = 0; i < array.size(); i++) \
+ { \
+ if (i != 0) \
+ str.append(","); \
+ str.append(Utf8Str(array[i]).c_str()); \
+ } \
+ Bstr bstr(str); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ outputMachineReadableString(a_pszMachine, &bstr); \
+ else \
+ RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
+ } while (0)
+
+#define SHOW_UUID_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
+ SHOW_STRING_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman)
+
+#define SHOW_USHORT_PROP_EX2(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit, a_szFmtMachine, a_szFmtHuman) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ USHORT u16 = 0; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&u16), hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ RTPrintf("%s=" a_szFmtMachine "\n", a_pszMachine, u16); \
+ else \
+ RTPrintf("%-28s " a_szFmtHuman "%s\n", a_pszHuman, u16, u16, a_pszUnit); \
+ } while (0)
+
+#define SHOW_ULONG_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ ULONG u32 = 0; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&u32), hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ RTPrintf("%s=%u\n", a_pszMachine, u32); \
+ else \
+ RTPrintf("%-28s %u%s\n", a_pszHuman, u32, a_pszUnit); \
+ } while (0)
+
+#define SHOW_LONG64_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit) \
+ do \
+ { \
+ Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
+ LONG64 i64 = 0; \
+ CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&i64), hrcCheck); \
+ if (details == VMINFO_MACHINEREADABLE) \
+ RTPrintf("%s=%lld\n", a_pszMachine, i64); \
+ else \
+ RTPrintf("%-28s %'lld%s\n", a_pszHuman, i64, a_pszUnit); \
+ } while (0)
+
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Helper for formatting an indexed name or some such thing.
+ */
+static const char *FmtNm(char psz[80], const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTStrPrintfV(psz, 80, pszFormat, va);
+ va_end(va);
+ return psz;
+}
+
+HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
+ ComPtr<ISnapshot> &currentSnapshot,
+ VMINFO_DETAILS details,
+ const Utf8Str &prefix /* = ""*/,
+ int level /*= 0*/)
+{
+ /* start with the root */
+ Bstr name;
+ Bstr uuid;
+ Bstr description;
+ CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Name)(name.asOutParam()), hrcCheck);
+ CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Id)(uuid.asOutParam()), hrcCheck);
+ CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Description)(description.asOutParam()), hrcCheck);
+ bool fCurrent = (rootSnapshot == currentSnapshot);
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ /* print with hierarchical numbering */
+ RTPrintf("SnapshotName%s=\"%ls\"\n", prefix.c_str(), name.raw());
+ RTPrintf("SnapshotUUID%s=\"%s\"\n", prefix.c_str(), Utf8Str(uuid).c_str());
+ if (!description.isEmpty())
+ RTPrintf("SnapshotDescription%s=\"%ls\"\n", prefix.c_str(), description.raw());
+ if (fCurrent)
+ {
+ RTPrintf("CurrentSnapshotName=\"%ls\"\n", name.raw());
+ RTPrintf("CurrentSnapshotUUID=\"%s\"\n", Utf8Str(uuid).c_str());
+ RTPrintf("CurrentSnapshotNode=\"SnapshotName%s\"\n", prefix.c_str());
+ }
+ }
+ else
+ {
+ /* print with indentation */
+ RTPrintf(Info::tr(" %sName: %ls (UUID: %s)%s\n"),
+ prefix.c_str(),
+ name.raw(),
+ Utf8Str(uuid).c_str(),
+ (fCurrent) ? " *" : "");
+ if (!description.isEmpty() && RTUtf16Chr(description.raw(), '\n') == NULL)
+ RTPrintf(Info::tr(" %sDescription: %ls\n"), prefix.c_str(), description.raw());
+ else if (!description.isEmpty())
+ RTPrintf(Info::tr(" %sDescription:\n%ls\n"), prefix.c_str(), description.raw());
+ }
+
+ /* get the children */
+ HRESULT hrc = S_OK;
+ SafeIfaceArray <ISnapshot> coll;
+ CHECK_ERROR2I_RET(rootSnapshot,COMGETTER(Children)(ComSafeArrayAsOutParam(coll)), hrcCheck);
+ if (!coll.isNull())
+ {
+ for (size_t index = 0; index < coll.size(); ++index)
+ {
+ ComPtr<ISnapshot> snapshot = coll[index];
+ if (snapshot)
+ {
+ Utf8Str newPrefix;
+ if (details == VMINFO_MACHINEREADABLE)
+ newPrefix.printf("%s-%d", prefix.c_str(), index + 1);
+ else
+ newPrefix.printf("%s ", prefix.c_str());
+
+ /* recursive call */
+ HRESULT hrc2 = showSnapshots(snapshot, currentSnapshot, details, newPrefix, level + 1);
+ if (FAILED(hrc2))
+ hrc = hrc2;
+ }
+ }
+ }
+ return hrc;
+}
+
+static void makeTimeStr(char *s, int cb, int64_t millies)
+{
+ RTTIME t;
+ RTTIMESPEC ts;
+
+ RTTimeSpecSetMilli(&ts, millies);
+
+ RTTimeExplode(&t, &ts);
+
+ RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
+ t.i32Year, t.u8Month, t.u8MonthDay,
+ t.u8Hour, t.u8Minute, t.u8Second);
+}
+
+const char *machineStateToName(MachineState_T machineState, bool fShort)
+{
+ switch (machineState)
+ {
+ case MachineState_PoweredOff:
+ return fShort ? "poweroff" : Info::tr("powered off");
+ case MachineState_Saved:
+ return fShort ? "saved" : Info::tr("saved");
+ case MachineState_Teleported:
+ return fShort ? "teleported" : Info::tr("teleported");
+ case MachineState_Aborted:
+ return fShort ? "aborted" : Info::tr("aborted");
+ case MachineState_AbortedSaved:
+ return fShort ? "aborted-saved" : Info::tr("aborted-saved");
+ case MachineState_Running:
+ return fShort ? "running" : Info::tr("running");
+ case MachineState_Paused:
+ return fShort ? "paused" : Info::tr("paused");
+ case MachineState_Stuck:
+ return fShort ? "gurumeditation" : Info::tr("guru meditation");
+ case MachineState_Teleporting:
+ return fShort ? "teleporting" : Info::tr("teleporting");
+ case MachineState_LiveSnapshotting:
+ return fShort ? "livesnapshotting" : Info::tr("live snapshotting");
+ case MachineState_Starting:
+ return fShort ? "starting" : Info::tr("starting");
+ case MachineState_Stopping:
+ return fShort ? "stopping" : Info::tr("stopping");
+ case MachineState_Saving:
+ return fShort ? "saving" : Info::tr("saving");
+ case MachineState_Restoring:
+ return fShort ? "restoring" : Info::tr("restoring");
+ case MachineState_TeleportingPausedVM:
+ return fShort ? "teleportingpausedvm" : Info::tr("teleporting paused vm");
+ case MachineState_TeleportingIn:
+ return fShort ? "teleportingin" : Info::tr("teleporting (incoming)");
+ case MachineState_DeletingSnapshotOnline:
+ return fShort ? "deletingsnapshotlive" : Info::tr("deleting snapshot live");
+ case MachineState_DeletingSnapshotPaused:
+ return fShort ? "deletingsnapshotlivepaused" : Info::tr("deleting snapshot live paused");
+ case MachineState_OnlineSnapshotting:
+ return fShort ? "onlinesnapshotting" : Info::tr("online snapshotting");
+ case MachineState_RestoringSnapshot:
+ return fShort ? "restoringsnapshot" : Info::tr("restoring snapshot");
+ case MachineState_DeletingSnapshot:
+ return fShort ? "deletingsnapshot" : Info::tr("deleting snapshot");
+ case MachineState_SettingUp:
+ return fShort ? "settingup" : Info::tr("setting up");
+ case MachineState_Snapshotting:
+ return fShort ? "snapshotting" : Info::tr("offline snapshotting");
+ default:
+ break;
+ }
+ return Info::tr("unknown");
+}
+
+const char *facilityStateToName(AdditionsFacilityStatus_T faStatus, bool fShort)
+{
+ switch (faStatus)
+ {
+ case AdditionsFacilityStatus_Inactive:
+ return fShort ? "inactive" : Info::tr("not active");
+ case AdditionsFacilityStatus_Paused:
+ return fShort ? "paused" : Info::tr("paused");
+ case AdditionsFacilityStatus_PreInit:
+ return fShort ? "preinit" : Info::tr("pre-initializing");
+ case AdditionsFacilityStatus_Init:
+ return fShort ? "init" : Info::tr("initializing");
+ case AdditionsFacilityStatus_Active:
+ return fShort ? "active" : Info::tr("active/running");
+ case AdditionsFacilityStatus_Terminating:
+ return fShort ? "terminating" : Info::tr("terminating");
+ case AdditionsFacilityStatus_Terminated:
+ return fShort ? "terminated" : Info::tr("terminated");
+ case AdditionsFacilityStatus_Failed:
+ return fShort ? "failed" : Info::tr("failed");
+ case AdditionsFacilityStatus_Unknown:
+ default:
+ break;
+ }
+ return Info::tr("unknown");
+}
+
+static const char *storageControllerTypeToName(StorageControllerType_T enmCtlType, bool fMachineReadable = false)
+{
+ switch (enmCtlType)
+ {
+ case StorageControllerType_LsiLogic:
+ return "LsiLogic";
+ case StorageControllerType_LsiLogicSas:
+ return "LsiLogicSas";
+ case StorageControllerType_BusLogic:
+ return "BusLogic";
+ case StorageControllerType_IntelAhci:
+ return "IntelAhci";
+ case StorageControllerType_PIIX3:
+ return "PIIX3";
+ case StorageControllerType_PIIX4:
+ return "PIIX4";
+ case StorageControllerType_ICH6:
+ return "ICH6";
+ case StorageControllerType_I82078:
+ return "I82078";
+ case StorageControllerType_USB:
+ return "USB";
+ case StorageControllerType_NVMe:
+ return "NVMe";
+ case StorageControllerType_VirtioSCSI:
+ return "VirtioSCSI";
+ default:
+ return fMachineReadable ? "unknown" : Info::tr("unknown");
+ }
+}
+
+
+DECLINLINE(bool) doesMachineReadableStringNeedEscaping(const char *psz)
+{
+ return psz == NULL
+ || *psz == '\0'
+ || strchr(psz, '"') != NULL
+ || strchr(psz, '\\') != NULL;
+}
+
+
+/**
+ * This simply outputs the string adding necessary escaping and nothing else.
+ */
+void outputMachineReadableStringWorker(const char *psz)
+{
+ for (;;)
+ {
+ const char *pszDoubleQuote = strchr(psz, '"');
+ const char *pszSlash = strchr(psz, '\\');
+ const char *pszNext;
+ if (pszSlash)
+ pszNext = !pszDoubleQuote || (uintptr_t)pszSlash < (uintptr_t)pszDoubleQuote ? pszSlash : pszDoubleQuote;
+ else if (pszDoubleQuote)
+ pszNext = pszDoubleQuote;
+ else
+ {
+ RTStrmWrite(g_pStdOut, psz, strlen(psz));
+ break;
+ }
+ RTStrmWrite(g_pStdOut, psz, pszNext - psz);
+ char const szTmp[2] = { '\\', *pszNext };
+ RTStrmWrite(g_pStdOut, szTmp, sizeof(szTmp));
+
+ psz = pszNext + 1;
+ }
+}
+
+
+/**
+ * This takes care of escaping double quotes and slashes that the string might
+ * contain.
+ *
+ * @param pszName The variable name.
+ * @param pszValue The value.
+ * @param fQuoteName Whether to unconditionally quote the name or not.
+ * @param fNewline Whether to automatically add a newline after the value.
+ */
+void outputMachineReadableString(const char *pszName, const char *pszValue, bool fQuoteName /*=false*/, bool fNewline /*=true*/)
+{
+ if (!fQuoteName)
+ fQuoteName = strchr(pszName, '=') != NULL;
+ bool const fEscapeName = doesMachineReadableStringNeedEscaping(pszName);
+ bool const fEscapeValue = doesMachineReadableStringNeedEscaping(pszValue);
+ if (!fEscapeName && !fEscapeValue)
+ {
+ if (fNewline)
+ RTPrintf(!fQuoteName ? "%s=\"%s\"\n" : "\"%s\"=\"%s\"\n", pszName, pszValue);
+ else
+ RTPrintf(!fQuoteName ? "%s=\"%s\"" : "\"%s\"=\"%s\"", pszName, pszValue);
+ }
+ else
+ {
+ /* The name and string quotation: */
+ if (!fEscapeName)
+ RTPrintf(fQuoteName ? "\"%s\"=\"" : "%s=\"", pszName);
+ else
+ {
+ if (fQuoteName)
+ RTStrmWrite(g_pStdOut, RT_STR_TUPLE("\""));
+ outputMachineReadableStringWorker(pszName);
+ if (fQuoteName)
+ RTStrmWrite(g_pStdOut, RT_STR_TUPLE("\"=\""));
+ else
+ RTStrmWrite(g_pStdOut, RT_STR_TUPLE("=\""));
+ }
+
+ /* the value and the closing quotation */
+ outputMachineReadableStringWorker(pszValue);
+ if (fNewline)
+ RTStrmWrite(g_pStdOut, RT_STR_TUPLE("\"\n"));
+ else
+ RTStrmWrite(g_pStdOut, RT_STR_TUPLE("\""));
+ }
+}
+
+
+/**
+ * This takes care of escaping double quotes and slashes that the string might
+ * contain.
+ *
+ * @param pszName The variable name.
+ * @param pbstrValue The value.
+ * @param fQuoteName Whether to unconditionally quote the name or not.
+ * @param fNewline Whether to automatically add a newline after the value.
+ */
+void outputMachineReadableString(const char *pszName, Bstr const *pbstrValue, bool fQuoteName /*=false*/, bool fNewline /*=true*/)
+{
+ com::Utf8Str strValue(*pbstrValue);
+ outputMachineReadableString(pszName, strValue.c_str(), fQuoteName, fNewline);
+}
+
+
+/**
+ * Variant that allows formatting the name string, C string value.
+ *
+ * @param pszValue The value.
+ * @param fQuoteName Whether to unconditionally quote the name or not.
+ * @param pszNameFmt The variable name.
+ */
+void outputMachineReadableStringWithFmtName(const char *pszValue, bool fQuoteName, const char *pszNameFmt, ...)
+{
+ com::Utf8Str strName;
+ va_list va;
+ va_start(va, pszNameFmt);
+ strName.printfV(pszNameFmt, va);
+ va_end(va);
+
+ outputMachineReadableString(strName.c_str(), pszValue, fQuoteName);
+}
+
+
+/**
+ * Variant that allows formatting the name string, Bstr value.
+ *
+ * @param pbstrValue The value.
+ * @param fQuoteName Whether to unconditionally quote the name or not.
+ * @param pszNameFmt The variable name.
+ */
+void outputMachineReadableStringWithFmtName(com::Bstr const *pbstrValue, bool fQuoteName, const char *pszNameFmt, ...)
+{
+ com::Utf8Str strName;
+ va_list va;
+ va_start(va, pszNameFmt);
+ strName.printfV(pszNameFmt, va);
+ va_end(va);
+
+ outputMachineReadableString(strName.c_str(), pbstrValue, fQuoteName);
+}
+
+
+/**
+ * Machine readable outputting of a boolean value.
+ */
+void outputMachineReadableBool(const char *pszName, BOOL const *pfValue)
+{
+ RTPrintf("%s=\"%s\"\n", pszName, *pfValue ? "on" : "off");
+}
+
+
+/**
+ * Machine readable outputting of a boolean value.
+ */
+void outputMachineReadableBool(const char *pszName, bool const *pfValue)
+{
+ RTPrintf("%s=\"%s\"\n", pszName, *pfValue ? "on" : "off");
+}
+
+
+/**
+ * Machine readable outputting of a ULONG value.
+ */
+void outputMachineReadableULong(const char *pszName, ULONG *puValue)
+{
+ RTPrintf("%s=\"%u\"\n", pszName, *puValue);
+}
+
+
+/**
+ * Machine readable outputting of a LONG64 value.
+ */
+void outputMachineReadableLong64(const char *pszName, LONG64 *puValue)
+{
+ RTPrintf("%s=\"%llu\"\n", pszName, *puValue);
+}
+
+
+/**
+ * Helper for parsing extra data config.
+ * @returns true, false, or -1 if invalid.
+ */
+static int parseCfgmBool(Bstr const *pbstr)
+{
+ /* GetExtraData returns empty strings if the requested data wasn't
+ found, so fend that off first: */
+ size_t cwcLeft = pbstr->length();
+ if (!cwcLeft)
+ return false;
+ PCRTUTF16 pwch = pbstr->raw();
+
+ /* Skip type prefix: */
+ if ( cwcLeft >= 8
+ && pwch[0] == 'i'
+ && pwch[1] == 'n'
+ && pwch[2] == 't'
+ && pwch[3] == 'e'
+ && pwch[4] == 'g'
+ && pwch[5] == 'e'
+ && pwch[6] == 'r'
+ && pwch[7] == ':')
+ {
+ pwch += 8;
+ cwcLeft -= 8;
+ }
+
+ /* Hex prefix? */
+ bool fHex = false;
+ if ( cwcLeft >= 2
+ && pwch[0] == '0'
+ && (pwch[1] == 'x' || pwch[1] == 'X'))
+ {
+ pwch += 2;
+ cwcLeft -= 2;
+ fHex = true;
+ }
+
+ /* Empty string is wrong: */
+ if (cwcLeft == 0)
+ return -1;
+
+ /* Check that it's all digits and return when we find a non-zero
+ one or reaches the end: */
+ do
+ {
+ RTUTF16 const wc = *pwch++;
+ if (!RT_C_IS_DIGIT(wc) && (!fHex || !RT_C_IS_XDIGIT(wc)))
+ return -1;
+ if (wc != '0')
+ return true;
+ } while (--cwcLeft > 0);
+ return false;
+}
+
+
+/**
+ * Converts bandwidth group type to a string.
+ * @returns String representation.
+ * @param enmType Bandwidth control group type.
+ */
+static const char * bwGroupTypeToString(BandwidthGroupType_T enmType)
+{
+ switch (enmType)
+ {
+ case BandwidthGroupType_Null: return Info::tr("Null");
+ case BandwidthGroupType_Disk: return Info::tr("Disk");
+ case BandwidthGroupType_Network: return Info::tr("Network");
+#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
+ case BandwidthGroupType_32BitHack: break; /* Shut up compiler warnings. */
+#endif
+ }
+ return Info::tr("unknown");
+}
+
+HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
+ VMINFO_DETAILS details)
+{
+ SafeIfaceArray<IBandwidthGroup> bwGroups;
+ CHECK_ERROR2I_RET(bwCtrl, GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)), hrcCheck);
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(bwGroups.size() != 0 ? "\n" : Info::tr("<none>\n"));
+ for (size_t i = 0; i < bwGroups.size(); i++)
+ {
+ Bstr strName;
+ CHECK_ERROR2I_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), hrcCheck);
+ BandwidthGroupType_T enmType;
+ CHECK_ERROR2I_RET(bwGroups[i], COMGETTER(Type)(&enmType), hrcCheck);
+ LONG64 cbMaxPerSec;
+ CHECK_ERROR2I_RET(bwGroups[i], COMGETTER(MaxBytesPerSec)(&cbMaxPerSec), hrcCheck);
+
+ const char *pszType = bwGroupTypeToString(enmType);
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ /* Complicated condensed format. */
+ char szName[64];
+ RTStrPrintf(szName, sizeof(szName), "BandwidthGroup%zu", i);
+ outputMachineReadableString(szName, &strName, false /*fQuoteName*/, false /*fNewline*/);
+ RTPrintf(",%s,%RI64\n", pszType, cbMaxPerSec);
+ }
+ else
+ {
+ if (cbMaxPerSec == 0)
+ {
+ RTPrintf(Info::tr("#%zu: Name: '%ls', Type: %s, Limit: none (disabled)\n"), i, strName.raw(), pszType);
+ continue;
+ }
+
+ /* translate to human readable units.*/
+ const char *pszUnit;
+ LONG64 cUnits;
+ if (!(cbMaxPerSec % _1G))
+ {
+ cUnits = cbMaxPerSec / _1G;
+ pszUnit = "GiB/s";
+ }
+ else if (!(cbMaxPerSec % _1M))
+ {
+ cUnits = cbMaxPerSec / _1M;
+ pszUnit = "MiB/s";
+ }
+ else if (!(cbMaxPerSec % _1K))
+ {
+ cUnits = cbMaxPerSec / _1K;
+ pszUnit = "KiB/s";
+ }
+ else
+ {
+ cUnits = cbMaxPerSec;
+ pszUnit = "bytes/s";
+ }
+
+ /*
+ * We want to report network rate limit in bits/s, not bytes.
+ * Only if it cannot be express it in kilobits we will fall
+ * back to reporting it in bytes.
+ */
+ if ( enmType == BandwidthGroupType_Network
+ && !(cbMaxPerSec % 125) )
+ {
+ LONG64 cNetUnits = cbMaxPerSec / 125;
+ const char *pszNetUnit = "kbps";
+ if (!(cNetUnits % 1000000))
+ {
+ cNetUnits /= 1000000;
+ pszNetUnit = "Gbps";
+ }
+ else if (!(cNetUnits % 1000))
+ {
+ cNetUnits /= 1000;
+ pszNetUnit = "Mbps";
+ }
+ RTPrintf(Info::tr("#%zu: Name: '%ls', Type: %s, Limit: %RI64 %s (%RI64 %s)\n"),
+ i, strName.raw(), pszType, cNetUnits, pszNetUnit, cUnits, pszUnit);
+ }
+ else
+ RTPrintf(Info::tr("#%zu: Name: '%ls', Type: %s, Limit: %RI64 %s\n"), i, strName.raw(), pszType, cUnits, pszUnit);
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+/** Shows a shared folder. */
+static HRESULT showSharedFolder(ComPtr<ISharedFolder> &sf, VMINFO_DETAILS details, const char *pszDesc,
+ const char *pszMrInfix, size_t idxMr, bool fFirst)
+{
+ Bstr name, hostPath, bstrAutoMountPoint;
+ BOOL writable = FALSE, fAutoMount = FALSE;
+ CHECK_ERROR2I_RET(sf, COMGETTER(Name)(name.asOutParam()), hrcCheck);
+ CHECK_ERROR2I_RET(sf, COMGETTER(HostPath)(hostPath.asOutParam()), hrcCheck);
+ CHECK_ERROR2I_RET(sf, COMGETTER(Writable)(&writable), hrcCheck);
+ CHECK_ERROR2I_RET(sf, COMGETTER(AutoMount)(&fAutoMount), hrcCheck);
+ CHECK_ERROR2I_RET(sf, COMGETTER(AutoMountPoint)(bstrAutoMountPoint.asOutParam()), hrcCheck);
+
+ if (fFirst && details != VMINFO_MACHINEREADABLE)
+ RTPrintf("\n\n");
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ char szNm[80];
+ outputMachineReadableString(FmtNm(szNm, "SharedFolderName%s%zu", pszMrInfix, idxMr), &name);
+ outputMachineReadableString(FmtNm(szNm, "SharedFolderPath%s%zu", pszMrInfix, idxMr), &hostPath);
+ }
+ else
+ {
+ RTPrintf(Info::tr("Name: '%ls', Host path: '%ls' (%s), %s%s"),
+ name.raw(), hostPath.raw(), pszDesc, writable ? Info::tr("writable") : Info::tr("readonly"),
+ fAutoMount ? Info::tr(", auto-mount") : "");
+ if (bstrAutoMountPoint.isNotEmpty())
+ RTPrintf(Info::tr(", mount-point: '%ls'\n"), bstrAutoMountPoint.raw());
+ else
+ RTPrintf("\n");
+ }
+ return S_OK;
+}
+
+/** Displays a list of IUSBDevices or IHostUSBDevices. */
+template <class IUSBDeviceType>
+static HRESULT showUsbDevices(SafeIfaceArray<IUSBDeviceType> &coll, const char *pszPfx,
+ const char *pszName, VMINFO_DETAILS details)
+{
+ if (coll.size() > 0)
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s\n\n", pszName);
+ for (size_t i = 0; i < coll.size(); ++i)
+ {
+ ComPtr<IUSBDeviceType> dev = coll[i];
+ char szValue[128];
+ char szNm[80];
+
+ SHOW_STRING_PROP(dev, Id, FmtNm(szNm, "%sActive%zu", pszPfx, i + 1), "UUID:");
+ SHOW_USHORT_PROP_EX2(dev, VendorId, FmtNm(szNm, "%sVendorId%zu", pszPfx, i + 1), Info::tr("VendorId:"), "", "%#06x", "%#06x (%04X)");
+ SHOW_USHORT_PROP_EX2(dev, ProductId, FmtNm(szNm, "%sProductId%zu", pszPfx, i + 1), Info::tr("ProductId:"), "", "%#06x", "%#06x (%04X)");
+
+ USHORT bcdRevision;
+ CHECK_ERROR2I_RET(dev, COMGETTER(Revision)(&bcdRevision), hrcCheck);
+ if (details == VMINFO_MACHINEREADABLE)
+ RTStrPrintf(szValue, sizeof(szValue), "%#04x%02x", bcdRevision >> 8, bcdRevision & 0xff);
+ else
+ RTStrPrintf(szValue, sizeof(szValue), "%u.%u (%02u%02u)\n",
+ bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff);
+ SHOW_UTF8_STRING(FmtNm(szNm, "%sRevision%zu", pszPfx, i + 1), Info::tr("Revision:"), szValue);
+
+ SHOW_STRING_PROP_NOT_EMPTY(dev, Manufacturer, FmtNm(szNm, "%sManufacturer%zu", pszPfx, i + 1), Info::tr("Manufacturer:"));
+ SHOW_STRING_PROP_NOT_EMPTY(dev, Product, FmtNm(szNm, "%sProduct%zu", pszPfx, i + 1), Info::tr("Product:"));
+ SHOW_STRING_PROP_NOT_EMPTY(dev, SerialNumber, FmtNm(szNm, "%sSerialNumber%zu", pszPfx, i + 1), Info::tr("SerialNumber:"));
+ SHOW_STRING_PROP_NOT_EMPTY(dev, Address, FmtNm(szNm, "%sAddress%zu", pszPfx, i + 1), Info::tr("Address:"));
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("\n");
+ }
+ }
+ else if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s %s\n", pszName, Info::tr("<none>"));
+ return S_OK;
+}
+
+/** Displays the medium attachments of the given controller. */
+static HRESULT showMediumAttachments(ComPtr<IMachine> &machine, ComPtr<IStorageController> ptrStorageCtl, VMINFO_DETAILS details)
+{
+ Bstr bstrStorageCtlName;
+ CHECK_ERROR2I_RET(ptrStorageCtl, COMGETTER(Name)(bstrStorageCtlName.asOutParam()), hrcCheck);
+ ULONG cDevices;
+ CHECK_ERROR2I_RET(ptrStorageCtl, COMGETTER(MaxDevicesPerPortCount)(&cDevices), hrcCheck);
+ ULONG cPorts;
+ CHECK_ERROR2I_RET(ptrStorageCtl, COMGETTER(PortCount)(&cPorts), hrcCheck);
+
+ for (ULONG i = 0; i < cPorts; ++ i)
+ {
+ for (ULONG k = 0; k < cDevices; ++ k)
+ {
+ ComPtr<IMediumAttachment> mediumAttach;
+ HRESULT hrc = machine->GetMediumAttachment(bstrStorageCtlName.raw(), i, k, mediumAttach.asOutParam());
+ if (!SUCCEEDED(hrc) && hrc != VBOX_E_OBJECT_NOT_FOUND)
+ {
+ com::GlueHandleComError(machine, "GetMediumAttachment", hrc, __FILE__, __LINE__);
+ return hrc;
+ }
+
+ BOOL fIsEjected = FALSE;
+ BOOL fTempEject = FALSE;
+ BOOL fHotPlug = FALSE;
+ BOOL fNonRotational = FALSE;
+ BOOL fDiscard = FALSE;
+ DeviceType_T devType = DeviceType_Null;
+ if (mediumAttach)
+ {
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(TemporaryEject)(&fTempEject), hrcCheck);
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(IsEjected)(&fIsEjected), hrcCheck);
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(Type)(&devType), hrcCheck);
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(HotPluggable)(&fHotPlug), hrcCheck);
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(NonRotational)(&fNonRotational), hrcCheck);
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(Discard)(&fDiscard), hrcCheck);
+ }
+
+ ComPtr<IMedium> medium;
+ hrc = machine->GetMedium(bstrStorageCtlName.raw(), i, k, medium.asOutParam());
+ if (SUCCEEDED(hrc) && medium)
+ {
+ BOOL fPassthrough = FALSE;
+ if (mediumAttach)
+ {
+ CHECK_ERROR2I_RET(mediumAttach, COMGETTER(Passthrough)(&fPassthrough), hrcCheck);
+ }
+
+ Bstr bstrFilePath;
+ CHECK_ERROR2I_RET(medium, COMGETTER(Location)(bstrFilePath.asOutParam()), hrcCheck);
+ Bstr bstrUuid;
+ CHECK_ERROR2I_RET(medium, COMGETTER(Id)(bstrUuid.asOutParam()), hrcCheck);
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr(" Port %u, Unit %u: UUID: %ls%s%s%s%s%s%s\n Location: \"%ls\"\n"),
+ i, k, bstrUuid.raw(),
+ fPassthrough ? Info::tr(", passthrough enabled") : "",
+ fTempEject ? Info::tr(", temp eject") : "",
+ fIsEjected ? Info::tr(", ejected") : "",
+ fHotPlug ? Info::tr(", hot-pluggable") : "",
+ fNonRotational ? Info::tr(", non-rotational (SSD)") : "",
+ fDiscard ? Info::tr(", discards unused blocks") : "",
+ bstrFilePath.raw());
+ else
+ {
+ /* Note! dvdpassthough, tempeject and IsEjected was all missed the port
+ and unit bits prior to VBox 7.0. */
+ /** @todo This would look better on the "%ls-%d-%d-{tag}" form! */
+ outputMachineReadableStringWithFmtName(&bstrFilePath,
+ true, "%ls-%d-%d", bstrStorageCtlName.raw(), i, k);
+ outputMachineReadableStringWithFmtName(&bstrUuid,
+ true, "%ls-ImageUUID-%d-%d", bstrStorageCtlName.raw(), i, k);
+
+ if (fPassthrough)
+ outputMachineReadableStringWithFmtName("on",
+ true, "%ls-dvdpassthrough-%d-%d", bstrStorageCtlName.raw(), i, k);
+ if (devType == DeviceType_DVD)
+ {
+ outputMachineReadableStringWithFmtName(fTempEject ? "on" : "off",
+ true, "%ls-tempeject-%d-%d", bstrStorageCtlName.raw(), i, k);
+ outputMachineReadableStringWithFmtName(fIsEjected ? "on" : "off",
+ true, "%ls-IsEjected-%d-%d", bstrStorageCtlName.raw(), i, k);
+ }
+
+ if ( bstrStorageCtlName.compare(Bstr("SATA"), Bstr::CaseInsensitive)== 0
+ || bstrStorageCtlName.compare(Bstr("USB"), Bstr::CaseInsensitive)== 0)
+ outputMachineReadableStringWithFmtName(fHotPlug ? "on" : "off",
+ true, "%ls-hot-pluggable-%d-%d", bstrStorageCtlName.raw(),
+ i, k);
+
+ outputMachineReadableStringWithFmtName(fNonRotational ? "on" : "off",
+ true, "%ls-nonrotational-%d-%d", bstrStorageCtlName.raw(), i, k);
+ outputMachineReadableStringWithFmtName(fDiscard ? "on" : "off",
+ true, "%ls-discard-%d-%d", bstrStorageCtlName.raw(), i, k);
+ }
+ }
+ else if (SUCCEEDED(hrc))
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr(" Port %u, Unit %u: Empty%s%s\n"), i, k,
+ fTempEject ? Info::tr(", temp eject") : "",
+ fIsEjected ? Info::tr(", ejected") : "");
+ else
+ {
+ outputMachineReadableStringWithFmtName("emptydrive", true, "%ls-%d-%d", bstrStorageCtlName.raw(), i, k);
+ if (devType == DeviceType_DVD)
+ outputMachineReadableStringWithFmtName(fIsEjected ? "on" : "off",
+ true, "%ls-IsEjected-%d-%d", bstrStorageCtlName.raw(), i, k);
+ }
+ }
+ else if (details == VMINFO_MACHINEREADABLE)
+ outputMachineReadableStringWithFmtName("none", true, "%ls-%d-%d", bstrStorageCtlName.raw(), i, k);
+ else if (hrc != VBOX_E_OBJECT_NOT_FOUND)
+ RTPrintf(Info::tr(" Port %u, Unit %u: GetMedium failed: %Rhrc\n"), i, k, hrc);
+
+ }
+ }
+ return S_OK;
+}
+
+
+#ifdef VBOX_WITH_IOMMU_AMD
+static const char *iommuTypeToString(IommuType_T iommuType, VMINFO_DETAILS details)
+{
+ switch (iommuType)
+ {
+ case IommuType_None:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "none";
+ return Info::tr("None");
+
+ case IommuType_Automatic:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "automatic";
+ return Info::tr("Automatic");
+
+ case IommuType_AMD:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "amd";
+ return "AMD";
+
+ case IommuType_Intel:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "intel";
+ return "Intel";
+
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "unknown";
+ return Info::tr("Unknown");
+ }
+}
+#endif
+
+static const char *paravirtProviderToString(ParavirtProvider_T provider, VMINFO_DETAILS details)
+{
+ switch (provider)
+ {
+ case ParavirtProvider_None:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "none";
+ return Info::tr("None");
+
+ case ParavirtProvider_Default:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "default";
+ return Info::tr("Default");
+
+ case ParavirtProvider_Legacy:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "legacy";
+ return Info::tr("Legacy");
+
+ case ParavirtProvider_Minimal:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "minimal";
+ return Info::tr("Minimal");
+
+ case ParavirtProvider_HyperV:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "hyperv";
+ return "HyperV";
+
+ case ParavirtProvider_KVM:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "kvm";
+ return "KVM";
+
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ return "unknown";
+ return Info::tr("Unknown");
+ }
+}
+
+
+/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
+ time. MSC 7.1/32 doesn't have quite as much trouble with it, but still
+ sufficient to qualify for this hack as well since this code isn't performance
+ critical and probably won't gain much from the extra optimizing in real life. */
+#if defined(_MSC_VER)
+# pragma optimize("g", off)
+# pragma warning(push)
+# if _MSC_VER < RT_MSC_VER_VC120
+# pragma warning(disable: 4748)
+# endif
+#endif
+
+HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
+ ComPtr<IMachine> machine,
+ ComPtr<ISession> pSession,
+ VMINFO_DETAILS details /*= VMINFO_NONE*/)
+{
+ HRESULT hrc;
+ ComPtr<IConsole> pConsole;
+ if (pSession)
+ pSession->COMGETTER(Console)(pConsole.asOutParam());
+
+ char szNm[80];
+ char szValue[256];
+
+ /*
+ * The rules for output in -argdump format:
+ * 1) the key part (the [0-9a-zA-Z_\-]+ string before the '=' delimiter)
+ * is all lowercase for "VBoxManage modifyvm" parameters. Any
+ * other values printed are in CamelCase.
+ * 2) strings (anything non-decimal) are printed surrounded by
+ * double quotes '"'. If the strings themselves contain double
+ * quotes, these characters are escaped by '\'. Any '\' character
+ * in the original string is also escaped by '\'.
+ * 3) numbers (containing just [0-9\-]) are written out unchanged.
+ */
+
+ BOOL fAccessible;
+ CHECK_ERROR2I_RET(machine, COMGETTER(Accessible)(&fAccessible), hrcCheck);
+ if (!fAccessible)
+ {
+ Bstr uuid;
+ machine->COMGETTER(Id)(uuid.asOutParam());
+ if (details == VMINFO_COMPACT)
+ RTPrintf(Info::tr("\"<inaccessible>\" {%s}\n"), Utf8Str(uuid).c_str());
+ else
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("name=\"<inaccessible>\"\n");
+ else
+ RTPrintf(Info::tr("Name: <inaccessible!>\n"));
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
+ else
+ RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
+ if (details != VMINFO_MACHINEREADABLE)
+ {
+ Bstr settingsFilePath;
+ hrc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
+ RTPrintf(Info::tr("Config file: %ls\n"), settingsFilePath.raw());
+
+ Bstr strCipher;
+ Bstr strPasswordId;
+ HRESULT hrc2 = machine->GetEncryptionSettings(strCipher.asOutParam(), strPasswordId.asOutParam());
+ if (SUCCEEDED(hrc2))
+ {
+ RTPrintf("Encryption: enabled\n");
+ RTPrintf("Cipher: %ls\n", strCipher.raw());
+ RTPrintf("Password ID: %ls\n", strPasswordId.raw());
+ }
+ else
+ RTPrintf("Encryption: disabled\n");
+
+ ComPtr<IVirtualBoxErrorInfo> accessError;
+ hrc = machine->COMGETTER(AccessError)(accessError.asOutParam());
+ RTPrintf(Info::tr("Access error details:\n"));
+ ErrorInfo ei(accessError);
+ GluePrintErrorInfo(ei);
+ RTPrintf("\n");
+ }
+ }
+ return S_OK;
+ }
+
+ if (details == VMINFO_COMPACT)
+ {
+ Bstr machineName;
+ machine->COMGETTER(Name)(machineName.asOutParam());
+ Bstr uuid;
+ machine->COMGETTER(Id)(uuid.asOutParam());
+
+ RTPrintf("\"%ls\" {%s}\n", machineName.raw(), Utf8Str(uuid).c_str());
+ return S_OK;
+ }
+
+ SHOW_STRING_PROP( machine, Name, "name", Info::tr("Name:"));
+ {
+ Bstr strCipher;
+ Bstr strPasswordId;
+ HRESULT hrc2 = machine->GetEncryptionSettings(strCipher.asOutParam(), strPasswordId.asOutParam());
+ if (SUCCEEDED(hrc2))
+ {
+ RTPrintf("Encryption: enabled\n");
+ RTPrintf("Cipher: %ls\n", strCipher.raw());
+ RTPrintf("Password ID: %ls\n", strPasswordId.raw());
+ }
+ else
+ RTPrintf("Encryption: disabled\n");
+ }
+ SHOW_STRINGARRAY_PROP( machine, Groups, "groups", Info::tr("Groups:"));
+ Bstr osTypeId;
+ CHECK_ERROR2I_RET(machine, COMGETTER(OSTypeId)(osTypeId.asOutParam()), hrcCheck);
+ ComPtr<IGuestOSType> osType;
+ pVirtualBox->GetGuestOSType(osTypeId.raw(), osType.asOutParam());
+ if (!osType.isNull())
+ SHOW_STRING_PROP( osType, Description, "ostype", Info::tr("Guest OS:"));
+ else
+ SHOW_STRING_PROP( machine, OSTypeId, "ostype", Info::tr("Guest OS:"));
+ SHOW_UUID_PROP( machine, Id, "UUID", "UUID:");
+ SHOW_STRING_PROP( machine, SettingsFilePath, "CfgFile", Info::tr("Config file:"));
+ SHOW_STRING_PROP( machine, SnapshotFolder, "SnapFldr", Info::tr("Snapshot folder:"));
+ SHOW_STRING_PROP( machine, LogFolder, "LogFldr", Info::tr("Log folder:"));
+ SHOW_UUID_PROP( machine, HardwareUUID, "hardwareuuid", Info::tr("Hardware UUID:"));
+ SHOW_ULONG_PROP( machine, MemorySize, "memory", Info::tr("Memory size:"), "MB");
+ SHOW_BOOLEAN_PROP( machine, PageFusionEnabled, "pagefusion", Info::tr("Page Fusion:"));
+ ComPtr<IGraphicsAdapter> pGraphicsAdapter;
+ machine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam());
+ SHOW_ULONG_PROP(pGraphicsAdapter, VRAMSize, "vram", Info::tr("VRAM size:"), "MB");
+ SHOW_ULONG_PROP( machine, CPUExecutionCap, "cpuexecutioncap", Info::tr("CPU exec cap:"), "%");
+ SHOW_BOOLEAN_PROP( machine, HPETEnabled, "hpet", Info::tr("HPET:"));
+ SHOW_STRING_PROP_MAJ( machine, CPUProfile, "cpu-profile", Info::tr("CPUProfile:"), "host", 6);
+
+ ChipsetType_T chipsetType;
+ CHECK_ERROR2I_RET(machine, COMGETTER(ChipsetType)(&chipsetType), hrcCheck);
+ const char *pszChipsetType;
+ switch (chipsetType)
+ {
+ case ChipsetType_Null:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszChipsetType = "invalid";
+ else
+ pszChipsetType = Info::tr("invalid");
+ break;
+ case ChipsetType_PIIX3: pszChipsetType = "piix3"; break;
+ case ChipsetType_ICH9: pszChipsetType = "ich9"; break;
+ default:
+ AssertFailed();
+ if (details == VMINFO_MACHINEREADABLE)
+ pszChipsetType = "unknown";
+ else
+ pszChipsetType = Info::tr("unknown");
+ break;
+ }
+ SHOW_UTF8_STRING("chipset", Info::tr("Chipset:"), pszChipsetType);
+
+ FirmwareType_T firmwareType;
+ CHECK_ERROR2I_RET(machine, COMGETTER(FirmwareType)(&firmwareType), hrcCheck);
+ const char *pszFirmwareType;
+ switch (firmwareType)
+ {
+ case FirmwareType_BIOS: pszFirmwareType = "BIOS"; break;
+ case FirmwareType_EFI: pszFirmwareType = "EFI"; break;
+ case FirmwareType_EFI32: pszFirmwareType = "EFI32"; break;
+ case FirmwareType_EFI64: pszFirmwareType = "EFI64"; break;
+ case FirmwareType_EFIDUAL: pszFirmwareType = "EFIDUAL"; break;
+ default:
+ AssertFailed();
+ if (details == VMINFO_MACHINEREADABLE)
+ pszFirmwareType = "unknown";
+ else
+ pszFirmwareType = Info::tr("unknown");
+ break;
+ }
+ SHOW_UTF8_STRING("firmware", Info::tr("Firmware:"), pszFirmwareType);
+
+ SHOW_ULONG_PROP( machine, CPUCount, "cpus", Info::tr("Number of CPUs:"), "");
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_PAE, &f), "pae", "PAE:");
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_LongMode, &f), "longmode", Info::tr("Long Mode:"));
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_TripleFaultReset, &f), "triplefaultreset", Info::tr("Triple Fault Reset:"));
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_APIC, &f), "apic", "APIC:");
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_X2APIC, &f), "x2apic", "X2APIC:");
+ SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_HWVirt, &f), "nested-hw-virt", Info::tr("Nested VT-x/AMD-V:"));
+ SHOW_ULONG_PROP( machine, CPUIDPortabilityLevel, "cpuid-portability-level", Info::tr("CPUID Portability Level:"), "");
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s ", Info::tr("CPUID overrides:"));
+ ULONG uOrdinal = 0;
+ for (uOrdinal = 0; uOrdinal < _4K; uOrdinal++)
+ {
+ ULONG uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX;
+ hrc = machine->GetCPUIDLeafByOrdinal(uOrdinal, &uLeaf, &uSubLeaf, &uEAX, &uEBX, &uECX, &uEDX);
+ if (SUCCEEDED(hrc))
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x,%08x", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
+ else
+ {
+ if (!uOrdinal)
+ RTPrintf(Info::tr("Leaf no. EAX EBX ECX EDX\n"));
+ RTPrintf("%-28s %08x/%03x %08x %08x %08x %08x\n", "", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
+ }
+ }
+ else
+ {
+ if (hrc != E_INVALIDARG)
+ com::GlueHandleComError(machine, "GetCPUIDLeaf", hrc, __FILE__, __LINE__);
+ break;
+ }
+ }
+ if (!uOrdinal && details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr("None\n"));
+
+ ComPtr<IBIOSSettings> biosSettings;
+ CHECK_ERROR2I_RET(machine, COMGETTER(BIOSSettings)(biosSettings.asOutParam()), hrcCheck);
+
+ ComPtr<INvramStore> nvramStore;
+ CHECK_ERROR2I_RET(machine, COMGETTER(NonVolatileStore)(nvramStore.asOutParam()), hrcCheck);
+
+ BIOSBootMenuMode_T bootMenuMode;
+ CHECK_ERROR2I_RET(biosSettings, COMGETTER(BootMenuMode)(&bootMenuMode), hrcCheck);
+ const char *pszBootMenu;
+ switch (bootMenuMode)
+ {
+ case BIOSBootMenuMode_Disabled:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszBootMenu = "disabled";
+ else
+ pszBootMenu = Info::tr("disabled");
+ break;
+ case BIOSBootMenuMode_MenuOnly:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszBootMenu = "menuonly";
+ else
+ pszBootMenu = Info::tr("menu only");
+ break;
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszBootMenu = "messageandmenu";
+ else
+ pszBootMenu = Info::tr("message and menu");
+ }
+ SHOW_UTF8_STRING("bootmenu", Info::tr("Boot menu mode:"), pszBootMenu);
+
+ ComPtr<ISystemProperties> systemProperties;
+ CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck);
+ ULONG maxBootPosition = 0;
+ CHECK_ERROR2I_RET(systemProperties, COMGETTER(MaxBootPosition)(&maxBootPosition), hrcCheck);
+ for (ULONG i = 1; i <= maxBootPosition; i++)
+ {
+ DeviceType_T bootOrder;
+ CHECK_ERROR2I_RET(machine, GetBootOrder(i, &bootOrder), hrcCheck);
+ const char *pszDevice;
+ if (bootOrder == DeviceType_Floppy)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "floppy" : Info::tr("Floppy");
+ else if (bootOrder == DeviceType_DVD)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "dvd" : "DVD";
+ else if (bootOrder == DeviceType_HardDisk)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "disk" : Info::tr("HardDisk");
+ else if (bootOrder == DeviceType_Network)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "net" : Info::tr("Network");
+ else if (bootOrder == DeviceType_USB)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "usb" : "USB";
+ else if (bootOrder == DeviceType_SharedFolder)
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "sharedfolder" : Info::tr("Shared Folder");
+ else
+ pszDevice = details == VMINFO_MACHINEREADABLE ? "none" : Info::tr("Not Assigned");
+ SHOW_UTF8_STRING(FmtNm(szNm, "boot%u", i), FmtNm(szNm, Info::tr("Boot Device %u:"), i), pszDevice);
+ }
+
+ SHOW_BOOLEAN_PROP(biosSettings, ACPIEnabled, "acpi", "ACPI:");
+ SHOW_BOOLEAN_PROP(biosSettings, IOAPICEnabled, "ioapic", "IOAPIC:");
+
+ APICMode_T apicMode;
+ CHECK_ERROR2I_RET(biosSettings, COMGETTER(APICMode)(&apicMode), hrcCheck);
+ const char *pszAPIC;
+ switch (apicMode)
+ {
+ case APICMode_Disabled:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszAPIC = "disabled";
+ else
+ pszAPIC = Info::tr("disabled");
+ break;
+ case APICMode_APIC:
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszAPIC = "apic";
+ else
+ pszAPIC = "APIC";
+ break;
+ case APICMode_X2APIC:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszAPIC = "x2apic";
+ else
+ pszAPIC = "x2APIC";
+ break;
+ }
+ SHOW_UTF8_STRING("biosapic", Info::tr("BIOS APIC mode:"), pszAPIC);
+
+ SHOW_LONG64_PROP(biosSettings, TimeOffset, "biossystemtimeoffset", Info::tr("Time offset:"), Info::tr("ms"));
+ Bstr bstrNVRAMFile;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(NonVolatileStorageFile)(bstrNVRAMFile.asOutParam()), hrcCheck);
+ if (bstrNVRAMFile.isNotEmpty())
+ SHOW_BSTR_STRING("BIOS NVRAM File", Info::tr("BIOS NVRAM File:"), bstrNVRAMFile);
+ SHOW_BOOLEAN_PROP_EX(machine, RTCUseUTC, "rtcuseutc", Info::tr("RTC:"), "UTC", Info::tr("local time"));
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &f), "hwvirtex", Info::tr("Hardware Virtualization:"));
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", Info::tr("Nested Paging:"));
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", Info::tr("Large Pages:"));
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID:");
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", Info::tr("VT-x Unrestricted Exec.:"));
+ SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, &f), "virtvmsavevmload", Info::tr("AMD-V Virt. Vmsave/Vmload:"));
+
+#ifdef VBOX_WITH_IOMMU_AMD
+ IommuType_T iommuType;
+ CHECK_ERROR2I_RET(machine, COMGETTER(IommuType)(&iommuType), hrcCheck);
+ const char *pszIommuType = iommuTypeToString(iommuType, details);
+ SHOW_UTF8_STRING("iommu", "IOMMU:", pszIommuType);
+#endif
+
+ ParavirtProvider_T paravirtProvider;
+ CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtProvider)(&paravirtProvider), hrcCheck);
+ const char *pszParavirtProvider = paravirtProviderToString(paravirtProvider, details);
+ SHOW_UTF8_STRING("paravirtprovider", Info::tr("Paravirt. Provider:"), pszParavirtProvider);
+
+ ParavirtProvider_T effParavirtProvider;
+ CHECK_ERROR2I_RET(machine, GetEffectiveParavirtProvider(&effParavirtProvider), hrcCheck);
+ const char *pszEffParavirtProvider = paravirtProviderToString(effParavirtProvider, details);
+ SHOW_UTF8_STRING("effparavirtprovider", Info::tr("Effective Paravirt. Prov.:"), pszEffParavirtProvider);
+
+ Bstr paravirtDebug;
+ CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtDebug)(paravirtDebug.asOutParam()), hrcCheck);
+ if (paravirtDebug.isNotEmpty())
+ SHOW_BSTR_STRING("paravirtdebug", Info::tr("Paravirt. Debug:"), paravirtDebug);
+
+ MachineState_T machineState;
+ CHECK_ERROR2I_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
+ const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
+
+ LONG64 stateSince;
+ machine->COMGETTER(LastStateChange)(&stateSince);
+ RTTIMESPEC timeSpec;
+ RTTimeSpecSetMilli(&timeSpec, stateSince);
+ char pszTime[30] = {0};
+ RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("VMState=\"%s\"\n", pszState);
+ RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
+
+ Bstr stateFile;
+ machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
+ if (!stateFile.isEmpty())
+ RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
+ }
+ else
+ RTPrintf(Info::tr("%-28s %s (since %s)\n"), Info::tr("State:"), pszState, pszTime);
+
+ GraphicsControllerType_T enmGraphics;
+ hrc = pGraphicsAdapter->COMGETTER(GraphicsControllerType)(&enmGraphics);
+ if (SUCCEEDED(hrc))
+ {
+ const char *pszCtrl;
+ switch (enmGraphics)
+ {
+ case GraphicsControllerType_Null:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "null";
+ else
+ pszCtrl = Info::tr("Null");
+ break;
+ case GraphicsControllerType_VBoxVGA:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "vboxvga";
+ else
+ pszCtrl = "VBoxVGA";
+ break;
+ case GraphicsControllerType_VMSVGA:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "vmsvga";
+ else
+ pszCtrl = "VMSVGA";
+ break;
+ case GraphicsControllerType_VBoxSVGA:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "vboxsvga";
+ else
+ pszCtrl = "VBoxSVGA";
+ break;
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "unknown";
+ else
+ pszCtrl = Info::tr("Unknown");
+ break;
+ }
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("graphicscontroller=\"%s\"\n", pszCtrl);
+ else
+ RTPrintf("%-28s %s\n", Info::tr("Graphics Controller:"), pszCtrl);
+ }
+
+ SHOW_ULONG_PROP(pGraphicsAdapter, MonitorCount, "monitorcount", Info::tr("Monitor count:"), "");
+ SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate3DEnabled, "accelerate3d", Info::tr("3D Acceleration:"));
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate2DVideoEnabled, "accelerate2dvideo", Info::tr("2D Video Acceleration:"));
+#endif
+ SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", Info::tr("Teleporter Enabled:"));
+ SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", Info::tr("Teleporter Port:"), "");
+ SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", Info::tr("Teleporter Address:"));
+ SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", Info::tr("Teleporter Password:"));
+ SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", Info::tr("Tracing Enabled:"));
+ SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", Info::tr("Allow Tracing to Access VM:"));
+ SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", Info::tr("Tracing Configuration:"));
+ SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", Info::tr("Autostart Enabled:"));
+ SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", Info::tr("Autostart Delay:"), "");
+ SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", Info::tr("Default Frontend:"));
+
+ VMProcPriority_T enmVMProcPriority;
+ CHECK_ERROR2I_RET(machine, COMGETTER(VMProcessPriority)(&enmVMProcPriority), hrcCheck);
+ const char *pszVMProcPriority;
+ switch (enmVMProcPriority)
+ {
+ case VMProcPriority_Flat:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszVMProcPriority = "flat";
+ else
+ pszVMProcPriority = Info::tr("flat");
+ break;
+ case VMProcPriority_Low:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszVMProcPriority = "low";
+ else
+ pszVMProcPriority = Info::tr("low");
+ break;
+ case VMProcPriority_Normal:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszVMProcPriority = "normal";
+ else
+ pszVMProcPriority = Info::tr("normal");
+ break;
+ case VMProcPriority_High:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszVMProcPriority = "high";
+ else
+ pszVMProcPriority = Info::tr("high");
+ break;
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszVMProcPriority = "default";
+ else
+ pszVMProcPriority = Info::tr("default");
+ break;
+ }
+ SHOW_UTF8_STRING("vmprocpriority", Info::tr("VM process priority:"), pszVMProcPriority);
+
+/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
+ * checking where missing. */
+ /*
+ * Storage Controllers and their attached Mediums.
+ */
+ com::SafeIfaceArray<IStorageController> storageCtls;
+ CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
+ if (storageCtls.size() > 0)
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%s\n", Info::tr("Storage Controllers:"));
+
+ for (size_t i = 0; i < storageCtls.size(); ++i)
+ {
+ ComPtr<IStorageController> storageCtl = storageCtls[i];
+
+ Bstr bstrName;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(Name)(bstrName.asOutParam()), hrcCheck);
+ StorageControllerType_T enmCtlType = StorageControllerType_Null;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(ControllerType)(&enmCtlType), hrcCheck);
+ ULONG uInstance = 0;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(Instance)(&uInstance), hrcCheck);
+ ULONG cMaxPorts = 0;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(MaxPortCount)(&cMaxPorts), hrcCheck);
+ ULONG cPorts = 0;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(PortCount)(&cPorts), hrcCheck);
+ BOOL fBootable = FALSE;
+ CHECK_ERROR2I_RET(storageCtl, COMGETTER(Bootable)(&fBootable), hrcCheck);
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ outputMachineReadableString(FmtNm(szNm, "storagecontrollername%u", i), &bstrName);
+ outputMachineReadableString(FmtNm(szNm, "storagecontrollertype%u", i),
+ storageControllerTypeToName(enmCtlType, true));
+ RTPrintf("storagecontrollerinstance%u=\"%u\"\n", i, uInstance);
+ RTPrintf("storagecontrollermaxportcount%u=\"%u\"\n", i, cMaxPorts);
+ RTPrintf("storagecontrollerportcount%u=\"%u\"\n", i, cPorts);
+ RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
+ }
+ else
+ {
+ RTPrintf(Info::tr("#%u: '%ls', Type: %s, Instance: %u, Ports: %u (max %u), %s\n"), i, bstrName.raw(),
+ storageControllerTypeToName(enmCtlType, false), uInstance, cPorts, cMaxPorts,
+ fBootable ? Info::tr("Bootable") : Info::tr("Not bootable"));
+ hrc = showMediumAttachments(machine, storageCtl, details);
+ if (FAILED(hrc))
+ return hrc;
+ }
+ }
+ }
+ else if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s %s\n", Info::tr("Storage Controllers:"), Info::tr("<none>"));
+
+ if (details == VMINFO_MACHINEREADABLE)
+ for (size_t j = 0; j < storageCtls.size(); ++ j)
+ {
+ hrc = showMediumAttachments(machine, storageCtls[j], details);
+ if (FAILED(hrc))
+ return hrc;
+ }
+
+ /* get the maximum amount of NICS */
+ ULONG maxNICs = getMaxNics(pVirtualBox, machine);
+
+ for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
+ {
+ ComPtr<INetworkAdapter> nic;
+ hrc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
+ if (SUCCEEDED(hrc) && nic)
+ {
+ FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "nic%u" : Info::tr("NIC %u:"), currentNIC + 1);
+
+ BOOL fEnabled;
+ nic->COMGETTER(Enabled)(&fEnabled);
+ if (!fEnabled)
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("%s=\"none\"\n", szNm);
+ else
+ RTPrintf(Info::tr("%-28s disabled\n"), szNm);
+ }
+ else
+ {
+ Bstr strMACAddress;
+ nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
+ Utf8Str strAttachment;
+ Utf8Str strNatSettings;
+ Utf8Str strNatForwardings;
+ NetworkAttachmentType_T attachment;
+ nic->COMGETTER(AttachmentType)(&attachment);
+ switch (attachment)
+ {
+ case NetworkAttachmentType_Null:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAttachment = "null";
+ else
+ strAttachment = Info::tr("none");
+ break;
+
+ case NetworkAttachmentType_NAT:
+ {
+ Bstr strNetwork;
+ ComPtr<INATEngine> engine;
+ nic->COMGETTER(NATEngine)(engine.asOutParam());
+ engine->COMGETTER(Network)(strNetwork.asOutParam());
+ com::SafeArray<BSTR> forwardings;
+ engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
+ strNatForwardings = "";
+ for (size_t i = 0; i < forwardings.size(); ++i)
+ {
+ bool fSkip = false;
+ BSTR r = forwardings[i];
+ Utf8Str utf = Utf8Str(r);
+ Utf8Str strName;
+ Utf8Str strProto;
+ Utf8Str strHostPort;
+ Utf8Str strHostIP;
+ Utf8Str strGuestPort;
+ Utf8Str strGuestIP;
+ size_t pos, ppos;
+ pos = ppos = 0;
+#define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
+ do { \
+ pos = str.find(",", ppos); \
+ if (pos == Utf8Str::npos) \
+ { \
+ Log(( #res " extracting from %s is failed\n", str.c_str())); \
+ fSkip = true; \
+ } \
+ res = str.substr(ppos, pos - ppos); \
+ Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
+ ppos = pos + 1; \
+ } while (0)
+ ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
+ if (fSkip) continue;
+ ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
+ if (fSkip) continue;
+ ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
+ if (fSkip) continue;
+ ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
+ if (fSkip) continue;
+ ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
+ if (fSkip) continue;
+ strGuestPort = utf.substr(ppos, utf.length() - ppos);
+#undef ITERATE_TO_NEXT_TERM
+ switch (strProto.toUInt32())
+ {
+ case NATProtocol_TCP:
+ strProto = "tcp";
+ break;
+ case NATProtocol_UDP:
+ strProto = "udp";
+ break;
+ default:
+ strProto = "unk";
+ break;
+ }
+ if (details == VMINFO_MACHINEREADABLE)
+ /** @todo r=bird: This probably isn't good enough wrt escaping. */
+ strNatForwardings.appendPrintf("Forwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
+ i, strName.c_str(), strProto.c_str(),
+ strHostIP.c_str(), strHostPort.c_str(),
+ strGuestIP.c_str(), strGuestPort.c_str());
+ else
+ strNatForwardings.appendPrintf(Info::tr("NIC %d Rule(%d): name = %s, protocol = %s, host ip = %s, host port = %s, guest ip = %s, guest port = %s\n"),
+ currentNIC + 1, i, strName.c_str(),
+ strProto.c_str(), strHostIP.c_str(), strHostPort.c_str(),
+ strGuestIP.c_str(), strGuestPort.c_str());
+ }
+ ULONG mtu = 0;
+ ULONG sockSnd = 0;
+ ULONG sockRcv = 0;
+ ULONG tcpSnd = 0;
+ ULONG tcpRcv = 0;
+ engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
+
+/** @todo r=klaus dnsproxy etc needs to be dumped, too */
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
+ strAttachment = "nat";
+ strNatSettings.printf("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
+ mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
+ }
+ else
+ {
+ strAttachment = "NAT";
+ strNatSettings.printf(Info::tr("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n"),
+ currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
+ }
+ break;
+ }
+
+ case NetworkAttachmentType_Bridged:
+ {
+ Bstr strBridgeAdp;
+ nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
+ strAttachment = "bridged";
+ }
+ else
+ strAttachment.printf(Info::tr("Bridged Interface '%ls'"), strBridgeAdp.raw());
+ break;
+ }
+
+ case NetworkAttachmentType_Internal:
+ {
+ Bstr strNetwork;
+ nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
+ strAttachment = "intnet";
+ }
+ else
+ strAttachment.printf(Info::tr("Internal Network '%s'"), Utf8Str(strNetwork).c_str());
+ break;
+ }
+
+ case NetworkAttachmentType_HostOnly:
+ {
+ Bstr strHostonlyAdp;
+ nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
+ strAttachment = "hostonly";
+ }
+ else
+ strAttachment.printf(Info::tr("Host-only Interface '%ls'"), strHostonlyAdp.raw());
+ break;
+ }
+
+ case NetworkAttachmentType_Generic:
+ {
+ Bstr strGenericDriver;
+ nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
+ strAttachment = "Generic";
+ }
+ else
+ {
+ strAttachment.printf(Info::tr("Generic '%ls'"), strGenericDriver.raw());
+
+ // show the generic properties
+ com::SafeArray<BSTR> aProperties;
+ com::SafeArray<BSTR> aValues;
+ hrc = nic->GetProperties(NULL,
+ ComSafeArrayAsOutParam(aProperties),
+ ComSafeArrayAsOutParam(aValues));
+ if (SUCCEEDED(hrc))
+ {
+ strAttachment += " { ";
+ for (unsigned i = 0; i < aProperties.size(); ++i)
+ strAttachment.appendPrintf(!i ? "%ls='%ls'" : ", %ls='%ls'", aProperties[i], aValues[i]);
+ strAttachment += " }";
+ }
+ }
+ break;
+ }
+
+ case NetworkAttachmentType_NATNetwork:
+ {
+ Bstr strNetwork;
+ nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("nat-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
+ strAttachment = "natnetwork";
+ }
+ else
+ strAttachment.printf(Info::tr("NAT Network '%s'"), Utf8Str(strNetwork).c_str());
+ break;
+ }
+
+#ifdef VBOX_WITH_VMNET
+ case NetworkAttachmentType_HostOnlyNetwork:
+ {
+ Bstr strNetwork;
+ nic->COMGETTER(HostOnlyNetwork)(strNetwork.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("hostonly-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
+ strAttachment = "hostonlynetwork";
+ }
+ else
+ strAttachment.printf(Info::tr("Host Only Network '%s'"), Utf8Str(strNetwork).c_str());
+ break;
+ }
+#endif /* VBOX_WITH_VMNET */
+
+#ifdef VBOX_WITH_CLOUD_NET
+ case NetworkAttachmentType_Cloud:
+ {
+ Bstr strNetwork;
+ nic->COMGETTER(CloudNetwork)(strNetwork.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("cloud-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
+ strAttachment = "cloudnetwork";
+ }
+ else
+ strAttachment.printf(Info::tr("Cloud Network '%s'"), Utf8Str(strNetwork).c_str());
+ break;
+ }
+#endif /* VBOX_WITH_CLOUD_NET */
+
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAttachment = "unknown";
+ else
+ strAttachment = Info::tr("unknown");
+ break;
+ }
+
+ /* cable connected */
+ BOOL fConnected;
+ nic->COMGETTER(CableConnected)(&fConnected);
+
+ /* promisc policy */
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ CHECK_ERROR2I_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
+ const char *pszPromiscuousGuestPolicy;
+ switch (enmPromiscModePolicy)
+ {
+ case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = Info::tr("deny"); break;
+ case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = Info::tr("allow-vms"); break;
+ case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = Info::tr("allow-all"); break;
+ default: AssertFailedReturn(E_INVALIDARG);
+ }
+
+ /* trace stuff */
+ BOOL fTraceEnabled;
+ nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
+ Bstr traceFile;
+ nic->COMGETTER(TraceFile)(traceFile.asOutParam());
+
+ /* NIC type */
+ NetworkAdapterType_T NICType;
+ nic->COMGETTER(AdapterType)(&NICType);
+ const char *pszNICType;
+ switch (NICType)
+ {
+ case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
+ case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
+ case NetworkAdapterType_Am79C960: pszNICType = "Am79C960"; break;
+#ifdef VBOX_WITH_E1000
+ case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
+ case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
+ case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
+#endif
+#ifdef VBOX_WITH_VIRTIO
+ case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
+#endif
+ case NetworkAdapterType_NE1000: pszNICType = "NE1000"; break;
+ case NetworkAdapterType_NE2000: pszNICType = "NE2000"; break;
+ case NetworkAdapterType_WD8003: pszNICType = "WD8003"; break;
+ case NetworkAdapterType_WD8013: pszNICType = "WD8013"; break;
+ case NetworkAdapterType_ELNK2: pszNICType = "3C503"; break;
+ case NetworkAdapterType_ELNK1: pszNICType = "3C501"; break;
+ default:
+ AssertFailed();
+ if (details == VMINFO_MACHINEREADABLE)
+ pszNICType = "unknown";
+ else
+ pszNICType = Info::tr("unknown");
+ break;
+ }
+
+ /* reported line speed */
+ ULONG ulLineSpeed;
+ nic->COMGETTER(LineSpeed)(&ulLineSpeed);
+
+ /* boot priority of the adapter */
+ ULONG ulBootPriority;
+ nic->COMGETTER(BootPriority)(&ulBootPriority);
+
+ /* bandwidth group */
+ ComObjPtr<IBandwidthGroup> pBwGroup;
+ Bstr strBwGroup;
+ nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
+ if (!pBwGroup.isNull())
+ pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
+
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
+ RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
+ RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
+ RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
+ RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
+ }
+ else
+ RTPrintf(Info::tr("%-28s MAC: %ls, Attachment: %s, Cable connected: %s, Trace: %s (file: %ls), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s, Bandwidth group: %ls\n"),
+ szNm, strMACAddress.raw(), strAttachment.c_str(),
+ fConnected ? Info::tr("on") : Info::tr("off"),
+ fTraceEnabled ? Info::tr("on") : Info::tr("off"),
+ traceFile.isEmpty() ? Bstr(Info::tr("none")).raw() : traceFile.raw(),
+ pszNICType,
+ ulLineSpeed / 1000,
+ (int)ulBootPriority,
+ pszPromiscuousGuestPolicy,
+ strBwGroup.isEmpty() ? Bstr(Info::tr("none")).raw() : strBwGroup.raw());
+ if (strNatSettings.length())
+ RTPrintf(strNatSettings.c_str());
+ if (strNatForwardings.length())
+ RTPrintf(strNatForwardings.c_str());
+ }
+ }
+ }
+
+ /* Pointing device information */
+ PointingHIDType_T aPointingHID;
+ const char *pszHID = Info::tr("Unknown");
+ const char *pszMrHID = "unknown";
+ machine->COMGETTER(PointingHIDType)(&aPointingHID);
+ switch (aPointingHID)
+ {
+ case PointingHIDType_None:
+ pszHID = Info::tr("None");
+ pszMrHID = "none";
+ break;
+ case PointingHIDType_PS2Mouse:
+ pszHID = Info::tr("PS/2 Mouse");
+ pszMrHID = "ps2mouse";
+ break;
+ case PointingHIDType_USBMouse:
+ pszHID = Info::tr("USB Mouse");
+ pszMrHID = "usbmouse";
+ break;
+ case PointingHIDType_USBTablet:
+ pszHID = Info::tr("USB Tablet");
+ pszMrHID = "usbtablet";
+ break;
+ case PointingHIDType_ComboMouse:
+ pszHID = Info::tr("USB Tablet and PS/2 Mouse");
+ pszMrHID = "combomouse";
+ break;
+ case PointingHIDType_USBMultiTouch:
+ pszHID = Info::tr("USB Multi-Touch");
+ pszMrHID = "usbmultitouch";
+ break;
+ default:
+ break;
+ }
+ SHOW_UTF8_STRING("hidpointing", Info::tr("Pointing Device:"), details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
+
+ /* Keyboard device information */
+ KeyboardHIDType_T aKeyboardHID;
+ machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
+ pszHID = Info::tr("Unknown");
+ pszMrHID = "unknown";
+ switch (aKeyboardHID)
+ {
+ case KeyboardHIDType_None:
+ pszHID = Info::tr("None");
+ pszMrHID = "none";
+ break;
+ case KeyboardHIDType_PS2Keyboard:
+ pszHID = Info::tr("PS/2 Keyboard");
+ pszMrHID = "ps2kbd";
+ break;
+ case KeyboardHIDType_USBKeyboard:
+ pszHID = Info::tr("USB Keyboard");
+ pszMrHID = "usbkbd";
+ break;
+ case KeyboardHIDType_ComboKeyboard:
+ pszHID = Info::tr("USB and PS/2 Keyboard");
+ pszMrHID = "combokbd";
+ break;
+ default:
+ break;
+ }
+ SHOW_UTF8_STRING("hidkeyboard", Info::tr("Keyboard Device:"), details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
+
+ ComPtr<ISystemProperties> sysProps;
+ pVirtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
+
+ /* get the maximum amount of UARTs */
+ ULONG maxUARTs = 0;
+ sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
+ for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
+ {
+ ComPtr<ISerialPort> uart;
+ hrc = machine->GetSerialPort(currentUART, uart.asOutParam());
+ if (SUCCEEDED(hrc) && uart)
+ {
+ FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "uart%u" : Info::tr("UART %u:"), currentUART + 1);
+
+ /* show the config of this UART */
+ BOOL fEnabled;
+ uart->COMGETTER(Enabled)(&fEnabled);
+ if (!fEnabled)
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("%s=\"off\"\n", szNm);
+ else
+ RTPrintf(Info::tr("%-28s disabled\n"), szNm);
+ }
+ else
+ {
+ ULONG ulIRQ, ulIOBase;
+ PortMode_T HostMode;
+ Bstr path;
+ BOOL fServer;
+ UartType_T UartType;
+ uart->COMGETTER(IRQ)(&ulIRQ);
+ uart->COMGETTER(IOBase)(&ulIOBase);
+ uart->COMGETTER(Path)(path.asOutParam());
+ uart->COMGETTER(Server)(&fServer);
+ uart->COMGETTER(HostMode)(&HostMode);
+ uart->COMGETTER(UartType)(&UartType);
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
+ else
+ RTPrintf(Info::tr("%-28s I/O base: %#06x, IRQ: %d"), szNm, ulIOBase, ulIRQ);
+ switch (HostMode)
+ {
+ default:
+ case PortMode_Disconnected:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
+ else
+ RTPrintf(Info::tr(", disconnected"));
+ break;
+ case PortMode_RawFile:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uartmode%d=\"file,%ls\"\n", currentUART + 1,
+ path.raw());
+ else
+ RTPrintf(Info::tr(", attached to raw file '%ls'\n"),
+ path.raw());
+ break;
+ case PortMode_TCP:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
+ fServer ? "tcpserver" : "tcpclient", path.raw());
+ else
+ RTPrintf(Info::tr(", attached to tcp (%s) '%ls'"),
+ fServer ? Info::tr("server") : Info::tr("client"), path.raw());
+ break;
+ case PortMode_HostPipe:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
+ fServer ? "server" : "client", path.raw());
+ else
+ RTPrintf(Info::tr(", attached to pipe (%s) '%ls'"),
+ fServer ? Info::tr("server") : Info::tr("client"), path.raw());
+ break;
+ case PortMode_HostDevice:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
+ path.raw());
+ else
+ RTPrintf(Info::tr(", attached to device '%ls'"), path.raw());
+ break;
+ }
+ switch (UartType)
+ {
+ default:
+ case UartType_U16450:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uarttype%d=\"16450\"\n", currentUART + 1);
+ else
+ RTPrintf(", 16450\n");
+ break;
+ case UartType_U16550A:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uarttype%d=\"16550A\"\n", currentUART + 1);
+ else
+ RTPrintf(", 16550A\n");
+ break;
+ case UartType_U16750:
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("uarttype%d=\"16750\"\n", currentUART + 1);
+ else
+ RTPrintf(", 16750\n");
+ break;
+ }
+ }
+ }
+ }
+
+ /* get the maximum amount of LPTs */
+ ULONG maxLPTs = 0;
+ sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
+ for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
+ {
+ ComPtr<IParallelPort> lpt;
+ hrc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
+ if (SUCCEEDED(hrc) && lpt)
+ {
+ FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "lpt%u" : Info::tr("LPT %u:"), currentLPT + 1);
+
+ /* show the config of this LPT */
+ BOOL fEnabled;
+ lpt->COMGETTER(Enabled)(&fEnabled);
+ if (!fEnabled)
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("%s=\"off\"\n", szNm);
+ else
+ RTPrintf(Info::tr("%-28s disabled\n"), szNm);
+ }
+ else
+ {
+ ULONG ulIRQ, ulIOBase;
+ Bstr path;
+ lpt->COMGETTER(IRQ)(&ulIRQ);
+ lpt->COMGETTER(IOBase)(&ulIOBase);
+ lpt->COMGETTER(Path)(path.asOutParam());
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
+ else
+ RTPrintf(Info::tr("%-28s I/O base: %#06x, IRQ: %d"), szNm, ulIOBase, ulIRQ);
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1, path.raw());
+ else
+ RTPrintf(Info::tr(", attached to device '%ls'\n"), path.raw());
+ }
+ }
+ }
+
+ ComPtr<IAudioSettings> audioSettings;
+ ComPtr<IAudioAdapter> audioAdapter;
+ hrc = machine->COMGETTER(AudioSettings)(audioSettings.asOutParam());
+ if (SUCCEEDED(hrc))
+ hrc = audioSettings->COMGETTER(Adapter)(audioAdapter.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ const char *pszDrv = Info::tr("Unknown");
+ const char *pszCtrl = Info::tr("Unknown");
+ const char *pszCodec = Info::tr("Unknown");
+ BOOL fEnabled;
+ hrc = audioAdapter->COMGETTER(Enabled)(&fEnabled);
+ if (SUCCEEDED(hrc) && fEnabled)
+ {
+ AudioDriverType_T enmDrvType;
+ hrc = audioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
+ switch (enmDrvType)
+ {
+ case AudioDriverType_Default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "default";
+ else
+ pszDrv = Info::tr("Default");
+ break;
+ case AudioDriverType_Null:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "null";
+ else
+ pszDrv = Info::tr("Null");
+ break;
+ case AudioDriverType_OSS:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "oss";
+ else
+ pszDrv = "OSS";
+ break;
+ case AudioDriverType_ALSA:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "alsa";
+ else
+ pszDrv = "ALSA";
+ break;
+ case AudioDriverType_Pulse:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "pulse";
+ else
+ pszDrv = "PulseAudio";
+ break;
+ case AudioDriverType_WinMM:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "winmm";
+ else
+ pszDrv = "WINMM";
+ break;
+ case AudioDriverType_DirectSound:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "dsound";
+ else
+ pszDrv = "DirectSound";
+ break;
+ case AudioDriverType_WAS:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "was";
+ else
+ pszDrv = "Windows Audio Session (WAS)";
+ break;
+ case AudioDriverType_CoreAudio:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "coreaudio";
+ else
+ pszDrv = "CoreAudio";
+ break;
+ case AudioDriverType_SolAudio:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "solaudio";
+ else
+ pszDrv = "SolAudio";
+ break;
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszDrv = "unknown";
+ break;
+ }
+ AudioControllerType_T enmCtrlType;
+ hrc = audioAdapter->COMGETTER(AudioController)(&enmCtrlType);
+ switch (enmCtrlType)
+ {
+ case AudioControllerType_AC97:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "ac97";
+ else
+ pszCtrl = "AC97";
+ break;
+ case AudioControllerType_SB16:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "sb16";
+ else
+ pszCtrl = "SB16";
+ break;
+ case AudioControllerType_HDA:
+ if (details == VMINFO_MACHINEREADABLE)
+ pszCtrl = "hda";
+ else
+ pszCtrl = "HDA";
+ break;
+ default:
+ break;
+ }
+ AudioCodecType_T enmCodecType;
+ hrc = audioAdapter->COMGETTER(AudioCodec)(&enmCodecType);
+ switch (enmCodecType)
+ {
+ case AudioCodecType_SB16:
+ pszCodec = "SB16";
+ break;
+ case AudioCodecType_STAC9700:
+ pszCodec = "STAC9700";
+ break;
+ case AudioCodecType_AD1980:
+ pszCodec = "AD1980";
+ break;
+ case AudioCodecType_STAC9221:
+ pszCodec = "STAC9221";
+ break;
+ case AudioCodecType_Null: break; /* Shut up MSC. */
+ default: break;
+ }
+ }
+ else
+ fEnabled = FALSE;
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("audio=\"%s\"\n", fEnabled ? pszDrv : "none");
+ else
+ {
+ RTPrintf("%-28s %s", Info::tr("Audio:"), fEnabled ? Info::tr("enabled") : Info::tr("disabled"));
+ if (fEnabled)
+ RTPrintf(Info::tr(" (Driver: %s, Controller: %s, Codec: %s)"), pszDrv, pszCtrl, pszCodec);
+ RTPrintf("\n");
+ }
+ SHOW_BOOLEAN_PROP(audioAdapter, EnabledOut, "audio_out", Info::tr("Audio playback:"));
+ SHOW_BOOLEAN_PROP(audioAdapter, EnabledIn, "audio_in", Info::tr("Audio capture:"));
+
+ /** @todo Add printing run-time host audio device selection(s) here. */
+ }
+
+ /* Shared clipboard */
+ {
+ const char *psz;
+ ClipboardMode_T enmMode = (ClipboardMode_T)0;
+ hrc = machine->COMGETTER(ClipboardMode)(&enmMode);
+ switch (enmMode)
+ {
+ case ClipboardMode_Disabled:
+ psz = "disabled";
+ break;
+ case ClipboardMode_HostToGuest:
+ psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : Info::tr("HostToGuest");
+ break;
+ case ClipboardMode_GuestToHost:
+ psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : Info::tr("GuestToHost");
+ break;
+ case ClipboardMode_Bidirectional:
+ psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : Info::tr("Bidirectional");
+ break;
+ default:
+ psz = details == VMINFO_MACHINEREADABLE ? "unknown" : Info::tr("Unknown");
+ break;
+ }
+ SHOW_UTF8_STRING("clipboard", Info::tr("Clipboard Mode:"), psz);
+#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+ SHOW_BOOLEAN_PROP(machine, ClipboardFileTransfersEnabled, "clipboard_file_transfers", Info::tr("Clipboard file transfers:"));
+#endif
+ }
+
+ /* Drag and drop */
+ {
+ const char *psz;
+ DnDMode_T enmMode;
+ hrc = machine->COMGETTER(DnDMode)(&enmMode);
+ switch (enmMode)
+ {
+ case DnDMode_Disabled:
+ psz = "disabled";
+ break;
+ case DnDMode_HostToGuest:
+ psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : Info::tr("HostToGuest");
+ break;
+ case DnDMode_GuestToHost:
+ psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : Info::tr("GuestToHost");
+ break;
+ case DnDMode_Bidirectional:
+ psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : Info::tr("Bidirectional");
+ break;
+ default:
+ psz = details == VMINFO_MACHINEREADABLE ? "unknown" : Info::tr("Unknown");
+ break;
+ }
+ SHOW_UTF8_STRING("draganddrop", Info::tr("Drag and drop Mode:"), psz);
+ }
+
+ {
+ SessionState_T sessState;
+ hrc = machine->COMGETTER(SessionState)(&sessState);
+ if (SUCCEEDED(hrc) && sessState != SessionState_Unlocked)
+ {
+ Bstr sessName;
+ hrc = machine->COMGETTER(SessionName)(sessName.asOutParam());
+ if (SUCCEEDED(hrc) && !sessName.isEmpty())
+ SHOW_BSTR_STRING("SessionName", Info::tr("Session name:"), sessName);
+ }
+ }
+
+ if (pConsole)
+ {
+ do
+ {
+ ComPtr<IDisplay> display;
+ hrc = pConsole->COMGETTER(Display)(display.asOutParam());
+ if (hrc == E_ACCESSDENIED || display.isNull())
+ break; /* VM not powered up */
+ if (FAILED(hrc))
+ {
+ com::GlueHandleComError(pConsole, "COMGETTER(Display)(display.asOutParam())", hrc, __FILE__, __LINE__);
+ return hrc;
+ }
+ ULONG xRes, yRes, bpp;
+ LONG xOrigin, yOrigin;
+ GuestMonitorStatus_T monitorStatus;
+ hrc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin, &monitorStatus);
+ if (hrc == E_ACCESSDENIED)
+ break; /* VM not powered up */
+ if (FAILED(hrc))
+ {
+ com::ErrorInfo info(display, COM_IIDOF(IDisplay));
+ GluePrintErrorInfo(info);
+ return hrc;
+ }
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d %d\n", xRes, yRes, bpp, xOrigin, yOrigin, monitorStatus);
+ else
+ {
+ const char *pszMonitorStatus = Info::tr("unknown status");
+ switch (monitorStatus)
+ {
+ case GuestMonitorStatus_Blank: pszMonitorStatus = Info::tr("blank"); break;
+ case GuestMonitorStatus_Enabled: pszMonitorStatus = Info::tr("enabled"); break;
+ case GuestMonitorStatus_Disabled: pszMonitorStatus = Info::tr("disabled"); break;
+ default: break;
+ }
+ RTPrintf("%-28s %dx%dx%d at %d,%d %s\n", Info::tr("Video mode:"), xRes, yRes, bpp, xOrigin, yOrigin, pszMonitorStatus);
+ }
+ }
+ while (0);
+ }
+
+ /*
+ * Remote Desktop
+ */
+ ComPtr<IVRDEServer> vrdeServer;
+ hrc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ if (SUCCEEDED(hrc) && vrdeServer)
+ {
+ BOOL fEnabled = false;
+ vrdeServer->COMGETTER(Enabled)(&fEnabled);
+ if (fEnabled)
+ {
+ LONG currentPort = -1;
+ Bstr ports;
+ vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
+ Bstr address;
+ vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
+ BOOL fMultiCon;
+ vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
+ BOOL fReuseCon;
+ vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
+ Bstr videoChannel;
+ vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
+ BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
+ || (videoChannel == "1");
+ Bstr videoChannelQuality;
+ vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
+ AuthType_T authType = (AuthType_T)0;
+ const char *strAuthType;
+ vrdeServer->COMGETTER(AuthType)(&authType);
+ switch (authType)
+ {
+ case AuthType_Null:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAuthType = "null";
+ else
+ strAuthType = Info::tr("null");
+ break;
+ case AuthType_External:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAuthType = "external";
+ else
+ strAuthType = Info::tr("external");
+ break;
+ case AuthType_Guest:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAuthType = "guest";
+ else
+ strAuthType = Info::tr("guest");
+ break;
+ default:
+ if (details == VMINFO_MACHINEREADABLE)
+ strAuthType = "unknown";
+ else
+ strAuthType = Info::tr("unknown");
+ break;
+ }
+ if (pConsole)
+ {
+ ComPtr<IVRDEServerInfo> vrdeServerInfo;
+ CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), hrc);
+ if (!vrdeServerInfo.isNull())
+ {
+ hrc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
+ if (hrc == E_ACCESSDENIED)
+ {
+ currentPort = -1; /* VM not powered up */
+ }
+ else if (FAILED(hrc))
+ {
+ com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
+ GluePrintErrorInfo(info);
+ return hrc;
+ }
+ }
+ }
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ RTPrintf("vrde=\"on\"\n");
+ RTPrintf("vrdeport=%d\n", currentPort);
+ RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
+ RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
+ RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
+ RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
+ RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
+ RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
+ if (fVideoChannel)
+ RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
+ }
+ else
+ {
+ if (address.isEmpty())
+ address = "0.0.0.0";
+ RTPrintf(Info::tr("%-28s enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)\n"),
+ "VRDE:", address.raw(), ports.raw(), fMultiCon ? Info::tr("on") : Info::tr("off"),
+ fReuseCon ? Info::tr("on") : Info::tr("off"), strAuthType);
+ if (pConsole && currentPort != -1 && currentPort != 0)
+ RTPrintf("%-28s %d\n", Info::tr("VRDE port:"), currentPort);
+ if (fVideoChannel)
+ RTPrintf(Info::tr("%-28s enabled (Quality %ls)\n"), Info::tr("Video redirection:"), videoChannelQuality.raw());
+ else
+ RTPrintf(Info::tr("%-28s disabled\n"), Info::tr("Video redirection:"));
+ }
+ com::SafeArray<BSTR> aProperties;
+ if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
+ {
+ unsigned i;
+ for (i = 0; i < aProperties.size(); ++i)
+ {
+ Bstr value;
+ vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
+ if (details == VMINFO_MACHINEREADABLE)
+ {
+ if (value.isEmpty())
+ RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
+ else
+ RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
+ }
+ else
+ {
+ if (value.isEmpty())
+ RTPrintf(Info::tr("%-28s: %-10lS = <not set>\n"), Info::tr("VRDE property"), aProperties[i]);
+ else
+ RTPrintf("%-28s: %-10lS = \"%ls\"\n", Info::tr("VRDE property"), aProperties[i], value.raw());
+ }
+ }
+ }
+ }
+ else
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("vrde=\"off\"\n");
+ else
+ RTPrintf(Info::tr("%-28s disabled\n"), "VRDE:");
+ }
+ }
+
+ /*
+ * USB.
+ */
+ SafeIfaceArray<IUSBController> USBCtlColl;
+ hrc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
+ if (SUCCEEDED(hrc))
+ {
+ bool fOhciEnabled = false;
+ bool fEhciEnabled = false;
+ bool fXhciEnabled = false;
+
+ for (unsigned i = 0; i < USBCtlColl.size(); i++)
+ {
+ USBControllerType_T enmType;
+
+ hrc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
+ if (SUCCEEDED(hrc))
+ {
+ switch (enmType)
+ {
+ case USBControllerType_OHCI:
+ fOhciEnabled = true;
+ break;
+ case USBControllerType_EHCI:
+ fEhciEnabled = true;
+ break;
+ case USBControllerType_XHCI:
+ fXhciEnabled = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ SHOW_BOOL_VALUE("usb", "OHCI USB:", fOhciEnabled);
+ SHOW_BOOL_VALUE("ehci", "EHCI USB:", fEhciEnabled);
+ SHOW_BOOL_VALUE("xhci", "xHCI USB:", fXhciEnabled);
+ }
+
+ ComPtr<IUSBDeviceFilters> USBFlts;
+ hrc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ SafeIfaceArray <IUSBDeviceFilter> Coll;
+ hrc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
+ if (SUCCEEDED(hrc))
+ {
+ if (Coll.size() > 0)
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr("USB Device Filters:\n"));
+ for (size_t index = 0; index < Coll.size(); ++index)
+ {
+ ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
+
+ if (details != VMINFO_MACHINEREADABLE)
+ SHOW_UTF8_STRING("index", Info::tr("Index:"), FmtNm(szNm, "%zu", index));
+ SHOW_BOOLEAN_PROP_EX(DevPtr, Active, FmtNm(szNm, "USBFilterActive%zu", index + 1), Info::tr(" Active:"), Info::tr("yes"), Info::tr("no"));
+ SHOW_STRING_PROP(DevPtr, Name, FmtNm(szNm, "USBFilterName%zu", index + 1), Info::tr(" Name:"));
+ SHOW_STRING_PROP(DevPtr, VendorId, FmtNm(szNm, "USBFilterVendorId%zu", index + 1), Info::tr(" VendorId:"));
+ SHOW_STRING_PROP(DevPtr, ProductId, FmtNm(szNm, "USBFilterProductId%zu", index + 1), Info::tr(" ProductId:"));
+ SHOW_STRING_PROP(DevPtr, Revision, FmtNm(szNm, "USBFilterRevision%zu", index + 1), Info::tr(" Revision:"));
+ SHOW_STRING_PROP(DevPtr, Manufacturer, FmtNm(szNm, "USBFilterManufacturer%zu", index + 1), Info::tr(" Manufacturer:"));
+ SHOW_STRING_PROP(DevPtr, Product, FmtNm(szNm, "USBFilterProduct%zu", index + 1), Info::tr(" Product:"));
+ SHOW_STRING_PROP(DevPtr, Remote, FmtNm(szNm, "USBFilterRemote%zu", index + 1), Info::tr(" Remote:"));
+ SHOW_STRING_PROP(DevPtr, SerialNumber, FmtNm(szNm, "USBFilterSerialNumber%zu", index + 1), Info::tr(" Serial Number:"));
+ if (details != VMINFO_MACHINEREADABLE)
+ {
+ ULONG fMaskedIfs;
+ CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), hrc);
+ if (fMaskedIfs)
+ RTPrintf("%-28s %#010x\n", Info::tr("Masked Interfaces:"), fMaskedIfs);
+ }
+ }
+ }
+ else if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s %s\n", Info::tr("USB Device Filters:"), Info::tr("<none>"));
+ }
+
+ if (pConsole)
+ {
+ {
+ SafeIfaceArray<IHostUSBDevice> coll;
+ CHECK_ERROR_RET(pConsole, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), hrc);
+ hrc = showUsbDevices(coll, "USBRemote", Info::tr("Available remote USB devices:"), details);
+ if (FAILED(hrc))
+ return hrc;
+ }
+
+ {
+ SafeIfaceArray<IUSBDevice> coll;
+ CHECK_ERROR_RET(pConsole, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), hrc);
+ showUsbDevices(coll, "USBAttach", Info::tr("Currently attached USB devices:"), details);
+ if (FAILED(hrc))
+ return hrc;
+ }
+ }
+ } /* USB */
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ /* Host PCI passthrough devices */
+ {
+ SafeIfaceArray <IPCIDeviceAttachment> assignments;
+ hrc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
+ if (SUCCEEDED(hrc))
+ {
+ if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
+ {
+ RTPrintf(Info::tr("\nAttached physical PCI devices:\n\n"));
+ }
+
+ for (size_t index = 0; index < assignments.size(); ++index)
+ {
+ ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
+ char szHostPCIAddress[32], szGuestPCIAddress[32];
+ LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
+ Bstr DevName;
+
+ Assignment->COMGETTER(Name)(DevName.asOutParam());
+ Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
+ Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
+ PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
+ PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
+
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
+ else
+ RTPrintf(Info::tr(" Host device %ls at %s attached as %s\n"), DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
+ }
+
+ if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
+ {
+ RTPrintf("\n");
+ }
+ }
+ }
+ /* Host PCI passthrough devices */
+#endif
+
+ /*
+ * Bandwidth groups
+ */
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s ", Info::tr("Bandwidth groups:"));
+ {
+ ComPtr<IBandwidthControl> bwCtrl;
+ CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), hrc);
+
+ hrc = showBandwidthGroups(bwCtrl, details);
+ }
+
+
+ /*
+ * Shared folders
+ */
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s ", Info::tr("Shared folders:"));
+ uint32_t numSharedFolders = 0;
+#if 0 // not yet implemented
+ /* globally shared folders first */
+ {
+ SafeIfaceArray <ISharedFolder> sfColl;
+ CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
+ for (size_t i = 0; i < sfColl.size(); ++i)
+ {
+ ComPtr<ISharedFolder> sf = sfColl[i];
+ showSharedFolder(sf, details, Info::tr("global mapping"), "GlobalMapping", i + 1, numSharedFolders == 0);
+ ++numSharedFolders;
+ }
+ }
+#endif
+ /* now VM mappings */
+ {
+ com::SafeIfaceArray <ISharedFolder> folders;
+ CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), hrc);
+ for (size_t i = 0; i < folders.size(); ++i)
+ {
+ ComPtr<ISharedFolder> sf = folders[i];
+ showSharedFolder(sf, details, Info::tr("machine mapping"), "MachineMapping", i + 1, numSharedFolders == 0);
+ ++numSharedFolders;
+ }
+ }
+ /* transient mappings */
+ if (pConsole)
+ {
+ com::SafeIfaceArray <ISharedFolder> folders;
+ CHECK_ERROR_RET(pConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), hrc);
+ for (size_t i = 0; i < folders.size(); ++i)
+ {
+ ComPtr<ISharedFolder> sf = folders[i];
+ showSharedFolder(sf, details, Info::tr("transient mapping"), "TransientMapping", i + 1, numSharedFolders == 0);
+ ++numSharedFolders;
+ }
+ }
+ if (details != VMINFO_MACHINEREADABLE)
+ {
+ if (!numSharedFolders)
+ RTPrintf(Info::tr("<none>\n"));
+ else
+ RTPrintf("\n");
+ }
+
+ if (pConsole)
+ {
+ /*
+ * Live VRDE info.
+ */
+ ComPtr<IVRDEServerInfo> vrdeServerInfo;
+ CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), hrc);
+ BOOL fActive = FALSE;
+ ULONG cNumberOfClients = 0;
+ LONG64 BeginTime = 0;
+ LONG64 EndTime = 0;
+ LONG64 BytesSent = 0;
+ LONG64 BytesSentTotal = 0;
+ LONG64 BytesReceived = 0;
+ LONG64 BytesReceivedTotal = 0;
+ Bstr User;
+ Bstr Domain;
+ Bstr ClientName;
+ Bstr ClientIP;
+ ULONG ClientVersion = 0;
+ ULONG EncryptionStyle = 0;
+
+ if (!vrdeServerInfo.isNull())
+ {
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&fActive), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&cNumberOfClients), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), hrc);
+ CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), hrc);
+ }
+
+ SHOW_BOOL_VALUE_EX("VRDEActiveConnection", Info::tr("VRDE Connection:"), fActive, Info::tr("active"), Info::tr("not active"));
+ SHOW_ULONG_VALUE("VRDEClients=", Info::tr("Clients so far:"), cNumberOfClients, "");
+
+ if (cNumberOfClients > 0)
+ {
+ char szTimeValue[128];
+ makeTimeStr(szTimeValue, sizeof(szTimeValue), BeginTime);
+ if (fActive)
+ SHOW_UTF8_STRING("VRDEStartTime", Info::tr("Start time:"), szTimeValue);
+ else
+ {
+ SHOW_UTF8_STRING("VRDELastStartTime", Info::tr("Last started:"), szTimeValue);
+ makeTimeStr(szTimeValue, sizeof(szTimeValue), EndTime);
+ SHOW_UTF8_STRING("VRDELastEndTime", Info::tr("Last ended:"), szTimeValue);
+ }
+
+ int64_t ThroughputSend = 0;
+ int64_t ThroughputReceive = 0;
+ if (EndTime != BeginTime)
+ {
+ ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
+ ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
+ }
+ SHOW_LONG64_VALUE("VRDEBytesSent", Info::tr("Sent:"), BytesSent, Info::tr("Bytes"));
+ SHOW_LONG64_VALUE("VRDEThroughputSend", Info::tr("Average speed:"), ThroughputSend, Info::tr("B/s"));
+ SHOW_LONG64_VALUE("VRDEBytesSentTotal", Info::tr("Sent total:"), BytesSentTotal, Info::tr("Bytes"));
+
+ SHOW_LONG64_VALUE("VRDEBytesReceived", Info::tr("Received:"), BytesReceived, Info::tr("Bytes"));
+ SHOW_LONG64_VALUE("VRDEThroughputReceive", Info::tr("Speed:"), ThroughputReceive, Info::tr("B/s"));
+ SHOW_LONG64_VALUE("VRDEBytesReceivedTotal", Info::tr("Received total:"), BytesReceivedTotal, Info::tr("Bytes"));
+
+ if (fActive)
+ {
+ SHOW_BSTR_STRING("VRDEUserName", Info::tr("User name:"), User);
+ SHOW_BSTR_STRING("VRDEDomain", Info::tr("Domain:"), Domain);
+ SHOW_BSTR_STRING("VRDEClientName", Info::tr("Client name:"), ClientName);
+ SHOW_BSTR_STRING("VRDEClientIP", Info::tr("Client IP:"), ClientIP);
+ SHOW_ULONG_VALUE("VRDEClientVersion", Info::tr("Client version:"), ClientVersion, "");
+ SHOW_UTF8_STRING("VRDEEncryption", Info::tr("Encryption:"), EncryptionStyle == 0 ? "RDP4" : "RDP5 (X.509)");
+ }
+ }
+ }
+
+#ifdef VBOX_WITH_RECORDING
+ {
+ ComPtr<IRecordingSettings> recordingSettings;
+ CHECK_ERROR_RET(machine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()), hrc);
+
+ BOOL fEnabled;
+ CHECK_ERROR_RET(recordingSettings, COMGETTER(Enabled)(&fEnabled), hrc);
+ SHOW_BOOL_VALUE_EX("recording_enabled", Info::tr("Recording enabled:"), fEnabled, Info::tr("yes"), Info::tr("no"));
+
+ SafeIfaceArray <IRecordingScreenSettings> saScreenSettings;
+ CHECK_ERROR_RET(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saScreenSettings)), hrc);
+
+ SHOW_ULONG_VALUE("recording_screens", Info::tr("Recording screens:"), saScreenSettings.size(), "");
+
+ for (size_t i = 0; i < saScreenSettings.size(); ++i)
+ {
+ ComPtr<IRecordingScreenSettings> screenSettings = saScreenSettings[i];
+
+ FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "rec_screen%zu" : Info::tr("Screen %u:"), i);
+ RTPrintf(Info::tr(" %s\n"), szNm);
+
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Enabled)(&fEnabled), hrc);
+ ULONG idScreen;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Id)(&idScreen), hrc);
+ com::SafeArray<RecordingFeature_T> vecFeatures;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Features)(ComSafeArrayAsOutParam(vecFeatures)), hrc);
+ ULONG Width;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(VideoWidth)(&Width), hrc);
+ ULONG Height;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(VideoHeight)(&Height), hrc);
+ ULONG Rate;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(VideoRate)(&Rate), hrc);
+ ULONG Fps;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(VideoFPS)(&Fps), hrc);
+ RecordingDestination_T enmDst;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Destination)(&enmDst), hrc);
+ Bstr bstrFile;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Filename)(bstrFile.asOutParam()), hrc);
+ Bstr bstrOptions;
+ CHECK_ERROR_RET(screenSettings, COMGETTER(Options)(bstrOptions.asOutParam()), hrc);
+
+ BOOL fRecordVideo = FALSE;
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ BOOL fRecordAudio = FALSE;
+# endif
+ for (size_t f = 0; f < vecFeatures.size(); ++f)
+ {
+ if (vecFeatures[f] == RecordingFeature_Video)
+ fRecordVideo = TRUE;
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ else if (vecFeatures[f] == RecordingFeature_Audio)
+ fRecordAudio = TRUE;
+# endif
+ }
+
+ SHOW_BOOL_VALUE_EX("rec_screen_enabled", Info::tr(" Enabled:"), fEnabled,
+ Info::tr("yes"), Info::tr("no"));
+ SHOW_ULONG_VALUE ("rec_screen_id", Info::tr(" ID:"), idScreen, "");
+ SHOW_BOOL_VALUE_EX("rec_screen_video_enabled", Info::tr(" Record video:"), fRecordVideo,
+ Info::tr("yes"), Info::tr("no"));
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ SHOW_BOOL_VALUE_EX("rec_screen_audio_enabled", Info::tr(" Record audio:"), fRecordAudio,
+ Info::tr("yes"), Info::tr("no"));
+# endif
+ SHOW_UTF8_STRING("rec_screen_dest", Info::tr(" Destination:"),
+ enmDst == RecordingDestination_File
+ ? Info::tr("File") : Info::tr("Unknown"));
+ /** @todo Implement other destinations. */
+ if (enmDst == RecordingDestination_File)
+ SHOW_BSTR_STRING("rec_screen_dest_filename", Info::tr(" File:"), bstrFile);
+
+ SHOW_BSTR_STRING ("rec_screen_opts", Info::tr(" Options:"), bstrOptions);
+
+ /* Video properties. */
+ RTStrPrintf(szValue, sizeof(szValue), "%ux%u", Width, Height);
+ SHOW_UTF8_STRING ("rec_screen_video_res_xy", Info::tr(" Video dimensions:"), szValue);
+ SHOW_ULONG_VALUE ("rec_screen_video_rate_kbps", Info::tr(" Video rate:"), Rate, Info::tr("kbps"));
+ SHOW_ULONG_VALUE ("rec_screen_video_fps", Info::tr(" Video FPS:"), Fps, Info::tr("fps"));
+
+ /** @todo Add more audio capturing profile / information here. */
+ }
+ }
+#endif /* VBOX_WITH_RECORDING */
+
+ if ( details == VMINFO_STANDARD
+ || details == VMINFO_FULL
+ || details == VMINFO_MACHINEREADABLE)
+ {
+ Bstr description;
+ machine->COMGETTER(Description)(description.asOutParam());
+ if (!description.isEmpty())
+ {
+ if (details == VMINFO_MACHINEREADABLE)
+ outputMachineReadableString("description", &description);
+ else
+ RTPrintf(Info::tr("Description:\n%ls\n"), description.raw());
+ }
+ }
+
+ /* VMMDev testing config (extra data) */
+ if (details != VMINFO_MACHINEREADABLE)
+ {
+ Bstr bstr;
+ CHECK_ERROR2I_RET(machine, GetExtraData(Bstr("VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled").raw(),
+ bstr.asOutParam()), hrcCheck);
+ int const fEnabled = parseCfgmBool(&bstr);
+
+ CHECK_ERROR2I_RET(machine, GetExtraData(Bstr("VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO").raw(),
+ bstr.asOutParam()), hrcCheck);
+ int const fMmio = parseCfgmBool(&bstr);
+ if (fEnabled || fMmio)
+ {
+ RTPrintf("%-28s %s, %s %s\n",
+ Info::tr("VMMDev Testing"),
+ fEnabled > 0 ? Info::tr("enabled") : fEnabled == 0 ? Info::tr("disabled") : Info::tr("misconfigured"),
+ "MMIO:",
+ fMmio > 0 ? Info::tr("enabled") : fMmio == 0 ? Info::tr("disabled") : Info::tr("misconfigured"));
+ for (uint32_t i = 0; i < 10; i++)
+ {
+ BstrFmt bstrName("VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u", i);
+ CHECK_ERROR2I_RET(machine, GetExtraData(bstrName.raw(), bstr.asOutParam()), hrcCheck);
+ if (bstr.isNotEmpty())
+ RTPrintf("%-28s %ls\n", FmtNm(szNm, "VMMDev Testing Cfg Dword%u:", i), bstr.raw());
+ }
+ }
+ }
+
+ /*
+ * Snapshots.
+ */
+ ComPtr<ISnapshot> snapshot;
+ hrc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
+ if (SUCCEEDED(hrc) && snapshot)
+ {
+ ComPtr<ISnapshot> currentSnapshot;
+ hrc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr("* Snapshots:\n"));
+ showSnapshots(snapshot, currentSnapshot, details);
+ }
+ }
+
+ /*
+ * Guest stuff (mainly interesting when running).
+ */
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf(Info::tr("* Guest:\n"));
+
+ SHOW_ULONG_PROP(machine, MemoryBalloonSize, "GuestMemoryBalloon",
+ Info::tr("Configured memory balloon:"), Info::tr("MB"));
+
+ if (pConsole)
+ {
+ ComPtr<IGuest> guest;
+ hrc = pConsole->COMGETTER(Guest)(guest.asOutParam());
+ if (SUCCEEDED(hrc) && !guest.isNull())
+ {
+ SHOW_STRING_PROP_NOT_EMPTY(guest, OSTypeId, "GuestOSType", Info::tr("OS type:"));
+
+ AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
+ hrc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
+ if (SUCCEEDED(hrc))
+ SHOW_ULONG_VALUE("GuestAdditionsRunLevel", Info::tr("Additions run level:"), (ULONG)guestRunLevel, "");
+
+ Bstr guestString;
+ hrc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
+ if ( SUCCEEDED(hrc)
+ && !guestString.isEmpty())
+ {
+ ULONG uRevision;
+ hrc = guest->COMGETTER(AdditionsRevision)(&uRevision);
+ if (FAILED(hrc))
+ uRevision = 0;
+ RTStrPrintf(szValue, sizeof(szValue), "%ls r%u", guestString.raw(), uRevision);
+ SHOW_UTF8_STRING("GuestAdditionsVersion", Info::tr("Additions version:"), szValue);
+ }
+
+ /* Print information about known Guest Additions facilities: */
+ SafeIfaceArray <IAdditionsFacility> collFac;
+ CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), hrc);
+ if (collFac.size() > 0)
+ {
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%s\n", Info::tr("Guest Facilities:"));
+ LONG64 lLastUpdatedMS;
+ char szLastUpdated[32];
+ AdditionsFacilityStatus_T curStatus;
+ for (size_t index = 0; index < collFac.size(); ++index)
+ {
+ ComPtr<IAdditionsFacility> fac = collFac[index];
+ if (fac)
+ {
+ CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), hrc);
+ if (!guestString.isEmpty())
+ {
+ CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), hrc);
+ CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), hrc);
+ if (details == VMINFO_MACHINEREADABLE)
+ RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
+ guestString.raw(), curStatus, lLastUpdatedMS);
+ else
+ {
+ makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
+ RTPrintf(Info::tr("Facility \"%ls\": %s (last update: %s)\n"),
+ guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
+ }
+ }
+ else
+ AssertMsgFailed(("Facility with undefined name retrieved!\n"));
+ }
+ else
+ AssertMsgFailed(("Invalid facility returned!\n"));
+ }
+ }
+ else if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("%-28s %s\n", Info::tr("Guest Facilities:"), Info::tr("<none>"));
+ }
+ }
+
+ if (details != VMINFO_MACHINEREADABLE)
+ RTPrintf("\n");
+ return S_OK;
+}
+
+#if defined(_MSC_VER)
+# pragma optimize("", on)
+# pragma warning(pop)
+#endif
+
+static const RTGETOPTDEF g_aShowVMInfoOptions[] =
+{
+ { "--details", 'D', RTGETOPT_REQ_NOTHING },
+ { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
+ { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--log", 'l', RTGETOPT_REQ_UINT32 },
+ { "--password-id", 'i', RTGETOPT_REQ_STRING },
+ { "-password-id", 'i', RTGETOPT_REQ_STRING },
+ { "--password", 'w', RTGETOPT_REQ_STRING },
+ { "-password", 'w', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleShowVMInfo(HandlerArg *a)
+{
+ HRESULT hrc;
+ const char *VMNameOrUuid = NULL;
+ bool fLog = false;
+ uint32_t uLogIdx = 0;
+ bool fDetails = false;
+ bool fMachinereadable = false;
+ Bstr bstrPasswordId;
+ const char *pszPassword = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'D': // --details
+ fDetails = true;
+ break;
+
+ case 'M': // --machinereadable
+ fMachinereadable = true;
+ break;
+
+ case 'l': // --log
+ fLog = true;
+ uLogIdx = ValueUnion.u32;
+ break;
+
+ case 'i': // --password-id
+ bstrPasswordId = ValueUnion.psz;
+ break;
+
+ case 'w': // --password
+ pszPassword = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!VMNameOrUuid)
+ VMNameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(Info::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* check for required options */
+ if (!VMNameOrUuid)
+ return errorSyntax(Info::tr("VM name or UUID required"));
+
+ /* try to find the given machine */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
+ machine.asOutParam()));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ /* Printing the log is exclusive. */
+ if (fLog && (fMachinereadable || fDetails))
+ return errorSyntax(Info::tr("Option --log is exclusive"));
+
+ /* add VM password if required */
+ if (pszPassword && bstrPasswordId.isNotEmpty())
+ {
+ Utf8Str strPassword;
+ if (!RTStrCmp(pszPassword, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read new password from file");
+ return rcExit;
+ }
+ }
+ CHECK_ERROR(machine, AddEncryptionPassword(bstrPasswordId.raw(), Bstr(strPassword).raw()));
+ }
+
+ if (fLog)
+ {
+ ULONG64 uOffset = 0;
+ SafeArray<BYTE> aLogData;
+ size_t cbLogData;
+ while (true)
+ {
+ /* Reset the array */
+ aLogData.setNull();
+ /* Fetch a chunk of the log file */
+ CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
+ ComSafeArrayAsOutParam(aLogData)));
+ cbLogData = aLogData.size();
+ if (cbLogData == 0)
+ break;
+ /* aLogData has a platform dependent line ending, standardize on
+ * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
+ * Windows. Otherwise we end up with CR/CR/LF on Windows. */
+ size_t cbLogDataPrint = cbLogData;
+ for (BYTE *s = aLogData.raw(), *d = s;
+ s - aLogData.raw() < (ssize_t)cbLogData;
+ s++, d++)
+ {
+ if (*s == '\r')
+ {
+ /* skip over CR, adjust destination */
+ d--;
+ cbLogDataPrint--;
+ }
+ else if (s != d)
+ *d = *s;
+ }
+ RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
+ uOffset += cbLogData;
+ }
+ }
+ else
+ {
+ /* 2nd option can be -details or -argdump */
+ VMINFO_DETAILS details = VMINFO_NONE;
+ if (fMachinereadable)
+ details = VMINFO_MACHINEREADABLE;
+ else if (fDetails)
+ details = VMINFO_FULL;
+ else
+ details = VMINFO_STANDARD;
+
+ /* open an existing session for the VM */
+ hrc = machine->LockMachine(a->session, LockType_Shared);
+ if (SUCCEEDED(hrc))
+ /* get the session machine */
+ hrc = a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ hrc = showVMInfo(a->virtualBox, machine, a->session, details);
+
+ a->session->UnlockMachine();
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+
+#include <VBox/com/VirtualBox.h>
+
+#include <VBox/log.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+
+#include <vector>
+#include <algorithm>
+
+#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<IVirtualBox> pVirtualBox)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> 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<IVirtualBox> pVirtualBox,
+ bool fIsBridged)
+{
+ HRESULT hrc;
+ ComPtr<IHost> host;
+ CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam()));
+ com::SafeIfaceArray<IHostNetworkInterface> 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<IHostNetworkInterface> 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<IVirtualBox> pVirtualBox)
+{
+ HRESULT hrc;
+ com::SafeIfaceArray<IHostOnlyNetwork> hostOnlyNetworks;
+ CHECK_ERROR(pVirtualBox, COMGETTER(HostOnlyNetworks)(ComSafeArrayAsOutParam(hostOnlyNetworks)));
+ for (size_t i = 0; i < hostOnlyNetworks.size(); ++i)
+ {
+ ComPtr<IHostOnlyNetwork> 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<IVirtualBox> pVirtualBox)
+{
+ com::SafeIfaceArray<ICloudNetwork> cloudNetworks;
+ CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(CloudNetworks)(ComSafeArrayAsOutParam(cloudNetworks)), hrcCheck);
+ for (size_t i = 0; i < cloudNetworks.size(); ++i)
+ {
+ ComPtr<ICloudNetwork> 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<IVirtualBox> 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<IHost> 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<IVirtualBox> pVirtualBox,
+ const com::SafeIfaceArray<IMedium> &aMedia,
+ const char *pszParentUUIDStr,
+ bool fOptLong)
+{
+ HRESULT hrc = S_OK;
+ for (size_t i = 0; i < aMedia.size(); ++i)
+ {
+ ComPtr<IMedium> pMedium = aMedia[i];
+
+ hrc = showMediumInfo(pVirtualBox, pMedium, pszParentUUIDStr, fOptLong);
+
+ RTPrintf("\n");
+
+ com::SafeIfaceArray<IMedium> 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<IVirtualBox> pVirtualBox)
+{
+ HRESULT hrc;
+ ComPtr<ISystemProperties> systemProperties;
+ CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()));
+ com::SafeIfaceArray<IMediumFormat> 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 <MediumFormatCapabilities_T> 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<BSTR> fileExtensions;
+ com::SafeArray<DeviceType_T> 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<BSTR> propertyNames;
+ com::SafeArray<BSTR> propertyDescriptions;
+ com::SafeArray<DataType_T> propertyTypes;
+ com::SafeArray<ULONG> propertyFlags;
+ com::SafeArray<BSTR> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc;
+ ComPtr<IHost> Host;
+ CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(Host.asOutParam()), 1);
+
+ SafeIfaceArray<IHostUSBDevice> 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("<none>\n\n"));
+ }
+ else
+ {
+ for (size_t i = 0; i < CollPtr.size(); ++i)
+ {
+ ComPtr<IHostUSBDevice> 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<BSTR> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc;
+
+ RTPrintf(List::tr("Global USB Device Filters:\n\n"));
+
+ ComPtr<IHost> host;
+ CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(host.asOutParam()), 1);
+
+ SafeIfaceArray<IHostUSBDeviceFilter> coll;
+ CHECK_ERROR_RET(host, COMGETTER(USBDeviceFilters)(ComSafeArrayAsOutParam(coll)), 1);
+
+ if (coll.size() == 0)
+ {
+ RTPrintf(List::tr("<none>\n\n"));
+ }
+ else
+ {
+ for (size_t index = 0; index < coll.size(); ++index)
+ {
+ ComPtr<IHostUSBDeviceFilter> 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("<invalid>");
+ 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<IVirtualBox> &pVirtualBox)
+{
+ ComPtr<ISystemProperties> 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<IUpdateAgent> 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<IVirtualBox> &pVirtualBox)
+{
+ ComPtr<IHost> pHost;
+ CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(Host)(pHost.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IUpdateAgent> 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<IDHCPConfig> 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<DHCPOption_T> 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<DHCPOptionEncoding_T> Encodings;
+ com::SafeArray<BSTR> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrcRet = S_OK;
+ com::SafeIfaceArray<IDHCPServer> 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<IDHCPServer> 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<IDHCPGlobalConfig> 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<IDHCPGroupConfig> 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<IDHCPGroupCondition> 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<IDHCPIndividualConfig> 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<IVirtualBox> &pVirtualBox)
+{
+ ComObjPtr<IExtPackManager> ptrExtPackMgr;
+ CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), hrcCheck);
+
+ SafeIfaceArray<IExtPack> 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<IVirtualBox> &pVirtualBox)
+{
+ SafeArray<BSTR> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc;
+ ComPtr<IHost> host;
+ CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam()));
+ com::SafeIfaceArray<IHostVideoInputDevice> 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<IHostVideoInputDevice> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<ISystemProperties> systemProperties;
+ CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()));
+ com::SafeArray<BitmapFormat_T> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR(pVirtualBox, COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()));
+ com::SafeIfaceArray<ICloudProvider> 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<ICloudProvider> 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<IVirtualBox> &pVirtualBox, bool fOptLong)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR(pVirtualBox, COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()));
+ com::SafeIfaceArray<ICloudProvider> apCloudProviders;
+ CHECK_ERROR(pCloudProviderManager, COMGETTER(Providers)(ComSafeArrayAsOutParam(apCloudProviders)));
+
+ for (size_t i = 0; i < apCloudProviders.size(); ++i)
+ {
+ ComPtr<ICloudProvider> pCloudProvider = apCloudProviders[i];
+ com::SafeIfaceArray<ICloudProfile> apCloudProfiles;
+ CHECK_ERROR(pCloudProvider, COMGETTER(Profiles)(ComSafeArrayAsOutParam(apCloudProfiles)));
+ for (size_t j = 0; j < apCloudProfiles.size(); ++j)
+ {
+ ComPtr<ICloudProfile> 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<BSTR> names;
+ com::SafeArray<BSTR> 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<IVirtualBox> &ptrVirtualBox, bool fOptLong, bool fOptSorted)
+{
+ ComPtr<ISystemProperties> ptrSysProps;
+ CHECK_ERROR2I_RET(ptrVirtualBox, COMGETTER(SystemProperties)(ptrSysProps.asOutParam()), hrcCheck);
+ com::SafeIfaceArray<ICPUProfile> 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<std::pair<com::Bstr, ICPUProfile *> > 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<com::Bstr, ICPUProfile *>(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<IVirtualBox> pVirtualBox, bool fOptLong)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<IHost> pHost;
+ CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(Host)(pHost.asOutParam()), hrcCheck);
+ com::SafeIfaceArray<IHostDrive> apHostDrives;
+ CHECK_ERROR2I_RET(pHost, COMGETTER(HostDrives)(ComSafeArrayAsOutParam(apHostDrives)), hrcCheck);
+ for (size_t i = 0; i < apHostDrives.size(); ++i)
+ {
+ ComPtr<IHostDrive> 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<IHostDrivePartition> 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<IHostDrivePartition> 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<IHostDrivePartition> 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<IHostDrivePartition> 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<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc = S_OK;
+ switch (enmCommand)
+ {
+ case kListNotSpecified:
+ AssertFailed();
+ return E_FAIL;
+
+ case kListVMs:
+ {
+ /*
+ * Get the list of all registered VMs
+ */
+ com::SafeIfaceArray<IMachine> 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<std::pair<com::Bstr, IMachine *> > 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<com::Bstr, IMachine *>(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<IMachine> machines;
+ hrc = pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(machines));
+ com::SafeArray<MachineState_T> 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<IGuestOSType> coll;
+ hrc = pVirtualBox->COMGETTER(GuestOSTypes)(ComSafeArrayAsOutParam(coll));
+ if (SUCCEEDED(hrc))
+ {
+ /*
+ * Iterate through the collection.
+ */
+ for (size_t i = 0; i < coll.size(); ++i)
+ {
+ ComPtr<IGuestOSType> 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<IHost> host;
+ CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam()));
+ com::SafeIfaceArray<IMedium> coll;
+ CHECK_ERROR(host, COMGETTER(DVDDrives)(ComSafeArrayAsOutParam(coll)));
+ if (SUCCEEDED(hrc))
+ {
+ for (size_t i = 0; i < coll.size(); ++i)
+ {
+ ComPtr<IMedium> 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<IHost> host;
+ CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam()));
+ com::SafeIfaceArray<IMedium> coll;
+ CHECK_ERROR(host, COMGETTER(FloppyDrives)(ComSafeArrayAsOutParam(coll)));
+ if (SUCCEEDED(hrc))
+ {
+ for (size_t i = 0; i < coll.size(); ++i)
+ {
+ ComPtr<IMedium> 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<IHost> 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<IMedium> hdds;
+ CHECK_ERROR(pVirtualBox, COMGETTER(HardDisks)(ComSafeArrayAsOutParam(hdds)));
+ hrc = listMedia(pVirtualBox, hdds, List::tr("base"), fOptLong);
+ break;
+ }
+
+ case kListDvds:
+ {
+ com::SafeIfaceArray<IMedium> dvds;
+ CHECK_ERROR(pVirtualBox, COMGETTER(DVDImages)(ComSafeArrayAsOutParam(dvds)));
+ hrc = listMedia(pVirtualBox, dvds, NULL, fOptLong);
+ break;
+ }
+
+ case kListFloppies:
+ {
+ com::SafeIfaceArray<IMedium> 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: */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
new file mode 100644
index 00000000..57ca8b34
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
@@ -0,0 +1,671 @@
+/* $Id: VBoxManageMetrics.cpp $ */
+/** @file
+ * VBoxManage - The 'metrics' 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/asm.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+#include <iprt/thread.h>
+#include <VBox/log.h>
+
+#include <set>
+#include <utility>
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Metrics);
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+
+static HRESULT parseFilterParameters(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComSafeArrayOut(BSTR, outMetrics),
+ ComSafeArrayOut(IUnknown *, outObjects))
+{
+ HRESULT hrc = S_OK;
+ com::SafeArray<BSTR> retMetrics(1);
+ com::SafeIfaceArray <IUnknown> retObjects;
+
+ Bstr metricNames, baseNames;
+
+ /* Metric list */
+ if (argc > 1)
+ metricNames = argv[1];
+ else
+ {
+ metricNames = L"*";
+ baseNames = L"*";
+ }
+ metricNames.cloneTo(&retMetrics[0]);
+
+ /* Object name */
+ if (argc > 0 && strcmp(argv[0], "*"))
+ {
+ if (!strcmp(argv[0], "host"))
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam()));
+ retObjects.reset(1);
+ host.queryInterfaceTo(&retObjects[0]);
+ }
+ else
+ {
+ ComPtr<IMachine> machine;
+ hrc = aVirtualBox->FindMachine(Bstr(argv[0]).raw(),
+ machine.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ retObjects.reset(1);
+ machine.queryInterfaceTo(&retObjects[0]);
+ }
+ else
+ {
+ errorArgument(Metrics::tr("Invalid machine name: '%s'"), argv[0]);
+ return hrc;
+ }
+ }
+
+ }
+
+ retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
+ retObjects.detachTo(ComSafeArrayOutArg(outObjects));
+
+ return hrc;
+}
+
+static Bstr toBaseName(Utf8Str& aFullName)
+{
+ char *pszRaw = aFullName.mutableRaw();
+ /*
+ * Currently there are two metrics which base name is the same as the
+ * sub-metric name: CPU/MHz and Net/<iface>/LinkSpeed.
+ */
+ if (pszRaw && strcmp(pszRaw, "CPU/MHz") && !RTStrSimplePatternMatch("Net/*/LinkSpeed", pszRaw))
+ {
+ char *pszSlash = strrchr(pszRaw, '/');
+ if (pszSlash)
+ {
+ *pszSlash = 0;
+ aFullName.jolt();
+ }
+ }
+ return Bstr(aFullName);
+}
+
+static Bstr getObjectName(ComPtr<IUnknown> aObject)
+{
+ HRESULT hrc;
+
+ ComPtr<IHost> host = aObject;
+ if (!host.isNull())
+ return Bstr(Metrics::tr("host"));
+
+ ComPtr<IMachine> machine = aObject;
+ if (!machine.isNull())
+ {
+ Bstr name;
+ CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
+ if (SUCCEEDED(hrc))
+ return name;
+ }
+ return Bstr(Metrics::tr("unknown"));
+}
+
+static void listAffectedMetrics(ComSafeArrayIn(IPerformanceMetric*, aMetrics))
+{
+ HRESULT hrc;
+ com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
+ if (metrics.size())
+ {
+ ComPtr<IUnknown> object;
+ Bstr metricName;
+ RTPrintf(Metrics::tr("The following metrics were modified:\n\n"
+ "Object Metric\n"
+ "---------- --------------------\n"));
+ for (size_t i = 0; i < metrics.size(); i++)
+ {
+ CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
+ CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
+ RTPrintf("%-10ls %-20ls\n",
+ getObjectName(object).raw(), metricName.raw());
+ }
+ RTPrintf("\n");
+ }
+ else
+ {
+ RTMsgError(Metrics::tr("No metrics match the specified filter!"));
+ }
+}
+
+/**
+ * list
+ */
+static RTEXITCODE handleMetricsList(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_LIST);
+
+ hrc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeIfaceArray<IPerformanceMetric> metricInfo;
+
+ CHECK_ERROR(performanceCollector,
+ GetMetrics(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(metricInfo)));
+
+ ComPtr<IUnknown> object;
+ Bstr metricName, unit, description;
+ ULONG period, count;
+ LONG minimum, maximum;
+ RTPrintf(Metrics::tr(
+"Object Metric Unit Minimum Maximum Period Count Description\n"
+"--------------- ---------------------------------------- ---- ---------- ---------- ---------- ---------- -----------\n"));
+ for (size_t i = 0; i < metricInfo.size(); i++)
+ {
+ CHECK_ERROR(metricInfo[i], COMGETTER(Object)(object.asOutParam()));
+ CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricName.asOutParam()));
+ CHECK_ERROR(metricInfo[i], COMGETTER(Period)(&period));
+ CHECK_ERROR(metricInfo[i], COMGETTER(Count)(&count));
+ CHECK_ERROR(metricInfo[i], COMGETTER(MinimumValue)(&minimum));
+ CHECK_ERROR(metricInfo[i], COMGETTER(MaximumValue)(&maximum));
+ CHECK_ERROR(metricInfo[i], COMGETTER(Unit)(unit.asOutParam()));
+ CHECK_ERROR(metricInfo[i], COMGETTER(Description)(description.asOutParam()));
+ RTPrintf("%-15ls %-40ls %-4ls %10d %10d %10u %10u %ls\n",
+ getObjectName(object).raw(), metricName.raw(), unit.raw(),
+ minimum, maximum, period, count, description.raw());
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Metrics setup
+ */
+static RTEXITCODE handleMetricsSetup(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+ uint32_t period = 1, samples = 1;
+ bool listMatches = false;
+ int i;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_SETUP);
+
+ for (i = 1; i < argc; i++)
+ {
+ if ( !strcmp(argv[i], "--period")
+ || !strcmp(argv[i], "-period"))
+ {
+ if (argc <= i + 1)
+ return errorArgument(Metrics::tr("Missing argument to '%s'"), argv[i]);
+ if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
+ || !period)
+ return errorArgument(Metrics::tr("Invalid value for 'period' parameter: '%s'"), argv[i]);
+ }
+ else if ( !strcmp(argv[i], "--samples")
+ || !strcmp(argv[i], "-samples"))
+ {
+ if (argc <= i + 1)
+ return errorArgument(Metrics::tr("Missing argument to '%s'"), argv[i]);
+ if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
+ || !samples)
+ return errorArgument(Metrics::tr("Invalid value for 'samples' parameter: '%s'"), argv[i]);
+ }
+ else if ( !strcmp(argv[i], "--list")
+ || !strcmp(argv[i], "-list"))
+ listMatches = true;
+ else
+ break; /* The rest of params should define the filter */
+ }
+
+ hrc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
+ CHECK_ERROR(performanceCollector,
+ SetupMetrics(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects), period, samples,
+ ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(hrc))
+ return RTEXITCODE_SYNTAX; /** @todo figure out why we must return 2 here. */
+
+ if (listMatches)
+ listAffectedMetrics(ComSafeArrayAsInParam(affectedMetrics));
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * metrics query
+ */
+static RTEXITCODE handleMetricsQuery(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_QUERY);
+
+ hrc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeArray<BSTR> retNames;
+ com::SafeIfaceArray<IUnknown> retObjects;
+ com::SafeArray<BSTR> retUnits;
+ com::SafeArray<ULONG> retScales;
+ com::SafeArray<ULONG> retSequenceNumbers;
+ com::SafeArray<ULONG> retIndices;
+ com::SafeArray<ULONG> retLengths;
+ com::SafeArray<LONG> retData;
+ CHECK_ERROR(performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(retNames),
+ ComSafeArrayAsOutParam(retObjects),
+ ComSafeArrayAsOutParam(retUnits),
+ ComSafeArrayAsOutParam(retScales),
+ ComSafeArrayAsOutParam(retSequenceNumbers),
+ ComSafeArrayAsOutParam(retIndices),
+ ComSafeArrayAsOutParam(retLengths),
+ ComSafeArrayAsOutParam(retData)) );
+
+ RTPrintf(Metrics::tr(
+ "Object Metric Values\n"
+ "--------------- ---------------------------------------- --------------------------------------------\n"));
+ for (unsigned i = 0; i < retNames.size(); i++)
+ {
+ Bstr metricUnit(retUnits[i]);
+ Bstr metricName(retNames[i]);
+ RTPrintf("%-15ls %-40ls ", getObjectName(retObjects[i]).raw(), metricName.raw());
+ const char *separator = "";
+ for (unsigned j = 0; j < retLengths[i]; j++)
+ {
+ if (retScales[i] == 1)
+ RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
+ else
+ RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
+ (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
+ separator = ", ";
+ }
+ RTPrintf("\n");
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+static void getTimestamp(char *pts, size_t tsSize)
+{
+ *pts = 0;
+ AssertReturnVoid(tsSize >= 13); /* 3+3+3+3+1 */
+ RTTIMESPEC TimeSpec;
+ RTTIME Time;
+ RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
+ pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
+ *pts++ = ':';
+ pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
+ *pts++ = ':';
+ pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
+ *pts++ = '.';
+ pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
+ *pts = 0;
+}
+
+/** Used by the handleMetricsCollect loop. */
+static bool volatile g_fKeepGoing = true;
+
+#ifdef RT_OS_WINDOWS
+/**
+ * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
+ * the console.
+ *
+ * @returns true if handled, false if not handled.
+ * @param dwCtrlType The type of control signal.
+ *
+ * @remarks This is called on a new thread.
+ */
+static BOOL WINAPI ctrlHandler(DWORD dwCtrlType) RT_NOTHROW_DEF
+{
+ switch (dwCtrlType)
+ {
+ /* Ctrl-C or Ctrl-Break or Close */
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ /* Let's shut down gracefully. */
+ ASMAtomicWriteBool(&g_fKeepGoing, false);
+ return TRUE;
+ }
+ /* Don't care about the rest -- let it die a horrible death. */
+ return FALSE;
+}
+#endif /* RT_OS_WINDOWS */
+
+/**
+ * collect
+ */
+static RTEXITCODE handleMetricsCollect(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+ uint32_t period = 1, samples = 1;
+ bool isDetached = false, listMatches = false;
+ int i;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_COLLECT);
+
+ for (i = 1; i < argc; i++)
+ {
+ if ( !strcmp(argv[i], "--period")
+ || !strcmp(argv[i], "-period"))
+ {
+ if (argc <= i + 1)
+ return errorArgument(Metrics::tr("Missing argument to '%s'"), argv[i]);
+ if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
+ || !period)
+ return errorArgument(Metrics::tr("Invalid value for 'period' parameter: '%s'"), argv[i]);
+ }
+ else if ( !strcmp(argv[i], "--samples")
+ || !strcmp(argv[i], "-samples"))
+ {
+ if (argc <= i + 1)
+ return errorArgument(Metrics::tr("Missing argument to '%s'"), argv[i]);
+ if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
+ || !samples)
+ return errorArgument(Metrics::tr("Invalid value for 'samples' parameter: '%s'"), argv[i]);
+ }
+ else if ( !strcmp(argv[i], "--list")
+ || !strcmp(argv[i], "-list"))
+ listMatches = true;
+ else if ( !strcmp(argv[i], "--detach")
+ || !strcmp(argv[i], "-detach"))
+ isDetached = true;
+ else
+ break; /* The rest of params should define the filter */
+ }
+
+ hrc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeIfaceArray<IPerformanceMetric> metricInfo;
+
+ CHECK_ERROR(performanceCollector,
+ GetMetrics(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(metricInfo)));
+
+ std::set<std::pair<ComPtr<IUnknown>,Bstr> > baseMetrics;
+ ComPtr<IUnknown> objectFiltered;
+ Bstr metricNameFiltered;
+ for (i = 0; i < (int)metricInfo.size(); i++)
+ {
+ CHECK_ERROR(metricInfo[i], COMGETTER(Object)(objectFiltered.asOutParam()));
+ CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricNameFiltered.asOutParam()));
+ Utf8Str baseMetricName(metricNameFiltered);
+ baseMetrics.insert(std::make_pair(objectFiltered, toBaseName(baseMetricName)));
+ }
+ com::SafeArray<BSTR> baseMetricsFiltered(baseMetrics.size());
+ com::SafeIfaceArray<IUnknown> objectsFiltered(baseMetrics.size());
+ std::set<std::pair<ComPtr<IUnknown>,Bstr> >::iterator it;
+ i = 0;
+ for (it = baseMetrics.begin(); it != baseMetrics.end(); ++it)
+ {
+ it->first.queryInterfaceTo(&objectsFiltered[i]);
+ Bstr(it->second).detachTo(&baseMetricsFiltered[i++]);
+ }
+ com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
+ CHECK_ERROR(performanceCollector,
+ SetupMetrics(ComSafeArrayAsInParam(baseMetricsFiltered),
+ ComSafeArrayAsInParam(objectsFiltered), period, samples,
+ ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(hrc))
+ return RTEXITCODE_SYNTAX; /** @todo figure out why we must return 2 here. */
+
+ if (listMatches)
+ listAffectedMetrics(ComSafeArrayAsInParam(affectedMetrics));
+ if (!affectedMetrics.size())
+ return RTEXITCODE_FAILURE;
+
+ if (isDetached)
+ {
+ RTMsgWarning(Metrics::tr("The background process holding collected metrics will shutdown\n"
+ "in few seconds, discarding all collected data and parameters."));
+ return RTEXITCODE_SUCCESS;
+ }
+
+#ifdef RT_OS_WINDOWS
+ SetConsoleCtrlHandler(ctrlHandler, true);
+#endif /* RT_OS_WINDOWS */
+
+ RTPrintf(Metrics::tr("Time stamp Object Metric Value\n"));
+
+ while (g_fKeepGoing)
+ {
+ RTPrintf("------------ ---------- -------------------- --------------------\n");
+ RTThreadSleep(period * 1000); // Sleep for 'period' seconds
+ char ts[15];
+
+ getTimestamp(ts, sizeof(ts));
+ com::SafeArray<BSTR> retNames;
+ com::SafeIfaceArray<IUnknown> retObjects;
+ com::SafeArray<BSTR> retUnits;
+ com::SafeArray<ULONG> retScales;
+ com::SafeArray<ULONG> retSequenceNumbers;
+ com::SafeArray<ULONG> retIndices;
+ com::SafeArray<ULONG> retLengths;
+ com::SafeArray<LONG> retData;
+ CHECK_ERROR(performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(retNames),
+ ComSafeArrayAsOutParam(retObjects),
+ ComSafeArrayAsOutParam(retUnits),
+ ComSafeArrayAsOutParam(retScales),
+ ComSafeArrayAsOutParam(retSequenceNumbers),
+ ComSafeArrayAsOutParam(retIndices),
+ ComSafeArrayAsOutParam(retLengths),
+ ComSafeArrayAsOutParam(retData)) );
+ for (unsigned j = 0; j < retNames.size(); j++)
+ {
+ Bstr metricUnit(retUnits[j]);
+ Bstr metricName(retNames[j]);
+ RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(retObjects[j]).raw(), metricName.raw());
+ const char *separator = "";
+ for (unsigned k = 0; k < retLengths[j]; k++)
+ {
+ if (retScales[j] == 1)
+ RTPrintf("%s%d %ls", separator, retData[retIndices[j] + k], metricUnit.raw());
+ else
+ RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[j] + k] / retScales[j],
+ (retData[retIndices[j] + k] * 100 / retScales[j]) % 100, metricUnit.raw());
+ separator = ", ";
+ }
+ RTPrintf("\n");
+ }
+ RTStrmFlush(g_pStdOut);
+ }
+
+#ifdef RT_OS_WINDOWS
+ SetConsoleCtrlHandler(ctrlHandler, false);
+#endif /* RT_OS_WINDOWS */
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Enable metrics
+ */
+static RTEXITCODE handleMetricsEnable(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+ bool listMatches = false;
+ int i;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_ENABLE);
+
+ for (i = 1; i < argc; i++)
+ {
+ if ( !strcmp(argv[i], "--list")
+ || !strcmp(argv[i], "-list"))
+ listMatches = true;
+ else
+ break; /* The rest of params should define the filter */
+ }
+
+ hrc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
+ CHECK_ERROR(performanceCollector,
+ EnableMetrics(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(hrc))
+ return RTEXITCODE_SYNTAX; /** @todo figure out why we must return 2 here. */
+
+ if (listMatches)
+ listAffectedMetrics(ComSafeArrayAsInParam(affectedMetrics));
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Disable metrics
+ */
+static RTEXITCODE handleMetricsDisable(int argc, char *argv[],
+ ComPtr<IVirtualBox> aVirtualBox,
+ ComPtr<IPerformanceCollector> performanceCollector)
+{
+ HRESULT hrc;
+ com::SafeArray<BSTR> metrics;
+ com::SafeIfaceArray<IUnknown> objects;
+ bool listMatches = false;
+ int i;
+
+ setCurrentSubcommand(HELP_SCOPE_METRICS_DISABLE);
+
+ for (i = 1; i < argc; i++)
+ {
+ if ( !strcmp(argv[i], "--list")
+ || !strcmp(argv[i], "-list"))
+ listMatches = true;
+ else
+ break; /* The rest of params should define the filter */
+ }
+
+ hrc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
+ ComSafeArrayAsOutParam(metrics),
+ ComSafeArrayAsOutParam(objects));
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
+ CHECK_ERROR(performanceCollector,
+ DisableMetrics(ComSafeArrayAsInParam(metrics),
+ ComSafeArrayAsInParam(objects),
+ ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(hrc))
+ return RTEXITCODE_SYNTAX; /** @todo figure out why we must return 2 here. */
+
+ if (listMatches)
+ listAffectedMetrics(ComSafeArrayAsInParam(affectedMetrics));
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+RTEXITCODE handleMetrics(HandlerArg *a)
+{
+ /* at least one option: subcommand name */
+ if (a->argc < 1)
+ return errorSyntax(Metrics::tr("Subcommand missing"));
+
+ ComPtr<IPerformanceCollector> performanceCollector;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()), RTEXITCODE_FAILURE);
+
+ RTEXITCODE rcExit;
+ if (!strcmp(a->argv[0], "list"))
+ rcExit = handleMetricsList(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else if (!strcmp(a->argv[0], "setup"))
+ rcExit = handleMetricsSetup(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else if (!strcmp(a->argv[0], "query"))
+ rcExit = handleMetricsQuery(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else if (!strcmp(a->argv[0], "collect"))
+ rcExit = handleMetricsCollect(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else if (!strcmp(a->argv[0], "enable"))
+ rcExit = handleMetricsEnable(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else if (!strcmp(a->argv[0], "disable"))
+ rcExit = handleMetricsDisable(a->argc, a->argv, a->virtualBox, performanceCollector);
+ else
+ return errorSyntax(Metrics::tr("Invalid subcommand '%s'"), a->argv[0]);
+
+ return rcExit;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
new file mode 100644
index 00000000..fca7a98c
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
@@ -0,0 +1,2920 @@
+/* $Id: VBoxManageMisc.cpp $ */
+/** @file
+ * VBoxManage - VirtualBox's command-line interface.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+#include <VBox/com/NativeEventQueue.h>
+
+#include <iprt/asm.h>
+#include <iprt/buildconfig.h>
+#include <iprt/cidr.h>
+#include <iprt/ctype.h>
+#include <iprt/dir.h>
+#include <iprt/env.h>
+#include <iprt/file.h>
+#include <iprt/sha.h>
+#include <iprt/initterm.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/cpp/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#include <iprt/thread.h>
+#include <iprt/uuid.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+#include <VBox/version.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+
+#include <list>
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Misc);
+
+static const RTGETOPTDEF g_aRegisterVMOptions[] =
+{
+ { "--password", 'p', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleRegisterVM(HandlerArg *a)
+{
+ HRESULT hrc;
+ const char *VMName = NULL;
+
+ Bstr bstrVMName;
+ Bstr bstrPasswordFile;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aRegisterVMOptions, RT_ELEMENTS(g_aRegisterVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'p': // --password
+ bstrPasswordFile = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (bstrVMName.isEmpty())
+ VMName = ValueUnion.psz;
+ else
+ return errorSyntax(Misc::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Misc::tr("Invalid option -%c"), c);
+ return errorSyntax(Misc::tr("Invalid option case %i"), c);
+ }
+ if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz);
+ if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ return errorSyntax(Misc::tr("error: %Rrs"), c);
+ }
+ }
+
+ Utf8Str strPassword;
+
+ if (bstrPasswordFile.isNotEmpty())
+ {
+ if (bstrPasswordFile == "-")
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, Misc::tr("Enter password:"));
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(a->argv[3], &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ return RTMsgErrorExitFailure(Misc::tr("Failed to read password from file"));
+ }
+ }
+
+ ComPtr<IMachine> machine;
+ /** @todo Ugly hack to get both the API interpretation of relative paths
+ * and the client's interpretation of relative paths. Remove after the API
+ * has been redesigned. */
+ hrc = a->virtualBox->OpenMachine(Bstr(a->argv[0]).raw(),
+ Bstr(strPassword).raw(),
+ machine.asOutParam());
+ if (FAILED(hrc) && !RTPathStartsWithRoot(a->argv[0]))
+ {
+ char szVMFileAbs[RTPATH_MAX] = "";
+ int vrc = RTPathAbs(a->argv[0], szVMFileAbs, sizeof(szVMFileAbs));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExitFailure(Misc::tr("Failed to convert \"%s\" to an absolute path: %Rrc"),
+ a->argv[0], vrc);
+ CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(szVMFileAbs).raw(),
+ Bstr(strPassword).raw(),
+ machine.asOutParam()));
+ }
+ else if (FAILED(hrc))
+ com::GlueHandleComError(a->virtualBox,
+ "OpenMachine(Bstr(a->argv[0]).raw(), Bstr(strPassword).raw(), machine.asOutParam()))",
+ hrc, __FILE__, __LINE__);
+ if (SUCCEEDED(hrc))
+ {
+ ASSERT(machine);
+ CHECK_ERROR(a->virtualBox, RegisterMachine(machine));
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aUnregisterVMOptions[] =
+{
+ { "--delete", 'd', RTGETOPT_REQ_NOTHING },
+ { "-delete", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--delete-all", 'a', RTGETOPT_REQ_NOTHING },
+ { "-delete-all", 'a', RTGETOPT_REQ_NOTHING }, // deprecated
+};
+
+RTEXITCODE handleUnregisterVM(HandlerArg *a)
+{
+ HRESULT hrc;
+ const char *VMName = NULL;
+ bool fDelete = false;
+ bool fDeleteAll = false;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aUnregisterVMOptions, RT_ELEMENTS(g_aUnregisterVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'd': // --delete
+ fDelete = true;
+ break;
+
+ case 'a': // --delete-all
+ fDeleteAll = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!VMName)
+ VMName = ValueUnion.psz;
+ else
+ return errorSyntax(Misc::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Misc::tr("Invalid option -%c"), c);
+ return errorSyntax(Misc::tr("Invalid option case %i"), c);
+ }
+ if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz);
+ if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ return errorSyntax(Misc::tr("error: %Rrs"), c);
+ }
+ }
+
+ /* check for required options */
+ if (!VMName)
+ return errorSyntax(Misc::tr("VM name required"));
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(VMName).raw(),
+ machine.asOutParam()),
+ RTEXITCODE_FAILURE);
+ SafeIfaceArray<IMedium> aMedia;
+ CHECK_ERROR_RET(machine, Unregister(fDeleteAll ? CleanupMode_DetachAllReturnHardDisksAndVMRemovable
+ :CleanupMode_DetachAllReturnHardDisksOnly,
+ ComSafeArrayAsOutParam(aMedia)),
+ RTEXITCODE_FAILURE);
+ if (fDelete || fDeleteAll)
+ {
+ ComPtr<IProgress> pProgress;
+ CHECK_ERROR_RET(machine, DeleteConfig(ComSafeArrayAsInParam(aMedia), pProgress.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (Misc::tr("Machine delete failed")), RTEXITCODE_FAILURE);
+ }
+ else
+ {
+ /* Note that the IMachine::Unregister method will return the medium
+ * reference in a sane order, which means that closing will normally
+ * succeed, unless there is still another machine which uses the
+ * medium. No harm done if we ignore the error. */
+ for (size_t i = 0; i < aMedia.size(); i++)
+ {
+ IMedium *pMedium = aMedia[i];
+ if (pMedium)
+ hrc = pMedium->Close();
+ }
+ hrc = S_OK; /** @todo r=andy Why overwriting the result from closing the medium above? */
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+static const RTGETOPTDEF g_aCreateVMOptions[] =
+{
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "-name", 'n', RTGETOPT_REQ_STRING },
+ { "--groups", 'g', RTGETOPT_REQ_STRING },
+ { "--basefolder", 'p', RTGETOPT_REQ_STRING },
+ { "-basefolder", 'p', RTGETOPT_REQ_STRING },
+ { "--ostype", 'o', RTGETOPT_REQ_STRING },
+ { "-ostype", 'o', RTGETOPT_REQ_STRING },
+ { "--uuid", 'u', RTGETOPT_REQ_UUID },
+ { "-uuid", 'u', RTGETOPT_REQ_UUID },
+ { "--register", 'r', RTGETOPT_REQ_NOTHING },
+ { "-register", 'r', RTGETOPT_REQ_NOTHING },
+ { "--default", 'd', RTGETOPT_REQ_NOTHING },
+ { "-default", 'd', RTGETOPT_REQ_NOTHING },
+ { "--cipher", 'c', RTGETOPT_REQ_STRING },
+ { "-cipher", 'c', RTGETOPT_REQ_STRING },
+ { "--password-id", 'i', RTGETOPT_REQ_STRING },
+ { "-password-id", 'i', RTGETOPT_REQ_STRING },
+ { "--password", 'w', RTGETOPT_REQ_STRING },
+ { "-password", 'w', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleCreateVM(HandlerArg *a)
+{
+ HRESULT hrc;
+ Bstr bstrBaseFolder;
+ Bstr bstrName;
+ Bstr bstrOsTypeId;
+ Bstr bstrUuid;
+ bool fRegister = false;
+ bool fDefault = false;
+ /* TBD. Now not used */
+ Bstr bstrDefaultFlags;
+ com::SafeArray<BSTR> groups;
+ Bstr bstrCipher;
+ Bstr bstrPasswordId;
+ const char *pszPassword = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateVMOptions, RT_ELEMENTS(g_aCreateVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n': // --name
+ bstrName = ValueUnion.psz;
+ break;
+
+ case 'g': // --groups
+ parseGroups(ValueUnion.psz, &groups);
+ break;
+
+ case 'p': // --basefolder
+ bstrBaseFolder = ValueUnion.psz;
+ break;
+
+ case 'o': // --ostype
+ bstrOsTypeId = ValueUnion.psz;
+ break;
+
+ case 'u': // --uuid
+ bstrUuid = Guid(ValueUnion.Uuid).toUtf16().raw();
+ break;
+
+ case 'r': // --register
+ fRegister = true;
+ break;
+
+ case 'd': // --default
+ fDefault = true;
+ break;
+
+ case 'c': // --cipher
+ bstrCipher = ValueUnion.psz;
+ break;
+
+ case 'i': // --password-id
+ bstrPasswordId = ValueUnion.psz;
+ break;
+
+ case 'w': // --password
+ pszPassword = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* check for required options */
+ if (bstrName.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --name is required"));
+
+ do
+ {
+ Bstr createFlags;
+ if (!bstrUuid.isEmpty())
+ createFlags = BstrFmt("UUID=%ls", bstrUuid.raw());
+ Bstr bstrPrimaryGroup;
+ if (groups.size())
+ bstrPrimaryGroup = groups[0];
+ Bstr bstrSettingsFile;
+ CHECK_ERROR_BREAK(a->virtualBox,
+ ComposeMachineFilename(bstrName.raw(),
+ bstrPrimaryGroup.raw(),
+ createFlags.raw(),
+ bstrBaseFolder.raw(),
+ bstrSettingsFile.asOutParam()));
+ Utf8Str strPassword;
+ if (pszPassword)
+ {
+ if (!RTStrCmp(pszPassword, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read new password from file");
+ return rcExit;
+ }
+ }
+ }
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_BREAK(a->virtualBox,
+ CreateMachine(bstrSettingsFile.raw(),
+ bstrName.raw(),
+ ComSafeArrayAsInParam(groups),
+ bstrOsTypeId.raw(),
+ createFlags.raw(),
+ bstrCipher.raw(),
+ bstrPasswordId.raw(),
+ Bstr(strPassword).raw(),
+ machine.asOutParam()));
+
+ CHECK_ERROR_BREAK(machine, SaveSettings());
+ if (fDefault)
+ {
+ /* ApplyDefaults assumes the machine is already registered */
+ CHECK_ERROR_BREAK(machine, ApplyDefaults(bstrDefaultFlags.raw()));
+ CHECK_ERROR_BREAK(machine, SaveSettings());
+ }
+ if (fRegister)
+ {
+ CHECK_ERROR_BREAK(a->virtualBox, RegisterMachine(machine));
+ }
+
+ Bstr uuid;
+ CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam()));
+ Bstr settingsFile;
+ CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam()));
+ RTPrintf(Misc::tr("Virtual machine '%ls' is created%s.\n"
+ "UUID: %s\n"
+ "Settings file: '%ls'\n"),
+ bstrName.raw(), fRegister ? Misc::tr(" and registered") : "",
+ Utf8Str(uuid).c_str(), settingsFile.raw());
+ }
+ while (0);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aMoveVMOptions[] =
+{
+ { "--type", 't', RTGETOPT_REQ_STRING },
+ { "--folder", 'f', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleMoveVM(HandlerArg *a)
+{
+ HRESULT hrc;
+ const char *pszSrcName = NULL;
+ const char *pszType = NULL;
+ char szTargetFolder[RTPATH_MAX];
+
+ int c;
+ int vrc = VINF_SUCCESS;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aMoveVMOptions, RT_ELEMENTS(g_aMoveVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 't': // --type
+ pszType = ValueUnion.psz;
+ break;
+
+ case 'f': // --target folder
+ if (ValueUnion.psz && ValueUnion.psz[0] != '\0')
+ {
+ vrc = RTPathAbs(ValueUnion.psz, szTargetFolder, sizeof(szTargetFolder));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("RTPathAbs(%s,,) failed with vrc=%Rrc"),
+ ValueUnion.psz, vrc);
+ } else {
+ szTargetFolder[0] = '\0';
+ }
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszSrcName)
+ pszSrcName = ValueUnion.psz;
+ else
+ return errorSyntax(Misc::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+
+ if (!pszType)
+ pszType = "basic";
+
+ /* Check for required options */
+ if (!pszSrcName)
+ return errorSyntax(Misc::tr("VM name required"));
+
+ /* Get the machine object */
+ ComPtr<IMachine> srcMachine;
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(pszSrcName).raw(),
+ srcMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ if (srcMachine)
+ {
+ /* Start the moving */
+ ComPtr<IProgress> progress;
+
+ /* we have to open a session for this task */
+ CHECK_ERROR_RET(srcMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+ ComPtr<IMachine> sessionMachine;
+
+ CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(sessionMachine,
+ MoveTo(Bstr(szTargetFolder).raw(),
+ Bstr(pszType).raw(),
+ progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Misc::tr("Move VM failed")), RTEXITCODE_FAILURE);
+
+ sessionMachine.setNull();
+ CHECK_ERROR_RET(a->session, UnlockMachine(), RTEXITCODE_FAILURE);
+
+ RTPrintf(Misc::tr("Machine has been successfully moved into %s\n"),
+ szTargetFolder[0] != '\0' ? szTargetFolder : Misc::tr("the same location"));
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+static const RTGETOPTDEF g_aCloneVMOptions[] =
+{
+ { "--snapshot", 's', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--groups", 'g', RTGETOPT_REQ_STRING },
+ { "--mode", 'm', RTGETOPT_REQ_STRING },
+ { "--options", 'o', RTGETOPT_REQ_STRING },
+ { "--register", 'r', RTGETOPT_REQ_NOTHING },
+ { "--basefolder", 'p', RTGETOPT_REQ_STRING },
+ { "--uuid", 'u', RTGETOPT_REQ_UUID },
+};
+
+static int parseCloneMode(const char *psz, CloneMode_T *pMode)
+{
+ if (!RTStrICmp(psz, "machine"))
+ *pMode = CloneMode_MachineState;
+ else if (!RTStrICmp(psz, "machineandchildren"))
+ *pMode = CloneMode_MachineAndChildStates;
+ else if (!RTStrICmp(psz, "all"))
+ *pMode = CloneMode_AllStates;
+ else
+ return VERR_PARSE_ERROR;
+
+ return VINF_SUCCESS;
+}
+
+static int parseCloneOptions(const char *psz, com::SafeArray<CloneOptions_T> *options)
+{
+ int vrc = VINF_SUCCESS;
+ while (psz && *psz && RT_SUCCESS(vrc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "KeepAllMACs", len))
+ options->push_back(CloneOptions_KeepAllMACs);
+ else if (!RTStrNICmp(psz, "KeepNATMACs", len))
+ options->push_back(CloneOptions_KeepNATMACs);
+ else if (!RTStrNICmp(psz, "KeepDiskNames", len))
+ options->push_back(CloneOptions_KeepDiskNames);
+ else if ( !RTStrNICmp(psz, "Link", len)
+ || !RTStrNICmp(psz, "Linked", len))
+ options->push_back(CloneOptions_Link);
+ else if ( !RTStrNICmp(psz, "KeepHwUUIDs", len)
+ || !RTStrNICmp(psz, "KeepHwUUID", len))
+ options->push_back(CloneOptions_KeepHwUUIDs);
+ else
+ vrc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ return vrc;
+}
+
+RTEXITCODE handleCloneVM(HandlerArg *a)
+{
+ HRESULT hrc;
+ const char *pszSrcName = NULL;
+ const char *pszSnapshotName = NULL;
+ CloneMode_T mode = CloneMode_MachineState;
+ com::SafeArray<CloneOptions_T> options;
+ const char *pszTrgName = NULL;
+ const char *pszTrgBaseFolder = NULL;
+ bool fRegister = false;
+ Bstr bstrUuid;
+ com::SafeArray<BSTR> groups;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneVMOptions, RT_ELEMENTS(g_aCloneVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 's': // --snapshot
+ pszSnapshotName = ValueUnion.psz;
+ break;
+
+ case 'n': // --name
+ pszTrgName = ValueUnion.psz;
+ break;
+
+ case 'g': // --groups
+ parseGroups(ValueUnion.psz, &groups);
+ break;
+
+ case 'p': // --basefolder
+ pszTrgBaseFolder = ValueUnion.psz;
+ break;
+
+ case 'm': // --mode
+ if (RT_FAILURE(parseCloneMode(ValueUnion.psz, &mode)))
+ return errorArgument(Misc::tr("Invalid clone mode '%s'\n"), ValueUnion.psz);
+ break;
+
+ case 'o': // --options
+ if (RT_FAILURE(parseCloneOptions(ValueUnion.psz, &options)))
+ return errorArgument(Misc::tr("Invalid clone options '%s'\n"), ValueUnion.psz);
+ break;
+
+ case 'u': // --uuid
+ bstrUuid = Guid(ValueUnion.Uuid).toUtf16().raw();
+ break;
+
+ case 'r': // --register
+ fRegister = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (!pszSrcName)
+ pszSrcName = ValueUnion.psz;
+ else
+ return errorSyntax(Misc::tr("Invalid parameter '%s'"), ValueUnion.psz);
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* Check for required options */
+ if (!pszSrcName)
+ return errorSyntax(Misc::tr("VM name required"));
+
+ /* Get the machine object */
+ ComPtr<IMachine> srcMachine;
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(pszSrcName).raw(),
+ srcMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ /* If a snapshot name/uuid was given, get the particular machine of this
+ * snapshot. */
+ if (pszSnapshotName)
+ {
+ ComPtr<ISnapshot> srcSnapshot;
+ CHECK_ERROR_RET(srcMachine, FindSnapshot(Bstr(pszSnapshotName).raw(),
+ srcSnapshot.asOutParam()),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(srcSnapshot, COMGETTER(Machine)(srcMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+
+ /* Default name necessary? */
+ if (!pszTrgName)
+ pszTrgName = RTStrAPrintf2(Misc::tr("%s Clone"), pszSrcName);
+
+ Bstr createFlags;
+ if (!bstrUuid.isEmpty())
+ createFlags = BstrFmt("UUID=%ls", bstrUuid.raw());
+ Bstr bstrPrimaryGroup;
+ if (groups.size())
+ bstrPrimaryGroup = groups[0];
+ Bstr bstrSettingsFile;
+ CHECK_ERROR_RET(a->virtualBox,
+ ComposeMachineFilename(Bstr(pszTrgName).raw(),
+ bstrPrimaryGroup.raw(),
+ createFlags.raw(),
+ Bstr(pszTrgBaseFolder).raw(),
+ bstrSettingsFile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<IMachine> trgMachine;
+ CHECK_ERROR_RET(a->virtualBox, CreateMachine(bstrSettingsFile.raw(),
+ Bstr(pszTrgName).raw(),
+ ComSafeArrayAsInParam(groups),
+ NULL,
+ createFlags.raw(),
+ NULL,
+ NULL,
+ NULL,
+ trgMachine.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ /* Start the cloning */
+ ComPtr<IProgress> progress;
+ CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine,
+ mode,
+ ComSafeArrayAsInParam(options),
+ progress.asOutParam()),
+ RTEXITCODE_FAILURE);
+ hrc = showProgress(progress);
+ CHECK_PROGRESS_ERROR_RET(progress, (Misc::tr("Clone VM failed")), RTEXITCODE_FAILURE);
+
+ if (fRegister)
+ CHECK_ERROR_RET(a->virtualBox, RegisterMachine(trgMachine), RTEXITCODE_FAILURE);
+
+ Bstr bstrNewName;
+ CHECK_ERROR_RET(trgMachine, COMGETTER(Name)(bstrNewName.asOutParam()), RTEXITCODE_FAILURE);
+ RTPrintf(Misc::tr("Machine has been successfully cloned as \"%ls\"\n"), bstrNewName.raw());
+
+ return RTEXITCODE_SUCCESS;
+}
+
+RTEXITCODE handleStartVM(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ std::list<const char *> VMs;
+ Bstr sessionType;
+ com::SafeArray<IN_BSTR> aBstrEnv;
+ const char *pszPassword = NULL;
+ const char *pszPasswordId = NULL;
+ Utf8Str strPassword;
+
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
+ /* make sure the VM process will by default start on the same display as VBoxManage */
+ {
+ const char *pszDisplay = RTEnvGet("DISPLAY");
+ if (pszDisplay)
+ aBstrEnv.push_back(BstrFmt("DISPLAY=%s", pszDisplay).raw());
+ const char *pszXAuth = RTEnvGet("XAUTHORITY");
+ if (pszXAuth)
+ aBstrEnv.push_back(BstrFmt("XAUTHORITY=%s", pszXAuth).raw());
+ }
+#endif
+
+ static const RTGETOPTDEF s_aStartVMOptions[] =
+ {
+ { "--type", 't', RTGETOPT_REQ_STRING },
+ { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
+ { "--putenv", 'E', RTGETOPT_REQ_STRING },
+ { "--password", 'p', RTGETOPT_REQ_STRING },
+ { "--password-id", 'i', RTGETOPT_REQ_STRING }
+ };
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aStartVMOptions, RT_ELEMENTS(s_aStartVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 't': // --type
+ if (!RTStrICmp(ValueUnion.psz, "gui"))
+ {
+ sessionType = "gui";
+ }
+#ifdef VBOX_WITH_VBOXSDL
+ else if (!RTStrICmp(ValueUnion.psz, "sdl"))
+ {
+ sessionType = "sdl";
+ }
+#endif
+#ifdef VBOX_WITH_HEADLESS
+ else if (!RTStrICmp(ValueUnion.psz, "capture"))
+ {
+ sessionType = "capture";
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "headless"))
+ {
+ sessionType = "headless";
+ }
+#endif
+ else
+ sessionType = ValueUnion.psz;
+ break;
+
+ case 'E': // --putenv
+ if (!RTStrStr(ValueUnion.psz, "\n"))
+ aBstrEnv.push_back(Bstr(ValueUnion.psz).raw());
+ else
+ return errorSyntax(Misc::tr("Parameter to option --putenv must not contain any newline character"));
+ break;
+
+ case 'p': // --password
+ pszPassword = ValueUnion.psz;
+ break;
+
+ case 'i': // --password-id
+ pszPasswordId = ValueUnion.psz;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ VMs.push_back(ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Misc::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Misc::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Misc::tr("error: %Rrs"), c);
+ }
+ }
+
+ /* check for required options */
+ if (VMs.empty())
+ return errorSyntax(Misc::tr("at least one VM name or uuid required"));
+
+ if (pszPassword)
+ {
+ if (!RTStrCmp(pszPassword, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read new password from file");
+ return rcExit;
+ }
+ }
+ }
+
+ for (std::list<const char *>::const_iterator it = VMs.begin();
+ it != VMs.end();
+ ++it)
+ {
+ HRESULT hrc2 = hrc;
+ const char *pszVM = *it;
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszVM).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ if (pszPasswordId && strPassword.isNotEmpty())
+ {
+ CHECK_ERROR(machine, AddEncryptionPassword(Bstr(pszPasswordId).raw(), Bstr(strPassword).raw()));
+ if (hrc == VBOX_E_PASSWORD_INCORRECT)
+ RTMsgError("Password incorrect!");
+ }
+ if (SUCCEEDED(hrc))
+ {
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(machine, LaunchVMProcess(a->session, sessionType.raw(),
+ ComSafeArrayAsInParam(aBstrEnv), progress.asOutParam()));
+ if (SUCCEEDED(hrc) && !progress.isNull())
+ {
+ RTPrintf("Waiting for VM \"%s\" to power on...\n", pszVM);
+ CHECK_ERROR(progress, WaitForCompletion(-1));
+ if (SUCCEEDED(hrc))
+ {
+ BOOL completed = true;
+ CHECK_ERROR(progress, COMGETTER(Completed)(&completed));
+ if (SUCCEEDED(hrc))
+ {
+ ASSERT(completed);
+
+ LONG iRc;
+ CHECK_ERROR(progress, COMGETTER(ResultCode)(&iRc));
+ if (SUCCEEDED(hrc))
+ {
+ if (SUCCEEDED(iRc))
+ RTPrintf("VM \"%s\" has been successfully started.\n", pszVM);
+ else
+ {
+ ProgressErrorInfo info(progress);
+ com::GluePrintErrorInfo(info);
+ }
+ hrc = iRc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+
+ /* make sure that we remember the failed state */
+ if (FAILED(hrc2))
+ hrc = hrc2;
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+static const RTGETOPTDEF g_aSetVMEncryptionOptions[] =
+{
+ { "--new-password", 'n', RTGETOPT_REQ_STRING },
+ { "--old-password", 'o', RTGETOPT_REQ_STRING },
+ { "--cipher", 'c', RTGETOPT_REQ_STRING },
+ { "--new-password-id", 'i', RTGETOPT_REQ_STRING },
+ { "--force", 'f', RTGETOPT_REQ_NOTHING},
+};
+
+RTEXITCODE handleSetVMEncryption(HandlerArg *a, const char *pszFilenameOrUuid)
+{
+ HRESULT hrc;
+ ComPtr<IMachine> machine;
+ const char *pszPasswordNew = NULL;
+ const char *pszPasswordOld = NULL;
+ const char *pszCipher = NULL;
+ const char *pszNewPasswordId = NULL;
+ BOOL fForce = FALSE;
+ Utf8Str strPasswordNew;
+ Utf8Str strPasswordOld;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aSetVMEncryptionOptions, RT_ELEMENTS(g_aSetVMEncryptionOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n': // --new-password
+ pszPasswordNew = ValueUnion.psz;
+ break;
+
+ case 'o': // --old-password
+ pszPasswordOld = ValueUnion.psz;
+ break;
+
+ case 'c': // --cipher
+ pszCipher = ValueUnion.psz;
+ break;
+
+ case 'i': // --new-password-id
+ pszNewPasswordId = ValueUnion.psz;
+ break;
+
+ case 'f': // --force
+ fForce = TRUE;
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Misc::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Misc::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax(Misc::tr("%s: %Rrs"), ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Misc::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Misc::tr("VM name or UUID required"));
+
+ if (!pszPasswordNew && !pszPasswordOld)
+ return errorSyntax(Misc::tr("No password specified"));
+
+ if ( (pszPasswordNew && !pszNewPasswordId)
+ || (!pszPasswordNew && pszNewPasswordId))
+ return errorSyntax(Misc::tr("A new password must always have a valid identifier set at the same time"));
+
+ if (pszPasswordOld)
+ {
+ if (!RTStrCmp(pszPasswordOld, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordOld, "Enter old password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPasswordOld, &strPasswordOld);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read old password from file");
+ return rcExit;
+ }
+ }
+ }
+ if (pszPasswordNew)
+ {
+ if (!RTStrCmp(pszPasswordNew, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordNew, "Enter new password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPasswordNew, &strPasswordNew);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read new password from file");
+ return rcExit;
+ }
+ }
+ }
+
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(machine, ChangeEncryption(Bstr(strPasswordOld).raw(), Bstr(pszCipher).raw(),
+ Bstr(strPasswordNew).raw(), Bstr(pszNewPasswordId).raw(),
+ fForce, progress.asOutParam()));
+ if (SUCCEEDED(hrc))
+ hrc = showProgress(progress);
+ if (FAILED(hrc))
+ {
+ if (hrc == E_NOTIMPL)
+ RTMsgError("Encrypt VM operation is not implemented!");
+ else if (hrc == VBOX_E_NOT_SUPPORTED)
+ RTMsgError("Encrypt VM operation for this cipher is not implemented yet!");
+ else if (!progress.isNull())
+ CHECK_PROGRESS_ERROR(progress, ("Failed to encrypt the VM"));
+ else
+ RTMsgError("Failed to encrypt the VM!");
+ }
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleCheckVMPassword(HandlerArg *a, const char *pszFilenameOrUuid)
+{
+ HRESULT hrc;
+ ComPtr<IMachine> machine;
+ Utf8Str strPassword;
+
+ if (a->argc != 1)
+ return errorSyntax(Misc::tr("Invalid number of arguments: %d"), a->argc);
+
+ if (!RTStrCmp(a->argv[0], "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(a->argv[0], &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read password from file");
+ return rcExit;
+ }
+ }
+
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ CHECK_ERROR(machine, CheckEncryptionPassword(Bstr(strPassword).raw()));
+ if (SUCCEEDED(hrc))
+ RTPrintf("The given password is correct\n");
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static const RTGETOPTDEF g_aAddVMOptions[] =
+{
+ { "--password", 'p', RTGETOPT_REQ_STRING },
+ { "--password-id", 'i', RTGETOPT_REQ_STRING }
+};
+
+RTEXITCODE handleAddVMPassword(HandlerArg *a, const char *pszFilenameOrUuid)
+{
+ HRESULT hrc;
+ ComPtr<IMachine> machine;
+ const char *pszPassword = NULL;
+ const char *pszPasswordId = NULL;
+ Utf8Str strPassword;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aAddVMOptions, RT_ELEMENTS(g_aAddVMOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'p': // --password
+ pszPassword = ValueUnion.psz;
+ break;
+
+ case 'i': // --password-id
+ pszPasswordId = ValueUnion.psz;
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(Misc::tr("Invalid option -%c"), c);
+ else
+ return errorSyntax(Misc::tr("Invalid option case %i"), c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax(Misc::tr("%s: %Rrs"), ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(Misc::tr("error: %Rrs"), c);
+ }
+ }
+
+ if (!pszFilenameOrUuid)
+ return errorSyntax(Misc::tr("VM name or UUID required"));
+
+ if (!pszPassword)
+ return errorSyntax(Misc::tr("No password specified"));
+
+ if (!pszPasswordId)
+ return errorSyntax(Misc::tr("No password identifier specified"));
+
+ if (!RTStrCmp(pszPassword, "-"))
+ {
+ /* Get password from console. */
+ RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:");
+ if (rcExit == RTEXITCODE_FAILURE)
+ return rcExit;
+ }
+ else
+ {
+ RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword);
+ if (rcExit == RTEXITCODE_FAILURE)
+ {
+ RTMsgError("Failed to read new password from file");
+ return rcExit;
+ }
+ }
+
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ ComPtr<IProgress> progress;
+ CHECK_ERROR(machine, AddEncryptionPassword(Bstr(pszPasswordId).raw(), Bstr(strPassword).raw()));
+ if (hrc == VBOX_E_PASSWORD_INCORRECT)
+ RTMsgError("Password incorrect!");
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleRemoveVMPassword(HandlerArg *a, const char *pszFilenameOrUuid)
+{
+ HRESULT hrc;
+ ComPtr<IMachine> machine;
+
+ if (a->argc != 1)
+ return errorSyntax(Misc::tr("Invalid number of arguments: %d"), a->argc);
+
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ CHECK_ERROR(machine, RemoveEncryptionPassword(Bstr(a->argv[0]).raw()));
+ if (hrc == VBOX_E_INVALID_VM_STATE)
+ RTMsgError("The machine is in online or transient state\n");
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleEncryptVM(HandlerArg *a)
+{
+ if (a->argc < 2)
+ return errorSyntax(Misc::tr("subcommand required"));
+
+ HandlerArg handlerArg;
+ handlerArg.argc = a->argc - 2;
+ handlerArg.argv = &a->argv[2];
+ handlerArg.virtualBox = a->virtualBox;
+ handlerArg.session = a->session;
+ if (!strcmp(a->argv[1], "setencryption"))
+ return handleSetVMEncryption(&handlerArg, a->argv[0]);
+ if (!strcmp(a->argv[1], "checkpassword"))
+ return handleCheckVMPassword(&handlerArg, a->argv[0]);
+ if (!strcmp(a->argv[1], "addpassword"))
+ return handleAddVMPassword(&handlerArg, a->argv[0]);
+ if (!strcmp(a->argv[1], "removepassword"))
+ return handleRemoveVMPassword(&handlerArg, a->argv[0]);
+ return errorSyntax(Misc::tr("unknown subcommand"));
+}
+#endif /* !VBOX_WITH_FULL_VM_ENCRYPTION */
+
+RTEXITCODE handleDiscardState(HandlerArg *a)
+{
+ HRESULT hrc;
+
+ if (a->argc != 1)
+ return errorSyntax(Misc::tr("Incorrect number of parameters"));
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ do
+ {
+ /* we have to open a session for this task */
+ CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
+ do
+ {
+ ComPtr<IMachine> sessionMachine;
+ CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+ CHECK_ERROR_BREAK(sessionMachine, DiscardSavedState(true /* fDeleteFile */));
+ } while (0);
+ CHECK_ERROR_BREAK(a->session, UnlockMachine());
+ } while (0);
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleAdoptState(HandlerArg *a)
+{
+ HRESULT hrc;
+
+ if (a->argc != 2)
+ return errorSyntax(Misc::tr("Incorrect number of parameters"));
+
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ char szStateFileAbs[RTPATH_MAX] = "";
+ int vrc = RTPathAbs(a->argv[1], szStateFileAbs, sizeof(szStateFileAbs));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Cannot convert filename \"%s\" to absolute path: %Rrc"),
+ a->argv[0], vrc);
+
+ do
+ {
+ /* we have to open a session for this task */
+ CHECK_ERROR_BREAK(machine, LockMachine(a->session, LockType_Write));
+ do
+ {
+ ComPtr<IMachine> sessionMachine;
+ CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+ CHECK_ERROR_BREAK(sessionMachine, AdoptSavedState(Bstr(szStateFileAbs).raw()));
+ } while (0);
+ CHECK_ERROR_BREAK(a->session, UnlockMachine());
+ } while (0);
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleGetExtraData(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ if (a->argc > 2 || a->argc < 1)
+ return errorSyntax(Misc::tr("Incorrect number of parameters"));
+
+ /* global data? */
+ if (!strcmp(a->argv[0], "global"))
+ {
+ /* enumeration? */
+ if (a->argc < 2 || !strcmp(a->argv[1], "enumerate"))
+ {
+ SafeArray<BSTR> aKeys;
+ CHECK_ERROR(a->virtualBox, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
+
+ for (size_t i = 0;
+ i < aKeys.size();
+ ++i)
+ {
+ Bstr bstrKey(aKeys[i]);
+ Bstr bstrValue;
+ CHECK_ERROR(a->virtualBox, GetExtraData(bstrKey.raw(),
+ bstrValue.asOutParam()));
+
+ RTPrintf(Misc::tr("Key: %ls, Value: %ls\n"), bstrKey.raw(), bstrValue.raw());
+ }
+ }
+ else
+ {
+ Bstr value;
+ CHECK_ERROR(a->virtualBox, GetExtraData(Bstr(a->argv[1]).raw(),
+ value.asOutParam()));
+ if (!value.isEmpty())
+ RTPrintf(Misc::tr("Value: %ls\n"), value.raw());
+ else
+ RTPrintf(Misc::tr("No value set!\n"));
+ }
+ }
+ else
+ {
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ /* enumeration? */
+ if (a->argc < 2 || !strcmp(a->argv[1], "enumerate"))
+ {
+ SafeArray<BSTR> aKeys;
+ CHECK_ERROR(machine, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
+
+ for (size_t i = 0;
+ i < aKeys.size();
+ ++i)
+ {
+ Bstr bstrKey(aKeys[i]);
+ Bstr bstrValue;
+ CHECK_ERROR(machine, GetExtraData(bstrKey.raw(),
+ bstrValue.asOutParam()));
+
+ RTPrintf(Misc::tr("Key: %ls, Value: %ls\n"), bstrKey.raw(), bstrValue.raw());
+ }
+ }
+ else
+ {
+ Bstr value;
+ CHECK_ERROR(machine, GetExtraData(Bstr(a->argv[1]).raw(),
+ value.asOutParam()));
+ if (!value.isEmpty())
+ RTPrintf(Misc::tr("Value: %ls\n"), value.raw());
+ else
+ RTPrintf(Misc::tr("No value set!\n"));
+ }
+ }
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleSetExtraData(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ if (a->argc < 2)
+ return errorSyntax(Misc::tr("Not enough parameters"));
+
+ /* global data? */
+ if (!strcmp(a->argv[0], "global"))
+ {
+ /** @todo passing NULL is deprecated */
+ if (a->argc < 3)
+ CHECK_ERROR(a->virtualBox, SetExtraData(Bstr(a->argv[1]).raw(),
+ NULL));
+ else if (a->argc == 3)
+ CHECK_ERROR(a->virtualBox, SetExtraData(Bstr(a->argv[1]).raw(),
+ Bstr(a->argv[2]).raw()));
+ else
+ return errorSyntax(Misc::tr("Too many parameters"));
+ }
+ else
+ {
+ ComPtr<IMachine> machine;
+ CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()));
+ if (machine)
+ {
+ /* open an existing session for the VM */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ /* get the session machine */
+ ComPtr<IMachine> sessionMachine;
+ CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+ /** @todo passing NULL is deprecated */
+ if (a->argc < 3)
+ CHECK_ERROR(sessionMachine, SetExtraData(Bstr(a->argv[1]).raw(),
+ NULL));
+ else if (a->argc == 3)
+ CHECK_ERROR(sessionMachine, SetExtraData(Bstr(a->argv[1]).raw(),
+ Bstr(a->argv[2]).raw()));
+ else
+ return errorSyntax(Misc::tr("Too many parameters"));
+ }
+ }
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleSetProperty(HandlerArg *a)
+{
+ HRESULT hrc;
+
+ /* there must be two arguments: property name and value */
+ if (a->argc != 2)
+ return errorSyntax(Misc::tr("Incorrect number of parameters"));
+
+ ComPtr<ISystemProperties> systemProperties;
+ a->virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
+
+ if (!strcmp(a->argv[0], "machinefolder"))
+ {
+ /* reset to default? */
+ if (!strcmp(a->argv[1], "default"))
+ CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
+ else
+ CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(a->argv[1]).raw()));
+ }
+ else if (!strcmp(a->argv[0], "hwvirtexclusive"))
+ {
+ bool fHwVirtExclusive;
+
+ if (!strcmp(a->argv[1], "on"))
+ fHwVirtExclusive = true;
+ else if (!strcmp(a->argv[1], "off"))
+ fHwVirtExclusive = false;
+ else
+ return errorArgument(Misc::tr("Invalid hwvirtexclusive argument '%s'"), a->argv[1]);
+ CHECK_ERROR(systemProperties, COMSETTER(ExclusiveHwVirt)(fHwVirtExclusive));
+ }
+ else if ( !strcmp(a->argv[0], "vrdeauthlibrary")
+ || !strcmp(a->argv[0], "vrdpauthlibrary"))
+ {
+ if (!strcmp(a->argv[0], "vrdpauthlibrary"))
+ RTStrmPrintf(g_pStdErr, Misc::tr("Warning: 'vrdpauthlibrary' is deprecated. Use 'vrdeauthlibrary'.\n"));
+
+ /* reset to default? */
+ if (!strcmp(a->argv[1], "default"))
+ CHECK_ERROR(systemProperties, COMSETTER(VRDEAuthLibrary)(NULL));
+ else
+ CHECK_ERROR(systemProperties, COMSETTER(VRDEAuthLibrary)(Bstr(a->argv[1]).raw()));
+ }
+ else if (!strcmp(a->argv[0], "websrvauthlibrary"))
+ {
+ /* reset to default? */
+ if (!strcmp(a->argv[1], "default"))
+ CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));
+ else
+ CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(a->argv[1]).raw()));
+ }
+ else if (!strcmp(a->argv[0], "vrdeextpack"))
+ {
+ /* disable? */
+ if (!strcmp(a->argv[1], "null"))
+ CHECK_ERROR(systemProperties, COMSETTER(DefaultVRDEExtPack)(NULL));
+ else
+ CHECK_ERROR(systemProperties, COMSETTER(DefaultVRDEExtPack)(Bstr(a->argv[1]).raw()));
+ }
+ else if (!strcmp(a->argv[0], "loghistorycount"))
+ {
+ uint32_t uVal;
+ int vrc;
+ vrc = RTStrToUInt32Ex(a->argv[1], NULL, 0, &uVal);
+ if (vrc != VINF_SUCCESS)
+ return errorArgument(Misc::tr("Error parsing Log history count '%s'"), a->argv[1]);
+ CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));
+ }
+ else if (!strcmp(a->argv[0], "autostartdbpath"))
+ {
+ /* disable? */
+ if (!strcmp(a->argv[1], "null"))
+ CHECK_ERROR(systemProperties, COMSETTER(AutostartDatabasePath)(NULL));
+ else
+ CHECK_ERROR(systemProperties, COMSETTER(AutostartDatabasePath)(Bstr(a->argv[1]).raw()));
+ }
+ else if (!strcmp(a->argv[0], "defaultfrontend"))
+ {
+ Bstr bstrDefaultFrontend(a->argv[1]);
+ if (!strcmp(a->argv[1], "default"))
+ bstrDefaultFrontend.setNull();
+ CHECK_ERROR(systemProperties, COMSETTER(DefaultFrontend)(bstrDefaultFrontend.raw()));
+ }
+ else if (!strcmp(a->argv[0], "logginglevel"))
+ {
+ Bstr bstrLoggingLevel(a->argv[1]);
+ if (!strcmp(a->argv[1], "default"))
+ bstrLoggingLevel.setNull();
+ CHECK_ERROR(systemProperties, COMSETTER(LoggingLevel)(bstrLoggingLevel.raw()));
+ }
+ else if (!strcmp(a->argv[0], "proxymode"))
+ {
+ ProxyMode_T enmProxyMode;
+ if (!RTStrICmpAscii(a->argv[1], "system"))
+ enmProxyMode = ProxyMode_System;
+ else if (!RTStrICmpAscii(a->argv[1], "noproxy"))
+ enmProxyMode = ProxyMode_NoProxy;
+ else if (!RTStrICmpAscii(a->argv[1], "manual"))
+ enmProxyMode = ProxyMode_Manual;
+ else
+ return errorArgument(Misc::tr("Unknown proxy mode: '%s'"), a->argv[1]);
+ CHECK_ERROR(systemProperties, COMSETTER(ProxyMode)(enmProxyMode));
+ }
+ else if (!strcmp(a->argv[0], "proxyurl"))
+ {
+ Bstr bstrProxyUrl(a->argv[1]);
+ CHECK_ERROR(systemProperties, COMSETTER(ProxyURL)(bstrProxyUrl.raw()));
+ }
+#ifdef VBOX_WITH_MAIN_NLS
+ else if (!strcmp(a->argv[0], "language"))
+ {
+ Bstr bstrLanguage(a->argv[1]);
+ CHECK_ERROR(systemProperties, COMSETTER(LanguageId)(bstrLanguage.raw()));
+
+ /* Kudge alert! Make sure the language change notification is processed,
+ otherwise it may arrive as (XP)COM shuts down and cause
+ trouble in debug builds. */
+# ifdef DEBUG
+ uint64_t const tsStart = RTTimeNanoTS();
+# endif
+ unsigned cMsgs = 0;
+ int vrc;
+ while ( RT_SUCCESS(vrc = NativeEventQueue::getMainEventQueue()->processEventQueue(32 /*ms*/))
+ || vrc == VERR_INTERRUPTED)
+ cMsgs++;
+# ifdef DEBUG
+ RTPrintf("vrc=%Rrc cMsgs=%u nsElapsed=%'RU64\n", vrc, cMsgs, RTTimeNanoTS() - tsStart);
+# endif
+ }
+#endif
+ else
+ return errorSyntax(Misc::tr("Invalid parameter '%s'"), a->argv[0]);
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * sharedfolder add
+ */
+static RTEXITCODE handleSharedFolderAdd(HandlerArg *a)
+{
+ /*
+ * Parse arguments (argv[0] == subcommand).
+ */
+ static const RTGETOPTDEF s_aAddOptions[] =
+ {
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "-name", 'n', RTGETOPT_REQ_STRING }, // deprecated
+ { "--hostpath", 'p', RTGETOPT_REQ_STRING },
+ { "-hostpath", 'p', RTGETOPT_REQ_STRING }, // deprecated
+ { "--readonly", 'r', RTGETOPT_REQ_NOTHING },
+ { "-readonly", 'r', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--transient", 't', RTGETOPT_REQ_NOTHING },
+ { "-transient", 't', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--automount", 'a', RTGETOPT_REQ_NOTHING },
+ { "-automount", 'a', RTGETOPT_REQ_NOTHING }, // deprecated
+ { "--auto-mount-point", 'm', RTGETOPT_REQ_STRING },
+ };
+ const char *pszMachineName = NULL;
+ const char *pszName = NULL;
+ const char *pszHostPath = NULL;
+ bool fTransient = false;
+ bool fWritable = true;
+ bool fAutoMount = false;
+ const char *pszAutoMountPoint = "";
+
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aAddOptions, RT_ELEMENTS(s_aAddOptions), 1 /*iFirst*/, 0 /*fFlags*/);
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n':
+ pszName = ValueUnion.psz;
+ break;
+ case 'p':
+ pszHostPath = ValueUnion.psz;
+ break;
+ case 'r':
+ fWritable = false;
+ break;
+ case 't':
+ fTransient = true;
+ break;
+ case 'a':
+ fAutoMount = true;
+ break;
+ case 'm':
+ pszAutoMountPoint = ValueUnion.psz;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszMachineName)
+ return errorArgument(Misc::tr("Machine name is given more than once: first '%s', then '%s'"),
+ pszMachineName, ValueUnion.psz);
+ pszMachineName = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszMachineName)
+ return errorSyntax(Misc::tr("No machine was specified"));
+
+ if (!pszName)
+ return errorSyntax(Misc::tr("No shared folder name (--name) was given"));
+ if (strchr(pszName, ' '))
+ return errorSyntax(Misc::tr("Invalid shared folder name '%s': contains space"), pszName);
+ if (strchr(pszName, '\t'))
+ return errorSyntax(Misc::tr("Invalid shared folder name '%s': contains tabs"), pszName);
+ if (strchr(pszName, '\n') || strchr(pszName, '\r'))
+ return errorSyntax(Misc::tr("Invalid shared folder name '%s': contains newline"), pszName);
+
+ if (!pszHostPath)
+ return errorSyntax(Misc::tr("No host path (--hostpath) was given"));
+ char szAbsHostPath[RTPATH_MAX];
+ int vrc = RTPathAbs(pszHostPath, szAbsHostPath, sizeof(szAbsHostPath));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("RTAbsPath failed on '%s': %Rrc"), pszHostPath, vrc);
+
+ /*
+ * Done parsing, do some work.
+ */
+ ComPtr<IMachine> ptrMachine;
+ CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+ AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
+
+ HRESULT hrc;
+ if (fTransient)
+ {
+ /* open an existing session for the VM */
+ CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+ /* get the session machine */
+ ComPtr<IMachine> ptrSessionMachine;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /* get the session console */
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+ if (ptrConsole.isNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running."), pszMachineName);
+
+ CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
+ fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
+ a->session->UnlockMachine();
+ }
+ else
+ {
+ /* open a session for the VM */
+ CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ ComPtr<IMachine> ptrSessionMachine;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
+ fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
+ }
+
+ a->session->UnlockMachine();
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * sharedfolder remove
+ */
+static RTEXITCODE handleSharedFolderRemove(HandlerArg *a)
+{
+ /*
+ * Parse arguments (argv[0] == subcommand).
+ */
+ static const RTGETOPTDEF s_aRemoveOptions[] =
+ {
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "-name", 'n', RTGETOPT_REQ_STRING }, // deprecated
+ { "--transient", 't', RTGETOPT_REQ_NOTHING },
+ { "-transient", 't', RTGETOPT_REQ_NOTHING }, // deprecated
+ };
+ const char *pszMachineName = NULL;
+ const char *pszName = NULL;
+ bool fTransient = false;
+
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aRemoveOptions, RT_ELEMENTS(s_aRemoveOptions), 1 /*iFirst*/, 0 /*fFlags*/);
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'n':
+ pszName = ValueUnion.psz;
+ break;
+ case 't':
+ fTransient = true;
+ break;
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszMachineName)
+ return errorArgument(Misc::tr("Machine name is given more than once: first '%s', then '%s'"),
+ pszMachineName, ValueUnion.psz);
+ pszMachineName = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszMachineName)
+ return errorSyntax(Misc::tr("No machine was specified"));
+ if (!pszName)
+ return errorSyntax(Misc::tr("No shared folder name (--name) was given"));
+
+ /*
+ * Done parsing, do some real work.
+ */
+ ComPtr<IMachine> ptrMachine;
+ CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+ AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
+
+ HRESULT hrc;
+ if (fTransient)
+ {
+ /* open an existing session for the VM */
+ CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ /* get the session machine */
+ ComPtr<IMachine> ptrSessionMachine;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+ /* get the session console */
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+ if (ptrConsole.isNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
+
+ CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
+
+ a->session->UnlockMachine();
+ }
+ else
+ {
+ /* open a session for the VM */
+ CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ ComPtr<IMachine> ptrSessionMachine;
+ CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
+
+ /* commit and close the session */
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
+ }
+ a->session->UnlockMachine();
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+RTEXITCODE handleSharedFolder(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorSyntax(Misc::tr("Not enough parameters"));
+
+ if (!strcmp(a->argv[0], "add"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_ADD);
+ return handleSharedFolderAdd(a);
+ }
+
+ if (!strcmp(a->argv[0], "remove"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_REMOVE);
+ return handleSharedFolderRemove(a);
+ }
+
+ return errorUnknownSubcommand(a->argv[0]);
+}
+
+RTEXITCODE handleExtPack(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorNoSubcommand();
+
+ ComObjPtr<IExtPackManager> ptrExtPackMgr;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), RTEXITCODE_FAILURE);
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ int ch;
+ HRESULT hrc = S_OK;
+
+ if (!strcmp(a->argv[0], "install"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_EXTPACK_INSTALL);
+ const char *pszName = NULL;
+ bool fReplace = false;
+
+ static const RTGETOPTDEF s_aInstallOptions[] =
+ {
+ { "--replace", 'r', RTGETOPT_REQ_NOTHING },
+ { "--accept-license", 'a', RTGETOPT_REQ_STRING },
+ };
+
+ RTCList<RTCString> lstLicenseHashes;
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aInstallOptions, RT_ELEMENTS(s_aInstallOptions), 1, 0 /*fFlags*/);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (ch)
+ {
+ case 'r':
+ fReplace = true;
+ break;
+
+ case 'a':
+ lstLicenseHashes.append(ValueUnion.psz);
+ lstLicenseHashes[lstLicenseHashes.size() - 1].toLower();
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszName)
+ return errorSyntax(Misc::tr("Too many extension pack names given to \"extpack uninstall\""));
+ pszName = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+ if (!pszName)
+ return errorSyntax(Misc::tr("No extension pack name was given to \"extpack install\""));
+
+ char szPath[RTPATH_MAX];
+ int vrc = RTPathAbs(pszName, szPath, sizeof(szPath));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("RTPathAbs(%s,,) failed with vrc=%Rrc"), pszName, vrc);
+
+ Bstr bstrTarball(szPath);
+ Bstr bstrName;
+ ComPtr<IExtPackFile> ptrExtPackFile;
+ CHECK_ERROR2I_RET(ptrExtPackMgr, OpenExtPackFile(bstrTarball.raw(), ptrExtPackFile.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2I_RET(ptrExtPackFile, COMGETTER(Name)(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+ BOOL fShowLicense = true;
+ CHECK_ERROR2I_RET(ptrExtPackFile, COMGETTER(ShowLicense)(&fShowLicense), RTEXITCODE_FAILURE);
+ if (fShowLicense)
+ {
+ Bstr bstrLicense;
+ CHECK_ERROR2I_RET(ptrExtPackFile,
+ QueryLicense(Bstr("").raw() /* PreferredLocale */,
+ Bstr("").raw() /* PreferredLanguage */,
+ Bstr("txt").raw() /* Format */,
+ bstrLicense.asOutParam()), RTEXITCODE_FAILURE);
+ Utf8Str strLicense(bstrLicense);
+ uint8_t abHash[RTSHA256_HASH_SIZE];
+ char szDigest[RTSHA256_DIGEST_LEN + 1];
+ RTSha256(strLicense.c_str(), strLicense.length(), abHash);
+ vrc = RTSha256ToString(abHash, szDigest, sizeof(szDigest));
+ AssertRCStmt(vrc, szDigest[0] = '\0');
+ if (lstLicenseHashes.contains(szDigest))
+ RTPrintf(Misc::tr("License accepted.\n"));
+ else
+ {
+ RTPrintf("%s\n", strLicense.c_str());
+ RTPrintf(Misc::tr("Do you agree to these license terms and conditions (y/n)? "));
+ ch = RTStrmGetCh(g_pStdIn);
+ RTPrintf("\n");
+ if (ch != 'y' && ch != 'Y')
+ {
+ RTPrintf(Misc::tr("Installation of \"%ls\" aborted.\n"), bstrName.raw());
+ return RTEXITCODE_FAILURE;
+ }
+ if (szDigest[0])
+ RTPrintf(Misc::tr("License accepted. For batch installation add\n"
+ "--accept-license=%s\n"
+ "to the VBoxManage command line.\n\n"), szDigest);
+ }
+ }
+ ComPtr<IProgress> ptrProgress;
+ CHECK_ERROR2I_RET(ptrExtPackFile, Install(fReplace, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE);
+ hrc = showProgress(ptrProgress);
+ CHECK_PROGRESS_ERROR_RET(ptrProgress, (Misc::tr("Failed to install \"%s\""), szPath), RTEXITCODE_FAILURE);
+
+ RTPrintf(Misc::tr("Successfully installed \"%ls\".\n"), bstrName.raw());
+ }
+ else if (!strcmp(a->argv[0], "uninstall"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_EXTPACK_UNINSTALL);
+ const char *pszName = NULL;
+ bool fForced = false;
+
+ static const RTGETOPTDEF s_aUninstallOptions[] =
+ {
+ { "--force", 'f', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions), 1, 0);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (ch)
+ {
+ case 'f':
+ fForced = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ if (pszName)
+ return errorSyntax(Misc::tr("Too many extension pack names given to \"extpack uninstall\""));
+ pszName = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(ch, &ValueUnion);
+ }
+ }
+ if (!pszName)
+ return errorSyntax(Misc::tr("No extension pack name was given to \"extpack uninstall\""));
+
+ Bstr bstrName(pszName);
+ ComPtr<IProgress> ptrProgress;
+ CHECK_ERROR2I_RET(ptrExtPackMgr, Uninstall(bstrName.raw(), fForced, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE);
+ hrc = showProgress(ptrProgress);
+ CHECK_PROGRESS_ERROR_RET(ptrProgress, (Misc::tr("Failed to uninstall \"%s\""), pszName), RTEXITCODE_FAILURE);
+
+ RTPrintf(Misc::tr("Successfully uninstalled \"%s\".\n"), pszName);
+ }
+ else if (!strcmp(a->argv[0], "cleanup"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_EXTPACK_CLEANUP);
+ if (a->argc > 1)
+ return errorTooManyParameters(&a->argv[1]);
+ CHECK_ERROR2I_RET(ptrExtPackMgr, Cleanup(), RTEXITCODE_FAILURE);
+ RTPrintf(Misc::tr("Successfully performed extension pack cleanup\n"));
+ }
+ else
+ return errorUnknownSubcommand(a->argv[0]);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+RTEXITCODE handleUnattendedDetect(HandlerArg *a)
+{
+ HRESULT hrc;
+
+ /*
+ * Options. We work directly on an IUnattended instace while parsing
+ * the options. This saves a lot of extra clutter.
+ */
+ bool fMachineReadable = false;
+ char szIsoPath[RTPATH_MAX];
+ szIsoPath[0] = '\0';
+
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--iso", 'i', RTGETOPT_REQ_STRING },
+ { "--machine-readable", 'M', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'i': // --iso
+ vrc = RTPathAbs(ValueUnion.psz, szIsoPath, sizeof(szIsoPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ break;
+
+ case 'M': // --machine-readable.
+ fMachineReadable = true;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /*
+ * Check for required stuff.
+ */
+ if (szIsoPath[0] == '\0')
+ return errorSyntax(Misc::tr("No ISO specified"));
+
+ /*
+ * Do the job.
+ */
+ ComPtr<IUnattended> ptrUnattended;
+ CHECK_ERROR2_RET(hrc, a->virtualBox, CreateUnattendedInstaller(ptrUnattended.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(IsoPath)(Bstr(szIsoPath).raw()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2(hrc, ptrUnattended, DetectIsoOS());
+ RTEXITCODE rcExit = SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+
+ /*
+ * Retrieve the results.
+ */
+ Bstr bstrDetectedOSTypeId;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSTypeId)(bstrDetectedOSTypeId.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrDetectedVersion;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSVersion)(bstrDetectedVersion.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrDetectedFlavor;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSFlavor)(bstrDetectedFlavor.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrDetectedLanguages;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSLanguages)(bstrDetectedLanguages.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrDetectedHints;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSHints)(bstrDetectedHints.asOutParam()), RTEXITCODE_FAILURE);
+ SafeArray<BSTR> aImageNames;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedImageNames)(ComSafeArrayAsOutParam(aImageNames)), RTEXITCODE_FAILURE);
+ SafeArray<ULONG> aImageIndices;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedImageIndices)(ComSafeArrayAsOutParam(aImageIndices)), RTEXITCODE_FAILURE);
+ Assert(aImageNames.size() == aImageIndices.size());
+ BOOL fInstallSupported = FALSE;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(IsUnattendedInstallSupported)(&fInstallSupported), RTEXITCODE_FAILURE);
+
+ if (fMachineReadable)
+ {
+ outputMachineReadableString("OSTypeId", &bstrDetectedOSTypeId);
+ outputMachineReadableString("OSVersion", &bstrDetectedVersion);
+ outputMachineReadableString("OSFlavor", &bstrDetectedFlavor);
+ outputMachineReadableString("OSLanguages", &bstrDetectedLanguages);
+ outputMachineReadableString("OSHints", &bstrDetectedHints);
+ for (size_t i = 0; i < aImageNames.size(); i++)
+ {
+ Bstr const bstrName = aImageNames[i];
+ outputMachineReadableStringWithFmtName(&bstrName, false, "ImageIndex%u", aImageIndices[i]);
+ }
+ outputMachineReadableBool("IsInstallSupported", &fInstallSupported);
+ }
+ else
+ {
+ RTMsgInfo(Misc::tr("Detected '%s' to be:\n"), szIsoPath);
+ RTPrintf(Misc::tr(" OS TypeId = %ls\n"
+ " OS Version = %ls\n"
+ " OS Flavor = %ls\n"
+ " OS Languages = %ls\n"
+ " OS Hints = %ls\n"),
+ bstrDetectedOSTypeId.raw(),
+ bstrDetectedVersion.raw(),
+ bstrDetectedFlavor.raw(),
+ bstrDetectedLanguages.raw(),
+ bstrDetectedHints.raw());
+ for (size_t i = 0; i < aImageNames.size(); i++)
+ RTPrintf(" Image #%-3u = %ls\n", aImageIndices[i], aImageNames[i]);
+ if (fInstallSupported)
+ RTPrintf(Misc::tr(" Unattended installation supported = yes\n"));
+ else
+ RTPrintf(Misc::tr(" Unattended installation supported = no\n"));
+ }
+
+ return rcExit;
+}
+
+RTEXITCODE handleUnattendedInstall(HandlerArg *a)
+{
+ HRESULT hrc;
+ char szAbsPath[RTPATH_MAX];
+
+ /*
+ * Options. We work directly on an IUnattended instance while parsing
+ * the options. This saves a lot of extra clutter.
+ */
+ ComPtr<IUnattended> ptrUnattended;
+ CHECK_ERROR2_RET(hrc, a->virtualBox, CreateUnattendedInstaller(ptrUnattended.asOutParam()), RTEXITCODE_FAILURE);
+ RTCList<RTCString> arrPackageSelectionAdjustments;
+ ComPtr<IMachine> ptrMachine;
+ bool fDryRun = false;
+ const char *pszSessionType = "none";
+
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--iso", 'i', RTGETOPT_REQ_STRING },
+ { "--user", 'u', RTGETOPT_REQ_STRING },
+ { "--password", 'p', RTGETOPT_REQ_STRING },
+ { "--password-file", 'X', RTGETOPT_REQ_STRING },
+ { "--full-user-name", 'U', RTGETOPT_REQ_STRING },
+ { "--key", 'k', RTGETOPT_REQ_STRING },
+ { "--install-additions", 'A', RTGETOPT_REQ_NOTHING },
+ { "--no-install-additions", 'N', RTGETOPT_REQ_NOTHING },
+ { "--additions-iso", 'a', RTGETOPT_REQ_STRING },
+ { "--install-txs", 't', RTGETOPT_REQ_NOTHING },
+ { "--no-install-txs", 'T', RTGETOPT_REQ_NOTHING },
+ { "--validation-kit-iso", 'K', RTGETOPT_REQ_STRING },
+ { "--locale", 'l', RTGETOPT_REQ_STRING },
+ { "--country", 'Y', RTGETOPT_REQ_STRING },
+ { "--time-zone", 'z', RTGETOPT_REQ_STRING },
+ { "--proxy", 'y', RTGETOPT_REQ_STRING },
+ { "--hostname", 'H', RTGETOPT_REQ_STRING },
+ { "--package-selection-adjustment", 's', RTGETOPT_REQ_STRING },
+ { "--dry-run", 'D', RTGETOPT_REQ_NOTHING },
+ // advance options:
+ { "--auxiliary-base-path", 'x', RTGETOPT_REQ_STRING },
+ { "--image-index", 'm', RTGETOPT_REQ_UINT32 },
+ { "--script-template", 'c', RTGETOPT_REQ_STRING },
+ { "--post-install-template", 'C', RTGETOPT_REQ_STRING },
+ { "--post-install-command", 'P', RTGETOPT_REQ_STRING },
+ { "--extra-install-kernel-parameters", 'I', RTGETOPT_REQ_STRING },
+ { "--language", 'L', RTGETOPT_REQ_STRING },
+ // start vm related options:
+ { "--start-vm", 'S', RTGETOPT_REQ_STRING },
+ /** @todo Add a --wait option too for waiting for the VM to shut down or
+ * something like that...? */
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case VINF_GETOPT_NOT_OPTION:
+ if (ptrMachine.isNotNull())
+ return errorSyntax(Misc::tr("VM name/UUID given more than once!"));
+ CHECK_ERROR2_RET(hrc, a->virtualBox, FindMachine(Bstr(ValueUnion.psz).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Machine)(ptrMachine), RTEXITCODE_FAILURE);
+ break;
+
+ case 'i': // --iso
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(IsoPath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'u': // --user
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(User)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'p': // --password
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Password)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'X': // --password-file
+ {
+ Utf8Str strPassword;
+ RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &strPassword);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ return rcExit;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Password)(Bstr(strPassword).raw()), RTEXITCODE_FAILURE);
+ break;
+ }
+
+ case 'U': // --full-user-name
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(FullUserName)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'k': // --key
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ProductKey)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'A': // --install-additions
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(InstallGuestAdditions)(TRUE), RTEXITCODE_FAILURE);
+ break;
+ case 'N': // --no-install-additions
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(InstallGuestAdditions)(FALSE), RTEXITCODE_FAILURE);
+ break;
+ case 'a': // --additions-iso
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(AdditionsIsoPath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 't': // --install-txs
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(InstallTestExecService)(TRUE), RTEXITCODE_FAILURE);
+ break;
+ case 'T': // --no-install-txs
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(InstallTestExecService)(FALSE), RTEXITCODE_FAILURE);
+ break;
+ case 'K': // --valiation-kit-iso
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ValidationKitIsoPath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'l': // --locale
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Locale)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'Y': // --country
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Country)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'z': // --time-zone;
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(TimeZone)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'y': // --proxy
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Proxy)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'H': // --hostname
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Hostname)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 's': // --package-selection-adjustment
+ arrPackageSelectionAdjustments.append(ValueUnion.psz);
+ break;
+
+ case 'D':
+ fDryRun = true;
+ break;
+
+ case 'x': // --auxiliary-base-path
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(AuxiliaryBasePath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'm': // --image-index
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ImageIndex)(ValueUnion.u32), RTEXITCODE_FAILURE);
+ break;
+
+ case 'c': // --script-template
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ScriptTemplatePath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'C': // --post-install-script-template
+ vrc = RTPathAbs(ValueUnion.psz, szAbsPath, sizeof(szAbsPath));
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Misc::tr("RTPathAbs failed on '%s': %Rrc"), ValueUnion.psz, vrc);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(PostInstallScriptTemplatePath)(Bstr(szAbsPath).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'P': // --post-install-command.
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(PostInstallCommand)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'I': // --extra-install-kernel-parameters
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ExtraInstallKernelParameters)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'L': // --language
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Language)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
+ break;
+
+ case 'S': // --start-vm
+ pszSessionType = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /*
+ * Check for required stuff.
+ */
+ if (ptrMachine.isNull())
+ return errorSyntax(Misc::tr("Missing VM name/UUID"));
+
+ /*
+ * Set accumulative attributes.
+ */
+ if (arrPackageSelectionAdjustments.size() == 1)
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(PackageSelectionAdjustments)(Bstr(arrPackageSelectionAdjustments[0]).raw()),
+ RTEXITCODE_FAILURE);
+ else if (arrPackageSelectionAdjustments.size() > 1)
+ {
+ RTCString strAdjustments;
+ strAdjustments.join(arrPackageSelectionAdjustments, ";");
+ CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(PackageSelectionAdjustments)(Bstr(strAdjustments).raw()), RTEXITCODE_FAILURE);
+ }
+
+ /*
+ * Get details about the machine so we can display them below.
+ */
+ Bstr bstrMachineName;
+ CHECK_ERROR2_RET(hrc, ptrMachine, COMGETTER(Name)(bstrMachineName.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrUuid;
+ CHECK_ERROR2_RET(hrc, ptrMachine, COMGETTER(Id)(bstrUuid.asOutParam()), RTEXITCODE_FAILURE);
+ BSTR bstrInstalledOS;
+ CHECK_ERROR2_RET(hrc, ptrMachine, COMGETTER(OSTypeId)(&bstrInstalledOS), RTEXITCODE_FAILURE);
+ Utf8Str strInstalledOS(bstrInstalledOS);
+
+ /*
+ * Temporarily lock the machine to check whether it's running or not.
+ * We take this opportunity to disable the first run wizard.
+ */
+ CHECK_ERROR2_RET(hrc, ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ {
+ ComPtr<IConsole> ptrConsole;
+ CHECK_ERROR2(hrc, a->session, COMGETTER(Console)(ptrConsole.asOutParam()));
+
+ if ( ptrConsole.isNull()
+ && SUCCEEDED(hrc)
+ && ( RTStrICmp(pszSessionType, "gui") == 0
+ || RTStrICmp(pszSessionType, "none") == 0))
+ {
+ ComPtr<IMachine> ptrSessonMachine;
+ CHECK_ERROR2(hrc, a->session, COMGETTER(Machine)(ptrSessonMachine.asOutParam()));
+ if (ptrSessonMachine.isNotNull())
+ {
+ CHECK_ERROR2(hrc, ptrSessonMachine, SetExtraData(Bstr("GUI/FirstRun").raw(), Bstr("0").raw()));
+ }
+ }
+
+ a->session->UnlockMachine();
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ if (ptrConsole.isNotNull())
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%ls' is currently running"), bstrMachineName.raw());
+ }
+
+ /*
+ * Do the work.
+ */
+ RTMsgInfo(Misc::tr("%s unattended installation of %s in machine '%ls' (%ls).\n"),
+ RTStrICmp(pszSessionType, "none") == 0 ? Misc::tr("Preparing") : Misc::tr("Starting"),
+ strInstalledOS.c_str(), bstrMachineName.raw(), bstrUuid.raw());
+
+ CHECK_ERROR2_RET(hrc, ptrUnattended,Prepare(), RTEXITCODE_FAILURE);
+ if (!fDryRun)
+ {
+ CHECK_ERROR2_RET(hrc, ptrUnattended, ConstructMedia(), RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc, ptrUnattended, ReconfigureVM(), RTEXITCODE_FAILURE);
+ }
+
+ /*
+ * Retrieve and display the parameters actually used.
+ */
+ RTMsgInfo(Misc::tr("Using values:\n"));
+#define SHOW_ATTR(a_Attr, a_szText, a_Type, a_szFmt) do { \
+ a_Type Value; \
+ HRESULT hrc2 = ptrUnattended->COMGETTER(a_Attr)(&Value); \
+ if (SUCCEEDED(hrc2)) \
+ RTPrintf(" %32s = " a_szFmt "\n", a_szText, Value); \
+ else \
+ RTPrintf(Misc::tr(" %32s = failed: %Rhrc\n"), a_szText, hrc2); \
+ } while (0)
+#define SHOW_STR_ATTR(a_Attr, a_szText) do { \
+ Bstr bstrString; \
+ HRESULT hrc2 = ptrUnattended->COMGETTER(a_Attr)(bstrString.asOutParam()); \
+ if (SUCCEEDED(hrc2)) \
+ RTPrintf(" %32s = %ls\n", a_szText, bstrString.raw()); \
+ else \
+ RTPrintf(Misc::tr(" %32s = failed: %Rhrc\n"), a_szText, hrc2); \
+ } while (0)
+
+ SHOW_STR_ATTR(IsoPath, "isoPath");
+ SHOW_STR_ATTR(User, "user");
+ SHOW_STR_ATTR(Password, "password");
+ SHOW_STR_ATTR(FullUserName, "fullUserName");
+ SHOW_STR_ATTR(ProductKey, "productKey");
+ SHOW_STR_ATTR(AdditionsIsoPath, "additionsIsoPath");
+ SHOW_ATTR( InstallGuestAdditions, "installGuestAdditions", BOOL, "%RTbool");
+ SHOW_STR_ATTR(ValidationKitIsoPath, "validationKitIsoPath");
+ SHOW_ATTR( InstallTestExecService, "installTestExecService", BOOL, "%RTbool");
+ SHOW_STR_ATTR(Locale, "locale");
+ SHOW_STR_ATTR(Country, "country");
+ SHOW_STR_ATTR(TimeZone, "timeZone");
+ SHOW_STR_ATTR(Proxy, "proxy");
+ SHOW_STR_ATTR(Hostname, "hostname");
+ SHOW_STR_ATTR(PackageSelectionAdjustments, "packageSelectionAdjustments");
+ SHOW_STR_ATTR(AuxiliaryBasePath, "auxiliaryBasePath");
+ SHOW_ATTR( ImageIndex, "imageIndex", ULONG, "%u");
+ SHOW_STR_ATTR(ScriptTemplatePath, "scriptTemplatePath");
+ SHOW_STR_ATTR(PostInstallScriptTemplatePath, "postInstallScriptTemplatePath");
+ SHOW_STR_ATTR(PostInstallCommand, "postInstallCommand");
+ SHOW_STR_ATTR(ExtraInstallKernelParameters, "extraInstallKernelParameters");
+ SHOW_STR_ATTR(Language, "language");
+ SHOW_STR_ATTR(DetectedOSTypeId, "detectedOSTypeId");
+ SHOW_STR_ATTR(DetectedOSVersion, "detectedOSVersion");
+ SHOW_STR_ATTR(DetectedOSFlavor, "detectedOSFlavor");
+ SHOW_STR_ATTR(DetectedOSLanguages, "detectedOSLanguages");
+ SHOW_STR_ATTR(DetectedOSHints, "detectedOSHints");
+ {
+ ULONG idxImage = 0;
+ HRESULT hrc2 = ptrUnattended->COMGETTER(ImageIndex)(&idxImage);
+ if (FAILED(hrc2))
+ idxImage = 0;
+ SafeArray<BSTR> aImageNames;
+ hrc2 = ptrUnattended->COMGETTER(DetectedImageNames)(ComSafeArrayAsOutParam(aImageNames));
+ if (SUCCEEDED(hrc2))
+ {
+ SafeArray<ULONG> aImageIndices;
+ hrc2 = ptrUnattended->COMGETTER(DetectedImageIndices)(ComSafeArrayAsOutParam(aImageIndices));
+ if (SUCCEEDED(hrc2))
+ {
+ Assert(aImageNames.size() == aImageIndices.size());
+ for (size_t i = 0; i < aImageNames.size(); i++)
+ {
+ char szTmp[64];
+ RTStrPrintf(szTmp, sizeof(szTmp), "detectedImage[%u]%s", i, idxImage != aImageIndices[i] ? "" : "*");
+ RTPrintf(" %32s = #%u: %ls\n", szTmp, aImageIndices[i], aImageNames[i]);
+ }
+ }
+ else
+ RTPrintf(Misc::tr(" %32s = failed: %Rhrc\n"), "detectedImageIndices", hrc2);
+ }
+ else
+ RTPrintf(Misc::tr(" %32 = failed: %Rhrc\n"), "detectedImageNames", hrc2);
+ }
+
+#undef SHOW_STR_ATTR
+#undef SHOW_ATTR
+
+ /* We can drop the IUnatteded object now. */
+ ptrUnattended.setNull();
+
+ /*
+ * Start the VM if requested.
+ */
+ if ( fDryRun
+ || RTStrICmp(pszSessionType, "none") == 0)
+ {
+ if (!fDryRun)
+ RTMsgInfo(Misc::tr("VM '%ls' (%ls) is ready to be started (e.g. VBoxManage startvm).\n"), bstrMachineName.raw(), bstrUuid.raw());
+ hrc = S_OK;
+ }
+ else
+ {
+ com::SafeArray<IN_BSTR> aBstrEnv;
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
+ /* make sure the VM process will start on the same display as VBoxManage */
+ const char *pszDisplay = RTEnvGet("DISPLAY");
+ if (pszDisplay)
+ aBstrEnv.push_back(BstrFmt("DISPLAY=%s", pszDisplay).raw());
+ const char *pszXAuth = RTEnvGet("XAUTHORITY");
+ if (pszXAuth)
+ aBstrEnv.push_back(BstrFmt("XAUTHORITY=%s", pszXAuth).raw());
+#endif
+ ComPtr<IProgress> ptrProgress;
+ CHECK_ERROR2(hrc, ptrMachine, LaunchVMProcess(a->session, Bstr(pszSessionType).raw(), ComSafeArrayAsInParam(aBstrEnv), ptrProgress.asOutParam()));
+ if (SUCCEEDED(hrc) && !ptrProgress.isNull())
+ {
+ RTMsgInfo(Misc::tr("Waiting for VM '%ls' to power on...\n"), bstrMachineName.raw());
+ CHECK_ERROR2(hrc, ptrProgress, WaitForCompletion(-1));
+ if (SUCCEEDED(hrc))
+ {
+ BOOL fCompleted = true;
+ CHECK_ERROR2(hrc, ptrProgress, COMGETTER(Completed)(&fCompleted));
+ if (SUCCEEDED(hrc))
+ {
+ ASSERT(fCompleted);
+
+ LONG iRc;
+ CHECK_ERROR2(hrc, ptrProgress, COMGETTER(ResultCode)(&iRc));
+ if (SUCCEEDED(hrc))
+ {
+ if (SUCCEEDED(iRc))
+ RTMsgInfo(Misc::tr("VM '%ls' (%ls) has been successfully started.\n"),
+ bstrMachineName.raw(), bstrUuid.raw());
+ else
+ {
+ ProgressErrorInfo info(ptrProgress);
+ com::GluePrintErrorInfo(info);
+ }
+ hrc = iRc;
+ }
+ }
+ }
+ }
+
+ /*
+ * Do we wait for the VM to power down?
+ */
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+RTEXITCODE handleUnattended(HandlerArg *a)
+{
+ /*
+ * Sub-command switch.
+ */
+ if (a->argc < 1)
+ return errorNoSubcommand();
+
+ if (!strcmp(a->argv[0], "detect"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_UNATTENDED_DETECT);
+ return handleUnattendedDetect(a);
+ }
+
+ if (!strcmp(a->argv[0], "install"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_UNATTENDED_INSTALL);
+ return handleUnattendedInstall(a);
+ }
+
+ /* Consider some kind of create-vm-and-install-guest-os command. */
+ return errorUnknownSubcommand(a->argv[0]);
+}
+
+/**
+ * Common Cloud profile options.
+ */
+typedef struct
+{
+ const char *pszProviderName;
+ const char *pszProfileName;
+} CLOUDPROFILECOMMONOPT;
+typedef CLOUDPROFILECOMMONOPT *PCLOUDPROFILECOMMONOPT;
+
+/**
+ * Sets the properties of cloud profile
+ *
+ * @returns 0 on success, 1 on failure
+ */
+
+static RTEXITCODE setCloudProfileProperties(HandlerArg *a, int iFirst, PCLOUDPROFILECOMMONOPT pCommonOpts)
+{
+
+ HRESULT hrc = S_OK;
+
+ Bstr bstrProvider(pCommonOpts->pszProviderName);
+ Bstr bstrProfile(pCommonOpts->pszProfileName);
+
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--clouduser", 'u', RTGETOPT_REQ_STRING },
+ { "--fingerprint", 'p', RTGETOPT_REQ_STRING },
+ { "--keyfile", 'k', RTGETOPT_REQ_STRING },
+ { "--passphrase", 'P', RTGETOPT_REQ_STRING },
+ { "--tenancy", 't', RTGETOPT_REQ_STRING },
+ { "--compartment", 'c', RTGETOPT_REQ_STRING },
+ { "--region", 'r', RTGETOPT_REQ_STRING }
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'u': // --clouduser
+ Bstr("user").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'p': // --fingerprint
+ Bstr("fingerprint").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'k': // --keyfile
+ Bstr("key_file").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'P': // --passphrase
+ Bstr("pass_phrase").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 't': // --tenancy
+ Bstr("tenancy").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'c': // --compartment
+ Bstr("compartment").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'r': // --region
+ Bstr("region").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /* check for required options */
+ if (bstrProvider.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --provider is required"));
+ if (bstrProfile.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --profile is required"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+
+ if (pCloudProvider)
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(bstrProfile.raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ SetProperties(ComSafeArrayAsInParam(names), ComSafeArrayAsInParam(values)),
+ RTEXITCODE_FAILURE);
+ }
+
+ CHECK_ERROR2(hrc, pCloudProvider, SaveProfiles());
+
+ RTPrintf(Misc::tr("Provider %ls: profile '%ls' was updated.\n"),bstrProvider.raw(), bstrProfile.raw());
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/**
+ * Gets the properties of cloud profile
+ *
+ * @returns 0 on success, 1 on failure
+ */
+static RTEXITCODE showCloudProfileProperties(HandlerArg *a, PCLOUDPROFILECOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ Bstr bstrProvider(pCommonOpts->pszProviderName);
+ Bstr bstrProfile(pCommonOpts->pszProfileName);
+
+ /* check for required options */
+ if (bstrProvider.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --provider is required"));
+ if (bstrProfile.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --profile is required"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ if (pCloudProvider)
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(bstrProfile.raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ Bstr bstrProviderID;
+ pCloudProfile->COMGETTER(ProviderId)(bstrProviderID.asOutParam());
+ RTPrintf(Misc::tr("Provider GUID: %ls\n"), bstrProviderID.raw());
+
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ GetProperties(Bstr().raw(), ComSafeArrayAsOutParam(names), ComSafeArrayAsOutParam(values)),
+ RTEXITCODE_FAILURE);
+ 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 ? Misc::tr("Property: ") : " ",
+ names[k], value.raw());
+ fFirst = false;
+ }
+
+ RTPrintf("\n");
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE addCloudProfile(HandlerArg *a, int iFirst, PCLOUDPROFILECOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ Bstr bstrProvider(pCommonOpts->pszProviderName);
+ Bstr bstrProfile(pCommonOpts->pszProfileName);
+
+
+ /* check for required options */
+ if (bstrProvider.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --provider is required"));
+ if (bstrProfile.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --profile is required"));
+
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--clouduser", 'u', RTGETOPT_REQ_STRING },
+ { "--fingerprint", 'p', RTGETOPT_REQ_STRING },
+ { "--keyfile", 'k', RTGETOPT_REQ_STRING },
+ { "--passphrase", 'P', RTGETOPT_REQ_STRING },
+ { "--tenancy", 't', RTGETOPT_REQ_STRING },
+ { "--compartment", 'c', RTGETOPT_REQ_STRING },
+ { "--region", 'r', RTGETOPT_REQ_STRING }
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'u': // --clouduser
+ Bstr("user").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'p': // --fingerprint
+ Bstr("fingerprint").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'k': // --keyfile
+ Bstr("key_file").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'P': // --passphrase
+ Bstr("pass_phrase").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 't': // --tenancy
+ Bstr("tenancy").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'c': // --compartment
+ Bstr("compartment").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ case 'r': // --region
+ Bstr("region").detachTo(names.appendedRaw());
+ Bstr(ValueUnion.psz).detachTo(values.appendedRaw());
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ CreateProfile(bstrProfile.raw(),
+ ComSafeArrayAsInParam(names),
+ ComSafeArrayAsInParam(values)),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2(hrc, pCloudProvider, SaveProfiles());
+
+ RTPrintf(Misc::tr("Provider %ls: profile '%ls' was added.\n"),bstrProvider.raw(), bstrProfile.raw());
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE deleteCloudProfile(HandlerArg *a, PCLOUDPROFILECOMMONOPT pCommonOpts)
+{
+ HRESULT hrc = S_OK;
+
+ Bstr bstrProvider(pCommonOpts->pszProviderName);
+ Bstr bstrProfile(pCommonOpts->pszProfileName);
+
+ /* check for required options */
+ if (bstrProvider.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --provider is required"));
+ if (bstrProfile.isEmpty())
+ return errorSyntax(Misc::tr("Parameter --profile is required"));
+
+ ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+ ComPtr<ICloudProviderManager> pCloudProviderManager;
+ CHECK_ERROR2_RET(hrc, pVirtualBox,
+ COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
+ RTEXITCODE_FAILURE);
+ ComPtr<ICloudProvider> pCloudProvider;
+ CHECK_ERROR2_RET(hrc, pCloudProviderManager,
+ GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ ComPtr<ICloudProfile> pCloudProfile;
+ if (pCloudProvider)
+ {
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ GetProfileByName(bstrProfile.raw(), pCloudProfile.asOutParam()),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc, pCloudProfile,
+ Remove(),
+ RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2_RET(hrc, pCloudProvider,
+ SaveProfiles(),
+ RTEXITCODE_FAILURE);
+
+ RTPrintf(Misc::tr("Provider %ls: profile '%ls' was deleted.\n"), bstrProvider.raw(), bstrProfile.raw());
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleCloudProfile(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorNoSubcommand();
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--provider", 'v', RTGETOPT_REQ_STRING },
+ { "--profile", 'f', RTGETOPT_REQ_STRING },
+ /* subcommands */
+ { "add", 1000, RTGETOPT_REQ_NOTHING },
+ { "show", 1001, RTGETOPT_REQ_NOTHING },
+ { "update", 1002, RTGETOPT_REQ_NOTHING },
+ { "delete", 1003, RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ CLOUDPROFILECOMMONOPT CommonOpts = { NULL, NULL };
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'v': // --provider
+ CommonOpts.pszProviderName = ValueUnion.psz;
+ break;
+ case 'f': // --profile
+ CommonOpts.pszProfileName = ValueUnion.psz;
+ break;
+ /* Sub-commands: */
+ case 1000:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDPROFILE_ADD);
+ return addCloudProfile(a, GetState.iNext, &CommonOpts);
+ case 1001:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDPROFILE_SHOW);
+ return showCloudProfileProperties(a, &CommonOpts);
+ case 1002:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDPROFILE_UPDATE);
+ return setCloudProfileProperties(a, GetState.iNext, &CommonOpts);
+ case 1003:
+ setCurrentSubcommand(HELP_SCOPE_CLOUDPROFILE_DELETE);
+ return deleteCloudProfile(a, &CommonOpts);
+ case VINF_GETOPT_NOT_OPTION:
+ return errorUnknownSubcommand(ValueUnion.psz);
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ return errorNoSubcommand();
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageModifyNvram.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageModifyNvram.cpp
new file mode 100644
index 00000000..d36bed08
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageModifyNvram.cpp
@@ -0,0 +1,582 @@
+/* $Id: VBoxManageModifyNvram.cpp $ */
+/** @file
+ * VBoxManage - The nvram control related commands.
+ */
+
+/*
+ * Copyright (C) 2021-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/errcore.h>
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#include <iprt/stream.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/uuid.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Nvram);
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Handles the 'modifynvram myvm inituefivarstore' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramInitUefiVarStore(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ RT_NOREF(a);
+
+ CHECK_ERROR2I_RET(nvramStore, InitUefiVariableStore(0 /*aSize*/), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm enrollmssignatures' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramEnrollMsSignatures(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ RT_NOREF(a);
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2I_RET(uefiVarStore, EnrollDefaultMsSignatures(), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Helper for handleModifyNvramEnrollPlatformKey() and handleModifyNvramEnrollMok().
+ *
+ * This function reads key from file and enrolls it either as a PK (Platform Key)
+ * or as a MOK (Machine Owner Key).
+ *
+ * @returns Exit code.
+ * @param pszKey Path to a file which contains the key.
+ * @param pszOwnerUuid Owner's UUID.
+ * @param nvramStore Reference to the NVRAM store interface.
+ * @param fPk If True, a key will be enrolled as a PK, otherwise as a MOK.
+ */
+static RTEXITCODE handleModifyNvramEnrollPlatformKeyOrMok(const char *pszKey, const char *pszOwnerUuid,
+ ComPtr<INvramStore> &nvramStore, bool fPk)
+{
+ RTFILE hKeyFile;
+
+ int vrc = RTFileOpen(&hKeyFile, pszKey, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_SUCCESS(vrc))
+ {
+ uint64_t cbSize;
+ vrc = RTFileQuerySize(hKeyFile, &cbSize);
+ if (RT_SUCCESS(vrc))
+ {
+ if (cbSize <= _32K)
+ {
+ SafeArray<BYTE> aKey((size_t)cbSize);
+ vrc = RTFileRead(hKeyFile, aKey.raw(), (size_t)cbSize, NULL);
+ if (RT_SUCCESS(vrc))
+ {
+ RTFileClose(hKeyFile);
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+ if (fPk)
+ CHECK_ERROR2I_RET(uefiVarStore, EnrollPlatformKey(ComSafeArrayAsInParam(aKey), Bstr(pszOwnerUuid).raw()), RTEXITCODE_FAILURE);
+ else
+ CHECK_ERROR2I_RET(uefiVarStore, AddSignatureToMok(ComSafeArrayAsInParam(aKey), Bstr(pszOwnerUuid).raw(), SignatureType_X509), RTEXITCODE_FAILURE);
+
+ return RTEXITCODE_SUCCESS;
+ }
+ else
+ RTMsgError(Nvram::tr("Cannot read contents of file \"%s\": %Rrc"), pszKey, vrc);
+ }
+ else
+ RTMsgError(Nvram::tr("File \"%s\" is bigger than 32KByte"), pszKey);
+ }
+ else
+ RTMsgError(Nvram::tr("Cannot get size of file \"%s\": %Rrc"), pszKey, vrc);
+
+ RTFileClose(hKeyFile);
+ }
+ else
+ RTMsgError(Nvram::tr("Cannot open file \"%s\": %Rrc"), pszKey, vrc);
+
+ return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm enrollpk' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvramStore Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramEnrollPlatformKey(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--platform-key", 'p', RTGETOPT_REQ_STRING },
+ { "--owner-uuid", 'f', RTGETOPT_REQ_STRING }
+ };
+
+ const char *pszPlatformKey = NULL;
+ const char *pszOwnerUuid = NULL;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'p':
+ pszPlatformKey = ValueUnion.psz;
+ break;
+ case 'f':
+ pszOwnerUuid = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszPlatformKey)
+ return errorSyntax(Nvram::tr("No platform key file path was given to \"enrollpk\""));
+ if (!pszOwnerUuid)
+ return errorSyntax(Nvram::tr("No owner UUID was given to \"enrollpk\""));
+
+ return handleModifyNvramEnrollPlatformKeyOrMok(pszPlatformKey, pszOwnerUuid, nvramStore, true /* fPk */);
+}
+
+
+/**
+ * Handles the 'modifynvram myvm enrollmok' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvramStore Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramEnrollMok(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--mok", 'p', RTGETOPT_REQ_STRING },
+ { "--owner-uuid", 'f', RTGETOPT_REQ_STRING }
+ };
+
+ const char *pszMok = NULL;
+ const char *pszOwnerUuid = NULL;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'p':
+ pszMok = ValueUnion.psz;
+ break;
+ case 'f':
+ pszOwnerUuid = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszMok)
+ return errorSyntax(Nvram::tr("No machine owner key file path was given to \"enrollpk\""));
+ if (!pszOwnerUuid)
+ return errorSyntax(Nvram::tr("No owner UUID was given to \"enrollpk\""));
+
+ return handleModifyNvramEnrollPlatformKeyOrMok(pszMok, pszOwnerUuid, nvramStore, false /* fPk */);
+}
+
+
+/**
+ * Handles the 'modifynvram myvm enrollorclpk' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramEnrollOraclePlatformKey(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ RT_NOREF(a);
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+
+ CHECK_ERROR2I_RET(uefiVarStore, EnrollOraclePlatformKey(), RTEXITCODE_FAILURE);
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm listvars' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramListUefiVars(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ RT_NOREF(a);
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+
+ com::SafeArray<BSTR> aNames;
+ com::SafeArray<BSTR> aOwnerGuids;
+ CHECK_ERROR2I_RET(uefiVarStore, QueryVariables(ComSafeArrayAsOutParam(aNames), ComSafeArrayAsOutParam(aOwnerGuids)), RTEXITCODE_FAILURE);
+ for (size_t i = 0; i < aNames.size(); i++)
+ {
+ Bstr strName = aNames[i];
+ Bstr strOwnerGuid = aOwnerGuids[i];
+
+ RTPrintf("%-32ls {%ls}\n", strName.raw(), strOwnerGuid.raw());
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm queryvar' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramQueryUefiVar(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--filename", 'f', RTGETOPT_REQ_STRING }
+ };
+
+ const char *pszVarName = NULL;
+ const char *pszVarDataFilename = NULL;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ pszVarName = ValueUnion.psz;
+ break;
+ case 'f':
+ pszVarDataFilename = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszVarName)
+ return errorSyntax(Nvram::tr("No variable name was given to \"queryvar\""));
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+
+ Bstr strOwnerGuid;
+ com::SafeArray<UefiVariableAttributes_T> aVarAttrs;
+ com::SafeArray<BYTE> aData;
+ CHECK_ERROR2I_RET(uefiVarStore, QueryVariableByName(Bstr(pszVarName).raw(), strOwnerGuid.asOutParam(),
+ ComSafeArrayAsOutParam(aVarAttrs), ComSafeArrayAsOutParam(aData)),
+ RTEXITCODE_FAILURE);
+
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ if (!pszVarDataFilename)
+ {
+ RTPrintf("%s {%ls}:\n"
+ "%.*Rhxd\n", pszVarName, strOwnerGuid.raw(), aData.size(), aData.raw());
+ }
+ else
+ {
+ /* Just write the data to the file. */
+ RTFILE hFile = NIL_RTFILE;
+ vrc = RTFileOpen(&hFile, pszVarDataFilename, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = RTFileWrite(hFile, aData.raw(), aData.size(), NULL /*pcbWritten*/);
+ if (RT_FAILURE(vrc))
+ rcExit = RTMsgErrorExitFailure(Nvram::tr("Error writing to '%s': %Rrc"), pszVarDataFilename, vrc);
+
+ RTFileClose(hFile);
+ }
+ else
+ rcExit = RTMsgErrorExitFailure(Nvram::tr("Error opening '%s': %Rrc"), pszVarDataFilename, vrc);
+ }
+
+ return rcExit;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm deletevar' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramDeleteUefiVar(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--owner-uuid", 'f', RTGETOPT_REQ_STRING }
+ };
+
+ const char *pszVarName = NULL;
+ const char *pszOwnerUuid = NULL;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ pszVarName = ValueUnion.psz;
+ break;
+ case 'f':
+ pszOwnerUuid = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszVarName)
+ return errorSyntax(Nvram::tr("No variable name was given to \"deletevar\""));
+ if (!pszOwnerUuid)
+ return errorSyntax(Nvram::tr("No owner UUID was given to \"deletevar\""));
+
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2I_RET(uefiVarStore, DeleteVariable(Bstr(pszVarName).raw(), Bstr(pszOwnerUuid).raw()), RTEXITCODE_FAILURE);
+
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Handles the 'modifynvram myvm changevar' sub-command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ * @param nvram Reference to the NVRAM store interface.
+ */
+static RTEXITCODE handleModifyNvramChangeUefiVar(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
+{
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ /* common options */
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--filename", 'f', RTGETOPT_REQ_STRING }
+ };
+
+ const char *pszVarName = NULL;
+ const char *pszVarDataFilename = NULL;
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n':
+ pszVarName = ValueUnion.psz;
+ break;
+ case 'f':
+ pszVarDataFilename = ValueUnion.psz;
+ break;
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pszVarName)
+ return errorSyntax(Nvram::tr("No variable name was given to \"changevar\""));
+ if (!pszVarDataFilename)
+ return errorSyntax(Nvram::tr("No variable data filename was given to \"changevar\""));
+
+ RTFILE hFile = NIL_RTFILE;
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ vrc = RTFileOpen(&hFile, pszVarDataFilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
+ if (RT_SUCCESS(vrc))
+ {
+ uint64_t cbFile = 0;
+ vrc = RTFileQuerySize(hFile, &cbFile);
+ if (RT_SUCCESS(vrc))
+ {
+ com::SafeArray<BYTE> aData;
+ aData.resize(cbFile);
+
+ vrc = RTFileRead(hFile, aData.raw(), aData.size(), NULL /*pcbRead*/);
+ RTFileClose(hFile);
+
+ if (RT_SUCCESS(vrc))
+ {
+ ComPtr<IUefiVariableStore> uefiVarStore;
+ CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR2I_RET(uefiVarStore, ChangeVariable(Bstr(pszVarName).raw(), ComSafeArrayAsInParam(aData)), RTEXITCODE_FAILURE);
+ }
+ else
+ rcExit = RTMsgErrorExitFailure(Nvram::tr("Error reading from '%s': %Rrc"), pszVarDataFilename, vrc);
+ }
+ }
+ else
+ rcExit = RTMsgErrorExitFailure(Nvram::tr("Error opening '%s': %Rrc"), pszVarDataFilename, vrc);
+
+ return rcExit;
+}
+
+
+/**
+ * Handles the 'modifynvram' command.
+ * @returns Exit code.
+ * @param a The handler argument package.
+ */
+RTEXITCODE handleModifyNvram(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ ComPtr<IMachine> machine;
+ ComPtr<INvramStore> nvramStore;
+
+ if (a->argc < 2)
+ return errorNoSubcommand();
+
+ /* try to find the given machine */
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /* open a session for the VM (new or shared) */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+ hrc = machine->COMGETTER(NonVolatileStore)(nvramStore.asOutParam());
+ if (FAILED(hrc)) goto leave;
+
+ if (!strcmp(a->argv[1], "inituefivarstore"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_INITUEFIVARSTORE);
+ hrc = handleModifyNvramInitUefiVarStore(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "enrollmssignatures"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_ENROLLMSSIGNATURES);
+ hrc = handleModifyNvramEnrollMsSignatures(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "enrollpk"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_ENROLLPK);
+ hrc = handleModifyNvramEnrollPlatformKey(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "enrollmok"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_ENROLLMOK);
+ hrc = handleModifyNvramEnrollMok(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "enrollorclpk"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_ENROLLORCLPK);
+ hrc = handleModifyNvramEnrollOraclePlatformKey(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "listvars"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_LISTVARS);
+ hrc = handleModifyNvramListUefiVars(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "queryvar"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_QUERYVAR);
+ hrc = handleModifyNvramQueryUefiVar(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "deletevar"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_DELETEVAR);
+ hrc = handleModifyNvramDeleteUefiVar(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "changevar"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_MODIFYNVRAM_CHANGEVAR);
+ hrc = handleModifyNvramChangeUefiVar(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else
+ return errorUnknownSubcommand(a->argv[0]);
+
+ /* commit changes */
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+
+leave:
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
new file mode 100644
index 00000000..4a360725
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
@@ -0,0 +1,3646 @@
+/* $Id: VBoxManageModifyVM.cpp $ */
+/** @file
+ * VBoxManage - Implementation of modifyvm 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/cidr.h>
+#include <iprt/ctype.h>
+#include <iprt/file.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/getopt.h>
+#include <VBox/log.h>
+#include "VBoxManage.h"
+#include "VBoxManageUtils.h"
+
+DECLARE_TRANSLATION_CONTEXT(ModifyVM);
+
+using namespace com;
+/** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */
+#if defined(_MSC_VER)
+# pragma optimize("g", off)
+# if _MSC_VER < RT_MSC_VER_VC120
+# pragma warning(disable:4748)
+# endif
+#endif
+
+enum
+{
+ MODIFYVM_NAME = 1000,
+ MODIFYVM_GROUPS,
+ MODIFYVM_DESCRIPTION,
+ MODIFYVM_OSTYPE,
+ MODIFYVM_ICONFILE,
+ MODIFYVM_MEMORY,
+ MODIFYVM_PAGEFUSION,
+ MODIFYVM_VRAM,
+ MODIFYVM_FIRMWARE,
+ MODIFYVM_ACPI,
+ MODIFYVM_IOAPIC,
+ MODIFYVM_PAE,
+ MODIFYVM_LONGMODE,
+ MODIFYVM_CPUID_PORTABILITY,
+ MODIFYVM_TFRESET,
+ MODIFYVM_APIC,
+ MODIFYVM_X2APIC,
+ MODIFYVM_PARAVIRTPROVIDER,
+ MODIFYVM_PARAVIRTDEBUG,
+ MODIFYVM_HWVIRTEX,
+ MODIFYVM_NESTEDPAGING,
+ MODIFYVM_LARGEPAGES,
+ MODIFYVM_VTXVPID,
+ MODIFYVM_VTXUX,
+ MODIFYVM_VIRT_VMSAVE_VMLOAD,
+ MODIFYVM_IBPB_ON_VM_EXIT,
+ MODIFYVM_IBPB_ON_VM_ENTRY,
+ MODIFYVM_SPEC_CTRL,
+ MODIFYVM_L1D_FLUSH_ON_SCHED,
+ MODIFYVM_L1D_FLUSH_ON_VM_ENTRY,
+ MODIFYVM_MDS_CLEAR_ON_SCHED,
+ MODIFYVM_MDS_CLEAR_ON_VM_ENTRY,
+ MODIFYVM_NESTED_HW_VIRT,
+ MODIFYVM_CPUS,
+ MODIFYVM_CPUHOTPLUG,
+ MODIFYVM_CPU_PROFILE,
+ MODIFYVM_PLUGCPU,
+ MODIFYVM_UNPLUGCPU,
+ MODIFYVM_SETCPUID,
+ MODIFYVM_DELCPUID,
+ MODIFYVM_DELCPUID_OLD, // legacy, different syntax from MODIFYVM_DELCPUID
+ MODIFYVM_DELALLCPUID,
+ MODIFYVM_GRAPHICSCONTROLLER,
+ MODIFYVM_MONITORCOUNT,
+ MODIFYVM_ACCELERATE3D,
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ MODIFYVM_ACCELERATE2DVIDEO,
+#endif
+ MODIFYVM_BIOSLOGOFADEIN,
+ MODIFYVM_BIOSLOGOFADEOUT,
+ MODIFYVM_BIOSLOGODISPLAYTIME,
+ MODIFYVM_BIOSLOGOIMAGEPATH,
+ MODIFYVM_BIOSBOOTMENU,
+ MODIFYVM_BIOSAPIC,
+ MODIFYVM_BIOSSYSTEMTIMEOFFSET,
+ MODIFYVM_BIOSPXEDEBUG,
+ MODIFYVM_SYSTEMUUIDLE,
+ MODIFYVM_BOOT,
+ MODIFYVM_HDA, // deprecated
+ MODIFYVM_HDB, // deprecated
+ MODIFYVM_HDD, // deprecated
+ MODIFYVM_IDECONTROLLER, // deprecated
+ MODIFYVM_SATAPORTCOUNT, // deprecated
+ MODIFYVM_SATAPORT, // deprecated
+ MODIFYVM_SATA, // deprecated
+ MODIFYVM_SCSIPORT, // deprecated
+ MODIFYVM_SCSITYPE, // deprecated
+ MODIFYVM_SCSI, // deprecated
+ MODIFYVM_DVDPASSTHROUGH, // deprecated
+ MODIFYVM_DVD, // deprecated
+ MODIFYVM_FLOPPY, // deprecated
+ MODIFYVM_NICTRACEFILE,
+ MODIFYVM_NICTRACE,
+ MODIFYVM_NICPROPERTY,
+ MODIFYVM_NICTYPE,
+ MODIFYVM_NICSPEED,
+ MODIFYVM_NICBOOTPRIO,
+ MODIFYVM_NICPROMISC,
+ MODIFYVM_NICBWGROUP,
+ MODIFYVM_NIC,
+ MODIFYVM_CABLECONNECTED,
+ MODIFYVM_BRIDGEADAPTER,
+#ifdef VBOX_WITH_CLOUD_NET
+ MODIFYVM_CLOUDNET,
+#endif /* VBOX_WITH_CLOUD_NET */
+ MODIFYVM_HOSTONLYADAPTER,
+#ifdef VBOX_WITH_VMNET
+ MODIFYVM_HOSTONLYNET,
+#endif /* VBOX_WITH_VMNET */
+ MODIFYVM_INTNET,
+ MODIFYVM_GENERICDRV,
+ MODIFYVM_NATNETWORKNAME,
+ MODIFYVM_NATNET,
+ MODIFYVM_NATBINDIP,
+ MODIFYVM_NATSETTINGS,
+ MODIFYVM_NATPF,
+ MODIFYVM_NATALIASMODE,
+ MODIFYVM_NATTFTPPREFIX,
+ MODIFYVM_NATTFTPFILE,
+ MODIFYVM_NATTFTPSERVER,
+ MODIFYVM_NATDNSPASSDOMAIN,
+ MODIFYVM_NATDNSPROXY,
+ MODIFYVM_NATDNSHOSTRESOLVER,
+ MODIFYVM_NATLOCALHOSTREACHABLE,
+ MODIFYVM_MACADDRESS,
+ MODIFYVM_HIDPTR,
+ MODIFYVM_HIDKBD,
+ MODIFYVM_UARTMODE,
+ MODIFYVM_UARTTYPE,
+ MODIFYVM_UART,
+#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
+ MODIFYVM_LPTMODE,
+ MODIFYVM_LPT,
+#endif
+ MODIFYVM_GUESTMEMORYBALLOON,
+ MODIFYVM_AUDIOCONTROLLER,
+ MODIFYVM_AUDIOCODEC,
+ MODIFYVM_AUDIODRIVER,
+ MODIFYVM_AUDIOENABLED,
+ MODIFYVM_AUDIO, /* Deprecated; remove in the next major version. */
+ MODIFYVM_AUDIOIN,
+ MODIFYVM_AUDIOOUT,
+#ifdef VBOX_WITH_SHARED_CLIPBOARD
+ MODIFYVM_CLIPBOARD_MODE,
+# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+ MODIFYVM_CLIPBOARD_FILE_TRANSFERS,
+# endif
+#endif
+ MODIFYVM_DRAGANDDROP,
+ MODIFYVM_VRDPPORT, /* VRDE: deprecated */
+ MODIFYVM_VRDPADDRESS, /* VRDE: deprecated */
+ MODIFYVM_VRDPAUTHTYPE, /* VRDE: deprecated */
+ MODIFYVM_VRDPMULTICON, /* VRDE: deprecated */
+ MODIFYVM_VRDPREUSECON, /* VRDE: deprecated */
+ MODIFYVM_VRDPVIDEOCHANNEL, /* VRDE: deprecated */
+ MODIFYVM_VRDPVIDEOCHANNELQUALITY, /* VRDE: deprecated */
+ MODIFYVM_VRDP, /* VRDE: deprecated */
+ MODIFYVM_VRDEPROPERTY,
+ MODIFYVM_VRDEPORT,
+ MODIFYVM_VRDEADDRESS,
+ MODIFYVM_VRDEAUTHTYPE,
+ MODIFYVM_VRDEAUTHLIBRARY,
+ MODIFYVM_VRDEMULTICON,
+ MODIFYVM_VRDEREUSECON,
+ MODIFYVM_VRDEVIDEOCHANNEL,
+ MODIFYVM_VRDEVIDEOCHANNELQUALITY,
+ MODIFYVM_VRDE_EXTPACK,
+ MODIFYVM_VRDE,
+ MODIFYVM_RTCUSEUTC,
+ MODIFYVM_USBRENAME,
+ MODIFYVM_USBXHCI,
+ MODIFYVM_USBEHCI,
+ MODIFYVM_USBOHCI,
+ MODIFYVM_SNAPSHOTFOLDER,
+ MODIFYVM_TELEPORTER_ENABLED,
+ MODIFYVM_TELEPORTER_PORT,
+ MODIFYVM_TELEPORTER_ADDRESS,
+ MODIFYVM_TELEPORTER_PASSWORD,
+ MODIFYVM_TELEPORTER_PASSWORD_FILE,
+ MODIFYVM_TRACING_ENABLED,
+ MODIFYVM_TRACING_CONFIG,
+ MODIFYVM_TRACING_ALLOW_VM_ACCESS,
+ MODIFYVM_HARDWARE_UUID,
+ MODIFYVM_HPET,
+ MODIFYVM_IOCACHE,
+ MODIFYVM_IOCACHESIZE,
+ MODIFYVM_CPU_EXECTUION_CAP,
+ MODIFYVM_AUTOSTART_ENABLED,
+ MODIFYVM_AUTOSTART_DELAY,
+ MODIFYVM_AUTOSTOP_TYPE,
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ MODIFYVM_ATTACH_PCI,
+ MODIFYVM_DETACH_PCI,
+#endif
+#ifdef VBOX_WITH_USB_CARDREADER
+ MODIFYVM_USBCARDREADER,
+#endif
+#ifdef VBOX_WITH_RECORDING
+ MODIFYVM_RECORDING,
+ MODIFYVM_RECORDING_FEATURES,
+ MODIFYVM_RECORDING_SCREENS,
+ MODIFYVM_RECORDING_FILENAME,
+ MODIFYVM_RECORDING_VIDEO_WIDTH,
+ MODIFYVM_RECORDING_VIDEO_HEIGHT,
+ MODIFYVM_RECORDING_VIDEO_RES,
+ MODIFYVM_RECORDING_VIDEO_RATE,
+ MODIFYVM_RECORDING_VIDEO_FPS,
+ MODIFYVM_RECORDING_MAXTIME,
+ MODIFYVM_RECORDING_MAXSIZE,
+ MODIFYVM_RECORDING_OPTIONS,
+#endif
+ MODIFYVM_CHIPSET,
+#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
+ MODIFYVM_IOMMU,
+#endif
+#if defined(VBOX_WITH_TPM)
+ MODIFYVM_TPM_LOCATION,
+ MODIFYVM_TPM_TYPE,
+#endif
+ MODIFYVM_DEFAULTFRONTEND,
+ MODIFYVM_VMPROC_PRIORITY,
+ MODIFYVM_TESTING_ENABLED,
+ MODIFYVM_TESTING_MMIO,
+ MODIFYVM_TESTING_CFG_DWORD,
+ MODIFYVM_GUEST_DEBUG_PROVIDER,
+ MODIFYVM_GUEST_DEBUG_IO_PROVIDER,
+ MODIFYVM_GUEST_DEBUG_ADDRESS,
+ MODIFYVM_GUEST_DEBUG_PORT,
+};
+
+static const RTGETOPTDEF g_aModifyVMOptions[] =
+{
+ OPT1("--name", MODIFYVM_NAME, RTGETOPT_REQ_STRING),
+ OPT1("--groups", MODIFYVM_GROUPS, RTGETOPT_REQ_STRING),
+ OPT1("--description", MODIFYVM_DESCRIPTION, RTGETOPT_REQ_STRING),
+ OPT2("--os-type", "--ostype", MODIFYVM_OSTYPE, RTGETOPT_REQ_STRING),
+ OPT2("--icon-file", "--iconfile", MODIFYVM_ICONFILE, RTGETOPT_REQ_STRING),
+ OPT1("--memory", MODIFYVM_MEMORY, RTGETOPT_REQ_UINT32),
+ OPT2("--page-fusion", "--pagefusion", MODIFYVM_PAGEFUSION, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--vram", MODIFYVM_VRAM, RTGETOPT_REQ_UINT32),
+ OPT1("--firmware", MODIFYVM_FIRMWARE, RTGETOPT_REQ_STRING),
+ OPT1("--acpi", MODIFYVM_ACPI, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--ioapic", MODIFYVM_IOAPIC, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--pae", MODIFYVM_PAE, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--long-mode", "--longmode", MODIFYVM_LONGMODE, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--cpuid-portability-level", MODIFYVM_CPUID_PORTABILITY, RTGETOPT_REQ_UINT32),
+ OPT2("--triple-fault-reset", "--triplefaultreset", MODIFYVM_TFRESET, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--apic", MODIFYVM_APIC, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--x2apic", MODIFYVM_X2APIC, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--paravirt-provider", "--paravirtprovider", MODIFYVM_PARAVIRTPROVIDER, RTGETOPT_REQ_STRING),
+ OPT2("--paravirt-debug", "--paravirtdebug", MODIFYVM_PARAVIRTDEBUG, RTGETOPT_REQ_STRING),
+ OPT1("--hwvirtex", MODIFYVM_HWVIRTEX, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--nested-paging", "--nestedpaging", MODIFYVM_NESTEDPAGING, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--large-pages", "--largepages", MODIFYVM_LARGEPAGES, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--vtx-vpid", "--vtxvpid", MODIFYVM_VTXVPID, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--vtx-ux", "--vtxux", MODIFYVM_VTXUX, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--virt-vmsave-vmload", MODIFYVM_VIRT_VMSAVE_VMLOAD, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--ibpb-on-vm-exit", MODIFYVM_IBPB_ON_VM_EXIT, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--ibpb-on-vm-entry", MODIFYVM_IBPB_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--spec-ctrl", MODIFYVM_SPEC_CTRL, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--l1d-flush-on-sched", MODIFYVM_L1D_FLUSH_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--l1d-flush-on-vm-entry", MODIFYVM_L1D_FLUSH_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--mds-clear-on-sched", MODIFYVM_MDS_CLEAR_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--mds-clear-on-vm-entry", MODIFYVM_MDS_CLEAR_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--nested-hw-virt", MODIFYVM_NESTED_HW_VIRT, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--cpuid-set", "--cpuidset", MODIFYVM_SETCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX),
+ OPT1("--cpuid-remove", MODIFYVM_DELCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX),
+ OPT1("--cpuidremove", MODIFYVM_DELCPUID_OLD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX), /* legacy - syntax differs */
+ OPT2("--cpuid-remove-all", "--cpuidremoveall", MODIFYVM_DELALLCPUID, RTGETOPT_REQ_NOTHING),
+ OPT1("--cpus", MODIFYVM_CPUS, RTGETOPT_REQ_UINT32),
+ OPT2("--cpu-hotplug", "--cpuhotplug", MODIFYVM_CPUHOTPLUG, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--cpu-profile", MODIFYVM_CPU_PROFILE, RTGETOPT_REQ_STRING),
+ OPT2("--plug-cpu", "--plugcpu", MODIFYVM_PLUGCPU, RTGETOPT_REQ_UINT32),
+ OPT2("--unplug-cpu", "--unplugcpu", MODIFYVM_UNPLUGCPU, RTGETOPT_REQ_UINT32),
+ OPT2("--cpu-execution-cap", "--cpuexecutioncap", MODIFYVM_CPU_EXECTUION_CAP, RTGETOPT_REQ_UINT32),
+ OPT2("--rtc-use-utc", "--rtcuseutc", MODIFYVM_RTCUSEUTC, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--graphicscontroller", "--graphicscontroller", MODIFYVM_GRAPHICSCONTROLLER, RTGETOPT_REQ_STRING),
+ OPT2("--monitor-count", "--monitorcount", MODIFYVM_MONITORCOUNT, RTGETOPT_REQ_UINT32),
+ OPT2("--accelerate-3d", "--accelerate3d", MODIFYVM_ACCELERATE3D, RTGETOPT_REQ_BOOL_ONOFF),
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ OPT2("--accelerate-2d-video", "--accelerate2dvideo", MODIFYVM_ACCELERATE2DVIDEO, RTGETOPT_REQ_BOOL_ONOFF),
+#endif
+ OPT2("--bios-logo-fade-in", "--bioslogofadein", MODIFYVM_BIOSLOGOFADEIN, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--bios-logo-fade-out", "--bioslogofadeout", MODIFYVM_BIOSLOGOFADEOUT, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--bios-logo-display-time", "--bioslogodisplaytime", MODIFYVM_BIOSLOGODISPLAYTIME, RTGETOPT_REQ_UINT32),
+ OPT2("--bios-logo-image-path", "--bioslogoimagepath", MODIFYVM_BIOSLOGOIMAGEPATH, RTGETOPT_REQ_STRING),
+ OPT2("--bios-boot-menu", "--biosbootmenu", MODIFYVM_BIOSBOOTMENU, RTGETOPT_REQ_STRING),
+ OPT2("--bios-system-time-offset", "--biossystemtimeoffset", MODIFYVM_BIOSSYSTEMTIMEOFFSET, RTGETOPT_REQ_INT64),
+ OPT2("--bios-apic", "--biosapic", MODIFYVM_BIOSAPIC, RTGETOPT_REQ_STRING),
+ OPT2("--bios-pxe-debug", "--biospxedebug", MODIFYVM_BIOSPXEDEBUG, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--system-uuid-le", "--system-uuid-le", MODIFYVM_SYSTEMUUIDLE, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--boot", MODIFYVM_BOOT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT1("--hda", MODIFYVM_HDA, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--hdb", MODIFYVM_HDB, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--hdd", MODIFYVM_HDD, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--idec-ontroller", "--idecontroller", MODIFYVM_IDECONTROLLER, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--sata-port-count", "--sataportcount", MODIFYVM_SATAPORTCOUNT, RTGETOPT_REQ_UINT32), /* deprecated */
+ OPT2("--sata-port", "--sataport", MODIFYVM_SATAPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */
+ OPT1("--sata", MODIFYVM_SATA, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--scsi-port", "--scsiport", MODIFYVM_SCSIPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */
+ OPT2("--scsi-type", "--scsitype", MODIFYVM_SCSITYPE, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--scsi", MODIFYVM_SCSI, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--dvd-pass-through", "--dvdpassthrough", MODIFYVM_DVDPASSTHROUGH, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--dvd", MODIFYVM_DVD, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--floppy", MODIFYVM_FLOPPY, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--nic-trace-file", "--nictracefile", MODIFYVM_NICTRACEFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-trace", "--nictrace", MODIFYVM_NICTRACE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-property", "--nicproperty", MODIFYVM_NICPROPERTY, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-type", "--nictype", MODIFYVM_NICTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-speed", "--nicspeed", MODIFYVM_NICSPEED, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-boot-prio", "--nicbootprio", MODIFYVM_NICBOOTPRIO, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-promisc", "--nicpromisc", MODIFYVM_NICPROMISC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-bandwidth-group", "--nicbandwidthgroup", MODIFYVM_NICBWGROUP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT1("--nic", MODIFYVM_NIC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--cable-connected", "--cableconnected", MODIFYVM_CABLECONNECTED, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--bridge-adapter", "--bridgeadapter", MODIFYVM_BRIDGEADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#ifdef VBOX_WITH_CLOUD_NET
+ OPT2("--cloud-network", "--cloudnetwork", MODIFYVM_CLOUDNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#endif /* VBOX_WITH_CLOUD_NET */
+ OPT2("--host-only-adapter", "--hostonlyadapter", MODIFYVM_HOSTONLYADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#ifdef VBOX_WITH_VMNET
+ OPT2("--host-only-net", "--hostonlynet", MODIFYVM_HOSTONLYNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#endif
+ OPT1("--intnet", MODIFYVM_INTNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nic-generic-drv", "--nicgenericdrv", MODIFYVM_GENERICDRV, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-network", "--natnetwork", MODIFYVM_NATNETWORKNAME, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-net", "--natnet", MODIFYVM_NATNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-bind-ip", "--natbindip", MODIFYVM_NATBINDIP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-settings", "--natsettings", MODIFYVM_NATSETTINGS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-pf", "--natpf", MODIFYVM_NATPF, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-alias-mode", "--nataliasmode", MODIFYVM_NATALIASMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-tftp-prefix", "--nattftpprefix", MODIFYVM_NATTFTPPREFIX, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-tftp-file", "--nattftpfile", MODIFYVM_NATTFTPFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-tftp-server", "--nattftpserver", MODIFYVM_NATTFTPSERVER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-dns-pass-domain", "--natdnspassdomain", MODIFYVM_NATDNSPASSDOMAIN, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-dns-proxy", "--natdnsproxy", MODIFYVM_NATDNSPROXY, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-dns-host-resolver", "--natdnshostresolver", MODIFYVM_NATDNSHOSTRESOLVER, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--nat-localhostreachable", "--natlocalhostreachable", MODIFYVM_NATLOCALHOSTREACHABLE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
+ OPT2("--mac-address", "--macaddress", MODIFYVM_MACADDRESS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT1("--mouse", MODIFYVM_HIDPTR, RTGETOPT_REQ_STRING),
+ OPT1("--keyboard", MODIFYVM_HIDKBD, RTGETOPT_REQ_STRING),
+ OPT2("--uart-mode", "--uartmode", MODIFYVM_UARTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT2("--uart-type", "--uarttype", MODIFYVM_UARTTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT1("--uart", MODIFYVM_UART, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
+ OPT2("--lpt-mode", "--lptmode", MODIFYVM_LPTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+ OPT1("--lpt", MODIFYVM_LPT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
+#endif
+ OPT2("--guest-memory-balloon", "--guestmemoryballoon", MODIFYVM_GUESTMEMORYBALLOON, RTGETOPT_REQ_UINT32),
+ OPT2("--audio-controller", "--audiocontroller", MODIFYVM_AUDIOCONTROLLER, RTGETOPT_REQ_STRING),
+ OPT2("--audio-codec", "--audiocodec", MODIFYVM_AUDIOCODEC, RTGETOPT_REQ_STRING),
+ OPT1("--audio", MODIFYVM_AUDIO, RTGETOPT_REQ_STRING),
+ OPT2("--audio-driver", "--audiodriver", MODIFYVM_AUDIODRIVER, RTGETOPT_REQ_STRING),
+ OPT2("--audio-enabled", "--audioenabled", MODIFYVM_AUDIOENABLED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--audio-in", "--audioin", MODIFYVM_AUDIOIN, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--audio-out", "--audioout", MODIFYVM_AUDIOOUT, RTGETOPT_REQ_BOOL_ONOFF),
+#ifdef VBOX_WITH_SHARED_CLIPBOARD
+ OPT1("--clipboard-mode", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING),
+ OPT1("--clipboard", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING), /* deprecated */
+# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+ OPT1("--clipboard-file-transfers", MODIFYVM_CLIPBOARD_FILE_TRANSFERS, RTGETOPT_REQ_STRING),
+# endif
+#endif
+ OPT2("--drag-and-drop", "--draganddrop", MODIFYVM_DRAGANDDROP, RTGETOPT_REQ_STRING),
+ OPT2("--vrdp-port", "--vrdpport", MODIFYVM_VRDPPORT, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--vrdp-address", "--vrdpaddress", MODIFYVM_VRDPADDRESS, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--vrdp-auth-type", "--vrdpauthtype", MODIFYVM_VRDPAUTHTYPE, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT2("--vrdp-multi-con", "--vrdpmulticon", MODIFYVM_VRDPMULTICON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--vrdp-reuse-con", "--vrdpreusecon", MODIFYVM_VRDPREUSECON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--vrdp-video-channel", "--vrdpvideochannel", MODIFYVM_VRDPVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--vrdp-video-channel-quality", "--vrdpvideochannelquality",MODIFYVM_VRDPVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING), /* deprecated */
+ OPT1("--vrdp", MODIFYVM_VRDP, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--vrde-property", "--vrdeproperty", MODIFYVM_VRDEPROPERTY, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-port", "--vrdeport", MODIFYVM_VRDEPORT, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-address", "--vrdeaddress", MODIFYVM_VRDEADDRESS, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-auth-type", "--vrdeauthtype", MODIFYVM_VRDEAUTHTYPE, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-auth-library", "--vrdeauthlibrary", MODIFYVM_VRDEAUTHLIBRARY, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-multi-con", "--vrdemulticon", MODIFYVM_VRDEMULTICON, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--vrde-reuse-con", "--vrdereusecon", MODIFYVM_VRDEREUSECON, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--vrde-video-channel", "--vrdevideochannel", MODIFYVM_VRDEVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--vrde-video-channel-quality", "--vrdevideochannelquality",MODIFYVM_VRDEVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING),
+ OPT2("--vrde-extpack", "--vrdeextpack", MODIFYVM_VRDE_EXTPACK, RTGETOPT_REQ_STRING),
+ OPT1("--vrde", MODIFYVM_VRDE, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--usb-rename", "--usbrename", MODIFYVM_USBRENAME, RTGETOPT_REQ_STRING),
+ OPT2("--usb-xhci", "--usbxhci", MODIFYVM_USBXHCI, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--usb-ehci", "--usbehci", MODIFYVM_USBEHCI, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--usb-ohci", "--usbohci", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--usb", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--snapshot-folder", "--snapshotfolder", MODIFYVM_SNAPSHOTFOLDER, RTGETOPT_REQ_STRING),
+ OPT1("--teleporter", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--teleporter-enabled", "--teleporterenabled", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
+ OPT2("--teleporter-port", "--teleporterport", MODIFYVM_TELEPORTER_PORT, RTGETOPT_REQ_UINT32),
+ OPT2("--teleporter-address", "--teleporteraddress", MODIFYVM_TELEPORTER_ADDRESS, RTGETOPT_REQ_STRING),
+ OPT2("--teleporter-password", "--teleporterpassword", MODIFYVM_TELEPORTER_PASSWORD, RTGETOPT_REQ_STRING),
+ OPT2("--teleporter-password-file", "--teleporterpasswordfile", MODIFYVM_TELEPORTER_PASSWORD_FILE, RTGETOPT_REQ_STRING),
+ OPT1("--tracing-enabled", MODIFYVM_TRACING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--tracing-config", MODIFYVM_TRACING_CONFIG, RTGETOPT_REQ_STRING),
+ OPT1("--tracing-allow-vm-access", MODIFYVM_TRACING_ALLOW_VM_ACCESS, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--hardware-uuid", "--hardwareuuid", MODIFYVM_HARDWARE_UUID, RTGETOPT_REQ_STRING),
+ OPT1("--hpet", MODIFYVM_HPET, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--iocache", MODIFYVM_IOCACHE, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--iocache-size", "--iocachesize", MODIFYVM_IOCACHESIZE, RTGETOPT_REQ_UINT32),
+ OPT1("--chipset", MODIFYVM_CHIPSET, RTGETOPT_REQ_STRING),
+#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
+ OPT1("--iommu", MODIFYVM_IOMMU, RTGETOPT_REQ_STRING),
+#endif
+#if defined(VBOX_WITH_TPM)
+ OPT1("--tpm-type", MODIFYVM_TPM_TYPE, RTGETOPT_REQ_STRING),
+ OPT1("--tpm-location", MODIFYVM_TPM_LOCATION, RTGETOPT_REQ_STRING),
+#endif
+#ifdef VBOX_WITH_RECORDING
+ OPT1("--recording", MODIFYVM_RECORDING, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT2("--recording-screens", "--recordingscreens", MODIFYVM_RECORDING_SCREENS, RTGETOPT_REQ_STRING),
+ OPT2("--recording-file", "--recordingfile", MODIFYVM_RECORDING_FILENAME, RTGETOPT_REQ_STRING),
+ OPT2("--recording-max-time", "--recordingmaxtime", MODIFYVM_RECORDING_MAXTIME, RTGETOPT_REQ_INT32),
+ OPT2("--recording-max-size", "--recordingmaxsize", MODIFYVM_RECORDING_MAXSIZE, RTGETOPT_REQ_INT32),
+ OPT2("--recording-opts", "--recordingopts", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING),
+ OPT2("--recording-options", "--recordingoptions", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING),
+ OPT2("--recording-video-res", "--recordingvideores", MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING),
+ OPT2("--recording-video-resolution", "--recordingvideoresolution",MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING),
+ OPT2("--recording-video-rate", "--recordingvideorate", MODIFYVM_RECORDING_VIDEO_RATE, RTGETOPT_REQ_UINT32),
+ OPT2("--recording-video-fps", "--recordingvideofps", MODIFYVM_RECORDING_VIDEO_FPS, RTGETOPT_REQ_UINT32),
+#endif
+ OPT1("--autostart-enabled", MODIFYVM_AUTOSTART_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--autostart-delay", MODIFYVM_AUTOSTART_DELAY, RTGETOPT_REQ_UINT32),
+ OPT1("--autostop-type", MODIFYVM_AUTOSTOP_TYPE, RTGETOPT_REQ_STRING),
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ OPT2("--pci-attach", "--pciattach", MODIFYVM_ATTACH_PCI, RTGETOPT_REQ_STRING),
+ OPT2("--pci-detach", "--pcidetach", MODIFYVM_DETACH_PCI, RTGETOPT_REQ_STRING),
+#endif
+#ifdef VBOX_WITH_USB_CARDREADER
+ OPT2("--usb-card-reader", "--usbcardreader", MODIFYVM_USBCARDREADER, RTGETOPT_REQ_BOOL_ONOFF),
+#endif
+ OPT2("--default-frontend", "--defaultfrontend", MODIFYVM_DEFAULTFRONTEND, RTGETOPT_REQ_STRING),
+ OPT1("--vm-process-priority", MODIFYVM_VMPROC_PRIORITY, RTGETOPT_REQ_STRING),
+ OPT1("--testing-enabled", MODIFYVM_TESTING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--testing-mmio", MODIFYVM_TESTING_MMIO, RTGETOPT_REQ_BOOL_ONOFF),
+ OPT1("--testing-cfg-dword", MODIFYVM_TESTING_CFG_DWORD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
+ OPT1("--guest-debug-provider", MODIFYVM_GUEST_DEBUG_PROVIDER, RTGETOPT_REQ_STRING),
+ OPT1("--guest-debug-io-provider", MODIFYVM_GUEST_DEBUG_IO_PROVIDER, RTGETOPT_REQ_STRING),
+ OPT1("--guest-debug-address", MODIFYVM_GUEST_DEBUG_ADDRESS, RTGETOPT_REQ_STRING),
+ OPT1("--guest-debug-port", MODIFYVM_GUEST_DEBUG_PORT, RTGETOPT_REQ_UINT32),
+};
+
+static void vrdeWarningDeprecatedOption(const char *pszOption)
+{
+ RTStrmPrintf(g_pStdErr, ModifyVM::tr("Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n"), pszOption, pszOption);
+}
+
+
+/**
+ * Wrapper around IMachine::SetExtraData that does the error reporting.
+ *
+ * @returns COM result code.
+ * @param rSessionMachine The IMachine.
+ * @param pszVariable The variable to set.
+ * @param pszValue The value to set. To delete pass empty string, not
+ * NULL.
+ */
+static HRESULT setExtraData(ComPtr<IMachine> &rSessionMachine, const char *pszVariable, const char *pszValue)
+{
+ HRESULT hrc = rSessionMachine->SetExtraData(Bstr(pszVariable).raw(), Bstr(pszValue).raw());
+ if (FAILED(hrc))
+ {
+ char *pszContext = RTStrAPrintf2("IMachine::SetExtraData('%s', '%s')", pszVariable, pszValue);
+ com::GlueHandleComError(rSessionMachine, pszContext, hrc, __FILE__, __LINE__);
+ RTStrFree(pszContext);
+ }
+ return hrc;
+}
+
+
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+/** Parse PCI address in format 01:02.03 and convert it to the numeric representation. */
+static int32_t parsePci(const char* szPciAddr)
+{
+ uint8_t aVals[3] = {0, 0, 0};
+
+ char *pszNext;
+ int vrc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &aVals[0]);
+ if (RT_FAILURE(vrc) || pszNext == NULL || *pszNext != ':')
+ return -1;
+
+ vrc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[1]);
+ if (RT_FAILURE(vrc) || pszNext == NULL || *pszNext != '.')
+ return -1;
+
+ vrc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[2]);
+ if (RT_FAILURE(vrc) || pszNext == NULL)
+ return -1;
+
+ return (aVals[0] << 8) | (aVals[1] << 3) | (aVals[2] << 0);
+}
+#endif
+
+void parseGroups(const char *pcszGroups, com::SafeArray<BSTR> *pGroups)
+{
+ while (pcszGroups)
+ {
+ char *pComma = RTStrStr(pcszGroups, ",");
+ if (pComma)
+ {
+ Bstr(pcszGroups, pComma - pcszGroups).detachTo(pGroups->appendedRaw());
+ pcszGroups = pComma + 1;
+ }
+ else
+ {
+ Bstr(pcszGroups).detachTo(pGroups->appendedRaw());
+ pcszGroups = NULL;
+ }
+ }
+}
+
+#ifdef VBOX_WITH_RECORDING
+int parseScreens(const char *pcszScreens, com::SafeArray<BOOL> *pScreens)
+{
+ if (!RTStrICmp(pcszScreens, "all"))
+ {
+ for (uint32_t i = 0; i < pScreens->size(); i++)
+ (*pScreens)[i] = TRUE;
+ return VINF_SUCCESS;
+ }
+ if (!RTStrICmp(pcszScreens, "none"))
+ {
+ for (uint32_t i = 0; i < pScreens->size(); i++)
+ (*pScreens)[i] = FALSE;
+ return VINF_SUCCESS;
+ }
+ while (pcszScreens && *pcszScreens)
+ {
+ char *pszNext;
+ uint32_t iScreen;
+ int vrc = RTStrToUInt32Ex(pcszScreens, &pszNext, 0, &iScreen);
+ if (RT_FAILURE(vrc))
+ return VERR_PARSE_ERROR;
+ if (iScreen >= pScreens->size())
+ return VERR_PARSE_ERROR;
+ if (pszNext && *pszNext)
+ {
+ pszNext = RTStrStripL(pszNext);
+ if (*pszNext != ',')
+ return VERR_PARSE_ERROR;
+ pszNext++;
+ }
+ (*pScreens)[iScreen] = true;
+ pcszScreens = pszNext;
+ }
+ return VINF_SUCCESS;
+}
+#endif
+
+static int parseNum(uint32_t uIndex, unsigned cMaxIndex, const char *pszName)
+{
+ if ( uIndex >= 1
+ && uIndex <= cMaxIndex)
+ return uIndex;
+ errorArgument(ModifyVM::tr("Invalid %s number %u"), pszName, uIndex);
+ return 0;
+}
+
+VMProcPriority_T nameToVMProcPriority(const char *pszName)
+{
+ if (!RTStrICmp(pszName, "default"))
+ return VMProcPriority_Default;
+ if (!RTStrICmp(pszName, "flat"))
+ return VMProcPriority_Flat;
+ if (!RTStrICmp(pszName, "low"))
+ return VMProcPriority_Low;
+ if (!RTStrICmp(pszName, "normal"))
+ return VMProcPriority_Normal;
+ if (!RTStrICmp(pszName, "high"))
+ return VMProcPriority_High;
+
+ return VMProcPriority_Invalid;
+}
+
+RTEXITCODE handleModifyVM(HandlerArg *a)
+{
+ int c;
+ HRESULT hrc;
+ Bstr name;
+
+ /* VM ID + at least one parameter. Parameter arguments are checked
+ * individually. */
+ if (a->argc < 2)
+ return errorSyntax(ModifyVM::tr("Not enough parameters"));
+
+ /* try to find the given sessionMachine */
+ ComPtr<IMachine> machine;
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+
+ /* Get the number of network adapters */
+ ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, machine);
+
+ /* open a session for the VM */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+ /* get the mutable session sessionMachine */
+ ComPtr<IMachine> sessionMachine;
+ CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IBIOSSettings> biosSettings;
+ sessionMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
+
+ ComPtr<IGraphicsAdapter> pGraphicsAdapter;
+ sessionMachine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam());
+
+ RTGETOPTSTATE GetOptState;
+ RTGetOptInit(&GetOptState, a->argc, a->argv, g_aModifyVMOptions,
+ RT_ELEMENTS(g_aModifyVMOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ RTGETOPTUNION ValueUnion;
+ while ( SUCCEEDED (hrc)
+ && (c = RTGetOpt(&GetOptState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case MODIFYVM_NAME:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+ case MODIFYVM_GROUPS:
+ {
+ com::SafeArray<BSTR> groups;
+ parseGroups(ValueUnion.psz, &groups);
+ CHECK_ERROR(sessionMachine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups)));
+ break;
+ }
+ case MODIFYVM_DESCRIPTION:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+ case MODIFYVM_OSTYPE:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_ICONFILE:
+ {
+ RTFILE iconFile;
+ int vrc = RTFileOpen(&iconFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(ModifyVM::tr("Cannot open file \"%s\": %Rrc"), ValueUnion.psz, vrc);
+ hrc = E_FAIL;
+ break;
+ }
+ uint64_t cbSize;
+ vrc = RTFileQuerySize(iconFile, &cbSize);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(ModifyVM::tr("Cannot get size of file \"%s\": %Rrc"), ValueUnion.psz, vrc);
+ hrc = E_FAIL;
+ break;
+ }
+ if (cbSize > _256K)
+ {
+ RTMsgError(ModifyVM::tr("File \"%s\" is bigger than 256KByte"), ValueUnion.psz);
+ hrc = E_FAIL;
+ break;
+ }
+ SafeArray<BYTE> icon((size_t)cbSize);
+ hrc = RTFileRead(iconFile, icon.raw(), (size_t)cbSize, NULL);
+ if (RT_FAILURE(vrc))
+ {
+ RTMsgError(ModifyVM::tr("Cannot read contents of file \"%s\": %Rrc"), ValueUnion.psz, vrc);
+ hrc = E_FAIL;
+ break;
+ }
+ RTFileClose(iconFile);
+ CHECK_ERROR(sessionMachine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon)));
+ break;
+ }
+
+ case MODIFYVM_MEMORY:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(MemorySize)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_PAGEFUSION:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PageFusionEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VRAM:
+ {
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(VRAMSize)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_FIRMWARE:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "efi"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "efi32"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI32));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "efi64"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI64));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "efidual"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "bios"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_BIOS));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --firmware argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_ACPI:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_IOAPIC:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_PAE:
+ {
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_LONGMODE:
+ {
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_CPUID_PORTABILITY:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(CPUIDPortabilityLevel)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_TFRESET:
+ {
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_APIC:
+ {
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_APIC, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_X2APIC:
+ {
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_X2APIC, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_PARAVIRTPROVIDER:
+ {
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "disabled"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_None));
+ else if (!RTStrICmp(ValueUnion.psz, "default"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default));
+ else if (!RTStrICmp(ValueUnion.psz, "legacy"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy));
+ else if (!RTStrICmp(ValueUnion.psz, "minimal"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal));
+ else if (!RTStrICmp(ValueUnion.psz, "hyperv"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV));
+ else if (!RTStrICmp(ValueUnion.psz, "kvm"))
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM));
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --paravirtprovider argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_PARAVIRTDEBUG:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(ParavirtDebug)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_HWVIRTEX:
+ {
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_SETCPUID:
+ {
+ uint32_t const idx = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uFirst : ValueUnion.u32;
+ uint32_t const idxSub = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uSecond : UINT32_MAX;
+ uint32_t aValue[4];
+ for (unsigned i = 0; i < 4; i++)
+ {
+ int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+ aValue[i] = ValueUnion.u32;
+ }
+ CHECK_ERROR(sessionMachine, SetCPUIDLeaf(idx, idxSub, aValue[0], aValue[1], aValue[2], aValue[3]));
+ break;
+ }
+
+ case MODIFYVM_DELCPUID:
+ CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond));
+ break;
+
+ case MODIFYVM_DELCPUID_OLD:
+ CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32, UINT32_MAX));
+ break;
+
+ case MODIFYVM_DELALLCPUID:
+ {
+ CHECK_ERROR(sessionMachine, RemoveAllCPUIDLeaves());
+ break;
+ }
+
+ case MODIFYVM_NESTEDPAGING:
+ {
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_LARGEPAGES:
+ {
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VTXVPID:
+ {
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VTXUX:
+ {
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VIRT_VMSAVE_VMLOAD:
+ CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, ValueUnion.f));
+ break;
+
+ case MODIFYVM_IBPB_ON_VM_EXIT:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMExit, ValueUnion.f));
+ break;
+
+ case MODIFYVM_IBPB_ON_VM_ENTRY:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMEntry, ValueUnion.f));
+ break;
+
+ case MODIFYVM_SPEC_CTRL:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_SpecCtrl, ValueUnion.f));
+ break;
+
+ case MODIFYVM_L1D_FLUSH_ON_SCHED:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnEMTScheduling, ValueUnion.f));
+ break;
+
+ case MODIFYVM_L1D_FLUSH_ON_VM_ENTRY:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnVMEntry, ValueUnion.f));
+ break;
+
+ case MODIFYVM_MDS_CLEAR_ON_SCHED:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnEMTScheduling, ValueUnion.f));
+ break;
+
+ case MODIFYVM_MDS_CLEAR_ON_VM_ENTRY:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnVMEntry, ValueUnion.f));
+ break;
+
+ case MODIFYVM_NESTED_HW_VIRT:
+ CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_HWVirt, ValueUnion.f));
+ break;
+
+ case MODIFYVM_CPUS:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(CPUCount)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_RTCUSEUTC:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(RTCUseUTC)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_CPUHOTPLUG:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_CPU_PROFILE:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(CPUProfile)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_PLUGCPU:
+ {
+ CHECK_ERROR(sessionMachine, HotPlugCPU(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_UNPLUGCPU:
+ {
+ CHECK_ERROR(sessionMachine, HotUnplugCPU(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_CPU_EXECTUION_CAP:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(CPUExecutionCap)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_GRAPHICSCONTROLLER:
+ {
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "disabled"))
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null));
+ else if ( !RTStrICmp(ValueUnion.psz, "vboxvga")
+ || !RTStrICmp(ValueUnion.psz, "vbox")
+ || !RTStrICmp(ValueUnion.psz, "vga")
+ || !RTStrICmp(ValueUnion.psz, "vesa"))
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA));
+#ifdef VBOX_WITH_VMSVGA
+ else if ( !RTStrICmp(ValueUnion.psz, "vmsvga")
+ || !RTStrICmp(ValueUnion.psz, "vmware"))
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA));
+ else if ( !RTStrICmp(ValueUnion.psz, "vboxsvga")
+ || !RTStrICmp(ValueUnion.psz, "svga"))
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxSVGA));
+#endif
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --graphicscontroller argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_MONITORCOUNT:
+ {
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(MonitorCount)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_ACCELERATE3D:
+ {
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate3DEnabled)(ValueUnion.f));
+ break;
+ }
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ case MODIFYVM_ACCELERATE2DVIDEO:
+ {
+ CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f));
+ break;
+ }
+#endif
+
+ case MODIFYVM_BIOSLOGOFADEIN:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_BIOSLOGOFADEOUT:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_BIOSLOGODISPLAYTIME:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_BIOSLOGOIMAGEPATH:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_BIOSBOOTMENU:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "menuonly"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "messageandmenu"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --biosbootmenu argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_BIOSAPIC:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_Disabled));
+ }
+ else if ( !RTStrICmp(ValueUnion.psz, "apic")
+ || !RTStrICmp(ValueUnion.psz, "lapic")
+ || !RTStrICmp(ValueUnion.psz, "xapic"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_APIC));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "x2apic"))
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_X2APIC));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --biosapic argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_BIOSSYSTEMTIMEOFFSET:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(ValueUnion.i64));
+ break;
+ }
+
+ case MODIFYVM_BIOSPXEDEBUG:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_SYSTEMUUIDLE:
+ {
+ CHECK_ERROR(biosSettings, COMSETTER(SMBIOSUuidLittleEndian)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_BOOT:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Null));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "floppy"))
+ {
+ CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "dvd"))
+ {
+ CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "disk"))
+ {
+ CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "net"))
+ {
+ CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Network));
+ }
+ else
+ return errorArgument(ModifyVM::tr("Invalid boot device '%s'"), ValueUnion.psz);
+ break;
+ }
+
+ case MODIFYVM_HDA: // deprecated
+ case MODIFYVM_HDB: // deprecated
+ case MODIFYVM_HDD: // deprecated
+ case MODIFYVM_SATAPORT: // deprecated
+ {
+ uint32_t u1 = 0, u2 = 0;
+ Bstr bstrController = L"IDE Controller";
+
+ switch (c)
+ {
+ case MODIFYVM_HDA: // deprecated
+ u1 = 0;
+ break;
+
+ case MODIFYVM_HDB: // deprecated
+ u1 = 0;
+ u2 = 1;
+ break;
+
+ case MODIFYVM_HDD: // deprecated
+ u1 = 1;
+ u2 = 1;
+ break;
+
+ case MODIFYVM_SATAPORT: // deprecated
+ u1 = GetOptState.uIndex;
+ bstrController = L"SATA";
+ break;
+ }
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ sessionMachine->DetachDevice(bstrController.raw(), u1, u2);
+ }
+ else
+ {
+ ComPtr<IMedium> hardDisk;
+ hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
+ AccessMode_ReadWrite, hardDisk,
+ false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
+ if (FAILED(hrc))
+ break;
+ if (hardDisk)
+ {
+ CHECK_ERROR(sessionMachine, AttachDevice(bstrController.raw(),
+ u1, u2,
+ DeviceType_HardDisk,
+ hardDisk));
+ }
+ else
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_IDECONTROLLER: // deprecated
+ {
+ ComPtr<IStorageController> storageController;
+ CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("IDE Controller").raw(),
+ storageController.asOutParam()));
+
+ if (!RTStrICmp(ValueUnion.psz, "PIIX3"))
+ {
+ CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "PIIX4"))
+ {
+ CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "ICH6"))
+ {
+ CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_ICH6));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --idecontroller argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_SATAPORTCOUNT: // deprecated
+ {
+ ComPtr<IStorageController> SataCtl;
+ CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("SATA").raw(),
+ SataCtl.asOutParam()));
+
+ if (SUCCEEDED(hrc) && ValueUnion.u32 > 0)
+ CHECK_ERROR(SataCtl, COMSETTER(PortCount)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_SATA: // deprecated
+ {
+ if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
+ {
+ ComPtr<IStorageController> ctl;
+ CHECK_ERROR(sessionMachine, AddStorageController(Bstr("SATA").raw(),
+ StorageBus_SATA,
+ ctl.asOutParam()));
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
+ CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("SATA").raw()));
+ else
+ return errorArgument(ModifyVM::tr("Invalid --usb argument '%s'"), ValueUnion.psz);
+ break;
+ }
+
+ case MODIFYVM_SCSIPORT: // deprecated
+ {
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ hrc = sessionMachine->DetachDevice(Bstr("LsiLogic").raw(),
+ GetOptState.uIndex, 0);
+ if (FAILED(hrc))
+ CHECK_ERROR(sessionMachine, DetachDevice(Bstr("BusLogic").raw(),
+ GetOptState.uIndex, 0));
+ }
+ else
+ {
+ ComPtr<IMedium> hardDisk;
+ hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
+ AccessMode_ReadWrite, hardDisk,
+ false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
+ if (FAILED(hrc))
+ break;
+ if (hardDisk)
+ {
+ hrc = sessionMachine->AttachDevice(Bstr("LsiLogic").raw(),
+ GetOptState.uIndex, 0,
+ DeviceType_HardDisk,
+ hardDisk);
+ if (FAILED(hrc))
+ CHECK_ERROR(sessionMachine,
+ AttachDevice(Bstr("BusLogic").raw(),
+ GetOptState.uIndex, 0,
+ DeviceType_HardDisk,
+ hardDisk));
+ }
+ else
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_SCSITYPE: // deprecated
+ {
+ ComPtr<IStorageController> ctl;
+
+ if (!RTStrICmp(ValueUnion.psz, "LsiLogic"))
+ {
+ hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
+ if (FAILED(hrc))
+ CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
+
+ CHECK_ERROR(sessionMachine,
+ AddStorageController(Bstr("LsiLogic").raw(),
+ StorageBus_SCSI,
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "BusLogic"))
+ {
+ hrc = sessionMachine->RemoveStorageController(Bstr("LsiLogic").raw());
+ if (FAILED(hrc))
+ CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("BusLogic").raw()));
+
+ CHECK_ERROR(sessionMachine,
+ AddStorageController(Bstr("BusLogic").raw(),
+ StorageBus_SCSI,
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
+ }
+ else
+ return errorArgument(ModifyVM::tr("Invalid --scsitype argument '%s'"), ValueUnion.psz);
+ break;
+ }
+
+ case MODIFYVM_SCSI: // deprecated
+ {
+ if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
+ {
+ ComPtr<IStorageController> ctl;
+
+ CHECK_ERROR(sessionMachine, AddStorageController(Bstr("BusLogic").raw(),
+ StorageBus_SCSI,
+ ctl.asOutParam()));
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
+ {
+ hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
+ if (FAILED(hrc))
+ CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
+ }
+ break;
+ }
+
+ case MODIFYVM_DVDPASSTHROUGH: // deprecated
+ {
+ CHECK_ERROR(sessionMachine, PassthroughDevice(Bstr("IDE Controller").raw(),
+ 1, 0,
+ !RTStrICmp(ValueUnion.psz, "on")));
+ break;
+ }
+
+ case MODIFYVM_DVD: // deprecated
+ {
+ ComPtr<IMedium> dvdMedium;
+
+ /* unmount? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ /* nothing to do, NULL object will cause unmount */
+ }
+ /* host drive? */
+ else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
+ hrc = host->FindHostDVDDrive(Bstr(ValueUnion.psz + 5).raw(),
+ dvdMedium.asOutParam());
+ if (!dvdMedium)
+ {
+ /* 2nd try: try with the real name, important on Linux+libhal */
+ char szPathReal[RTPATH_MAX];
+ if (RT_FAILURE(RTPathReal(ValueUnion.psz + 5, szPathReal, sizeof(szPathReal))))
+ {
+ errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5);
+ hrc = E_FAIL;
+ break;
+ }
+ hrc = host->FindHostDVDDrive(Bstr(szPathReal).raw(),
+ dvdMedium.asOutParam());
+ if (!dvdMedium)
+ {
+ errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ }
+ else
+ {
+ hrc = openMedium(a, ValueUnion.psz, DeviceType_DVD,
+ AccessMode_ReadOnly, dvdMedium,
+ false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
+ if (FAILED(hrc))
+ break;
+ if (!dvdMedium)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ }
+
+ CHECK_ERROR(sessionMachine, MountMedium(Bstr("IDE Controller").raw(),
+ 1, 0,
+ dvdMedium,
+ FALSE /* aForce */));
+ break;
+ }
+
+ case MODIFYVM_FLOPPY: // deprecated
+ {
+ ComPtr<IMedium> floppyMedium;
+ ComPtr<IMediumAttachment> floppyAttachment;
+ sessionMachine->GetMediumAttachment(Bstr("Floppy Controller").raw(),
+ 0, 0, floppyAttachment.asOutParam());
+
+ /* disable? */
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ {
+ /* disable the controller */
+ if (floppyAttachment)
+ CHECK_ERROR(sessionMachine, DetachDevice(Bstr("Floppy Controller").raw(),
+ 0, 0));
+ }
+ else
+ {
+ /* enable the controller */
+ if (!floppyAttachment)
+ CHECK_ERROR(sessionMachine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(),
+ 0, 0,
+ DeviceType_Floppy));
+
+ /* unmount? */
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "empty")) // deprecated
+ {
+ /* nothing to do, NULL object will cause unmount */
+ }
+ /* host drive? */
+ else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
+ hrc = host->FindHostFloppyDrive(Bstr(ValueUnion.psz + 5).raw(),
+ floppyMedium.asOutParam());
+ if (!floppyMedium)
+ {
+ errorArgument(ModifyVM::tr("Invalid host floppy drive name \"%s\""), ValueUnion.psz + 5);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ else
+ {
+ hrc = openMedium(a, ValueUnion.psz, DeviceType_Floppy,
+ AccessMode_ReadWrite, floppyMedium,
+ false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
+ if (FAILED(hrc))
+ break;
+ if (!floppyMedium)
+ {
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ CHECK_ERROR(sessionMachine, MountMedium(Bstr("Floppy Controller").raw(),
+ 0, 0,
+ floppyMedium,
+ FALSE /* aForce */));
+ }
+ break;
+ }
+
+ case MODIFYVM_NICTRACEFILE:
+ {
+
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(TraceFile)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NICTRACE:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(TraceEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_NICPROPERTY:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ if (nic)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(ValueUnion.psz);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(nic, SetProperty(bstrName.raw(), bstrValue.raw()));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --nicproperty%d argument '%s'"), GetOptState.uIndex, ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for --nicproperty%d '%s'\n"),
+ GetOptState.uIndex, ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ }
+ break;
+ }
+ case MODIFYVM_NICTYPE:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ if (!RTStrICmp(ValueUnion.psz, "Am79C970A"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "Am79C973"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "Am79C960"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C960));
+ }
+#ifdef VBOX_WITH_E1000
+ else if (!RTStrICmp(ValueUnion.psz, "82540EM"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "82543GC"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "82545EM"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82545EM));
+ }
+#endif
+#ifdef VBOX_WITH_VIRTIO
+ else if (!RTStrICmp(ValueUnion.psz, "virtio"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Virtio));
+ }
+#endif /* VBOX_WITH_VIRTIO */
+ else if (!RTStrICmp(ValueUnion.psz, "NE1000"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE1000));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "NE2000"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE2000));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "WD8003"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8003));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "WD8013"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8013));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "3C503"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK2));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "3C501"))
+ {
+ CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK1));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid NIC type '%s' specified for NIC %u"),
+ ValueUnion.psz, GetOptState.uIndex);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_NICSPEED:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(LineSpeed)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_NICBOOTPRIO:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* Somewhat arbitrary limitation - we can pass a list of up to 4 PCI devices
+ * to the PXE ROM, hence only boot priorities 1-4 are allowed (in addition to
+ * 0 for the default lowest priority).
+ */
+ if (ValueUnion.u32 > 4)
+ {
+ errorArgument(ModifyVM::tr("Invalid boot priority '%u' specfied for NIC %u"), ValueUnion.u32, GetOptState.uIndex);
+ hrc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(BootPriority)(ValueUnion.u32));
+ }
+ break;
+ }
+
+ case MODIFYVM_NICPROMISC:
+ {
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ if (!RTStrICmp(ValueUnion.psz, "deny"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
+ else if ( !RTStrICmp(ValueUnion.psz, "allow-vms")
+ || !RTStrICmp(ValueUnion.psz, "allow-network"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
+ else if (!RTStrICmp(ValueUnion.psz, "allow-all"))
+ enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
+ else
+ {
+ errorArgument(ModifyVM::tr("Unknown promiscuous mode policy '%s'"), ValueUnion.psz);
+ hrc = E_INVALIDARG;
+ break;
+ }
+
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
+ break;
+ }
+
+ case MODIFYVM_NICBWGROUP:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ /* Just remove the bandwidth group. */
+ CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(NULL));
+ }
+ else
+ {
+ ComPtr<IBandwidthControl> bwCtrl;
+ ComPtr<IBandwidthGroup> bwGroup;
+
+ CHECK_ERROR(sessionMachine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(ValueUnion.psz).raw(), bwGroup.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(bwGroup));
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_NIC:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /*
+ * Check if the NIC is already enabled. Do not try to
+ * enable it if it already is. That makes a
+ * difference for saved VMs for which you can change
+ * the NIC attachment, but can't change the NIC
+ * enabled status (yes, the setter also should not
+ * freak out about a no-op request).
+ */
+ BOOL fEnabled;;
+ CHECK_ERROR(nic, COMGETTER(Enabled)(&fEnabled));
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ if (RT_BOOL(fEnabled))
+ CHECK_ERROR(nic, COMSETTER(Enabled)(FALSE));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "null"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Null));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "nat"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT));
+ }
+ else if ( !RTStrICmp(ValueUnion.psz, "bridged")
+ || !RTStrICmp(ValueUnion.psz, "hostif")) /* backward compatibility */
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "intnet"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "hostonly"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly));
+ }
+#ifdef VBOX_WITH_VMNET
+ else if (!RTStrICmp(ValueUnion.psz, "hostonlynet"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnlyNetwork));
+ }
+#endif /* VBOX_WITH_VMNET */
+ else if (!RTStrICmp(ValueUnion.psz, "generic"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "natnetwork"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork));
+ }
+#ifdef VBOX_WITH_CLOUD_NET
+ else if (!RTStrICmp(ValueUnion.psz, "cloud"))
+ {
+ if (!fEnabled)
+ CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
+ CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Cloud));
+ }
+#endif /* VBOX_WITH_CLOUD_NET */
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid type '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_CABLECONNECTED:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(CableConnected)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_BRIDGEADAPTER:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* remove it? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr(ValueUnion.psz).raw()));
+ verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
+ HostNetworkInterfaceType_Bridged);
+ }
+ break;
+ }
+
+#ifdef VBOX_WITH_CLOUD_NET
+ case MODIFYVM_CLOUDNET:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* remove it? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr(ValueUnion.psz).raw()));
+ }
+ break;
+ }
+#endif /* VBOX_WITH_CLOUD_NET */
+
+ case MODIFYVM_HOSTONLYADAPTER:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* remove it? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr(ValueUnion.psz).raw()));
+ verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
+ HostNetworkInterfaceType_HostOnly);
+ }
+ break;
+ }
+
+#ifdef VBOX_WITH_VMNET
+ case MODIFYVM_HOSTONLYNET:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* remove it? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr(ValueUnion.psz).raw()));
+ }
+ break;
+ }
+#endif /* VBOX_WITH_VMNET */
+
+ case MODIFYVM_INTNET:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* remove it? */
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw()));
+ }
+ break;
+ }
+
+ case MODIFYVM_GENERICDRV:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NATNETWORKNAME:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMSETTER(NATNetwork)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NATNET:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ const char *psz = ValueUnion.psz;
+ if (!RTStrICmp("default", psz))
+ psz = "";
+
+ CHECK_ERROR(engine, COMSETTER(Network)(Bstr(psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NATBINDIP:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(HostIP)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+#define ITERATE_TO_NEXT_TERM(ch) \
+ do { \
+ while (*ch != ',') \
+ { \
+ if (*ch == 0) \
+ { \
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), \
+ GetOptState.pDef->pszLong); \
+ } \
+ ch++; \
+ } \
+ *ch = '\0'; \
+ ch++; \
+ } while(0)
+
+ case MODIFYVM_NATSETTINGS:
+ {
+ ComPtr<INetworkAdapter> nic;
+ ComPtr<INATEngine> engine;
+ char *strMtu;
+ char *strSockSnd;
+ char *strSockRcv;
+ char *strTcpSnd;
+ char *strTcpRcv;
+ char *strRaw = RTStrDup(ValueUnion.psz);
+ char *ch = strRaw;
+ strMtu = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strSockSnd = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strSockRcv = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strTcpSnd = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strTcpRcv = RTStrStrip(ch);
+
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+ CHECK_ERROR(engine, SetNetworkSettings(RTStrToUInt32(strMtu), RTStrToUInt32(strSockSnd), RTStrToUInt32(strSockRcv),
+ RTStrToUInt32(strTcpSnd), RTStrToUInt32(strTcpRcv)));
+ break;
+ }
+
+
+ case MODIFYVM_NATPF:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ /* format name:proto:hostip:hostport:guestip:guestport*/
+ if (RTStrCmp(ValueUnion.psz, "delete") != 0)
+ {
+ char *strName;
+ char *strProto;
+ char *strHostIp;
+ char *strHostPort;
+ char *strGuestIp;
+ char *strGuestPort;
+ char *strRaw = RTStrDup(ValueUnion.psz);
+ char *ch = strRaw;
+ strName = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strProto = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strHostIp = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strHostPort = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strGuestIp = RTStrStrip(ch);
+ ITERATE_TO_NEXT_TERM(ch);
+ strGuestPort = RTStrStrip(ch);
+ NATProtocol_T proto;
+ if (RTStrICmp(strProto, "udp") == 0)
+ proto = NATProtocol_UDP;
+ else if (RTStrICmp(strProto, "tcp") == 0)
+ proto = NATProtocol_TCP;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid proto '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex);
+ hrc = E_FAIL;
+ break;
+ }
+ CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto,
+ Bstr(strHostIp).raw(),
+ RTStrToUInt16(strHostPort),
+ Bstr(strGuestIp).raw(),
+ RTStrToUInt16(strGuestPort)));
+ }
+ else
+ {
+ /* delete NAT Rule operation */
+ int vrc;
+ vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Not enough parameters"));
+ CHECK_ERROR(engine, RemoveRedirect(Bstr(ValueUnion.psz).raw()));
+ }
+ break;
+ }
+ #undef ITERATE_TO_NEXT_TERM
+ case MODIFYVM_NATALIASMODE:
+ {
+ ComPtr<INetworkAdapter> nic;
+ ComPtr<INATEngine> engine;
+ uint32_t aliasMode = 0;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+ if (RTStrCmp(ValueUnion.psz, "default") == 0)
+ aliasMode = 0;
+ else
+ {
+ char *token = (char *)ValueUnion.psz;
+ while (token)
+ {
+ if (RTStrNCmp(token, RT_STR_TUPLE("log")) == 0)
+ aliasMode |= NATAliasMode_AliasLog;
+ else if (RTStrNCmp(token, RT_STR_TUPLE("proxyonly")) == 0)
+ aliasMode |= NATAliasMode_AliasProxyOnly;
+ else if (RTStrNCmp(token, RT_STR_TUPLE("sameports")) == 0)
+ aliasMode |= NATAliasMode_AliasUseSamePorts;
+ token = RTStrStr(token, ",");
+ if (token == NULL)
+ break;
+ token++;
+ }
+ }
+ CHECK_ERROR(engine, COMSETTER(AliasMode)(aliasMode));
+ break;
+ }
+
+ case MODIFYVM_NATTFTPPREFIX:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(TFTPPrefix)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NATTFTPFILE:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(TFTPBootFile)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_NATTFTPSERVER:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(TFTPNextServer)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+ case MODIFYVM_NATDNSPASSDOMAIN:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(DNSPassDomain)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_NATDNSPROXY:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(DNSProxy)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_NATDNSHOSTRESOLVER:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(DNSUseHostResolver)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_NATLOCALHOSTREACHABLE:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ ComPtr<INATEngine> engine;
+ CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
+
+ CHECK_ERROR(engine, COMSETTER(LocalhostReachable)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_MACADDRESS:
+ {
+ if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
+ break;
+
+ ComPtr<INetworkAdapter> nic;
+ CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
+ ASSERT(nic);
+
+ /* generate one? */
+ if (!RTStrICmp(ValueUnion.psz, "auto"))
+ {
+ CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr().raw()));
+ }
+ else
+ {
+ CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr(ValueUnion.psz).raw()));
+ }
+ break;
+ }
+
+ case MODIFYVM_HIDPTR:
+ {
+ bool fEnableUsb = false;
+ if (!RTStrICmp(ValueUnion.psz, "ps2"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "usb"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "usbtablet"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "usbmultitouch"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "usbmtscreenpluspad"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouchScreenPlusPad));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_None));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid type '%s' specfied for pointing device"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ if (fEnableUsb)
+ {
+ /* Make sure either the OHCI or xHCI controller is enabled. */
+ ULONG cOhciCtrls = 0;
+ ULONG cXhciCtrls = 0;
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+ if (SUCCEEDED(hrc)) {
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
+ if ( SUCCEEDED(hrc)
+ && cOhciCtrls + cXhciCtrls == 0)
+ {
+ /* If there's nothing, enable OHCI (always available). */
+ ComPtr<IUSBController> UsbCtl;
+ CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+ UsbCtl.asOutParam()));
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_HIDKBD:
+ {
+ bool fEnableUsb = false;
+ if (!RTStrICmp(ValueUnion.psz, "ps2"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_PS2Keyboard));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "usb"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_USBKeyboard));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "none"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_None));
+ if (SUCCEEDED(hrc))
+ fEnableUsb = true;
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid type '%s' specfied for keyboard"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ if (fEnableUsb)
+ {
+ /* Make sure either the OHCI or xHCI controller is enabled. */
+ ULONG cOhciCtrls = 0;
+ ULONG cXhciCtrls = 0;
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+ if (SUCCEEDED(hrc)) {
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
+ if ( SUCCEEDED(hrc)
+ && cOhciCtrls + cXhciCtrls == 0)
+ {
+ /* If there's nothing, enable OHCI (always available). */
+ ComPtr<IUSBController> UsbCtl;
+ CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+ UsbCtl.asOutParam()));
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_UARTMODE:
+ {
+ ComPtr<ISerialPort> uart;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+ ASSERT(uart);
+
+ if (!RTStrICmp(ValueUnion.psz, "disconnected"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
+ }
+ else if ( !RTStrICmp(ValueUnion.psz, "server")
+ || !RTStrICmp(ValueUnion.psz, "client")
+ || !RTStrICmp(ValueUnion.psz, "tcpserver")
+ || !RTStrICmp(ValueUnion.psz, "tcpclient")
+ || !RTStrICmp(ValueUnion.psz, "file"))
+ {
+ const char *pszMode = ValueUnion.psz;
+
+ int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+
+ CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
+
+ if (!RTStrICmp(pszMode, "server"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
+ CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
+ }
+ else if (!RTStrICmp(pszMode, "client"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
+ CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
+ }
+ else if (!RTStrICmp(pszMode, "tcpserver"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+ CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
+ }
+ else if (!RTStrICmp(pszMode, "tcpclient"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
+ CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
+ }
+ else if (!RTStrICmp(pszMode, "file"))
+ {
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile));
+ }
+ }
+ else
+ {
+ CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
+ CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostDevice));
+ }
+ break;
+ }
+
+ case MODIFYVM_UARTTYPE:
+ {
+ ComPtr<ISerialPort> uart;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+ ASSERT(uart);
+
+ if (!RTStrICmp(ValueUnion.psz, "16450"))
+ {
+ CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16450));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "16550A"))
+ {
+ CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16550A));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "16750"))
+ {
+ CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16750));
+ }
+ else
+ return errorSyntax(ModifyVM::tr("Invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+ break;
+ }
+
+ case MODIFYVM_UART:
+ {
+ ComPtr<ISerialPort> uart;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
+ ASSERT(uart);
+
+ if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
+ CHECK_ERROR(uart, COMSETTER(Enabled)(FALSE));
+ else
+ {
+ const char *pszIOBase = ValueUnion.psz;
+ uint32_t uVal = 0;
+
+ int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_UART;
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+
+ CHECK_ERROR(uart, COMSETTER(IRQ)(ValueUnion.u32));
+
+ vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal);
+ if (vrc != VINF_SUCCESS || uVal == 0)
+ return errorArgument(ModifyVM::tr("Error parsing UART I/O base '%s'"), pszIOBase);
+ CHECK_ERROR(uart, COMSETTER(IOBase)(uVal));
+
+ CHECK_ERROR(uart, COMSETTER(Enabled)(TRUE));
+ }
+ break;
+ }
+
+#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
+ case MODIFYVM_LPTMODE:
+ {
+ ComPtr<IParallelPort> lpt;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
+ ASSERT(lpt);
+
+ CHECK_ERROR(lpt, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_LPT:
+ {
+ ComPtr<IParallelPort> lpt;
+
+ CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
+ ASSERT(lpt);
+
+ if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
+ CHECK_ERROR(lpt, COMSETTER(Enabled)(FALSE));
+ else
+ {
+ const char *pszIOBase = ValueUnion.psz;
+ uint32_t uVal = 0;
+
+ int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_LPT;
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+
+ CHECK_ERROR(lpt, COMSETTER(IRQ)(ValueUnion.u32));
+
+ vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal);
+ if (vrc != VINF_SUCCESS || uVal == 0)
+ return errorArgument(ModifyVM::tr("Error parsing LPT I/O base '%s'"), pszIOBase);
+ CHECK_ERROR(lpt, COMSETTER(IOBase)(uVal));
+
+ CHECK_ERROR(lpt, COMSETTER(Enabled)(TRUE));
+ }
+ break;
+ }
+#endif
+
+ case MODIFYVM_GUESTMEMORYBALLOON:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(MemoryBalloonSize)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_AUDIOCONTROLLER:
+ {
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+
+ if (!RTStrICmp(ValueUnion.psz, "sb16"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16));
+ else if (!RTStrICmp(ValueUnion.psz, "ac97"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97));
+ else if (!RTStrICmp(ValueUnion.psz, "hda"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_HDA));
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --audiocontroller argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_AUDIOCODEC:
+ {
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+
+ if (!RTStrICmp(ValueUnion.psz, "sb16"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_SB16));
+ else if (!RTStrICmp(ValueUnion.psz, "stac9700"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9700));
+ else if (!RTStrICmp(ValueUnion.psz, "ad1980"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_AD1980));
+ else if (!RTStrICmp(ValueUnion.psz, "stac9221"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9221));
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --audiocodec argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_AUDIODRIVER:
+ RT_FALL_THROUGH();
+ case MODIFYVM_AUDIO: /** @todo Deprecated; remove. */
+ {
+ if (c == MODIFYVM_AUDIO)
+ RTStrmPrintf(g_pStdErr,
+ ModifyVM::tr("Warning: --audio is deprecated and will be removed soon. Use --audio-driver instead!\n"));
+
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+ /* disable? */
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "null"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null));
+ else if (!RTStrICmp(ValueUnion.psz, "default"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Default));
+#ifdef RT_OS_WINDOWS
+# ifdef VBOX_WITH_WINMM
+ else if (!RTStrICmp(ValueUnion.psz, "winmm"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM));
+# endif
+ else if (!RTStrICmp(ValueUnion.psz, "dsound"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound));
+ else if (!RTStrICmp(ValueUnion.psz, "was"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WAS));
+#endif /* RT_OS_WINDOWS */
+#ifdef VBOX_WITH_AUDIO_OSS
+ else if (!RTStrICmp(ValueUnion.psz, "oss"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS));
+#endif
+#ifdef VBOX_WITH_AUDIO_ALSA
+ else if (!RTStrICmp(ValueUnion.psz, "alsa"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA));
+#endif
+#ifdef VBOX_WITH_AUDIO_PULSE
+ else if (!RTStrICmp(ValueUnion.psz, "pulse"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse));
+#endif
+#ifdef RT_OS_DARWIN
+ else if (!RTStrICmp(ValueUnion.psz, "coreaudio"))
+ CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio));
+#endif /* !RT_OS_DARWIN */
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid %s argument '%s'"),
+ c == MODIFYVM_AUDIO ? "--audio" : "--audio-driver", ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+
+ if ( SUCCEEDED(hrc)
+ && c == MODIFYVM_AUDIO) /* To keep the original behavior until we remove the command. */
+ CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(RTStrICmp(ValueUnion.psz, "none") == false ? false : true));
+
+ break;
+ }
+
+ case MODIFYVM_AUDIOENABLED:
+ {
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+
+ CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_AUDIOIN:
+ {
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+
+ CHECK_ERROR(audioAdapter, COMSETTER(EnabledIn)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_AUDIOOUT:
+ {
+ ComPtr<IAudioSettings> audioSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
+ ComPtr<IAudioAdapter> audioAdapter;
+ CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
+ ASSERT(audioAdapter);
+
+ CHECK_ERROR(audioAdapter, COMSETTER(EnabledOut)(ValueUnion.f));
+ break;
+ }
+
+#ifdef VBOX_WITH_SHARED_CLIPBOARD
+ case MODIFYVM_CLIPBOARD_MODE:
+ {
+ ClipboardMode_T mode = ClipboardMode_Disabled; /* Shut up MSC */
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ mode = ClipboardMode_Disabled;
+ else if (!RTStrICmp(ValueUnion.psz, "hosttoguest"))
+ mode = ClipboardMode_HostToGuest;
+ else if (!RTStrICmp(ValueUnion.psz, "guesttohost"))
+ mode = ClipboardMode_GuestToHost;
+ else if (!RTStrICmp(ValueUnion.psz, "bidirectional"))
+ mode = ClipboardMode_Bidirectional;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --clipboard-mode argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(ClipboardMode)(mode));
+ }
+ break;
+ }
+
+# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+ case MODIFYVM_CLIPBOARD_FILE_TRANSFERS:
+ {
+ BOOL fEnabled = false; /* Shut up MSC */
+ if (!RTStrICmp(ValueUnion.psz, "enabled"))
+ fEnabled = true;
+ else if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ fEnabled = false;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --clipboard-file-transfers argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(ClipboardFileTransfersEnabled)(fEnabled));
+ }
+ break;
+ }
+# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
+#endif /* VBOX_WITH_SHARED_CLIPBOARD */
+
+ case MODIFYVM_DRAGANDDROP:
+ {
+ DnDMode_T mode = DnDMode_Disabled; /* Shut up MSC */
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ mode = DnDMode_Disabled;
+ else if (!RTStrICmp(ValueUnion.psz, "hosttoguest"))
+ mode = DnDMode_HostToGuest;
+ else if (!RTStrICmp(ValueUnion.psz, "guesttohost"))
+ mode = DnDMode_GuestToHost;
+ else if (!RTStrICmp(ValueUnion.psz, "bidirectional"))
+ mode = DnDMode_Bidirectional;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --draganddrop argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(DnDMode)(mode));
+ }
+ break;
+ }
+
+ case MODIFYVM_VRDE_EXTPACK:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ if (vrdeServer)
+ {
+ if (RTStrICmp(ValueUnion.psz, "default") != 0)
+ {
+ Bstr bstr(ValueUnion.psz);
+ CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(bstr.raw()));
+ }
+ else
+ CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(Bstr().raw()));
+ }
+ break;
+ }
+
+ case MODIFYVM_VRDEPROPERTY:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ if (vrdeServer)
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(ValueUnion.psz);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName = pszProperty;
+ Bstr bstrValue = &pDelimiter[1];
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(bstrName.raw(), bstrValue.raw()));
+ }
+ else
+ {
+ RTStrFree(pszProperty);
+
+ errorArgument(ModifyVM::tr("Invalid --vrdeproperty argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ break;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for VRDE property '%s'\n"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_VRDPPORT:
+ vrdeWarningDeprecatedOption("port");
+ RT_FALL_THRU();
+
+ case MODIFYVM_VRDEPORT:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ if (!RTStrICmp(ValueUnion.psz, "default"))
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr("0").raw()));
+ else
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_VRDPADDRESS:
+ vrdeWarningDeprecatedOption("address");
+ RT_FALL_THRU();
+
+ case MODIFYVM_VRDEADDRESS:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Address").raw(), Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_VRDPAUTHTYPE:
+ vrdeWarningDeprecatedOption("authtype");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDEAUTHTYPE:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ if (!RTStrICmp(ValueUnion.psz, "null"))
+ {
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Null));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "external"))
+ {
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_External));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "guest"))
+ {
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Guest));
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --vrdeauthtype argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_VRDEAUTHLIBRARY:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ if (vrdeServer)
+ {
+ if (RTStrICmp(ValueUnion.psz, "default") != 0)
+ {
+ Bstr bstr(ValueUnion.psz);
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(bstr.raw()));
+ }
+ else
+ CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(Bstr().raw()));
+ }
+ break;
+ }
+
+ case MODIFYVM_VRDPMULTICON:
+ vrdeWarningDeprecatedOption("multicon");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDEMULTICON:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, COMSETTER(AllowMultiConnection)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VRDPREUSECON:
+ vrdeWarningDeprecatedOption("reusecon");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDEREUSECON:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, COMSETTER(ReuseSingleConnection)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_VRDPVIDEOCHANNEL:
+ vrdeWarningDeprecatedOption("videochannel");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDEVIDEOCHANNEL:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Enabled").raw(),
+ ValueUnion.f? Bstr("true").raw(): Bstr("false").raw()));
+ break;
+ }
+
+ case MODIFYVM_VRDPVIDEOCHANNELQUALITY:
+ vrdeWarningDeprecatedOption("videochannelquality");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDEVIDEOCHANNELQUALITY:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Quality").raw(),
+ Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_VRDP:
+ vrdeWarningDeprecatedOption("");
+ RT_FALL_THRU();
+ case MODIFYVM_VRDE:
+ {
+ ComPtr<IVRDEServer> vrdeServer;
+ sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
+ ASSERT(vrdeServer);
+
+ CHECK_ERROR(vrdeServer, COMSETTER(Enabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_USBRENAME:
+ {
+ const char *pszName = ValueUnion.psz;
+ int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
+ GetOptState.pDef->pszLong);
+ const char *pszNewName = ValueUnion.psz;
+
+ SafeIfaceArray<IUSBController> ctrls;
+ CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
+ bool fRenamed = false;
+ for (size_t i = 0; i < ctrls.size(); i++)
+ {
+ ComPtr<IUSBController> pCtrl = ctrls[i];
+ Bstr bstrName;
+ CHECK_ERROR(pCtrl, COMGETTER(Name)(bstrName.asOutParam()));
+ if (bstrName == pszName)
+ {
+ bstrName = pszNewName;
+ CHECK_ERROR(pCtrl, COMSETTER(Name)(bstrName.raw()));
+ fRenamed = true;
+ }
+ }
+ if (!fRenamed)
+ {
+ errorArgument(ModifyVM::tr("Invalid --usbrename parameters, nothing renamed"));
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_USBXHCI:
+ {
+ ULONG cXhciCtrls = 0;
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
+ if (SUCCEEDED(hrc))
+ {
+ if (!cXhciCtrls && ValueUnion.f)
+ {
+ ComPtr<IUSBController> UsbCtl;
+ CHECK_ERROR(sessionMachine, AddUSBController(Bstr("xHCI").raw(), USBControllerType_XHCI,
+ UsbCtl.asOutParam()));
+ }
+ else if (cXhciCtrls && !ValueUnion.f)
+ {
+ SafeIfaceArray<IUSBController> ctrls;
+ CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
+ for (size_t i = 0; i < ctrls.size(); i++)
+ {
+ ComPtr<IUSBController> pCtrl = ctrls[i];
+ USBControllerType_T enmType;
+ CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
+ if (enmType == USBControllerType_XHCI)
+ {
+ Bstr ctrlName;
+ CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
+ CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_USBEHCI:
+ {
+ ULONG cEhciCtrls = 0;
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_EHCI, &cEhciCtrls);
+ if (SUCCEEDED(hrc))
+ {
+ if (!cEhciCtrls && ValueUnion.f)
+ {
+ ComPtr<IUSBController> UsbCtl;
+ CHECK_ERROR(sessionMachine, AddUSBController(Bstr("EHCI").raw(), USBControllerType_EHCI,
+ UsbCtl.asOutParam()));
+ }
+ else if (cEhciCtrls && !ValueUnion.f)
+ {
+ SafeIfaceArray<IUSBController> ctrls;
+ CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
+ for (size_t i = 0; i < ctrls.size(); i++)
+ {
+ ComPtr<IUSBController> pCtrl = ctrls[i];
+ USBControllerType_T enmType;
+ CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
+ if (enmType == USBControllerType_EHCI)
+ {
+ Bstr ctrlName;
+ CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
+ CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_USBOHCI:
+ {
+ ULONG cOhciCtrls = 0;
+ hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
+ if (SUCCEEDED(hrc))
+ {
+ if (!cOhciCtrls && ValueUnion.f)
+ {
+ ComPtr<IUSBController> UsbCtl;
+ CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
+ UsbCtl.asOutParam()));
+ }
+ else if (cOhciCtrls && !ValueUnion.f)
+ {
+ SafeIfaceArray<IUSBController> ctrls;
+ CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
+ for (size_t i = 0; i < ctrls.size(); i++)
+ {
+ ComPtr<IUSBController> pCtrl = ctrls[i];
+ USBControllerType_T enmType;
+ CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
+ if (enmType == USBControllerType_OHCI)
+ {
+ Bstr ctrlName;
+ CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
+ CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MODIFYVM_SNAPSHOTFOLDER:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "default"))
+ CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr().raw()));
+ else
+ CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_TELEPORTER_ENABLED:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TeleporterEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_TELEPORTER_PORT:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPort)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_TELEPORTER_ADDRESS:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TeleporterAddress)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_TELEPORTER_PASSWORD:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_TELEPORTER_PASSWORD_FILE:
+ {
+ Utf8Str password;
+ RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &password);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ hrc = E_FAIL;
+ else
+ CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(password).raw()));
+ break;
+ }
+
+ case MODIFYVM_TRACING_ENABLED:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TracingEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_TRACING_CONFIG:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(TracingConfig)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_TRACING_ALLOW_VM_ACCESS:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(AllowTracingToAccessVM)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_HARDWARE_UUID:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(HardwareUUID)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+
+ case MODIFYVM_HPET:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(HPETEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_IOCACHE:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(IOCacheEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_IOCACHESIZE:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(IOCacheSize)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_CHIPSET:
+ {
+ if (!RTStrICmp(ValueUnion.psz, "piix3"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_PIIX3));
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "ich9"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_ICH9));
+ BOOL fIoApic = FALSE;
+ CHECK_ERROR(biosSettings, COMGETTER(IOAPICEnabled)(&fIoApic));
+ if (!fIoApic)
+ {
+ RTStrmPrintf(g_pStdErr, ModifyVM::tr("*** I/O APIC must be enabled for ICH9, enabling. ***\n"));
+ CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(TRUE));
+ }
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --chipset argument '%s' (valid: piix3,ich9)"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
+ case MODIFYVM_IOMMU:
+ {
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "disabled"))
+ CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_None));
+ else if (!RTStrICmp(ValueUnion.psz, "amd"))
+ CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_AMD));
+ else if (!RTStrICmp(ValueUnion.psz, "intel"))
+ {
+#ifdef VBOX_WITH_IOMMU_INTEL
+ CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Intel));
+#else
+ errorArgument(ModifyVM::tr("Invalid --iommu argument '%s' (valid: none,amd,automatic)"), ValueUnion.psz);
+ hrc = E_FAIL;
+#endif
+ }
+ else if (!RTStrICmp(ValueUnion.psz, "automatic"))
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Automatic));
+#ifndef VBOX_WITH_IOMMU_INTEL
+ RTStrmPrintf(g_pStdErr,
+ ModifyVM::tr("Warning: On Intel hosts, 'automatic' will not enable an IOMMU since the Intel IOMMU device is not supported yet.\n"));
+#endif
+ }
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --iommu argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+#endif
+#if defined(VBOX_WITH_TPM)
+ case MODIFYVM_TPM_TYPE:
+ {
+ ComPtr<ITrustedPlatformModule> tpm;
+ sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam());
+
+ if ( !RTStrICmp(ValueUnion.psz, "none")
+ || !RTStrICmp(ValueUnion.psz, "disabled"))
+ CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_None));
+ else if (!RTStrICmp(ValueUnion.psz, "1.2"))
+ CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v1_2));
+ else if (!RTStrICmp(ValueUnion.psz, "2.0"))
+ CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v2_0));
+ else if (!RTStrICmp(ValueUnion.psz, "host"))
+ CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Host));
+ else if (!RTStrICmp(ValueUnion.psz, "swtpm"))
+ CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Swtpm));
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --tpm-type argument '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ break;
+ }
+
+ case MODIFYVM_TPM_LOCATION:
+ {
+ ComPtr<ITrustedPlatformModule> tpm;
+ sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam());
+
+ CHECK_ERROR(tpm, COMSETTER(Location)(Bstr(ValueUnion.psz).raw()));
+ break;
+ }
+#endif
+#ifdef VBOX_WITH_RECORDING
+ case MODIFYVM_RECORDING:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_SCREENS:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_FILENAME:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_VIDEO_WIDTH:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_VIDEO_HEIGHT:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_VIDEO_RES:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_VIDEO_RATE:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_VIDEO_FPS:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_MAXTIME:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_MAXSIZE:
+ RT_FALL_THROUGH();
+ case MODIFYVM_RECORDING_OPTIONS:
+ {
+ ComPtr<IRecordingSettings> recordingSettings;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()));
+ SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
+ CHECK_ERROR_BREAK(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)));
+
+ switch (c)
+ {
+ case MODIFYVM_RECORDING:
+ {
+ CHECK_ERROR(recordingSettings, COMSETTER(Enabled)(ValueUnion.f));
+ break;
+ }
+ case MODIFYVM_RECORDING_SCREENS:
+ {
+ ULONG cMonitors = 64;
+ CHECK_ERROR(pGraphicsAdapter, COMGETTER(MonitorCount)(&cMonitors));
+ com::SafeArray<BOOL> screens(cMonitors);
+ if (RT_FAILURE(parseScreens(ValueUnion.psz, &screens)))
+ {
+ errorArgument(ModifyVM::tr("Invalid list of screens specified\n"));
+ hrc = E_FAIL;
+ break;
+ }
+
+ if (cMonitors > saRecordingScreenScreens.size()) /* Paranoia. */
+ cMonitors = (ULONG)saRecordingScreenScreens.size();
+
+ for (size_t i = 0; i < cMonitors; ++i)
+ CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Enabled)(screens[i]));
+ break;
+ }
+ case MODIFYVM_RECORDING_FILENAME:
+ {
+ Bstr bstr;
+ /* empty string will fall through, leaving bstr empty */
+ if (*ValueUnion.psz)
+ {
+ char szVCFileAbs[RTPATH_MAX] = "";
+ int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs));
+ if (RT_FAILURE(vrc))
+ {
+ errorArgument(ModifyVM::tr("Cannot convert filename \"%s\" to absolute path\n"), ValueUnion.psz);
+ hrc = E_FAIL;
+ break;
+ }
+ bstr = szVCFileAbs;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Filename)(bstr.raw()));
+ break;
+ }
+ case MODIFYVM_RECORDING_VIDEO_WIDTH:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_VIDEO_HEIGHT:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_VIDEO_RES:
+ {
+ uint32_t uWidth = 0;
+ char *pszNext;
+ int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth);
+ if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x')
+ {
+ errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected <width>x<height>)"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ break;
+ }
+ uint32_t uHeight = 0;
+ vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight);
+ if (vrc != VINF_SUCCESS)
+ {
+ errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected <width>x<height>)"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ break;
+ }
+
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ {
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(uWidth));
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(uHeight));
+ }
+ break;
+ }
+ case MODIFYVM_RECORDING_VIDEO_RATE:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoRate)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_VIDEO_FPS:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoFPS)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_MAXTIME:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxTime)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_MAXSIZE:
+ {
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxFileSize)(ValueUnion.u32));
+ break;
+ }
+ case MODIFYVM_RECORDING_OPTIONS:
+ {
+ Bstr bstr(ValueUnion.psz);
+ for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
+ CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Options)(bstr.raw()));
+ break;
+ }
+ }
+
+ break;
+ }
+#endif
+ case MODIFYVM_AUTOSTART_ENABLED:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(ValueUnion.f));
+ break;
+ }
+
+ case MODIFYVM_AUTOSTART_DELAY:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(ValueUnion.u32));
+ break;
+ }
+
+ case MODIFYVM_AUTOSTOP_TYPE:
+ {
+ AutostopType_T enmAutostopType = AutostopType_Disabled;
+
+ if (!RTStrICmp(ValueUnion.psz, "disabled"))
+ enmAutostopType = AutostopType_Disabled;
+ else if (!RTStrICmp(ValueUnion.psz, "savestate"))
+ enmAutostopType = AutostopType_SaveState;
+ else if (!RTStrICmp(ValueUnion.psz, "poweroff"))
+ enmAutostopType = AutostopType_PowerOff;
+ else if (!RTStrICmp(ValueUnion.psz, "acpishutdown"))
+ enmAutostopType = AutostopType_AcpiShutdown;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --autostop-type argument '%s' (valid: disabled, savestate, poweroff, acpishutdown)"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(sessionMachine, COMSETTER(AutostopType)(enmAutostopType));
+ break;
+ }
+#ifdef VBOX_WITH_PCI_PASSTHROUGH
+ case MODIFYVM_ATTACH_PCI:
+ {
+ const char* pAt = strchr(ValueUnion.psz, '@');
+ int32_t iHostAddr, iGuestAddr;
+
+ iHostAddr = parsePci(ValueUnion.psz);
+ iGuestAddr = pAt != NULL ? parsePci(pAt + 1) : iHostAddr;
+
+ if (iHostAddr == -1 || iGuestAddr == -1)
+ {
+ errorArgument(ModifyVM::tr("Invalid --pciattach argument '%s' (valid: 'HB:HD.HF@GB:GD.GF' or just 'HB:HD.HF')"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(sessionMachine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE));
+ }
+
+ break;
+ }
+ case MODIFYVM_DETACH_PCI:
+ {
+ int32_t iHostAddr;
+
+ iHostAddr = parsePci(ValueUnion.psz);
+ if (iHostAddr == -1)
+ {
+ errorArgument(ModifyVM::tr("Invalid --pcidetach argument '%s' (valid: 'HB:HD.HF')"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(sessionMachine, DetachHostPCIDevice(iHostAddr));
+ }
+
+ break;
+ }
+#endif
+
+#ifdef VBOX_WITH_USB_CARDREADER
+ case MODIFYVM_USBCARDREADER:
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f));
+ break;
+ }
+#endif /* VBOX_WITH_USB_CARDREADER */
+
+ case MODIFYVM_DEFAULTFRONTEND:
+ {
+ Bstr bstr(ValueUnion.psz);
+ if (bstr == "default")
+ bstr = Bstr::Empty;
+ CHECK_ERROR(sessionMachine, COMSETTER(DefaultFrontend)(bstr.raw()));
+ break;
+ }
+
+ case MODIFYVM_VMPROC_PRIORITY:
+ {
+ VMProcPriority_T enmPriority = nameToVMProcPriority(ValueUnion.psz);
+ if (enmPriority == VMProcPriority_Invalid)
+ {
+ errorArgument(ModifyVM::tr("Invalid --vm-process-priority '%s'"), ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+ else
+ {
+ CHECK_ERROR(sessionMachine, COMSETTER(VMProcessPriority)(enmPriority));
+ }
+ break;
+ }
+
+ case MODIFYVM_TESTING_ENABLED:
+ hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled", ValueUnion.f ? "1" : "");
+ break;
+
+ case MODIFYVM_TESTING_MMIO:
+ hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO", ValueUnion.f ? "1" : "");
+ break;
+
+ case MODIFYVM_TESTING_CFG_DWORD:
+ if (GetOptState.uIndex <= 9)
+ {
+ char szVar[128];
+ RTStrPrintf(szVar, sizeof(szVar), "VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u",
+ GetOptState.uIndex);
+ char szValue[32];
+ RTStrPrintf(szValue, sizeof(szValue), "%u", ValueUnion.u32);
+ hrc = setExtraData(sessionMachine, szVar, szValue);
+ }
+ else
+ hrc = errorArgumentHr(ModifyVM::tr("--testing-cfg-dword index %u is out of range: 0 thru 9"),
+ GetOptState.uIndex);
+ break;
+
+ case MODIFYVM_GUEST_DEBUG_PROVIDER:
+ {
+ ComPtr<IGuestDebugControl> gstDbgCtrl;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
+
+ GuestDebugProvider_T enmDebugProvider = GuestDebugProvider_None;
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ enmDebugProvider = GuestDebugProvider_None;
+ else if (!RTStrICmp(ValueUnion.psz, "native"))
+ enmDebugProvider = GuestDebugProvider_Native;
+ else if (!RTStrICmp(ValueUnion.psz, "gdb"))
+ enmDebugProvider = GuestDebugProvider_GDB;
+ else if (!RTStrICmp(ValueUnion.psz, "kd"))
+ enmDebugProvider = GuestDebugProvider_KD;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --guest-debug-provider '%s' (valid: none, native, gdb, kd)"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugProvider)(enmDebugProvider));
+ break;
+ }
+
+ case MODIFYVM_GUEST_DEBUG_IO_PROVIDER:
+ {
+ ComPtr<IGuestDebugControl> gstDbgCtrl;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
+
+ GuestDebugIoProvider_T enmDebugIoProvider = GuestDebugIoProvider_None;
+
+ if (!RTStrICmp(ValueUnion.psz, "none"))
+ enmDebugIoProvider = GuestDebugIoProvider_None;
+ else if (!RTStrICmp(ValueUnion.psz, "tcp"))
+ enmDebugIoProvider = GuestDebugIoProvider_TCP;
+ else if (!RTStrICmp(ValueUnion.psz, "udp"))
+ enmDebugIoProvider = GuestDebugIoProvider_UDP;
+ else if (!RTStrICmp(ValueUnion.psz, "ipc"))
+ enmDebugIoProvider = GuestDebugIoProvider_IPC;
+ else
+ {
+ errorArgument(ModifyVM::tr("Invalid --guest-debug-io-provider '%s' (valid: none, tcp, udp, ipc)"),
+ ValueUnion.psz);
+ hrc = E_FAIL;
+ }
+
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugIoProvider)(enmDebugIoProvider));
+ break;
+ }
+
+ case MODIFYVM_GUEST_DEBUG_ADDRESS:
+ {
+ ComPtr<IGuestDebugControl> gstDbgCtrl;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
+
+ Bstr bstr(ValueUnion.psz);
+ CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugAddress)(bstr.raw()));
+ break;
+ }
+
+ case MODIFYVM_GUEST_DEBUG_PORT:
+ {
+ ComPtr<IGuestDebugControl> gstDbgCtrl;
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
+ CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugPort)(ValueUnion.u32));
+ break;
+ }
+
+ default:
+ errorGetOpt(c, &ValueUnion);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+
+ /* commit changes */
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(sessionMachine, SaveSettings());
+
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp
new file mode 100644
index 00000000..8f911fec
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageNATNetwork.cpp
@@ -0,0 +1,702 @@
+/* $Id: VBoxManageNATNetwork.cpp $ */
+/** @file
+ * VBoxManage - Implementation of NAT Network command 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#ifndef RT_OS_WINDOWS
+# include <netinet/in.h>
+#else
+/* from <ws2ipdef.h> */
+# define INET6_ADDRSTRLEN 65
+#endif
+
+#define IPv6
+
+#include <iprt/cdefs.h>
+#include <iprt/cidr.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/net.h>
+#include <iprt/getopt.h>
+#include <iprt/ctype.h>
+
+#include <VBox/log.h>
+
+#include <algorithm>
+#include <vector>
+#include <iprt/sanitized/string>
+
+#include "VBoxManage.h"
+#include "VBoxPortForwardString.h"
+
+
+DECLARE_TRANSLATION_CONTEXT(Nat);
+
+using namespace com;
+
+typedef enum
+{
+ OP_ADD = 1000,
+ OP_REMOVE,
+ OP_MODIFY,
+ OP_START,
+ OP_STOP
+} OPCODE;
+
+typedef struct PFNAME2DELETE
+{
+ char szName[PF_NAMELEN];
+ bool fIPv6;
+} PFNAME2DELETE, *PPFNAME2DELETE;
+
+typedef std::vector<PFNAME2DELETE> VPF2DELETE;
+typedef VPF2DELETE::const_iterator VPF2DELETEITERATOR;
+
+typedef std::vector<PORTFORWARDRULE> VPF2ADD;
+typedef VPF2ADD::const_iterator VPF2ADDITERATOR;
+
+typedef std::vector<std::string> LOOPBACK2DELETEADD;
+typedef LOOPBACK2DELETEADD::iterator LOOPBACK2DELETEADDITERATOR;
+
+static HRESULT printNATNetwork(const ComPtr<INATNetwork> &pNATNet,
+ bool fLong = true)
+{
+ HRESULT hrc;
+
+ do
+ {
+ Bstr strVal;
+ BOOL fVal;
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(NetworkName)(strVal.asOutParam()));
+ RTPrintf(Nat::tr("Name: %ls\n"), strVal.raw());
+
+ if (fLong)
+ {
+ /*
+ * What does it even mean for a natnet to be disabled?
+ * (rhetorical question). Anyway, don't print it unless
+ * asked for a complete dump.
+ */
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(Enabled)(&fVal));
+ RTPrintf(Nat::tr("Enabled: %s\n"), fVal ? Nat::tr("Yes") : Nat::tr("No"));
+ }
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(Network)(strVal.asOutParam()));
+ RTPrintf(Nat::tr("Network: %ls\n"), strVal.raw());
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(Gateway)(strVal.asOutParam()));
+ RTPrintf(Nat::tr("Gateway: %ls\n"), strVal.raw());
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(NeedDhcpServer)(&fVal));
+ RTPrintf(Nat::tr("DHCP Server: %s\n"), fVal ? Nat::tr("Yes") : Nat::tr("No"));
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(IPv6Enabled)(&fVal));
+ RTPrintf("IPv6: %s\n", fVal ? Nat::tr("Yes") : Nat::tr("No"));
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(IPv6Prefix)(strVal.asOutParam()));
+ RTPrintf(Nat::tr("IPv6 Prefix: %ls\n"), strVal.raw());
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(AdvertiseDefaultIPv6RouteEnabled)(&fVal));
+ RTPrintf(Nat::tr("IPv6 Default: %s\n"), fVal ? Nat::tr("Yes") : Nat::tr("No"));
+
+
+ if (fLong)
+ {
+ com::SafeArray<BSTR> strs;
+
+#define PRINT_STRING_ARRAY(title) do { \
+ if (strs.size() > 0) \
+ { \
+ RTPrintf(title); \
+ for (size_t j = 0; j < strs.size(); ++j) \
+ RTPrintf(" %s\n", Utf8Str(strs[j]).c_str()); \
+ } \
+ } while (0)
+
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(PortForwardRules4)(ComSafeArrayAsOutParam(strs)));
+ PRINT_STRING_ARRAY(Nat::tr("Port-forwarding (ipv4)\n"));
+ strs.setNull();
+
+ CHECK_ERROR(pNATNet, COMGETTER(PortForwardRules6)(ComSafeArrayAsOutParam(strs)));
+ PRINT_STRING_ARRAY(Nat::tr("Port-forwarding (ipv6)\n"));
+ strs.setNull();
+
+ CHECK_ERROR(pNATNet, COMGETTER(LocalMappings)(ComSafeArrayAsOutParam(strs)));
+ PRINT_STRING_ARRAY(Nat::tr("loopback mappings (ipv4)\n"));
+ strs.setNull();
+
+#undef PRINT_STRING_ARRAY
+ }
+
+ RTPrintf("\n");
+ } while (0);
+
+ return hrc;
+}
+
+static RTEXITCODE handleNATList(HandlerArg *a)
+{
+ HRESULT hrc;
+
+ RTPrintf(Nat::tr("NAT Networks:\n\n"));
+
+ const char *pszFilter = NULL;
+ if (a->argc > 1)
+ pszFilter = a->argv[1];
+
+ size_t cFound = 0;
+
+ com::SafeIfaceArray<INATNetwork> arrNetNets;
+ CHECK_ERROR(a->virtualBox, COMGETTER(NATNetworks)(ComSafeArrayAsOutParam(arrNetNets)));
+ for (size_t i = 0; i < arrNetNets.size(); ++i)
+ {
+ ComPtr<INATNetwork> pNATNet = arrNetNets[i];
+
+ if (pszFilter)
+ {
+ Bstr strVal;
+ CHECK_ERROR_BREAK(pNATNet, COMGETTER(NetworkName)(strVal.asOutParam()));
+
+ Utf8Str strValUTF8(strVal);
+ if (!RTStrSimplePatternMatch(pszFilter, strValUTF8.c_str()))
+ continue;
+ }
+
+ hrc = printNATNetwork(pNATNet);
+ if (FAILED(hrc))
+ break;
+
+ cFound++;
+ }
+
+ if (SUCCEEDED(hrc))
+ RTPrintf(Nat::tr("%zu %s found\n"), cFound, cFound == 1 ? Nat::tr("network") : Nat::tr("networks", "", cFound));
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+static RTEXITCODE handleOp(HandlerArg *a, OPCODE enmCode)
+{
+ if (a->argc - 1 <= 1)
+ return errorSyntax(Nat::tr("Not enough parameters"));
+
+ const char *pNetName = NULL;
+ const char *pPrefixIPv4 = NULL;
+ const char *pPrefixIPv6 = NULL;
+ int enable = -1;
+ int dhcp = -1;
+ int ipv6 = -1;
+ int ipv6_default = -1;
+
+ VPF2DELETE vPfName2Delete;
+ VPF2ADD vPf2Add;
+
+ LOOPBACK2DELETEADD vLoopback2Delete;
+ LOOPBACK2DELETEADD vLoopback2Add;
+
+ LONG loopback6Offset = 0; /* ignore me */
+
+ enum
+ {
+ kNATNetworkIota = 1000,
+ kNATNetwork_IPv6Default,
+ kNATNetwork_IPv6Prefix,
+ };
+
+ static const RTGETOPTDEF g_aNATNetworkIPOptions[] =
+ {
+ { "--netname", 't', RTGETOPT_REQ_STRING },
+ { "--network", 'n', RTGETOPT_REQ_STRING }, /* old name */
+ { "--ipv4-prefix", 'n', RTGETOPT_REQ_STRING }, /* new name */
+ { "--dhcp", 'h', RTGETOPT_REQ_BOOL },
+ { "--ipv6", '6', RTGETOPT_REQ_BOOL }, /* old name */
+ { "--ipv6-default", kNATNetwork_IPv6Default, RTGETOPT_REQ_BOOL },
+ { "--ipv6-enable", '6', RTGETOPT_REQ_BOOL }, /* new name */
+ { "--ipv6-prefix", kNATNetwork_IPv6Prefix, RTGETOPT_REQ_STRING },
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ { "--port-forward-4", 'p', RTGETOPT_REQ_STRING },
+ { "--port-forward-6", 'P', RTGETOPT_REQ_STRING },
+ { "--loopback-4", 'l', RTGETOPT_REQ_STRING },
+ { "--loopback-6", 'L', RTGETOPT_REQ_STRING },
+ };
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aNATNetworkIPOptions,
+ enmCode != OP_REMOVE ? RT_ELEMENTS(g_aNATNetworkIPOptions) : 4, /* we use only --netname and --ifname for remove*/
+ 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 't': // --netname
+ if (pNetName)
+ return errorSyntax(Nat::tr("You can only specify --netname only once."));
+ pNetName = ValueUnion.psz;
+ break;
+
+ case 'n': // --network
+ if (pPrefixIPv4)
+ return errorSyntax(Nat::tr("You can only specify --network only once."));
+ pPrefixIPv4 = ValueUnion.psz;
+ break;
+
+ case 'e': // --enable
+ if (enable >= 0)
+ return errorSyntax(Nat::tr("You can specify either --enable or --disable once."));
+ enable = 1;
+ break;
+
+ case 'd': // --disable
+ if (enable >= 0)
+ return errorSyntax(Nat::tr("You can specify either --enable or --disable once."));
+ enable = 0;
+ break;
+
+ case 'h':
+ if (dhcp != -1)
+ return errorSyntax(Nat::tr("You can specify --dhcp only once."));
+ dhcp = ValueUnion.f;
+ break;
+
+ case '6':
+ if (ipv6 != -1)
+ return errorSyntax(Nat::tr("You can specify --ipv6 only once."));
+ ipv6 = ValueUnion.f;
+ break;
+
+ case kNATNetwork_IPv6Prefix:
+ if (pPrefixIPv6)
+ return errorSyntax(Nat::tr("You can specify --ipv6-prefix only once."));
+ pPrefixIPv6 = ValueUnion.psz;
+ break;
+
+ case kNATNetwork_IPv6Default: // XXX: uwe
+ if (ipv6_default != -1)
+ return errorSyntax(Nat::tr("You can specify --ipv6-default only once."));
+ ipv6_default = ValueUnion.f;
+ break;
+
+ case 'L': /* ipv6 loopback */
+ case 'l': /* ipv4 loopback */
+ if (RTStrCmp(ValueUnion.psz, "delete") == 0)
+ {
+ /* deletion */
+ if (enmCode != OP_MODIFY)
+ errorSyntax(Nat::tr("loopback couldn't be deleted on modified\n"));
+ if (c == 'L')
+ loopback6Offset = -1;
+ else
+ {
+ int vrc;
+ RTGETOPTUNION Addr2Delete;
+ vrc = RTGetOptFetchValue(&GetState,
+ &Addr2Delete,
+ RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Nat::tr("Not enough parŠ°meters\n"));
+
+ vLoopback2Delete.push_back(std::string(Addr2Delete.psz));
+ }
+ }
+ else
+ {
+ /* addition */
+ if (c == 'L')
+ loopback6Offset = ValueUnion.u32;
+ else
+ vLoopback2Add.push_back(std::string(ValueUnion.psz));
+ }
+ break;
+
+ case 'P': /* ipv6 portforwarding*/
+ case 'p': /* ipv4 portforwarding */
+ {
+ if (RTStrCmp(ValueUnion.psz, "delete") != 0)
+ {
+ /* addition */
+ /* netPfStrToPf will clean up the Pfr */
+ PORTFORWARDRULE Pfr;
+ int irc = netPfStrToPf(ValueUnion.psz, (c == 'P'), &Pfr);
+ if (RT_FAILURE(irc))
+ return errorSyntax(Nat::tr("Invalid port-forward rule %s\n"), ValueUnion.psz);
+
+ vPf2Add.push_back(Pfr);
+ }
+ else
+ {
+ /* deletion */
+ if (enmCode != OP_MODIFY)
+ return errorSyntax(Nat::tr("Port-forward could be deleted on modify\n"));
+
+ RTGETOPTUNION NamePf2DeleteUnion;
+ int vrc = RTGetOptFetchValue(&GetState, &NamePf2DeleteUnion, RTGETOPT_REQ_STRING);
+ if (RT_FAILURE(vrc))
+ return errorSyntax(Nat::tr("Not enough parŠ°meters\n"));
+
+ if (strlen(NamePf2DeleteUnion.psz) > PF_NAMELEN)
+ return errorSyntax(Nat::tr("Port-forward rule name is too long\n"));
+
+ PFNAME2DELETE Name2Delete;
+ RT_ZERO(Name2Delete);
+ RTStrCopy(Name2Delete.szName, PF_NAMELEN, NamePf2DeleteUnion.psz);
+ Name2Delete.fIPv6 = (c == 'P');
+ vPfName2Delete.push_back(Name2Delete);
+ }
+ break;
+ }
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if (!pNetName)
+ return errorSyntax(Nat::tr("You need to specify the --netname option"));
+ /* verification */
+ switch (enmCode)
+ {
+ case OP_ADD:
+ if (!pPrefixIPv4)
+ return errorSyntax(Nat::tr("You need to specify the --network option"));
+ break;
+ case OP_MODIFY:
+ case OP_REMOVE:
+ case OP_START:
+ case OP_STOP:
+ break;
+ default:
+ AssertMsgFailedReturn((Nat::tr("Unknown operation (:%d)"), enmCode), RTEXITCODE_FAILURE);
+ }
+
+ HRESULT hrc;
+ Bstr NetName;
+ NetName = Bstr(pNetName);
+
+ ComPtr<INATNetwork> net;
+ hrc = a->virtualBox->FindNATNetworkByName(NetName.mutableRaw(), net.asOutParam());
+ if (enmCode == OP_ADD)
+ {
+ if (SUCCEEDED(hrc))
+ return errorArgument(Nat::tr("NATNetwork server already exists"));
+
+ CHECK_ERROR(a->virtualBox, CreateNATNetwork(NetName.raw(), net.asOutParam()));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to create the NAT network service"));
+ }
+ else if (FAILED(hrc))
+ return errorArgument(Nat::tr("NATNetwork server does not exist"));
+
+ switch (enmCode)
+ {
+ case OP_ADD:
+ case OP_MODIFY:
+ {
+ if (pPrefixIPv4)
+ {
+ CHECK_ERROR(net, COMSETTER(Network)(Bstr(pPrefixIPv4).raw()));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+ if (dhcp >= 0)
+ {
+ CHECK_ERROR(net, COMSETTER(NeedDhcpServer) ((BOOL)dhcp));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+
+ /*
+ * If we are asked to disable IPv6, do it early so that
+ * the same command can also set IPv6 prefix to empty if
+ * it so wishes.
+ */
+ if (ipv6 == 0)
+ {
+ CHECK_ERROR(net, COMSETTER(IPv6Enabled)(FALSE));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+
+ if (pPrefixIPv6)
+ {
+ CHECK_ERROR(net, COMSETTER(IPv6Prefix)(Bstr(pPrefixIPv6).raw()));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+
+ /*
+ * If we are asked to enable IPv6, do it late, so that the
+ * same command can also set IPv6 prefix.
+ */
+ if (ipv6 > 0)
+ {
+ CHECK_ERROR(net, COMSETTER(IPv6Enabled)(TRUE));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+
+ if (ipv6_default != -1)
+ {
+ BOOL fIPv6Default = RT_BOOL(ipv6_default);
+ CHECK_ERROR(net, COMSETTER(AdvertiseDefaultIPv6RouteEnabled)(fIPv6Default));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+
+ if (!vPfName2Delete.empty())
+ {
+ VPF2DELETEITERATOR it;
+ for (it = vPfName2Delete.begin(); it != vPfName2Delete.end(); ++it)
+ {
+ CHECK_ERROR(net, RemovePortForwardRule((BOOL)(*it).fIPv6,
+ Bstr((*it).szName).raw()));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to delete pf"));
+ }
+ }
+
+ if (!vPf2Add.empty())
+ {
+ VPF2ADDITERATOR it;
+ for (it = vPf2Add.begin(); it != vPf2Add.end(); ++it)
+ {
+ NATProtocol_T proto = NATProtocol_TCP;
+ if ((*it).iPfrProto == IPPROTO_TCP)
+ proto = NATProtocol_TCP;
+ else if ((*it).iPfrProto == IPPROTO_UDP)
+ proto = NATProtocol_UDP;
+ else
+ continue; /* XXX: warning here. */
+
+ CHECK_ERROR(net, AddPortForwardRule((BOOL)(*it).fPfrIPv6,
+ Bstr((*it).szPfrName).raw(),
+ proto,
+ Bstr((*it).szPfrHostAddr).raw(),
+ (*it).u16PfrHostPort,
+ Bstr((*it).szPfrGuestAddr).raw(),
+ (*it).u16PfrGuestPort));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to add pf"));
+ }
+ }
+
+ if (loopback6Offset)
+ {
+ if (loopback6Offset == -1)
+ loopback6Offset = 0; /* deletion */
+
+ CHECK_ERROR_RET(net, COMSETTER(LoopbackIp6)(loopback6Offset), RTEXITCODE_FAILURE);
+ }
+
+ /* addLocalMapping (hostid, offset) */
+ if (!vLoopback2Add.empty())
+ {
+ /* we're expecting stings 127.0.0.1=5 */
+ LOOPBACK2DELETEADDITERATOR it;
+ for (it = vLoopback2Add.begin();
+ it != vLoopback2Add.end();
+ ++it)
+ {
+ std::string address, strOffset;
+ size_t pos = it->find('=');
+ LONG lOffset = 0;
+ Bstr bstrAddress;
+
+ AssertReturn(pos != std::string::npos, errorArgument(Nat::tr("invalid loopback string")));
+
+ address = it->substr(0, pos);
+ strOffset = it->substr(pos + 1);
+
+ lOffset = RTStrToUInt32(strOffset.c_str());
+ AssertReturn(lOffset > 0, errorArgument(Nat::tr("invalid loopback string")));
+
+ bstrAddress = Bstr(address.c_str());
+
+ CHECK_ERROR_RET(net, AddLocalMapping(bstrAddress.raw(), lOffset), RTEXITCODE_FAILURE);
+ }
+ }
+
+ if (!vLoopback2Delete.empty())
+ {
+ /* we're expecting stings 127.0.0.1 */
+ LOOPBACK2DELETEADDITERATOR it;
+ for (it = vLoopback2Add.begin();
+ it != vLoopback2Add.end();
+ ++it)
+ {
+ Bstr bstrAddress;
+ bstrAddress = Bstr(it->c_str());
+
+ CHECK_ERROR_RET(net, AddLocalMapping(bstrAddress.raw(), 0), RTEXITCODE_FAILURE);
+ }
+ }
+
+ if (enable >= 0)
+ {
+ CHECK_ERROR(net, COMSETTER(Enabled) ((BOOL)enable));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to set configuration"));
+ }
+ break;
+ }
+ case OP_REMOVE:
+ {
+ CHECK_ERROR(a->virtualBox, RemoveNATNetwork(net));
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to remove nat network"));
+ break;
+ }
+ case OP_START:
+ {
+ CHECK_ERROR(net, Start());
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to start network"));
+ break;
+ }
+ case OP_STOP:
+ {
+ CHECK_ERROR(net, Stop());
+ if (FAILED(hrc))
+ return errorArgument(Nat::tr("Failed to stop network"));
+ break;
+ }
+ default:;
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+
+/*
+ * VBoxManage natnetwork ...
+ */
+RTEXITCODE handleNATNetwork(HandlerArg *a)
+{
+ if (a->argc < 1)
+ return errorSyntax(Nat::tr("Not enough parameters"));
+
+ RTEXITCODE rcExit;
+ if (strcmp(a->argv[0], "modify") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_MODIFY);
+ rcExit = handleOp(a, OP_MODIFY);
+ }
+ else if (strcmp(a->argv[0], "add") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_ADD);
+ rcExit = handleOp(a, OP_ADD);
+ }
+ else if (strcmp(a->argv[0], "remove") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_REMOVE);
+ rcExit = handleOp(a, OP_REMOVE);
+ }
+ else if (strcmp(a->argv[0], "start") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_START);
+ rcExit = handleOp(a, OP_START);
+ }
+ else if (strcmp(a->argv[0], "stop") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_STOP);
+ rcExit = handleOp(a, OP_STOP);
+ }
+ else if (strcmp(a->argv[0], "list") == 0)
+ {
+ setCurrentSubcommand(HELP_SCOPE_NATNETWORK_LIST);
+ rcExit = handleNATList(a);
+ }
+ else
+ rcExit = errorSyntax(Nat::tr("Invalid parameter '%s'"), a->argv[0]);
+ return rcExit;
+}
+
+
+/*
+ * VBoxManage list natnetworks ...
+ */
+RTEXITCODE listNATNetworks(bool fLong, bool fSorted,
+ const ComPtr<IVirtualBox> &pVirtualBox)
+{
+ HRESULT hrc;
+
+ com::SafeIfaceArray<INATNetwork> aNets;
+ CHECK_ERROR_RET(pVirtualBox,
+ COMGETTER(NATNetworks)(ComSafeArrayAsOutParam(aNets)),
+ RTEXITCODE_FAILURE);
+
+ const size_t cNets = aNets.size();
+ if (cNets == 0)
+ return RTEXITCODE_SUCCESS;
+
+ /*
+ * Sort the list if necessary. The sort is indirect via an
+ * intermediate array of indexes.
+ */
+ std::vector<size_t> vIndexes(cNets);
+ for (size_t i = 0; i < cNets; ++i)
+ vIndexes[i] = i;
+
+ if (fSorted)
+ {
+ std::vector<com::Bstr> vBstrNames(cNets);
+ for (size_t i = 0; i < cNets; ++i)
+ {
+ CHECK_ERROR_RET(aNets[i],
+ COMGETTER(NetworkName)(vBstrNames[i].asOutParam()),
+ RTEXITCODE_FAILURE);
+ }
+
+ struct SortBy {
+ const std::vector<com::Bstr> &ks;
+ SortBy(const std::vector<com::Bstr> &aKeys) : ks(aKeys) {}
+ bool operator() (size_t l, size_t r) { return ks[l] < ks[r]; }
+ };
+
+ std::sort(vIndexes.begin(), vIndexes.end(),
+ SortBy(vBstrNames));
+ }
+
+ for (size_t i = 0; i < cNets; ++i)
+ {
+ printNATNetwork(aNets[vIndexes[i]], fLong);
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
new file mode 100644
index 00000000..69598c44
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
@@ -0,0 +1,670 @@
+/* $Id: VBoxManageSnapshot.cpp $ */
+/** @file
+ * VBoxManage - The 'snapshot' 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/time.h>
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Snapshot);
+
+/**
+ * Helper function used with "VBoxManage snapshot ... dump". Gets called to find the
+ * snapshot in the machine's snapshot tree that uses a particular diff image child of
+ * a medium.
+ * Horribly inefficient since we keep re-querying the snapshots tree for each image,
+ * but this is for quick debugging only.
+ * @param pMedium
+ * @param pThisSnapshot
+ * @param pCurrentSnapshot
+ * @param uMediumLevel
+ * @param uSnapshotLevel
+ * @return
+ */
+bool FindAndPrintSnapshotUsingMedium(ComPtr<IMedium> &pMedium,
+ ComPtr<ISnapshot> &pThisSnapshot,
+ ComPtr<ISnapshot> &pCurrentSnapshot,
+ uint32_t uMediumLevel,
+ uint32_t uSnapshotLevel)
+{
+ HRESULT hrc;
+
+ do
+ {
+ // get snapshot machine so we can figure out which diff image this created
+ ComPtr<IMachine> pSnapshotMachine;
+ CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Machine)(pSnapshotMachine.asOutParam()));
+
+ // get media attachments
+ SafeIfaceArray<IMediumAttachment> aAttachments;
+ CHECK_ERROR_BREAK(pSnapshotMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments)));
+
+ for (uint32_t i = 0;
+ i < aAttachments.size();
+ ++i)
+ {
+ ComPtr<IMediumAttachment> pAttach(aAttachments[i]);
+ DeviceType_T type;
+ CHECK_ERROR_BREAK(pAttach, COMGETTER(Type)(&type));
+ if (type == DeviceType_HardDisk)
+ {
+ ComPtr<IMedium> pMediumInSnapshot;
+ CHECK_ERROR_BREAK(pAttach, COMGETTER(Medium)(pMediumInSnapshot.asOutParam()));
+
+ if (pMediumInSnapshot == pMedium)
+ {
+ // get snapshot name
+ Bstr bstrSnapshotName;
+ CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Name)(bstrSnapshotName.asOutParam()));
+
+ RTPrintf("%*s \"%ls\"%s\n",
+ 50 + uSnapshotLevel * 2, "", // indent
+ bstrSnapshotName.raw(),
+ (pThisSnapshot == pCurrentSnapshot) ? " (CURSNAP)" : "");
+ return true; // found
+ }
+ }
+ }
+
+ // not found: then recurse into child snapshots
+ SafeIfaceArray<ISnapshot> aSnapshots;
+ CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Children)(ComSafeArrayAsOutParam(aSnapshots)));
+
+ for (uint32_t i = 0;
+ i < aSnapshots.size();
+ ++i)
+ {
+ ComPtr<ISnapshot> pChild(aSnapshots[i]);
+ if (FindAndPrintSnapshotUsingMedium(pMedium,
+ pChild,
+ pCurrentSnapshot,
+ uMediumLevel,
+ uSnapshotLevel + 1))
+ // found:
+ break;
+ }
+ } while (0);
+
+ return false;
+}
+
+/**
+ * Helper function used with "VBoxManage snapshot ... dump". Called from DumpSnapshot()
+ * for each hard disk attachment found in a virtual machine. This then writes out the
+ * root (base) medium for that hard disk attachment and recurses into the children
+ * tree of that medium, correlating it with the snapshots of the machine.
+ * @param pCurrentStateMedium constant, the medium listed in the current machine data (latest diff image).
+ * @param pMedium variant, initially the base medium, then a child of the base medium when recursing.
+ * @param pRootSnapshot constant, the root snapshot of the machine, if any; this then looks into the child snapshots.
+ * @param pCurrentSnapshot constant, the machine's current snapshot (so we can mark it in the output).
+ * @param uLevel variant, the recursion level for output indentation.
+ */
+void DumpMediumWithChildren(ComPtr<IMedium> &pCurrentStateMedium,
+ ComPtr<IMedium> &pMedium,
+ ComPtr<ISnapshot> &pRootSnapshot,
+ ComPtr<ISnapshot> &pCurrentSnapshot,
+ uint32_t uLevel)
+{
+ HRESULT hrc;
+ do
+ {
+ // print this medium
+ Bstr bstrMediumName;
+ CHECK_ERROR_BREAK(pMedium, COMGETTER(Name)(bstrMediumName.asOutParam()));
+ RTPrintf("%*s \"%ls\"%s\n",
+ uLevel * 2, "", // indent
+ bstrMediumName.raw(),
+ (pCurrentStateMedium == pMedium) ? " (CURSTATE)" : "");
+
+ // find and print the snapshot that uses this particular medium (diff image)
+ FindAndPrintSnapshotUsingMedium(pMedium, pRootSnapshot, pCurrentSnapshot, uLevel, 0);
+
+ // recurse into children
+ SafeIfaceArray<IMedium> aChildren;
+ CHECK_ERROR_BREAK(pMedium, COMGETTER(Children)(ComSafeArrayAsOutParam(aChildren)));
+ for (uint32_t i = 0;
+ i < aChildren.size();
+ ++i)
+ {
+ ComPtr<IMedium> pChild(aChildren[i]);
+ DumpMediumWithChildren(pCurrentStateMedium, pChild, pRootSnapshot, pCurrentSnapshot, uLevel + 1);
+ }
+ } while (0);
+}
+
+
+/**
+ * Handles the 'snapshot myvm list' sub-command.
+ * @returns Exit code.
+ * @param pArgs The handler argument package.
+ * @param pMachine Reference to the VM (locked) we're operating on.
+ */
+static RTEXITCODE handleSnapshotList(HandlerArg *pArgs, ComPtr<IMachine> &pMachine)
+{
+ static const RTGETOPTDEF g_aOptions[] =
+ {
+ { "--details", 'D', RTGETOPT_REQ_NOTHING },
+ { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
+ };
+
+ VMINFO_DETAILS enmDetails = VMINFO_STANDARD;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, g_aOptions, RT_ELEMENTS(g_aOptions), 2 /*iArg*/, 0 /*fFlags*/);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 'D': enmDetails = VMINFO_FULL; break;
+ case 'M': enmDetails = VMINFO_MACHINEREADABLE; break;
+ default: return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ ComPtr<ISnapshot> pSnapshot;
+ HRESULT hrc = pMachine->FindSnapshot(Bstr().raw(), pSnapshot.asOutParam());
+ if (FAILED(hrc))
+ {
+ RTPrintf(Snapshot::tr("This machine does not have any snapshots\n"));
+ return RTEXITCODE_FAILURE;
+ }
+ if (pSnapshot)
+ {
+ ComPtr<ISnapshot> pCurrentSnapshot;
+ CHECK_ERROR2I_RET(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()), RTEXITCODE_FAILURE);
+ hrc = showSnapshots(pSnapshot, pCurrentSnapshot, enmDetails);
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Implementation for "VBoxManage snapshot ... dump". This goes thru the machine's
+ * medium attachments and calls DumpMediumWithChildren() for each hard disk medium found,
+ * which then dumps the parent/child tree of that medium together with the corresponding
+ * snapshots.
+ * @param pMachine Machine to dump snapshots for.
+ */
+void DumpSnapshot(ComPtr<IMachine> &pMachine)
+{
+ HRESULT hrc;
+
+ do
+ {
+ // get root snapshot
+ ComPtr<ISnapshot> pSnapshot;
+ CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr("").raw(), pSnapshot.asOutParam()));
+
+ // get current snapshot
+ ComPtr<ISnapshot> pCurrentSnapshot;
+ CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()));
+
+ // get media attachments
+ SafeIfaceArray<IMediumAttachment> aAttachments;
+ CHECK_ERROR_BREAK(pMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments)));
+ for (uint32_t i = 0;
+ i < aAttachments.size();
+ ++i)
+ {
+ ComPtr<IMediumAttachment> pAttach(aAttachments[i]);
+ DeviceType_T type;
+ CHECK_ERROR_BREAK(pAttach, COMGETTER(Type)(&type));
+ if (type == DeviceType_HardDisk)
+ {
+ ComPtr<IMedium> pCurrentStateMedium;
+ CHECK_ERROR_BREAK(pAttach, COMGETTER(Medium)(pCurrentStateMedium.asOutParam()));
+
+ ComPtr<IMedium> pBaseMedium;
+ CHECK_ERROR_BREAK(pCurrentStateMedium, COMGETTER(Base)(pBaseMedium.asOutParam()));
+
+ Bstr bstrBaseMediumName;
+ CHECK_ERROR_BREAK(pBaseMedium, COMGETTER(Name)(bstrBaseMediumName.asOutParam()));
+
+ RTPrintf(Snapshot::tr("[%RI32] Images and snapshots for medium \"%ls\"\n"), i, bstrBaseMediumName.raw());
+
+ DumpMediumWithChildren(pCurrentStateMedium,
+ pBaseMedium,
+ pSnapshot,
+ pCurrentSnapshot,
+ 0);
+ }
+ }
+ } while (0);
+}
+
+typedef enum SnapshotUniqueFlags
+{
+ SnapshotUniqueFlags_Null = 0,
+ SnapshotUniqueFlags_Number = RT_BIT(1),
+ SnapshotUniqueFlags_Timestamp = RT_BIT(2),
+ SnapshotUniqueFlags_Space = RT_BIT(16),
+ SnapshotUniqueFlags_Force = RT_BIT(30)
+} SnapshotUniqueFlags;
+
+static int parseSnapshotUniqueFlags(const char *psz, SnapshotUniqueFlags *pUnique)
+{
+ int vrc = VINF_SUCCESS;
+ unsigned uUnique = 0;
+ while (psz && *psz && RT_SUCCESS(vrc))
+ {
+ size_t len;
+ const char *pszComma = strchr(psz, ',');
+ if (pszComma)
+ len = pszComma - psz;
+ else
+ len = strlen(psz);
+ if (len > 0)
+ {
+ if (!RTStrNICmp(psz, "number", len))
+ uUnique |= SnapshotUniqueFlags_Number;
+ else if (!RTStrNICmp(psz, "timestamp", len))
+ uUnique |= SnapshotUniqueFlags_Timestamp;
+ else if (!RTStrNICmp(psz, "space", len))
+ uUnique |= SnapshotUniqueFlags_Space;
+ else if (!RTStrNICmp(psz, "force", len))
+ uUnique |= SnapshotUniqueFlags_Force;
+ else
+ vrc = VERR_PARSE_ERROR;
+ }
+ if (pszComma)
+ psz += len + 1;
+ else
+ psz += len;
+ }
+
+ if (RT_SUCCESS(vrc))
+ *pUnique = (SnapshotUniqueFlags)uUnique;
+ return vrc;
+}
+
+/**
+ * Implementation for all VBoxManage snapshot ... subcommands.
+ * @param a
+ * @return
+ */
+RTEXITCODE handleSnapshot(HandlerArg *a)
+{
+ HRESULT hrc;
+
+/** @todo r=bird: sub-standard command line parsing here!
+ *
+ * 'VBoxManage snapshot empty take --help' takes a snapshot rather than display
+ * help as you would expect.
+ *
+ */
+
+ /* we need at least a VM and a command */
+ if (a->argc < 2)
+ return errorSyntax(Snapshot::tr("Not enough parameters"));
+
+ /* the first argument must be the VM */
+ Bstr bstrMachine(a->argv[0]);
+ ComPtr<IMachine> pMachine;
+ CHECK_ERROR(a->virtualBox, FindMachine(bstrMachine.raw(),
+ pMachine.asOutParam()));
+ if (!pMachine)
+ return RTEXITCODE_FAILURE;
+
+ /* we have to open a session for this task (new or shared) */
+ CHECK_ERROR_RET(pMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ do
+ {
+ /* replace the (read-only) IMachine object by a writable one */
+ ComPtr<IMachine> sessionMachine;
+ CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
+
+ /* switch based on the command */
+ bool fDelete = false,
+ fRestore = false,
+ fRestoreCurrent = false;
+
+ if (!strcmp(a->argv[1], "take"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SNAPSHOT_TAKE);
+
+ /* there must be a name */
+ if (a->argc < 3)
+ {
+ errorSyntax(Snapshot::tr("Missing snapshot name"));
+ hrc = E_FAIL;
+ break;
+ }
+ Bstr name(a->argv[2]);
+
+ /* parse the optional arguments */
+ Bstr desc;
+ bool fPause = true; /* default is NO live snapshot */
+ SnapshotUniqueFlags enmUnique = SnapshotUniqueFlags_Null;
+ static const RTGETOPTDEF s_aTakeOptions[] =
+ {
+ { "--description", 'd', RTGETOPT_REQ_STRING },
+ { "-description", 'd', RTGETOPT_REQ_STRING },
+ { "-desc", 'd', RTGETOPT_REQ_STRING },
+ { "--pause", 'p', RTGETOPT_REQ_NOTHING },
+ { "--live", 'l', RTGETOPT_REQ_NOTHING },
+ { "--uniquename", 'u', RTGETOPT_REQ_STRING }
+ };
+ RTGETOPTSTATE GetOptState;
+ RTGetOptInit(&GetOptState, a->argc, a->argv, s_aTakeOptions, RT_ELEMENTS(s_aTakeOptions),
+ 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ int ch;
+ RTGETOPTUNION Value;
+ int vrc;
+ while ( SUCCEEDED(hrc)
+ && (ch = RTGetOpt(&GetOptState, &Value)))
+ {
+ switch (ch)
+ {
+ case 'p':
+ fPause = true;
+ break;
+
+ case 'l':
+ fPause = false;
+ break;
+
+ case 'd':
+ desc = Value.psz;
+ break;
+
+ case 'u':
+ vrc = parseSnapshotUniqueFlags(Value.psz, &enmUnique);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Snapshot::tr("Invalid unique name description '%s'"), Value.psz);
+ break;
+
+ default:
+ errorGetOpt(ch, &Value);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ if (FAILED(hrc))
+ break;
+
+ if (enmUnique & (SnapshotUniqueFlags_Number | SnapshotUniqueFlags_Timestamp))
+ {
+ ComPtr<ISnapshot> pSnapshot;
+ hrc = sessionMachine->FindSnapshot(name.raw(),
+ pSnapshot.asOutParam());
+ if (SUCCEEDED(hrc) || (enmUnique & SnapshotUniqueFlags_Force))
+ {
+ /* there is a duplicate, need to create a unique name */
+ uint32_t count = 0;
+ RTTIMESPEC now;
+
+ if (enmUnique & SnapshotUniqueFlags_Number)
+ {
+ if (enmUnique & SnapshotUniqueFlags_Force)
+ count = 1;
+ else
+ count = 2;
+ RTTimeSpecSetNano(&now, 0); /* Shut up MSC */
+ }
+ else
+ RTTimeNow(&now);
+
+ while (count < 500)
+ {
+ Utf8Str suffix;
+ if (enmUnique & SnapshotUniqueFlags_Number)
+ suffix = Utf8StrFmt("%u", count);
+ else
+ {
+ RTTIMESPEC nowplus = now;
+ RTTimeSpecAddSeconds(&nowplus, count);
+ RTTIME stamp;
+ RTTimeExplode(&stamp, &nowplus);
+ suffix = Utf8StrFmt("%04u-%02u-%02uT%02u:%02u:%02uZ", stamp.i32Year, stamp.u8Month, stamp.u8MonthDay, stamp.u8Hour, stamp.u8Minute, stamp.u8Second);
+ }
+ Bstr tryName = name;
+ if (enmUnique & SnapshotUniqueFlags_Space)
+ tryName = BstrFmt("%ls %s", name.raw(), suffix.c_str());
+ else
+ tryName = BstrFmt("%ls%s", name.raw(), suffix.c_str());
+ count++;
+ hrc = sessionMachine->FindSnapshot(tryName.raw(),
+ pSnapshot.asOutParam());
+ if (FAILED(hrc))
+ {
+ name = tryName;
+ break;
+ }
+ }
+ if (SUCCEEDED(hrc))
+ {
+ errorArgument(Snapshot::tr("Failed to generate a unique snapshot name"));
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ hrc = S_OK;
+ }
+
+ ComPtr<IProgress> progress;
+ Bstr snapId;
+ CHECK_ERROR_BREAK(sessionMachine, TakeSnapshot(name.raw(), desc.raw(),
+ fPause, snapId.asOutParam(),
+ progress.asOutParam()));
+
+ hrc = showProgress(progress);
+ if (SUCCEEDED(hrc))
+ RTPrintf(Snapshot::tr("Snapshot taken. UUID: %ls\n"), snapId.raw());
+ else
+ CHECK_PROGRESS_ERROR(progress, (Snapshot::tr("Failed to take snapshot")));
+ }
+ else if ( (fDelete = !strcmp(a->argv[1], "delete"))
+ || (fRestore = !strcmp(a->argv[1], "restore"))
+ || (fRestoreCurrent = !strcmp(a->argv[1], "restorecurrent"))
+ )
+ {
+ setCurrentSubcommand(fDelete ? HELP_SCOPE_SNAPSHOT_DELETE
+ : fRestore ? HELP_SCOPE_SNAPSHOT_RESTORE
+ : HELP_SCOPE_SNAPSHOT_RESTORECURRENT);
+
+ if (fRestoreCurrent)
+ {
+ if (a->argc > 2)
+ {
+ errorSyntax(Snapshot::tr("Too many arguments"));
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ /* exactly one parameter: snapshot name */
+ else if (a->argc != 3)
+ {
+ errorSyntax(Snapshot::tr("Expecting snapshot name only"));
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<ISnapshot> pSnapshot;
+
+ if (fRestoreCurrent)
+ {
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
+ if (pSnapshot.isNull())
+ {
+ RTPrintf(Snapshot::tr("This machine does not have any snapshots\n"));
+ return RTEXITCODE_FAILURE;
+ }
+ }
+ else
+ {
+ // restore or delete snapshot: then resolve cmd line argument to snapshot instance
+ CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
+ pSnapshot.asOutParam()));
+ }
+
+ Bstr bstrSnapGuid;
+ CHECK_ERROR_BREAK(pSnapshot, COMGETTER(Id)(bstrSnapGuid.asOutParam()));
+
+ Bstr bstrSnapName;
+ CHECK_ERROR_BREAK(pSnapshot, COMGETTER(Name)(bstrSnapName.asOutParam()));
+
+ ComPtr<IProgress> pProgress;
+
+ RTPrintf(Snapshot::tr("%s snapshot '%ls' (%ls)\n"),
+ fDelete ? Snapshot::tr("Deleting") : Snapshot::tr("Restoring"), bstrSnapName.raw(), bstrSnapGuid.raw());
+
+ if (fDelete)
+ {
+ CHECK_ERROR_BREAK(sessionMachine, DeleteSnapshot(bstrSnapGuid.raw(),
+ pProgress.asOutParam()));
+ }
+ else
+ {
+ // restore or restore current
+ CHECK_ERROR_BREAK(sessionMachine, RestoreSnapshot(pSnapshot, pProgress.asOutParam()));
+ }
+
+ hrc = showProgress(pProgress);
+ CHECK_PROGRESS_ERROR(pProgress, (Snapshot::tr("Snapshot operation failed")));
+ }
+ else if (!strcmp(a->argv[1], "edit"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SNAPSHOT_EDIT);
+ if (a->argc < 3)
+ {
+ errorSyntax(Snapshot::tr("Missing snapshot name"));
+ hrc = E_FAIL;
+ break;
+ }
+
+ /* Parse the optional arguments, allowing more freedom than the
+ * synopsis explains. Can rename multiple snapshots and so on. */
+ ComPtr<ISnapshot> pSnapshot;
+ static const RTGETOPTDEF s_aEditOptions[] =
+ {
+ { "--current", 'c', RTGETOPT_REQ_NOTHING },
+ { "-current", 'c', RTGETOPT_REQ_NOTHING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "-name", 'n', RTGETOPT_REQ_STRING },
+ { "-newname", 'n', RTGETOPT_REQ_STRING },
+ { "--description", 'd', RTGETOPT_REQ_STRING },
+ { "-description", 'd', RTGETOPT_REQ_STRING },
+ { "-desc", 'd', RTGETOPT_REQ_STRING }
+ };
+ RTGETOPTSTATE GetOptState;
+ RTGetOptInit(&GetOptState, a->argc, a->argv, s_aEditOptions, RT_ELEMENTS(s_aEditOptions),
+ 2, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ int ch;
+ RTGETOPTUNION Value;
+ while ( SUCCEEDED(hrc)
+ && (ch = RTGetOpt(&GetOptState, &Value)))
+ {
+ switch (ch)
+ {
+ case 'c':
+ CHECK_ERROR_BREAK(sessionMachine, COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam()));
+ if (pSnapshot.isNull())
+ {
+ RTPrintf(Snapshot::tr("This machine does not have any snapshots\n"));
+ return RTEXITCODE_FAILURE;
+ }
+ break;
+
+ case 'n':
+ CHECK_ERROR_BREAK(pSnapshot, COMSETTER(Name)(Bstr(Value.psz).raw()));
+ break;
+
+ case 'd':
+ CHECK_ERROR_BREAK(pSnapshot, COMSETTER(Description)(Bstr(Value.psz).raw()));
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(Value.psz).raw(), pSnapshot.asOutParam()));
+ break;
+
+ default:
+ errorGetOpt(ch, &Value);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+
+ if (FAILED(hrc))
+ break;
+ }
+ else if (!strcmp(a->argv[1], "showvminfo"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SNAPSHOT_SHOWVMINFO);
+
+ /* exactly one parameter: snapshot name */
+ if (a->argc != 3)
+ {
+ errorSyntax(Snapshot::tr("Expecting snapshot name only"));
+ hrc = E_FAIL;
+ break;
+ }
+
+ ComPtr<ISnapshot> pSnapshot;
+
+ CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
+ pSnapshot.asOutParam()));
+
+ /* get the machine of the given snapshot */
+ ComPtr<IMachine> pMachine2;
+ pSnapshot->COMGETTER(Machine)(pMachine2.asOutParam());
+ showVMInfo(a->virtualBox, pMachine2, NULL, VMINFO_NONE);
+ }
+ else if (!strcmp(a->argv[1], "list"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_SNAPSHOT_LIST);
+ hrc = handleSnapshotList(a, sessionMachine) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
+ }
+ else if (!strcmp(a->argv[1], "dump")) // undocumented parameter to debug snapshot info
+ DumpSnapshot(sessionMachine);
+ else
+ {
+ errorSyntax(Snapshot::tr("Invalid parameter '%s'"), a->argv[1]);
+ hrc = E_FAIL;
+ }
+ } while (0);
+
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
new file mode 100644
index 00000000..395196ad
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
@@ -0,0 +1,1306 @@
+/* $Id: VBoxManageStorageController.cpp $ */
+/** @file
+ * VBoxManage - The storage controller related commands.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/path.h>
+#include <iprt/param.h>
+#include <iprt/string.h>
+#include <iprt/ctype.h>
+#include <iprt/stream.h>
+#include <iprt/getopt.h>
+#include <VBox/log.h>
+
+#include "VBoxManage.h"
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Storage);
+
+// funcs
+///////////////////////////////////////////////////////////////////////////////
+
+
+static const RTGETOPTDEF g_aStorageAttachOptions[] =
+{
+ { "--storagectl", 's', RTGETOPT_REQ_STRING },
+ { "--port", 'p', RTGETOPT_REQ_UINT32 },
+ { "--device", 'd', RTGETOPT_REQ_UINT32 },
+ { "--type", 't', RTGETOPT_REQ_STRING },
+ { "--medium", 'm', RTGETOPT_REQ_STRING },
+ { "--mtype", 'M', RTGETOPT_REQ_STRING },
+ { "--passthrough", 'h', RTGETOPT_REQ_STRING },
+ { "--tempeject", 'e', RTGETOPT_REQ_STRING },
+ { "--nonrotational", 'n', RTGETOPT_REQ_STRING },
+ { "--discard", 'u', RTGETOPT_REQ_STRING },
+ { "--hotpluggable", 'o', RTGETOPT_REQ_STRING },
+ { "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING },
+ { "--forceunmount", 'f', RTGETOPT_REQ_NOTHING },
+ { "--comment", 'C', RTGETOPT_REQ_STRING },
+ { "--setuuid", 'q', RTGETOPT_REQ_STRING },
+ { "--setparentuuid", 'Q', RTGETOPT_REQ_STRING },
+ // iSCSI options
+ { "--server", 'S', RTGETOPT_REQ_STRING },
+ { "--target", 'T', RTGETOPT_REQ_STRING },
+ { "--tport", 'P', RTGETOPT_REQ_STRING },
+ { "--lun", 'L', RTGETOPT_REQ_STRING },
+ { "--encodedlun", 'E', RTGETOPT_REQ_STRING },
+ { "--username", 'U', RTGETOPT_REQ_STRING },
+ { "--password", 'W', RTGETOPT_REQ_STRING },
+ { "--passwordfile", 'w', RTGETOPT_REQ_STRING },
+ { "--initiator", 'N', RTGETOPT_REQ_STRING },
+ { "--intnet", 'I', RTGETOPT_REQ_NOTHING },
+};
+
+RTEXITCODE handleStorageAttach(HandlerArg *a)
+{
+ int c = VERR_INTERNAL_ERROR; /* initialized to shut up gcc */
+ HRESULT hrc = S_OK;
+ ULONG port = ~0U;
+ ULONG device = ~0U;
+ bool fForceUnmount = false;
+ bool fSetMediumType = false;
+ bool fSetNewUuid = false;
+ bool fSetNewParentUuid = false;
+ MediumType_T enmMediumType = MediumType_Normal;
+ Bstr bstrComment;
+ const char *pszCtl = NULL;
+ DeviceType_T devTypeRequested = DeviceType_Null;
+ const char *pszMedium = NULL;
+ const char *pszPassThrough = NULL;
+ const char *pszTempEject = NULL;
+ const char *pszNonRotational = NULL;
+ const char *pszDiscard = NULL;
+ const char *pszHotPluggable = NULL;
+ const char *pszBandwidthGroup = NULL;
+ Bstr bstrNewUuid;
+ Bstr bstrNewParentUuid;
+ // iSCSI options
+ Bstr bstrServer;
+ Bstr bstrTarget;
+ Bstr bstrPort;
+ Bstr bstrLun;
+ Bstr bstrUsername;
+ Bstr bstrPassword;
+ Bstr bstrInitiator;
+ Bstr bstrIso;
+ Utf8Str strIso;
+ bool fIntNet = false;
+
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ ComPtr<IMachine> machine;
+ ComPtr<IStorageController> storageCtl;
+ ComPtr<ISystemProperties> systemProperties;
+
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aStorageAttachOptions,
+ RT_ELEMENTS(g_aStorageAttachOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ while ( SUCCEEDED(hrc)
+ && (c = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ switch (c)
+ {
+ case 's': // storage controller name
+ {
+ if (ValueUnion.psz)
+ pszCtl = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'p': // port
+ {
+ port = ValueUnion.u32;
+ break;
+ }
+
+ case 'd': // device
+ {
+ device = ValueUnion.u32;
+ break;
+ }
+
+ case 'm': // medium <none|emptydrive|additions|uuid|filename|host:<drive>|iSCSI>
+ {
+ if (ValueUnion.psz)
+ pszMedium = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 't': // type <dvddrive|hdd|fdd>
+ {
+ if (ValueUnion.psz)
+ {
+ if (!RTStrICmp(ValueUnion.psz, "hdd"))
+ devTypeRequested = DeviceType_HardDisk;
+ else if (!RTStrICmp(ValueUnion.psz, "fdd"))
+ devTypeRequested = DeviceType_Floppy;
+ else if (!RTStrICmp(ValueUnion.psz, "dvddrive"))
+ devTypeRequested = DeviceType_DVD;
+ else
+ return errorArgument(Storage::tr("Invalid --type argument '%s'"), ValueUnion.psz);
+ }
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'h': // passthrough <on|off>
+ {
+ if (ValueUnion.psz)
+ pszPassThrough = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'e': // tempeject <on|off>
+ {
+ if (ValueUnion.psz)
+ pszTempEject = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'n': // nonrotational <on|off>
+ {
+ if (ValueUnion.psz)
+ pszNonRotational = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'u': // discard <on|off>
+ {
+ if (ValueUnion.psz)
+ pszDiscard = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'o': // hotpluggable <on|off>
+ {
+ if (ValueUnion.psz)
+ pszHotPluggable = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'b': // bandwidthgroup <name>
+ {
+ if (ValueUnion.psz)
+ pszBandwidthGroup = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+ }
+
+ case 'f': // force unmount medium during runtime
+ {
+ fForceUnmount = true;
+ break;
+ }
+
+ case 'C':
+ if (ValueUnion.psz)
+ bstrComment = ValueUnion.psz;
+ else
+ hrc = E_FAIL;
+ break;
+
+ case 'q':
+ if (ValueUnion.psz)
+ {
+ bstrNewUuid = ValueUnion.psz;
+ fSetNewUuid = true;
+ }
+ else
+ hrc = E_FAIL;
+ break;
+
+ case 'Q':
+ if (ValueUnion.psz)
+ {
+ bstrNewParentUuid = ValueUnion.psz;
+ fSetNewParentUuid = true;
+ }
+ else
+ hrc = E_FAIL;
+ break;
+
+ case 'S': // --server
+ bstrServer = ValueUnion.psz;
+ break;
+
+ case 'T': // --target
+ bstrTarget = ValueUnion.psz;
+ break;
+
+ case 'P': // --tport
+ bstrPort = ValueUnion.psz;
+ break;
+
+ case 'L': // --lun
+ bstrLun = ValueUnion.psz;
+ break;
+
+ case 'E': // --encodedlun
+ bstrLun = BstrFmt("enc%s", ValueUnion.psz);
+ break;
+
+ case 'U': // --username
+ bstrUsername = ValueUnion.psz;
+ break;
+
+ case 'W': // --password
+ bstrPassword = ValueUnion.psz;
+ break;
+
+ case 'w': // --passwordFile
+ {
+ Utf8Str utf8Password;
+ RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &utf8Password);
+ if (rcExit != RTEXITCODE_SUCCESS)
+ hrc = E_FAIL;
+ bstrPassword = utf8Password;
+ break;
+ }
+ case 'N': // --initiator
+ bstrInitiator = ValueUnion.psz;
+ break;
+
+ case 'M': // --type
+ {
+ int vrc = parseMediumType(ValueUnion.psz, &enmMediumType);
+ if (RT_FAILURE(vrc))
+ return errorArgument(Storage::tr("Invalid medium type '%s'"), ValueUnion.psz);
+ fSetMediumType = true;
+ break;
+ }
+
+ case 'I': // --intnet
+ fIntNet = true;
+ break;
+
+ default:
+ {
+ errorGetOpt(c, &ValueUnion);
+ hrc = E_FAIL;
+ break;
+ }
+ }
+ }
+
+ if (FAILED(hrc))
+ return RTEXITCODE_FAILURE;
+
+ if (!pszCtl)
+ return errorSyntax(Storage::tr("Storage controller name not specified"));
+
+ /* get the virtualbox system properties */
+ CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), RTEXITCODE_FAILURE);
+
+ // find the machine, lock it, get the mutable session machine
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ SessionType_T st;
+ CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), RTEXITCODE_FAILURE);
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ try
+ {
+ bool fRunTime = (st == SessionType_Shared);
+
+ if (fRunTime)
+ {
+ if (pszPassThrough)
+ throw Utf8Str(Storage::tr("Drive passthrough state cannot be changed while the VM is running\n"));
+ else if (pszBandwidthGroup)
+ throw Utf8Str(Storage::tr("Bandwidth group cannot be changed while the VM is running\n"));
+ }
+
+ /* check if the storage controller is present */
+ hrc = machine->GetStorageControllerByName(Bstr(pszCtl).raw(),
+ storageCtl.asOutParam());
+ if (FAILED(hrc))
+ throw Utf8StrFmt(Storage::tr("Could not find a controller named '%s'\n"), pszCtl);
+
+ StorageBus_T storageBus = StorageBus_Null;
+ CHECK_ERROR_RET(storageCtl, COMGETTER(Bus)(&storageBus), RTEXITCODE_FAILURE);
+ ULONG maxPorts = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxPortCountForStorageBus(storageBus, &maxPorts), RTEXITCODE_FAILURE);
+ ULONG maxDevices = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxDevicesPerPortForStorageBus(storageBus, &maxDevices), RTEXITCODE_FAILURE);
+
+ if (port == ~0U)
+ {
+ if (maxPorts == 1)
+ port = 0;
+ else
+ return errorSyntax(Storage::tr("Port not specified"));
+ }
+ if (device == ~0U)
+ {
+ if (maxDevices == 1)
+ device = 0;
+ else
+ return errorSyntax(Storage::tr("Device not specified"));
+ }
+
+ /* for sata controller check if the port count is big enough
+ * to accommodate the current port which is being assigned
+ * else just increase the port count
+ */
+ {
+ ULONG ulPortCount = 0;
+ ULONG ulMaxPortCount = 0;
+
+ CHECK_ERROR(storageCtl, COMGETTER(MaxPortCount)(&ulMaxPortCount));
+ CHECK_ERROR(storageCtl, COMGETTER(PortCount)(&ulPortCount));
+
+ if ( (ulPortCount != ulMaxPortCount)
+ && (port >= ulPortCount)
+ && (port < ulMaxPortCount))
+ CHECK_ERROR(storageCtl, COMSETTER(PortCount)(port + 1));
+ }
+
+ StorageControllerType_T ctlType = StorageControllerType_Null;
+ CHECK_ERROR(storageCtl, COMGETTER(ControllerType)(&ctlType));
+
+ if (!RTStrICmp(pszMedium, "none"))
+ {
+ CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl).raw(), port, device));
+ }
+ else if (!RTStrICmp(pszMedium, "emptydrive"))
+ {
+ if (fRunTime)
+ {
+ ComPtr<IMediumAttachment> mediumAttachment;
+ DeviceType_T deviceType = DeviceType_Null;
+ hrc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, device,
+ mediumAttachment.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ mediumAttachment->COMGETTER(Type)(&deviceType);
+
+ if ( (deviceType == DeviceType_DVD)
+ || (deviceType == DeviceType_Floppy))
+ {
+ /* just unmount the floppy/dvd */
+ CHECK_ERROR(machine, UnmountMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ fForceUnmount));
+ }
+ }
+ else if (devTypeRequested == DeviceType_DVD)
+ {
+ /*
+ * Try to attach an empty DVD drive as a hotplug operation.
+ * Main will complain if the controller doesn't support hotplugging.
+ */
+ CHECK_ERROR(machine, AttachDeviceWithoutMedium(Bstr(pszCtl).raw(), port, device,
+ devTypeRequested));
+ deviceType = DeviceType_DVD; /* To avoid the error message below. */
+ }
+
+ if ( FAILED(hrc)
+ || !( deviceType == DeviceType_DVD
+ || deviceType == DeviceType_Floppy)
+ )
+ throw Utf8StrFmt(Storage::tr("No DVD/Floppy Drive attached to the controller '%s'"
+ "at the port: %u, device: %u"), pszCtl, port, device);
+
+ }
+ else
+ {
+ DeviceType_T deviceType = DeviceType_Null;
+ com::SafeArray <DeviceType_T> saDeviceTypes;
+ ULONG driveCheck = 0;
+
+ /* check if the device type is supported by the controller */
+ CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
+ for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
+ {
+ if ( (saDeviceTypes[i] == DeviceType_DVD)
+ || (saDeviceTypes[i] == DeviceType_Floppy))
+ driveCheck++;
+ }
+
+ if (!driveCheck)
+ throw Utf8StrFmt(Storage::tr("The attachment is not supported by the storage controller '%s'"), pszCtl);
+
+ if (storageBus == StorageBus_Floppy)
+ deviceType = DeviceType_Floppy;
+ else
+ deviceType = DeviceType_DVD;
+
+ /* attach a empty floppy/dvd drive after removing previous attachment */
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ CHECK_ERROR(machine, AttachDeviceWithoutMedium(Bstr(pszCtl).raw(), port, device,
+ deviceType));
+ }
+ } // end if (!RTStrICmp(pszMedium, "emptydrive"))
+ else
+ {
+ ComPtr<IMedium> pMedium2Mount;
+
+ // not "none", not "emptydrive": then it must be a UUID or filename or hostdrive or iSCSI;
+ // for all these we first need to know the type of drive we're attaching to
+ {
+ /*
+ * try to determine the type of the drive from the
+ * storage controller chipset, the attachment and
+ * the medium being attached
+ */
+ if (ctlType == StorageControllerType_I82078) // floppy controller
+ devTypeRequested = DeviceType_Floppy;
+ else
+ {
+ /*
+ * for SATA/SCSI/IDE it is hard to tell if it is a harddisk or
+ * a dvd being attached so lets check if the medium attachment
+ * and the medium, both are of same type. if yes then we are
+ * sure of its type and don't need the user to enter it manually
+ * else ask the user for the type.
+ */
+ ComPtr<IMediumAttachment> mediumAttachment;
+ hrc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device,
+ mediumAttachment.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ DeviceType_T deviceType;
+ mediumAttachment->COMGETTER(Type)(&deviceType);
+
+ if (pszMedium)
+ {
+ if (!RTStrICmp(pszMedium, "additions"))
+ {
+ ComPtr<ISystemProperties> pProperties;
+ CHECK_ERROR(a->virtualBox,
+ COMGETTER(SystemProperties)(pProperties.asOutParam()));
+ CHECK_ERROR(pProperties, COMGETTER(DefaultAdditionsISO)(bstrIso.asOutParam()));
+ strIso = Utf8Str(bstrIso);
+ if (strIso.isEmpty())
+ throw Utf8Str(Storage::tr("Cannot find the Guest Additions ISO image\n"));
+ pszMedium = strIso.c_str();
+ if (devTypeRequested == DeviceType_Null)
+ devTypeRequested = DeviceType_DVD;
+ }
+ ComPtr<IMedium> pExistingMedium;
+ hrc = openMedium(a, pszMedium, deviceType,
+ AccessMode_ReadWrite,
+ pExistingMedium,
+ false /* fForceNewUuidOnOpen */,
+ true /* fSilent */);
+ if (SUCCEEDED(hrc) && pExistingMedium)
+ {
+ if ( (deviceType == DeviceType_DVD)
+ || (deviceType == DeviceType_HardDisk)
+ )
+ devTypeRequested = deviceType;
+ }
+ }
+ else
+ devTypeRequested = deviceType;
+ }
+ }
+ }
+
+ if (devTypeRequested == DeviceType_Null) // still the initializer value?
+ throw Utf8Str(Storage::tr("Argument --type must be specified\n"));
+
+ /* check if the device type is supported by the controller */
+ {
+ com::SafeArray <DeviceType_T> saDeviceTypes;
+
+ CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
+ if (SUCCEEDED(hrc))
+ {
+ ULONG driveCheck = 0;
+ for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
+ if (saDeviceTypes[i] == devTypeRequested)
+ driveCheck++;
+ if (!driveCheck)
+ throw Utf8StrFmt(Storage::tr("The given attachment is not supported by the storage controller '%s'"), pszCtl);
+ }
+ else
+ goto leave;
+ }
+
+ // find the medium given
+ /* host drive? */
+ if (!RTStrNICmp(pszMedium, RT_STR_TUPLE("host:")))
+ {
+ ComPtr<IHost> host;
+ CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
+
+ if (devTypeRequested == DeviceType_DVD)
+ {
+ hrc = host->FindHostDVDDrive(Bstr(pszMedium + 5).raw(),
+ pMedium2Mount.asOutParam());
+ if (!pMedium2Mount)
+ {
+ /* 2nd try: try with the real name, important on Linux+libhal */
+ char szPathReal[RTPATH_MAX];
+ if (RT_FAILURE(RTPathReal(pszMedium + 5, szPathReal, sizeof(szPathReal))))
+ throw Utf8StrFmt(Storage::tr("Invalid host DVD drive name \"%s\""), pszMedium + 5);
+ hrc = host->FindHostDVDDrive(Bstr(szPathReal).raw(),
+ pMedium2Mount.asOutParam());
+ if (!pMedium2Mount)
+ throw Utf8StrFmt(Storage::tr("Invalid host DVD drive name \"%s\""), pszMedium + 5);
+ }
+ }
+ else
+ {
+ // floppy
+ hrc = host->FindHostFloppyDrive(Bstr(pszMedium + 5).raw(),
+ pMedium2Mount.asOutParam());
+ if (!pMedium2Mount)
+ throw Utf8StrFmt(Storage::tr("Invalid host floppy drive name \"%s\""), pszMedium + 5);
+ }
+ }
+ else if (!RTStrICmp(pszMedium, "iSCSI"))
+ {
+ /* check for required options */
+ if (bstrServer.isEmpty() || bstrTarget.isEmpty())
+ throw Utf8StrFmt(Storage::tr("Parameters --server and --target are required for iSCSI media"));
+
+ /** @todo move the location stuff to Main, which can use pfnComposeName
+ * from the disk backends to construct the location properly. Also do
+ * not use slashes to separate the parts, as otherwise only the last
+ * element containing information will be shown. */
+ Bstr bstrISCSIMedium;
+ if ( bstrLun.isEmpty()
+ || (bstrLun == "0")
+ || (bstrLun == "enc0")
+ )
+ bstrISCSIMedium = BstrFmt("%ls|%ls", bstrServer.raw(), bstrTarget.raw());
+ else
+ bstrISCSIMedium = BstrFmt("%ls|%ls|%ls", bstrServer.raw(), bstrTarget.raw(), bstrLun.raw());
+
+ CHECK_ERROR(a->virtualBox, CreateMedium(Bstr("iSCSI").raw(),
+ bstrISCSIMedium.raw(),
+ AccessMode_ReadWrite,
+ DeviceType_HardDisk,
+ pMedium2Mount.asOutParam()));
+ if (FAILED(hrc)) goto leave; /** @todo r=andy Argh!! Why not using exceptions here? */
+ if (!bstrPort.isEmpty())
+ bstrServer = BstrFmt("%ls:%ls", bstrServer.raw(), bstrPort.raw());
+
+ // set the other iSCSI parameters as properties
+ com::SafeArray <BSTR> names;
+ com::SafeArray <BSTR> values;
+ Bstr("TargetAddress").detachTo(names.appendedRaw());
+ bstrServer.detachTo(values.appendedRaw());
+ Bstr("TargetName").detachTo(names.appendedRaw());
+ bstrTarget.detachTo(values.appendedRaw());
+
+ if (!bstrLun.isEmpty())
+ {
+ Bstr("LUN").detachTo(names.appendedRaw());
+ bstrLun.detachTo(values.appendedRaw());
+ }
+ if (!bstrUsername.isEmpty())
+ {
+ Bstr("InitiatorUsername").detachTo(names.appendedRaw());
+ bstrUsername.detachTo(values.appendedRaw());
+ }
+ if (!bstrPassword.isEmpty())
+ {
+ Bstr("InitiatorSecret").detachTo(names.appendedRaw());
+ bstrPassword.detachTo(values.appendedRaw());
+ }
+ if (!bstrInitiator.isEmpty())
+ {
+ Bstr("InitiatorName").detachTo(names.appendedRaw());
+ bstrInitiator.detachTo(values.appendedRaw());
+ }
+
+ /// @todo add --targetName and --targetPassword options
+
+ if (fIntNet)
+ {
+ Bstr("HostIPStack").detachTo(names.appendedRaw());
+ Bstr("0").detachTo(values.appendedRaw());
+ }
+
+ CHECK_ERROR(pMedium2Mount, SetProperties(ComSafeArrayAsInParam(names),
+ ComSafeArrayAsInParam(values)));
+ if (FAILED(hrc)) goto leave;
+ Bstr guid;
+ CHECK_ERROR(pMedium2Mount, COMGETTER(Id)(guid.asOutParam()));
+ if (FAILED(hrc)) goto leave;
+ RTPrintf(Storage::tr("iSCSI disk created. UUID: %s\n"), Utf8Str(guid).c_str());
+ }
+ else
+ {
+ if (!pszMedium)
+ {
+ ComPtr<IMediumAttachment> mediumAttachment;
+ hrc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device,
+ mediumAttachment.asOutParam());
+ if (FAILED(hrc))
+ throw Utf8Str(Storage::tr("Missing --medium argument"));
+ }
+ else
+ {
+ Bstr bstrMedium(pszMedium);
+ hrc = openMedium(a, pszMedium, devTypeRequested,
+ AccessMode_ReadWrite, pMedium2Mount,
+ fSetNewUuid, false /* fSilent */);
+ if (FAILED(hrc) || !pMedium2Mount)
+ throw Utf8StrFmt(Storage::tr("Invalid UUID or filename \"%s\""), pszMedium);
+ }
+ }
+
+ // set medium/parent medium UUID, if so desired
+ if (pMedium2Mount && (fSetNewUuid || fSetNewParentUuid))
+ {
+ CHECK_ERROR(pMedium2Mount, SetIds(fSetNewUuid, bstrNewUuid.raw(),
+ fSetNewParentUuid, bstrNewParentUuid.raw()));
+ if (FAILED(hrc))
+ throw Utf8Str(Storage::tr("Failed to set the medium/parent medium UUID"));
+ }
+
+ // set medium type, if so desired
+ if (pMedium2Mount && fSetMediumType)
+ {
+ MediumType_T enmMediumTypeOld;
+ CHECK_ERROR(pMedium2Mount, COMGETTER(Type)(&enmMediumTypeOld));
+ if (SUCCEEDED(hrc))
+ {
+ if (enmMediumTypeOld != enmMediumType)
+ {
+ CHECK_ERROR(pMedium2Mount, COMSETTER(Type)(enmMediumType));
+ if (FAILED(hrc))
+ throw Utf8Str(Storage::tr("Failed to set the medium type"));
+ }
+ }
+ }
+
+ if (pMedium2Mount && !bstrComment.isEmpty())
+ {
+ CHECK_ERROR(pMedium2Mount, COMSETTER(Description)(bstrComment.raw()));
+ }
+
+ if (pszMedium)
+ {
+ switch (devTypeRequested)
+ {
+ case DeviceType_DVD:
+ case DeviceType_Floppy:
+ {
+ if (!fRunTime)
+ {
+ ComPtr<IMediumAttachment> mediumAttachment;
+ // check if there is a dvd/floppy drive at the given location, if not attach one first
+ hrc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
+ port,
+ device,
+ mediumAttachment.asOutParam());
+ if (SUCCEEDED(hrc))
+ {
+ DeviceType_T deviceType;
+ mediumAttachment->COMGETTER(Type)(&deviceType);
+ if (deviceType != devTypeRequested)
+ {
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ hrc = machine->AttachDeviceWithoutMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ devTypeRequested); // DeviceType_DVD or DeviceType_Floppy
+ }
+ }
+ else
+ {
+ hrc = machine->AttachDeviceWithoutMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ devTypeRequested); // DeviceType_DVD or DeviceType_Floppy
+ }
+ }
+
+ if (pMedium2Mount)
+ {
+ CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ pMedium2Mount,
+ fForceUnmount));
+ }
+ break;
+ } // end DeviceType_DVD or DeviceType_Floppy:
+
+ case DeviceType_HardDisk:
+ {
+ // if there is anything attached at the given location, remove it
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
+ port,
+ device,
+ DeviceType_HardDisk,
+ pMedium2Mount));
+ break;
+ }
+
+ default: break; /* Shut up MSC */
+ }
+ }
+ }
+
+ if ( pszPassThrough
+ && (SUCCEEDED(hrc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszPassThrough, "on"))
+ {
+ CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszPassThrough, "off"))
+ {
+ CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Invalid --passthrough argument '%s'"), pszPassThrough);
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Couldn't find the controller attachment for the controller '%s'\n"), pszCtl);
+ }
+
+ if ( pszTempEject
+ && (SUCCEEDED(hrc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszTempEject, "on"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszTempEject, "off"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Invalid --tempeject argument '%s'"), pszTempEject);
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Couldn't find the controller attachment for the controller '%s'\n"), pszCtl);
+ }
+
+ if ( pszNonRotational
+ && (SUCCEEDED(hrc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszNonRotational, "on"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszNonRotational, "off"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Invalid --nonrotational argument '%s'"), pszNonRotational);
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Couldn't find the controller attachment for the controller '%s'\n"), pszCtl);
+ }
+
+ if ( pszDiscard
+ && (SUCCEEDED(hrc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszDiscard, "on"))
+ {
+ CHECK_ERROR(machine, SetAutoDiscardForDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszDiscard, "off"))
+ {
+ CHECK_ERROR(machine, SetAutoDiscardForDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Invalid --discard argument '%s'"), pszDiscard);
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Couldn't find the controller attachment for the controller '%s'\n"), pszCtl);
+ }
+
+ if ( pszHotPluggable
+ && (SUCCEEDED(hrc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszHotPluggable, "on"))
+ {
+ CHECK_ERROR(machine, SetHotPluggableForDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszHotPluggable, "off"))
+ {
+ CHECK_ERROR(machine, SetHotPluggableForDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Invalid --hotpluggable argument '%s'"), pszHotPluggable);
+ }
+ else
+ throw Utf8StrFmt(Storage::tr("Couldn't find the controller attachment for the controller '%s'\n"), pszCtl);
+ }
+
+ if ( pszBandwidthGroup
+ && !fRunTime
+ && SUCCEEDED(hrc))
+ {
+
+ if (!RTStrICmp(pszBandwidthGroup, "none"))
+ {
+ /* Just remove the bandwidth gorup. */
+ CHECK_ERROR(machine, SetNoBandwidthGroupForDevice(Bstr(pszCtl).raw(),
+ port, device));
+ }
+ else
+ {
+ ComPtr<IBandwidthControl> bwCtrl;
+ ComPtr<IBandwidthGroup> bwGroup;
+
+ CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(pszBandwidthGroup).raw(), bwGroup.asOutParam()));
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(),
+ port, device, bwGroup));
+ }
+ }
+ }
+ }
+
+ /* commit changes */
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+ }
+ catch (const Utf8Str &strError)
+ {
+ errorArgument("%s", strError.c_str());
+ hrc = E_FAIL;
+ }
+
+ // machine must always be unlocked, even on errors
+leave:
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+
+static const RTGETOPTDEF g_aStorageControllerOptions[] =
+{
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--add", 'a', RTGETOPT_REQ_STRING },
+ { "--controller", 'c', RTGETOPT_REQ_STRING },
+ { "--portcount", 'p', RTGETOPT_REQ_UINT32 },
+ { "--remove", 'r', RTGETOPT_REQ_NOTHING },
+ { "--rename", 'R', RTGETOPT_REQ_STRING },
+ { "--hostiocache", 'i', RTGETOPT_REQ_STRING },
+ { "--bootable", 'b', RTGETOPT_REQ_STRING },
+};
+
+RTEXITCODE handleStorageController(HandlerArg *a)
+{
+ int c;
+ const char *pszCtl = NULL;
+ const char *pszBusType = NULL;
+ const char *pszCtlType = NULL;
+ const char *pszHostIOCache = NULL;
+ const char *pszBootable = NULL;
+ const char *pszCtlNewName = NULL;
+ ULONG portcount = ~0U;
+ bool fRemoveCtl = false;
+ ComPtr<IMachine> machine;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+
+ if (a->argc < 4)
+ return errorSyntax(Storage::tr("Too few parameters"));
+
+ RTGetOptInit (&GetState, a->argc, a->argv, g_aStorageControllerOptions,
+ RT_ELEMENTS(g_aStorageControllerOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'n': // controller name
+ Assert(ValueUnion.psz);
+ pszCtl = ValueUnion.psz;
+ break;
+
+ case 'a': // controller bus type <ide/sata/scsi/floppy>
+ Assert(ValueUnion.psz);
+ pszBusType = ValueUnion.psz;
+ break;
+
+ case 'c': // controller <lsilogic/buslogic/intelahci/piix3/piix4/ich6/i82078>
+ Assert(ValueUnion.psz);
+ pszCtlType = ValueUnion.psz;
+ break;
+
+ case 'p': // portcount
+ portcount = ValueUnion.u32;
+ break;
+
+ case 'r': // remove controller
+ fRemoveCtl = true;
+ break;
+
+ case 'R': // rename controller
+ Assert(ValueUnion.psz);
+ pszCtlNewName = ValueUnion.psz;
+ break;
+
+ case 'i':
+ pszHostIOCache = ValueUnion.psz;
+ break;
+
+ case 'b':
+ pszBootable = ValueUnion.psz;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ HRESULT hrc;
+
+ /* try to find the given machine */
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
+ machine.asOutParam()), RTEXITCODE_FAILURE);
+
+ /* open a session for the VM */
+ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(machine.asOutParam());
+
+ if (!pszCtl)
+ {
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+ return errorSyntax(Storage::tr("Storage controller name not specified\n"));
+ }
+
+ if (fRemoveCtl)
+ {
+ CHECK_ERROR(machine, RemoveStorageController(Bstr(pszCtl).raw()));
+ }
+ else
+ {
+ if (pszBusType)
+ {
+ ComPtr<IStorageController> ctl;
+
+ if (!RTStrICmp(pszBusType, "ide"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_IDE,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "sata"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_SATA,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "scsi"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_SCSI,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "floppy"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_Floppy,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "sas"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_SAS,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "usb"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_USB,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "pcie"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_PCIe,
+ ctl.asOutParam()));
+ }
+ else if (!RTStrICmp(pszBusType, "virtio-scsi") || !RTStrICmp(pszBusType, "virtio"))
+ {
+ CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
+ StorageBus_VirtioSCSI,
+ ctl.asOutParam()));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Invalid --add argument '%s'"), pszBusType);
+ hrc = E_FAIL;
+ }
+ }
+
+ if ( pszCtlType
+ && SUCCEEDED(hrc))
+ {
+ ComPtr<IStorageController> ctl;
+
+ CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszCtlType, "lsilogic"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
+ }
+ else if (!RTStrICmp(pszCtlType, "buslogic"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
+ }
+ else if (!RTStrICmp(pszCtlType, "intelahci"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
+ }
+ else if (!RTStrICmp(pszCtlType, "piix3"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
+ }
+ else if (!RTStrICmp(pszCtlType, "piix4"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
+ }
+ else if (!RTStrICmp(pszCtlType, "ich6"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_ICH6));
+ }
+ else if (!RTStrICmp(pszCtlType, "i82078"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_I82078));
+ }
+ else if (!RTStrICmp(pszCtlType, "lsilogicsas"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogicSas));
+ }
+ else if (!RTStrICmp(pszCtlType, "usb"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_USB));
+ }
+ else if (!RTStrICmp(pszCtlType, "nvme"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_NVMe));
+ }
+ else if (!RTStrICmp(pszCtlType, "virtio-scsi") || !RTStrICmp(pszCtlType, "virtio"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_VirtioSCSI));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Invalid --type argument '%s'"), pszCtlType);
+ hrc = E_FAIL;
+ }
+ }
+ else
+ {
+ errorArgument(Storage::tr("Couldn't find the controller with the name: '%s'\n"), pszCtl);
+ hrc = E_FAIL;
+ }
+ }
+
+ if ( (portcount != ~0U)
+ && SUCCEEDED(hrc))
+ {
+ ComPtr<IStorageController> ctl;
+
+ CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(ctl, COMSETTER(PortCount)(portcount));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Couldn't find the controller with the name: '%s'\n"), pszCtl);
+ hrc = E_FAIL; /** @todo r=andy Overwrites original hrc. */
+ }
+ }
+
+ if ( pszHostIOCache
+ && SUCCEEDED(hrc))
+ {
+ ComPtr<IStorageController> ctl;
+
+ CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszHostIOCache, "on"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(UseHostIOCache)(TRUE));
+ }
+ else if (!RTStrICmp(pszHostIOCache, "off"))
+ {
+ CHECK_ERROR(ctl, COMSETTER(UseHostIOCache)(FALSE));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Invalid --hostiocache argument '%s'"), pszHostIOCache);
+ hrc = E_FAIL;
+ }
+ }
+ else
+ {
+ errorArgument(Storage::tr("Couldn't find the controller with the name: '%s'\n"), pszCtl);
+ hrc = E_FAIL; /** @todo r=andy Ditto. */
+ }
+ }
+
+ if ( pszBootable
+ && SUCCEEDED(hrc))
+ {
+ if (SUCCEEDED(hrc))
+ {
+ if (!RTStrICmp(pszBootable, "on"))
+ {
+ CHECK_ERROR(machine, SetStorageControllerBootable(Bstr(pszCtl).raw(), TRUE));
+ }
+ else if (!RTStrICmp(pszBootable, "off"))
+ {
+ CHECK_ERROR(machine, SetStorageControllerBootable(Bstr(pszCtl).raw(), FALSE));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Invalid --bootable argument '%s'"), pszBootable);
+ hrc = E_FAIL;
+ }
+ }
+ else
+ {
+ errorArgument(Storage::tr("Couldn't find the controller with the name: '%s'\n"), pszCtl);
+ hrc = E_FAIL;
+ }
+ }
+
+ if ( pszCtlNewName
+ && SUCCEEDED(hrc))
+ {
+ ComPtr<IStorageController> ctl;
+
+ CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
+ ctl.asOutParam()));
+
+ if (SUCCEEDED(hrc))
+ {
+ CHECK_ERROR(ctl, COMSETTER(Name)(Bstr(pszCtlNewName).raw()));
+ }
+ else
+ {
+ errorArgument(Storage::tr("Couldn't find the controller with the name: '%s'\n"), pszCtl);
+ hrc = E_FAIL;
+ }
+ }
+
+ }
+
+ /* commit changes */
+ if (SUCCEEDED(hrc))
+ CHECK_ERROR(machine, SaveSettings());
+
+ /* it's important to always close sessions */
+ a->session->UnlockMachine();
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
new file mode 100644
index 00000000..f86a02c9
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
@@ -0,0 +1,581 @@
+/* $Id: VBoxManageUSB.cpp $ */
+/** @file
+ * VBoxManage - VirtualBox's command-line interface.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include <VBox/com/com.h>
+#include <VBox/com/string.h>
+#include <VBox/com/Guid.h>
+#include <VBox/com/array.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+
+#include "VBoxManage.h"
+
+#include <iprt/asm.h>
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Usb);
+
+/**
+ * Quick IUSBDevice implementation for detaching / attaching
+ * devices to the USB Controller.
+ */
+class MyUSBDevice : public IUSBDevice
+{
+public:
+ // public initializer/uninitializer for internal purposes only
+ MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)
+ : m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),
+ m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),
+ m_bstrComment(a_pszComment),
+ m_cRefs(0)
+ {
+ }
+ virtual ~MyUSBDevice() {}
+
+ STDMETHOD_(ULONG, AddRef)(void)
+ {
+ return ASMAtomicIncU32(&m_cRefs);
+ }
+ STDMETHOD_(ULONG, Release)(void)
+ {
+ ULONG cRefs = ASMAtomicDecU32(&m_cRefs);
+ if (!cRefs)
+ delete this;
+ return cRefs;
+ }
+ STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)
+ {
+ Guid guid(iid);
+ if (guid == Guid(COM_IIDOF(IUnknown)))
+ *ppvObject = (IUnknown *)this;
+#ifdef RT_OS_WINDOWS
+ else if (guid == Guid(COM_IIDOF(IDispatch)))
+ *ppvObject = (IDispatch *)this;
+#endif
+ else if (guid == Guid(COM_IIDOF(IUSBDevice)))
+ *ppvObject = (IUSBDevice *)this;
+ else
+ return E_NOINTERFACE;
+ AddRef();
+ return S_OK;
+ }
+
+ STDMETHOD(COMGETTER(Id))(OUT_GUID a_pId) { NOREF(a_pId); return E_NOTIMPL; }
+ STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId) { *a_pusVendorId = m_usVendorId; return S_OK; }
+ STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId) { *a_pusProductId = m_usProductId; return S_OK; }
+ STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision) { *a_pusRevision = m_bcdRevision; return S_OK; }
+ STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash; return S_OK; }
+ STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer) { NOREF(a_pManufacturer); return E_NOTIMPL; }
+ STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct) { NOREF(a_pProduct); return E_NOTIMPL; }
+ STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber) { NOREF(a_pSerialNumber); return E_NOTIMPL; }
+ STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress) { NOREF(a_pAddress); return E_NOTIMPL; }
+
+private:
+ /** The vendor id of this USB device. */
+ USHORT m_usVendorId;
+ /** The product id of this USB device. */
+ USHORT m_usProductId;
+ /** The product revision number of this USB device.
+ * (high byte = integer; low byte = decimal) */
+ USHORT m_bcdRevision;
+ /** The USB serial hash of the device. */
+ uint64_t m_u64SerialHash;
+ /** The user comment string. */
+ Bstr m_bstrComment;
+ /** Reference counter. */
+ uint32_t volatile m_cRefs;
+};
+
+
+// types
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+class Nullable
+{
+public:
+
+ Nullable() : mIsNull(true) {}
+ Nullable(const T &aValue, bool aIsNull = false)
+ : mIsNull(aIsNull), mValue(aValue) {}
+
+ bool isNull() const { return mIsNull; };
+ void setNull(bool aIsNull = true) { mIsNull = aIsNull; }
+
+ operator const T&() const { return mValue; }
+
+ Nullable &operator= (const T &aValue)
+ {
+ mValue = aValue;
+ mIsNull = false;
+ return *this;
+ }
+
+private:
+
+ bool mIsNull;
+ T mValue;
+};
+
+/** helper structure to encapsulate USB filter manipulation commands */
+struct USBFilterCmd
+{
+ struct USBFilter
+ {
+ USBFilter()
+ : mAction(USBDeviceFilterAction_Null)
+ {}
+
+ Bstr mName;
+ Nullable <bool> mActive;
+ Bstr mVendorId;
+ Bstr mProductId;
+ Bstr mRevision;
+ Bstr mManufacturer;
+ Bstr mProduct;
+ Bstr mPort;
+ Bstr mRemote;
+ Bstr mSerialNumber;
+ Nullable <ULONG> mMaskedInterfaces;
+ USBDeviceFilterAction_T mAction;
+ };
+
+ enum Action { Invalid, Add, Modify, Remove };
+
+ USBFilterCmd() : mAction(Invalid), mIndex(0), mGlobal(false) {}
+
+ Action mAction;
+ uint32_t mIndex;
+ /** flag whether the command target is a global filter */
+ bool mGlobal;
+ /** machine this command is targeted at (null for global filters) */
+ ComPtr<IMachine> mMachine;
+ USBFilter mFilter;
+};
+
+RTEXITCODE handleUSBFilter(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+ USBFilterCmd cmd;
+
+ /* which command? */
+ cmd.mAction = USBFilterCmd::Invalid;
+ if (!strcmp(a->argv[0], "add"))
+ {
+ cmd.mAction = USBFilterCmd::Add;
+ setCurrentSubcommand(HELP_SCOPE_USBFILTER_ADD);
+ }
+ else if (!strcmp(a->argv[0], "modify"))
+ {
+ cmd.mAction = USBFilterCmd::Modify;
+ setCurrentSubcommand(HELP_SCOPE_USBFILTER_MODIFY);
+ }
+ else if (!strcmp(a->argv[0], "remove"))
+ {
+ cmd.mAction = USBFilterCmd::Remove;
+ setCurrentSubcommand(HELP_SCOPE_USBFILTER_REMOVE);
+ }
+
+ if (cmd.mAction == USBFilterCmd::Invalid)
+ return errorUnknownSubcommand(a->argv[0]);
+
+ /* which index? */
+ if (VINF_SUCCESS != RTStrToUInt32Full(a->argv[1], 10, &cmd.mIndex))
+ return errorSyntax(Usb::tr("Invalid index '%s'"), a->argv[1]);
+
+ if (cmd.mAction == USBFilterCmd::Add || cmd.mAction == USBFilterCmd::Modify)
+ {
+ // set Active to true by default
+ // (assuming that the user sets up all necessary attributes
+ // at once and wants the filter to be active immediately)
+ if (cmd.mAction == USBFilterCmd::Add)
+ cmd.mFilter.mActive = true;
+
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--target", 't', RTGETOPT_REQ_STRING },
+ { "--name", 'n', RTGETOPT_REQ_STRING },
+ { "--active", 'a', RTGETOPT_REQ_STRING },
+ { "--vendorid", 'v', RTGETOPT_REQ_STRING },
+ { "--productid", 'p', RTGETOPT_REQ_STRING },
+ { "--revision", 'r', RTGETOPT_REQ_STRING },
+ { "--manufacturer", 'm', RTGETOPT_REQ_STRING },
+ { "--product", 'P', RTGETOPT_REQ_STRING },
+ { "--serialnumber", 's', RTGETOPT_REQ_STRING },
+ { "--port", 'o', RTGETOPT_REQ_STRING },
+ { "--remote", 'R', RTGETOPT_REQ_STRING },
+ { "--maskedinterfaces", 'M', RTGETOPT_REQ_UINT32 },
+ { "--action", 'A', RTGETOPT_REQ_STRING }
+ };
+
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 't': // --target
+ if (!strcmp(ValueUnion.psz, "global"))
+ cmd.mGlobal = true;
+ else
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(ValueUnion.psz).raw(),
+ cmd.mMachine.asOutParam()), RTEXITCODE_FAILURE);
+ break;
+ case 'n': // --name
+ cmd.mFilter.mName = ValueUnion.psz;
+ break;
+ case 'a': // --active
+ if (!strcmp(ValueUnion.psz, "yes"))
+ cmd.mFilter.mActive = true;
+ else if (!strcmp(ValueUnion.psz, "no"))
+ cmd.mFilter.mActive = false;
+ else
+ return errorArgument(Usb::tr("Invalid --active argument '%s'"), ValueUnion.psz);
+ break;
+ case 'v': // --vendorid
+ cmd.mFilter.mVendorId = ValueUnion.psz;
+ break;
+ case 'p': // --productid
+ cmd.mFilter.mProductId = ValueUnion.psz;
+ break;
+ case 'r': // --revision
+ cmd.mFilter.mRevision = ValueUnion.psz;
+ break;
+ case 'm': // --manufacturer
+ cmd.mFilter.mManufacturer = ValueUnion.psz;
+ break;
+ case 'P': // --product
+ cmd.mFilter.mProduct = ValueUnion.psz;
+ break;
+ case 's': // --serialnumber
+ cmd.mFilter.mSerialNumber = ValueUnion.psz;
+ break;
+ case 'o': // --port
+ cmd.mFilter.mPort = ValueUnion.psz;
+ break;
+ case 'R': // --remote
+ cmd.mFilter.mRemote = ValueUnion.psz;
+ break;
+ case 'M': // --maskedinterfaces
+ cmd.mFilter.mMaskedInterfaces = ValueUnion.u32;
+ break;
+ case 'A': // --action
+ if (!strcmp(ValueUnion.psz, "ignore"))
+ cmd.mFilter.mAction = USBDeviceFilterAction_Ignore;
+ else if (!strcmp(ValueUnion.psz, "hold"))
+ cmd.mFilter.mAction = USBDeviceFilterAction_Hold;
+ else
+ return errorArgument(Usb::tr("Invalid USB filter action '%s'"), ValueUnion.psz);
+ break;
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+
+ // mandatory/forbidden options
+ if (!cmd.mGlobal && !cmd.mMachine)
+ return errorSyntax(Usb::tr("Missing required option: --target"));
+
+ if (cmd.mAction == USBFilterCmd::Add)
+ {
+ if (cmd.mFilter.mName.isEmpty())
+ return errorSyntax(Usb::tr("Missing required option: --name"));
+
+ if (cmd.mGlobal && cmd.mFilter.mAction == USBDeviceFilterAction_Null)
+ return errorSyntax(Usb::tr("Missing required option: --action"));
+
+ if (cmd.mGlobal && !cmd.mFilter.mRemote.isEmpty())
+ return errorSyntax(Usb::tr("Option --remote applies to VM filters only (--target=<uuid|vmname>)"));
+ }
+ }
+ else if (cmd.mAction == USBFilterCmd::Remove)
+ {
+ RTGETOPTSTATE GetState;
+ RTGETOPTUNION ValueUnion;
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--target", 't', RTGETOPT_REQ_STRING }
+ };
+ int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/);
+ AssertRCReturn(vrc, RTEXITCODE_FAILURE);
+
+ while ((vrc = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (vrc)
+ {
+ case 't': // --target
+ if (!strcmp(ValueUnion.psz, "global"))
+ cmd.mGlobal = true;
+ else
+ CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(ValueUnion.psz).raw(),
+ cmd.mMachine.asOutParam()), RTEXITCODE_FAILURE);
+ break;
+ default:
+ return errorGetOpt(vrc, &ValueUnion);
+ }
+ }
+ // mandatory options
+ if (!cmd.mGlobal && !cmd.mMachine)
+ return errorSyntax(Usb::tr("Missing required option: --target"));
+ }
+
+ USBFilterCmd::USBFilter &f = cmd.mFilter;
+
+ ComPtr<IHost> host;
+ ComPtr<IUSBDeviceFilters> flts;
+ if (cmd.mGlobal)
+ CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+ else
+ {
+ /* open a session for the VM */
+ CHECK_ERROR_RET(cmd.mMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+ /* get the mutable session machine */
+ a->session->COMGETTER(Machine)(cmd.mMachine.asOutParam());
+ /* and get the USB device filters */
+ CHECK_ERROR_RET(cmd.mMachine, COMGETTER(USBDeviceFilters)(flts.asOutParam()), RTEXITCODE_FAILURE);
+ }
+
+ switch (cmd.mAction)
+ {
+ case USBFilterCmd::Add:
+ {
+ if (cmd.mGlobal)
+ {
+ ComPtr<IHostUSBDeviceFilter> flt;
+ CHECK_ERROR_BREAK(host, CreateUSBDeviceFilter(f.mName.raw(),
+ flt.asOutParam()));
+
+ if (!f.mActive.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Active)(f.mActive));
+ if (!f.mVendorId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(VendorId)(f.mVendorId.raw()));
+ if (!f.mProductId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(ProductId)(f.mProductId.raw()));
+ if (!f.mRevision.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Revision)(f.mRevision.raw()));
+ if (!f.mManufacturer.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Manufacturer)(f.mManufacturer.raw()));
+ if (!f.mProduct.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Product)(f.mProduct.raw()));
+ if (!f.mPort.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Port)(f.mPort.raw()));
+ if (!f.mSerialNumber.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(SerialNumber)(f.mSerialNumber.raw()));
+ if (!f.mMaskedInterfaces.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(MaskedInterfaces)(f.mMaskedInterfaces));
+
+ if (f.mAction != USBDeviceFilterAction_Null)
+ CHECK_ERROR_BREAK(flt, COMSETTER(Action)(f.mAction));
+
+ CHECK_ERROR_BREAK(host, InsertUSBDeviceFilter(cmd.mIndex, flt));
+ }
+ else
+ {
+ ComPtr<IUSBDeviceFilter> flt;
+ CHECK_ERROR_BREAK(flts, CreateDeviceFilter(f.mName.raw(),
+ flt.asOutParam()));
+
+ if (!f.mActive.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Active)(f.mActive));
+ if (!f.mVendorId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(VendorId)(f.mVendorId.raw()));
+ if (!f.mProductId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(ProductId)(f.mProductId.raw()));
+ if (!f.mRevision.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Revision)(f.mRevision.raw()));
+ if (!f.mManufacturer.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Manufacturer)(f.mManufacturer.raw()));
+ if (!f.mProduct.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Product)(f.mProduct.raw()));
+ if (!f.mPort.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Port)(f.mPort.raw()));
+ if (!f.mRemote.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Remote)(f.mRemote.raw()));
+ if (!f.mSerialNumber.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(SerialNumber)(f.mSerialNumber.raw()));
+ if (!f.mMaskedInterfaces.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(MaskedInterfaces)(f.mMaskedInterfaces));
+
+ CHECK_ERROR_BREAK(flts, InsertDeviceFilter(cmd.mIndex, flt));
+ }
+ break;
+ }
+ case USBFilterCmd::Modify:
+ {
+ if (cmd.mGlobal)
+ {
+ SafeIfaceArray <IHostUSBDeviceFilter> coll;
+ CHECK_ERROR_BREAK(host, COMGETTER(USBDeviceFilters)(ComSafeArrayAsOutParam(coll)));
+
+ ComPtr<IHostUSBDeviceFilter> flt = coll[cmd.mIndex];
+
+ if (!f.mName.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Name)(f.mName.raw()));
+ if (!f.mActive.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Active)(f.mActive));
+ if (!f.mVendorId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(VendorId)(f.mVendorId.raw()));
+ if (!f.mProductId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(ProductId)(f.mProductId.raw()));
+ if (!f.mRevision.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Revision)(f.mRevision.raw()));
+ if (!f.mManufacturer.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Manufacturer)(f.mManufacturer.raw()));
+ if (!f.mProduct.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Product)(f.mProduct.raw()));
+ if (!f.mPort.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Port)(f.mPort.raw()));
+ if (!f.mSerialNumber.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(SerialNumber)(f.mSerialNumber.raw()));
+ if (!f.mMaskedInterfaces.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(MaskedInterfaces)(f.mMaskedInterfaces));
+
+ if (f.mAction != USBDeviceFilterAction_Null)
+ CHECK_ERROR_BREAK(flt, COMSETTER(Action)(f.mAction));
+ }
+ else
+ {
+ SafeIfaceArray <IUSBDeviceFilter> coll;
+ CHECK_ERROR_BREAK(flts, COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(coll)));
+
+ ComPtr<IUSBDeviceFilter> flt = coll[cmd.mIndex];
+
+ if (!f.mName.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Name)(f.mName.raw()));
+ if (!f.mActive.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Active)(f.mActive));
+ if (!f.mVendorId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(VendorId)(f.mVendorId.raw()));
+ if (!f.mProductId.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(ProductId)(f.mProductId.raw()));
+ if (!f.mRevision.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Revision)(f.mRevision.raw()));
+ if (!f.mManufacturer.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Manufacturer)(f.mManufacturer.raw()));
+ if (!f.mProduct.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Product)(f.mProduct.raw()));
+ if (!f.mPort.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Port)(f.mPort.raw()));
+ if (!f.mRemote.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(Remote)(f.mRemote.raw()));
+ if (!f.mSerialNumber.isEmpty())
+ CHECK_ERROR_BREAK(flt, COMSETTER(SerialNumber)(f.mSerialNumber.raw()));
+ if (!f.mMaskedInterfaces.isNull())
+ CHECK_ERROR_BREAK(flt, COMSETTER(MaskedInterfaces)(f.mMaskedInterfaces));
+ }
+ break;
+ }
+ case USBFilterCmd::Remove:
+ {
+ if (cmd.mGlobal)
+ {
+ ComPtr<IHostUSBDeviceFilter> flt;
+ CHECK_ERROR_BREAK(host, RemoveUSBDeviceFilter(cmd.mIndex));
+ }
+ else
+ {
+ ComPtr<IUSBDeviceFilter> flt;
+ CHECK_ERROR_BREAK(flts, RemoveDeviceFilter(cmd.mIndex, flt.asOutParam()));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (cmd.mMachine)
+ {
+ if (SUCCEEDED(hrc))
+ {
+ /* commit the session */
+ CHECK_ERROR(cmd.mMachine, SaveSettings());
+ }
+ /* close the session */
+ a->session->UnlockMachine();
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+RTEXITCODE handleUSBDevSource(HandlerArg *a)
+{
+ HRESULT hrc = S_OK;
+
+ /* at least: 0: command, 1: source id */
+ if (a->argc < 2)
+ return errorSyntax(Usb::tr("Not enough parameters"));
+
+ ComPtr<IHost> host;
+ if (!strcmp(a->argv[0], "add"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_USBDEVSOURCE_ADD);
+
+ Bstr strBackend;
+ Bstr strAddress;
+ if (a->argc != 6)
+ return errorSyntax(Usb::tr("Invalid number of parameters"));
+
+ for (int i = 2; i < a->argc; i++)
+ {
+ if (!strcmp(a->argv[i], "--backend"))
+ {
+ i++;
+ strBackend = a->argv[i];
+ }
+ else if (!strcmp(a->argv[i], "--address"))
+ {
+ i++;
+ strAddress = a->argv[i];
+ }
+ else
+ return errorSyntax(Usb::tr("Parameter \"%s\" is invalid"), a->argv[i]);
+ }
+
+ SafeArray<BSTR> usbSourcePropNames;
+ SafeArray<BSTR> usbSourcePropValues;
+
+ CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(host, AddUSBDeviceSource(strBackend.raw(), Bstr(a->argv[1]).raw(), strAddress.raw(),
+ ComSafeArrayAsInParam(usbSourcePropNames), ComSafeArrayAsInParam(usbSourcePropValues)),
+ RTEXITCODE_FAILURE);
+ }
+ else if (!strcmp(a->argv[0], "remove"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_USBDEVSOURCE_REMOVE);
+ CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
+ CHECK_ERROR_RET(host, RemoveUSBDeviceSource(Bstr(a->argv[1]).raw()), RTEXITCODE_FAILURE);
+ }
+
+ return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageUpdateCheck.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageUpdateCheck.cpp
new file mode 100644
index 00000000..5b66b70b
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageUpdateCheck.cpp
@@ -0,0 +1,392 @@
+/* $Id: VBoxManageUpdateCheck.cpp $ */
+/** @file
+ * VBoxManage - The 'updatecheck' command.
+ */
+
+/*
+ * Copyright (C) 2020-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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <VBox/com/com.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/VirtualBox.h>
+#include <VBox/com/array.h>
+
+#include <iprt/buildconfig.h>
+#include <VBox/version.h>
+
+#include <VBox/log.h>
+#include <iprt/getopt.h>
+#include <iprt/stream.h>
+#include <iprt/ctype.h>
+#include <iprt/message.h>
+
+#include "VBoxManage.h"
+
+DECLARE_TRANSLATION_CONTEXT(UpdateCheck);
+
+using namespace com; // SafeArray
+
+
+static RTEXITCODE doUpdateList(int argc, char **argv, ComPtr<IUpdateAgent> pUpdateAgent)
+{
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--machine-readable", 'm', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
+ AssertRCReturn(vrc, RTEXITCODE_INIT);
+
+ bool fMachineReadable = false;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'm':
+ fMachineReadable = true;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /*
+ * Do the work.
+ */
+ BOOL fEnabled;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(Enabled)(&fEnabled), RTEXITCODE_FAILURE);
+ if (fMachineReadable)
+ outputMachineReadableBool("enabled", &fEnabled);
+ else
+ RTPrintf(UpdateCheck::tr("Enabled: %s\n"),
+ fEnabled ? UpdateCheck::tr("yes") : UpdateCheck::tr("no"));
+
+ ULONG cCheckCount;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(CheckCount)(&cCheckCount), RTEXITCODE_FAILURE);
+ if (fMachineReadable)
+ outputMachineReadableULong("count", &cCheckCount);
+ else
+ RTPrintf(UpdateCheck::tr("Count: %u\n"), cCheckCount);
+
+ ULONG uCheckFreqSeconds;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(CheckFrequency)(&uCheckFreqSeconds), RTEXITCODE_FAILURE);
+
+ ULONG uCheckFreqDays = uCheckFreqSeconds / RT_SEC_1DAY;
+
+ if (fMachineReadable)
+ outputMachineReadableULong("frequency-days", &uCheckFreqDays);
+ else if (uCheckFreqDays == 0)
+ RTPrintf(UpdateCheck::tr("Frequency: Never\n"));
+ else if (uCheckFreqDays == 1)
+ RTPrintf(UpdateCheck::tr("Frequency: Every day\n"));
+ else
+ RTPrintf(UpdateCheck::tr("Frequency: Every %u days\n"), uCheckFreqDays);
+
+ UpdateChannel_T enmUpdateChannel;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(Channel)(&enmUpdateChannel), RTEXITCODE_FAILURE);
+ const char *psz;
+ const char *pszMachine;
+ switch (enmUpdateChannel)
+ {
+ case UpdateChannel_Stable:
+ psz = UpdateCheck::tr("Stable - new minor and maintenance releases");
+ pszMachine = "stable";
+ break;
+ case UpdateChannel_All:
+ psz = UpdateCheck::tr("All releases - new minor, maintenance, and major releases");
+ pszMachine = "all-releases";
+ break;
+ case UpdateChannel_WithBetas:
+ psz = UpdateCheck::tr("With Betas - new minor, maintenance, major, and beta releases");
+ pszMachine = "with-betas";
+ break;
+ default:
+ AssertFailed();
+ psz = UpdateCheck::tr("Unset");
+ pszMachine = "invalid";
+ break;
+ }
+ if (fMachineReadable)
+ outputMachineReadableString("channel", pszMachine);
+ else
+ RTPrintf(UpdateCheck::tr("Channel: %s\n"), psz);
+
+ Bstr bstrVal;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(LastCheckDate)(bstrVal.asOutParam()),
+ RTEXITCODE_FAILURE);
+ if (fMachineReadable)
+ outputMachineReadableString("last-check-date", &bstrVal);
+ else if (bstrVal.isNotEmpty())
+ RTPrintf(UpdateCheck::tr("Last Check Date: %ls\n"), bstrVal.raw());
+
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(RepositoryURL)(bstrVal.asOutParam()), RTEXITCODE_FAILURE);
+ if (fMachineReadable)
+ outputMachineReadableString("repo-url", &bstrVal);
+ else
+ RTPrintf(UpdateCheck::tr("Repository: %ls\n"), bstrVal.raw());
+
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE doUpdateModify(int argc, char **argv, ComPtr<IUpdateAgent> pUpdateAgent)
+{
+ /*
+ * Parse options.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--enable", 'e', RTGETOPT_REQ_NOTHING },
+ { "--disable", 'd', RTGETOPT_REQ_NOTHING },
+ { "--channel", 'c', RTGETOPT_REQ_STRING },
+ { "--frequency", 'f', RTGETOPT_REQ_UINT32 },
+ };
+
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
+ AssertRCReturn(vrc, RTEXITCODE_INIT);
+
+ int fEnabled = -1; /* Tristate: -1 (not modified), false, true. */
+ UpdateChannel_T enmChannel = (UpdateChannel_T)-1;
+ uint32_t cFrequencyDays = 0;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'e':
+ fEnabled = true;
+ break;
+
+ case 'd':
+ fEnabled = false;
+ break;
+
+ case 'c':
+ if (!RTStrICmp(ValueUnion.psz, "stable"))
+ enmChannel = UpdateChannel_Stable;
+ else if (!RTStrICmp(ValueUnion.psz, "withbetas"))
+ enmChannel = UpdateChannel_WithBetas;
+ /** @todo UpdateChannel_WithTesting once supported. */
+ else if (!RTStrICmp(ValueUnion.psz, "all"))
+ enmChannel = UpdateChannel_All;
+ else
+ return errorArgument(UpdateCheck::tr("Invalid channel specified: '%s'"), ValueUnion.psz);
+ break;
+
+ case 'f':
+ cFrequencyDays = ValueUnion.u32;
+ if (cFrequencyDays == 0)
+ return errorArgument(UpdateCheck::tr("The update frequency cannot be zero"));
+ break;
+
+ /** @todo Add more options like repo handling etc. */
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ if ( fEnabled == -1
+ && enmChannel == (UpdateChannel_T)-1
+ && cFrequencyDays == 0)
+ return errorSyntax(UpdateCheck::tr("No change requested"));
+
+ /*
+ * Make the changes.
+ */
+ if (enmChannel != (UpdateChannel_T)-1)
+ {
+ CHECK_ERROR2I_RET(pUpdateAgent, COMSETTER(Channel)(enmChannel), RTEXITCODE_FAILURE);
+ }
+ if (fEnabled != -1)
+ {
+ CHECK_ERROR2I_RET(pUpdateAgent, COMSETTER(Enabled)((BOOL)fEnabled), RTEXITCODE_FAILURE);
+ }
+ if (cFrequencyDays)
+ {
+ CHECK_ERROR2I_RET(pUpdateAgent, COMSETTER(CheckFrequency)(cFrequencyDays * RT_SEC_1DAY), RTEXITCODE_FAILURE);
+ }
+ return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE doUpdateCheck(int argc, char **argv, ComPtr<IUpdateAgent> pUpdateAgent)
+{
+ /*
+ * Parse arguments.
+ */
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--machine-readable", 'm', RTGETOPT_REQ_NOTHING }
+ };
+ RTGETOPTSTATE GetState;
+ int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
+ AssertRCReturn(vrc, RTEXITCODE_INIT);
+
+ bool fMachineReadable = false;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
+ {
+ switch (c)
+ {
+ case 'm':
+ fMachineReadable = true;
+ break;
+
+ default:
+ return errorGetOpt(c, &ValueUnion);
+ }
+ }
+
+ /*
+ * Do the work.
+ */
+ Bstr bstrName;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(Name)(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+
+ if (!fMachineReadable)
+ RTPrintf(UpdateCheck::tr("Checking for a new %ls version...\n"), bstrName.raw());
+
+ /*
+ * We don't call CHECK_ERROR2I_RET(pHostUpdate, VBoxUpdate(updateCheckType, ...); here so we can check for a specific
+ * return value indicating update checks are disabled.
+ */
+ ComPtr<IProgress> pProgress;
+ HRESULT hrc = pUpdateAgent->CheckFor(pProgress.asOutParam());
+ if (FAILED(hrc))
+ {
+ if (pProgress.isNull())
+ RTStrmPrintf(g_pStdErr, UpdateCheck::tr("Failed to create update progress object: %Rhrc\n"), hrc);
+ else
+ com::GlueHandleComError(pUpdateAgent, "HostUpdate(UpdateChannel_Stable, pProgress.asOutParam())",
+ hrc, __FILE__, __LINE__);
+ return RTEXITCODE_FAILURE;
+ }
+
+ /* HRESULT hrc = */ showProgress(pProgress, fMachineReadable ? SHOW_PROGRESS_NONE : SHOW_PROGRESS);
+ CHECK_PROGRESS_ERROR_RET(pProgress, (UpdateCheck::tr("Checking for update failed.")), RTEXITCODE_FAILURE);
+
+ UpdateState_T updateState;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(State)(&updateState), RTEXITCODE_FAILURE);
+
+ BOOL const fUpdateNeeded = updateState == UpdateState_Available;
+ if (fMachineReadable)
+ outputMachineReadableBool("update-needed", &fUpdateNeeded);
+
+ switch (updateState)
+ {
+ case UpdateState_Available:
+ {
+ Bstr bstrUpdateVersion;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(Version)(bstrUpdateVersion.asOutParam()), RTEXITCODE_FAILURE);
+ Bstr bstrUpdateURL;
+ CHECK_ERROR2I_RET(pUpdateAgent, COMGETTER(DownloadUrl)(bstrUpdateURL.asOutParam()), RTEXITCODE_FAILURE);
+
+ if (!fMachineReadable)
+ RTPrintf(UpdateCheck::tr(
+ "A new version of %ls has been released! Version %ls is available at virtualbox.org.\n"
+ "You can download this version here: %ls\n"),
+ bstrName.raw(), bstrUpdateVersion.raw(), bstrUpdateURL.raw());
+ else
+ {
+ outputMachineReadableString("update-version", &bstrUpdateVersion);
+ outputMachineReadableString("update-url", &bstrUpdateURL);
+ }
+
+ break;
+ }
+
+ case UpdateState_NotAvailable:
+ {
+ if (!fMachineReadable)
+ RTPrintf(UpdateCheck::tr("You are already running the most recent version of %ls.\n"), bstrName.raw());
+ break;
+ }
+
+ case UpdateState_Canceled:
+ break;
+
+ case UpdateState_Error:
+ RT_FALL_THROUGH();
+ default:
+ {
+ if (!fMachineReadable)
+ RTPrintf(UpdateCheck::tr("Something went wrong while checking for updates!\n"
+ "Please check network connection and try again later.\n"));
+ break;
+ }
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the 'updatecheck' command.
+ *
+ * @returns Appropriate exit code.
+ * @param a Handler argument.
+ */
+RTEXITCODE handleUpdateCheck(HandlerArg *a)
+{
+ ComPtr<IHost> pHost;
+ CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(pHost.asOutParam()), RTEXITCODE_FAILURE);
+
+ ComPtr<IUpdateAgent> pUpdate;
+ CHECK_ERROR2I_RET(pHost, COMGETTER(UpdateHost)(pUpdate.asOutParam()), RTEXITCODE_FAILURE);
+ /** @todo Add other update agents here. */
+
+ if (a->argc < 1)
+ return errorNoSubcommand();
+ if (!RTStrICmp(a->argv[0], "perform"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_PERFORM);
+ return doUpdateCheck(a->argc - 1, &a->argv[1], pUpdate);
+ }
+ if (!RTStrICmp(a->argv[0], "list"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_LIST);
+ return doUpdateList(a->argc - 1, &a->argv[1], pUpdate);
+ }
+ if (!RTStrICmp(a->argv[0], "modify"))
+ {
+ setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_MODIFY);
+ return doUpdateModify(a->argc - 1, &a->argv[1], pUpdate);
+ }
+ return errorUnknownSubcommand(a->argv[0]);
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageUtils.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageUtils.cpp
new file mode 100644
index 00000000..ad3fc508
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageUtils.cpp
@@ -0,0 +1,131 @@
+/* $Id: VBoxManageUtils.cpp $ */
+/** @file
+ * VBoxManageUtils.h - VBoxManage utility functions.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "VBoxManageUtils.h"
+#include "VBoxManage.h"
+
+#include <iprt/message.h>
+#include <iprt/string.h>
+
+#include <VBox/com/array.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/com/string.h>
+
+using namespace com;
+
+DECLARE_TRANSLATION_CONTEXT(Utils);
+
+unsigned int getMaxNics(const ComPtr<IVirtualBox> &pVirtualBox,
+ const ComPtr<IMachine> &pMachine)
+{
+ ULONG NetworkAdapterCount = 0;
+ do {
+ HRESULT hrc;
+
+ ComPtr<ISystemProperties> info;
+ CHECK_ERROR_BREAK(pVirtualBox, COMGETTER(SystemProperties)(info.asOutParam()));
+
+ ChipsetType_T aChipset;
+ CHECK_ERROR_BREAK(pMachine, COMGETTER(ChipsetType)(&aChipset));
+
+ CHECK_ERROR_BREAK(info, GetMaxNetworkAdapters(aChipset, &NetworkAdapterCount));
+ } while (0);
+
+ return (unsigned int)NetworkAdapterCount;
+}
+
+
+/**
+ * API does NOT verify that whether the interface name set as the
+ * bridged or host-only interface of a NIC is valid. Warn the user if
+ * IHost doesn't seem to know about it (non-fatal).
+ */
+void verifyHostNetworkInterfaceName(const ComPtr<IVirtualBox> &pVirtualBox,
+ const char *pszTargetName,
+ HostNetworkInterfaceType_T enmTargetType)
+{
+ HRESULT hrc;
+
+ AssertReturnVoid( enmTargetType == HostNetworkInterfaceType_Bridged
+ || enmTargetType == HostNetworkInterfaceType_HostOnly);
+
+ ComPtr<IHost> host;
+ hrc = pVirtualBox->COMGETTER(Host)(host.asOutParam());
+ if (FAILED(hrc))
+ return;
+
+ SafeIfaceArray<IHostNetworkInterface> ifs;
+ hrc = host->COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(ifs));
+ if (FAILED(hrc))
+ return;
+
+ for (size_t i = 0; i < ifs.size(); ++i)
+ {
+ const ComPtr<IHostNetworkInterface> iface = ifs[i];
+
+ Bstr bstrName;
+ hrc = iface->COMGETTER(Name)(bstrName.asOutParam());
+ if (FAILED(hrc))
+ return;
+
+ if (!bstrName.equals(pszTargetName))
+ continue;
+
+ /* we found the interface but is it the right type? */
+ HostNetworkInterfaceType_T enmType;
+ hrc = iface->COMGETTER(InterfaceType)(&enmType);
+ if (FAILED(hrc))
+ return;
+
+ if (enmType == enmTargetType)
+ return; /* seems ok */
+
+ const char *pszTypeName;
+ char a_szUnknownTypeBuf[32];
+ switch (enmType)
+ {
+ case HostNetworkInterfaceType_Bridged:
+ pszTypeName = Utils::tr("type bridged");
+ break;
+
+ case HostNetworkInterfaceType_HostOnly:
+ pszTypeName = Utils::tr("type host-only");
+ break;
+
+ default:
+ RTStrPrintf(a_szUnknownTypeBuf, sizeof(a_szUnknownTypeBuf),
+ Utils::tr("unknown type %RU32"), enmType);
+ pszTypeName = a_szUnknownTypeBuf;
+ break;
+ }
+
+ RTMsgWarning(Utils::tr("Interface \"%s\" is of %s"), pszTargetName, pszTypeName);
+ return;
+ }
+
+ RTMsgWarning(Utils::tr("Interface \"%s\" doesn't seem to exist"), pszTargetName);
+}
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageUtils.h b/src/VBox/Frontends/VBoxManage/VBoxManageUtils.h
new file mode 100644
index 00000000..55241c37
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageUtils.h
@@ -0,0 +1,45 @@
+/* $Id: VBoxManageUtils.h $ */
+/** @file
+ * VBoxManageUtils.h - Declarations for VBoxManage utility functions.
+ */
+
+/*
+ * 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 <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_VBoxManage_VBoxManageUtils_h
+#define VBOX_INCLUDED_SRC_VBoxManage_VBoxManageUtils_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/com.h>
+#include <VBox/com/ptr.h>
+#include <VBox/com/VirtualBox.h>
+
+unsigned int getMaxNics(const ComPtr<IVirtualBox> &pVirtualBox,
+ const ComPtr<IMachine> &pMachine);
+
+void verifyHostNetworkInterfaceName(const ComPtr<IVirtualBox> &pVirtualBox,
+ const char *pszTargetName,
+ HostNetworkInterfaceType_T enmTargetType);
+
+#endif /* !VBOX_INCLUDED_SRC_VBoxManage_VBoxManageUtils_h */
diff --git a/src/VBox/Frontends/VBoxManage/nls/ApprovedLanguages.kmk b/src/VBox/Frontends/VBoxManage/nls/ApprovedLanguages.kmk
new file mode 100644
index 00000000..de405a5d
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/nls/ApprovedLanguages.kmk
@@ -0,0 +1,40 @@
+# $Id: ApprovedLanguages.kmk $
+## @file
+# ApprovedLanguages.kmk - List of approved VBoxManage translations.
+#
+
+#
+# Copyright (C) 2007-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 <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+# The list of approved VBoxManage languages.
+VBOX_APPROVED_VBOXMANAGE_LANGUAGES := \
+ ru
+
+# The list of approved VBoxManage language codes for built-in docbook
+# help. Order matters for codes in the case of a language used in
+# multiple countries. The language code used when no country is
+# specified should be placed before other codes with the same language.
+# For example: if en_US, en_UK and en_AU are approved the en_US should
+# be placed before others allowing en_US to be used when the user
+# specifies "en" as the desired language.
+VBOX_APPROVED_VBOXMANAGE_DOCBOOK_LANGUAGES := \
+ ru_RU
diff --git a/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_ru.ts b/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_ru.ts
new file mode 100644
index 00000000..6cf00e15
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_ru.ts
@@ -0,0 +1,12354 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru">
+<context>
+ <name>Appliance</name>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="256"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1551"/>
+ <source>Option &quot;%s&quot; can&apos;t be used together with &quot;--cloud&quot; option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Š° Š²Š¼ŠµŃŃ‚Šµ с &quot;--cloud&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="259"/>
+ <location filename="../VBoxManageAppliance.cpp" line="334"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1554"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1637"/>
+ <source>Value of option &quot;%s&quot; is out of range.</source>
+ <translation>Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ Š¾ŠæцŠøŠø &quot;%s&quot; Š²Ń‹Ń…Š¾Š“Šøт Š·Š° Š³Ń€Š°Š½Šøцы Š“ŠøŠ°ŠæŠ°Š·Š¾Š½Š°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="268"/>
+ <location filename="../VBoxManageAppliance.cpp" line="275"/>
+ <location filename="../VBoxManageAppliance.cpp" line="289"/>
+ <location filename="../VBoxManageAppliance.cpp" line="303"/>
+ <location filename="../VBoxManageAppliance.cpp" line="317"/>
+ <location filename="../VBoxManageAppliance.cpp" line="324"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1562"/>
+ <source>Option &quot;%s&quot; requires preceding --vsys or --cloud option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; трŠµŠ±ŃƒŠµŃ‚ Š½Š°Š»ŠøчŠøя ŠæрŠµŠ“шŠµŃŃ‚Š²ŃƒŠµŃ‰ŠµŠ³Š¾ --vsys ŠøŠ»Šø --cloud.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="282"/>
+ <location filename="../VBoxManageAppliance.cpp" line="296"/>
+ <location filename="../VBoxManageAppliance.cpp" line="310"/>
+ <location filename="../VBoxManageAppliance.cpp" line="331"/>
+ <location filename="../VBoxManageAppliance.cpp" line="342"/>
+ <location filename="../VBoxManageAppliance.cpp" line="352"/>
+ <location filename="../VBoxManageAppliance.cpp" line="362"/>
+ <location filename="../VBoxManageAppliance.cpp" line="372"/>
+ <location filename="../VBoxManageAppliance.cpp" line="382"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1569"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1576"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1583"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1590"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1597"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1604"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1611"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1618"/>
+ <source>Option &quot;%s&quot; requires preceding --vsys option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; трŠµŠ±ŃƒŠµŃ‚ Š½Š°Š»ŠøчŠøя ŠæрŠµŠ“шŠµŃŃ‚Š²ŃƒŠµŃ‰ŠµŠ³Š¾ --vsys.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="345"/>
+ <location filename="../VBoxManageAppliance.cpp" line="355"/>
+ <location filename="../VBoxManageAppliance.cpp" line="365"/>
+ <location filename="../VBoxManageAppliance.cpp" line="375"/>
+ <location filename="../VBoxManageAppliance.cpp" line="385"/>
+ <source>Option &quot;%s&quot; requires preceding --unit option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; трŠµŠ±ŃƒŠµŃ‚ Š½Š°Š»ŠøчŠøя ŠæрŠµŠ“шŠµŃŃ‚Š²ŃƒŠµŃ‰ŠµŠ³Š¾ --unit.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="392"/>
+ <source>Invalid import options &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Šµ Š¾ŠæцŠøŠø ŠøŠ¼ŠæŠ¾Ń€Ń‚Š° &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="401"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1634"/>
+ <source>Option &quot;%s&quot; can&apos;t be used together with &quot;--vsys&quot; option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Š° Š²Š¼ŠµŃŃ‚Šµ с &quot;--vsys&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="410"/>
+ <location filename="../VBoxManageAppliance.cpp" line="417"/>
+ <location filename="../VBoxManageAppliance.cpp" line="424"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1646"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1653"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1660"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1667"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1674"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1681"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1688"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1695"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1702"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1709"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1716"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1723"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1730"/>
+ <source>Option &quot;%s&quot; requires preceding --cloud option.</source>
+ <translation>ŠžŠæцŠøя &quot;%s&quot; трŠµŠ±ŃƒŠµŃ‚ Š½Š°Š»ŠøчŠøя ŠæрŠµŠ“шŠµŃŃ‚Š²ŃƒŠµŃ‰ŠµŠ³Š¾ --cloud.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="433"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="440"/>
+ <source>Invalid option -%c</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń Š¾ŠæцŠøя -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="442"/>
+ <source>Invalid option case %i</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š¾ŠæцŠøŠø %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="445"/>
+ <source>unknown option: %s
+</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="449"/>
+ <source>error: %Rrs</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ°: %Rrs</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="455"/>
+ <source>Not enough arguments for &quot;import&quot; command.</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š² Š“Š»Ń ŠŗŠ¾Š¼Š°Š½Š“ы &quot;import&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="477"/>
+ <source>Not enough arguments for import from the Cloud.</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š² Š“Š»Ń ŠøŠ¼ŠæŠ¾Ń€Ń‚Š° ŠøŠ· Š¾Š±Š»Š°ŠŗŠ°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="500"/>
+ <source>Appliance read failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="512"/>
+ <source>Interpreting %ls...
+</source>
+ <translation>Š˜Š½Ń‚ŠµŃ€ŠæрŠµŃ‚Š°Ń†Šøя %ls...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="544"/>
+ <source>Disks:
+</source>
+ <translation>Š”ŠøсŠŗŠø:
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="565"/>
+ <source>Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).</source>
+ <translation>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠøŠø -vsys; OVF сŠ¾Š“ŠµŃ€Š¶Šøт тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½ŃƒŃŽ сŠøстŠµŠ¼Ńƒ.</numerusform>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠø -vsys; OVF сŠ¾Š“ŠµŃ€Š¶Šøт тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Šµ сŠøстŠµŠ¼Ń‹.</numerusform>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠøŠø -vsys; OVF сŠ¾Š“ŠµŃ€Š¶Šøт тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Ń… сŠøстŠµŠ¼.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="600"/>
+ <source>Virtual system %u:
+</source>
+ <translation>Š’ŠøртуŠ°Š»ŃŒŠ½Š°Ń сŠøстŠµŠ¼Š° %u:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="630"/>
+ <source>%2u: OS type specified with --ostype: &quot;%ls&quot;
+</source>
+ <translation>%2u: Š¢ŠøŠæ ŠžŠ” уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ чŠµŃ€ŠµŠ· --ostype: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="634"/>
+ <source>%2u: Suggested OS type: &quot;%ls&quot;
+ (change with &quot;--vsys %u --ostype &lt;type&gt;&quot;; use &quot;list ostypes&quot; to list all possible values)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Ń‹Š¹ тŠøŠæ ŠžŠ”: &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --ostype &lt;тŠøŠæ&gt;&quot;; ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &quot;list ostypes&quot; Š“Š»Ń ŠæрŠ¾ŃŠ¼Š¾Ń‚Ń€Š° Š²ŃŠµŃ… Š²Š¾Š·Š¼Š¾Š¶Š½Ń‹Ń… Š·Š½Š°Ń‡ŠµŠ½ŠøŠ¹)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="643"/>
+ <source>%2u: VM name specified with --vmname: &quot;%ls&quot;
+</source>
+ <translation>%2u: Š˜Š¼Ń Š’Šœ, уŠŗŠ°Š·Š°Š½Š½Š¾Šµ чŠµŃ€ŠµŠ· --vmname: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="647"/>
+ <source>%2u: Suggested VM name &quot;%ls&quot;
+ (change with &quot;--vsys %u --vmname &lt;name&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Šµ ŠøŠ¼Ń Š’Šœ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --vmname &lt;ŠøŠ¼Ń&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="653"/>
+ <source>%2u: Product (ignored): %ls
+</source>
+ <translation>%2u: ŠŸŃ€Š¾Š“уŠŗт (ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½): %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="658"/>
+ <source>%2u: ProductUrl (ignored): %ls
+</source>
+ <translation>%2u: Url ŠæрŠ¾Š“уŠŗтŠ° (ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½): %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="663"/>
+ <source>%2u: Vendor (ignored): %ls
+</source>
+ <translation>%2u: ŠŸŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗ (ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½): %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="668"/>
+ <source>%2u: VendorUrl (ignored): %ls
+</source>
+ <translation>%2u: Url ŠæŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗŠ° (ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½): %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="673"/>
+ <source>%2u: Version (ignored): %ls
+</source>
+ <translation>%2u: Š’ŠµŃ€ŃŠøя (ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½Š°): %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="681"/>
+ <source>%2u: Description specified with --description: &quot;%ls&quot;
+</source>
+ <translation>%2u: ŠžŠæŠøсŠ°Š½ŠøŠµ, уŠŗŠ°Š·Š°Š½Š½Š¾Šµ чŠµŃ€ŠµŠ· --description: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="685"/>
+ <source>%2u: Description &quot;%ls&quot;
+ (change with &quot;--vsys %u --description &lt;desc&gt;&quot;)
+</source>
+ <translation>%2u: ŠžŠæŠøсŠ°Š½ŠøŠµ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --description &lt;Š¾ŠæŠøсŠ°Š½ŠøŠµ&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="696"/>
+ <source>%2u: End-user license agreement
+ (accept with &quot;--vsys %u --eula accept&quot;):
+
+%ls
+
+</source>
+ <translation>%2u: Š›ŠøцŠµŠ½Š·ŠøŠ¾Š½Š½Š¾Šµ сŠ¾Š³Š»Š°ŃˆŠµŠ½ŠøŠµ
+ (ŠæрŠøŠ½ŃŃ‚ŃŒ чŠµŃ€ŠµŠ· &quot;--vsys %u --eula accept&quot;):
+
+%ls
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="703"/>
+ <source>%2u: End-user license agreement (accepted)
+</source>
+ <translation>%2u: Š›ŠøцŠµŠ½Š·ŠøŠ¾Š½Š½Š¾Šµ сŠ¾Š³Š»Š°ŃˆŠµŠ½ŠøŠµ (ŠæрŠøŠ½ŃŃ‚Š¾)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="708"/>
+ <source>Argument to --eula must be either &quot;show&quot; or &quot;accept&quot;.</source>
+ <translation>ŠŃ€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --eula Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ ŠøŠ»Šø &quot;show&quot; ŠøŠ»Šø &quot;accept&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="711"/>
+ <source>%2u: End-user license agreement
+ (display with &quot;--vsys %u --eula show&quot;;
+ accept with &quot;--vsys %u --eula accept&quot;)
+</source>
+ <translation>%2u: Š›ŠøцŠµŠ½Š·ŠøŠ¾Š½Š½Š¾Šµ сŠ¾Š³Š»Š°ŃˆŠµŠ½ŠøŠµ
+ (ŠæŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ чŠµŃ€ŠµŠ· &quot;--vsys %u --eula show&quot;;
+ ŠæрŠøŠ½ŃŃ‚ŃŒ чŠµŃ€ŠµŠ· &quot;--vsys %u --eula accept&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="727"/>
+ <source>%2u: No. of CPUs specified with --cpus: %ls
+</source>
+ <translation>%2u: Š§ŠøсŠ»Š¾ Š¦ŠŸŠ£ уŠŗŠ°Š·Š°Š½Š½Ń‹Ń… чŠµŃ€ŠµŠ· --cpus: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="731"/>
+ <source>Argument to --cpus option must be a number greater than %d and less than %d.</source>
+ <translation>ŠŃ€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --cpus Š“Š¾Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ чŠøсŠ»Š¾Š¼ Š±Š¾Š»ŃŒŃˆŠµ %d Šø Š¼ŠµŠ½ŃŒŃˆŠµ %d.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="735"/>
+ <source>%2u: Number of CPUs: %ls
+ (change with &quot;--vsys %u --cpus &lt;n&gt;&quot;)
+</source>
+ <translation>%2u: Š§ŠøсŠ»Š¾ Š¦ŠŸŠ£: %ls
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --cpus &lt;n&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="747"/>
+ <source>%2u: Guest memory specified with --memory: %ls MB
+</source>
+ <translation>%2u: Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹, уŠŗŠ°Š·Š°Š½Š½Š¾Š¹ чŠµŃ€ŠµŠ· --memory: %ls MB
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="751"/>
+ <source>Argument to --memory option must be a non-negative number.</source>
+ <translation>ŠŃ€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --memory Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ Š½ŠµŠ¾Ń‚Ń€ŠøцŠ°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¼ чŠøсŠ»Š¾Š¼.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="754"/>
+ <source>%2u: Guest memory: %ls MB
+ (change with &quot;--vsys %u --memory &lt;MB&gt;&quot;)
+</source>
+ <translation>%2u: Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹: %ls MB
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --memory &lt;MB&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="762"/>
+ <source>%2u: IDE controller, type %ls -- disabled
+</source>
+ <translation>%2u: IDE ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="768"/>
+ <source>%2u: IDE controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: IDE ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="778"/>
+ <source>%2u: SATA controller, type %ls -- disabled
+</source>
+ <translation>%2u: SATA ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="784"/>
+ <source>%2u: SATA controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: SATA ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="794"/>
+ <source>%2u: SAS controller, type %ls -- disabled
+</source>
+ <translation>%2u: SAS ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="800"/>
+ <source>%2u: SAS controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: SAS ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="810"/>
+ <source>%2u: SCSI controller, type %ls -- disabled
+</source>
+ <translation>%2u: SCSI ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="821"/>
+ <source>%2u: SCSI controller, type set with --unit %u --scsitype: &quot;%ls&quot;
+</source>
+ <translation>%2u: SCSI ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ устŠ°Š½Š¾Š²Š»ŠµŠ½ чŠµŃ€ŠµŠ· --unit %u --scsitype: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="827"/>
+ <source>%2u: SCSI controller, type %ls
+ (change with &quot;--vsys %u --unit %u --scsitype {BusLogic|LsiLogic}&quot;;
+ disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: SCSI ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --scsitype {BusLogic|LsiLogic}&quot;;
+ Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="839"/>
+ <source>%2u: VirtioSCSI controller, type %ls -- disabled
+</source>
+ <translation>%2u: VirtioSCSI ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="845"/>
+ <source>%2u: VirtioSCSI controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: VirtioSCSI ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€, тŠøŠæ %ls
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="855"/>
+ <source>%2u: Hard disk image: source image=%ls -- disabled
+</source>
+ <translation>%2u: ŠžŠ±Ń€Š°Š· Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ°: Š¾Š±Ń€Š°Š· ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°=%ls -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <source>Option --ImportToVDI shall not be used together with manually set target path.</source>
+ <translation type="vanished">ŠžŠæцŠøя --ImportToVDI Š½Šµ Š“Š¾Š»Š¶Š½Š° ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ Š²Š¼ŠµŃŃ‚Šµ с ŠæутŠµŠ¼ Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¼ Š²Ń€ŃƒŃ‡Š½ŃƒŃŽ.</translation>
+ </message>
+ <message>
+ <source>%2u: Hard disk image: source image=%ls, target path=%ls, %ls
+</source>
+ <translation type="vanished">%2u: ŠžŠ±Ń€Š°Š· Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ°: Š¾Š±Ń€Š°Š· ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°=%ls, Šæуть Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя=%ls, %ls
+</translation>
+ </message>
+ <message>
+ <source>%2u: Hard disk image: source image=%ls, target path=%ls, %ls
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="vanished">%2u: ŠžŠ±Ń€Š°Š· Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ°: Š¾Š±Ń€Š°Š· ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°=%ls, Šæуть Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя=%ls, %ls
+ (ŠøŠ·Š¼ŠµŠ½Šøть Šæуть Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --disk Šæуть&quot;;
+ Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="870"/>
+ <source>Option --ImportToVDI can not be used together with a manually set target path.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="898"/>
+ <source>Invalid controller value: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="903"/>
+ <location filename="../VBoxManageAppliance.cpp" line="970"/>
+ <source>Invalid storage controller specified: %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="916"/>
+ <source>Invalid port value: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="931"/>
+ <source>Failed to extract controller value from ExtraConfig: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="937"/>
+ <source>Failed to extract channel value from ExtraConfig: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="963"/>
+ <source>Device already attached to controller %u at this port (%u) location.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1001"/>
+ <source>Illegal port value: %u. For %ls controllers the only valid values are 0 to %lu (inclusive)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1023"/>
+ <source>%2u: Hard disk image specified with --disk: source image=%ls, target path=%ls, %s
+ (change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1035"/>
+ <source>%2u: Hard disk image specified with --disk and --controller: source image=%ls, target path=%ls, %s
+ (change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1045"/>
+ <source>%2u: Hard disk image specified with --disk and --port: source image=%ls, target path=%ls, %s
+ (change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1055"/>
+ <source>%2u: Hard disk image specified with --controller and --port: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1065"/>
+ <source>%2u: Hard disk image specified with --port: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1077"/>
+ <source>%2u: Hard disk image specified with --controller: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1089"/>
+ <source>%2u: Hard disk image specified with --disk and --controller and --port: source image=%ls, target path=%ls, %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1174"/>
+ <source>%2u: Hard disk image: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;;
+ disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1191"/>
+ <source>%2u: CD-ROM -- disabled
+</source>
+ <translation>%2u: CD-ROM -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1196"/>
+ <source>%2u: CD-ROM
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: CD-ROM
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1204"/>
+ <source>%2u: Floppy -- disabled
+</source>
+ <translation>%2u: Š¤Š»Š¾ŠæŠæŠø -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1209"/>
+ <source>%2u: Floppy
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: Š¤Š»Š¾ŠæŠæŠø
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1215"/>
+ <source>%2u: Network adapter: orig %ls, config %ls, extra %ls
+</source>
+ <translation>%2u: Š”ŠµŃ‚ŠµŠ²Š¾Š¹ Š°Š“Š°ŠæтŠµŃ€: Š¾Ń€ŠøŠ³. %ls, ŠŗŠ¾Š½Ń„ŠøŠ³. %ls, эŠŗстрŠ° %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1225"/>
+ <source>%2u: USB controller -- disabled
+</source>
+ <translation>%2u: USB ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€ -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1230"/>
+ <source>%2u: USB controller
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: USB ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1238"/>
+ <source>%2u: Sound card &quot;%ls&quot; -- disabled
+</source>
+ <translation>%2u: ŠŃƒŠ“ŠøŠ¾ ŠŗŠ°Ń€Ń‚Š° &quot;%ls&quot; -- Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1244"/>
+ <source>%2u: Sound card (appliance expects &quot;%ls&quot;, can change on import)
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation>%2u: ŠŃƒŠ“ŠøŠ¾ ŠŗŠ°Ń€Ń‚Š° (ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя Š¾Š¶ŠøŠ“Š°ŠµŃ‚ &quot;%ls&quot;, Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½Š° ŠæрŠø ŠøŠ¼ŠæŠ¾Ń€Ń‚Šµ)
+ (Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --unit %u --ignore&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1256"/>
+ <source>%2u: VM settings file name specified with --settingsfile: &quot;%ls&quot;
+</source>
+ <translation>%2u: Š˜Š¼Ń фŠ°Š¹Š»Š° Š½Š°ŃŃ‚Ń€Š¾ŠµŠŗ Š’Šœ уŠŗŠ°Š·Š°Š½Š½Š¾Šµ чŠµŃ€ŠµŠ· --settingsfile: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1260"/>
+ <source>%2u: Suggested VM settings file name &quot;%ls&quot;
+ (change with &quot;--vsys %u --settingsfile &lt;filename&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Š¾Šµ ŠøŠ¼Ń фŠ°Š¹Š»Š° Š½Š°ŃŃ‚Ń€Š¾ŠµŠŗ Š’Šœ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --settingsfile &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1269"/>
+ <source>%2u: VM base folder specified with --basefolder: &quot;%ls&quot;
+</source>
+ <translation>%2u: ŠžŃŠ½Š¾Š²Š½Š°Ń ŠæŠ°ŠæŠŗŠ° Š’Šœ уŠŗŠ°Š·Š°Š½Š½Š°Ń чŠµŃ€ŠµŠ· --basefolder: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1273"/>
+ <source>%2u: Suggested VM base folder &quot;%ls&quot;
+ (change with &quot;--vsys %u --basefolder &lt;path&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Š°Ń Š¾ŃŠ½Š¾Š²Š½Š°Ń ŠæŠ°ŠæŠŗŠ° Š’Šœ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --basefolder &lt;Šæуть&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1282"/>
+ <source>%2u: VM group specified with --group: &quot;%ls&quot;
+</source>
+ <translation>%2u: Š“Ń€ŃƒŠæŠæŠ° Š’Šœ, уŠŗŠ°Š·Š°Š½Š½Š°Ń чŠµŃ€ŠµŠ· --group: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1286"/>
+ <source>%2u: Suggested VM group &quot;%ls&quot;
+ (change with &quot;--vsys %u --group &lt;group&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Š°Ń Š³Ń€ŃƒŠæŠæŠ° Š’Šœ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--vsys %u --group &lt;Š³Ń€ŃƒŠæŠæŠ°&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1292"/>
+ <source>%2u: Suggested cloud shape &quot;%ls&quot;
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Š°Ń Š¾Š±Š»Š°Ń‡Š½Š°Ń фŠ¾Ń€Š¼Š° &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1300"/>
+ <source>%2u: Cloud bucket id specified with --cloudbucket: &quot;%ls&quot;
+</source>
+ <translation>%2u: ID Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ ŠŗŠ¾Ń€Š·ŠøŠ½Ń‹, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ чŠµŃ€ŠµŠ· --cloudbucket: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1304"/>
+ <source>%2u: Suggested cloud bucket id &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudbucket &lt;id&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Ń‹Š¹ ID Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ ŠŗŠ¾Ń€Š·ŠøŠ½Ń‹ &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--cloud %u --cloudbucket &lt;id&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1313"/>
+ <source>%2u: Cloud profile name specified with --cloudprofile: &quot;%ls&quot;
+</source>
+ <translation>%2u: Š˜Š¼Ń Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń, уŠŗŠ°Š·Š°Š½Š½Š¾Š³Š¾ чŠµŃ€ŠµŠ· --cloudprofile: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1317"/>
+ <source>%2u: Suggested cloud profile name &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudprofile &lt;id&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Š¾Šµ ŠøŠ¼Ń Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--cloud %u --cloudprofile &lt;id&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1326"/>
+ <source>%2u: Cloud instance id specified with --cloudinstanceid: &quot;%ls&quot;
+</source>
+ <translation>%2u: ID Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š°, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ чŠµŃ€ŠµŠ· --cloudinstanceid: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1330"/>
+ <source>%2u: Suggested cloud instance id &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudinstanceid &lt;id&gt;&quot;)
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Ń‹Š¹ ID Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° &quot;%ls&quot;
+ (ŠøŠ·Š¼ŠµŠ½Šøть чŠµŃ€ŠµŠ· &quot;--cloud %u --cloudinstanceid &lt;id&gt;&quot;)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1336"/>
+ <source>%2u: Suggested cloud base image id &quot;%ls&quot;
+</source>
+ <translation>%2u: ŠŸŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½Š½Ń‹Š¹ ID Suggested cloud base image id &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1384"/>
+ <source>Cannot import until the license agreement listed above is accepted.</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾ŠøŠ·Š²ŠµŃŃ‚Šø ŠøŠ¼ŠæŠ¾Ń€Ń‚ ŠæŠ¾ŠŗŠ° Š½Šµ ŠæрŠøŠ½ŃŃ‚Ń‹ усŠ»Š¾Š²Šøя Š»ŠøцŠµŠ½Š·ŠøŠ¾Š½Š½Š¾Š³Š¾ сŠ¾Š³Š»Š°ŃˆŠµŠ½Šøя, ŠæŠ¾ŠŗŠ°Š·Š°Š½Š½Ń‹Šµ Š²Ń‹ŃˆŠµ.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1386"/>
+ <source>Cannot import until the %c license agreements listed above are accepted.</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾ŠøŠ·Š²ŠµŃŃ‚Šø ŠøŠ¼ŠæŠ¾Ń€Ń‚ ŠæŠ¾ŠŗŠ° Š½Šµ ŠæрŠøŠ½ŃŃ‚Ń‹ усŠ»Š¾Š²Šøя Š»ŠøцŠµŠ½Š·ŠøŠ¾Š½Š½Š¾Š³Š¾ сŠ¾Š³Š»Š°ŃˆŠµŠ½Šøя %c, ŠæŠ¾ŠŗŠ°Š·Š°Š½Š½Ń‹Šµ Š²Ń‹ŃˆŠµ.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1397"/>
+ <source>Appliance import failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾ŠøŠ·Š²ŠµŃŃ‚Šø ŠøŠ¼ŠæŠ¾Ń€Ń‚ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1400"/>
+ <source>Successfully imported the appliance.
+</source>
+ <translation>ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя ŠøŠ¼ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½Š° усŠæŠµŃˆŠ½Š¾.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1517"/>
+ <source>You can only specify --output once.</source>
+ <translation>--output Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1625"/>
+ <source>Invalid export options &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Šµ Š¾ŠæцŠøŠø ŠøŠ¼ŠæŠ¾Ń€Ń‚Š° &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1751"/>
+ <source>unhandled option: -%c</source>
+ <translation>Š½ŠµŠ¾Š±Ń€Š°Š±Š¾Ń‚Š°Š½Š½Š°Ń Š¾ŠæцŠøя: -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1753"/>
+ <source>unhandled option: %i</source>
+ <translation>Š½ŠµŠ¾Š±Ń€Š°Š±Š¾Ń‚Š°Š½Š½Š°Ń Š¾ŠæцŠøя: %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1756"/>
+ <source>unknown option: %s</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1771"/>
+ <source>At least one machine must be specified with the export command.</source>
+ <translation>ŠšŠ°Šŗ Š¼ŠøŠ½ŠøŠ¼ŃƒŠ¼ Š¾Š“Š½Š° Š¼Š°ŃˆŠøŠ½Š° Š“Š¾Š»Š¶Š½Š° Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½Š° Š² ŠŗŠ¾Š¼Š°Š½Š“Šµ эŠŗсŠæŠ¾Ń€Ń‚Š°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1775"/>
+ <source>Missing --output argument with export command.</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ --output у ŠŗŠ¾Š¼Š°Š½Š“ы эŠŗсŠæŠ¾Ń€Ń‚Š°.</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="1789"/>
+ <source>Invalid index %RI32 with -vsys option; you specified only %zu virtual system(s).</source>
+ <translation>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠø -vsys option; Š²Ń‹ уŠŗŠ°Š·Š°Š»Šø тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½ŃƒŃŽ сŠøстŠµŠ¼Ńƒ.</numerusform>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠø -vsys option; Š²Ń‹ уŠŗŠ°Š·Š°Š»Šø тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Šµ сŠøстŠµŠ¼Ń‹.</numerusform>
+ <numerusform>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI32 у Š¾ŠæцŠøŠø -vsys option; Š²Ń‹ уŠŗŠ°Š·Š°Š»Šø тŠ¾Š»ŃŒŠŗŠ¾ %zu Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Ń… сŠøстŠµŠ¼.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1878"/>
+ <source>Cannot read license file &quot;%s&quot; which should be included in the virtual system %u.</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ фŠ°Š¹Š» Š»ŠøцŠµŠ½Š·ŠøŠø &quot;%s&quot;, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š² Š²ŠøртуŠ°Š»ŃŒŠ½ŃƒŃŽ сŠøстŠµŠ¼Ńƒ %u.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1941"/>
+ <source>Enter the passwords for the following identifiers to export the apppliance:
+</source>
+ <translation>Š’Š²ŠµŠ“ŠøтŠµ ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š»Ń сŠ»ŠµŠ“ующŠøх ŠøŠ“ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń‚Š¾Ń€Š¾Š², чтŠ¾Š±Ń‹ эŠŗсŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1948"/>
+ <source>Password ID %s:</source>
+ <translation>ID ŠæŠ°Ń€Š¾Š»Ń %s:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1978"/>
+ <source>Appliance write failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæŠøсŠ°Ń‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="1981"/>
+ <source>Successfully exported %d machine(s).
+</source>
+ <translation>
+ <numerusform>%d Š¼Š°ŃˆŠøŠ½Š° эŠŗсŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½Š° усŠæŠµŃˆŠ½Š¾.
+</numerusform>
+ <numerusform>%d Š¼Š°ŃˆŠøŠ½Ń‹ эŠŗсŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½Ń‹ усŠæŠµŃˆŠ½Š¾.
+</numerusform>
+ <numerusform>%d Š¼Š°ŃˆŠøŠ½ эŠŗсŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½Š¾ усŠæŠµŃˆŠ½Š¾.
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2037"/>
+ <source>Creating a cloud instance...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š°...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2042"/>
+ <source>Creating the cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2054"/>
+ <source>A cloud instance with id &apos;%s&apos; (provider &apos;%s&apos;) was created
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ с ID &apos;%s&apos; (ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€ &apos;%s&apos;) сŠ¾Š·Š“Š°Š½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2107"/>
+ <source>Failed to open OVA &apos;%s&apos; for updating: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Šŗрыть OVA &apos;%s&apos; Š“Š»Ń Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2113"/>
+ <source>Failed to open OVA &apos;%s&apos; as a TAR file: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Šŗрыть OVA &apos;%s&apos; ŠŗŠ°Šŗ фŠ°Š¹Š» TAR: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2120"/>
+ <source>Scanning OVA &apos;%s&apos; for a manifest and signature...</source>
+ <translation>Š”ŠŗŠ°Š½ŠøрŠ¾Š²Š°Š½ŠøŠµ OVA &apos;%s&apos; Š½Š° Š½Š°Š»ŠøчŠøŠµ Š¼Š°Š½ŠøфŠµŃŃ‚Š° Šø ŠæŠ¾Š“ŠæŠøсŠø...</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2136"/>
+ <source>RTVfsFsStrmNext returned %Rrc</source>
+ <translation>RTVfsFsStrmNext Š²Š¾Š·Š²Ń€Š°Ń‚ŠøŠ» %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2152"/>
+ <source>OVA contains multiple manifests! first: %s second: %s</source>
+ <translation>OVA сŠ¾Š“ŠµŃ€Š¶Šøт Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ Š¼Š°Š½ŠøфŠµŃŃ‚Š¾Š²! ŠæŠµŃ€Š²Ń‹Š¹: %s Š²Ń‚Š¾Ń€Š¾Š¹: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2156"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2194"/>
+ <source>Unsupported OVA file ordering! Signature file (&apos;%s&apos;) as succeeded by &apos;%s&apos;.</source>
+ <translation>ŠŠµŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Š¹ ŠæŠ¾Ń€ŃŠ“Š¾Šŗ фŠ°Š¹Š»Š¾Š² OVA! Š¤Š°Š¹Š» ŠæŠ¾Š“ŠæŠøсŠø (&apos;%s&apos;) ŠæŠ¾ŃŠ»Šµ &apos;%s&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2161"/>
+ <source>Found manifest file: %s</source>
+ <translation>ŠŠ°Š¹Š“ŠµŠ½ фŠ°Š¹Š» Š¼Š°Š½ŠøфŠµŃŃ‚Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2170"/>
+ <source>Failed to memorize the manifest: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæŠ¾Š¼Š½Šøть Š¼Š°Š½ŠøфŠµŃŃ‚: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2173"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2414"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2488"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2647"/>
+ <source>Out of memory!</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2181"/>
+ <source>Multiple signature files! (%s)</source>
+ <translation>ŠŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ фŠ°Š¹Š»Š¾Š² ŠæŠ¾Š“ŠæŠøсŠµŠ¹! (%s)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2185"/>
+ <source>Found existing signature file: %s</source>
+ <translation>ŠŠ°Š¹Š“ŠµŠ½ сущŠµŃŃ‚Š²ŃƒŃŽŃ‰ŠøŠ¹ фŠ°Š¹Š» сŠøŠ³Š½Š°Ń‚ŃƒŃ€Ń‹: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2210"/>
+ <source>The OVA contains no manifest and cannot be signed!</source>
+ <translation>OVA Š½Šµ сŠ¾Š“ŠµŃ€Š¶Šøт Š¼Š°Š½ŠøфŠµŃŃ‚Š° Šø Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠæŠ¾Š“ŠæŠøсŠ°Š½!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2213"/>
+ <source>The OVA is already signed (&apos;%s&apos;)! (Use the --force option to force re-signing it.)</source>
+ <translation>OVA уŠ¶Šµ ŠæŠ¾Š“ŠæŠøсŠ°Š½ (&apos;%s&apos;)! (Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ Š¾ŠæцŠøю --force, чтŠ¾Š±Ń‹ Š·Š°Š½Š¾Š²Š¾ ŠæŠ¾Š“ŠæŠøсŠ°Ń‚ŃŒ ŠµŠ³Š¾.)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2233"/>
+ <source>Writing &apos;%s&apos; to the OVA...</source>
+ <translation>Š—Š°ŠæŠøсь &apos;%s&apos; Š² OVA...</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2243"/>
+ <source>RTZipTarFsStreamTruncate failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTZipTarFsStreamTruncate Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2252"/>
+ <source>RTVfsFileSeek(hVfsFileSignature) failed: %Rrc</source>
+ <translation>RTVfsFileSeek(hVfsFileSignature) Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2258"/>
+ <source>RTVfsFsStrmAdd(&apos;%s&apos;) failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTVfsFsStrmAdd(&apos;%s&apos;) Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2265"/>
+ <source>RTVfsFsStrmEnd failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTVfsFsStrmEnd Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2301"/>
+ <source> Successfully decoded the PKCS#7/CMS signature...</source>
+ <translation> PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь Š“ŠµŠŗŠ¾Š“ŠøрŠ¾Š²Š°Š½Š° усŠæŠµŃˆŠ½Š¾...</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2317"/>
+ <source> Successfully verified the PKCS#7/CMS signature</source>
+ <translation> PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь ŠæрŠ¾Š²ŠµŃ€ŠµŠ½Š° усŠæŠµŃˆŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2320"/>
+ <source>Failed to verify the PKCS#7/CMS signature: %Rrc%RTeim</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Š²ŠµŃ€Šøть PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь: %Rrc%RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2324"/>
+ <source>RTCrPkcs7SignedData_CheckSanity failed on PKCS#7/CMS signature: %Rrc%RTeim</source>
+ <translation>RTCrPkcs7SignedData_CheckSanity Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š° с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсŠø: %Rrc%RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2329"/>
+ <source>PKCS#7/CMS signature inner ContentType isn&apos;t &apos;data&apos; but: %s</source>
+ <translation>Š’Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠµŠµ ŠæŠ¾Š»Šµ ContentType PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсŠø яŠ²Š»ŃŠµŃ‚ся Š½Šµ Š“Š°Š½Š½Ń‹Š¼Šø, Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2333"/>
+ <source>PKCS#7/CMD signature is not &apos;signedData&apos;: %s</source>
+ <translation>PKCS#7/CMD ŠæŠ¾Š“ŠæŠøсь Š½Šµ &apos;signedData&apos;: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2374"/>
+ <source>RTCrPkcs7ContentInfo_Clone failed: %Rrc</source>
+ <translation>RTCrPkcs7ContentInfo_Clone Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2378"/>
+ <source>RTCrPkcs7ContentInfo_DecodeAsn1 failed to decode PKCS#7/CMS signature: %Rrc%RTemi</source>
+ <translation>RTCrPkcs7ContentInfo_DecodeAsn1 Š½Šµ сŠ¼Š¾Š³ Š“ŠµŠŗŠ¾Š“ŠøрŠ¾Š²Š°Ń‚ŃŒ PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь: %Rrc%RTemi</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2409"/>
+ <source>Manifest is too big: %#RX64 bytes, max 4MiB</source>
+ <translation>
+ <numerusform>ŠœŠ°Š½ŠøфŠµŃŃ‚ сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Š¹: %#RX64 Š±Š°Š¹Ń‚, Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ 4MiB</numerusform>
+ <numerusform>ŠœŠ°Š½ŠøфŠµŃŃ‚ сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Š¹: %#RX64 Š±Š°Š¹Ń‚Š°, Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ 4MiB</numerusform>
+ <numerusform>ŠœŠ°Š½ŠøфŠµŃŃ‚ сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Š¹: %#RX64 Š±Š°Š¹Ń‚, Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ 4MiB</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2434"/>
+ <source>RTCrStoreCertAddFromFile failed on &apos;%s&apos;: %Rrc%#RTeim</source>
+ <translation>RTCrStoreCertAddFromFile Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2440"/>
+ <source>RTCrStoreCreateInMem failed: %Rrc</source>
+ <translation>RTCrStoreCreateInMem Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2471"/>
+ <source>Created PKCS#7/CMS signature: %zu bytes, %s.</source>
+ <translation>
+ <numerusform>PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚, %s.</numerusform>
+ <numerusform>PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚Š°, %s.</numerusform>
+ <numerusform>PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсь сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚, %s.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2474"/>
+ <source>Using SHA-1 instead of SHA-3 for the PKCS#7/CMS signature.</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся SHA-1 Š²Š¼ŠµŃŃ‚Š¾ SHA-3 Š“Š»Ń PKCS#7/CMS ŠæŠ¾Š“ŠæŠøсŠø.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2483"/>
+ <source>RTCrPemWriteBlobToVfsFile failed: %Rrc</source>
+ <translation>RTCrPemWriteBlobToVfsFile Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2491"/>
+ <source>RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim</source>
+ <translation>RTCrPkcs7SimpleSignSignedData Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2495"/>
+ <source>RTVfsFileReadAt failed: %Rrc</source>
+ <translation>RTVfsFileReadAt Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2548"/>
+ <source>Unsupported digest type: %s</source>
+ <translation>ŠŠµŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Š¹ тŠøŠæ Š“Š°Š¹Š“Š¶ŠµŃŃ‚Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2557"/>
+ <source>Failed to create digest for %s: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š“Š°Š¹Š“Š¶ŠµŃŃ‚ Š“Š»Ń %s: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2583"/>
+ <source>Created OVA signature: %zu bytes, %s</source>
+ <translation>
+ <numerusform>ŠŸŠ¾Š“ŠæŠøсь OVA сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚, %s</numerusform>
+ <numerusform>ŠŸŠ¾Š“ŠæŠøсь OVA сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚Š°, %s</numerusform>
+ <numerusform>ŠŸŠ¾Š“ŠæŠøсь OVA сŠ¾Š·Š“Š°Š½Š°: %zu Š±Š°Š¹Ń‚, %s</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2596"/>
+ <source> Successfully decoded and verified the OVA signature.
+</source>
+ <translation> Š”ŠøŠ³Š½Š°Ń‚ŃƒŃ€Š° OVA Š“ŠµŠŗŠ¾Š“ŠøрŠ¾Š²Š°Š½Š° Šø ŠæрŠ¾Š²ŠµŃ€ŠµŠ½Š° усŠæŠµŃˆŠ½Š¾.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2627"/>
+ <source>Failed to write certificate to signature file: %Rrc%#RTeim</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæŠøсŠ°Ń‚ŃŒ сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚ Š² фŠ°Š¹Š» ŠæŠ¾Š“ŠæŠøсŠø: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2631"/>
+ <source>Failed to produce signature file: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ“ŠµŠ»Š°Ń‚ŃŒ фŠ°Š¹Š» сŠøŠ³Š½Š°Ń‚ŃƒŃ€Ń‹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2635"/>
+ <source>RTVfsMemFileCreate failed: %Rrc</source>
+ <translation>RTVfsMemFileCreate Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2638"/>
+ <source>Encountered a problem when validating the signature we just created: %Rrc%#RTeim
+Please make sure the certificate and private key matches.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Encountered a problem when validating the signature we just created: %Rrc%#RTeim
+Plase make sure the certificate and private key matches.</source>
+ <translation type="vanished">Š”тŠ¾Š»ŠŗŠ½ŃƒŠ»Šøсь с ŠæрŠ¾Š±Š»ŠµŠ¼Š¾Š¹ ŠæрŠø ŠæрŠ¾Š²ŠµŃ€ŠŗŠµ тŠ¾Š»ŃŒŠŗŠ¾ чтŠ¾ сŠ¾Š·Š“Š°Š½Š½Š¾Š¹ ŠæŠ¾Š“ŠæŠøсŠø: %Rrc%#RTeim
+ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, уŠ±ŠµŠ“ŠøтŠµŃŃŒ, чтŠ¾ сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚ Šø ŠæрŠøŠ²Š°Ń‚Š½Ń‹Š¹ ŠŗŠ»ŃŽŃ‡ сŠ¾Š¾Ń‚Š²ŠµŃ‚стŠ²ŃƒŃŽŃ‚ Š“руŠ³ Š“руŠ³Ńƒ.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2643"/>
+ <source>2nd RTCrPkixPubKeySignDigest call failed: %Rrc%#RTeim</source>
+ <translation>Š’Ń‚Š¾Ń€Š¾Š¹ Š²Ń‹Š·Š¾Š² RTCrPkixPubKeySignDigest Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2650"/>
+ <source>RTCrPkixPubKeySignDigest failed: %Rrc%#RTeim</source>
+ <translation>RTCrPkixPubKeySignDigest Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2653"/>
+ <source>Failed to create digest %s: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š“Š°Š¹Š“Š¶ŠµŃŃ‚ %s: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2717"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2724"/>
+ <source>Password is given more than once.</source>
+ <translation>ŠŸŠ°Ń€Š¾Š»ŃŒ уŠŗŠ°Š·Š°Š½ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2742"/>
+ <source>Unknown digest type: %s</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Ń‹Š¹ тŠøŠæ Š“Š°Š¹Š“Š¶ŠµŃŃ‚Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2755"/>
+ <source>Too many intermediate certificates: max %zu</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠæрŠ¾Š¼ŠµŠ¶ŃƒŃ‚Š¾Ń‡Š½Ń‹Ń… сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚Š¾Š²: Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ %zu</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2791"/>
+ <source>No OVA file was specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ фŠ°Š¹Š» OVA!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2793"/>
+ <source>No signing certificate (--certificate=&lt;file&gt;) was specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚ (--certificate=&lt;фŠ°Š¹Š»&gt;)!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2795"/>
+ <source>No signing private key (--private-key=&lt;file&gt;) was specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ŠæрŠøŠ²Š°Ń‚Š½Ń‹Š¹ ŠŗŠ»ŃŽŃ‡ (--private-key=&lt;фŠ°Š¹Š»&gt;)!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2799"/>
+ <source>The specified OVA file was not found: %s</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½ уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ фŠ°Š¹Š» OVA: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2801"/>
+ <source>The specified certificate file was not found: %s</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ фŠ°Š¹Š» сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2803"/>
+ <source>The specified private key file was not found: %s</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ фŠ°Š¹Š» ŠæрŠøŠ²Š°Ń‚Š½Š¾Š³Š¾ ŠŗŠ»ŃŽŃ‡Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2824"/>
+ <source>Error reading certificate from &apos;%s&apos;: %Rrc%#RTeim</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° чтŠµŠ½Šøя сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚Š° ŠøŠ· &apos;%s&apos;: %Rrc%#RTeim</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2833"/>
+ <source>Successfully read the certificate and private key.</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ ŠæрŠ¾Ń‡Ń‚ŠµŠ½Ń‹ сŠµŃ€Ń‚ŠøфŠøŠŗŠ°Ń‚ Šø ŠæрŠøŠ²Š°Ń‚Š½Ń‹Š¹ ŠŗŠ»ŃŽŃ‡.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2859"/>
+ <source>Successfully signed &apos;%s&apos;.</source>
+ <translation>&apos;%s&apos; ŠæŠ¾Š“ŠæŠøсŠ°Š½ усŠæŠµŃˆŠ½Š¾.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2865"/>
+ <source>Error reading the private key from %s: %Rrc%#RTeim</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° чтŠµŠ½Šøя ŠæрŠøŠ²Š°Ń‚Š½Š¾Š³Š¾ ŠŗŠ»ŃŽŃ‡Š° ŠøŠ· %s: %Rrc%#RTeim</translation>
+ </message>
+</context>
+<context>
+ <name>BWControl</name>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="65"/>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="88"/>
+ <source>Limit is too big
+</source>
+ <translation>Š›ŠøŠ¼Šøт сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Š¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="75"/>
+ <source>Invalid unit suffix. Valid suffixes are: k, m, g, K, M, G
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ суффŠøŠŗс ŠµŠ“ŠøŠ½Šøцы ŠøŠ·Š¼ŠµŃ€ŠµŠ½Šøя. Š”Š¾ŠæустŠøŠ¼Ń‹Šµ суффŠøŠŗсы: k, m, g, K, M, G
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="79"/>
+ <source>Trailing spaces in limit!
+</source>
+ <translation>Š£ Š»ŠøŠ¼ŠøтŠ° ŠæрŠ¾Š±ŠµŠ»Ń‹ Š² ŠŗŠ¾Š½Ń†Šµ стрŠ¾ŠŗŠø!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="81"/>
+ <source>No digits in limit specifier
+</source>
+ <translation>ŠŠµŃ‚ цŠøфр Š² сŠæŠµŃ†ŠøфŠøŠŗŠ°Ń‚Š¾Ń€Šµ Š»ŠøŠ¼ŠøтŠ°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="83"/>
+ <source>Invalid limit specifier
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ сŠæŠµŃ†ŠøфŠøŠŗŠ°Ń‚Š¾Ń€ Š»ŠøŠ¼ŠøтŠ°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="86"/>
+ <source>Limit cannot be negative
+</source>
+ <translation>Š›ŠøŠ¼Šøт Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ Š¾Ń‚Ń€ŠøцŠ°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¼
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="114"/>
+ <source>Bandwidth group name must not be empty!
+</source>
+ <translation>Š˜Š¼Ń Š³Ń€ŃƒŠæŠæы ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠæустыŠ¼!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="174"/>
+ <source>Invalid bandwidth group type
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ Š³Ń€ŃƒŠæŠæы ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="318"/>
+ <source>Too few parameters</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š°Š»Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="320"/>
+ <source>Too many parameters</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="341"/>
+ <source>Bandwidth groups cannot be created while the VM is running
+</source>
+ <translation>ŠŠµŠ»ŃŒŠ·Ń сŠ¾Š·Š“Š°Š²Š°Ń‚ŃŒ Š³Ń€ŃƒŠæŠæы ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя ŠæŠ¾ŠŗŠ° рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ Š’Šœ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="350"/>
+ <source>Bandwidth groups cannot be deleted while the VM is running
+</source>
+ <translation>ŠŠµŠ»ŃŒŠ·Ń уŠ“Š°Š»ŃŃ‚ŃŒ Š³Ń€ŃƒŠæŠæы ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя ŠæŠ¾ŠŗŠ° рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ Š’Šœ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="361"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>Cloud</name>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="74"/>
+ <source>Parameter --provider is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --provider</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="79"/>
+ <source>Parameter --profile is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --profile</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="164"/>
+ <source>Unknown cloud instance state &quot;%s&quot;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾Šµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="210"/>
+ <location filename="../VBoxManageCloud.cpp" line="371"/>
+ <source>Parameter &apos;compartment&apos; is empty or absent.
+Trying to get the compartment from the passed cloud profile &apos;%s&apos;
+</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;compartment&apos; ŠæустŠ¾Š¹ ŠøŠ»Šø Š¾Ń‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚.
+ŠŸŠ¾ŠæытŠŗŠ° ŠæŠ¾Š»ŃƒŃ‡Šøть сŠµŠŗцŠøю ŠøŠ· ŠæŠµŃ€ŠµŠ“Š°Š½Š½Š¾Š³Š¾ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="219"/>
+ <location filename="../VBoxManageCloud.cpp" line="380"/>
+ <source>Found the compartment &apos;%s&apos;:
+</source>
+ <translation>ŠŠ°Š¹Š“ŠµŠ½Š° сŠµŠŗцŠøя &apos;%s&apos;:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="221"/>
+ <location filename="../VBoxManageCloud.cpp" line="382"/>
+ <source>Parameter --compartment-id is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --compartment-id</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="238"/>
+ <source>Reply is in the form &apos;instance name&apos; = &apos;instance id&apos;
+</source>
+ <translation>ŠžŃ‚Š²ŠµŃ‚ Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;ŠøŠ¼Ń эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š°&apos; = &apos;ID эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š°&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="247"/>
+ <source>Failed to list instances</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŃ‡ŠøсŠ»Šøть эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="256"/>
+ <source>The list of the instances for the cloud profile &apos;%ls&apos;
+and compartment &apos;%s&apos;:
+</source>
+ <translation>Š”ŠæŠøсŠ¾Šŗ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š¾Š² Š“Š»Ń Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń &apos;%ls&apos;
+Šø сŠµŠŗцŠøŠø &apos;%s&apos;:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="324"/>
+ <source>Unknown cloud image state &quot;%s&quot;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾Šµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="399"/>
+ <source>Reply is in the form &apos;image name&apos; = &apos;image id&apos;
+</source>
+ <translation>ŠžŃ‚Š²ŠµŃ‚ Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;ŠøŠ¼Ń Š¾Š±Ń€Š°Š·Š°&apos; = &apos;ID Š¾Š±Ń€Š°Š·Š°&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="407"/>
+ <source>Failed to list images</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŃ‡ŠøсŠ»Šøть Š¾Š±Ń€Š°Š·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="416"/>
+ <source>The list of the images for the cloud profile &apos;%ls&apos;
+and compartment &apos;%s&apos;:
+</source>
+ <translation>Š”ŠæŠøсŠ¾Šŗ Š¾Š±Ń€Š°Š·Š¾Š² Š“Š»Ń Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń &apos;%ls&apos;
+Šø сŠµŠŗцŠøŠø &apos;%s&apos;:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="473"/>
+ <location filename="../VBoxManageCloud.cpp" line="553"/>
+ <location filename="../VBoxManageCloud.cpp" line="747"/>
+ <location filename="../VBoxManageCloud.cpp" line="898"/>
+ <location filename="../VBoxManageCloud.cpp" line="980"/>
+ <location filename="../VBoxManageCloud.cpp" line="1062"/>
+ <location filename="../VBoxManageCloud.cpp" line="1159"/>
+ <location filename="../VBoxManageCloud.cpp" line="1236"/>
+ <location filename="../VBoxManageCloud.cpp" line="1342"/>
+ <location filename="../VBoxManageCloud.cpp" line="1537"/>
+ <location filename="../VBoxManageCloud.cpp" line="1622"/>
+ <location filename="../VBoxManageCloud.cpp" line="1713"/>
+ <location filename="../VBoxManageCloud.cpp" line="1808"/>
+ <source>Empty command parameter list, show help.
+</source>
+ <translation>Š”ŠæŠøсŠ¾Šŗ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š² ŠŗŠ¾Š¼Š°Š½Š“ы Šæуст, Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ сŠæрŠ°Š²ŠŗŠø.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="663"/>
+ <source>Warning!!! Public SSH key doesn&apos;t present in the passed arguments...
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ!!! ŠŸŃƒŠ±Š»ŠøчŠ½Ń‹Š¹ SSH ŠŗŠ»ŃŽŃ‡ Š½Šµ ŠæрŠµŠ“стŠ°Š²Š»ŠµŠ½ Š² ŠæŠµŃ€ŠµŠ“Š°Š½Š½Ń‹Ń… Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š°Ń…...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="666"/>
+ <source>Parameters --image-id and --boot-volume-id are mutually exclusive. Only one of them must be presented.</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚ры --image-id Šø --boot-volume-id Š²Š·Š°ŠøŠ¼Š¾ŠøсŠŗŠ»ŃŽŃ‡Š°ŃŽŃ‰ŠøŠµ. ŠœŠ¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ ŠøŠ· Š½Šøх.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="670"/>
+ <source>Missing parameter --image-id or --boot-volume-id. One of them must be presented.</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŃŽŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры --image-id Šø --boot-volume-id. ŠžŠ“ŠøŠ½ ŠøŠ· Š½Šøх Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="692"/>
+ <source>Checking the cloud image with id &apos;%s&apos;...
+</source>
+ <translation>ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° с ID &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="700"/>
+ <source>Checking the cloud image failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Š²ŠµŃ€Šøть Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="706"/>
+ <source>Creating cloud instance with name &apos;%s&apos; from the image &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos; ŠøŠ· Š¾Š±Ń€Š°Š·Š° &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="709"/>
+ <source>Creating cloud instance with name &apos;%s&apos; from the boot volume &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos; ŠøŠ· Š·Š°Š³Ń€Š°Š·ŃƒŠ·Š¾Ń‡Š½Š¾Š³Š¾ тŠ¾Š¼Š° &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="715"/>
+ <source>Creating cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="718"/>
+ <source>Cloud instance was created successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ сŠ¾Š·Š“Š°Š½ усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="762"/>
+ <location filename="../VBoxManageCloud.cpp" line="913"/>
+ <location filename="../VBoxManageCloud.cpp" line="995"/>
+ <location filename="../VBoxManageCloud.cpp" line="1077"/>
+ <location filename="../VBoxManageCloud.cpp" line="1386"/>
+ <location filename="../VBoxManageCloud.cpp" line="1728"/>
+ <source>Duplicate parameter: --id</source>
+ <translation>Š”ŃƒŠ±Š»ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --id</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="766"/>
+ <location filename="../VBoxManageCloud.cpp" line="917"/>
+ <location filename="../VBoxManageCloud.cpp" line="999"/>
+ <location filename="../VBoxManageCloud.cpp" line="1081"/>
+ <location filename="../VBoxManageCloud.cpp" line="1390"/>
+ <location filename="../VBoxManageCloud.cpp" line="1732"/>
+ <source>Empty parameter: --id</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --id</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="787"/>
+ <location filename="../VBoxManageCloud.cpp" line="938"/>
+ <location filename="../VBoxManageCloud.cpp" line="1020"/>
+ <location filename="../VBoxManageCloud.cpp" line="1102"/>
+ <location filename="../VBoxManageCloud.cpp" line="1439"/>
+ <location filename="../VBoxManageCloud.cpp" line="1754"/>
+ <source>Missing parameter: --id</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --id</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="795"/>
+ <source>Getting information about cloud instance with id %s...
+</source>
+ <translation>ŠŸŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŠµ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŠø Š¾Š± Š¾Š±Š»Š°Ń‡Š½Š¾Š¼ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Šµ с ID %s...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="796"/>
+ <source>Reply is in the form &apos;setting name&apos; = &apos;value&apos;
+</source>
+ <translation>ŠžŃ‚Š²ŠµŃ‚ Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;Š½Š°Š·Š²Š°Š½ŠøŠµ Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠø&apos; = &apos;Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="817"/>
+ <source>Getting information about cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š¾Š± Š¾Š±Š»Š°Ń‡Š½Š¾Š¼ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="819"/>
+ <source>Cloud instance info (provider &apos;%s&apos;):
+</source>
+ <translation>Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾Š± Š¾Š±Š»Š°Ń‡Š½Š¾Š¼ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Šµ (ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€ &apos;%s&apos;):
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="830"/>
+ <source>Availability domain = %ls
+</source>
+ <translation>Š”Š¾Š¼ŠµŠ½ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚Šø = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="830"/>
+ <source>Availability domain wasn&apos;t found
+</source>
+ <translation>Š”Š¾Š¼ŠµŠ½ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚Šø Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="831"/>
+ <source>Instance displayed name = %ls
+</source>
+ <translation>ŠžŃ‚Š¾Š±Ń€Š°Š¶Š°ŠµŠ¼Š¾Šµ ŠøŠ¼Ń эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="831"/>
+ <source>Instance displayed name wasn&apos;t found
+</source>
+ <translation>ŠžŃ‚Š¾Š±Ń€Š°Š¶Š°ŠµŠ¼Š¾Šµ ŠøŠ¼Ń эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="832"/>
+ <source>Instance state = %ls
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="832"/>
+ <source>Instance state wasn&apos;t found
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="833"/>
+ <source>Instance Id = %ls
+</source>
+ <translation>ID эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="833"/>
+ <source>Instance Id wasn&apos;t found
+</source>
+ <translation>ID эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="834"/>
+ <source>Instance name = %ls
+</source>
+ <translation>Š˜Š¼Ń эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="834"/>
+ <source>Instance name wasn&apos;t found
+</source>
+ <translation>Š˜Š¼Ń эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="835"/>
+ <source>Bootable image Id = %ls
+</source>
+ <translation>ID Š·Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="836"/>
+ <source>Image Id whom the instance is booted up wasn&apos;t found
+</source>
+ <translation>ID Š¾Š±Ń€Š°Š·Š°, Š¾Ń‚ŠŗуŠ“Š° Š·Š°Š³Ń€ŃƒŠ¶Š°ŠµŃ‚ся эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€,Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="837"/>
+ <source>Shape of the instance = %ls
+</source>
+ <translation>Š¤Š¾Ń€Š¼Š° эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="838"/>
+ <source>The shape of the instance wasn&apos;t found
+</source>
+ <translation>Š¤Š¾Ń€Š¼Š° эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="839"/>
+ <source>Type of guest OS = %ls
+</source>
+ <translation>Š¢ŠøŠæ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="839"/>
+ <source>Type of guest OS wasn&apos;t found
+</source>
+ <translation>Š¢ŠøŠæ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="840"/>
+ <source>RAM = %ls MB
+</source>
+ <translation>RAM = %ls MB
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="840"/>
+ <source>Value for RAM wasn&apos;t found
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ RAM Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="841"/>
+ <source>CPUs = %ls
+</source>
+ <translation>Š¦ŠŸŠ£ = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="841"/>
+ <source>Numbers of CPUs weren&apos;t found
+</source>
+ <translation>ŠšŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š¦ŠŸŠ£ Š½Šµ Š½Š°Š¹Š“ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="842"/>
+ <source>Instance public IP = %ls
+</source>
+ <translation>ŠŸŃƒŠ±Š»ŠøчŠ½Ń‹Š¹ IP эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="842"/>
+ <source>Public IP wasn&apos;t found
+</source>
+ <translation>ŠŸŃƒŠ±Š»ŠøчŠ½Ń‹Š¹ IP Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="843"/>
+ <source>Free-form tags or metadata weren&apos;t found
+</source>
+ <translation>Š¢ŠµŠ³Šø ŠøŠ»Šø Š¼ŠµŃ‚Š°Š“Š°Š½Š½Ń‹Šµ ŠæрŠ¾ŠøŠ·Š²Š¾Š»ŃŒŠ½Š¾Š¹ фŠ¾Ń€Š¼Ń‹ Š½Šµ Š½Š°Š¹Š“ŠµŠ½Ń‹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="844"/>
+ <source>Cloud-init script wasn&apos;t found
+</source>
+ <translation>Š”ŠŗрŠøŠæт ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†ŠøŠø Š¾Š±Š»Š°ŠŗŠ° Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="946"/>
+ <source>Starting cloud instance with id %s...
+</source>
+ <translation>Š—Š°ŠæусŠŗ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° с ID %s...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="953"/>
+ <source>Starting the cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæустŠøть Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="956"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was started
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ с ID %s (ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€ = &apos;%s&apos;, ŠæрŠ¾Ń„ŠøŠ»ŃŒ = &apos;%s&apos;) Š·Š°ŠæущŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1028"/>
+ <source>Pausing cloud instance with id %s...
+</source>
+ <translation>ŠŸŃ€ŠøŠ¾ŃŃ‚Š°Š½Š¾Š²ŠŗŠ° Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° с ID %s...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1035"/>
+ <source>Pause the cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Šøть Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1038"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was paused
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ с ID %s (ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€ = &apos;%s&apos;, ŠæрŠ¾Ń„ŠøŠ»ŃŒ = &apos;%s&apos;) ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1111"/>
+ <source>Terminating cloud instance with id %s...
+</source>
+ <translation>Š—Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ рŠ°Š±Š¾Ń‚Ń‹ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° с ID %s...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1118"/>
+ <source>Termination the cloud instance failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š²ŠµŃ€ŃˆŠøть рŠ°Š±Š¾Ń‚Ńƒ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1121"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was terminated
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ с ID %s (ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€ = &apos;%s&apos;, ŠæрŠ¾Ń„ŠøŠ»ŃŒ = &apos;%s&apos;) Š·Š°Š²ŠµŃ€ŃˆŠøŠ» рŠ°Š±Š¾Ń‚Ńƒ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1293"/>
+ <source>Conflicting parameters: --instance-id and --object-name can&apos;t be used together. Choose one.</source>
+ <translation>ŠšŠ¾Š½Ń„Š»ŠøŠŗтующŠøŠµ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры: --instance-id Šø --object-name Š½Šµ Š¼Š¾Š³ŃƒŃ‚ Š±Ń‹Ń‚ŃŒ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Ń‹ Š²Š¼ŠµŃŃ‚Šµ. Š’Ń‹Š±ŠµŃ€ŠøтŠµ Š¾Š“ŠøŠ½.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1302"/>
+ <source>Creating cloud image with name &apos;%s&apos; from the instance &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos; ŠøŠ· эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1305"/>
+ <source>Creating cloud image with name &apos;%s&apos; from the object &apos;%s&apos; in the bucket &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos; ŠøŠ· Š¾Š±ŃŠŠµŠŗтŠ° &apos;%s&apos; Š² ŠŗŠ¾Ń€Š·ŠøŠ½Šµ &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1313"/>
+ <source>Creating cloud image failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1316"/>
+ <source>Cloud image was created successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š· сŠ¾Š·Š“Š°Š½ усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1362"/>
+ <source>Duplicate parameter: --bucket-name</source>
+ <translation>Š”ŃƒŠ±Š»ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --bucket-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1366"/>
+ <source>Empty parameter: --bucket-name</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --bucket-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1374"/>
+ <source>Duplicate parameter: --object-name</source>
+ <translation>Š”ŃƒŠ±Š»ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --object-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1378"/>
+ <source>Empty parameter: --object-name</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --object-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1398"/>
+ <source>Duplicate parameter: --display-name</source>
+ <translation>Š”ŃƒŠ±Š»ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --display-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1402"/>
+ <source>Empty parameter: --display-name</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --display-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1410"/>
+ <source>Duplicate parameter: --launch-mode</source>
+ <translation>Š”ŃƒŠ±Š»ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --launch-mode</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1414"/>
+ <source>Empty parameter: --launch-mode</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --launch-mode</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1444"/>
+ <source>Missing parameter: --bucket-name</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: --bucket-name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1464"/>
+ <source>Exporting image &apos;%s&apos; to the Cloud with name &apos;%s&apos;...
+</source>
+ <translation>Š­ŠŗсŠæŠ¾Ń€Ń‚ Š¾Š±Ń€Š°Š·Š° &apos;%s&apos; Š² Š¾Š±Š»Š°ŠŗŠ¾ с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1467"/>
+ <source>Exporting image &apos;%s&apos; to the Cloud with default name
+</source>
+ <translation>Š­ŠŗсŠæŠ¾Ń€Ń‚ Š¾Š±Ń€Š°Š·Š° &apos;%s&apos; Š² Š¾Š±Š»Š°ŠŗŠ¾ с ŠøŠ¼ŠµŠ½ŠµŠ¼ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1495"/>
+ <source>Image %s was found
+</source>
+ <translation>ŠžŠ±Ń€Š°Š· %s Š½Šµ Š½Š°Š¹Š“ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1502"/>
+ <source>Process of exporting the image to the Cloud was interrupted. The image wasn&apos;t found.
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ эŠŗсŠæŠ¾Ń€Ń‚Š° Š¾Š±Ń€Š°Š·Š° Š² Š¾Š±Š»Š°ŠŗŠ¾ ŠæрŠµŃ€Š²Š°Š½. ŠžŠ±Ń€Š°Š· Š½Šµ Š½Š°Š¹Š“ŠµŠ½.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1511"/>
+ <source>Export the image to the Cloud failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ эŠŗсŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Ń‚ŃŒ Š¾Š±Ń€Š°Š· Š² Š¾Š±Š»Š°ŠŗŠ¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1514"/>
+ <source>Export the image to the Cloud was successfull
+</source>
+ <translation>Š­ŠŗсŠæŠ¾Ń€Ń‚ Š¾Š±Ń€Š°Š·Š° Š² Š¾Š±Š»Š°ŠŗŠ¾ Š·Š°ŠŗŠ¾Š½Ń‡ŠøŠ»ŃŃ усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1587"/>
+ <source>Creating an object &apos;%s&apos; from the cloud image &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±ŃŠŠµŠŗтŠ° &apos;%s&apos; ŠøŠ· Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1594"/>
+ <source>Cloud image import failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠøŠ¼ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Ń‚ŃŒ Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1598"/>
+ <source>Cloud image was imported successfully. Find the downloaded object with the name %s in the system temp folder (find the possible environment variables like TEMP, TMP and etc.)
+</source>
+ <translation>Š˜Š¼ŠæŠ¾Ń€Ń‚ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ усŠæŠµŃˆŠ½Š¾. ŠŠ°Š¹Š“ŠøтŠµ Š·Š°Š³Ń€ŃƒŠ¶ŠµŠ½Š½Ń‹Š¹ Š¾Š±ŃŠŠµŠŗт с ŠøŠ¼ŠµŠ½ŠµŠ¼ %s Š² сŠøстŠµŠ¼Š½Š¾Š¹ ŠæŠ°ŠæŠŗŠµ Š“Š»Ń Š²Ń€ŠµŠ¼ŠµŠ½Š½Ń‹Ń… фŠ°Š¹Š»Š¾Š² (ŠæŠ¾ŠøщŠøтŠµ Š²Š¾Š·Š¼Š¾Š¶Š½Ń‹Šµ ŠæŠµŃ€ŠµŠ¼ŠµŠ½Š½Ń‹Šµ Š¾ŠŗруŠ¶ŠµŠ½Šøя Š½Š°ŠæŠ¾Š“Š¾Š±ŠøŠµ TEMP, TMP Šø тŠ°Šŗ Š“Š°Š»ŠµŠµ.)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1658"/>
+ <source>Getting information about the cloud image with id &apos;%s&apos;...
+</source>
+ <translation>ŠŸŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŠµ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŠø Š¾Š± Š¾Š±Š»Š°Ń‡Š½Š¾Š¼ Š¾Š±Ń€Š°Š·Šµ с ID &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1664"/>
+ <source>Reply is in the form &apos;image property&apos; = &apos;value&apos;
+</source>
+ <translation>ŠžŃ‚Š²ŠµŃ‚ Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;сŠ²Š¾Š¹ŃŃ‚Š²Š¾ Š¾Š±Ń€Š°Š·Š°&apos; = &apos;Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1672"/>
+ <source>Getting information about the cloud image failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š¾Š± Š¾Š±Š»Š°Ń‡Š½Š¾Š¼ Š¾Š±Ń€Š°Š·Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1678"/>
+ <source>General information about the image:
+</source>
+ <translation>ŠžŠ±Ń‰Š°Ń ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾Š± Š¾Š±Ń€Š°Š·Šµ:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1763"/>
+ <source>Deleting cloud image with id %s...
+</source>
+ <translation>Š£Š“Š°Š»ŠµŠ½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š³Š¾ Š¾Š±Ń€Š°Š·Š° с ID %s...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1770"/>
+ <source>Deleting cloud image failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1773"/>
+ <source>Cloud image was deleted successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ Š¾Š±Ń€Š°Š· уŠ“Š°Š»ŠµŠ½ усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1956"/>
+ <location filename="../VBoxManageCloud.cpp" line="2007"/>
+ <location filename="../VBoxManageCloud.cpp" line="2081"/>
+ <location filename="../VBoxManageCloud.cpp" line="2128"/>
+ <source>Missing --name parameter</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1958"/>
+ <source>Missing --network-id parameter</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --network-id</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1970"/>
+ <source>Cloud network was created successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Š°Ń сŠµŃ‚ŃŒ сŠ¾Š·Š“Š°Š½Š° усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2015"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>State: %s
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>Enabled</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>Disabled</source>
+ <translation>ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2021"/>
+ <source>CloudProvider: %ls
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2024"/>
+ <source>CloudProfile: %ls
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ ŠæрŠ¾Ń„ŠøŠ»ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2027"/>
+ <source>CloudNetworkId: %ls
+</source>
+ <translation>ID Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ сŠµŃ‚Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2029"/>
+ <source>VBoxNetworkName: %ls
+
+</source>
+ <translation>Š˜Š¼Ń сŠµŃ‚Šø VBox: %ls
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2091"/>
+ <source>Cloud network %ls was updated successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Š°Ń сŠµŃ‚ŃŒ %ls Š¾Š±Š½Š¾Š²Š»ŠµŠ½Š° усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2141"/>
+ <source>Cloud network %ls was deleted successfully
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Š°Ń сŠµŃ‚ŃŒ %ls уŠ“Š°Š»ŠµŠ½Š° усŠæŠµŃˆŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <source>Failed to compose path to the unattended installer script templates (%Rrc)</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š±Ń€Š°Ń‚ŃŒ Šæуть Š“Š»Ń шŠ°Š±Š»Š¾Š½Š¾Š² сŠŗрŠøŠæтŠ¾Š² unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š° (%Rrc)</translation>
+ </message>
+ <message>
+ <source>Failed to obtain system properties.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть сŠ²Š¾Š¹ŃŃ‚Š²Š° сŠøстŠµŠ¼Ń‹.</translation>
+ </message>
+ <message>
+ <source>Failed to obtain proxy mode.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠµŠ¶ŠøŠ¼ ŠæрŠ¾ŠŗсŠø.</translation>
+ </message>
+ <message>
+ <source>Failed to obtain proxy URL.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть URL ŠæрŠ¾ŠŗсŠø.</translation>
+ </message>
+ <message>
+ <source>Failed to get system proxy for https://dl.fedoraproject.org. Will use direct connection.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть сŠøстŠµŠ¼Š½Ń‹Š¹ ŠæрŠ¾ŠŗсŠø Š“Š»Ń https://dl.fedoraproject.org. Š‘ŃƒŠ“ŠµŃ‚ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Š¾ ŠæряŠ¼Š¾Šµ сŠ¾ŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ.</translation>
+ </message>
+ <message>
+ <source>Failed to obtain default machine folder.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠæŠ°ŠæŠŗу Š¼Š°ŃˆŠøŠ½Ń‹ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю.</translation>
+ </message>
+ <message>
+ <source>Failed to obtain default guest additions ISO path.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть Šæуть ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю Šŗ ISO Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”.</translation>
+ </message>
+ <message>
+ <source>The default guest additions ISO path is empty nor it is provided as --guest-additions-iso parameter. Cannot proceed without it.</source>
+ <translation type="vanished">ŠŸŃƒŃ‚ŃŒ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю Šŗ ISO Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Šæуст ŠøŠ»Šø Š½Šµ уŠŗŠ°Š·Š°Š½ чŠµŃ€ŠµŠ· --guest-additions-iso parameter. ŠŸŃ€Š¾Š“Š¾Š»Š¶ŠµŠ½ŠøŠµ Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š±ŠµŠ· этŠ¾Š³Š¾.</translation>
+ </message>
+ <message>
+ <source>Failed to compose a path to the local gateway image (%Rrc)</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š±Ń€Š°Ń‚ŃŒ Šæуть Šŗ Š¾Š±Ń€Š°Š·Ńƒ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š° (%Rrc)</translation>
+ </message>
+ <message>
+ <source>Local gateway image already exists, skipping image preparation step.
+</source>
+ <translation type="vanished">ŠžŠ±Ń€Š°Š· Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š° уŠ¶Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚, ŠæрŠ¾ŠæусŠŗ шŠ°Š³Š° ŠæŠ¾Š“Š³Š¾Ń‚Š¾Š²ŠŗŠø Š¾Š±Ń€Š°Š·Š°.
+</translation>
+ </message>
+ <message>
+ <source>Preparing unattended install of temporary local gateway machine from %ls...
+</source>
+ <translation type="vanished">ŠŸŠ¾Š“Š³Š¾Ń‚Š¾Š²ŠŗŠ° unattended устŠ°Š½Š¾Š²ŠŗŠø Š¼Š°ŃˆŠøŠ½Ń‹ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š³Š¾ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š° ŠøŠ· %ls...
+</translation>
+ </message>
+ <message>
+ <source>Failed to open %ls.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Šŗрыть %ls.</translation>
+ </message>
+ <message>
+ <source>Failed to create &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to apply defaults to &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠøŠ¼ŠµŠ½Šøть Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠø ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю Šŗ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to adjust CPU count for &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š“стрŠ¾Šøть ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š¦ŠŸŠ£ Š“Š»Ń &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to adjust memory size for &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š“стрŠ¾Šøть рŠ°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to set attachment type for the second network adapter.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ устŠ°Š½Š¾Š²Šøть тŠøŠæ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя Š“Š»Ń Š²Ń‚Š¾Ń€Š¾Š³Š¾ сŠµŃ‚ŠµŠ²Š¾Š³Š¾ Š°Š“Š°ŠæтŠµŃ€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to disable the audio adapter.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть Š°ŃƒŠ“ŠøŠ¾ Š°Š“Š°ŠæтŠµŃ€.</translation>
+ </message>
+ <message>
+ <source>Failed to register &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Ń€ŠµŠ³ŠøстрŠøрŠ¾Š²Š°Ń‚ŃŒ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to create %ls.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ %ls.</translation>
+ </message>
+ <message>
+ <source>Failed to create base storage for local gateway image.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š±Š°Š·Š¾Š²Š¾Šµ хрŠ°Š½ŠøŠ»ŠøщŠµ Š“Š»Ń Š¾Š±Ń€Š°Š·Š° Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to lock &apos;%ls&apos; for modifications.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š±Š»Š¾ŠŗŠøрŠ¾Š²Š°Ń‚ŃŒ &apos;%ls&apos; Š“Š»Ń ŠøŠ·Š¼ŠµŠ½ŠµŠ½Šøя.</translation>
+ </message>
+ <message>
+ <source>Failed to obtain a mutable machine.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ·Š¼ŠµŠ½ŃŠµŠ¼ŃƒŃŽ Š¼Š°ŃˆŠøŠ½Ńƒ.</translation>
+ </message>
+ <message>
+ <source>Failed to attach HD to &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡Šøть Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ Šŗ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to attach ISO to &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡Šøть ISO Šŗ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to save &apos;%ls&apos; settings.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Ń…Ń€Š°Š½Šøть Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠø &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to create unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€.</translation>
+ </message>
+ <message>
+ <source>Failed to set machine for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ Š¼Š°ŃˆŠøŠ½Ńƒ Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set user for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set password for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set full user name for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ ŠæŠ¾Š»Š½Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to enable guest addtions for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²ŠŗŠ»ŃŽŃ‡Šøть Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set guest addtions ISO path for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ Šæуть Šŗ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøяŠ¼ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set script template for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ шŠ°Š±Š»Š¾Š½ сŠŗрŠøŠæтŠ° Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to set post install script template for the unattended installer.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ шŠ°Š»Š¾Š½ post-install сŠŗрŠøŠæтŠ° Š“Š»Ń unattended ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š°.</translation>
+ </message>
+ <message>
+ <source>Failed to prepare unattended installation.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š“Š³Š¾Ń‚Š¾Š²Šøть unattended устŠ°Š½Š¾Š²Šŗу.</translation>
+ </message>
+ <message>
+ <source>Failed to construct media for unattended installation.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š±Ń€Š°Ń‚ŃŒ Š½Š¾ŃŠøтŠµŠ»ŃŒ Š“Š»Ń unattended устŠ°Š½Š¾Š²ŠŗŠø.</translation>
+ </message>
+ <message>
+ <source>Failed to reconfigure %ls for unattended installation.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€ŠøрŠ¾Š²Š°Ń‚ŃŒ %ls Š“Š»Ń unattended устŠ°Š½Š¾Š²ŠŗŠø.</translation>
+ </message>
+ <message>
+ <source> %32s = failed: %Rhrc
+</source>
+ <translation type="vanished"> %32s = Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rhrc
+</translation>
+ </message>
+ <message>
+ <source>Performing unattended install of temporary local gateway...
+</source>
+ <translation type="vanished">ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“Šøтся unattended устŠ°Š½Š¾Š²ŠŗŠ° Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š³Š¾ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š°...
+</translation>
+ </message>
+ <message>
+ <source>Failed to launch &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæустŠøть &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to get machine state.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ Š¼Š°ŃˆŠøŠ½Ń‹.</translation>
+ </message>
+ <message>
+ <source>Temporary local gateway VM has aborted.</source>
+ <translation type="vanished">Š’Šœ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š³Š¾ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š° ŠæрŠµŃ€Š²Š°Š½Š°.</translation>
+ </message>
+ <message>
+ <source>Timed out (40min) while waiting for unattended install to finish.</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя (40 Š¼ŠøŠ½) Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Šøя unattended устŠ°Š½Š¾Š²ŠŗŠø.</translation>
+ </message>
+ <message>
+ <source><byte value="xd"/>Done.
+</source>
+ <translation type="vanished"><byte value="xd"/>Š”Š“ŠµŠ»Š°Š½Š¾.
+</translation>
+ </message>
+ <message>
+ <source>Detaching local gateway image...
+</source>
+ <translation type="vanished">ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ Š¾Š±Ń€Š°Š·Š° Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š°...
+</translation>
+ </message>
+ <message>
+ <source>Failed to detach HD to &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ Š¾Ń‚ &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Unregistering temporary local gateway machine...
+</source>
+ <translation type="vanished">ŠžŃ‚Š¼ŠµŠ½Š° рŠµŠ³ŠøстрŠ°Ń†ŠøŠø Š¼Š°ŃˆŠøŠ½Ń‹ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š³Š¾ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š°...
+</translation>
+ </message>
+ <message>
+ <source>Failed to unregister &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Š¼ŠµŠ½Šøть рŠµŠ³ŠøстрŠ°Ń†Šøю &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to delete config for &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю Š“Š»Ń &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Making local gateway image immutable...
+</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ шŠ»ŃŽŠ·Š° Š² Š½ŠµŠøŠ·Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¹...
+</translation>
+ </message>
+ <message>
+ <source>Failed to open &apos;%ls&apos;.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Šŗрыть &apos;%ls&apos;.</translation>
+ </message>
+ <message>
+ <source>Failed to make &apos;%ls&apos; immutable.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ“ŠµŠ»Š°Ń‚ŃŒ &apos;%ls&apos; Š½ŠµŠøŠ·Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¼.</translation>
+ </message>
+ <message>
+ <source>Missing --local-gateway-iso parameter</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --local-gateway-iso</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2209"/>
+ <source>Setting up tunnel network in the cloud...
+</source>
+ <translation>Š£ŃŃ‚Š°Š½Š¾Š²ŠŗŠ° туŠ½Š½ŠµŠ»ŃŒŠ½Š¾Š¹ сŠµŃ‚Šø Š² Š¾Š±Š»Š°ŠŗŠµ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2235"/>
+ <source>Setting up cloud network environment failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ устŠ°Š½Š¾Š²Šøть Š¾ŠŗруŠ¶ŠµŠ½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ сŠµŃ‚Šø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2239"/>
+ <source>Cloud network environment was set up successfully. Tunnel network id is: %ls
+</source>
+ <translation>ŠžŠŗруŠ¶ŠµŠ½ŠøŠµ Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ сŠµŃ‚Šø устŠ°Š½Š¾Š²Š»ŠµŠ½Š¾ усŠæŠµŃˆŠ½Š¾. ID туŠ½Š½ŠµŠ»ŃŒŠ½Š¾Š¹ сŠµŃ‚Šø: %ls
+</translation>
+ </message>
+</context>
+<context>
+ <name>CloudMachine</name>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="172"/>
+ <source>cloud: no providers available</source>
+ <translation>Š¾Š±Š»Š°ŠŗŠ¾: Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ Š½Šø Š¾Š“Š½Š¾Š³Š¾ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="178"/>
+ <source>cloud: multiple providers available, &apos;--provider&apos; option is required</source>
+ <translation>Š¾Š±Š»Š°ŠŗŠ¾: Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š¾Š², трŠµŠ±ŃƒŠµŃ‚ся Š¾ŠæцŠøя &apos;--provider&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="231"/>
+ <source>cloud: no profiles exist</source>
+ <translation>Š¾Š±Š»Š°ŠŗŠ¾: Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚ Š½Šø Š¾Š“Š½Š¾Š³Š¾ ŠæрŠ¾Ń„ŠøŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="237"/>
+ <source>cloud: multiple profiles exist, &apos;--profile&apos; option is required</source>
+ <translation>Š¾Š±Š»Š°ŠŗŠ¾: сущŠµŃŃ‚Š²ŃƒŠµŃ‚ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠ¾Ń„ŠøŠ»ŠµŠ¹, трŠµŠ±ŃƒŠµŃ‚ся Š¾ŠæцŠøя &apos;--profile&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="363"/>
+ <source>ambiguous name: %ls and %ls</source>
+ <translation>Š½ŠµŠ¾Š“Š½Š¾Š·Š½Š°Ń‡Š½Š¾Šµ ŠøŠ¼Ń: %ls Šø %ls</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="419"/>
+ <source>only one machine can be specified</source>
+ <translation>Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½Š° тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š° Š¼Š°ŃˆŠøŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="467"/>
+ <source>not a valid uuid: %s</source>
+ <translation>Š½ŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹ uuid: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="530"/>
+ <source>machine not specified</source>
+ <translation>Š¼Š°ŃˆŠøŠ½Š° Š½Šµ уŠŗŠ°Š·Š°Š½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="536"/>
+ <source>machine name is empty</source>
+ <translation>ŠøŠ¼Ń Š¼Š°ŃˆŠøŠ½Ń‹ ŠæустŠ¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="547"/>
+ <source>unable to find machine with id %s</source>
+ <translation>Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø Š¼Š°ŃˆŠøŠ½Ńƒ с ID %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="557"/>
+ <source>unable to find machine with name %s</source>
+ <translation>Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø Š¼Š°ŃˆŠøŠ½Ńƒ с ŠøŠ¼ŠµŠ½ŠµŠ¼ %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="567"/>
+ <source>unable to find machine %s</source>
+ <translation>Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø Š¼Š°ŃˆŠøŠ½Ńƒ %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="639"/>
+ <source>cloud machine: RTGetOptInit: %Rra</source>
+ <translation>Š¾Š±Š»Š°Ń‡Š½Š°Ń Š¼Š°ŃˆŠøŠ½Š°: RTGetOptInit: %Rra</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="654"/>
+ <location filename="../VBoxManageCloudMachine.cpp" line="789"/>
+ <source>Invalid sub-command: %s</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="700"/>
+ <source>cloud machine: internal error: %d</source>
+ <translation>Š¾Š±Š»Š°Ń‡Š½Š°Ń Š¼Š°ŃˆŠøŠ½Š°: Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŃŃ Š¾ŃˆŠøŠ±ŠŗŠ°: %d</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="705"/>
+ <source>cloud machine: command required
+Try &apos;--help&apos; for more information.</source>
+ <translation>Š¾Š±Š»Š°Ń‡Š½Š°Ń Š¼Š°ŃˆŠøŠ½Š°: трŠµŠ±ŃƒŠµŃ‚ся ŠŗŠ¾Š¼Š°Š½Š“Š°
+Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;--help&apos; Š“Š»Ń Š“ŠµŃ‚Š°Š»ŃŒŠ½Š¾Š¹ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŠø.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="757"/>
+ <source>cloud machine list: unexpected machine argument</source>
+ <translation>сŠæŠøсŠ¾Šŗ Š¾Š±Š»Š°Ń‡Š½Ń‹Ń… Š¼Š°ŃˆŠøŠ½: Š½ŠµŠ¾Š¶ŠøŠ“Š°Š½Š½Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Š¼Š°ŃˆŠøŠ½Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="765"/>
+ <source>cloud machine list: RTGetOptInit: %Rra</source>
+ <translation>сŠæŠøсŠ¾Šŗ Š¾Š±Š»Š°Ń‡Š½Ń‹Ń… Š¼Š°ŃˆŠøŠ½: RTGetOptInit: %Rra</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="987"/>
+ <source>machine is not accessible</source>
+ <translation>Š¼Š°ŃˆŠøŠ½Š° Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1017"/>
+ <source>State: Invalid (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1021"/>
+ <source>State: Provisioning (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: ŠŸŠ¾Š“Š³Š¾Ń‚Š¾Š²ŠŗŠ° (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1025"/>
+ <source>State: Running (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: Š Š°Š±Š¾Ń‚Š°ŠµŃ‚ (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1029"/>
+ <source>State: Starting (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: Š—Š°ŠæусŠŗŠ°ŠµŃ‚ся (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1033"/>
+ <source>State: Stopping (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: ŠžŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°ŠµŃ‚ся (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1037"/>
+ <source>State: Stopped (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: ŠžŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š° (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1041"/>
+ <source>State: CreatingImage (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: Š”Š¾Š·Š“Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1045"/>
+ <source>State: Terminating (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: Š—Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1049"/>
+ <source>State: Terminated (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: Š—Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1053"/>
+ <source>State: Unknown state (%RU32)
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾Šµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ (%RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1062"/>
+ <source>null details</source>
+ <translation>ŠæŠ¾Š“рŠ¾Š±Š½Š°Ń ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾Ń‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1109"/>
+ <source>%ls: unable to convert to boolean value
+</source>
+ <translation>%ls: Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š² Š±ŃƒŠ»ŠµŠ²Š¾ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1135"/>
+ <source>%ls: unable to convert to string value
+</source>
+ <translation>%ls: Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š² стрŠ¾ŠŗŠ¾Š²Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1177"/>
+ <source>%ls: unable to convert to integer value
+</source>
+ <translation>%ls: Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š² цŠµŠ»Š¾Ń‡ŠøсŠ»ŠµŠ½Š½Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1203"/>
+ <source>%ls: unable to convert to choice value
+</source>
+ <translation>%ls: Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š² Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š²Ń‹Š±Š¾Ń€Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1213"/>
+ <source>%ls: values: %Rhra</source>
+ <translation>%ls: Š·Š½Š°Ń‡ŠµŠ½Šøя: %Rhra</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1223"/>
+ <source>%ls: selectedIndex: %Rhra</source>
+ <translation>%ls: Š²Ń‹Š±Ń€Š°Š½Š½Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс: %Rhra</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1231"/>
+ <source>%ls: selected index %RI64 out of range [0, %zu)
+</source>
+ <translation>%ls: Š²Ń‹Š±Ń€Š°Š½Š½Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс %RI64 Š²Š½Šµ Š³Ń€Š°Š½Šøц Š“ŠøŠ°ŠæŠ°Š·Š¾Š½Š° [0, %zu)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1243"/>
+ <source>unknown value type %RU32
+</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Ń‹Š¹ тŠøŠæ Š·Š½Š°Ń‡ŠµŠ½Šøя %RU32
+</translation>
+ </message>
+</context>
+<context>
+ <name>CloudVM</name>
+ <message>
+ <source>Invalid %s number &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹ Š½Š¾Š¼ŠµŃ€ %s &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Failed to send a scancode</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾ŃŠ»Š°Ń‚ŃŒ сŠŗŠ°Š½ŠŗŠ¾Š“</translation>
+ </message>
+ <message numerus="yes">
+ <source>Only %d scancodes were stored</source>
+ <translation type="vanished">
+ <numerusform>Š”Š¾Ń…Ń€Š°Š½ŠµŠ½ тŠ¾Š»ŃŒŠŗŠ¾ %d сŠŗŠ°Š½ŠŗŠ¾Š“</numerusform>
+ <numerusform>Š”Š¾Ń…Ń€Š°Š½ŠµŠ½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ %d сŠŗŠ°Š½ŠŗŠ¾Š“Š°</numerusform>
+ <numerusform>Š”Š¾Ń…Ń€Š°Š½ŠµŠ½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ %d сŠŗŠ°Š½ŠŗŠ¾Š“Š¾Š²</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Out of memory allocating %d bytes</source>
+ <translation type="vanished">
+ <numerusform>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š±ŃƒŃ„ŠµŃ€ %d Š±Š°Š¹Ń‚</numerusform>
+ <numerusform>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š±ŃƒŃ„ŠµŃ€ %d Š±Š°Š¹Ń‚Š°</numerusform>
+ <numerusform>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š±ŃƒŃ„ŠµŃ€ %d Š±Š°Š¹Ń‚</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>File size %RI64 is greater than %RI64: &apos;%s&apos;</source>
+ <translation type="vanished">Š Š°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° %RI64 Š±Š¾Š»ŃŒŃˆŠµ чŠµŠ¼ %RI64: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Cannot get size of file &apos;%s&apos;: %Rrc</source>
+ <translation type="vanished">ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <source>Cannot open file &apos;%s&apos;: %Rrc</source>
+ <translation type="vanished">ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <source>Not enough parameters</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <source>Machine &apos;%s&apos; is not currently running</source>
+ <translation type="vanished">ŠœŠ°ŃˆŠøŠ½Š° &apos;%s&apos; сŠµŠ¹Ń‡Š°Ń Š½Šµ Š·Š°ŠæущŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected CPU number.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся Š½Š¾Š¼ŠµŃ€ Š¦ŠŸŠ£.</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected execution cap number.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся %% Š²Ń€ŠµŠ¼ŠµŠ½Šø Š² %% Š²Ń‹Š“ŠµŠ»ŠµŠ½Š½Š¾Š³Š¾ Š“Š»Ń Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя.</translation>
+ </message>
+ <message>
+ <source>Invalid value &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>audio adapter not enabled in VM configuration</source>
+ <translation type="vanished">Š°ŃƒŠ“ŠøŠ¾ Š°Š“Š°ŠæтŠµŃ€ Š½Šµ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š² ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø Š’Šœ</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;.</translation>
+ </message>
+ <message>
+ <source>Invalid &apos;%s&apos; argument &apos;%s&apos;.</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos; &apos;%s&apos;.</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected enabled / disabled.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся enabled / disabled.</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected drag and drop mode.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся рŠµŠ¶ŠøŠ¼ drag and drop.</translation>
+ </message>
+ <message>
+ <source>Failed to power off machine</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹ŠŗŠ»ŃŽŃ‡Šøть Š¼Š°ŃˆŠøŠ½Ńƒ</translation>
+ </message>
+ <message>
+ <source>Machine in invalid state %d -- %s
+</source>
+ <translation type="vanished">ŠœŠ°ŃˆŠøŠ½Š° Š² Š½ŠµŠ“Š¾ŠæустŠøŠ¼Š¾Š¼ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠø %d -- %s
+</translation>
+ </message>
+ <message>
+ <source>Failed to save machine state</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Ń…Ń€Š°Š½Šøть сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ Š¼Š°ŃˆŠøŠ½Ń‹</translation>
+ </message>
+ <message>
+ <source>Guest not running</source>
+ <translation type="vanished">Š“Š¾ŃŃ‚ŠµŠ²Š°Ń сŠøстŠµŠ¼Š° Š½Šµ Š·Š°ŠæущŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <source>Current installed Guest Additions don&apos;t support %s the guest.</source>
+ <translation type="vanished">Š¢ŠµŠŗущŠøŠµ устŠ°Š½Š¾Š²Š»ŠµŠ½Š½Ń‹Šµ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ %s Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹.</translation>
+ </message>
+ <message>
+ <source>rebooting</source>
+ <translation type="vanished">ŠæŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·Šŗу</translation>
+ </message>
+ <message>
+ <source>shutting down</source>
+ <translation type="vanished">Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected IBM PC AT set 2 keyboard scancode(s) as hex byte(s).</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŃŽŃ‚ся сŠŗŠ°Š½ŠŗŠ¾Š“ы ŠŗŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Ń‹ IBM PC AT set 2 Š² Š²ŠøŠ“Šµ hex Š±Š°Š¹Ń‚Š¾Š².</translation>
+ </message>
+ <message>
+ <source>Converting &apos;%s&apos; returned %Rrc!</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ &apos;%s&apos; Š²ŠµŃ€Š½ŃƒŠ»Š¾ %Rrc!</translation>
+ </message>
+ <message>
+ <source>Error: &apos;%s&apos; is not a hex byte!</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ°: &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся hex Š±Š°Š¹Ń‚Š¾Š¼!</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected ASCII string(s).</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся стрŠ¾ŠŗŠ° ASCII.</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;. Expected file name.</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся ŠøŠ¼Ń фŠ°Š¹Š»Š°.</translation>
+ </message>
+ <message>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid link state &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid filename or filename not specified for NIC %lu</source>
+ <translation type="vanished">ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Š¾Šµ ŠøŠ¼Ń фŠ°Š¹Š»Š° ŠøŠ»Šø ŠøŠ¼Ń фŠ°Š¹Š»Š° Š½Šµ уŠŗŠ°Š·Š°Š½Š¾ Š“Š»Ń сŠµŃ‚ŠµŠ²Š¾Š³Š¾ Š°Š“Š°ŠæтŠµŃ€Š° %lu</translation>
+ </message>
+ <message>
+ <source>The NIC %d is currently disabled and thus its tracefile can&apos;t be changed</source>
+ <translation type="vanished">NIC %d Š² Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šø ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ ŠµŠ³Š¾ трŠ°ŃŃŠøрŠ¾Š²Š¾Ń‡Š½Ń‹Š¹ фŠ°Š¹Š» Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½</translation>
+ </message>
+ <message>
+ <source>Invalid nictrace%lu argument &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ nictrace%lu &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>The NIC %d is currently disabled and thus its trace flag can&apos;t be changed</source>
+ <translation type="vanished">NIC %d Š² Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šø ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ ŠµŠ³Š¾ трŠ°ŃŃŠøрŠ¾Š²Š¾Ń‡Š½Ń‹Š¹ фŠ»Š°Š³ Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½</translation>
+ </message>
+ <message>
+ <source>Missing or invalid argument to &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ»Šø Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Wrong rule proto &apos;%s&apos; specified -- only &apos;udp&apos; and &apos;tcp&apos; are allowed.</source>
+ <translation type="vanished">Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Ń‹Š¹ ŠæрŠ¾Ń‚Š¾ŠŗŠ¾Š» ŠæрŠ°Š²ŠøŠ»Š° &apos;%s&apos; -- рŠ°Š·Ń€ŠµŃˆŠµŠ½Ń‹ тŠ¾Š»ŃŒŠŗŠ¾ &apos;udp&apos; Šø &apos;tcp&apos;.</translation>
+ </message>
+ <message>
+ <source>Invalid nicproperty%d argument &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ nicproperty%d &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error: Failed to allocate memory for nicproperty%d &apos;%s&apos;
+</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ°: ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ Š“Š»Ń nicproperty%d &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <source>The NIC %d is currently disabled and thus its properties can&apos;t be changed</source>
+ <translation type="vanished">NIC %d Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š² Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń, Šø ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠøŠ·Š¼ŠµŠ½Šøть ŠµŠ³Š¾ сŠ²Š¾Š¹ŃŃ‚Š²Š°</translation>
+ </message>
+ <message>
+ <source>Unknown promiscuous mode policy &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š»ŠøтŠøŠŗŠ° Š½ŠµŃ€Š°Š·Š±Š¾Ń€Ń‡ŠøŠ²Š¾Š³Š¾ рŠµŠ¶ŠøŠ¼Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>The NIC %d is currently disabled and thus its promiscuous mode can&apos;t be changed</source>
+ <translation type="vanished">NIC %d Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š² Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń, Šø ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠøŠ·Š¼ŠµŠ½Šøть Š½ŠµŃ€Š°Š·Š±Š¾Ń€Ń‡ŠøŠ²Ń‹Š¹ рŠµŠ¶ŠøŠ¼</translation>
+ </message>
+ <message>
+ <source>Invalid type &apos;%s&apos; specfied for NIC %lu</source>
+ <translation type="vanished">Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ &apos;%s&apos; Š“Š»Ń NIC %lu</translation>
+ </message>
+ <message>
+ <source>The NIC %d is currently disabled and thus its attachment type can&apos;t be changed</source>
+ <translation type="vanished">NIC %d Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š² Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń, Šø ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠøŠ·Š¼ŠµŠ½Šøть тŠøŠæ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <source>Warning: &apos;vrdp&apos; is deprecated. Use &apos;vrde&apos;.
+</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: &apos;vrdp&apos; устŠ°Ń€ŠµŠ». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;vrde&apos;.
+</translation>
+ </message>
+ <message>
+ <source>Invalid remote desktop server state &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ сŠµŃ€Š²ŠµŃ€Š° уŠ“Š°Š»ŠµŠ½Š½Š¾Š³Š¾ рŠ°Š±Š¾Ń‡ŠµŠ³Š¾ стŠ¾Š»Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Warning: &apos;vrdpport&apos; is deprecated. Use &apos;vrdeport&apos;.
+</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: &apos;vrdpport&apos; устŠ°Ń€ŠµŠ». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;vrdeport&apos;.
+</translation>
+ </message>
+ <message>
+ <source>Warning: &apos;vrdpvideochannelquality&apos; is deprecated. Use &apos;vrdevideochannelquality&apos;.
+</source>
+ <translation type="vanished">ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: &apos;vrdpvideochannelquality&apos; устŠ°Ń€ŠµŠ». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;vrdevideochannelquality&apos;.
+</translation>
+ </message>
+ <message>
+ <source>Invalid vrdeproperty argument &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ vrdeproperty &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error: Failed to allocate memory for VRDE property &apos;%s&apos;
+</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ°: ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ Š“Š»Ń сŠ²Š¾Š¹ŃŃ‚Š²Š° VRDE &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <source>Wrong number of arguments</source>
+ <translation type="vanished">ŠŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Zero UUID argument &apos;%s&apos;</source>
+ <translation type="vanished">ŠŃƒŠ»ŠµŠ²Š¾Š¹ UUID Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Incorrect number of parameters</source>
+ <translation type="vanished">ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <source>Either &quot;yes&quot; or &quot;no&quot; is expected</source>
+ <translation type="vanished">ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся тŠ¾Š»ŃŒŠŗŠ¾ &quot;yes&quot; ŠøŠ»Šø &quot;no&quot;</translation>
+ </message>
+ <message>
+ <source>Display status must be &lt;on&gt; or &lt;off&gt;</source>
+ <translation type="vanished">Š”тŠ°Ń‚ŃƒŃ эŠŗрŠ°Š½Š° Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ &lt;on&gt; ŠøŠ»Šø &lt;off&gt;</translation>
+ </message>
+ <message>
+ <source>Invalid host DVD drive name &quot;%s&quot;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń DVD Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <source>IDE Controller</source>
+ <translation type="vanished">IDE ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€</translation>
+ </message>
+ <message>
+ <source>Invalid host floppy drive name &quot;%s&quot;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń фŠ»Š¾ŠæŠæŠø Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <source>Floppy Controller</source>
+ <translation type="vanished">Š¤Š»Š¾ŠæŠæŠø ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€</translation>
+ </message>
+ <message>
+ <source>Error parsing guest memory balloon size &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° рŠ°Š·Š±Š¾Ń€Š° рŠ°Š·Š¼ŠµŃ€Š° balloon ŠæŠ°Š¼ŃŃ‚Šø Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Teleportation failed</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾ŠøŠ·Š²ŠµŃŃ‚Šø ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ</translation>
+ </message>
+ <message>
+ <source>Error parsing display number &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° рŠ°Š·Š±Š¾Ń€Š° Š½Š¾Š¼ŠµŃ€Š° эŠŗрŠ°Š½Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Failed to create file &apos;%s&apos; (%Rrc)</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ фŠ°Š¹Š» &apos;%s&apos; (%Rrc)</translation>
+ </message>
+ <message>
+ <source>Failed to write screenshot to file &apos;%s&apos; (%Rrc)</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæŠøсŠ°Ń‚ŃŒ сŠ½ŠøŠ¼Š¾Šŗ эŠŗрŠ°Š½Š° Š² фŠ°Š¹Š» &apos;%s&apos; (%Rrc)</translation>
+ </message>
+ <message>
+ <source>Invalid screen ID specified &apos;%u&apos;</source>
+ <translation type="vanished">Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ID эŠŗрŠ°Š½Š° &apos;%u&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing video width &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ шŠøрŠøŠ½Ń‹ Š²ŠøŠ“ŠµŠ¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing video height &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š²Ń‹ŃŠ¾Ń‚Ń‹ Š²ŠøŠ“ŠµŠ¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing video rate &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š±ŠøтрŠµŠ¹Ń‚Š° Š²ŠøŠ“ŠµŠ¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing video FPS &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ FPS Š²ŠøŠ“ŠµŠ¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing maximum time &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾Š³Š¾ Š²Ń€ŠµŠ¼ŠµŠ½Šø &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Error parsing maximum file size &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾Š³Š¾ рŠ°Š·Š¼ŠµŃ€Š° фŠ°Š¹Š»Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid argument to &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid parameters</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Šµ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры</translation>
+ </message>
+ <message>
+ <source>Enter password:</source>
+ <translation type="vanished">Š’Š²ŠµŠ“ŠøтŠµ ŠæŠ°Ń€Š¾Š»ŃŒ:</translation>
+ </message>
+ <message>
+ <source>Failed to read new password from file</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š½Š¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ ŠøŠ· фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <source>Incorrect arguments to &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Ń‹Šµ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Ń‹ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid vm-process-priority &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ vm-process-priority &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Invalid autostart delay number &apos;%s&apos;</source>
+ <translation type="vanished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š²Ń€ŠµŠ¼Ń Š·Š°Š“ŠµŃ€Š¶ŠŗŠø Š°Š²Ń‚Š¾ŃŃ‚Š°Ń€Ń‚Š° &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>ControlVM</name>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="65"/>
+ <source>Invalid %s number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="222"/>
+ <source>Failed to send a scancode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageControlVM.cpp" line="323"/>
+ <source>Out of memory allocating %d bytes.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="326"/>
+ <source>File size %RI64 is greater than %RI64: &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="329"/>
+ <source>Cannot get size of file &apos;%s&apos;: %Rrc.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="334"/>
+ <source>Cannot open file &apos;%s&apos;: %Rrc.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="351"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1372"/>
+ <source>Not enough parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="371"/>
+ <source>Machine &apos;%s&apos; is not currently running.</source>
+ <translation type="unfinished">ŠœŠ°ŃˆŠøŠ½Š° &apos;%s&apos; сŠµŠ¹Ń‡Š°Ń Š½Šµ Š·Š°ŠæущŠµŠ½Š°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="397"/>
+ <location filename="../VBoxManageControlVM.cpp" line="411"/>
+ <location filename="../VBoxManageControlVM.cpp" line="425"/>
+ <location filename="../VBoxManageControlVM.cpp" line="487"/>
+ <location filename="../VBoxManageControlVM.cpp" line="558"/>
+ <location filename="../VBoxManageControlVM.cpp" line="782"/>
+ <location filename="../VBoxManageControlVM.cpp" line="802"/>
+ <location filename="../VBoxManageControlVM.cpp" line="840"/>
+ <location filename="../VBoxManageControlVM.cpp" line="884"/>
+ <location filename="../VBoxManageControlVM.cpp" line="925"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1019"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1081"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1131"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1160"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1172"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1184"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1197"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1208"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1237"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1266"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1297"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1318"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1992"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2115"/>
+ <source>Missing argument to &apos;%s&apos;.</source>
+ <translation type="unfinished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="444"/>
+ <location filename="../VBoxManageControlVM.cpp" line="468"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2226"/>
+ <source>Invalid value &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="453"/>
+ <location filename="../VBoxManageControlVM.cpp" line="477"/>
+ <source>Audio adapter not enabled in VM configuration.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="498"/>
+ <location filename="../VBoxManageControlVM.cpp" line="528"/>
+ <source>Missing argument to &apos;%s %s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="513"/>
+ <location filename="../VBoxManageControlVM.cpp" line="536"/>
+ <source>Invalid &apos;%s %s&apos; argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="547"/>
+ <location filename="../VBoxManageControlVM.cpp" line="574"/>
+ <source>Invalid &apos;%s&apos; argument &apos;%s&apos;.</source>
+ <translation type="unfinished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos; &apos;%s&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="591"/>
+ <source>Failed to power off machine.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="611"/>
+ <source>Machine in invalid state %d -- %s.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="634"/>
+ <source>Failed to save machine state.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="665"/>
+ <location filename="../VBoxManageControlVM.cpp" line="700"/>
+ <location filename="../VBoxManageControlVM.cpp" line="754"/>
+ <location filename="../VBoxManageControlVM.cpp" line="775"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1478"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1500"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1624"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1658"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1755"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2001"/>
+ <source>Guest not running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="686"/>
+ <source>Current installed Guest Additions don&apos;t support rebooting the guest.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="688"/>
+ <source>Current installed Guest Additions don&apos;t support shutting down the guest.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="707"/>
+ <source>Missing argument to &apos;%s&apos;. Expected IBM PC AT set 2 keyboard scancode(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="727"/>
+ <source>Converting &apos;%s&apos; returned %Rrc!</source>
+ <translation type="unfinished">ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ &apos;%s&apos; Š²ŠµŃ€Š½ŃƒŠ»Š¾ %Rrc!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="736"/>
+ <source>&apos;%s&apos; is not a hex byte!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="761"/>
+ <source>Missing argument to &apos;%s&apos;. Expected ASCII string(s).</source>
+ <translation type="unfinished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;. ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся стрŠ¾ŠŗŠ° ASCII.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="814"/>
+ <source>Invalid link state &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="860"/>
+ <source>Filename not specified for NIC %lu.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="868"/>
+ <source>The NIC %d is currently disabled and thus its tracefile can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="901"/>
+ <source>Invalid nictrace%lu argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="909"/>
+ <source>The NIC %d is currently disabled and thus its trace flag can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="961"/>
+ <source>Missing or invalid argument to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="996"/>
+ <source>Wrong rule proto &apos;%s&apos; specified -- only &apos;udp&apos; and &apos;tcp&apos; are allowed.</source>
+ <translation type="unfinished">Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Ń‹Š¹ ŠæрŠ¾Ń‚Š¾ŠŗŠ¾Š» ŠæрŠ°Š²ŠøŠ»Š° &apos;%s&apos; -- рŠ°Š·Ń€ŠµŃˆŠµŠ½Ń‹ тŠ¾Š»ŃŒŠŗŠ¾ &apos;udp&apos; Šø &apos;tcp&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1050"/>
+ <source>Invalid nicproperty%d argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1057"/>
+ <source>Failed to allocate memory for nicproperty%d &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1065"/>
+ <source>The NIC %d is currently disabled and thus its properties can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1105"/>
+ <source>Unknown promiscuous mode policy &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1115"/>
+ <source>The NIC %d is currently disabled and thus its promiscuous mode can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1217"/>
+ <source>Invalid type &apos;%s&apos; specfied for NIC %lu.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1225"/>
+ <source>The NIC %d is currently disabled and thus its attachment type can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1233"/>
+ <source>&apos;vrdp&apos; is deprecated. Use &apos;vrde&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1249"/>
+ <source>Invalid remote desktop server state &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1262"/>
+ <source>&apos;vrdpport&apos; is deprecated. Use &apos;vrdeport&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1293"/>
+ <source>&apos;vrdpvideochannelquality&apos; is deprecated. Use &apos;vrdevideochannelquality&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1344"/>
+ <source>Invalid vrdeproperty argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1351"/>
+ <source>Failed to allocate memory for VRDE property &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1378"/>
+ <source>Wrong number of arguments.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1392"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1587"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2259"/>
+ <source>Invalid parameter &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1425"/>
+ <source>Zero UUID argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1444"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1491"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1542"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1599"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1638"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1735"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1787"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1821"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1840"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1854"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1888"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1910"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1932"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1954"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1978"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2048"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2093"/>
+ <source>Incorrect number of parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1462"/>
+ <source>Either &quot;yes&quot; or &quot;no&quot; is expected.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1527"/>
+ <source>Display status must be &lt;on&gt; or &lt;off&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1647"/>
+ <source>Error parsing guest memory balloon size &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1728"/>
+ <source>Teleportation failed</source>
+ <translation type="unfinished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾ŠøŠ·Š²ŠµŃŃ‚Šø ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1746"/>
+ <source>Error parsing display number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1769"/>
+ <source>Failed to create file &apos;%s&apos; (%Rrc).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1776"/>
+ <source>Failed to write screenshot to file &apos;%s&apos; (%Rrc).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1827"/>
+ <source>Error parsing list of screen IDs &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1863"/>
+ <source>Error parsing video width &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1872"/>
+ <source>Error parsing video height &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1897"/>
+ <source>Error parsing video rate &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1919"/>
+ <source>Error parsing video FPS &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1941"/>
+ <source>Error parsing maximum time &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1963"/>
+ <source>Error parsing maximum file size &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2037"/>
+ <source>Invalid argument to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2059"/>
+ <source>Invalid parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2072"/>
+ <source>Enter password:</source>
+ <translation type="unfinished">Š’Š²ŠµŠ“ŠøтŠµ ŠæŠ°Ń€Š¾Š»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2081"/>
+ <source>Failed to read new password from file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2129"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2144"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2185"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2198"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2219"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2239"/>
+ <source>Incorrect arguments to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2205"/>
+ <source>Invalid vm-process-priority &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2248"/>
+ <source>Invalid autostart delay number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DHCPServer</name>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="65"/>
+ <source>Either --network or --interface, not both</source>
+ <translation>Š˜Š»Šø --network ŠøŠ»Šø --interface, Š½Šµ Š²Š¼ŠµŃŃ‚Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="70"/>
+ <source>Either --interface or --network, not both</source>
+ <translation>Š˜Š»Šø --interface ŠøŠ»Šø --network, Š½Šµ Š²Š¼ŠµŃŃ‚Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="180"/>
+ <source>Failed to locate host-only interface &apos;%s&apos;</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Š±Š½Š°Ń€ŃƒŠ¶Šøть Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Š¹ ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń хŠ¾ŃŃ‚Š°&apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="194"/>
+ <source>Failed to find DHCP server for network &apos;%s&apos;</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š½Š°Š¹Ń‚Šø DHCP сŠµŃ€Š²ŠµŃ€ Š“Š»Ń сŠµŃ‚Šø &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="196"/>
+ <source>Failed to find DHCP server for host-only interface &apos;%s&apos; (network &apos;%ls&apos;)</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š½Š°Š¹Ń‚Šø DHCP сŠµŃ€Š²ŠµŃ€ Š“Š»Ń Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŠ° хŠ¾ŃŃ‚Š° &apos;%s&apos; (сŠµŃ‚ŃŒ &apos;%ls&apos;)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="200"/>
+ <location filename="../VBoxManageDHCPServer.cpp" line="890"/>
+ <source>You need to specify either --network or --interface to identify the DHCP server</source>
+ <translation>ŠŃƒŠ¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ Š»ŠøŠ±Š¾ --network Š»ŠøŠ±Š¾ --interface Š“Š»Ń ŠøŠ“ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń†ŠøŠø DHCP сŠµŃ€Š²ŠµŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="474"/>
+ <source>Incomplete option sequence preseeding &apos;--global&apos;</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--global&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="480"/>
+ <source>Incomplete option sequence preseeding &apos;--group&apos;</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--group&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="482"/>
+ <source>Group name cannot be empty</source>
+ <translation>Š˜Š¼Ń Š³Ń€ŃƒŠæŠæы Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠæустыŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="488"/>
+ <source>Incomplete option sequence preseeding &apos;--mac-address&apos;</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--mac-address&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="495"/>
+ <source>Incomplete option sequence preseeding &apos;--vm&apos;</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--vm&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="501"/>
+ <source>--nic option requires a --vm preceeding selecting the VM it should apply to</source>
+ <translation>ŠžŠæцŠøя --nic трŠµŠ±ŃƒŠµŃ‚ Š½Š°Š»ŠøчŠøя ŠæрŠµŠ“шŠµŃŃ‚Š²ŃƒŃŽŃ‰ŠµŠ¹ --vm Š“Š»Ń Š²Ń‹Š±Š¾Ń€Š° Š’Šœ, Šŗ ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¹ Š“Š°Š½Š½Š°Ń Š¾ŠæцŠøя ŠæрŠøŠ¼ŠµŠ½ŃŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="503"/>
+ <source>Incomplete option sequence preseeding &apos;--nic=%u</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--nic=%u&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="505"/>
+ <source>invalid NIC number: %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š½Š¾Š¼ŠµŃ€ NIC: %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="540"/>
+ <source>Malformed hex string given to --set-opt-hex %u: %s
+</source>
+ <translation>ŠŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š°Ń hex стрŠ¾ŠŗŠ° уŠŗŠ°Š·Š°Š½Š½Š°Ń Š² --set-opt-hex %u: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="555"/>
+ <source>--del-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--del-opt Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="567"/>
+ <source>--unforce-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--unforce-opt Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="571"/>
+ <source>--unsuppress-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--unsuppress-opt Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="629"/>
+ <source>--zap-options does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--zap-options Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="671"/>
+ <source>--remove-config does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--remove-config Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="673"/>
+ <source>--remove-config cannot be applied to the global config</source>
+ <translation>--remove-config Š½Šµ Š¼Š¾Š¶ŠµŃ‚ ŠæрŠøŠ¼ŠµŠ½ŃŃ‚ŃŒŃŃ Šŗ Š³Š»Š¾Š±Š°Š»ŃŒŠ½Š¾Š¹ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="686"/>
+ <source>--fixed-address can only be applied to a VM NIC or an MAC address</source>
+ <translation>--fixed-address ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š¾ тŠ¾Š»ŃŒŠŗŠ¾ Šŗ NIC Š’Šœ ŠøŠ»Šø MAC Š°Š“рŠµŃŃƒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="720"/>
+ <source>A group must be selected to perform condition alterations.</source>
+ <translation>Š”Š»Ń ŠæрŠ¾Š²ŠµŠ“ŠµŠ½Šøя ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŠ¹ ŠæŠ¾ усŠ»Š¾Š²Šøю Š“Š¾Š»Š¶Š½Š° Š±Ń‹Ń‚ŃŒ Š²Ń‹Š±Ń€Š°Š½Š° Š³Ń€ŃƒŠæŠæŠ°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="722"/>
+ <source>Condition value cannot be empty</source>
+ <translation>Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ усŠ»Š¾Š²Šøя Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠæустыŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="815"/>
+ <source>Could not find any condition of type %d with value &apos;%s&apos; to delete</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠŗŠ°ŠŗŠ¾Šµ-Š»ŠøŠ±Š¾ усŠ»Š¾Š²ŠøŠµ тŠøŠæŠ° %d сŠ¾ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµŠ¼ &apos;%s&apos; Š“Š»Ń уŠ“Š°Š»ŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="823"/>
+ <source>--zap-conditions can only be with a group selected</source>
+ <translation>--zap-conditions Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ с Š²Ń‹Š±Ń€Š°Š½Š½Š¾Š¹ Š³Ń€ŃƒŠæŠæŠ¾Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="842"/>
+ <source>Incomplete option sequence preseeding &apos;--id=%u</source>
+ <translation>ŠŠµŠæŠ¾Š»Š½Š°Ń ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š¾ŠæцŠøŠ¹ ŠæŠµŃ€ŠµŠ“ &apos;--id=%u&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="849"/>
+ <source>--value without --id=dhcp-opt-no</source>
+ <translation>--value Š±ŠµŠ· --id=dhcp-opt-no</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="863"/>
+ <source>--remove does not apply to the &apos;add&apos; subcommand</source>
+ <translation>--remove Š½Šµ ŠæрŠøŠ¼ŠµŠ½ŠøŠ¼Š° Šŗ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Šµ &apos;add&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="865"/>
+ <source>--remove without --id=dhcp-opt-no</source>
+ <translation>--remove Š±ŠµŠ· --id=dhcp-opt-no</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="895"/>
+ <source>Missing required option: --ip</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ трŠµŠ±ŃƒŠµŠ¼Š°Ń Š¾ŠæцŠøя: --ip</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="897"/>
+ <source>Missing required option: --netmask</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ трŠµŠ±ŃƒŠµŠ¼Š°Ń Š¾ŠæцŠøя: --netmask</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="899"/>
+ <source>Missing required option: --lowerip</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ трŠµŠ±ŃƒŠµŠ¼Š°Ń Š¾ŠæцŠøя: --lowerip</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="901"/>
+ <source>Missing required option: --upperip</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ трŠµŠ±ŃƒŠµŠ¼Š°Ń Š¾ŠæцŠøя: --upperip</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="919"/>
+ <source>Could not find interface &apos;%s&apos;</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="923"/>
+ <source>Could not get network name for the interface &apos;%s&apos;</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ¼Ń сŠµŃ‚Šø Š“Š»Ń ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŠ° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="934"/>
+ <source>DHCP server already exists</source>
+ <translation>DHCP сŠµŃ€Š²ŠµŃ€ уŠ¶Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="938"/>
+ <source>Failed to create the DHCP server</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ DHCP сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="941"/>
+ <source>DHCP server does not exist</source>
+ <translation>DHCP сŠµŃ€Š²ŠµŃ€ Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="973"/>
+ <source>Failed to set configuration (%ls, %ls, %ls, %ls)</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю (%ls, %ls, %ls, %ls)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1025"/>
+ <source>Failed to remove server</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1092"/>
+ <source>Failed to start the server</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæустŠøть сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1136"/>
+ <source>Failed to restart the server</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŠ·Š°ŠæустŠøть сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1180"/>
+ <source>Failed to stop the server</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾ŃŃ‚Š°Š½Š¾Š²Šøть сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1227"/>
+ <source>You need to specify a MAC address too look for</source>
+ <translation>ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ MAC Š°Š“рŠµŃ Š“Š»Ń ŠæŠ¾ŠøсŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1255"/>
+ <source>IP Address: %ls
+MAC Address: %RTmac
+State: %ls
+Issued: %s (%RU64)
+Expire: %s (%RU64)
+TTL: %RU64 sec, currently %RU64 sec left
+</source>
+ <translation>IP Š°Š“рŠµŃ: %ls
+MAC Š°Š“рŠµŃ: %RTmac
+Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %ls
+Š’Ń‹Š“Š°Š½: %s (%RU64)
+Š˜ŃŃ‚ŠµŠŗŠ°ŠµŃ‚: %s (%RU64)
+TTL: %RU64 сŠµŠŗ, сŠµŠ¹Ń‡Š°Ń %RU64 сŠµŠŗ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ
+</translation>
+ </message>
+</context>
+<context>
+ <name>DebugVM</name>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="115"/>
+ <source>The getregisters sub-command takes at least one register name</source>
+ <translation>ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š° getregisters ŠæрŠøŠ½ŠøŠ¼Š°ŠµŃ‚ ŠøŠ¼Ń ŠŗŠ°Šŗ Š¼ŠøŠ½ŠøŠ¼ŃƒŠ¼ Š¾Š“Š½Š¾Š³Š¾ рŠµŠ³ŠøстрŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="156"/>
+ <source>Must specify info item to display</source>
+ <translation>ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ эŠ»ŠµŠ¼ŠµŠ½Ń‚ Š“Š»Ń Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="303"/>
+ <source>The --compression option has already been given</source>
+ <translation>ŠžŠæцŠøя --compression уŠ¶Šµ ŠæрŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="308"/>
+ <source>The --filename option has already been given</source>
+ <translation>ŠžŠæцŠøя --filename уŠ¶Šµ ŠæрŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="317"/>
+ <source>The --filename option is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся Š¾ŠæцŠøя --filename</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="325"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTPathAbs Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="351"/>
+ <source>Detected: %ls
+</source>
+ <translation>ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Š¾: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="371"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="372"/>
+ <source>Version: %ls
+</source>
+ <translation>Š’ŠµŃ€ŃŠøя: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="450"/>
+ <source>setregisters expects input on the form &apos;register=value&apos; got &apos;%s&apos;</source>
+ <translation>setregisters Š¾Š¶ŠøŠ“Š°ŠµŃ‚ Š²Ń…Š¾Š“Š½Ń‹Ń… Š“Š°Š½Š½Ń‹Ń… Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;рŠµŠ³Šøстр=Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ&apos;, ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="462"/>
+ <source>Out of memory
+</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="474"/>
+ <source>The setregisters sub-command takes at least one register name</source>
+ <translation>ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š° setregisters ŠæрŠøŠ½ŠøŠ¼Š°ŠµŃ‚ ŠøŠ¼Ń ŠŗŠ°Šŗ Š¼ŠøŠ½ŠøŠ¼ŃƒŠ¼ Š¾Š“Š½Š¾Š³Š¾ рŠµŠ³ŠøстрŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="483"/>
+ <source>Successfully set %ls
+</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ устŠ°Š½Š¾Š²Š»ŠµŠ½ %ls
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDebugVM.cpp" line="489"/>
+ <source>Successfully set %u registers
+</source>
+ <translation>
+ <numerusform>Š£ŃŠæŠµŃˆŠ½Š¾ устŠ°Š½Š¾Š²Š»ŠµŠ½Š¾ %u рŠµŠ³Šøстр
+</numerusform>
+ <numerusform>Š£ŃŠæŠµŃˆŠ½Š¾ устŠ°Š½Š¾Š²Š»ŠµŠ½Š¾ %u рŠµŠ³ŠøстрŠ°
+</numerusform>
+ <numerusform>Š£ŃŠæŠµŃˆŠ½Š¾ устŠ°Š½Š¾Š²Š»ŠµŠ½Š¾ %u рŠµŠ³ŠøстрŠ¾Š²
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="516"/>
+ <source>export %s=&apos;%ls&apos;
+</source>
+ <translation>export %s=&apos;%ls&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="518"/>
+ <source>set %s=%ls
+</source>
+ <translation>set %s=%ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="533"/>
+ <source>Debug logger settings:
+</source>
+ <translation>ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š¶ŃƒŃ€Š½Š°Š»ŠøрŠ¾Š²Š°Š½Šøя (Š¾Ń‚Š»Š°Š“ŠŗŠ°):
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="557"/>
+ <source>Release logger settings:
+</source>
+ <translation>ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š¶ŃƒŃ€Š½Š°Š»ŠøрŠ¾Š²Š°Š½Šøя (рŠµŠ»ŠøŠ·):
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="631"/>
+ <source>The show sub-command has no idea what &apos;%s&apos; might be</source>
+ <translation>Š£ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“ы show Š½ŠµŃ‚ ŠøŠ“ŠµŠ¹ чтŠ¾ этŠ¾ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ - &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="705"/>
+ <source>====================== CPU #%u ======================
+</source>
+ <translation>====================== Š¦ŠŸŠ£ #%u ======================
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="752"/>
+ <source>Multiple --pattern options are not permitted</source>
+ <translation>ŠœŠ½Š¾Š¶ŠµŃŃ‚Š²ŠµŠ½Š½Ń‹Šµ Š¾ŠæцŠøŠø --pattern Š½Šµ рŠ°Š·Ń€ŠµŃˆŠ°ŃŽŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="766"/>
+ <source>The --reset and --descriptions options does not mix</source>
+ <translation>ŠžŠæцŠøŠø --reset Šø --descriptions Š½Šµ сŠ¼ŠµŃˆŠøŠ²Š°ŃŽŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="836"/>
+ <source>The --filename is missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ --filename</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="960"/>
+ <source>Machine &apos;%s&apos; is not currently running.
+</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° &apos;%s&apos; сŠµŠ¹Ń‡Š°Ń Š½Šµ Š·Š°ŠæущŠµŠ½Š°.
+</translation>
+ </message>
+</context>
+<context>
+ <name>Disk</name>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="64"/>
+ <source>Error code %Rrc at %s(%u) in function %s</source>
+ <translation>ŠšŠ¾Š“ Š¾ŃˆŠøŠ±ŠŗŠø %Rrc Š² %s(%u) Š² фуŠ½ŠŗцŠøŠø %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="184"/>
+ <location filename="../VBoxManageDisk.cpp" line="219"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ ŠøŠ¼Ń фŠ°Š¹Š»Š° &quot;%s&quot; Š² Š°Š±ŃŠ¾Š»ŃŽŃ‚Š½Ń‹Š¹ Šæуть</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="288"/>
+ <source>Out of memory copying &apos;%s&apos;</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń ŠŗŠ¾ŠæŠøрŠ¾Š²Š°Š½Šøя &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="328"/>
+ <location filename="../VBoxManageDisk.cpp" line="334"/>
+ <location filename="../VBoxManageDisk.cpp" line="340"/>
+ <location filename="../VBoxManageDisk.cpp" line="699"/>
+ <location filename="../VBoxManageDisk.cpp" line="705"/>
+ <location filename="../VBoxManageDisk.cpp" line="711"/>
+ <location filename="../VBoxManageDisk.cpp" line="1025"/>
+ <location filename="../VBoxManageDisk.cpp" line="1031"/>
+ <location filename="../VBoxManageDisk.cpp" line="1037"/>
+ <location filename="../VBoxManageDisk.cpp" line="1660"/>
+ <location filename="../VBoxManageDisk.cpp" line="1666"/>
+ <location filename="../VBoxManageDisk.cpp" line="1672"/>
+ <location filename="../VBoxManageDisk.cpp" line="1772"/>
+ <location filename="../VBoxManageDisk.cpp" line="1778"/>
+ <location filename="../VBoxManageDisk.cpp" line="1784"/>
+ <source>Only one command can be specified: &apos;%s&apos;</source>
+ <translation>ŠœŠ¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½Š° тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š° ŠŗŠ¾Š¼Š°Š½Š“Š°: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="371"/>
+ <source>Invalid key value pair: No &apos;=&apos;.</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠæŠ°Ń€Š° ŠŗŠ»ŃŽŃ‡/Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ: ŠŠµŃ‚ &apos;=&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="387"/>
+ <source>Cannot open replacement value file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» с ŠæŠ¾Š“Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµŠ¼ &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="403"/>
+ <source>Error reading replacement MBR file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° чтŠµŠ½Šøя фŠ°Š¹Š»Š° с ŠæŠ¾Š“Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¼ MBR &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="406"/>
+ <source>Out of memory reading &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæрŠø чтŠµŠ½ŠøŠø &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="410"/>
+ <source>Replacement value file &apos;%s&apos; is to big: %Rhcb, max 16MiB</source>
+ <translation>Š¤Š°Š¹Š» с ŠæŠ¾Š“Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµŠ¼ &apos;%s&apos; сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Š¹: %Rhcb, Š¼Š°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ 16MiB</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="414"/>
+ <source>Cannot get the size of the value file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° &apos;%s&apos;, сŠ¾Š“ŠµŃ€Š¶Š°Ń‰ŠøŠ¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="433"/>
+ <location filename="../VBoxManageDisk.cpp" line="1060"/>
+ <location filename="../VBoxManageDisk.cpp" line="1245"/>
+ <location filename="../VBoxManageDisk.cpp" line="2585"/>
+ <source>Invalid medium variant &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š½Š¾ŃŠøтŠµŠ»Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="437"/>
+ <location filename="../VBoxManageDisk.cpp" line="799"/>
+ <location filename="../VBoxManageDisk.cpp" line="1069"/>
+ <location filename="../VBoxManageDisk.cpp" line="1261"/>
+ <location filename="../VBoxManageDisk.cpp" line="1680"/>
+ <location filename="../VBoxManageDisk.cpp" line="1796"/>
+ <location filename="../VBoxManageDisk.cpp" line="2008"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="443"/>
+ <location filename="../VBoxManageDisk.cpp" line="806"/>
+ <location filename="../VBoxManageDisk.cpp" line="1687"/>
+ <location filename="../VBoxManageDisk.cpp" line="1803"/>
+ <location filename="../VBoxManageDisk.cpp" line="2015"/>
+ <source>Invalid option -%c</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń Š¾ŠæцŠøя -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="445"/>
+ <location filename="../VBoxManageDisk.cpp" line="808"/>
+ <location filename="../VBoxManageDisk.cpp" line="1689"/>
+ <location filename="../VBoxManageDisk.cpp" line="1805"/>
+ <location filename="../VBoxManageDisk.cpp" line="2017"/>
+ <source>Invalid option case %i</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š¾ŠæцŠøŠø %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="448"/>
+ <location filename="../VBoxManageDisk.cpp" line="811"/>
+ <location filename="../VBoxManageDisk.cpp" line="1692"/>
+ <location filename="../VBoxManageDisk.cpp" line="1808"/>
+ <location filename="../VBoxManageDisk.cpp" line="2020"/>
+ <source>unknown option: %s
+</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="452"/>
+ <location filename="../VBoxManageDisk.cpp" line="815"/>
+ <location filename="../VBoxManageDisk.cpp" line="1085"/>
+ <location filename="../VBoxManageDisk.cpp" line="1696"/>
+ <location filename="../VBoxManageDisk.cpp" line="1812"/>
+ <location filename="../VBoxManageDisk.cpp" line="2024"/>
+ <source>error: %Rrs</source>
+ <translation>Š¾ŃˆŠøŠ±ŠŗŠ°: %Rrs</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="463"/>
+ <location filename="../VBoxManageDisk.cpp" line="483"/>
+ <source>Parameters --filename is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --filename</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="465"/>
+ <source>Parameters --size is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --size</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="486"/>
+ <source>Creating a differencing medium is only supported for hard disks</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ рŠ°Š·Š½Š¾ŃŃ‚Š½Š¾Š³Š¾ Š½Š¾ŃŠøтŠµŠ»Ń ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся тŠ¾Š»ŃŒŠŗŠ¾ Š“Š»Ń Š¶ŠµŃŃ‚ŠŗŠøх Š“ŠøсŠŗŠ¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="505"/>
+ <source>Invalid parent hard disk reference, avoiding crash</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ссыŠ»ŠŗŠ° Š½Š° рŠ¾Š“ŠøтŠµŠ»ŃŒŃŠŗŠøŠ¹ Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ, ŠæрŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‰ŠµŠ½ŠøŠµ ŠŗрŠ°Ń…Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="588"/>
+ <source>The %s is not found in the property list of the requested medium format.</source>
+ <translation>%s Š½Šµ Š½Š°Š¹Š“ŠµŠ½ Š² сŠæŠøсŠŗŠµ сŠ²Š¾Š¹ŃŃ‚Š² Š·Š°ŠæрŠ¾ŃˆŠµŠ½Š½Š¾Š³Š¾ фŠ¾Ń€Š¼Š°Ń‚Š° Š½Š¾ŃŠøтŠµŠ»Ń.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="598"/>
+ <source>Base64 encoding of the property %s failed. (%Rhrc)</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠŗŠ¾Š“ŠøрŠ¾Š²Š°Ń‚ŃŒ сŠ²Š¾Š¹ŃŃ‚Š²Š¾, ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃ Base64. (%Rhrc)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="622"/>
+ <source>Failed to create medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š½Š¾ŃŠøтŠµŠ»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="630"/>
+ <source>Medium created. UUID: %s
+</source>
+ <translation>ŠŠ¾ŃŠøтŠµŠ»ŃŒ сŠ¾Š·Š“Š°Š½. UUID: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="718"/>
+ <source>Invalid medium type &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ Š½Š¾ŃŠøтŠµŠ»Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="725"/>
+ <source>Invalid autoreset parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ Š°Š²Ń‚Š¾ŃŠ±Ń€Š¾ŃŠ° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="748"/>
+ <source>Invalid --property argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --property &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="755"/>
+ <source>Error: Failed to allocate memory for medium property &apos;%s&apos;
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ°: ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ Š“Š»Ń сŠ²Š¾Š¹ŃŃ‚Š²Š° Š½Š¾ŃŠøтŠµŠ»Ń &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="823"/>
+ <location filename="../VBoxManageDisk.cpp" line="1705"/>
+ <location filename="../VBoxManageDisk.cpp" line="1820"/>
+ <source>Medium name or UUID required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠøŠ¼Ń ŠøŠ»Šø UUID Š½Š¾ŃŠøтŠµŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="834"/>
+ <source>No operation specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° Š¾ŠæŠµŃ€Š°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="855"/>
+ <source>Invalid medium reference, avoiding crash</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ссыŠ»ŠŗŠ° Š½Š° Š½Š¾ŃŠøтŠµŠ»ŃŒ, ŠæрŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‰ŠµŠ½ŠøŠµ ŠŗрŠ°Ń…Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="876"/>
+ <source>Error: Attempt to resize the medium from %RU64.%RU64 MB to %RU64.%RU64 MB. Use --resizebyte if this is intended!
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ°: ŠŸŠ¾ŠæытŠŗŠ° ŠøŠ·Š¼ŠµŠ½Šøть рŠ°Š·Š¼ŠµŃ€ Š½Š¾ŃŠøтŠµŠ»Ń с %RU64.%RU64 MB Š² %RU64.%RU64 MB. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ --resizebyte, ŠµŃŠ»Šø этŠ¾ тŠ°Šŗ Šø Š“Š¾Š»Š¶Š½Š¾ Š±Ń‹Ń‚ŃŒ!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="910"/>
+ <source>Compact medium operation is not implemented!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя сŠ¶Š°Ń‚Šøя Š½Š¾ŃŠøтŠµŠ»Ń Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="912"/>
+ <source>Compact medium operation for this format is not implemented yet!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя сŠ¶Š°Ń‚Šøя Š½Š¾ŃŠøтŠµŠ»Ń Š“Š»Ń этŠ¾Š³Š¾ фŠ¾Ń€Š¼Š°Ń‚Š° ŠµŃ‰Šµ Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="914"/>
+ <source>Failed to compact medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¶Š°Ń‚ŃŒ Š½Š¾ŃŠøтŠµŠ»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="916"/>
+ <source>Failed to compact medium!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¶Š°Ń‚ŃŒ Š½Š¾ŃŠøтŠµŠ»ŃŒ!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="929"/>
+ <source>Failed to resize medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠøŠ·Š¼ŠµŠ½Šøть рŠ°Š·Š¼ŠµŃ€ Š½Š¾ŃŠøтŠµŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="931"/>
+ <source>Resize medium operation is not implemented!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя ŠøŠ·Š¼ŠµŠ½ŠµŠ½Šøя рŠ°Š·Š¼ŠµŃ€Š° Š½Š¾ŃŠøтŠµŠ»Ń Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="933"/>
+ <source>Resize medium operation for this format is not implemented yet!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя ŠøŠ·Š¼ŠµŠ½ŠµŠ½Šøя рŠ°Š·Š¼ŠµŃ€Š° Š½Š¾ŃŠøтŠµŠ»Ń Š“Š»Ń этŠ¾Š³Š¾ фŠ¾Ń€Š¼Š°Ń‚Š° ŠµŃ‰Šµ Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="935"/>
+ <source>Failed to resize medium!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠøŠ·Š¼ŠµŠ½Šøть рŠ°Š·Š¼ŠµŃ€ Š½Š¾ŃŠøтŠµŠ»Ń!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="951"/>
+ <source>Failed to move medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŠ¼ŠµŃŃ‚Šøть Š½Š¾ŃŠøтŠµŠ»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="957"/>
+ <source>Move medium with UUID %s finished
+</source>
+ <translation>ŠŸŠµŃ€ŠµŠ¼ŠµŃ‰ŠµŠ½ŠøŠµ Š½Š¾ŃŠøтŠµŠ»Ń с UUID %s Š·Š°ŠŗŠ¾Š½Ń‡ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="970"/>
+ <source>Set new location of medium with UUID %s finished
+</source>
+ <translation>Š£ŃŃ‚Š°Š½Š¾Š²ŠŗŠ° Š½Š¾Š²Š¾Š³Š¾ Š¼ŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½Šøя Š½Š¾ŃŠøтŠµŠ»Ń с UUID %s Š·Š°ŠŗŠ¾Š½Ń‡ŠµŠ½Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="977"/>
+ <source>Medium description has been changed.
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ Š½Š¾ŃŠøтŠµŠ»Ń ŠøŠ·Š¼ŠµŠ½ŠµŠ½Š¾.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1076"/>
+ <source>unhandled option: -%c</source>
+ <translation>Š½ŠµŠ¾Š±Ń€Š°Š±Š¾Ń‚Š°Š½Š½Š°Ń Š¾ŠæцŠøя: -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1078"/>
+ <source>unhandled option: %i</source>
+ <translation>Š½ŠµŠ¾Š±Ń€Š°Š±Š¾Ń‚Š°Š½Š½Š°Ń Š¾ŠæцŠøя: %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1081"/>
+ <source>unknown option: %s</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1092"/>
+ <source>Mandatory UUID or input file parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: ŠøŠ»Šø UUID ŠøŠ»Šø Š²Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1094"/>
+ <source>Mandatory output file parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1096"/>
+ <source>Specified options which cannot be used with --existing</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š° Š¾ŠæцŠøя, ŠŗŠ¾Ń‚Š¾Ń€Š°Ń Š½Šµ Š¼Š¾Š¶ŠµŃ‚ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ с --existing</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1184"/>
+ <source>Failed to clone medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Ń‚ŃŒ Š½Š¾ŃŠøтŠµŠ»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1189"/>
+ <source>Clone medium created in format &apos;%ls&apos;. UUID: %s
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ Š½Š¾ŃŠøтŠµŠ»ŃŒ Š² фŠ¾Ń€Š¼Š°Ń‚Šµ &apos;%ls&apos;. UUID: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1233"/>
+ <source>Invalid UUID &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ UUID &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1270"/>
+ <source>Incorrect number of parameters</source>
+ <translation>ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1271"/>
+ <source>Converting from raw image file=&quot;%s&quot; to file=&quot;%s&quot;...
+</source>
+ <translation>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ ŠøŠ· фŠ°Š¹Š»Š° raw Š¾Š±Ń€Š°Š·Š° =&quot;%s&quot; Š² фŠ°Š¹Š» =&quot;%s&quot;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1293"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1305"/>
+ <source>Cannot get image size for file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ Š¾Š±Ń€Š°Š·Š° Š“Š»Ń фŠ°Š¹Š»Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="1309"/>
+ <source>Creating %s image with size %RU64 bytes (%RU64MB)...
+</source>
+ <translation>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %s Š¾Š±Ń€Š°Š·Š° рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB)...
+</numerusform>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %s Š¾Š±Ń€Š°Š·Š° рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚Š° (%RU64MB)...
+</numerusform>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %s Š¾Š±Ń€Š°Š·Š° рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB)...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1518"/>
+ <source>fixed</source>
+ <translation>фŠøŠŗсŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1516"/>
+ <source>dynamic</source>
+ <translation>Š“ŠøŠ½Š°Š¼ŠøчŠµŃŠŗŠøŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1310"/>
+ <source>fixed</source>
+ <comment>adjective</comment>
+ <translation>фŠøŠŗсŠøрŠ¾Š²Š°Š½Š½Š¾Š³Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1310"/>
+ <source>dynamic</source>
+ <comment>adjective</comment>
+ <translation>Š“ŠøŠ½Š°Š¼ŠøчŠµŃŠŗŠ¾Š³Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1313"/>
+ <source>Converted image from %s</source>
+ <translation>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ Š¾Š±Ń€Š°Š· ŠøŠ· %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1317"/>
+ <source>Cannot create the virtual disk container: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1335"/>
+ <source>Cannot create the disk image &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±Ń€Š°Š· Š“ŠøсŠŗŠ° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1345"/>
+ <source>Out of memory allocating buffers for image &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š±ŃƒŃ„ŠµŃ€Š¾Š² Š“Š»Ń Š¾Š±Ń€Š°Š·Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1364"/>
+ <source>Failed to write to disk image &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæŠøсŠ°Ń‚ŃŒ Š² Š¾Š±Ń€Š°Š· Š“ŠøсŠŗŠ° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1393"/>
+ <source>Parent UUID: %s
+</source>
+ <translation>Š Š¾Š“ŠøтŠµŠ»ŃŒŃŠŗŠøŠ¹ UUID: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1398"/>
+ <location filename="../VBoxManageDisk.cpp" line="1445"/>
+ <location filename="../VBoxManageDisk.cpp" line="1500"/>
+ <source>unknown</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1402"/>
+ <source>not created</source>
+ <translation>Š½Šµ сŠ¾Š·Š“Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1405"/>
+ <source>created</source>
+ <translation>сŠ¾Š·Š“Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1408"/>
+ <source>locked read</source>
+ <translation>Š·Š°Š±Š»Š¾ŠŗŠøрŠ¾Š²Š°Š½ Š½Š° чтŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1411"/>
+ <source>locked write</source>
+ <translation>Š·Š°Š±Š»Š¾ŠŗŠøрŠ¾Š²Š°Š½ Š½Š° Š·Š°ŠæŠøсь</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1414"/>
+ <source>inaccessible</source>
+ <translation>Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1417"/>
+ <source>creating</source>
+ <translation>сŠ¾Š·Š“Š°Š½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1420"/>
+ <source>deleting</source>
+ <translation>уŠ“Š°Š»ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1426"/>
+ <source>State: %s
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1432"/>
+ <source>Access Error: %ls
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° Š“Š¾ŃŃ‚ŃƒŠæŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1440"/>
+ <source>Description: %ls
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1450"/>
+ <source>normal (differencing)</source>
+ <translation>Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Ń‹Š¹ (рŠ°Š·Š½Š¾ŃŃ‚Š½Ń‹Š¹)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1452"/>
+ <source>normal (base)</source>
+ <translation>Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Ń‹Š¹ (Š±Š°Š·Š¾Š²Ń‹Š¹)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1455"/>
+ <source>immutable</source>
+ <translation>Š½ŠµŠøŠ·Š¼ŠµŠ½ŃŠµŠ¼Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1458"/>
+ <source>writethrough</source>
+ <translation>сŠŗŠ²Š¾Š·Š½Š°Ń Š·Š°ŠæŠøсь</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1461"/>
+ <source>shareable</source>
+ <translation>рŠ°Š·Š“ŠµŠ»ŃŠµŠ¼Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1464"/>
+ <source>readonly</source>
+ <translation>тŠ¾Š»ŃŒŠŗŠ¾ Š“Š»Ń чтŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1467"/>
+ <source>multiattach</source>
+ <translation>Š¼Š½Š¾Š¶ŠµŃŃ‚Š²ŠµŠ½Š½Š¾Šµ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1473"/>
+ <source>Type: %s
+</source>
+ <translation>Š¢ŠøŠæ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>Auto-Reset: %s
+</source>
+ <translation>ŠŠ²Ń‚Š¾ŃŠ±Ń€Š¾Ń: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>on</source>
+ <translation>Š²ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>off</source>
+ <translation>Š²Ń‹ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1485"/>
+ <source>Location: %ls
+</source>
+ <translation>Š Š°ŃŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1489"/>
+ <source>Storage format: %ls
+</source>
+ <translation>Š¤Š¾Ń€Š¼Š°Ń‚ хрŠ°Š½ŠµŠ½Šøя: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1504"/>
+ <source>split2G</source>
+ <translation>Š”ŠµŠ»Šøть ŠæŠ¾ 2G</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1507"/>
+ <source>streamOptimized</source>
+ <translation>Š¾ŠæтŠøŠ¼ŠøŠ·ŠøрŠ¾Š²Š°Š½ Š“Š»Ń ŠæŠ¾Ń‚Š¾ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1510"/>
+ <source>ESX</source>
+ <translation>ESX</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1513"/>
+ <source>default</source>
+ <translation>ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1520"/>
+ <source>differencing</source>
+ <translation>рŠ°Š·Š½Š¾ŃŃ‚Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1521"/>
+ <source>Format variant: %s %s
+</source>
+ <translation>Š’Š°Ń€ŠøŠ°Š½Ń‚ фŠ¾Ń€Š¼Š°Ń‚Š°: %s %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1526"/>
+ <source>Capacity: %lld MBytes
+</source>
+ <translation>Š•Š¼ŠŗŠ¾ŃŃ‚ŃŒ: %lld MB
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1531"/>
+ <source>Size on disk: %lld MBytes
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ Š½Š° Š“ŠøсŠŗŠµ: %lld MB
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1539"/>
+ <source>Encryption: enabled
+</source>
+ <translation>ŠØŠøфрŠ¾Š²Š°Š½ŠøŠµ: Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1542"/>
+ <source>Cipher: %ls
+</source>
+ <translation>ŠØŠøфр: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1543"/>
+ <source>Password ID: %ls
+</source>
+ <translation>ID ŠæŠ°Ń€Š¾Š»Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1547"/>
+ <source>Encryption: disabled
+</source>
+ <translation>ŠØŠøфрŠ¾Š²Š°Š½ŠøŠµ: Š²Ń‹ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1563"/>
+ <source>Property: </source>
+ <translation>Š”Š²Š¾Š¹ŃŃ‚Š²Š¾: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1584"/>
+ <source>In use by VMs: </source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся Š² Š’Šœ: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1619"/>
+ <source>Child UUIDs: </source>
+ <translation>Š”Š¾Ń‡ŠµŃ€Š½ŠøŠµ UUID: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1725"/>
+ <source>base</source>
+ <translation>Š±Š°Š·Š¾Š²Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1845"/>
+ <source>Failed to delete medium</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š½Š¾ŃŠøтŠµŠ»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1848"/>
+ <source>Failed to delete medium. Error code %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š½Š¾ŃŠøтŠµŠ»ŃŒ. ŠšŠ¾Š“ Š¾ŃˆŠøŠ±ŠŗŠø %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1884"/>
+ <source>unexpected parameter %s
+</source>
+ <translation>Š½ŠµŠ¾Š¶ŠøŠ“Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1897"/>
+ <source>Missing action</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š“ŠµŠ¹ŃŃ‚Š²ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1903"/>
+ <source>Invalid action given: %s</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š¾ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š“ŠµŠ¹ŃŃ‚Š²ŠøŠµ: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1909"/>
+ <source>Invalid number of arguments given for action: %s</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ чŠøсŠ»Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š², уŠŗŠ°Š·Š°Š½Š½Š¾Šµ Š“Š»Ń Š“ŠµŠ¹ŃŃ‚Š²Šøя: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2029"/>
+ <source>Disk name or UUID required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠøŠ¼Ń ŠøŠ»Šø UUID Š“ŠøсŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2032"/>
+ <source>No password specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ŠæŠ°Ń€Š¾Š»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2036"/>
+ <source>A new password must always have a valid identifier set at the same time</source>
+ <translation>ŠŠ¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š¾Š»Š¶ŠµŠ½ Š²ŃŠµŠ³Š“Š° ŠøŠ¼ŠµŃ‚ŃŒ Š“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹ ŠøŠ“ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń‚Š¾Ń€ Š·Š°Š“Š°Š½Š½Ń‹Š¹ Š² тŠ¾ Š¶Šµ Š²Ń€ŠµŠ¼Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2043"/>
+ <source>Enter new password:</source>
+ <translation>Š’Š²ŠµŠ“ŠøтŠµ Š½Š¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2052"/>
+ <source>Failed to read new password from file</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š½Š¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ ŠøŠ· фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2063"/>
+ <source>Enter old password:</source>
+ <translation>Š’Š²ŠµŠ“ŠøтŠµ стŠ°Ń€Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2072"/>
+ <source>Failed to read old password from file</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ стŠ°Ń€Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ ŠøŠ· фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2085"/>
+ <location filename="../VBoxManageDisk.cpp" line="2144"/>
+ <source>Invalid hard disk reference, avoiding crash</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ссыŠ»ŠŗŠ° Š½Š° Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ, ŠæрŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‰ŠµŠ½ŠøŠµ ŠŗрŠ°Ń…Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2096"/>
+ <source>Encrypt hard disk operation is not implemented!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя шŠøфрŠ¾Š²Š°Š½Šøя Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ° Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2098"/>
+ <source>Encrypt hard disk operation for this cipher is not implemented yet!</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†Šøя шфŠøрŠ¾Š²Š°Š½Šøя Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ° Š“Š»Ń этŠ¾Š³Š¾ шŠøфрŠ° ŠµŃ‰Šµ Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2100"/>
+ <source>Failed to encrypt hard disk</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŃˆŠøфрŠ¾Š²Š°Ń‚ŃŒ Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2102"/>
+ <source>Failed to encrypt hard disk!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŃˆŠøфрŠ¾Š²Š°Ń‚ŃŒ Š¶ŠµŃŃ‚ŠŗŠøŠ¹ Š“ŠøсŠŗ!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2116"/>
+ <source>Invalid number of arguments: %d</source>
+ <translation>ŠŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š²: %d</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2123"/>
+ <source>Enter password:</source>
+ <translation>Š’Š²ŠµŠ“ŠøтŠµ ŠæŠ°Ń€Š¾Š»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2132"/>
+ <source>Failed to read password from file</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ ŠøŠ· фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2148"/>
+ <source>The given password is correct
+</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ - ŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Ń‹Š¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2226"/>
+ <source>No medium specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ Š½Š¾ŃŠøтŠµŠ»ŃŒ!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2237"/>
+ <source>Enter encryption password:</source>
+ <translation>Š’Š²ŠµŠ“ŠøтŠµ ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š»Ń шŠøфрŠ¾Š²Š°Š½Šøя:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2389"/>
+ <location filename="../VBoxManageDisk.cpp" line="2610"/>
+ <source>Error opening &apos;%s&apos; for writing: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Ń‚Šŗрыть &apos;%s&apos; Š“Š»Ń Š·Š°ŠæŠøсŠø: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2405"/>
+ <source>Specified offset (%#RX64) is beyond the end of the medium (%#RX64)</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š½Š°Ń ŠæŠ¾Š·ŠøцŠøя (%#RX64) Š²Ń‹Ń…Š¾Š“Šøт Š·Š° Š³Ń€Š°Š½Šøцу Š½Š¾ŃŠøтŠµŠ»Ń (%#RX64)</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="2435"/>
+ <source>Read(%zu bytes at %#RX64)</source>
+ <translation>
+ <numerusform>Š§Ń‚ŠµŠ½ŠøŠµ (%zu Š±Š°Š¹Ń‚, ŠæŠ¾Š·ŠøцŠøя %#RX64)</numerusform>
+ <numerusform>Š§Ń‚ŠµŠ½ŠøŠµ (%zu Š±Š°Š¹Ń‚Š°, ŠæŠ¾Š·ŠøцŠøя %#RX64)</numerusform>
+ <numerusform>Š§Ń‚ŠµŠ½ŠøŠµ (%zu Š±Š°Š¹Ń‚, ŠæŠ¾Š·ŠøцŠøя %#RX64)</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2464"/>
+ <source>********** &lt;ditto x %RU64&gt;
+</source>
+ <translation>********** &lt;тŠ¾ Š¶Šµ сŠ°Š¼Š¾Šµ x %RU64&gt;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2513"/>
+ <location filename="../VBoxManageDisk.cpp" line="2654"/>
+ <source>Error writing to &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø Š·Š°ŠæŠøсŠø Š² &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="2521"/>
+ <source>Expected read() at offset %RU64 (%#RX64) to return %#zx bytes, only got %#zx!
+</source>
+ <translation>
+ <numerusform>ŠžŠ¶ŠøŠ“Š°Š»Š¾ŃŃŒ read() с ŠæŠ¾Š·Ń†ŠøŠø %RU64 (%#RX64) ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ %#zx Š±Š°Š¹Ń‚, ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ %#zx!
+</numerusform>
+ <numerusform>ŠžŠ¶ŠøŠ“Š°Š»Š¾ŃŃŒ read() с ŠæŠ¾Š·Ń†ŠøŠø %RU64 (%#RX64) ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ %#zx Š±Š°Š¹Ń‚Š°, ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ %#zx!
+</numerusform>
+ <numerusform>ŠžŠ¶ŠøŠ“Š°Š»Š¾ŃŃŒ read() с ŠæŠ¾Š·Ń†ŠøŠø %RU64 (%#RX64) ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ %#zx Š±Š°Š¹Ń‚, ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ %#zx!
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2537"/>
+ <location filename="../VBoxManageDisk.cpp" line="2675"/>
+ <source>Error closing &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø Š·Š°ŠŗрытŠøŠø &apos;%s&apos;: %Rrc</translation>
+ </message>
+</context>
+<context>
+ <name>GuestCtrl</name>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="276"/>
+ <source>Unable to install console control handler, rc=%Rrc
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ устŠ°Š½Š¾Š²Šøть Š¾Š±Ń€Š°Š±Š¾Ń‚чŠøŠŗ уŠæрŠ°Š²Š»ŠµŠ½Šøя ŠŗŠ¾Š½ŃŠ¾Š»Šø, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="303"/>
+ <source>Unable to uninstall console control handler, rc=%Rrc
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ уŠ“Š°Š»Šøть Š¾Š±Ń€Š°Š±Š¾Ń‚чŠøŠŗ уŠæрŠ°Š²Š»ŠµŠ½Šøя ŠŗŠ¾Š½ŃŠ¾Š»Šø, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="332"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="398"/>
+ <source>starting</source>
+ <translation>Š·Š°ŠæусŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="334"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="367"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="400"/>
+ <source>started</source>
+ <translation>Š·Š°ŠæущŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="336"/>
+ <source>paused</source>
+ <translation>ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="338"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="402"/>
+ <source>terminating</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="340"/>
+ <source>successfully terminated</source>
+ <translation>усŠæŠµŃˆŠ½Š¾ Š·Š°Š²ŠµŃ€ŃˆŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="342"/>
+ <source>terminated by signal</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ ŠæŠ¾ сŠøŠ³Š½Š°Š»Ńƒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="344"/>
+ <source>abnormally aborted</source>
+ <translation>Š½ŠµŠ½Š¾Ń€Š¼Š°Š»ŃŒŠ½Š¾ ŠæрŠµŃ€Š²Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="346"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="375"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="406"/>
+ <source>timed out</source>
+ <translation>ŠæрŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="348"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="408"/>
+ <source>timed out, hanging</source>
+ <translation>ŠæрŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя, Š·Š°Š²Šøс</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="350"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="410"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="435"/>
+ <source>killed</source>
+ <translation>уŠ±Šøт</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="352"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="373"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="412"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="437"/>
+ <source>error</source>
+ <translation>Š¾ŃˆŠøŠ±ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="356"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="387"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="416"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="441"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="451"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="464"/>
+ <source>unknown</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="369"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="404"/>
+ <source>terminated</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="371"/>
+ <source>status changed</source>
+ <translation>стŠ°Ń‚ŃƒŃ ŠøŠ·Š¼ŠµŠ½ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="377"/>
+ <source>stdin ready</source>
+ <translation>stdin Š³Š¾Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="379"/>
+ <source>data on stdout</source>
+ <translation>Š“Š°Š½Š½Ń‹Šµ Š² stdout</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="381"/>
+ <source>data on stderr</source>
+ <translation>Š“Š°Š½Š½Ń‹Šµ Š² stderr</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="383"/>
+ <source>waiting flag not supported</source>
+ <translation>фŠ»Š°Š³ Š¾Š¶ŠøŠ“Š°Š½Šøя Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="427"/>
+ <source>opening</source>
+ <translation>Š¾Ń‚ŠŗрыŠ²Š°ŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="429"/>
+ <source>open</source>
+ <translation>Š¾Ń‚Šŗрыт</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="431"/>
+ <source>closing</source>
+ <translation>Š·Š°ŠŗрыŠ²Š°ŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="433"/>
+ <source>closed</source>
+ <translation>Š·Š°Šŗрыт</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="452"/>
+ <source>fifo</source>
+ <translation>fifo</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="453"/>
+ <source>char-device</source>
+ <translation>сŠøŠ¼Š²Š¾Š»ŃŒŠ½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="454"/>
+ <source>directory</source>
+ <translation>Š“ŠøрŠµŠŗтŠ¾Ń€Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="455"/>
+ <source>block-device</source>
+ <translation>Š±Š»Š¾Ń‡Š½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="456"/>
+ <source>file</source>
+ <translation>фŠ°Š¹Š»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="457"/>
+ <source>symlink</source>
+ <translation>сŠøŠ²Š¾Š»ŠøчŠµŃŠŗŠ°Ń ссыŠ»ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="458"/>
+ <source>socket</source>
+ <translation>сŠ¾ŠŗŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="459"/>
+ <source>white-out</source>
+ <translation>white-out</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="478"/>
+ <source>Error details:</source>
+ <translation>ŠŸŠ¾Š“рŠ¾Š±Š½Š¾ŃŃ‚Šø Š¾ŃˆŠøŠ±ŠŗŠø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="483"/>
+ <source>Object has indicated no error (%Rhrc)!?
+</source>
+ <translation>ŠžŠ±ŃŠŠµŠŗт Š½Šµ ŠæŠ¾ŠŗŠ°Š·Š°Š» Š¾ŃˆŠøŠ±ŠŗŠø (%Rhrc)!?
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="515"/>
+ <source>Could not lookup progress information
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š¾ ŠæрŠ¾Š³Ń€ŠµŃŃŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="574"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3247"/>
+ <source>Out of memory</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="602"/>
+ <source>The --username|-u option is ignored by &apos;%s&apos;</source>
+ <translation>ŠžŠæцŠøя --username|-u ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="609"/>
+ <source>Password is given more than once.</source>
+ <translation>ŠŸŠ°Ń€Š¾Š»ŃŒ уŠŗŠ°Š·Š°Š½ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="613"/>
+ <source>The --password option is ignored by &apos;%s&apos;</source>
+ <translation>ŠžŠæцŠøя --password ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="620"/>
+ <source>The --password-file|-p option is ignored by &apos;%s&apos;</source>
+ <translation>ŠžŠæцŠøя --password-file|-p ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="627"/>
+ <source>The --domain option is ignored by &apos;%s&apos;</source>
+ <translation>ŠžŠæцŠø --domain ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Š½Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="692"/>
+ <source>Failed to get a IConsole pointer for the machine. Is it still running?
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть уŠŗŠ°Š·Š°Ń‚ŠµŠ»ŃŒ Š½Š° IConsole Š“Š»Ń Š¼Š°ŃˆŠøŠ½Ń‹. ŠžŠ½Š° Š²ŃŠµ ŠµŃ‰Šµ рŠ°Š±Š¾Ń‚Š°ŠµŃ‚?
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="697"/>
+ <source>Machine &quot;%s&quot; is not running (currently %s)!
+</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° &quot;%s&quot; Š½Šµ Š·Š°ŠæущŠµŠ½Š° (тŠµŠŗущŠøŠ¹: %s)!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="726"/>
+ <source>[%RU32] VBoxManage Guest Control [%s] - %s</source>
+ <translation>[%RU32] VBoxManage Š“Š¾ŃŃ‚ŠµŠ²Š¾Šµ Š£ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ [%s] - %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="728"/>
+ <source>No enough memory for session name</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń ŠøŠ¼ŠµŠ½Šø сŠµŃŃŠøŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="734"/>
+ <source>Creating guest session as user &apos;%s&apos;...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠµŃŃŠøŠø ŠæŠ¾Š“ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¼ &apos;%s&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="745"/>
+ <source>Out of memory setting up IGuest::CreateSession call</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š²Ń‹Š·Š¾Š²Š° IGuest::CreateSession</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="754"/>
+ <source>Waiting for guest session to start...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ стŠ°Ń€Ń‚Š° Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠµŃŃŠøŠø...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="766"/>
+ <source>Out of memory setting up IGuestSession::WaitForArray call</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š²Ń‹Š·Š¾Š²Š° IGuestSession::WaitForArray</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="782"/>
+ <source>Successfully started guest session (ID %RU32)
+</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ Š·Š°ŠæущŠµŠ½Š° Š³Š¾ŃŃ‚ŠµŠ²Š°Ń сŠµŃŃŠøя (ID %RU32)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="791"/>
+ <source>Error starting guest session (current status is: %s)
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° Š²Š¾ Š²Ń€ŠµŠ¼Ń стŠ°Ń€Ń‚Š° Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠµŃŃŠøŠø (тŠµŠŗущŠøŠ¹ стŠ°Ń‚ŃƒŃ: %s)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="792"/>
+ <source>&lt;unknown&gt;</source>
+ <translation>&lt;Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾&gt;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="851"/>
+ <source>No user name specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="891"/>
+ <source>Closing guest session ...
+</source>
+ <translation>Š—Š°ŠŗрытŠøŠµ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠµŃŃŠøŠø ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="897"/>
+ <source>Guest session detached
+</source>
+ <translation>Š“Š¾ŃŃ‚ŠµŠ²Š°Ń сŠµŃŃŠøя Š¾Ń‚сŠ¾ŠµŠ“ŠøŠ½ŠµŠ½Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1058"/>
+ <source>Unable to write output, rc=%Rrc
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š·Š°ŠæŠøсŠ°Ń‚ŃŒ Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ ŠæŠ¾Ń‚Š¾Šŗ, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1088"/>
+ <source>Unsupported %s line ending conversion</source>
+ <translation>ŠŠµŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Š¾Šµ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ %s Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Šøя стрŠ¾ŠŗŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1093"/>
+ <source>Error getting %s handle: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŠø %s Š¾Š±Ń€Š°Š±Š¾Ń‚чŠøŠŗŠ°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1216"/>
+ <source>Invalid argument variable[=value]: &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠæŠµŃ€ŠµŠ¼ŠµŠ½Š½Š°Ń Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š°[=Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ]: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1226"/>
+ <source>Warning: Deprecated option &quot;--no-profile&quot; specified
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: Š£ŠŗŠ°Š·Š°Š½Š° устŠ°Ń€ŠµŠ²ŃˆŠ°Ń Š¾ŠæцŠøя &quot;--no-profile&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1292"/>
+ <source>No executable specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ Š²Ń‹ŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ фŠ°Š¹Š»!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1344"/>
+ <source>Starting guest process ...
+</source>
+ <translation>Š”тŠ°Ń€Ń‚ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š³Š¾ ŠæрŠ¾Ń†ŠµŃŃŠ°...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1346"/>
+ <source>Starting guest process (within %ums)
+</source>
+ <translation>Š”тŠ°Ń€Ń‚ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š³Š¾ ŠæрŠ¾Ń†ŠµŃŃŠ° (Š² тŠµŃ‡ŠµŠ½ŠøŠµ %u Š¼ŃŠµŠŗ)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1368"/>
+ <source>Process &apos;%s&apos; (PID %RU32) started
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ &apos;%s&apos; (PID %RU32) Š·Š°ŠæущŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1373"/>
+ <source>[%RU32 - Session %RU32]
+</source>
+ <translation>[%RU32 - Š”ŠµŃŃŠøя %RU32]
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1394"/>
+ <source>waitResult: %d
+</source>
+ <translation>рŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚ Š¾Š¶ŠøŠ“Š°Š½Šøя: %d
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1410"/>
+ <source>Process terminated
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ Š·Š°Š²ŠµŃ€ŃˆŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1487"/>
+ <source>Process execution aborted!
+</source>
+ <translation>Š’Ń‹ŠæŠ¾Š»Š½ŠµŠ½ŠøŠµ ŠæрŠ¾Ń†ŠµŃŃŠ° ŠæрŠµŃ€Š²Š°Š½Š¾!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1493"/>
+ <source>Process successfully started!
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ усŠæŠµŃˆŠ½Š¾ Š·Š°ŠæущŠµŠ½!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1507"/>
+ <source>Exit code=%u (Status=%u [%s])
+</source>
+ <translation>ŠšŠ¾Š“ Š²Ń‹Ń…Š¾Š“Š° =%u (Š”тŠ°Ń‚ŃƒŃ =%u [%s])
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1516"/>
+ <source>Process timed out (guest side) and %s
+</source>
+ <translation>ŠŸŃ€ŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя ŠæрŠ¾Ń†ŠµŃŃŠ° (Š³Š¾ŃŃ‚ŠµŠ²Š°Ń стŠ¾Ń€Š¾Š½Š°) Šø %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1518"/>
+ <source>failed to terminate so far</source>
+ <translation>Š½Šµ уŠ“Š°Š»Š¾ŃŃŒ Š“Š¾ сŠøх ŠæŠ¾Ń€ Š·Š°Š²ŠµŃ€ŃˆŠøть</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1518"/>
+ <source>was terminated</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1524"/>
+ <source>Process now is in status [%s] (unexpected)
+</source>
+ <translation>Š”ŠµŠ¹Ń‡Š°Ń ŠæрŠ¾Ń†ŠµŃŃ Š² стŠ°Ń‚ŃƒŃŠµ [%s] (Š½ŠµŠ¾Š¶ŠøŠ“Š°Š½Š½Š¾)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1532"/>
+ <source>Process monitor loop quit with vrc=%Rrc
+</source>
+ <translation>Š¦ŠøŠŗŠ» Š½Š°Š±Š»ŃŽŠ“ŠµŠ½Šøя Š·Š° ŠæрŠ¾Ń†ŠµŃŃŠ¾Š¼ Š·Š°ŠŗŠ¾Š½Ń‡ŠøŠ»ŃŃ с vrc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1538"/>
+ <source>Process monitor loop timed out
+</source>
+ <translation>ŠŸŃ€ŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя Š² цŠøŠŗŠ»Šµ Š½Š°Š±Š»ŃŽŠ“ŠµŠ½Šøя Š·Š° ŠæрŠ¾Ń†ŠµŃŃŠ¾Š¼
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1641"/>
+ <source>No sources specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ŠøстŠ¾Ń‡Š½ŠøŠŗ!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1649"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2201"/>
+ <source>No destination specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1658"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1762"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTPathAbs Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1671"/>
+ <source>Copying from host to guest ...
+</source>
+ <translation>ŠšŠ¾ŠæŠøрŠ¾Š²Š°Š½ŠøŠµ ŠøŠ· хŠ¾ŃŃ‚Š° Š² Š³Š¾ŃŃ‚ŠµŠ²ŃƒŃŽ сŠøстŠµŠ¼Ńƒ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1673"/>
+ <source>Copying from guest to host ...
+</source>
+ <translation>ŠšŠ¾ŠæŠøрŠ¾Š²Š°Š½ŠøŠµ ŠøŠ· Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹ Š² хŠ¾ŃŃ‚...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1735"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1796"/>
+ <source>File &apos;%s&apos; -&gt; &apos;%s&apos;
+</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; -&gt; &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1744"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1782"/>
+ <source>Directory &apos;%s&apos; -&gt; &apos;%s&apos;
+</source>
+ <translation>Š”ŠøрŠµŠŗтŠ¾Ń€Šøя &apos;%s&apos; -&gt; &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1756"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1805"/>
+ <source>Not a file or directory: %s
+</source>
+ <translation>ŠŠµ фŠ°Š¹Š» Šø Š½Šµ Š“ŠøрŠµŠŗтŠ¾Ń€Šøя: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1685"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1759"/>
+ <source>RTPathQueryInfo failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTPathQueryInfo Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1703"/>
+ <source>Destination must be a directory!</source>
+ <translation>ŠŠ°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š“Š¾Š»Š¶Š½Š¾ Š±Ń‹Ń‚ŃŒ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠµŠ¹!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1811"/>
+ <source>FsObjQueryInfo failed on &apos;%s&apos;: %Rhrc</source>
+ <translation>FsObjQueryInfo Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rhrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1825"/>
+ <source>File copy failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠŗŠ¾ŠæŠøрŠ¾Š²Š°Ń‚ŃŒ фŠ°Š¹Š»</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1894"/>
+ <source>Creating %RU32 directories...
+</source>
+ <translation>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø...
+</numerusform>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ <numerusform>Š”Š¾Š·Š“Š°Š½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1898"/>
+ <source>mkdir was interrupted by Ctrl-C (%u left)
+</source>
+ <translation>mkdir ŠæрŠµŃ€Š²Š°Š½ чŠµŃ€ŠµŠ· Ctrl-C (%u Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1911"/>
+ <source>Creating directory &quot;%s&quot; ...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1922"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2006"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2127"/>
+ <source>Out of memory
+</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1932"/>
+ <source>No directory to create specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° Š“ŠøрŠµŠŗтŠ¾Ń€Šøя Š“Š»Ń сŠ¾Š·Š“Š°Š½Šøя!</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1980"/>
+ <source>Removing %RU32 directory tree(s)...
+</source>
+ <translation>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠµŃ€ŠµŠ²Š° Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠµŃ€ŠµŠ²ŃŒŠµŠ² Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠµŃ€ŠµŠ²ŃŒŠµŠ² Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1983"/>
+ <source>Removing %RU32 directorie(s)...
+</source>
+ <translation>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠ¹...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1988"/>
+ <source>rmdir was interrupted by Ctrl-C (%u left)
+</source>
+ <translation>rmdir ŠæрŠµŃ€Š²Š°Š½ чŠµŃ€ŠµŠ· Ctrl-C (%u Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1999"/>
+ <source>Removing directory &quot;%s&quot; ...
+</source>
+ <translation>Š£Š“Š°Š»ŠµŠ½ŠøŠµ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2018"/>
+ <source>Recursively removing directory &quot;%s&quot; ...
+</source>
+ <translation>Š ŠµŠŗурсŠøŠ²Š½Š¾Šµ уŠ“Š°Š»ŠµŠ½ŠøŠµ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2036"/>
+ <source>Directory deletion failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š“ŠøрŠµŠŗтŠ¾Ń€Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2042"/>
+ <source>Out of memory during recursive rmdir
+</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø Š“Š»Ń рŠµŠŗурсŠøŠ²Š½Š¾Š³Š¾ rmdir
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2060"/>
+ <source>No directory to remove specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° Š“ŠøрŠµŠŗтŠ¾Ń€Šøя Š“Š»Ń уŠ“Š°Š»ŠµŠ½Šøя!</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2100"/>
+ <source>Removing %RU32 file(s)...
+</source>
+ <translation>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 фŠ°Š¹Š»Š°...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 фŠ°Š¹Š»Š¾Š²...
+</numerusform>
+ <numerusform>Š£Š“Š°Š»ŠµŠ½ŠøŠµ %RU32 фŠ°Š¹Š»Š¾Š²...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2104"/>
+ <source>rm was interrupted by Ctrl-C (%u left)
+</source>
+ <translation>rm ŠæрŠµŃ€Š²Š°Š½ чŠµŃ€ŠµŠ· Ctrl-C (%u Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2115"/>
+ <source>Removing file &quot;%s&quot; ...
+</source>
+ <translation>Š£Š“Š°Š»ŠµŠ½ŠøŠµ фŠ°Š¹Š»Š° &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2137"/>
+ <source>No file to remove specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ фŠ°Š¹Š» Š“Š»Ń уŠ“Š°Š»ŠµŠ½Šøя!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2195"/>
+ <source>Failed to initialize, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·ŠøрŠ¾Š²Š°Ń‚ŃŒ, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2199"/>
+ <source>No source(s) to move specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ŠøстŠ¾Ń‡Š½ŠøŠŗ(Šø) Š“Š»Ń ŠæŠµŃ€ŠµŠ¼ŠµŃ‰ŠµŠ½Šøя!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2220"/>
+ <source>Destination does not exist
+</source>
+ <translation>ŠŠ°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2230"/>
+ <source>Destination must be a directory when specifying multiple sources
+</source>
+ <translation>ŠŠ°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š“Š¾Š»Š¶Š½Š¾ Š±Ń‹Ń‚ŃŒ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠµŠ¹ ŠŗŠ¾Š³Š“Š° уŠŗŠ°Š·Ń‹Š²Š°ŃŽŃ‚ся Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ ŠøстŠ¾Ń‡Š½ŠøŠŗŠ¾Š²
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2234"/>
+ <source>Unable to determine destination type: %Rhrc
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾ŠæрŠµŠ“ŠµŠ»Šøть тŠøŠæ Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2243"/>
+ <source>Renaming %RU32 %s ...
+</source>
+ <translation>ŠŸŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ %RU32 %s ...
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2244"/>
+ <source>sources</source>
+ <translation>
+ <numerusform>ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°</numerusform>
+ <numerusform>ŠøстŠ¾Ń‡Š½ŠøŠŗŠ¾Š²</numerusform>
+ <numerusform>ŠøстŠ¾Ń‡Š½ŠøŠŗŠ¾Š²</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2244"/>
+ <source>source</source>
+ <translation>ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2259"/>
+ <source>Cannot stat &quot;%s&quot;: No such file or directory
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю &quot;%s&quot;: ŠŠµŃ‚ тŠ°ŠŗŠ¾Š³Š¾ фŠ°Š¹Š»Š° ŠøŠ»Šø Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2276"/>
+ <source>Renaming %s &quot;%s&quot; to &quot;%s&quot; ...
+</source>
+ <translation>ŠŸŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ %s &quot;%s&quot; Š² &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2277"/>
+ <source>directory</source>
+ <comment>object</comment>
+ <translation>Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2277"/>
+ <source>file</source>
+ <comment>object</comment>
+ <translation>фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2296"/>
+ <source>Warning: Not all sources were renamed
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: ŠŠµ Š²ŃŠµ ŠøстŠ¾Ń‡Š½ŠøŠŗŠø ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½Ń‹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2355"/>
+ <source>More than one template specified!
+</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š¾ Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ шŠ°Š±Š»Š¾Š½Š°!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2364"/>
+ <source>No template specified!</source>
+ <translation>ŠØŠ°Š±Š»Š¾Š½Ń‹ Š½Šµ уŠŗŠ°Š·Š°Š½Ń‹!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2367"/>
+ <source>Creating temporary files is currently not supported!</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š²Ń€ŠµŠ¼ŠµŠ½Š½Ń‹Ń… фŠ°Š¹Š»Š¾Š² сŠµŠ¹Ń‡Š°Ń Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2379"/>
+ <source>Creating temporary directory from template &apos;%s&apos; in directory &apos;%s&apos; ...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø ŠøŠ· шŠ°Š±Š»Š¾Š½Š° &apos;%s&apos; Š² Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø &apos;%s&apos; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2382"/>
+ <source>Creating temporary directory from template &apos;%s&apos; in default temporary directory ...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø ŠøŠ· шŠ°Š±Š»Š¾Š½Š° &apos;%s&apos; Š²Š¾ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2385"/>
+ <source>Creating temporary file from template &apos;%s&apos; in directory &apos;%s&apos; ...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š²Ń€Š¼ŠµŠ½Š½Š¾Š³Š¾ фŠ°Š¹Š»Š° ŠøŠ· шŠ°Š±Š»Š¾Š½Š° &apos;%s&apos; Š² Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø &apos;%s&apos; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2388"/>
+ <source>Creating temporary file from template &apos;%s&apos; in default temporary directory ...
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ŠøŠµ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š³Š¾ фŠ°Š¹Š»Š° ŠøŠ· шŠ°Š±Š»Š¾Š½Š° &apos;%s&apos; Š²Š¾ Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2401"/>
+ <source>Directory name: %ls
+</source>
+ <translation>Š˜Š¼Ń Š“ŠøрŠµŠŗтŠ¾Ń€ŠøŠø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2444"/>
+ <source>Command &quot;%s&quot; not implemented yet!</source>
+ <translation>ŠšŠ¾Š¼Š°Š½Š“Š° &quot;%s&quot; ŠµŃ‰Šµ Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2452"/>
+ <source>Nothing to stat!</source>
+ <translation>ŠŠµŃ‚ Š¾Š±ŃŠŠµŠŗтŠ° Š“Š»Ń Š·Š°ŠæрŠ¾ŃŠ° ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŠø!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2465"/>
+ <source>Checking for element &quot;%s&quot; ...
+</source>
+ <translation>ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° эŠ»ŠµŠ¼ŠµŠ½Ń‚Š° &quot;%s&quot; ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2475"/>
+ <source>Failed to stat &apos;%s&apos;: No such file
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š“Š»Ń &apos;%s&apos;: ŠŠµŃ‚ тŠ°ŠŗŠ¾Š³Š¾ фŠ°Š¹Š»Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2480"/>
+ <source> File: &apos;%s&apos;
+</source>
+ <translation> Š¤Š°Š¹Š»: &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2515"/>
+ <source> Size: %-17RU64 Alloc: %-19RU64 Type: %s
+</source>
+ <translation> Š Š°Š·Š¼ŠµŃ€: %-17RU64 Š’Ń‹Š“ŠµŠ»ŠµŠ½Š¾: %-19RU64 Š¢ŠøŠæ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2517"/>
+ <source>Device: %#-17RX32 INode: %-18RU64 Links: %u
+</source>
+ <translation>Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾: %#-17RX32 INode: %-18RU64 Š”сыŠ»ŠŗŠø: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2528"/>
+ <source> Mode: %-16s Attrib: %-17s Dev ID: %#RX32
+</source>
+ <translation> Š ŠµŠ¶ŠøŠ¼: %-16s ŠŃ‚Ń‚Ń€ŠøŠ±ŃƒŃ‚Ń‹: %-17s ID устрŠ¾Š¹ŃŃ‚Š²Š°: %#RX32
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2530"/>
+ <source> Mode: %-16s Attrib: %s
+</source>
+ <translation> Š ŠµŠ¶ŠøŠ¼: %-16s ŠŃ‚Ń‚Ń€ŠøŠ±ŃƒŃ‚Ń‹: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2532"/>
+ <source> Owner: %4d/%-12ls Group: %4d/%ls
+</source>
+ <translation> Š’Š»Š°Š“ŠµŠ»ŠµŃ†: %4d/%-12ls Š“Ń€ŃƒŠæŠæŠ°: %4d/%ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2536"/>
+ <source> Birth: %s
+</source>
+ <translation> Š”Š¾Š·Š“Š°Š½: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2538"/>
+ <source>Change: %s
+</source>
+ <translation>Š˜Š·Š¼ŠµŠ½ŠµŠ½: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2540"/>
+ <source>Modify: %s
+</source>
+ <translation>ŠœŠ¾Š“ŠøфŠøцŠøрŠ¾Š²Š°Š½: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2542"/>
+ <source>Access: %s
+</source>
+ <translation>Š”Š¾ŃŃ‚ŃƒŠæ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2595"/>
+ <source>Current run level is %RU32
+</source>
+ <translation>Š¢ŠµŠŗущŠøŠ¹ урŠ¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя %RU32
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2602"/>
+ <source>Waiting for run level %RU32 ...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ урŠ¾Š²Š½Ń Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя %RU32 ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2615"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3565"/>
+ <source>Waiting failed with %Rrc
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ %Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2621"/>
+ <source>Run level %RU32 reached
+</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя %RU32 Š“Š¾ŃŃ‚ŠøŠ³Š½ŃƒŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2630"/>
+ <source>Run level %RU32 not reached within time
+</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя %RU32 Š½Šµ Š“Š¾ŃŃ‚ŠøŠ³Š½ŃƒŃ‚ Š·Š° Š¾Ń‚Š²ŠµŠ“ŠµŠ½Š½Š¾Šµ Š²Ń€ŠµŠ¼Ń
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2716"/>
+ <source>RTPathAbsCxx failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTPathAbsCxx Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2745"/>
+ <source>Updating Guest Additions ...
+</source>
+ <translation>ŠžŠ±Š½Š¾Š²Š»ŠµŠ½ŠøŠµ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2761"/>
+ <source>No Guest Additions source found or specified, aborting
+</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½ Šø Š½Šµ уŠŗŠ°Š·Š°Š½ ŠøстŠ¾Ń‡Š½ŠøŠŗ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”, ŠæрŠµŃ€Ń‹Š²Š°Š½ŠøŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2766"/>
+ <source>Source &quot;%s&quot; does not exist!
+</source>
+ <translation>Š˜ŃŃ‚Š¾Ń‡Š½ŠøŠŗ &quot;%s&quot; Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2777"/>
+ <source>OS type:</source>
+ <translation>Š¢ŠøŠæ ŠžŠ”:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2782"/>
+ <source>Additions run level:</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2794"/>
+ <source>Additions version:</source>
+ <translation>Š’ŠµŃ€ŃŠøя Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2802"/>
+ <source>Using source: %s
+</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŠ¼Ń‹Š¹ ŠøстŠ¾Ń‡Š½ŠøŠŗ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2811"/>
+ <source>Waiting for current Guest Additions inside VM getting ready for updating ...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ Š³Š¾Ń‚Š¾Š²Š½Š¾ŃŃ‚Šø тŠµŠŗущŠøх Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š²Š½ŃƒŃ‚Ń€Šø Š’Šœ Š“Š»Ń Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2832"/>
+ <source>Guest Additions %lsr%RU64 currently installed, waiting for Guest Additions installer to start ...
+</source>
+ <translation>Š”ŠµŠ¹Ń‡Š°Ń устŠ°Š½Š¾Š²Š»ŠµŠ½Ń‹ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” %lsr%RU64, Š¾Š¶ŠøŠ“Š°Š½ŠøŠµ Š·Š°ŠæусŠŗŠ° ŠøŠ½ŃŃ‚Š°Š»Š»ŃŃ‚Š¾Ń€Š° Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2856"/>
+ <source>Guest Additions update failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾Š±Š½Š¾Š²Šøть Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2861"/>
+ <source>Guest Additions update successful.
+</source>
+ <translation>Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” усŠæŠµŃˆŠ½Š¾ Š¾Š±Š½Š¾Š²Š»ŠµŠ½Ń‹.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2866"/>
+ <source>Rebooting guest ...
+</source>
+ <translation>ŠŸŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·ŠŗŠ° Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2874"/>
+ <source>Current installed Guest Additions don&apos;t support automatic rebooting. Please reboot manually.
+</source>
+ <translation>Š£ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń‹Šµ сŠµŠ¹Ń‡Š°Ń Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчсŠŗую ŠæŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·Šŗу. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·ŠøтŠµ Š²Ń€ŃƒŃ‡Š½ŃƒŃŽ.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2886"/>
+ <source>Waiting for new Guest Additions inside VM getting ready ...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ Š³Š¾Ń‚Š¾Š²Š½Š¾ŃŃ‚Šø Š½Š¾Š²Ń‹Ń… Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” Š²Š½ŃƒŃ‚Ń€Šø Š’Šœ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2894"/>
+ <source>Verifying Guest Additions update ...
+</source>
+ <translation>ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2913"/>
+ <source>Old Guest Additions: %ls%RU64
+</source>
+ <translation>Š”тŠ°Ń€Ń‹Šµ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”: %ls%RU64
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2915"/>
+ <source>New Guest Additions: %ls%RU64
+</source>
+ <translation>ŠŠ¾Š²Ń‹Šµ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”: %ls%RU64
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2920"/>
+ <source>
+Error updating Guest Additions, please check guest installer log
+</source>
+ <translation>
+ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠø Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”, ŠæŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæрŠ¾Š²ŠµŃ€ŃŒŃ‚Šµ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ Š¶ŃƒŃ€Š½Š°Š» устŠ°Š½Š¾Š²ŠŗŠø
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2925"/>
+ <source>
+WARNING: Guest Additions were downgraded
+</source>
+ <translation>
+ŠŸŠ Š•Š”Š£ŠŸŠ Š•Š–Š”Š•ŠŠ˜Š•: Š£ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Ń‹ Š±Š¾Š»ŠµŠµ стŠ°Ń€Ń‹Šµ Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2932"/>
+ <source>The guest needs to be restarted in order to make use of the updated Guest Additions.
+</source>
+ <translation>Š“Š¾ŃŃ‚ŠµŠ²ŃƒŃŽ сŠøстŠµŠ¼Ńƒ Š½Š°Š“Š¾ ŠæŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·Šøть Š“Š»Ń ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Šøя Š½Š¾Š²Ń‹Ń… Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3005"/>
+ <source>Invalid run level specified. Valid values are: system, userland, desktop</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ урŠ¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя. Š”Š¾ŠæустŠøŠ¼Ń‹Šµ Š·Š½Š°Ń‡ŠµŠ½Šøя: system, userland, desktop</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3019"/>
+ <source>Missing run level to wait for</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ урŠ¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š“Š»Ń Š¾Š¶ŠøŠ“Š°Š½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3066"/>
+ <source>Unknown list: &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Ń‹Š¹ сŠæŠøсŠ¾Šŗ: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3076"/>
+ <source>Missing list name</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ¼Ń сŠæŠøсŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3097"/>
+ <source>Active guest sessions:
+</source>
+ <translation>ŠŠŗтŠøŠ²Š½Ń‹Šµ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Šµ сŠµŃŃŠøŠø:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3116"/>
+ <source>
+ Session #%-3zu ID=%-3RU32 User=%-16ls Status=[%s] Name=%ls</source>
+ <translation>
+ Š”ŠµŃŃŠøя #%-3zu ID=%-3RU32 ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ=%-16ls Š”тŠ°Ń‚ŃƒŃ=[%s] Š˜Š¼Ń=%ls</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3139"/>
+ <source>
+ Process #%-03zu PID=%-6RU32 Status=[%s] Command=%ls</source>
+ <translation>
+ ŠŸŃ€Š¾Ń†ŠµŃŃ#%-03zu PID=%-6RU32 Š”тŠ°Ń‚ŃƒŃ=[%s] ŠšŠ¾Š¼Š°Š½Š“Š°=%ls</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3167"/>
+ <source>
+ File #%-03zu ID=%-6RU32 Status=[%s] Name=%ls</source>
+ <translation>
+ Š¤Š°Š¹Š» #%-03zu ID=%-6RU32 Š”тŠ°Ń‚ŃƒŃ=[%s] Š˜Š¼Ń=%ls</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3178"/>
+ <source>
+
+Total guest sessions: %zu
+</source>
+ <translation>
+
+Š’сŠµŠ³Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… сŠµŃŃŠøŠ¹: %zu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3180"/>
+ <source>Total guest processes: %zu
+</source>
+ <translation>Š’сŠµŠ³Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… ŠæрŠ¾Ń†ŠµŃŃŠ¾Š²: %zu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3182"/>
+ <source>Total guest files: %zu
+</source>
+ <translation>Š’сŠµŠ³Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… фŠ°Š¹Š»Š¾Š²: %zu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3185"/>
+ <source>No active guest sessions found
+</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ Š°ŠŗтŠøŠ²Š½Ń‹Ń… Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… сŠµŃŃŠøŠ¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3251"/>
+ <source>Invalid PID value: 0</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ PID: 0</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3254"/>
+ <source>Error parsing PID value: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š·Š½Š°Ń‡ŠµŠ½Šøя PID: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3264"/>
+ <source>At least one PID must be specified to kill!</source>
+ <translation>ŠŃƒŠ¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ хŠ¾Ń‚я Š±Ń‹ Š¾Š“ŠøŠ½ PID, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š½Š°Š“Š¾ уŠ±Šøть!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3268"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3422"/>
+ <source>No session ID specified!</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ID сŠµŃŃŠøŠø!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3272"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3426"/>
+ <source>Either session ID or name (pattern) must be specified</source>
+ <translation>ŠŃƒŠ¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ Š»ŠøŠ±Š¾ ID сŠµŃŃŠøŠø Š»ŠøŠ±Š¾ ŠøŠ¼Ń (шŠ°Š±Š»Š¾Š½)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3335"/>
+ <source>Terminating process (PID %RU32) (session ID %RU32) ...
+</source>
+ <translation>Š—Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ ŠæрŠ¾Ń†ŠµŃŃŠ° (PID %RU32) (ID сŠµŃŃŠøŠø %RU32) ...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3343"/>
+ <source>No matching process(es) for session ID %RU32 found
+</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ сŠ¾Š¾Ń‚Š²ŠµŃ‚стŠ²ŃƒŃŽŃ‰Šøх ŠæрŠ¾Ń†ŠµŃŃŠ¾Š² Š“Š»Ń ID сŠµŃŃŠøŠø %RU32
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3355"/>
+ <source>No matching session(s) found
+</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ сŠ¾Š¾Ń‚Š²ŠµŃ‚стŠ²ŃƒŃŽŃ‰Šøх сŠµŃŃŠøŠ¹
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3358"/>
+ <source>%RU32 process(es) terminated
+</source>
+ <translation>
+ <numerusform>Š—Š°Š²ŠµŃ€ŃˆŠµŠ½ %RU32 ŠæрŠ¾Ń†ŠµŃŃ
+</numerusform>
+ <numerusform>Š—Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ %RU32 ŠæрŠ¾Ń†ŠµŃŃŠ°
+</numerusform>
+ <numerusform>Š—Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ %RU32 ŠæрŠ¾Ń†ŠµŃŃŠ¾Š²
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3464"/>
+ <source>Closing guest session ID=#%RU32 &quot;%s&quot; ...
+</source>
+ <translation>Š—Š°ŠŗрытŠøŠµ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠµŃŃŠøŠø ID=#%RU32 &quot;%s&quot;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3468"/>
+ <source>Guest session successfully closed
+</source>
+ <translation>Š“Š¾ŃŃ‚ŠµŠ²Š°Ń сŠµŃŃŠøя усŠæŠµŃˆŠ½Š¾ Š·Š°ŠŗрытŠ°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3476"/>
+ <source>No guest session(s) found
+</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… сŠµŃŃŠøŠ¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3554"/>
+ <source>Waiting for events ...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ сŠ¾Š±Ń‹Ń‚ŠøŠ¹...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3709"/>
+ <source>Unknown sub-command: &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3718"/>
+ <source>Missing sub-command</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3720"/>
+ <source>Missing VM name and sub-command</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ¼Ń Š’Šœ Šø ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+</context>
+<context>
+ <name>GuestCtrlLsnr</name>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="106"/>
+ <source>File ID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation>Š¤Š°Š¹Š» с ID=%RU32 &quot;%s&quot; ŠøŠ·Š¼ŠµŠ½ŠøŠ» стŠ°Ń‚ŃƒŃ Š½Š° [%s]
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="162"/>
+ <source>Process PID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ PID=%RU32 &quot;%s&quot; ŠøŠ·Š¼ŠµŠ½ŠøŠ» стŠ°Ń‚ŃƒŃ Š½Š° [%s]
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="254"/>
+ <source>File &quot;%s&quot; %s
+</source>
+ <translation>Š¤Š°Š¹Š» &quot;%s&quot; %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="256"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="320"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="461"/>
+ <source>registered</source>
+ <translation>рŠµŠ³ŠøстрŠ°Ń†Šøя сŠ“ŠµŠ»Š°Š½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="256"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="320"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="461"/>
+ <source>unregistered</source>
+ <translation>рŠµŠ³ŠøстрŠ°Ń†Šøя Š¾Ń‚Š¼ŠµŠ½ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="260"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="324"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="465"/>
+ <source>Registering ...
+</source>
+ <translation>Š ŠµŠ³ŠøстрŠ°Ń†Šøя...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="283"/>
+ <source>Unregistering file ...
+</source>
+ <translation>ŠžŃ‚Š¼ŠµŠ½Š° рŠµŠ³ŠøстрŠ°Ń†ŠøŠø фŠ°Š¹Š»Š°...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="318"/>
+ <source>Process &quot;%s&quot; %s
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃ &quot;%s&quot; %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="347"/>
+ <source>Unregistering process ...
+</source>
+ <translation>ŠžŃ‚Š¼ŠµŠ½Š° рŠµŠ³ŠøстрŠ°Ń†ŠøŠø ŠæрŠ¾Ń†ŠµŃŃŠ°...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="384"/>
+ <source>Session ID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation>Š”ŠµŃŃŠøя ID=%RU32 &quot;%s&quot; ŠøŠ·Š¼ŠµŠ½ŠøŠ»Š° стŠ°Ń‚ŃƒŃ Š½Š° [%s]
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="459"/>
+ <source>Session ID=%RU32 &quot;%s&quot; %s
+</source>
+ <translation>Š”ŠµŃŃŠøя ID=%RU32 &quot;%s&quot; %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="490"/>
+ <source>Unregistering ...
+</source>
+ <translation>ŠžŃ‚Š¼ŠµŠ½Š° рŠµŠ³ŠøстрŠ°Ń†ŠøŠø...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="552"/>
+ <source>Reached run level %RU32
+</source>
+ <translation>Š”Š¾ŃŃ‚ŠøŠ³Š½ŃƒŃ‚ урŠ¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя %RU32
+</translation>
+ </message>
+</context>
+<context>
+ <name>GuestProp</name>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="64"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="125"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="171"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="215"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="304"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="407"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="422"/>
+ <source>Incorrect parameters</source>
+ <translation>ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Ń‹Šµ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="84"/>
+ <source>No value set!
+</source>
+ <translation>ŠŠµ Š·Š°Š“Š°Š½Š¾ ŠŗŠ°ŠŗŠ¾Šµ-Š»ŠøŠ±Š¾ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="86"/>
+ <source>Value: %ls
+</source>
+ <translation>Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="89"/>
+ <source>Timestamp: %lld
+</source>
+ <translation>Š’Ń€ŠµŠ¼Ń: %lld
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="90"/>
+ <source>Flags: %ls
+</source>
+ <translation>Š¤Š»Š°Š³Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="251"/>
+ <source>No properties found.
+</source>
+ <translation>Š”Š²Š¾Š¹ŃŃ‚Š²Š° Š½Šµ Š½Š°Š¹Š“ŠµŠ½Ń‹.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="253"/>
+ <source>Name: %ls, value: %ls, timestamp: %lld, flags: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls, Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ: %ls, Š²Ń€ŠµŠ¼Ń: %lld, фŠ»Š°Š³Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="362"/>
+ <source>Property %ls was deleted
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="364"/>
+ <source>Name: %ls, value: %ls, flags: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls, Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ: %ls, фŠ»Š°Š³Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="381"/>
+ <source>Time out or interruption while waiting for a notification.</source>
+ <translation>ŠŸŃ€ŠµŠ²Ń‹ŃˆŠµŠ½Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя ŠøŠ»Šø ŠæрŠµŃ€Ń‹Š²Š°Š½ŠøŠµ Š²Š¾ Š²Ń€ŠµŠ¼Ń Š¾Š¶ŠøŠ“Š°Š½Šøя Š¾ŠæŠ¾Š²ŠµŃ‰ŠµŠ½Šøя.</translation>
+ </message>
+</context>
+<context>
+ <name>Help</name>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="139"/>
+ <source>Usage - %s%s:
+</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ - %s%s:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="142"/>
+ <source>Usage:
+</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="231"/>
+ <source>No subcommand specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="257"/>
+ <source>Unknown subcommand: %s</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="290"/>
+ <source>Too many parameters</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="397"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="401"/>
+ <source>Invalid option -%c</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń Š¾ŠæцŠøя -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="403"/>
+ <source>Invalid option case %i</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š¾ŠæцŠøŠø %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="406"/>
+ <source>Unknown option: %s</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="408"/>
+ <source>Invalid argument format: %s</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ фŠ¾Ń€Š¼Š°Ń‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="432"/>
+ <source>Missing the %u%s value for option %s</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ %u%s Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š“Š»Ń Š¾ŠæцŠøŠø %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="434"/>
+ <source>st</source>
+ <translation>Š¾Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="435"/>
+ <source>nd</source>
+ <translation>Š¾Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="436"/>
+ <source>rd</source>
+ <translation>ьŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="437"/>
+ <source>th</source>
+ <translation>Š¾Šµ</translation>
+ </message>
+ <message>
+ <source>Usage:
+
+</source>
+ <translation type="vanished">Š˜ŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ:
+
+</translation>
+ </message>
+ <message>
+ <source>
+Syntax error: %N
+</source>
+ <translation type="vanished">
+Š”ŠøŠ½Ń‚Š°ŠŗсŠøчŠµŃŠŗŠ°Ń Š¾ŃˆŠøŠ±ŠŗŠ°: %N
+</translation>
+ </message>
+</context>
+<context>
+ <name>HostOnly</name>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="95"/>
+ <source>Failed to create the host-only adapter</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Š¹ Š°Š“Š°ŠæтŠµŃ€ хŠ¾ŃŃ‚Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="104"/>
+ <source>Interface &apos;%ls&apos; was successfully created
+</source>
+ <translation>Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń &apos;%ls&apos; усŠæŠµŃˆŠ½Š¾ сŠ¾Š·Š“Š°Š½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="123"/>
+ <location filename="../VBoxManageHostonly.cpp" line="214"/>
+ <source>Only one interface name can be specified</source>
+ <translation>ŠœŠ¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š¾ ŠøŠ¼Ń ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="131"/>
+ <source>No interface name was specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="149"/>
+ <source>Failed to remove the host-only adapter</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Š¹ Š°Š“Š°ŠæтŠµŃ€ хŠ¾ŃŃ‚Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="193"/>
+ <source>The --ip option is specified more than once</source>
+ <translation>ŠžŠæцŠøя --ip уŠŗŠ°Š·Š°Š½Š° Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°Š·Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="198"/>
+ <source>The --netmask option is specified more than once</source>
+ <translation>ŠžŠæцŠøя --netmask уŠŗŠ°Š·Š°Š½Š° Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°Š·Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="203"/>
+ <source>The --ipv6 option is specified more than once</source>
+ <translation>ŠžŠæцŠøя --ipv6 уŠŗŠ°Š·Š°Š½Š° Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°Š·Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="208"/>
+ <source>The --netmasklengthv6 option is specified more than once</source>
+ <translation>ŠžŠæцŠøя --netmasklengthv6 уŠŗŠ°Š·Š°Š½Š° Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°Š·Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="224"/>
+ <source>You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6.</source>
+ <translation>ŠŠµŠ»ŃŒŠ·Ń ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ --dhcp с ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š°Š¼Šø ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø стŠ°Ń‚ŠøчŠµŃŠŗŠ¾Š³Š¾ ip: --ip, --netmask, --ipv6 and --netmasklengthv6.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="226"/>
+ <source>You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously.</source>
+ <translation>ŠŠµŠ»ŃŒŠ·Ń ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю ipv4 (--ip Šø --netmask) с ipv6 (--ipv6 Šø --netmasklengthv6) Š¾Š“Š½Š¾Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="234"/>
+ <source>Could not find interface &apos;%s&apos;</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="250"/>
+ <source>IPv6 setting is not supported for this adapter</source>
+ <translation>ŠŠ°Š¹ŃŃ‚Ń€Š¾Š¹ŠŗŠø IPv6 Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ся Š“Š»Ń этŠ¾Š³Š¾ Š°Š“Š°ŠæтŠµŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="259"/>
+ <source>Neither -dhcp nor -ip nor -ipv6 was specfified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Ń‹ Š½Šø -dhcp Š½Šø -ip Š½Šø -ipv6</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="268"/>
+ <location filename="../VBoxManageHostonly.cpp" line="514"/>
+ <source>No sub-command specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="289"/>
+ <location filename="../VBoxManageHostonly.cpp" line="533"/>
+ <source>Unknown sub-command &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="410"/>
+ <source>The --name parameter must be specified</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --name Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="412"/>
+ <source>The --netmask parameter must be specified</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --netmask Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="414"/>
+ <source>The --lower-ip parameter must be specified</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --lower-ip Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="416"/>
+ <source>The --upper-ip parameter must be specified</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --upper-ip Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="447"/>
+ <location filename="../VBoxManageHostonly.cpp" line="503"/>
+ <source>Either --name or --id parameter must be specified</source>
+ <translation>ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ Š»ŠøŠ±Š¾ --name Š»ŠøŠ±Š¾ --id</translation>
+ </message>
+</context>
+<context>
+ <name>Info</name>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="284"/>
+ <source> %sName: %ls (UUID: %s)%s
+</source>
+ <translation> %sŠ˜Š¼Ń: %ls (UUID: %s)%s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="292"/>
+ <source> %sDescription:
+%ls
+</source>
+ <translation> %sŠžŠæŠøсŠ°Š½ŠøŠµ:
+%ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="341"/>
+ <source>powered off</source>
+ <translation>Š²Ń‹ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="343"/>
+ <source>saved</source>
+ <translation>сŠ¾Ń…Ń€Š°Š½ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="345"/>
+ <source>teleported</source>
+ <translation>ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="347"/>
+ <source>aborted</source>
+ <translation>ŠæрŠµŃ€Š²Š°Š½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="349"/>
+ <source>aborted-saved</source>
+ <translation>ŠæрŠµŃ€Š²Š°Š½Š°-сŠ¾Ń…Ń€Š°Š½ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="351"/>
+ <source>running</source>
+ <translation>рŠ°Š±Š¾Ń‚Š°ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="353"/>
+ <location filename="../VBoxManageInfo.cpp" line="399"/>
+ <source>paused</source>
+ <translation>ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="355"/>
+ <source>guru meditation</source>
+ <translation>Š³ŃƒŃ€Ńƒ Š¼ŠµŠ“ŠøтŠ°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="357"/>
+ <source>teleporting</source>
+ <translation>ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="359"/>
+ <source>live snapshotting</source>
+ <translation>сŠ¾Š·Š“Š°Š½ŠøŠµ Š¶ŠøŠ²Š¾Š³Š¾ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="361"/>
+ <source>starting</source>
+ <translation>Š·Š°ŠæусŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="363"/>
+ <source>stopping</source>
+ <translation>Š¾ŃŃ‚Š°Š½Š¾Š²ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="365"/>
+ <source>saving</source>
+ <translation>сŠ¾Ń…Ń€Š°Š½ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="367"/>
+ <source>restoring</source>
+ <translation>Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="369"/>
+ <source>teleporting paused vm</source>
+ <translation>ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Š¾Š¹ Š²Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="371"/>
+ <source>teleporting (incoming)</source>
+ <translation>ŠæŠ¾Ń€Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ (ŠøŠ·Š²Š½Šµ)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="373"/>
+ <source>deleting snapshot live</source>
+ <translation>уŠ“Š°Š»ŠµŠ½ŠøŠµ Š¶ŠøŠ²Š¾Š³Š¾ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="375"/>
+ <source>deleting snapshot live paused</source>
+ <translation>уŠ“Š°Š»ŠµŠ½ŠøŠµ Š¶ŠøŠ²Š¾Š³Š¾ сŠ½ŠøŠ¼ŠŗŠ° ŠæрŠøŠ¾ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="377"/>
+ <source>online snapshotting</source>
+ <translation>сŠ¾Š·Š“Š°Š½ŠøŠµ Š¾Š½Š»Š°Š¹Š½ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="379"/>
+ <source>restoring snapshot</source>
+ <translation>Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŠµ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="381"/>
+ <source>deleting snapshot</source>
+ <translation>уŠ“Š°Š»ŠµŠ½ŠøŠµ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="383"/>
+ <source>setting up</source>
+ <translation>Š½Š°ŃŃ‚Ń€Š¾Š¹ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="385"/>
+ <source>offline snapshotting</source>
+ <translation>сŠ¾Š·Š“Š°Š½ŠøŠµ Š¾Ń„Š»Š°Š¹Š½ сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="389"/>
+ <location filename="../VBoxManageInfo.cpp" line="416"/>
+ <location filename="../VBoxManageInfo.cpp" line="446"/>
+ <location filename="../VBoxManageInfo.cpp" line="699"/>
+ <location filename="../VBoxManageInfo.cpp" line="1186"/>
+ <location filename="../VBoxManageInfo.cpp" line="1206"/>
+ <location filename="../VBoxManageInfo.cpp" line="1806"/>
+ <location filename="../VBoxManageInfo.cpp" line="1860"/>
+ <location filename="../VBoxManageInfo.cpp" line="2412"/>
+ <source>unknown</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="397"/>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>not active</source>
+ <translation>Š½ŠµŠ°ŠŗтŠøŠ²Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="401"/>
+ <source>pre-initializing</source>
+ <translation>ŠæрŠµŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="403"/>
+ <source>initializing</source>
+ <translation>ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="405"/>
+ <source>active/running</source>
+ <translation>Š°ŠŗтŠøŠ²Š½Š¾/рŠ°Š±Š¾Ń‚Š°ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="407"/>
+ <source>terminating</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="409"/>
+ <source>terminated</source>
+ <translation>Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="411"/>
+ <source>failed</source>
+ <translation>Š¾Ń‚ŠŗŠ°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="692"/>
+ <location filename="../VBoxManageInfo.cpp" line="1404"/>
+ <location filename="../VBoxManageInfo.cpp" line="2139"/>
+ <source>Null</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="693"/>
+ <source>Disk</source>
+ <translation>Š”ŠøсŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="694"/>
+ <location filename="../VBoxManageInfo.cpp" line="1295"/>
+ <source>Network</source>
+ <translation>Š”ŠµŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <source>Name: &apos;%ls&apos;, Type: %s, Limit: none (disabled)
+</source>
+ <translation type="vanished">Š˜Š¼Ń: &apos;%ls&apos;, Š¢ŠøŠæ: %s, Š›ŠøŠ¼Šøт: Š½ŠµŃ‚(Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾)
+</translation>
+ </message>
+ <message>
+ <source>Name: &apos;%ls&apos;, Type: %s, Limit: %lld %sbits/sec (%lld %sbytes/sec)
+</source>
+ <translation type="vanished">Š˜Š¼Ń: &apos;%ls&apos;, Š¢ŠøŠæ: %s, Š›ŠøŠ¼Šøт: %lld %sŠ±Šøт/сŠµŠŗ (%lld %sŠ±Š°Š¹Ń‚/сŠµŠŗ)
+</translation>
+ </message>
+ <message>
+ <source>Name: &apos;%ls&apos;, Type: %s, Limit: %lld %sbytes/sec
+</source>
+ <translation type="vanished">Š˜Š¼Ń: &apos;%ls&apos;, Š¢ŠøŠæ: %s, Š›ŠøŠ¼Šøт: %lld %sŠ±Š°Š¹Ń‚/сŠµŠŗ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="813"/>
+ <source>Name: &apos;%ls&apos;, Host path: &apos;%ls&apos; (%s), %s%s</source>
+ <translation>Š˜Š¼Ń: &apos;%ls&apos;, ŠŸŃƒŃ‚ŃŒ хŠ¾ŃŃ‚Š°: &apos;%ls&apos; (%s), %s%s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="814"/>
+ <source>writable</source>
+ <translation>Š·Š°ŠæŠøсыŠ²Š°ŠµŠ¼Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="814"/>
+ <source>readonly</source>
+ <translation>тŠ¾Š»ŃŒŠŗŠ¾ Š“Š»Ń чтŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="815"/>
+ <source>, auto-mount</source>
+ <translation>, Š°Š²Ń‚Š¾Š¼Š¾Š½Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="817"/>
+ <source>, mount-point: &apos;%ls&apos;
+</source>
+ <translation>, тŠ¾Ń‡ŠŗŠ° ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя: &apos;%ls&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="995"/>
+ <location filename="../VBoxManageInfo.cpp" line="1027"/>
+ <location filename="../VBoxManageInfo.cpp" line="1914"/>
+ <location filename="../VBoxManageInfo.cpp" line="1950"/>
+ <source>None</source>
+ <translation>ŠŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1000"/>
+ <source>Automatic</source>
+ <translation>ŠŠ²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1015"/>
+ <location filename="../VBoxManageInfo.cpp" line="1057"/>
+ <location filename="../VBoxManageInfo.cpp" line="1428"/>
+ <location filename="../VBoxManageInfo.cpp" line="1908"/>
+ <location filename="../VBoxManageInfo.cpp" line="1945"/>
+ <location filename="../VBoxManageInfo.cpp" line="2124"/>
+ <location filename="../VBoxManageInfo.cpp" line="2125"/>
+ <location filename="../VBoxManageInfo.cpp" line="2126"/>
+ <location filename="../VBoxManageInfo.cpp" line="2269"/>
+ <location filename="../VBoxManageInfo.cpp" line="2298"/>
+ <source>Unknown</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1032"/>
+ <source>Default</source>
+ <translation>ŠŸŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1037"/>
+ <source>Legacy</source>
+ <translation>Š£ŃŃ‚Š°Ń€ŠµŠ²ŃˆŠøŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1042"/>
+ <source>Minimal</source>
+ <translation>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="85"/>
+ <location filename="../VBoxManageInfo.cpp" line="108"/>
+ <location filename="../VBoxManageInfo.cpp" line="131"/>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <location filename="../VBoxManageInfo.cpp" line="2349"/>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>enabled</source>
+ <translation>Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="85"/>
+ <location filename="../VBoxManageInfo.cpp" line="108"/>
+ <location filename="../VBoxManageInfo.cpp" line="131"/>
+ <location filename="../VBoxManageInfo.cpp" line="1263"/>
+ <location filename="../VBoxManageInfo.cpp" line="1317"/>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <location filename="../VBoxManageInfo.cpp" line="2350"/>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>disabled</source>
+ <translation>Š²Ń‹ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="290"/>
+ <source> %sDescription: %ls
+</source>
+ <translation> %sŠžŠæŠøсŠ°Š½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="862"/>
+ <location filename="../VBoxManageInfo.cpp" line="1542"/>
+ <location filename="../VBoxManageInfo.cpp" line="2572"/>
+ <location filename="../VBoxManageInfo.cpp" line="2985"/>
+ <source>&lt;none&gt;</source>
+ <translation>&lt;Š½ŠµŃ‚&gt;</translation>
+ </message>
+ <message>
+ <source> Port %u, Unit %u: UUID: %ls%s%s%s
+ Location: &quot;%ls&quot;
+</source>
+ <translation type="vanished"> ŠŸŠ¾Ń€Ń‚ %u, Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ %u: UUID: %ls%s%s%s
+ Š Š°ŃŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="922"/>
+ <source>, passthrough enabled</source>
+ <translation>, ŠæряŠ¼Š¾Š¹ Š“Š¾ŃŃ‚ŃƒŠæ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="923"/>
+ <location filename="../VBoxManageInfo.cpp" line="966"/>
+ <source>, temp eject</source>
+ <translation>, Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾ ŠøŠ·Š²Š»ŠµŃ‡ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="924"/>
+ <location filename="../VBoxManageInfo.cpp" line="967"/>
+ <source>, ejected</source>
+ <translation>, ŠøŠ·Š²Š»ŠµŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="925"/>
+ <source>, hot-pluggable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="926"/>
+ <source>, non-rotational (SSD)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="927"/>
+ <source>, discards unused blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="965"/>
+ <source> Port %u, Unit %u: Empty%s%s
+</source>
+ <translation> ŠŸŠ¾Ń€Ń‚ %u, Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ %u: ŠŸŃƒŃŃ‚Š¾Š¹%s%s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="979"/>
+ <source> Port %u, Unit %u: GetMedium failed: %Rhrc
+</source>
+ <translation> ŠŸŠ¾Ń€Ń‚ %u, Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ %u: GetMedium Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1106"/>
+ <source>&quot;&lt;inaccessible&gt;&quot; {%s}
+</source>
+ <translation>&quot;&lt;Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š¾&gt;&quot; {%s}
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1112"/>
+ <source>Name: &lt;inaccessible!&gt;
+</source>
+ <translation>Š˜Š¼Ń: &lt;Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š¾!&gt;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1121"/>
+ <source>Config file: %ls
+</source>
+ <translation>Š¤Š°Š¹Š» ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1124"/>
+ <source>Access error details:
+</source>
+ <translation>Š”ŠµŃ‚Š°Š»Šø Š¾ŃˆŠøŠ±ŠŗŠø Š“Š¾ŃŃ‚ŃƒŠæŠ°:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1144"/>
+ <source>Name:</source>
+ <translation>Š˜Š¼Ń:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1145"/>
+ <source>Groups:</source>
+ <translation>Š“Ń€ŃƒŠæŠæы:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1151"/>
+ <location filename="../VBoxManageInfo.cpp" line="1153"/>
+ <source>Guest OS:</source>
+ <translation>Š“Š¾ŃŃ‚ŠµŠ²Š°Ń ŠžŠ”:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1155"/>
+ <source>Config file:</source>
+ <translation>Š¤Š°Š¹Š» ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1156"/>
+ <source>Snapshot folder:</source>
+ <translation>ŠŸŠ°ŠæŠŗŠ° сŠ½ŠøŠ¼ŠŗŠ¾Š²:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1157"/>
+ <source>Log folder:</source>
+ <translation>ŠŸŠ°ŠæŠŗŠ° Š¶ŃƒŃ€Š½Š°Š»Š¾Š²:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1158"/>
+ <source>Hardware UUID:</source>
+ <translation>ŠŠæŠæŠ°Ń€Š°Ń‚Š½Ń‹Š¹ UUID:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1159"/>
+ <source>Memory size:</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1160"/>
+ <source>Page Fusion:</source>
+ <translation>Page Fusion:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1163"/>
+ <source>VRAM size:</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ VRAM:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1164"/>
+ <source>CPU exec cap:</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š¦ŠŸŠ£:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1165"/>
+ <source>HPET:</source>
+ <translation>HPET:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1166"/>
+ <source>CPUProfile:</source>
+ <translation>ŠŸŃ€Š¾Ń„ŠøŠ»ŃŒ Š¦ŠŸŠ£:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1177"/>
+ <source>invalid</source>
+ <translation>Š½ŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1189"/>
+ <source>Chipset:</source>
+ <translation>Š§ŠøŠæсŠµŃ‚:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1209"/>
+ <source>Firmware:</source>
+ <translation>ŠŸŃ€Š¾ŃˆŠøŠ²ŠŗŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1211"/>
+ <source>Number of CPUs:</source>
+ <translation>Š§ŠøсŠ»Š¾ Š¦ŠŸŠ£:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1213"/>
+ <source>Long Mode:</source>
+ <translation>Š”Š»ŠøŠ½Š½Ń‹Š¹ рŠµŠ¶ŠøŠ¼:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1214"/>
+ <source>Triple Fault Reset:</source>
+ <translation>Š”Š±Ń€Š¾Ń Š¢Ń€Š¾Š¹Š½Š¾Š³Š¾ ŠžŃ‚ŠŗŠ°Š·Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1217"/>
+ <source>Nested VT-x/AMD-V:</source>
+ <translation>Š’Š»Š¾Š¶ŠµŠ½Š½Ń‹Šµ Nested VT-x/AMD-V:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1218"/>
+ <source>CPUID Portability Level:</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ ŠŸŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½Š¾ŃŃ‚Šø CPUID:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1221"/>
+ <source>CPUID overrides:</source>
+ <translation>CPUID Š·Š°Š¼ŠµŠ½Ń‹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1234"/>
+ <source>Leaf no. EAX EBX ECX EDX
+</source>
+ <translation>Š›Šøст no. EAX EBX ECX EDX
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1246"/>
+ <source>None
+</source>
+ <translation>ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1269"/>
+ <source>menu only</source>
+ <translation>тŠ¾Š»ŃŒŠŗŠ¾ Š¼ŠµŠ½ŃŽ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1275"/>
+ <source>message and menu</source>
+ <translation>сŠ¾Š¾Š±Ń‰ŠµŠ½Šøя Šø Š¼ŠµŠ½ŃŽ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1277"/>
+ <source>Boot menu mode:</source>
+ <translation>Š ŠµŠ¶ŠøŠ¼ Š·Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Š¾Š³Š¾ Š¼ŠµŠ½ŃŽ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1289"/>
+ <source>Floppy</source>
+ <translation>Š¤Š»Š¾ŠæŠæŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1293"/>
+ <source>HardDisk</source>
+ <translation>Š–ŠµŃŃ‚ŠŗŠøŠ¹ Š”ŠøсŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1299"/>
+ <source>Shared Folder</source>
+ <translation>ŠžŠ±Ń‰Š°Ń ŠæŠ°ŠæŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1301"/>
+ <source>Not Assigned</source>
+ <translation>ŠŠµ Š½Š°Š·Š½Š°Ń‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1302"/>
+ <source>Boot Device %u:</source>
+ <translation>Š—Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾ %u:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1333"/>
+ <source>BIOS APIC mode:</source>
+ <translation>Š ŠµŠ¶ŠøŠ¼ BIOS APIC:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1335"/>
+ <source>Time offset:</source>
+ <translation>Š§Š°ŃŠ¾Š²Š¾Š¹ ŠæŠ¾ŃŃ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1335"/>
+ <source>ms</source>
+ <translation>Š¼Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1339"/>
+ <source>BIOS NVRAM File:</source>
+ <translation>Š¤Š°Š¹Š» BIOS NVRAM:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1340"/>
+ <source>RTC:</source>
+ <translation>RTC:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1340"/>
+ <source>local time</source>
+ <translation>Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Šµ Š²Ń€ŠµŠ¼Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1341"/>
+ <source>Hardware Virtualization:</source>
+ <translation>ŠŠæŠæŠ°Ń€Š°Ń‚Š½Š°Ń Š’ŠøртуŠ°Š»ŠøŠ·Š°Ń†Šøя:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1342"/>
+ <source>Nested Paging:</source>
+ <translation>Š’Š»Š¾Š¶ŠµŠ½Š½Ń‹Šµ стрŠ°Š½Šøцы:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1343"/>
+ <source>Large Pages:</source>
+ <translation>Š‘Š¾Š»ŃŒŃˆŠøŠµ Š”трŠ°Š½Šøцы:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1345"/>
+ <source>VT-x Unrestricted Exec.:</source>
+ <translation>VT-x ŠŠµŠ¾Š³Ń€Š°Š½ŠøчŠµŠ½Š½Š¾Šµ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1346"/>
+ <source>AMD-V Virt. Vmsave/Vmload:</source>
+ <translation>AMD-V Virt. Vmsave/Vmload:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1358"/>
+ <source>Paravirt. Provider:</source>
+ <translation>ŠŸŠ°Ń€Š°Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Š¹ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1363"/>
+ <source>Effective Paravirt. Prov.:</source>
+ <translation>Š­Ń„Ń„ŠµŠŗтŠøŠ²Š½Ń‹Š¹ ŠŸŠ°Ń€Š°Š²ŠøртуŠ°Š»ŃŒŠ½Ń‹Š¹ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1368"/>
+ <source>Paravirt. Debug:</source>
+ <translation>ŠŸŠ°Ń€Š°Š²ŠøрутŠ°Š»ŃŒŠ½Š°Ń Š¾Ń‚Š»Š°Š“ŠŗŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1391"/>
+ <source>%-28s %s (since %s)
+</source>
+ <translation>%-28s %s (с %s)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1391"/>
+ <source>State:</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1435"/>
+ <source>Graphics Controller:</source>
+ <translation>Š“Ń€Š°Ń„ŠøчŠµŃŠŗŠøŠ¹ ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1438"/>
+ <source>Monitor count:</source>
+ <translation>Š§ŠøсŠ»Š¾ Š¼Š¾Š½ŠøтŠ¾Ń€Š¾Š²:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1439"/>
+ <source>3D Acceleration:</source>
+ <translation>3D Š£ŃŠŗŠ¾Ń€ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1441"/>
+ <source>2D Video Acceleration:</source>
+ <translation>2D Š’ŠøŠ“ŠµŠ¾ Š£ŃŠŗŠ¾Ń€ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1443"/>
+ <source>Teleporter Enabled:</source>
+ <translation>Š¢ŠµŠ»ŠµŠæŠ¾Ń€Ń‚ŠµŃ€ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1444"/>
+ <source>Teleporter Port:</source>
+ <translation>ŠŸŠ¾Ń€Ń‚ тŠµŠ»ŠµŠæŠ¾Ń€Ń‚ŠµŃ€Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1445"/>
+ <source>Teleporter Address:</source>
+ <translation>ŠŠ“рŠµŃ тŠµŠ»ŠµŠæŠ¾Ń€Ń‚ŠµŃ€Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1446"/>
+ <source>Teleporter Password:</source>
+ <translation>ŠŸŠ°Ń€Š¾Š»ŃŒ тŠµŠ»ŠµŠæŠ¾Ń€Ń‚ŠµŃ€Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1447"/>
+ <source>Tracing Enabled:</source>
+ <translation>Š¢Ń€Š°ŃŃŠøрŠ¾Š²ŠŗŠ° Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1448"/>
+ <source>Allow Tracing to Access VM:</source>
+ <translation>Š Š°Š·Ń€ŠµŃˆŠøть трŠ°ŃŃŠøрŠ¾Š²ŠŗŠµ Š“Š¾ŃŃ‚ŃƒŠæ Šŗ Š’Šœ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1449"/>
+ <source>Tracing Configuration:</source>
+ <translation>ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя трŠ°ŃŃŠøрŠ¾Š²ŠŗŠø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1450"/>
+ <source>Autostart Enabled:</source>
+ <translation>ŠŠ²Ń‚Š¾ŃŃ‚Š°Ń€Ń‚ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1451"/>
+ <source>Autostart Delay:</source>
+ <translation>Š—Š°Š“ŠµŃ€Š¶ŠŗŠ° Š°Š²Ń‚Š¾ŃŃ‚Š°Ń€Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1452"/>
+ <source>Default Frontend:</source>
+ <translation>Š¤Ń€Š¾Š½Ń‚эŠ½Š“ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1463"/>
+ <source>flat</source>
+ <translation>рŠ°Š²Š½Š¾Š¼ŠµŃ€Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1469"/>
+ <source>low</source>
+ <translation>Š½ŠøŠ·ŠŗŠøŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1475"/>
+ <source>normal</source>
+ <translation>Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1481"/>
+ <source>high</source>
+ <translation>Š²Ń‹ŃŠ¾ŠŗŠøŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1487"/>
+ <source>default</source>
+ <translation>ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1490"/>
+ <source>VM process priority:</source>
+ <translation>ŠŸŃ€ŠøŠ¾Ń€ŠøтŠµŃ‚ ŠæрŠ¾Ń†ŠµŃŃŠ° Š’Šœ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2881"/>
+ <source>VMMDev Testing</source>
+ <translation>Š¢ŠµŃŃ‚ŠøрŠ¾Š²Š°Š½ŠøŠµ VMMDev</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>misconfigured</source>
+ <translation>Š½ŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š¾ Š½Š°ŃŃ‚Ń€Š¾ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2907"/>
+ <source>* Snapshots:
+</source>
+ <translation>* Š”Š½ŠøŠ¼ŠŗŠø:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2916"/>
+ <source>* Guest:
+</source>
+ <translation>* Š“Š¾ŃŃ‚ŠµŠ²Š°Ń сŠøстŠµŠ¼Š°:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2953"/>
+ <location filename="../VBoxManageInfo.cpp" line="2985"/>
+ <source>Guest Facilities:</source>
+ <translation>Š”рŠµŠ“стŠ²Š° Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1890"/>
+ <location filename="../VBoxManageInfo.cpp" line="1891"/>
+ <location filename="../VBoxManageInfo.cpp" line="2452"/>
+ <location filename="../VBoxManageInfo.cpp" line="2453"/>
+ <source>on</source>
+ <translation>Š²ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1890"/>
+ <location filename="../VBoxManageInfo.cpp" line="1891"/>
+ <location filename="../VBoxManageInfo.cpp" line="2452"/>
+ <location filename="../VBoxManageInfo.cpp" line="2453"/>
+ <source>off</source>
+ <translation>Š²Ń‹ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1561"/>
+ <source>NIC %u:</source>
+ <translation>NIC %u:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="732"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: none (disabled)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="780"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: %RI64 %s (%RI64 %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="784"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: %RI64 %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="920"/>
+ <source> Port %u, Unit %u: UUID: %ls%s%s%s%s%s%s
+ Location: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1570"/>
+ <location filename="../VBoxManageInfo.cpp" line="1992"/>
+ <location filename="../VBoxManageInfo.cpp" line="2098"/>
+ <location filename="../VBoxManageInfo.cpp" line="2459"/>
+ <location filename="../VBoxManageInfo.cpp" line="2491"/>
+ <source>%-28s disabled
+</source>
+ <translation>%-28s Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1587"/>
+ <location filename="../VBoxManageInfo.cpp" line="1892"/>
+ <location filename="../VBoxManageInfo.cpp" line="1897"/>
+ <source>none</source>
+ <translation>Š½ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1655"/>
+ <source>%sNIC %d Rule(%d): name = %s, protocol = %s, host ip = %s, host port = %s, guest ip = %s, guest port = %s
+</source>
+ <translation>%sNIC %d ŠŸŃ€Š°Š²ŠøŠ»Š¾(%d): ŠøŠ¼Ń = %s, ŠæрŠ¾Ń‚Š¾ŠŗŠ¾Š» = %s, хŠ¾ŃŃ‚ ip = %s, хŠ¾ŃŃ‚ ŠæŠ¾Ń€Ń‚ = %s, Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ip = %s, Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠæŠ¾Ń€Ń‚ = %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1678"/>
+ <source>NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)
+</source>
+ <translation>NIC %d ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø: MTU: %d, Š”Š¾ŠŗŠµŃ‚ (Š¾Ń‚ŠæрŠ°Š²Š»ŠµŠ½Š¾: %d, ŠæрŠøŠ½ŃŃ‚Š¾: %d), ŠžŠŗŠ½Š¾ TCP (Š¾Ń‚ŠæрŠ°Š²Š»ŠµŠ½Š¾:%d, ŠæрŠøŠ½ŃŃ‚Š¾: %d)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1694"/>
+ <source>Bridged Interface &apos;%ls&apos;</source>
+ <translation>Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń Š”ŠµŃ‚ŠµŠ²Š¾Š³Š¾ ŠœŠ¾ŃŃ‚Š° &apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1708"/>
+ <source>Internal Network &apos;%s&apos;</source>
+ <translation>Š’Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŃŃ Š”ŠµŃ‚ŃŒ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1722"/>
+ <source>Host-only Interface &apos;%ls&apos;</source>
+ <translation>Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń Š’ŠøртуŠ°Š»ŃŒŠ½Š¾Š¹ Š”ŠµŃ‚Šø &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1737"/>
+ <source>Generic &apos;%ls&apos;</source>
+ <translation>ŠžŠ±Ń‰ŠøŠ¹ &apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1766"/>
+ <source>NAT Network &apos;%s&apos;</source>
+ <translation>Š”ŠµŃ‚ŃŒ NAT &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1781"/>
+ <source>Host Only Network &apos;%s&apos;</source>
+ <translation>Š’ŠøртуŠ°Š»ŃŒŠ½Š°Ń Š”ŠµŃ‚ŃŒ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1797"/>
+ <source>Cloud Network &apos;%s&apos;</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Š°Ń Š”ŠµŃ‚ŃŒ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1820"/>
+ <source>deny</source>
+ <translation>Š·Š°ŠæрŠµŃ‚Šøть</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1821"/>
+ <source>allow-vms</source>
+ <translation>рŠ°Š·Ń€ŠµŃˆŠøть Š²Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1822"/>
+ <source>allow-all</source>
+ <translation>рŠ°Š·Ń€ŠµŃˆŠøть Š²ŃŠµŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1888"/>
+ <source>%-28s MAC: %ls, Attachment: %s, Cable connected: %s, Trace: %s (file: %ls), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s, Bandwidth group: %ls
+</source>
+ <translation>%-28s MAC: %ls, ŠŸŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ: %s, ŠšŠ°Š±ŠµŠ»ŃŒ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½: %s, Š¢Ń€Š°ŃŃŠøрŠ¾Š²ŠŗŠ°: %s (фŠ°Š¹Š»: %ls), Š¢ŠøŠæ: %s, Š—Š°ŃŠ²Š»ŠµŠ½Š½Š°Ń Š”ŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ: %d MŠ±/с, ŠŸŃ€ŠøŠ¾Ń€ŠøтŠµŃ‚ Š·Š°Š³Ń€ŃƒŠ·ŠŗŠø: %d, ŠŸŠ¾Š»ŠøтŠŗŠ° ŠŠµŃ€Š°Š·Š±Š¾Ń€Ń‡ŠøŠ²Š¾ŃŃ‚Šø: %s, Š“Ń€ŃƒŠæŠæŠ° ŠŸŠ¾Š»Š¾ŃŃ‹ ŠŸŃ€Š¾ŠæусŠŗŠ°Š½Šøя: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1918"/>
+ <source>PS/2 Mouse</source>
+ <translation>PS/2 ŠœŃ‹ŃˆŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1922"/>
+ <source>USB Mouse</source>
+ <translation>USB ŠœŃ‹ŃˆŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1926"/>
+ <source>USB Tablet</source>
+ <translation>USB ŠŸŠ»Š°Š½ŃˆŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1930"/>
+ <source>USB Tablet and PS/2 Mouse</source>
+ <translation>USB ŠŸŠ»Š°Š½ŃˆŠµŃ‚ Šø PS/2 ŠœŃ‹ŃˆŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1934"/>
+ <source>USB Multi-Touch</source>
+ <translation>USB ŠœŃƒŠ»ŃŒŃ‚ŠøтŠ°Ń‡</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1940"/>
+ <source>Pointing Device:</source>
+ <translation>Š£ŠŗŠ°Š·Š°Ń‚ŠµŠ»ŃŒŠ½Š¾Šµ Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1954"/>
+ <source>PS/2 Keyboard</source>
+ <translation>PS/2 ŠšŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1958"/>
+ <source>USB Keyboard</source>
+ <translation>USB ŠšŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1962"/>
+ <source>USB and PS/2 Keyboard</source>
+ <translation>USB Šø PS/2 ŠšŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1968"/>
+ <source>Keyboard Device:</source>
+ <translation>ŠšŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1982"/>
+ <source>UART %u:</source>
+ <translation>UART %u:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2011"/>
+ <location filename="../VBoxManageInfo.cpp" line="2111"/>
+ <source>%-28s I/O base: %#06x, IRQ: %d</source>
+ <translation>%-28s Š‘Š°Š·Š° I/O: %#06x, IRQ: %d</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2019"/>
+ <source>, disconnected</source>
+ <translation>, Š¾Ń‚сŠ¾ŠµŠ“ŠøŠ½ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2026"/>
+ <source>, attached to raw file &apos;%ls&apos;
+</source>
+ <translation>, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šŗ raw фŠ°Š¹Š»Ńƒ &apos;%ls&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2034"/>
+ <source>, attached to tcp (%s) &apos;%ls&apos;</source>
+ <translation>, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šŗ tcp (%s) &apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2035"/>
+ <location filename="../VBoxManageInfo.cpp" line="2043"/>
+ <source>server</source>
+ <translation>сŠµŃ€Š²ŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2035"/>
+ <location filename="../VBoxManageInfo.cpp" line="2043"/>
+ <source>client</source>
+ <translation>ŠŗŠ»ŠøŠµŠ½Ń‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2042"/>
+ <source>, attached to pipe (%s) &apos;%ls&apos;</source>
+ <translation>, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šŗ pipe (%s) &apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2050"/>
+ <source>, attached to device &apos;%ls&apos;</source>
+ <translation>, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šŗ устрŠ¾Š¹ŃŃ‚Š²Ńƒ &apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2088"/>
+ <source>LPT %u:</source>
+ <translation>LPT %u:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2115"/>
+ <source>, attached to device &apos;%ls&apos;
+</source>
+ <translation>, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Šŗ устрŠ¾Š¹ŃŃ‚Š²Ńƒ &apos;%ls&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <source>Audio:</source>
+ <translation>ŠŃƒŠ“ŠøŠ¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2242"/>
+ <source> (Driver: %s, Controller: %s, Codec: %s)</source>
+ <translation> (Š”Ń€Š°Š¹Š²ŠµŃ€: %s, ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€: %s, ŠšŠ¾Š“ŠµŠŗ: %s)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2245"/>
+ <source>Audio playback:</source>
+ <translation>ŠŃƒŠ“ŠøŠ¾ Š²Š¾ŃŠæрŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2246"/>
+ <source>Audio capture:</source>
+ <translation>ŠŃƒŠ“ŠøŠ¾ Š·Š°Ń…Š²Š°Ń‚:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2260"/>
+ <location filename="../VBoxManageInfo.cpp" line="2289"/>
+ <source>HostToGuest</source>
+ <translation>Š„Š¾ŃŃ‚-&gt;Š“Š¾ŃŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2263"/>
+ <location filename="../VBoxManageInfo.cpp" line="2292"/>
+ <source>GuestToHost</source>
+ <translation>Š“Š¾ŃŃ‚ŃŒ-&gt;Š„Š¾ŃŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2266"/>
+ <location filename="../VBoxManageInfo.cpp" line="2295"/>
+ <source>Bidirectional</source>
+ <translation>Š”Š²ŃƒŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2272"/>
+ <source>Clipboard Mode:</source>
+ <translation>Š ŠµŠ¶ŠøŠ¼ Š±ŃƒŃ„ŠµŃ€Š° Š¾Š±Š¼ŠµŠ½Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2274"/>
+ <source>Clipboard file transfers:</source>
+ <translation>ŠŸŠµŃ€ŠµŠ“Š°Ń‡Š° фŠ°Š¹Š»Š¾Š² чŠµŃ€ŠµŠ· Š±ŃƒŃ„ŠµŃ€ Š¾Š±Š¼ŠµŠ½Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2301"/>
+ <source>Drag and drop Mode:</source>
+ <translation>Š ŠµŠ¶ŠøŠ¼ Drag and Drop:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2312"/>
+ <source>Session name:</source>
+ <translation>Š˜Š¼Ń сŠµŃŃŠøŠø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2345"/>
+ <source>unknown status</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Ń‹Š¹ стŠ°Ń‚ŃƒŃ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2348"/>
+ <source>blank</source>
+ <translation>ŠæустŠ¾Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2353"/>
+ <source>Video mode:</source>
+ <translation>Š’ŠøŠ“ŠµŠ¾ рŠµŠ¶ŠøŠ¼:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2394"/>
+ <source>null</source>
+ <translation>ŠæустŠ¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2400"/>
+ <source>external</source>
+ <translation>Š²Š½ŠµŃˆŠ½ŠøŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2406"/>
+ <source>guest</source>
+ <translation>Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2451"/>
+ <source>%-28s enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)
+</source>
+ <translation>%-28s Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ (ŠŠ“рŠµŃ %ls, ŠŸŠ¾Ń€Ń‚Ń‹ %ls, ŠœŠ½Š¾Š³Š¾ Š”Š¾ŠµŠ“ŠøŠ½ŠµŠ½ŠøŠ¹: %s, ŠžŠ“Š½Š¾ Š”Š¾ŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ : %s, Š¢ŠøŠæ ŠŃƒŃ‚ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń†ŠøŠø: %s)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2455"/>
+ <source>VRDE port:</source>
+ <translation>ŠŸŠ¾Ń€Ń‚ VRDE:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2457"/>
+ <source>%-28s enabled (Quality %ls)
+</source>
+ <translation>%-28s Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ (ŠšŠ°Ń‡ŠµŃŃ‚Š²Š¾ %ls)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2457"/>
+ <location filename="../VBoxManageInfo.cpp" line="2459"/>
+ <source>Video redirection:</source>
+ <translation>Š’ŠøŠ“ŠµŠ¾ ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2479"/>
+ <source>%-28s: %-10lS = &lt;not set&gt;
+</source>
+ <translation>%-28s: %-10lS = &lt;Š½Šµ Š·Š°Š“Š°Š½&gt;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2479"/>
+ <location filename="../VBoxManageInfo.cpp" line="2481"/>
+ <source>VRDE property</source>
+ <translation>Š”Š²Š¾Š¹ŃŃ‚Š²Š¾ VRDE</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2552"/>
+ <source>Index:</source>
+ <translation>Š˜Š½Š“ŠµŠŗс:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source>yes</source>
+ <translation>Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source>no</source>
+ <translation>Š½ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="840"/>
+ <source>VendorId:</source>
+ <translation>ID ŠæŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="841"/>
+ <source>ProductId:</source>
+ <translation>ID ŠæрŠ¾Š“уŠŗтŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="850"/>
+ <source>Revision:</source>
+ <translation>Š ŠµŠ²ŠøŠ·Šøя:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="852"/>
+ <source>Manufacturer:</source>
+ <translation>ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøтŠµŠ»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="853"/>
+ <source>Product:</source>
+ <translation>ŠŸŃ€Š¾Š“уŠŗт:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2567"/>
+ <source>Masked Interfaces:</source>
+ <translation>Š”ŠŗрытыŠµ Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃ‹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="854"/>
+ <source>SerialNumber:</source>
+ <translation>Š”ŠµŃ€ŠøŠ¹Š½Ń‹Š¹ ŠŠ¾Š¼ŠµŃ€:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="855"/>
+ <source>Address:</source>
+ <translation>ŠŠ“рŠµŃ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2604"/>
+ <source>
+Attached physical PCI devices:
+
+</source>
+ <translation>
+ŠŸŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Šµ фŠøŠ·ŠøчŠµŃŠŗŠøŠµ PCI устрŠ¾Š¹ŃŃ‚Š²Š°:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2623"/>
+ <source> Host device %ls at %s attached as %s
+</source>
+ <translation> Š„Š¾ŃŃ‚ устрŠ¾Š¹ŃŃ‚Š²Š¾ %ls Š² %s, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Š¾Šµ ŠŗŠ°Šŗ %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2652"/>
+ <source>Shared folders:</source>
+ <translation>ŠžŠ±Ń‰ŠøŠµ ŠŸŠ°ŠæŠŗŠø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2662"/>
+ <source>global mapping</source>
+ <translation>Š³Š»Š¾Š±Š°Š»ŃŒŠ½Š¾Šµ Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2674"/>
+ <source>machine mapping</source>
+ <translation>Š¼Š°ŃˆŠøŠ½Š½Š¾Šµ Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2686"/>
+ <source>transient mapping</source>
+ <translation>Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾Šµ Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="709"/>
+ <location filename="../VBoxManageInfo.cpp" line="2693"/>
+ <source>&lt;none&gt;
+</source>
+ <translation>&lt;Š½ŠµŃ‚&gt;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1502"/>
+ <location filename="../VBoxManageInfo.cpp" line="1542"/>
+ <source>Storage Controllers:</source>
+ <translation>ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Ń‹ Š½Š¾ŃŠøтŠµŠ»ŠµŠ¹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1532"/>
+ <source>#%u: &apos;%ls&apos;, Type: %s, Instance: %u, Ports: %u (max %u), %s
+</source>
+ <translation>#%u: &apos;%ls&apos;, Š¢ŠøŠæ: %s, Š­ŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€: %u, ŠŸŠ¾Ń€Ń‚Ń‹: %u (Š¼Š°Šŗс. %u), %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1534"/>
+ <source>Bootable</source>
+ <translation>Š—Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1534"/>
+ <source>Not bootable</source>
+ <translation>ŠŠµŠ·Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Ń‹Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2546"/>
+ <source>USB Device Filters:
+</source>
+ <translation>Š¤ŠøŠ»ŃŒŃ‚ры USB устрŠ¾Š¹ŃŃ‚Š²:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source> Active:</source>
+ <translation> ŠŠŗтŠøŠ²Š½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2554"/>
+ <source> Name:</source>
+ <translation> Š˜Š¼Ń:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2555"/>
+ <source> VendorId:</source>
+ <translation> ID ŠæŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2556"/>
+ <source> ProductId:</source>
+ <translation> ID ŠæрŠ¾Š“уŠŗтŠ°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2557"/>
+ <source> Revision:</source>
+ <translation> Š ŠµŠ²ŠøŠ·Šøя:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2558"/>
+ <source> Manufacturer:</source>
+ <translation> ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøтŠµŠ»ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2559"/>
+ <source> Product:</source>
+ <translation> ŠŸŃ€Š¾Š“уŠŗт:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2560"/>
+ <source> Remote:</source>
+ <translation> Š£Š“Š°Š»ŠµŠ½Š½Š¾Šµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2561"/>
+ <source> Serial Number:</source>
+ <translation> Š”ŠµŃ€ŠøŠ¹Š½Ń‹Š¹ Š½Š¾Š¼ŠµŃ€:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2572"/>
+ <source>USB Device Filters:</source>
+ <translation>Š¤ŠøŠ»ŃŒŃ‚ры USB устрŠ¾Š¹ŃŃ‚Š²:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2580"/>
+ <source>Available remote USB devices:</source>
+ <translation>Š”Š¾ŃŃ‚ŃƒŠæŠ½Ń‹Šµ уŠ“Š°Š»ŠµŠ½Š½Ń‹Šµ USB устрŠ¾Š¹ŃŃ‚Š²Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2588"/>
+ <source>Currently attached USB devices:</source>
+ <translation>Š”ŠµŠ¹Ń‡Š°Ń ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Šµ USB устрŠ¾Š¹ŃŃ‚Š²Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2639"/>
+ <source>Bandwidth groups:</source>
+ <translation>Š“Ń€ŃƒŠæŠæы ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <source>VRDE Connection:</source>
+ <translation>VRDE Š”Š¾ŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>active</source>
+ <translation>Š°ŠŗтŠøŠ²Š½Š¾Šµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2739"/>
+ <source>Clients so far:</source>
+ <translation>ŠšŠ»ŠøŠµŠ½Ń‚Ń‹ Š½Š° Š“Š°Š½Š½Ń‹Š¹ Š¼Š¾Š¼ŠµŠ½Ń‚:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2746"/>
+ <source>Start time:</source>
+ <translation>Š’Ń€ŠµŠ¼Ń стŠ°Ń€Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2749"/>
+ <source>Last started:</source>
+ <translation>ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŠøŠ¹ рŠ°Š· Š½Š°Ń‡Š°Ń‚Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2751"/>
+ <source>Last ended:</source>
+ <translation>ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŠøŠ¹ рŠ°Š· Š·Š°ŠŗŠ¾Š½Ń‡ŠµŠ½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2761"/>
+ <source>Sent:</source>
+ <translation>ŠžŃ‚ŠæрŠ°Š²Š»ŠµŠ½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2761"/>
+ <location filename="../VBoxManageInfo.cpp" line="2763"/>
+ <location filename="../VBoxManageInfo.cpp" line="2765"/>
+ <location filename="../VBoxManageInfo.cpp" line="2767"/>
+ <source>Bytes</source>
+ <translation>Š‘Š°Š¹Ń‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2762"/>
+ <source>Average speed:</source>
+ <translation>Š”рŠµŠ“Š½ŃŃ сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2762"/>
+ <location filename="../VBoxManageInfo.cpp" line="2766"/>
+ <source>B/s</source>
+ <translation>Š‘/с</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2763"/>
+ <source>Sent total:</source>
+ <translation>Š’сŠµŠ³Š¾ Š¾Ń‚ŠæрŠ°Š²Š»ŠµŠ½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2765"/>
+ <source>Received:</source>
+ <translation>ŠŸŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2766"/>
+ <source>Speed:</source>
+ <translation>Š”ŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2767"/>
+ <source>Received total:</source>
+ <translation>Š’сŠµŠ³Š¾ ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Š¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2771"/>
+ <source>User name:</source>
+ <translation>Š˜Š¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2772"/>
+ <source>Domain:</source>
+ <translation>Š”Š¾Š¼ŠµŠ½:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2773"/>
+ <source>Client name:</source>
+ <translation>Š˜Š¼Ń ŠŗŠ»ŠøŠµŠ½Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2774"/>
+ <source>Client IP:</source>
+ <translation>IP ŠŗŠ»ŠøŠµŠ½Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2775"/>
+ <source>Client version:</source>
+ <translation>Š’ŠµŃ€ŃŠøя ŠŗŠ»ŠøŠµŠ½Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2776"/>
+ <source>Encryption:</source>
+ <translation>ŠØŠøфрŠ¾Š²Š°Š½ŠøŠµ:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <source>Capturing:</source>
+ <translation>Š—Š°Ń…Š²Š°Ń‚:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>Capture audio:</source>
+ <translation>Š—Š°Ń…Š²Š°Ń‚ Š°ŃƒŠ“ŠøŠ¾:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2840"/>
+ <source>Capture screens:</source>
+ <translation>Š—Š°Ń…Š²Š°Ń‚ эŠŗрŠ°Š½Š¾Š²:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2841"/>
+ <source>Capture file:</source>
+ <translation>Š¤Š°Š¹Š» Š·Š°Ń…Š²Š°Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2843"/>
+ <source>Capture dimensions:</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€Ń‹ Š·Š°Ń…Š²Š°Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2844"/>
+ <source>Capture rate:</source>
+ <translation>Š‘ŠøтрŠµŠ¹Ń‚ Š·Š°Ń…Š²Š°Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2844"/>
+ <location filename="../VBoxManageInfo.cpp" line="2845"/>
+ <source>kbps</source>
+ <translation>ŠŗŠ±/с</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2845"/>
+ <source>Capture FPS:</source>
+ <translation>FPS Š·Š°Ń…Š²Š°Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2846"/>
+ <source>Capture options:</source>
+ <translation>ŠžŠæцŠøŠø Š·Š°Ń…Š²Š°Ń‚Š°:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2863"/>
+ <source>Description:
+%ls
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ
+%ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2919"/>
+ <source>MB</source>
+ <translation>ŠœŠ‘</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2919"/>
+ <source>Configured memory balloon:</source>
+ <translation>ŠŠ°ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¹ balloon ŠæŠ°Š¼ŃŃ‚Šø:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2927"/>
+ <source>OS type:</source>
+ <translation>Š¢ŠøŠæ ŠžŠ”:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2932"/>
+ <source>Additions run level:</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2944"/>
+ <source>Additions version:</source>
+ <translation>Š’ŠµŃ€ŃŠøя Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹:</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2973"/>
+ <source>Facility &quot;%ls&quot;: %s (last update: %s)
+</source>
+ <translation>Š”рŠµŠ“стŠ²Š¾ &quot;%ls&quot;: %s (ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠµŠµ Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠµ: %s)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3044"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3054"/>
+ <source>VM name or UUID required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠøŠ¼Ń Š’Šœ ŠøŠ»Šø UUID</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3065"/>
+ <source>Option --log is exclusive</source>
+ <translation>ŠžŠæцŠøя --log эŠŗсŠŗŠ»ŃŽŠ·ŠøŠ²Š½Š°Ń</translation>
+ </message>
+</context>
+<context>
+ <name>Internal</name>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="169"/>
+ <source>Usage: VBoxManage internalcommands &lt;command&gt; [command arguments]
+
+Commands:
+
+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%sWARNING: This is a development tool and shall only be used to analyse
+ problems. It is completely unsupported and will change in
+ incompatible ways without warning.
+</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ: VBoxManage internalcommands &lt;ŠŗŠ¾Š¼Š°Š½Š“Š°&gt; [Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Ń‹ ŠŗŠ¾Š¼Š°Š½Š“ы]
+
+ŠšŠ¾Š¼Š°Š½Š“ы:
+
+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%sŠŸŠ Š•Š”Š£ŠŸŠ Š•Š–Š”Š•ŠŠ˜Š•: Š­Ń‚Š¾ ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ рŠ°Š·Ń€Š°Š±Š¾Ń‚чŠøŠŗŠ° Šø Š“Š¾Š»Š¶ŠµŠ½ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ
+ тŠ¾Š»ŃŒŠŗŠ¾ Š“Š»Ń Š°Š½Š°Š»ŠøŠ·Š° ŠæрŠ¾Š±Š»ŠµŠ¼. ŠžŠ½ Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся Š²Š¾Š¾Š±Ń‰Šµ
+ Šø Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½ Š±ŠµŠ· ŠæрŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½Šøя Šø Š±ŠµŠ· сŠ¾Ń…Ń€Š°Š½ŠµŠ½Šøя
+ сŠ¾Š²Š¼ŠµŃŃ‚ŠøŠ¼Š¾ŃŃ‚Šø.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="180"/>
+ <source> loadmap &lt;vmname|uuid&gt; &lt;symfile&gt; &lt;address&gt; [module] [subtrahend] [segment]
+ This will instruct DBGF to load the given map file
+ during initialization. (See also loadmap in the debugger.)
+
+</source>
+ <translation> loadmap &lt;ŠøŠ¼Ń Š²Š¼|uuid&gt; &lt;фŠ°Š¹Š» сŠøŠ¼Š²Š¾Š»Š¾Š²&gt; &lt;Š°Š“рŠµŃ&gt; [module] [subtrahend] [segment]
+ ŠžŠ½Š° Š³Š¾Š²Š¾Ń€Šøт DBGF Š·Š°Š³Ń€ŃƒŠ·Šøть уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ map фŠ°Š¹Š» Š²Š¾ Š²Ń€ŠµŠ¼Ń
+ ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†ŠøŠø. (Š”Š¼Š¾Ń‚Ń€Šø loadmap у Š¾Ń‚Š»Š°Š“чŠøŠŗŠ°.)
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="187"/>
+ <source> loadsyms &lt;vmname|uuid&gt; &lt;symfile&gt; [delta] [module] [module address]
+ This will instruct DBGF to load the given symbol file
+ during initialization.
+
+</source>
+ <translation> loadmap &lt;ŠøŠ¼Ń Š²Š¼|uuid&gt; &lt;фŠ°Š¹Š» сŠøŠ¼Š²Š¾Š»Š¾Š²&gt; [delta] [module] [module address]
+ ŠžŠ½Š° Š³Š¾Š²Š¾Ń€Šøт DBGF Š·Š°Š³Ń€ŃƒŠ·Šøть уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ фŠ°Š¹Š» сŠøŠ¼Š²Š¾Š»Š¾Š²
+ Š²Š¾ Š²Ń€ŠµŠ¼Ń ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·Š°Ń†ŠøŠø.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="194"/>
+ <source> sethduuid &lt;filepath&gt; [&lt;uuid&gt;]
+ Assigns a new UUID to the given image file. This way, multiple copies
+ of a container can be registered.
+
+</source>
+ <translation> sethduuid &lt;Šæуть Šŗ фŠ°Š¹Š»Ńƒ&gt; [&lt;uuid&gt;]
+ ŠŠ°Š·Š½Š°Ń‡Š°ŠµŃ‚ Š½Š¾Š²Ń‹Š¹ UUID Š“Š°Š½Š½Š¾Š¼Ńƒ фŠ°Š¹Š»Ńƒ Š¾Š±Ń€Š°Š·Š°. Š¢Š°ŠŗŠøŠ¼ Š¾Š±Ń€Š°Š·Š¾Š¼, Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ
+ Š·Š°Ń€ŠµŠ³ŠøстрŠøрŠ¾Š²Š°Š½Š¾ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ ŠŗŠ¾ŠæŠøŠ¹ Š¾Š“Š½Š¾Š³Š¾ Šø тŠ¾Š³Š¾ Š¶Šµ ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€Š°.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="201"/>
+ <source> sethdparentuuid &lt;filepath&gt; &lt;uuid&gt;
+ Assigns a new parent UUID to the given image file.
+
+</source>
+ <translation> sethdparentuuid &lt;Šæуть Šŗ фŠ°Š¹Š»Ńƒ&gt; &lt;uuid&gt;
+ ŠŠ°Š·Š½Š°Ń‡Š°ŠµŃ‚ Š½Š¾Š²Ń‹Š¹ рŠ¾Š“ŠøтŠµŠ»ŃŒŃŠŗŠøŠ¹ UUID Š“Š°Š½Š½Š¾Š¼Ńƒ фŠ°Š¹Š»Ńƒ Š¾Š±Ń€Š°Š·Š°.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="207"/>
+ <source> dumphdinfo &lt;filepath&gt;
+ Prints information about the image at the given location.
+
+</source>
+ <translation> dumphdinfo &lt;Šæуть Šŗ фŠ°Š¹Š»Ńƒ&gt;
+ Š’Ń‹Š²Š¾Š“Šøт ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š¾Š± Š¾Š±Ń€Š°Š·Šµ ŠæŠ¾ уŠŗŠ°Š·Š°Š½Š½Š¾Š¼Ńƒ рŠ°ŃŠæŠ¾Š»Š¾Š¶ŠµŠ½Šøю.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="213"/>
+ <source> listpartitions -rawdisk &lt;diskname&gt;
+ Lists all partitions on &lt;diskname&gt;.
+
+</source>
+ <translation> listpartitions -rawdisk &lt;ŠøŠ¼Ń Š“ŠøсŠŗŠ°&gt;
+ ŠŸŠµŃ€ŠµŃ‡ŠøсŠ»Šøть Š²ŃŠµ рŠ°Š·Š“ŠµŠ»Ń‹ Š½Š° &lt;ŠøŠ¼Ń Š“ŠøсŠŗŠ°&gt;.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="219"/>
+ <source> createrawvmdk -filename &lt;filename&gt; -rawdisk &lt;diskname&gt;
+ [-partitions &lt;list of partition numbers&gt; [-mbr &lt;filename&gt;] ]
+ [-relative]
+ Creates a new VMDK image which gives access to an entire host disk (if
+ the parameter -partitions is not specified) or some partitions of a
+ host disk. If access to individual partitions is granted, then the
+ parameter -mbr can be used to specify an alternative MBR to be used
+ (the partitioning information in the MBR file is ignored).
+ The diskname is on Linux e.g. /dev/sda, and on Windows e.g.
+ \\.\PhysicalDrive0).
+ On Linux or FreeBSD host the parameter -relative causes a VMDK file to
+ be created which refers to individual partitions instead to the entire
+ disk.
+ The necessary partition numbers can be queried with
+ VBoxManage internalcommands listpartitions
+
+</source>
+ <translation> createrawvmdk -filename &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt; -rawdisk &lt;ŠøŠ¼Ń Š“ŠøсŠŗŠ°&gt;
+ [-partitions &lt;сŠæŠøсŠ¾Šŗ Š½Š¾Š¼ŠµŃ€Š¾Š² рŠ°Š·Š“ŠµŠ»Š¾Š²&gt; [-mbr &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt;] ]
+ [-relative]
+ Š”Š¾Š·Š“Š°ŠµŃ‚ Š½Š¾Š²Ń‹Š¹ Š¾Š±Ń€Š°Š· VMDK, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š“Š°ŠµŃ‚ Š“Š¾ŃŃ‚ŃƒŠæ ŠŗŠ¾ Š²ŃŠµŠ¼Ńƒ Š“ŠøсŠŗу (ŠµŃŠ»Šø
+ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -partitions Š½Šµ уŠŗŠ°Š·Š°Š½) ŠøŠ»Šø Šŗ Š½ŠµŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¼ рŠ°Š·Š“ŠµŠ»Š°Š¼ Š“ŠøсŠŗŠ° хŠ¾ŃŃ‚Š°.
+ Š•ŃŠ»Šø Š“Š¾ŃŃ‚ŃƒŠæ Šŗ ŠŗŠ¾Š½ŠŗрŠµŃ‚Š½Ń‹Š¼ рŠ°Š·Š“ŠµŠ»Š°Š¼ рŠ°Š·Ń€ŠµŃˆŠµŠ½, ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -mbr Š¼Š¾Š¶ŠµŃ‚
+ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ Š“Š»Ń уŠŗŠ°Š·Š°Š½Šøя Š°Š»ŃŒŃ‚ŠµŃ€Š½Š°Ń‚ŠøŠ²Š½Š¾Š³Š¾ MBR (ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾ рŠ°Š·Š“ŠµŠ»Š°Ń…
+ Š² MBR фŠ°Š¹Š»Šµ ŠøŠ³Š½Š¾Ń€ŠøруŠµŃ‚ся). Š˜Š¼Ń Š“ŠøсŠŗŠ° Š² Linux - этŠ¾ Š½Š°ŠæрŠøŠ¼ŠµŃ€ /dev/sda,
+ Š° Š² Windows - Š½Š°ŠæрŠøŠ¼ŠµŃ€ \\.\PhysicalDrive0.
+ Š’ хŠ¾ŃŃ‚Š°Ń… Linux ŠøŠ»Šø FreeBSD, ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -relative Š·Š°ŃŃ‚Š°Š²Š»ŃŠµŃ‚ сŠ¾Š·Š“Š°Ń‚ŃŒ фŠ°Š¹Š»
+ VMDK, ссыŠ»Š°ŃŽŃ‰ŠøŠ¹ŃŃ Š½Š° ŠøŠ½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Šµ рŠ°Š·Š“ŠµŠ»Ń‹ Š²Š¼ŠµŃŃ‚Š¾ Š²ŃŠµŠ³Š¾ Š“ŠøсŠŗŠ°.
+ ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Ń‹Šµ Š½Š¾Š¼ŠµŃ€Š° рŠ°Š·Š“ŠµŠ»Š¾Š² Š¼Š¾Š³ŃƒŃ‚ Š±Ń‹Ń‚ŃŒ ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Ń‹ чŠµŃ€ŠµŠ·
+ VBoxManage internalcommands listpartitions
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="238"/>
+ <source> renamevmdk -from &lt;filename&gt; -to &lt;filename&gt;
+ Renames an existing VMDK image, including the base file and all its extents.
+
+</source>
+ <translation> renamevmdk -from &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt; -to &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt;
+ ŠŸŠµŃ€ŠµŠ¼ŠµŠ½Š¾Š²Ń‹Š²Š°ŠµŃ‚ сущŠµŃŃ‚Š²ŃƒŃŽŃ‰ŠøŠ¹ VMDK Š¾Š±Ń€Š°Š·, Š²ŠŗŠ»ŃŽŃ‡Š°ŃŃ Š±Š°Š·Š¾Š²Ń‹Š¹ фŠ°Š¹Š» Šø Š²ŃŠµ ŠµŠ³Š¾ эŠŗстŠµŠ½Ń‚Ń‹.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="245"/>
+ <source> converttoraw [-format &lt;fileformat&gt;] &lt;filename&gt; &lt;outputfile&gt;|stdout
+ Convert image to raw, writing to file or stdout.
+
+</source>
+ <translation> converttoraw [-format &lt;фŠ¾Ń€Š¼Š°Ń‚ фŠ°Š¹Š»Š°&gt;] &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt; &lt;Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»&gt;|stdout
+ ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š¾Š±Ń€Š°Š· Š² raw, Š·Š°ŠæŠøсыŠ²Š°Ń Š² фŠ°Š¹Š» ŠøŠ»Šø stdout.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="251"/>
+ <source> converttoraw [-format &lt;fileformat&gt;] &lt;filename&gt; &lt;outputfile&gt;
+ Convert image to raw, writing to file.
+
+</source>
+ <translation> converttoraw [-format &lt;фŠ¾Ń€Š¼Š°Ń‚ фŠ°Š¹Š»Š°&gt;] &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt; &lt;Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»&gt;
+ ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š¾Š±Ń€Š°Š· Š² raw, Š·Š°ŠæŠøсыŠ²Š°Ń Š² фŠ°Š¹Š».
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="259"/>
+ <source> converthd [-srcformat VDI|VMDK|VHD|RAW]
+ [-dstformat VDI|VMDK|VHD|RAW]
+ &lt;inputfile&gt; &lt;outputfile&gt;
+ converts hard disk images between formats
+
+</source>
+ <translation> converthd [-srcformat VDI|VMDK|VHD|RAW]
+ [-dstformat VDI|VMDK|VHD|RAW]
+ &lt;Š²Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»&gt; &lt;Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»&gt;
+ ŠæрŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š¾Š±Ń€Š°Š·Ń‹ Š¶ŠµŃŃ‚ŠŗŠøх Š“ŠøсŠŗŠ¾Š² Š² рŠ°Š·Š½Ń‹Šµ фŠ¾Ń€Š¼Š°Ń‚Ń‹
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="267"/>
+ <source> repairhd [-dry-run]
+ [-format VDI|VMDK|VHD|...]
+ &lt;filename&gt;
+ Tries to repair corrupted disk images
+
+</source>
+ <translation> repairhd [-dry-run]
+ [-format VDI|VMDK|VHD|...]
+ &lt;ŠøŠ¼Ń фŠ°Š¹Š»Š°&gt;
+ ŠŸŃ‹Ń‚Š°ŠµŃ‚ся Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Šøть ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½Š½Ń‹Š¹ Š¾Š±Ń€Š°Š· Š“ŠøсŠŗŠ°
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="276"/>
+ <source> modinstall
+ Installs the necessary driver for the host OS
+
+</source>
+ <translation> modinstall
+ Š£ŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°ŠµŃ‚ Š½ŃƒŠ¶Š½Ń‹Š¹ Š“рŠ°Š¹Š²ŠµŃ€ Š² ŠžŠ” хŠ¾ŃŃ‚Š°
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="282"/>
+ <source> moduninstall
+ Deinstalls the driver
+
+</source>
+ <translation> moduninstall
+ Š£Š“Š°Š»ŃŠµŃ‚ Š“рŠ°Š¹Š²ŠµŃ€
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="292"/>
+ <source> debuglog &lt;vmname|uuid&gt; [--enable|--disable] [--flags todo]
+ [--groups todo] [--destinations todo]
+ Controls debug logging.
+
+</source>
+ <translation> debuglog &lt;ŠøŠ¼Ń Š²Š¼|uuid&gt; [--enable|--disable] [--flags todo]
+ [--groups todo] [--destinations todo]
+ ŠšŠ¾Š½Ń‚Ń€Š¾Š»ŠøруŠµŃ‚ Š¾Ń‚Š»Š°Š“Š¾Ń‡Š½Š¾Šµ Š¶ŃƒŃ€Š½Š°Š»ŠøрŠ¾Š²Š°Š½ŠøŠµ.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="299"/>
+ <source> passwordhash &lt;password&gt;
+ Generates a password hash.
+
+</source>
+ <translation> passwordhash &lt;ŠæŠ°Ń€Š¾Š»ŃŒ&gt;
+ Š“ŠµŠ½ŠµŃ€ŠøруŠµŃ‚ хэш ŠæŠ°Ń€Š¾Š»Ń.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="305"/>
+ <source> gueststats &lt;vmname|uuid&gt; [--interval &lt;seconds&gt;]
+ Obtains and prints internal guest statistics.
+ Sets the update interval if specified.
+
+</source>
+ <translation> gueststats &lt;ŠøŠ¼Ń Š²Š¼|uuid&gt; [--interval &lt;сŠµŠŗуŠ½Š“ы&gt;]
+ ŠŸŠ¾Š»ŃƒŃ‡Š°ŠµŃ‚ Šø Š²Ń‹Š²Š¾Š“Šøт Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŃŽŃŽ стŠ°Ń‚ŠøстŠøŠŗу Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ сŠøстŠµŠ¼Ń‹.
+ Š—Š°Š“Š°ŠµŃ‚ ŠøŠ½Ń‚ŠµŃ€Š²Š°Š» Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя ŠµŃŠ»Šø уŠŗŠ°Š·Š°Š½Š¾.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="451"/>
+ <source>Cannot find unique key for &apos;%s&apos;!</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø уŠ½ŠøŠŗŠ°Š»ŃŒŠ½Ń‹Š¹ ŠŗŠ»ŃŽŃ‡ Š“Š»Ń &apos;%s&apos;!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="514"/>
+ <source>Failed to delete key &apos;%s&apos; from &apos;%s&apos;, string conversion error %Rrc!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть ŠŗŠ»ŃŽŃ‡ &apos;%s&apos; ŠøŠ· &apos;%s&apos;, Š¾ŃˆŠøŠ±ŠŗŠ° ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½Šøя стрŠ¾Šŗ %Rrc!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="538"/>
+ <source>Failed to set &apos;%s/%s/%s&apos; to &apos;%s&apos;! hrc=%#x</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ &apos;%s/%s/%s&apos; Š² &apos;%s&apos;! hrc=%#x</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="606"/>
+ <location filename="../VBoxInternalManage.cpp" line="683"/>
+ <source>Missing the filename argument!
+</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ ŠøŠ¼ŠµŠ½Šø фŠ°Š¹Š»Š°!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="614"/>
+ <source>Failed to read delta &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š“ŠµŠ»ŃŒŃ‚Ńƒ &apos;%s&apos;, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="626"/>
+ <location filename="../VBoxInternalManage.cpp" line="691"/>
+ <source>Failed to read module address &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š°Š“рŠµŃ Š¼Š¾Š“уŠ»Ń &apos;%s&apos;, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="634"/>
+ <source>Failed to read module size &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ рŠ°Š·Š¼ŠµŃ€ Š¼Š¾Š“уŠ»Ń &apos;%s&apos;, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="688"/>
+ <source>Missing the module address argument!
+</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Š°Š“рŠµŃŠ° Š¼Š¾Š“уŠ»Ń!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="702"/>
+ <source>Failed to read subtrahend &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š²Ń‹Ń‡ŠøтŠ°ŠµŠ¼Š¾Šµ &apos;%s&apos;, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="710"/>
+ <source>Failed to read segment number &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ Š½Š¾Š¼ŠµŃ€ сŠµŠ³Š¼ŠµŠ½Ń‚Š° &apos;%s&apos;, rc=%Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="737"/>
+ <source>Error code %Rrc at %s(%u) in function %s</source>
+ <translation>ŠšŠ¾Š“ Š¾ŃˆŠøŠ±ŠŗŠø %Rrc Š² %s(%u) Š² фуŠ½ŠŗцŠøŠø %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="760"/>
+ <location filename="../VBoxInternalManage.cpp" line="774"/>
+ <location filename="../VBoxInternalManage.cpp" line="832"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="765"/>
+ <location filename="../VBoxInternalManage.cpp" line="776"/>
+ <source>Invalid UUID parameter</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ UUID ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="780"/>
+ <source>Invalid invocation</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Ń‹Š·Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="788"/>
+ <location filename="../VBoxInternalManage.cpp" line="841"/>
+ <source>Format autodetect failed: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š°Š²Ń‚Š¾Š“ŠµŃ‚ŠµŠŗтŠøрŠ¾Š²Š°Ń‚ŃŒ фŠ¾Ń€Š¼Š°Ń‚: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="803"/>
+ <location filename="../VBoxInternalManage.cpp" line="856"/>
+ <location filename="../VBoxInternalManage.cpp" line="1958"/>
+ <location filename="../VBoxInternalManage.cpp" line="2056"/>
+ <location filename="../VBoxInternalManage.cpp" line="2130"/>
+ <source>Cannot create the virtual disk container: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="808"/>
+ <location filename="../VBoxInternalManage.cpp" line="861"/>
+ <source>Cannot open the image: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть Š¾Š±Ń€Š°Š·: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="815"/>
+ <source>Cannot set a new UUID: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š·Š°Š“Š°Ń‚ŃŒ Š½Š¾Š²Ń‹Š¹ UUID: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="817"/>
+ <source>UUID changed to: %s
+</source>
+ <translation>UUID ŠøŠ·Š¼ŠµŠ½ŠµŠ½ Š½Š°: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="942"/>
+ <source>The GPT header seems corrupt because it contains too many entries</source>
+ <translation>ŠšŠ°Š¶ŠµŃ‚ся, GPT Š·Š°Š³Š¾Š»Š¾Š²Š¾Šŗ ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½, ŠæŠ¾Ń‚Š¾Š¼Ńƒ чтŠ¾ Š¾Š½ сŠ¾Š“ŠµŃ€Š¶Šøт сŠ»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ эŠ»ŠµŠ¼ŠµŠ½Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="949"/>
+ <source>Allocating memory for the GPT partitions entries failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ Š“Š»Ń эŠ»ŠµŠ¼ŠµŠ½Ń‚Š¾Š² GPT рŠ°Š·Š“ŠµŠ»Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="958"/>
+ <source>Reading the partition table failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ тŠ°Š±Š»Šøцу рŠ°Š·Š“ŠµŠ»Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1042"/>
+ <source>More than one extended partition</source>
+ <translation>Š‘Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°ŃŃˆŠøрŠµŠ½Š½Š¾Š³Š¾ рŠ°Š·Š“ŠµŠ»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1060"/>
+ <source>Inconsistency for logical partition start</source>
+ <translation>ŠŠµŃŠ¾Š³Š»Š°ŃŠ¾Š²Š°Š½Š½Š¾ŃŃ‚ŃŒ Š½Š°Ń‡Š°Š»Š° Š»Š¾Š³ŠøчŠµŃŠŗŠ¾Š³Š¾ рŠ°Š·Š“ŠµŠ»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1072"/>
+ <source>Logical partition without magic</source>
+ <translation>Š›Š¾Š³ŠøчŠµŃŠŗŠøŠ¹ рŠ°Š·Š“ŠµŠ» Š±ŠµŠ· magic</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1079"/>
+ <source>Logical partition with type 0 encountered</source>
+ <translation>Š”тŠ¾Š»ŠŗŠ½ŃƒŠ»Šøсь с Š»Š¾Š³ŠøчŠµŃŠŗŠøŠ¼ рŠ°Š·Š“ŠµŠ»Š¾Š¼ тŠøŠæŠ° 0</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1096"/>
+ <source>Invalid partition start offset</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ сŠ¼ŠµŃ‰ŠµŠ½ŠøŠµ Š½Š°Ń‡Š°Š»Š° рŠ°Š·Š“ŠµŠ»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1116"/>
+ <source>Logical partition chain broken</source>
+ <translation>Š¦ŠµŠæŠ¾Ń‡ŠŗŠ° Š»Š¾Š³ŠøчŠµŃŠŗŠøх рŠ°Š·Š“ŠµŠ»Š¾Š² ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1139"/>
+ <source>Two partitions start at the same place</source>
+ <translation>Š”Š²Š° рŠ°Š·Š“ŠµŠ»Š° Š½Š°Ń‡ŠøŠ½Š°ŃŽŃ‚ся с Š¾Š“Š½Š¾Š³Š¾ Šø тŠ¾Š³Š¾ Š¶Šµ Š¼ŠµŃŃ‚Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1144"/>
+ <source>Partition starts at sector 0</source>
+ <translation>Š Š°Š·Š“ŠµŠ» Š½Š°Ń‡ŠøŠ½Š°ŠµŃ‚ся Š² сŠµŠŗтŠ¾Ń€Šµ 0</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1180"/>
+ <source>Overlapping GPT partitions</source>
+ <translation>ŠŸŠµŃ€ŠµŠŗрыŠ²Š°ŃŽŃ‰ŠøŠµŃŃ GPT рŠ°Š·Š“ŠµŠ»Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1196"/>
+ <source>Overlapping MBR partitions</source>
+ <translation>ŠŸŠµŃ€ŠµŠŗрыŠ²Š°ŃŽŃ‰ŠøŠµŃŃ MBR рŠ°Š·Š“ŠµŠ»Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1219"/>
+ <location filename="../VBoxInternalManage.cpp" line="1304"/>
+ <location filename="../VBoxInternalManage.cpp" line="1313"/>
+ <location filename="../VBoxInternalManage.cpp" line="1322"/>
+ <location filename="../VBoxInternalManage.cpp" line="1331"/>
+ <location filename="../VBoxInternalManage.cpp" line="2018"/>
+ <location filename="../VBoxInternalManage.cpp" line="2027"/>
+ <location filename="../VBoxInternalManage.cpp" line="2088"/>
+ <location filename="../VBoxInternalManage.cpp" line="2251"/>
+ <location filename="../VBoxInternalManage.cpp" line="2260"/>
+ <location filename="../VBoxInternalManage.cpp" line="2385"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="368"/>
+ <location filename="../VBoxInternalManage.cpp" line="1226"/>
+ <location filename="../VBoxInternalManage.cpp" line="1343"/>
+ <location filename="../VBoxInternalManage.cpp" line="2034"/>
+ <location filename="../VBoxInternalManage.cpp" line="2107"/>
+ <location filename="../VBoxInternalManage.cpp" line="2275"/>
+ <location filename="../VBoxInternalManage.cpp" line="2396"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="327"/>
+ <source>
+Syntax error: %N
+</source>
+ <translation type="unfinished">
+Š”ŠøŠ½Ń‚Š°ŠŗсŠøчŠµŃŠŗŠ°Ń Š¾ŃˆŠøŠ±ŠŗŠ°: %N
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="372"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń Š¾ŠæцŠøя -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="373"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š¾ŠæцŠøŠø %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="376"/>
+ <source>Unknown option: %s</source>
+ <translation type="unfinished">ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="378"/>
+ <source>Invalid argument format: %s</source>
+ <translation type="unfinished">ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ фŠ¾Ń€Š¼Š°Ń‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š°: %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1231"/>
+ <location filename="../VBoxInternalManage.cpp" line="1349"/>
+ <source>Mandatory parameter -rawdisk missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -rawdisk</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1236"/>
+ <source>Cannot open the raw disk: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть raw Š“ŠøсŠŗ: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1242"/>
+ <source>Number Type StartCHS EndCHS Size (MiB) Start (Sect)
+</source>
+ <translation>ŠŠ¾Š¼ŠµŃ€ Š¢ŠøŠæ ŠŠ°Ń‡CHS ŠšŠ¾Š½CHS Š Š°Š·Š¼ŠµŃ€ (MiB) Š”тŠ°Ń€Ń‚ (Š”ŠµŠŗт)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1347"/>
+ <source>Mandatory parameter -filename missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -filename</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1352"/>
+ <source>The parameter -mbr is only valid when the parameter -partitions is also present</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -mbr Š“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŠµŠ½ тŠ¾Š»ŃŒŠŗŠ¾ ŠŗŠ¾Š³Š“Š° тŠ°ŠŗŠ¶Šµ ŠæрŠøсутстŠ²ŃƒŠµŃ‚ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -partitions</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1361"/>
+ <source>Cannot open the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть raw Š“ŠøсŠŗ &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1390"/>
+ <source>File &apos;%s&apos; is no fixed/removable medium device</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся устрŠ¾Š¹ŃŃ‚Š²Š¾Š¼ фŠøŠŗсŠøрŠ¾Š²Š°Š½Š½Š¾Š³Š¾/сŠ¼ŠµŠ½Š½Š¾Š³Š¾ Š½Š¾ŃŠøтŠµŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1407"/>
+ <source>The -relative parameter is invalid for raw disk %s</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -relative Š½ŠµŠ“Š¾ŠæустŠøŠ¼ Š“Š»Ń raw Š“ŠøсŠŗŠ° %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1421"/>
+ <source>Cannot get the geometry of the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть Š³ŠµŠ¾Š¼ŠµŃ‚Ń€Šøю raw Š“ŠøсŠŗŠ° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1428"/>
+ <location filename="../VBoxInternalManage.cpp" line="1477"/>
+ <location filename="../VBoxInternalManage.cpp" line="1602"/>
+ <source>The -relative parameter is invalid for raw images</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -relative Š½ŠµŠ“Š¾ŠæустŠøŠ¼ Š“Š»Ń raw Š¾Š±Ń€Š°Š·Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1462"/>
+ <location filename="../VBoxInternalManage.cpp" line="1556"/>
+ <location filename="../VBoxInternalManage.cpp" line="1627"/>
+ <source>Cannot get the size of the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ raw Š“ŠøсŠŗŠ° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1472"/>
+ <location filename="../VBoxInternalManage.cpp" line="1527"/>
+ <location filename="../VBoxInternalManage.cpp" line="1565"/>
+ <source>Failed to get size of file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1484"/>
+ <source>File &apos;%s&apos; is no block device</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся Š±Š»Š¾Ń‡Š½Ń‹Š¼ устрŠ¾Š¹ŃŃ‚Š²Š¾Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1492"/>
+ <location filename="../VBoxInternalManage.cpp" line="1541"/>
+ <location filename="../VBoxInternalManage.cpp" line="1579"/>
+ <location filename="../VBoxInternalManage.cpp" line="1618"/>
+ <source>Failed to get file informtation for raw disk &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š“Š»Ń raw Š“ŠøсŠŗŠ° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1509"/>
+ <source>Cannot get the block size for file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ Š±Š»Š¾ŠŗŠ° фŠ°Š¹Š»Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1517"/>
+ <location filename="../VBoxInternalManage.cpp" line="1594"/>
+ <source>Cannot get the block count for file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š±Š»Š¾ŠŗŠ¾Š² Š² фŠ°Š¹Š»Šµ &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1533"/>
+ <source>File &apos;%s&apos; is neither block device nor regular file</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся Š½Šø Š±Š»Š¾Ń‡Š½Ń‹Š¼ устрŠ¾Š¹ŃŃ‚Š²Š¾Š¼, Š½Šø рŠµŠ³ŃƒŠ»ŃŃ€Š½Ń‹Š¼ фŠ°Š¹Š»Š¾Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1571"/>
+ <source>File &apos;%s&apos; is no block or char device</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся Š½Šø Š±Š»Š¾Ń‡Š½Ń‹Š¼ Š½Šø сŠøŠ¼Š²Š¾Š»ŃŒŠ½Ń‹Š¼ устрŠ¾Š¹ŃŃ‚Š²Š¾Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1610"/>
+ <source>File &apos;%s&apos; is neither character device nor regular file</source>
+ <translation>Š¤Š°Š¹Š» &apos;%s&apos; Š½Šµ яŠ²Š»ŃŠµŃ‚ся Š½Šø сŠøŠ¼Š²Š¾Š»ŃŒŠ½Ń‹Š¼ устрŠ¾Š¹ŃŃ‚Š²Š¾Š¼ Š½Šø рŠµŠ³ŃƒŠ»ŃŃ€Š½Ń‹Š¼ фŠ°Š¹Š»Š¾Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1635"/>
+ <source>Detected size of raw disk &apos;%s&apos; is %RU64, an invalid value</source>
+ <translation>ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Š½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ raw Š“ŠøсŠŗŠ° &apos;%s&apos; %RU64, чтŠ¾ Š½Šµ яŠ²Š»ŃŠµŃ‚ся Š“Š¾ŠæустŠøŠ¼Ń‹Š¼ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1667"/>
+ <source>Incorrect value in partitions parameter</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š² ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Šµ partitions</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1681"/>
+ <source>Incorrect separator in partitions parameter</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ рŠ°Š·Š“ŠµŠ»ŠøтŠµŠ»ŃŒ Š² ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Šµ partitions</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1691"/>
+ <source>Cannot read the partition information from &apos;%s&apos;</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøю Š¾ рŠ°Š·Š“ŠµŠ»Š°Ń… ŠøŠ· &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1706"/>
+ <source>It is not possible (and necessary) to explicitly give access to the extended partition %u. If required, enable access to all logical partitions inside this extended partition.</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ (Šø Š½Šµ Š½ŃƒŠ¶Š½Š¾) яŠ²Š½Š¾ Š“Š°Š²Š°Ń‚ŃŒ Š“Š¾ŃŃ‚ŃƒŠæ Šŗ рŠ°ŃŃ‰ŠøрŠµŠ½Š½Š¾Š¼Ńƒ рŠ°Š·Š“ŠµŠ»Ńƒ %u. Š•ŃŠ»Šø Š½ŃƒŠ¶Š½Š¾, Š“Š°Š¹Ń‚Šµ Š“Š¾ŃŃ‚ŃƒŠæ ŠŗŠ¾ Š²ŃŠµŠ¼ Š»Š¾Š³ŠøчŠµŃŠŗŠøŠ¼ рŠ°Š·Š“ŠµŠ»Š°Š¼ Š²Š½ŃƒŃ‚Ń€Šø рŠ°ŃŃˆŠøрŠµŠ½Š½Š¾Š³Š¾ рŠ°Š·Š“ŠµŠ»Š°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1726"/>
+ <location filename="../VBoxInternalManage.cpp" line="1794"/>
+ <source>Out of memory allocating the partition list for &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ сŠæŠøсŠ¾Šŗ рŠ°Š·Š“ŠµŠ»Š¾Š² Š“Š»Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1742"/>
+ <source>Out of memory allocating the partition descriptor for &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š“ŠµŃŠŗрŠøŠæтŠ¾Ń€ рŠ°Š·Š“ŠµŠ»Š° Š“Š»Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1751"/>
+ <source>Cannot read partition data from raw device &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ Š“Š°Š½Š½Ń‹Šµ рŠ°Š·Š“ŠµŠ»Š° ŠøŠ· raw устŠ°Ń€Š¾Š¹ŃŃ‚Š²Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1763"/>
+ <source>Cannot open replacement MBR file &apos;%s&apos; specified with -mbr: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» Š·Š°Š¼ŠµŠ½Ń‹ MBR &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ чŠµŃ€ŠµŠ· -mbr: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1771"/>
+ <source>Cannot read replacement MBR file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ фŠ°Š¹Š» Š·Š°Š¼ŠµŠ½Ń‹ MBR &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1837"/>
+ <source>Cannot create reference to individual partition %u, rc=%Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ссыŠ»Šŗу Š½Š° ŠøŠ½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š“ŠµŠ» %u, rc=%Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1852"/>
+ <source>Cannot create reference to individual partition %u (numbered %u), rc=%Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ссыŠ»Šŗу Š½Š° ŠøŠ½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š“ŠµŠ» %u (ŠæрŠ¾Š½ŃƒŠ¼ŠµŃ€Š¾Š²Š°Š½Š½Ń‹Š¹ ŠŗŠ°Šŗ %u), rc=%Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1914"/>
+ <source>MBR/EPT overlaps with data area</source>
+ <translation>MBR/EPT ŠæŠµŃ€ŠµŠŗрыŠ²Š°ŠµŃ‚ Š¾Š±Š»Š°ŃŃ‚ŃŒ Š“Š°Š½Š½Ń‹Ń…</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1920"/>
+ <source>GPT overlaps with data area</source>
+ <translation>GPT ŠæŠµŃ€ŠµŠŗрыŠ²Š°ŠµŃ‚ Š¾Š±Š»Š°ŃŃ‚ŃŒ Š“Š°Š½Š½Ń‹Ń…</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1977"/>
+ <source>Cannot create the raw disk VMDK: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ VMDK raw Š“ŠøсŠŗ: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1980"/>
+ <source>RAW host disk access VMDK file %s created successfully.
+</source>
+ <translation>VMDK фŠ°Š¹Š» %s Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ RAW Š“ŠøсŠŗу хŠ¾ŃŃ‚Š° сŠ¾Š·Š“Š°Š½ усŠæŠµŃˆŠ½Š¾.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2002"/>
+ <source>The raw disk vmdk file was not created</source>
+ <translation>vmdk фŠ°Š¹Š» Šŗ raw Š“ŠøсŠŗу Š½Šµ сŠ¾Š·Š“Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2039"/>
+ <source>Mandatory parameter -from missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -from</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2041"/>
+ <source>Mandatory parameter -to missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ -to</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2065"/>
+ <source>Cannot rename the image: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ Š¾Š±Ń€Š°Š·: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2068"/>
+ <source>Cannot create the source image: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±Ń€Š°Š· ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2112"/>
+ <source>Mandatory filename parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ ŠøŠ¼Ń фŠ°Š¹Š»Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2114"/>
+ <source>Mandatory outputfile parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€: Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ фŠ°Š¹Š»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2142"/>
+ <source>Cannot create destination file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ фŠ°Š¹Š» Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2161"/>
+ <location filename="../VBoxInternalManage.cpp" line="2304"/>
+ <location filename="../VBoxInternalManage.cpp" line="2424"/>
+ <source>No file format specified and autodetect failed - please specify format: %Rrc</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ фŠ¾Ń€Š¼Š°Ń‚ фŠ°Š¹Š»Š°, тŠ°ŠŗŠ¶Šµ Š°Š²Ń‚Š¾Š“ŠµŃ‚ŠµŠŗт Š½Šµ ŠæрŠ¾ŃˆŠµŠ» - ŠæŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, уŠŗŠ°Š¶ŠøтŠµ фŠ¾Ń€Š¼Š°Ń‚: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2164"/>
+ <source>Only converting harddisk images is supported</source>
+ <translation>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся тŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š¾Š² Š¶ŠµŃŃ‚ŠŗŠøх Š“ŠøсŠŗŠ¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2179"/>
+ <location filename="../VBoxInternalManage.cpp" line="2323"/>
+ <source>Cannot open the source image: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть Š¾Š±Ń€Š°Š· ŠøстŠ¾Ń‡Š½ŠøŠŗŠ°: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxInternalManage.cpp" line="2189"/>
+ <source>Converting image &quot;%s&quot; with size %RU64 bytes (%RU64MB) to raw...
+</source>
+ <translation>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB) Š² raw...
+</numerusform>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚Š° (%RU64MB) Š² raw...
+</numerusform>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB) Š² raw...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2211"/>
+ <source>Cannot copy image data: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠŗŠ¾ŠæŠøрŠ¾Š²Š°Ń‚ŃŒ Š“Š°Š½Š½Ń‹Šµ Š¾Š±Ń€Š°Š·Š°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2223"/>
+ <source>Out of memory allocating read buffer</source>
+ <translation>ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø ŠæŠ¾Š“ Š±ŃƒŃ„ŠµŃ€ чтŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2280"/>
+ <location filename="../VBoxInternalManage.cpp" line="2401"/>
+ <source>Mandatory input image parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ Š²Ń…Š¾Š“Š½Š¾Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2282"/>
+ <source>Mandatory output image parameter missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ Š²Ń‹Ń…Š¾Š“Š½Š¾Š¹ Š¾Š±Ń€Š°Š·</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2315"/>
+ <source>Cannot create the source virtual disk container: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€ ŠøсхŠ¾Š“Š½Š¾Š³Š¾ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ°: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2334"/>
+ <source>Cannot create the destination virtual disk container: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ° Š½Š°Š·Š½Š°Ń‡ŠµŠ½Šøя: %Rrc</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxInternalManage.cpp" line="2339"/>
+ <source>Converting image &quot;%s&quot; with size %RU64 bytes (%RU64MB)...
+</source>
+ <translation>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB)...
+</numerusform>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚Š° (%RU64MB)...
+</numerusform>
+ <numerusform>ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ Š¾Š±Ń€Š°Š·Š° &quot;%s&quot; рŠ°Š·Š¼ŠµŃ€Š¾Š¼ %RU64 Š±Š°Š¹Ń‚ (%RU64MB)...
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2348"/>
+ <source>Cannot copy the image: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠŗŠ¾ŠæŠøрŠ¾Š²Š°Ń‚ŃŒ Š¾Š±Ń€Š°Š·: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2476"/>
+ <location filename="../VBoxInternalManage.cpp" line="2611"/>
+ <source>Missing VM name/UUID</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ¼Ń Š’Šœ/UUID</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2576"/>
+ <source>One or more of the requested features are not implemented! Feel free to do this.</source>
+ <translation>ŠžŠ“ŠøŠ½ ŠøŠ»Šø Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ Š·Š°ŠæрŠ¾ŃˆŠµŠ½Š½Ń‹Ń… фуŠ½ŠŗцŠøŠ¹ Š½Šµ рŠµŠ°Š»ŠøŠ·Š¾Š²Š°Š½Ń‹! ŠŠµ стŠµŃŠ½ŃŠ¹Ń‚ŠµŃŃŒ сŠ“ŠµŠ»Š°Ń‚ŃŒ Šøх.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2592"/>
+ <source>password to hash required</source>
+ <translation>трŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š»Ń хŠµŃˆŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2598"/>
+ <source>Password hash: %s
+</source>
+ <translation>Š„ŠµŃˆ ŠæŠ°Ń€Š¾Š»Ń: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2641"/>
+ <source>Invalid update interval specified</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Ń‚ŠµŃ€Š²Š°Š» Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2643"/>
+ <source>argc=%d interval=%u
+</source>
+ <translation>argc=%d ŠøŠ½Ń‚ŠµŃ€Š²Š°Š»=%u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2694"/>
+ <source>Command missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2734"/>
+ <source>Invalid command &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠŗŠ¾Š¼Š°Š½Š“Š° &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>List</name>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="54"/>
+ <location filename="../VBoxManageList.cpp" line="68"/>
+ <location filename="../VBoxManageList.cpp" line="94"/>
+ <location filename="../VBoxManageList.cpp" line="853"/>
+ <location filename="../VBoxManageList.cpp" line="864"/>
+ <source>Unknown</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="59"/>
+ <location filename="../VBoxManageList.cpp" line="73"/>
+ <source>unknown</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="66"/>
+ <source>Up</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="67"/>
+ <source>Down</source>
+ <translation>Š’Ń‹ŠŗŠ»ŃŽŃ‡ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="81"/>
+ <source>HardDisk</source>
+ <translation>Š–ŠµŃŃ‚ŠŗŠøŠ¹ Š”ŠøсŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="83"/>
+ <source>Floppy</source>
+ <translation>Š¤Š»Š¾ŠæŠæŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="86"/>
+ <source>Network</source>
+ <translation>Š”ŠµŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="88"/>
+ <source>SharedFolder</source>
+ <translation>ŠžŠ±Ń‰Š°Ń ŠæŠ°ŠæŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="89"/>
+ <source>Graphics3D</source>
+ <translation>3D Š³Ń€Š°Ń„ŠøŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="111"/>
+ <location filename="../VBoxManageList.cpp" line="149"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="156"/>
+ <location filename="../VBoxManageList.cpp" line="215"/>
+ <location filename="../VBoxManageList.cpp" line="261"/>
+ <location filename="../VBoxManageList.cpp" line="1340"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="162"/>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>Enabled</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="162"/>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>Disabled</source>
+ <translation>ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="166"/>
+ <source>IPAddress: %ls
+</source>
+ <translation>IP Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="169"/>
+ <location filename="../VBoxManageList.cpp" line="225"/>
+ <source>NetworkMask: %ls
+</source>
+ <translation>Š”ŠµŃ‚ŠµŠ²Š°Ń Š¼Š°ŃŠŗŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="172"/>
+ <source>IPV6Address: %ls
+</source>
+ <translation>IPV6 Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="175"/>
+ <source>IPV6NetworkMaskPrefixLength: %d
+</source>
+ <translation>Š”Š»ŠøŠ½Š° ŠæрŠµŃ„ŠøŠŗсŠ° сŠµŃ‚ŠµŠ²Š¾Š¹ Š¼Š°ŃŠŗŠø IPV6: %d
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="178"/>
+ <source>HardwareAddress: %ls
+</source>
+ <translation>ŠŠæŠæŠ°Ń€Š°Ń‚Š½Ń‹Š¹ Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="181"/>
+ <source>MediumType: %s
+</source>
+ <translation>Š¢ŠøŠæ Š½Š¾ŃŠøтŠµŠ»Ń: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <source>Wireless: %s
+</source>
+ <translation>Š‘ŠµŃŠæрŠ¾Š²Š¾Š“Š½Ń‹Š¹: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>Yes</source>
+ <translation>Š”Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>No</source>
+ <translation>ŠŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="187"/>
+ <source>Status: %s
+</source>
+ <translation>Š”тŠ°Ń‚ŃƒŃ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="190"/>
+ <location filename="../VBoxManageList.cpp" line="236"/>
+ <location filename="../VBoxManageList.cpp" line="279"/>
+ <source>VBoxNetworkName: %ls
+
+</source>
+ <translation>Š˜Š¼Ń сŠµŃ‚Šø VBox: %ls
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>State: %s
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="228"/>
+ <source>LowerIP: %ls
+</source>
+ <translation>ŠŠøŠ¶Š½ŠøŠ¹ IP: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="231"/>
+ <source>UpperIP: %ls
+</source>
+ <translation>Š’ŠµŃ€Ń…Š½ŠøŠ¹ IP: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="271"/>
+ <source>CloudProvider: %ls
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="274"/>
+ <source>CloudProfile: %ls
+</source>
+ <translation>ŠžŠ±Š»Š°Ń‡Š½Ń‹Š¹ ŠæрŠ¾Ń„ŠøŠ»ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="277"/>
+ <source>CloudNetworkId: %ls
+</source>
+ <translation>ID Š¾Š±Š»Š°Ń‡Š½Š¾Š¹ сŠµŃ‚Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="301"/>
+ <source>HW virtualization</source>
+ <translation>ŠŠæŠæŠ°Ń€Š°Ń‚Š½Š°Ń Š²ŠøртуŠ°Š»ŠøŠ·Š°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="303"/>
+ <source>long mode</source>
+ <translation>Š“Š»ŠøŠ½Š½Ń‹Š¹ рŠµŠ¶ŠøŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="304"/>
+ <source>nested paging</source>
+ <translation>Š²Š»Š¾Š¶ŠµŠ½Š½Ń‹Šµ стрŠ°Š½Šøцы</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="305"/>
+ <source>unrestricted guest</source>
+ <translation>Š½ŠµŠ¾Š³Ń€Š°Š½ŠøчŠµŠ½Š½Ń‹Š¹ Š³Š¾ŃŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="306"/>
+ <source>nested HW virtualization</source>
+ <translation>Š²Š»Š¾Š¶ŠµŠ½Š½Š°Ń Š°ŠæŠæŠ°Ń€Š°Ń‚Š½Š°Ń Š²ŠøртуŠ°Š»ŠøŠ·Š°Ń†Šøя</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="307"/>
+ <source>virt. vmsave/vmload</source>
+ <translation>virt. vmsave/vmload</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="313"/>
+ <source>Host Information:
+
+</source>
+ <translation>Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾ хŠ¾ŃŃ‚Šµ:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="319"/>
+ <source>Host time: %s
+</source>
+ <translation>Š’Ń€ŠµŠ¼Ń хŠ¾ŃŃ‚Š°: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="323"/>
+ <source>Processor online count: %lu
+</source>
+ <translation>Š§ŠøсŠ»Š¾ Š°ŠŗтŠøŠ²Š½Ń‹Ń… ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š¾Š²: %lu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="326"/>
+ <source>Processor count: %lu
+</source>
+ <translation>Š§ŠøсŠ»Š¾ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š¾Š²: %lu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="329"/>
+ <source>Processor online core count: %lu
+</source>
+ <translation>Š§ŠøсŠ»Š¾ Š°ŠŗтŠøŠ²Š½Ń‹Ń… яŠ“ŠµŃ€ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š¾Š²: %lu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="332"/>
+ <source>Processor core count: %lu
+</source>
+ <translation>Š§ŠøсŠ»Š¾ яŠ“ŠµŃ€ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š¾Š²: %lu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <source>Processor supports %s: %s
+</source>
+ <translation>ŠŸŃ€Š¾Ń†ŠµŃŃŠ¾Ń€ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ %s: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <location filename="../VBoxManageList.cpp" line="1803"/>
+ <location filename="../VBoxManageList.cpp" line="1808"/>
+ <source>yes</source>
+ <translation>Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <location filename="../VBoxManageList.cpp" line="1803"/>
+ <location filename="../VBoxManageList.cpp" line="1808"/>
+ <source>no</source>
+ <translation>Š½ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="344"/>
+ <source>Processor#%u speed: %lu MHz
+</source>
+ <translation>Š”ŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š° #%u: %lu ŠœŠ“ц
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="346"/>
+ <source>Processor#%u speed: unknown
+</source>
+ <translation>Š”ŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š° #%u: Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="349"/>
+ <source>Processor#%u description: %ls
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ ŠæрŠ¾Ń†ŠµŃŃŠ¾Ń€Š° #%u: %ls
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="354"/>
+ <source>Memory size: %lu MByte
+</source>
+ <translation>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="358"/>
+ <source>Memory available: %lu MByte
+</source>
+ <translation>
+ <numerusform>Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚
+</numerusform>
+ <numerusform>Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ ŠæŠ°Š¼ŃŃ‚Šø: %lu ŠœŠ‘Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="362"/>
+ <source>Operating system: %ls
+</source>
+ <translation>ŠžŠæŠµŃ€Š°Ń†ŠøŠ¾Š½Š½Š°Ń сŠøстŠµŠ¼Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="366"/>
+ <source>Operating system version: %ls
+</source>
+ <translation>Š’ŠµŃ€ŃŠøя Š¾ŠæŠµŃ€Š°Ń†ŠøŠ¾Š½Š½Š¾Š¹ сŠøстŠµŠ¼Ń‹: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="424"/>
+ <source>Supported hard disk backends:
+
+</source>
+ <translation>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ Š±ŃŠŗŠµŠ½Š“ы Š¶ŠµŃŃ‚ŠŗŠøх Š“ŠøсŠŗŠ¾Š²:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="443"/>
+ <source>Backend %u: id=&apos;%ls&apos; description=&apos;%ls&apos; capabilities=%#06x extensions=&apos;</source>
+ <translation>Š‘эŠŗŠµŠ½Š“ %u: id=&apos;%ls&apos; Š¾ŠæŠøсŠ°Š½ŠøŠµ=&apos;%ls&apos; Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚Šø=%#06x рŠ°ŃŃˆŠøрŠµŠ½Šøя=&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="472"/>
+ <source> properties=(</source>
+ <translation> сŠ²Š¾Š¹ŃŃ‚Š²Š°=(</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="477"/>
+ <source>
+ name=&apos;%ls&apos; desc=&apos;%ls&apos; type=</source>
+ <translation>
+ ŠøŠ¼Ń=&apos;%ls&apos; Š¾ŠæŠøсŠ°Š½ŠøŠµ=&apos;%ls&apos; тŠøŠæ=</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="481"/>
+ <source>int</source>
+ <translation>int</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="482"/>
+ <source>byte</source>
+ <translation>byte</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="483"/>
+ <source>string</source>
+ <translation>string</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="488"/>
+ <source> flags=%#04x</source>
+ <translation> фŠ»Š°Š³Šø=%#04x</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="489"/>
+ <source> default=&apos;%ls&apos;</source>
+ <translation> ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю=&apos;%ls&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="515"/>
+ <source>Host USB Devices:
+
+</source>
+ <translation>USB устрŠ¾Š¹ŃŃ‚Š²Š° хŠ¾ŃŃ‚Š°:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="519"/>
+ <location filename="../VBoxManageList.cpp" line="657"/>
+ <source>&lt;none&gt;
+
+</source>
+ <translation>&lt;Š½ŠµŃ‚&gt;
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="543"/>
+ <source>UUID: %s
+VendorId: %#06x (%04X)
+ProductId: %#06x (%04X)
+Revision: %u.%u (%02u%02u)
+Port: %u
+</source>
+ <translation>UUID: %s
+ID ŠŸŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗŠ°: %#06x (%04X)
+ID ŠŸŃ€Š¾Š“уŠŗтŠ°: %#06x (%04X)
+Š ŠµŠ²ŠøŠ·Šøя: %u.%u (%02u%02u)
+ŠŸŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="559"/>
+ <source>Low</source>
+ <translation>ŠŠøŠ·ŠŗŠ°Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="562"/>
+ <source>Full</source>
+ <translation>ŠŸŠ¾Š»Š½Š°Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="565"/>
+ <source>High</source>
+ <translation>Š’ысŠ¾ŠŗŠ°Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="568"/>
+ <source>Super</source>
+ <translation>Š”уŠæŠµŃ€</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="571"/>
+ <source>SuperPlus</source>
+ <translation>Š”уŠæŠµŃ€ŠŸŠ»ŃŽŃ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="578"/>
+ <source>USB version/speed: %u/%s
+</source>
+ <translation>Š’ŠµŃ€ŃŠøя/сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ USB: %u/%s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="587"/>
+ <source>Manufacturer: %ls
+</source>
+ <translation>ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøтŠµŠ»ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="591"/>
+ <source>Product: %ls
+</source>
+ <translation>ŠŸŃ€Š¾Š“уŠŗт: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="594"/>
+ <source>SerialNumber: %ls
+</source>
+ <translation>Š”ŠµŃ€ŠøŠ¹Š½Ń‹Š¹ Š½Š¾Š¼ŠµŃ€: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="597"/>
+ <source>Address: %ls
+</source>
+ <translation>ŠŠ“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="600"/>
+ <source>Port path: %ls
+</source>
+ <translation>ŠŸŃƒŃ‚ŃŒ Šŗ ŠæŠ¾Ń€Ń‚Ńƒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="609"/>
+ <source>Not supported</source>
+ <translation>ŠŠµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="612"/>
+ <source>Unavailable</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚ŃƒŠæŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="615"/>
+ <source>Busy</source>
+ <translation>Š—Š°Š½ŃŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="618"/>
+ <source>Available</source>
+ <translation>Š”Š¾ŃŃ‚ŃƒŠæŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="621"/>
+ <source>Held</source>
+ <translation>Š£Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="624"/>
+ <source>Captured</source>
+ <translation>Š—Š°Ń…Š²Š°Ń‡ŠµŠ½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="630"/>
+ <source>Current State: %s
+
+</source>
+ <translation>Š¢ŠµŠŗущŠµŠµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ: %s
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="647"/>
+ <source>Global USB Device Filters:
+
+</source>
+ <translation>Š“Š»Š¾Š±Š°Š»ŃŒŠ½Ń‹Šµ фŠøŠ»ŃŒŃ‚ры USB устрŠ¾Š¹ŃŃ‚Š²:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="667"/>
+ <source>Index: %zu
+</source>
+ <translation>Š˜Š½Š“ŠµŠŗс: %zu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <source>Active: %s
+</source>
+ <translation>ŠŠŗтŠøŠ²Š½Š¾: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="675"/>
+ <source>&lt;invalid&gt;</source>
+ <translation>&lt;Š½ŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøтŠµŠ»ŃŒŠ½Š¾&gt;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="679"/>
+ <source>Ignore</source>
+ <translation>Š˜Š³Š½Š¾Ń€ŠøрŠ¾Š²Š°Ń‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="682"/>
+ <source>Hold</source>
+ <translation>Š£Š“ŠµŃ€Š¶ŠøŠ²Š°Ń‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="687"/>
+ <source>Action: %s
+</source>
+ <translation>Š”ŠµŠ¹ŃŃ‚Š²ŠøŠµ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="691"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="693"/>
+ <source>VendorId: %ls
+</source>
+ <translation>ID ŠŸŠ¾ŃŃ‚Š°Š²Ń‰ŠøŠŗŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="695"/>
+ <source>ProductId: %ls
+</source>
+ <translation>ID ŠŸŃ€Š¾Š“уŠŗтŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="697"/>
+ <source>Revision: %ls
+</source>
+ <translation>Š ŠµŠ²ŠøŠ·Šøя: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="699"/>
+ <source>Manufacturer: %ls
+</source>
+ <translation>ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøтŠµŠ»ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="701"/>
+ <source>Product: %ls
+</source>
+ <translation>ŠŸŃ€Š¾Š“уŠŗт: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="703"/>
+ <source>Serial Number: %ls
+
+</source>
+ <translation>Š”ŠµŃ€ŠøŠ¹Š½Ń‹Š¹ Š½Š¾Š¼ŠµŃ€: %ls
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="728"/>
+ <source>API version: %ls
+</source>
+ <translation>Š’ŠµŃ€ŃŠøя API: %ls
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="731"/>
+ <source>Minimum guest RAM size: %u Megabytes
+</source>
+ <translation>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="733"/>
+ <source>Maximum guest RAM size: %u Megabytes
+</source>
+ <translation>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š³Š¾ŃŃ‚ŠµŠ²Š¾Š¹ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="735"/>
+ <source>Minimum video RAM size: %u Megabytes
+</source>
+ <translation>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="737"/>
+ <source>Maximum video RAM size: %u Megabytes
+</source>
+ <translation>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ рŠ°Š·Š¼ŠµŃ€ Š²ŠøŠ“ŠµŠ¾ RAM: %u ŠœŠµŠ³Š°Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="739"/>
+ <source>Maximum guest monitor count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… Š¼Š¾Š½ŠøтŠ¾Ń€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="741"/>
+ <source>Minimum guest CPU count: %u
+</source>
+ <translation>ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… Š¦ŠŸŠ£: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="743"/>
+ <source>Maximum guest CPU count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ Š³Š¾ŃŃ‚ŠµŠ²Ń‹Ń… Š¦ŠŸŠ£: %u
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="745"/>
+ <source>Virtual disk limit (info): %lld Bytes
+</source>
+ <translation>
+ <numerusform>ŠžŠ³Ń€Š°Š½ŠøчŠµŠ½ŠøŠµ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ° (ŠøŠ½Ń„Š¾): %lld Š‘Š°Š¹Ń‚
+</numerusform>
+ <numerusform>ŠžŠ³Ń€Š°Š½ŠøчŠµŠ½ŠøŠµ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ° (ŠøŠ½Ń„Š¾): %lld Š‘Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>ŠžŠ³Ń€Š°Š½ŠøчŠµŠ½ŠøŠµ Š²ŠøртуŠ°Š»ŃŒŠ½Š¾Š³Š¾ Š“ŠøсŠŗŠ° (ŠøŠ½Ń„Š¾): %lld Š‘Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="747"/>
+ <source>Maximum Serial Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Ń… ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="749"/>
+ <source>Maximum Parallel Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ŠæŠ°Ń€Š°Š»Š»ŠµŠ»ŃŒŠ½Ń‹Ń… ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="751"/>
+ <source>Maximum Boot Position: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š°Ń Š·Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Š°Ń ŠæŠ¾Š·ŠøцŠøя: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="753"/>
+ <source>Maximum PIIX3 Network Adapter count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 сŠµŃ‚ŠµŠ²Ń‹Ń… Š°Š“Š°ŠæтŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="755"/>
+ <source>Maximum ICH9 Network Adapter count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 сŠµŃ‚ŠµŠ²Ń‹Ń… Š°Š“Š°ŠæтŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="757"/>
+ <source>Maximum PIIX3 IDE Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 IDE ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="759"/>
+ <source>Maximum ICH9 IDE Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 IDE ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="761"/>
+ <source>Maximum IDE Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ IDE ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="763"/>
+ <source>Maximum Devices per IDE Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° IDE ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="765"/>
+ <source>Maximum PIIX3 SATA Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 SATA ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="767"/>
+ <source>Maximum ICH9 SATA Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 SATA ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="769"/>
+ <source>Maximum SATA Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ SATA ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="771"/>
+ <source>Maximum Devices per SATA Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° SATA ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="773"/>
+ <source>Maximum PIIX3 SCSI Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 SCSI ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="775"/>
+ <source>Maximum ICH9 SCSI Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 SCSI ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="777"/>
+ <source>Maximum SCSI Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ SCSI ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="779"/>
+ <source>Maximum Devices per SCSI Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° SCSI ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="781"/>
+ <source>Maximum SAS PIIX3 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 SAS ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="783"/>
+ <source>Maximum SAS ICH9 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 SAS ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="785"/>
+ <source>Maximum SAS Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ SAS ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="787"/>
+ <source>Maximum Devices per SAS Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° SAS ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="789"/>
+ <source>Maximum NVMe PIIX3 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 NVMe ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="791"/>
+ <source>Maximum NVMe ICH9 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 NVMe ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="793"/>
+ <source>Maximum NVMe Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ NVMe ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="795"/>
+ <source>Maximum Devices per NVMe Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° NVMe ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="797"/>
+ <source>Maximum virtio-scsi PIIX3 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 virtio-scsi ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="799"/>
+ <source>Maximum virtio-scsi ICH9 Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 virtio-scsi ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="801"/>
+ <source>Maximum virtio-scsi Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ virtio-scsi ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="803"/>
+ <source>Maximum Devices per virtio-scsi Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° virtio-scsi ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="805"/>
+ <source>Maximum PIIX3 Floppy Controllers:%u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ PIIX3 Š¤Š»Š¾ŠæŠæŠø ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="807"/>
+ <source>Maximum ICH9 Floppy Controllers: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ ICH9 Š¤Š»Š¾ŠæŠæŠø ŠšŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="809"/>
+ <source>Maximum Floppy Port count: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ Š¤Š»Š¾ŠæŠæŠø ŠæŠ¾Ń€Ń‚Š¾Š²: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="811"/>
+ <source>Maximum Devices per Floppy Port: %u
+</source>
+ <translation>ŠœŠ°ŠŗсŠøŠ¼Š°Š»ŃŒŠ½Š¾ устрŠ¾Š¹ŃŃ‚Š² Š½Š° Š¤Š»Š¾ŠæŠæŠø ŠæŠ¾Ń€Ń‚: %u
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="814"/>
+ <source>Free disk space warning at: %u Bytes
+</source>
+ <translation>
+ <numerusform>Š”Š°Ń‚ŃŒ ŠæрŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>Š”Š°Ń‚ŃŒ ŠæрŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>Š”Š°Ń‚ŃŒ ŠæрŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="816"/>
+ <source>Free disk space warning at: %u %%
+</source>
+ <translation>Š”Š°Ń‚ŃŒ ŠæрŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u %%
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="818"/>
+ <source>Free disk space error at: %u Bytes
+</source>
+ <translation>
+ <numerusform>Š”Š°Ń‚ŃŒ Š¾ŃˆŠøŠ±Šŗу ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>Š”Š°Ń‚ŃŒ Š¾ŃˆŠøŠ±Šŗу ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>Š”Š°Ń‚ŃŒ Š¾ŃˆŠøŠ±Šŗу ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="820"/>
+ <source>Free disk space error at: %u %%
+</source>
+ <translation>Š”Š°Ń‚ŃŒ Š¾ŃˆŠøŠ±Šŗу ŠŗŠ¾Š³Š“Š° Š½Š° Š“ŠøсŠŗŠµ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ сŠ²Š¾Š±Š¾Š“Š½Š¾: %u %%
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="823"/>
+ <source>Default machine folder: %ls
+</source>
+ <translation>ŠŸŠ°ŠæŠŗŠ° Š¼Š°ŃˆŠøŠ½Ń‹ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <source>Raw-mode Supported: %s
+</source>
+ <translation>Raw-рŠµŠ¶ŠøŠ¼ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <source>Exclusive HW virtualization use: %s
+</source>
+ <translation>Š­ŠŗсŠŗŠ»ŃŽŠ·ŠøŠ²Š½Š¾Šµ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ Š°ŠæŠæŠ°Ń€Š°Ń‚Š½Š¾Š¹ Š²ŠøртуŠ°Š»ŠøŠ·Š°Ń†ŠøŠø: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <location filename="../VBoxManageList.cpp" line="1867"/>
+ <location filename="../VBoxManageList.cpp" line="1871"/>
+ <source>on</source>
+ <translation>Š²ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <location filename="../VBoxManageList.cpp" line="1867"/>
+ <location filename="../VBoxManageList.cpp" line="1871"/>
+ <source>off</source>
+ <translation>Š²Ń‹ŠŗŠ»</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="829"/>
+ <source>Default hard disk format: %ls
+</source>
+ <translation>Š¤Š¾Ń€Š¼Š°Ń‚ Š¶ŠµŃŃ‚ŠŗŠ¾Š³Š¾ Š“ŠøсŠŗŠ° ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="831"/>
+ <source>VRDE auth library: %ls
+</source>
+ <translation>Š‘ŠøŠ±Š»ŠøŠ¾Ń‚ŠµŠŗŠ° Š°ŃƒŃ‚ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń†ŠøŠø VRDE: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="833"/>
+ <source>Webservice auth. library: %ls
+</source>
+ <translation>Š‘ŠøŠ±Š»ŠøŠ¾Ń‚ŠµŠŗŠ° Š°ŃƒŃ‚ŠµŠ½Ń‚ŠøфŠøŠŗŠ°Ń†ŠøŠø Š²ŠµŠ±ŃŠµŃ€Š²ŠøсŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="835"/>
+ <source>Remote desktop ExtPack: %ls
+</source>
+ <translation>ŠŸŠ°ŠŗŠµŃ‚ рŠ°ŃŃˆŠøрŠµŠ½Šøя уŠ“Š°Š»ŠµŠ½Š½Š¾Š³Š¾ рŠ°Š±Š¾Ń‡ŠµŠ³Š¾ стŠ¾Š»Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="837"/>
+ <source>Log history count: %u
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ ŠøстŠ¾Ń€ŠøŠø Š² Š¶ŃƒŃ€Š½Š°Š»Šµ: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="839"/>
+ <source>Default frontend: %ls
+</source>
+ <translation>Š¤Ń€Š¾Š½Ń‚эŠ½Š“ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="844"/>
+ <source>Null</source>
+ <translation>ŠŸŃƒŃŃ‚Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="855"/>
+ <source>Default audio driver: %s
+</source>
+ <translation>ŠŃƒŠ“ŠøŠ¾ Š“рŠ°Š¹Š²ŠµŃ€ ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="857"/>
+ <source>Autostart database path: %ls
+</source>
+ <translation>ŠŸŃƒŃ‚ŃŒ Š±Š°Š·Ń‹ Š“Š°Š½Š½Ń‹Ń… Š°Š²Ń‚Š¾ŃŃ‚Š°Ń€Ń‚Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="859"/>
+ <source>Default Guest Additions ISO: %ls
+</source>
+ <translation>ISO Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ” ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="861"/>
+ <source>Logging Level: %ls
+</source>
+ <translation>Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š¶ŃƒŃ€Š½Š°Š»Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="867"/>
+ <source>System</source>
+ <translation>Š”ŠøстŠµŠ¼Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="868"/>
+ <source>NoProxy</source>
+ <translation>Š‘ŠµŠ· ŠŸŃ€Š¾ŠŗсŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="869"/>
+ <source>Manual</source>
+ <translation>Š’Ń€ŃƒŃ‡Š½ŃƒŃŽ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="874"/>
+ <source>Proxy Mode: %s
+</source>
+ <translation>Š ŠµŠ¶ŠøŠ¼ ŠŸŃ€Š¾ŠŗсŠø: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="876"/>
+ <source>Proxy URL: %ls
+</source>
+ <translation>URL ŠŸŃ€Š¾ŠŗсŠø: %ls
+</translation>
+ </message>
+ <message>
+ <source>Update check enabled: %s
+</source>
+ <translation type="vanished">ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°: %s
+</translation>
+ </message>
+ <message>
+ <source>Update check count: %u
+</source>
+ <translation type="vanished">ŠšŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠæрŠ¾Š²ŠµŃ€Š¾Šŗ Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: %u
+</translation>
+ </message>
+ <message>
+ <source>Update check frequency: never
+</source>
+ <translation type="vanished">Š§Š°ŃŃ‚Š¾Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: Š½ŠøŠŗŠ¾Š³Š“Š°
+</translation>
+ </message>
+ <message>
+ <source>Update check frequency: every day
+</source>
+ <translation type="vanished">Š§Š°ŃŃ‚Š¾Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: ŠŗŠ°Š¶Š“ыŠ¹ Š“ŠµŠ½ŃŒ
+</translation>
+ </message>
+ <message numerus="yes">
+ <source>Update check frequency: every %u days
+</source>
+ <translation type="vanished">
+ <numerusform>Š§Š°ŃŃ‚Š¾Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: ŠŗŠ°Š¶Š“ыŠ¹ %u Š“ŠµŠ½ŃŒ
+</numerusform>
+ <numerusform>Š§Š°ŃŃ‚Š¾Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: ŠŗŠ°Š¶Š“ыŠµ %u Š“Š½Ń
+</numerusform>
+ <numerusform>Š§Š°ŃŃ‚Š¾Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: ŠŗŠ°Š¶Š“ыŠµ %u Š“Š½ŠµŠ¹
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="908"/>
+ <source>Stable: new minor and maintenance releases</source>
+ <translation>Š”тŠ°Š±ŠøŠ»ŃŒŠ½Ń‹Šµ: Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ Šø ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="911"/>
+ <source>All releases: new minor, maintenance, and major releases</source>
+ <translation>Š’сŠµ рŠµŠ»ŠøŠ·Ń‹: Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ, ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ Šø Š¼Š°Š¶Š¾Ń€Š½Ń‹Šµ рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="914"/>
+ <source>With Betas: new minor, maintenance, major, and beta releases</source>
+ <translation>Š” Š±ŠµŃ‚Š°Š¼Šø: Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ, ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ, Š¼Š°Š¶Š¾Ń€Š½Ń‹Šµ Šø Š±ŠµŃ‚Š° рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="917"/>
+ <source>Unset</source>
+ <translation>ŠŠµ Š·Š°Š“Š°Š½Š¾</translation>
+ </message>
+ <message>
+ <source>Update check target: %s
+</source>
+ <translation type="vanished">Š¦ŠµŠ»ŃŒ ŠæрŠ¾Š²ŠµŃ€ŠŗŠø Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="924"/>
+ <source>Last check date: %ls
+</source>
+ <translation>ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŃŃ Š“Š°Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="879"/>
+ <source>User language: %ls
+</source>
+ <translation>ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ яŠ·Ń‹Šŗ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <source>Enabled: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="892"/>
+ <source>Check count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="895"/>
+ <source>Check frequency: never
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="897"/>
+ <source>Check frequency: every day
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="899"/>
+ <source>Check frequency: every %u days
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="920"/>
+ <source>Channel: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="922"/>
+ <source>Repository: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="952"/>
+ <source> minLeaseTime: default
+</source>
+ <translation> Š¼ŠøŠ½. Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы: ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="954"/>
+ <source> minLeaseTime: %u sec
+</source>
+ <translation> Š¼ŠøŠ½. Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы: %u сŠµŠŗ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="959"/>
+ <source> defaultLeaseTime: default
+</source>
+ <translation> Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="961"/>
+ <source> defaultLeaseTime: %u sec
+</source>
+ <translation> Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %u сŠµŠŗ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="966"/>
+ <source> maxLeaseTime: default
+</source>
+ <translation> Š¼Š°Šŗс. Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы: ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="968"/>
+ <source> maxLeaseTime: %u sec
+</source>
+ <translation> Š¼Š°Šŗс. Š²Ń€ŠµŠ¼Ń Š°Ń€ŠµŠ½Š“ы: %u сŠµŠŗ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="974"/>
+ <source> Forced options: %Rhrc
+</source>
+ <translation> Š¤Š¾Ń€ŃŠøрŠ¾Š²Š°Š½Š½Ń‹Šµ Š¾ŠæцŠøŠø: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="976"/>
+ <source> Forced options: None
+</source>
+ <translation> Š¤Š¾Ń€ŃŠøрŠ¾Š²Š°Š½Š½Ń‹Šµ Š¾ŠæцŠøŠø: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="979"/>
+ <source> Forced options: </source>
+ <translation> Š¤Š¾Ń€ŃŠøрŠ¾Š²Š°Š½Š½Ń‹Šµ Š¾ŠæцŠøŠø: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="987"/>
+ <source> Suppressed opt.s: %Rhrc
+</source>
+ <translation> ŠŸŠ¾Š“Š°Š²Š»ŠµŠ½Š½Ń‹Šµ Š¾ŠæцŠøŠø: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="989"/>
+ <source> Suppressed opts.: None
+</source>
+ <translation> ŠŸŠ¾Š“Š°Š²Š»ŠµŠ½Š½Ń‹Šµ Š¾ŠæцŠøŠø: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="992"/>
+ <source> Suppressed opts.: </source>
+ <translation> ŠŸŠ¾Š“Š°Š²Š»ŠµŠ½Š½Ń‹Šµ Š¾ŠæцŠøŠø: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1004"/>
+ <source> DHCP options: %Rhrc
+</source>
+ <translation> DHCP Š¾ŠæцŠøŠø: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1007"/>
+ <source> DHCP options: Return count mismatch: %zu, %zu, %zu
+</source>
+ <translation> DHCP Š¾ŠæцŠøŠø: Š§ŠøсŠ»Š¾ Š²Š¾Š·Š²Ń€Š°Ń‰ŠµŠ½Š½Ń‹Ń… Š½Šµ сŠ¾Š¾Ń‚Š²ŠµŃ‚стŠ²ŃƒŠµŃ‚: %zu, %zu, %zu
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1012"/>
+ <source> DHCP options: None
+</source>
+ <translation> DHCP Š¾ŠæцŠøŠø: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1019"/>
+ <source> %3d/legacy: %ls
+</source>
+ <translation> %3d/устŠ°Ń€ŠµŠ²ŃˆŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1053"/>
+ <source>NetworkName: %ls
+</source>
+ <translation>Š˜Š¼Ń сŠµŃ‚Šø: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1059"/>
+ <source>LowerIPAddress: %ls
+</source>
+ <translation>ŠŠøŠ¶Š½ŠøŠ¹ IP Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1062"/>
+ <source>UpperIPAddress: %ls
+</source>
+ <translation>Š’ŠµŃ€Ń…Š½ŠøŠ¹ IP Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1065"/>
+ <source>NetworkMask: %ls
+</source>
+ <translation>Š”ŠµŃ‚ŠµŠ²Š°Ń Š¼Š°ŃŠŗŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>Enabled: %s
+</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1072"/>
+ <source>Global Configuration:
+</source>
+ <translation>Š“Š»Š¾Š±Š°Š»ŃŒŠ½Š°Ń ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1087"/>
+ <source>Groups: %Rrc
+</source>
+ <translation>Š“Ń€ŃƒŠæŠæы: %Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1089"/>
+ <source>Groups: None
+</source>
+ <translation>Š“Ń€ŃƒŠæŠæы: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1095"/>
+ <source>Group: %ls
+</source>
+ <translation>Š“Ń€ŃƒŠæŠæŠ°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1100"/>
+ <source> Conditions: %Rhrc
+</source>
+ <translation> Š£ŃŠ»Š¾Š²Šøя: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1102"/>
+ <source> Conditions: None
+</source>
+ <translation> Š£ŃŠ»Š¾Š²Šøя: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1112"/>
+ <source> Conditions: %s %s %ls
+</source>
+ <translation> Š£ŃŠ»Š¾Š²Šøя: %s %s %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1113"/>
+ <source>include</source>
+ <translation>Š²ŠŗŠ»ŃŽŃ‡Š°Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1113"/>
+ <source>exclude</source>
+ <translation>ŠøсŠŗŠ»ŃŽŃ‡Š°Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1135"/>
+ <source>Individual Configs: %Rrc
+</source>
+ <translation>Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Šµ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø: %Rrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1137"/>
+ <source>Individual Configs: None
+</source>
+ <translation>Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Šµ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø: ŠŠµŃ‚
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1148"/>
+ <source>Individual Config: MAC %ls
+</source>
+ <translation>Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Š°Ń ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя: MAC %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1158"/>
+ <source>Individual Config: VM NIC: %ls slot %u, MAC %ls
+</source>
+ <translation>Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Š°Ń ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя: Š’Šœ NIC: %ls сŠ»Š¾Ń‚ %u, MAC %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1161"/>
+ <source>Individual Config: VM NIC: %ls slot %u, MAC %Rhrc
+</source>
+ <translation>Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Š°Ń ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøя: Š’Šœ NIC: %ls сŠ»Š¾Ń‚ %u, MAC %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1166"/>
+ <source> Fixed Address: %ls
+</source>
+ <translation> Š¤ŠøŠŗсŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ Š°Š“рŠµŃ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1168"/>
+ <source> Fixed Address: dynamic
+</source>
+ <translation> Š¤ŠøŠŗсŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ Š°Š“рŠµŃ: Š“ŠøŠ½Š°Š¼ŠøчŠµŃŠŗŠøŠ¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1194"/>
+ <source>Extension Packs: %u
+</source>
+ <translation>ŠŸŠ°ŠŗŠµŃ‚Ń‹ рŠ°ŃŃˆŠøрŠµŠ½ŠøŠ¹: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1220"/>
+ <source>Pack no.%2zu: %ls
+Version: %ls
+Revision: %u
+Edition: %ls
+Description: %ls
+VRDE Module: %ls
+Usable: %RTbool
+Why unusable: %ls
+</source>
+ <translation>ŠŸŠ°ŠŗŠµŃ‚ no.%2zu: %ls
+Š’ŠµŃ€ŃŠøя: %ls
+Š ŠµŠ²ŠøŠ·Šøя: %u
+Š ŠµŠ“Š°ŠŗцŠøя: %ls
+ŠžŠæŠøсŠ°Š½ŠøŠµ: %ls
+VRDE Š¼Š¾Š“уŠ»ŃŒ: %ls
+Š“Š¾Š“Š½Ń‹Š¹: %RTbool
+ŠŸŠ¾Ń‡ŠµŠ¼Ńƒ Š½Šµ Š³Š¾Š“ŠµŠ½: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1276"/>
+ <source>Video Input Devices: %u
+</source>
+ <translation>Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š° Š²Š²Š¾Š“Š° Š²ŠøŠ“ŠµŠ¾: %u
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1305"/>
+ <source>Supported %d screen shot formats:
+</source>
+ <translation>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Š¹ %d фŠ¾Ń€Š¼Š°Ń‚ сŠ½ŠøŠ¼ŠŗŠ° эŠŗрŠ°Š½Š°:
+</numerusform>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ %d фŠ¾Ń€Š¼Š°Ń‚Š° сŠ½ŠøŠ¼ŠŗŠ° эŠŗрŠ°Š½Š°:
+</numerusform>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ %d фŠ¾Ń€Š¼Š°Ń‚Š¾Š² сŠ½ŠøŠ¼ŠŗŠ° эŠŗрŠ°Š½Š°:
+</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1334"/>
+ <source>Supported %d cloud providers:
+</source>
+ <translation>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Š¹ %d Š¾Š±Š»Š°Ń‡Š½Ń‹Š¹ ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€:
+</numerusform>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ %d Š¾Š±Š»Š°Ń‡Š½Ń‹Ń… ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š°:
+</numerusform>
+ <numerusform>ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ %d Š¾Š±Š»Š°Ń‡Š½Ń‹Ń… ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š¾Š²:
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1342"/>
+ <source>Short Name: %ls
+</source>
+ <translation>ŠšŃ€Š°Ń‚ŠŗŠ¾Šµ ŠøŠ¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1378"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1381"/>
+ <source>Provider GUID: %ls
+</source>
+ <translation>GUID ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1397"/>
+ <source>Property: </source>
+ <translation>Š”Š²Š¾Š¹ŃŃ‚Š²Š¾: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1435"/>
+ <source>CPU Profile #%02zu:
+</source>
+ <translation>ŠŸŃ€Š¾Ń„ŠøŠ»ŃŒ Š¦ŠŸŠ£ #%02zu:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1436"/>
+ <source> Architecture: %s
+</source>
+ <translation> ŠŃ€Ń…ŠøтŠµŠŗтурŠ°: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1437"/>
+ <source> Name: %ls
+</source>
+ <translation> Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1439"/>
+ <source> Full Name: %ls
+</source>
+ <translation> ŠŸŠ¾Š»Š½Š¾Šµ ŠøŠ¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1689"/>
+ <source>%sDrive: %ls
+</source>
+ <translation>%sŠ”ŠøсŠŗ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1691"/>
+ <source>%sDrive: %Rhrc
+</source>
+ <translation>%sŠ”ŠøсŠŗ: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1696"/>
+ <source>Model: %Rhrc
+</source>
+ <translation>ŠœŠ¾Š“ŠµŠ»ŃŒ: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1698"/>
+ <source>Model: &quot;%ls&quot;
+</source>
+ <translation>ŠœŠ¾Š“ŠµŠ»ŃŒ: &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1700"/>
+ <source>Model: unknown/inaccessible
+</source>
+ <translation>ŠœŠ¾Š“ŠµŠ»ŃŒ: Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾/Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š¾
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1710"/>
+ <source>Further disk and partitioning information is not available for drive &quot;%ls&quot;. (E_ACCESSDENIED)
+</source>
+ <translation>Š”Š°Š»ŃŒŠ½ŠµŠ¹ŃˆŠ°Ń ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾ Š“ŠøсŠŗŠµ Šø ŠµŠ³Š¾ рŠ°Š·Š“ŠµŠ»Š°Ń… Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š° Š“Š»Ń Š“ŠøсŠŗŠ° &quot;%ls&quot;. (E_ACCESSDENIED)
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1723"/>
+ <source>Size: %llu bytes (%Rhcb)
+</source>
+ <translation>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€: %llu Š±Š°Š¹Ń‚ (%Rhcb)
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€: %llu Š±Š°Š¹Ń‚Š° (%Rhcb)
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€: %llu Š±Š°Š¹Ń‚ (%Rhcb)
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1725"/>
+ <source>Size: %Rhcb
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€: %Rhcb
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1728"/>
+ <source>Size: %Rhrc
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€: %Rhrc
+</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1735"/>
+ <source>Sector Size: %u bytes
+</source>
+ <translation>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ сŠµŠŗтŠ¾Ń€Š°: %u Š±Š°Š¹Ń‚
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ сŠµŠŗтŠ¾Ń€Š°: %u Š±Š°Š¹Ń‚Š°
+</numerusform>
+ <numerusform>Š Š°Š·Š¼ŠµŃ€ сŠµŠŗтŠ¾Ń€Š°: %u Š±Š°Š¹Ń‚
+</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1738"/>
+ <source>Sector Size: %Rhrc
+</source>
+ <translation>Š Š°Š·Š¼ŠµŃ€ сŠµŠŗтŠ¾Ń€Š°: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1745"/>
+ <source>Scheme: %s
+</source>
+ <translation>Š”хŠµŠ¼Š°: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1748"/>
+ <source>Scheme: %Rhrc
+</source>
+ <translation>Š”хŠµŠ¼Š°: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1756"/>
+ <source>Partitions: %Rhrc
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1760"/>
+ <source>Partitions: None (or not able to grok them).
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹: ŠŠµŃ‚ (ŠøŠ»Šø Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒŃŃ Š² Š½Šøх).
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1764"/>
+ <source>Partitions: First Last
+## Type Byte Size Byte Offset Cyl/Head/Sec Cyl/Head/Sec Active
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹: ŠŸŠµŃ€Š²Ń‹Š¹ ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŠøŠ¹
+## Š¢ŠøŠæ Š Š°Š·Š¼ŠµŃ€ Š±Š°Š¹Ń‚ Š”Š¼ŠµŃ‰ŠµŠ½ŠøŠµ Š±Š°Š¹Ń‚ Š¦ŠøŠ»/Š“Š¾Š»/Š”ŠµŠŗт Š¦ŠøŠ»/Š“Š¾Š»/Š”ŠµŠŗт ŠŠŗтŠøŠ²Š½Ń‹Š¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1767"/>
+ <source>Partitions: First Last
+## Type Size Start Cyl/Head/Sec Cyl/Head/Sec Active
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹: ŠŸŠµŃ€Š²Ń‹Š¹ ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŠøŠ¹
+## Š¢ŠøŠæ Š Š°Š·Š¼ŠµŃ€ Š”тŠ°Ń€Ń‚ Š¦ŠøŠ»/Š“Š¾Š»/Š”ŠµŠŗт Š¦ŠøŠ»/Š“Š¾Š»/Š”ŠµŠŗт ŠŠŗтŠøŠ²Š½Ń‹Š¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1826"/>
+ <source>Partitions:
+## %-*s Uuid Byte Size Byte Offset Active Name
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹:
+## %-*s Uuid Š Š°Š·Š¼ŠµŃ€ Š±Š°Š¹Ń‚ Š”Š¼ŠµŃ‰ŠµŠ½ŠøŠµ Š±Š°Š¹Ń‚ ŠŠŗтŠøŠ²ŠµŠ½ Š˜Š¼Ń
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1829"/>
+ <location filename="../VBoxManageList.cpp" line="1834"/>
+ <source>Type</source>
+ <translation>Š¢ŠøŠæ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1831"/>
+ <source>Partitions:
+## %-*s Uuid Size Start Active Name
+</source>
+ <translation>Š Š°Š·Š“ŠµŠ»Ń‹:
+## %-*s Uuid Š Š°Š·Š¼ŠµŃ€ Š”тŠ°Ń€Ń‚ ŠŠŗтŠøŠ²ŠµŠ½ Š˜Š¼Ń
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2043"/>
+ <source>Description: %ls
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2046"/>
+ <source>Family ID: %ls
+</source>
+ <translation>ID сŠµŠ¼ŠµŠ¹ŃŃ‚Š²Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2049"/>
+ <source>Family Desc: %ls
+</source>
+ <translation>ŠžŠæŠøсŠ°Š½ŠøŠµ сŠµŠ¼ŠµŠ¹ŃŃ‚Š²Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2052"/>
+ <source>64 bit: %RTbool
+</source>
+ <translation>64 Š±Šøт: %RTbool
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2075"/>
+ <location filename="../VBoxManageList.cpp" line="2097"/>
+ <source>Name: %ls
+
+</source>
+ <translation>Š˜Š¼Ń: %ls
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2134"/>
+ <source>Host CPUIDs:
+
+Leaf no. EAX EBX ECX EDX
+</source>
+ <translation>CPUID хŠ¾ŃŃ‚Š°:
+
+Š›Šøст no. EAX EBX ECX EDX
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2166"/>
+ <source>base</source>
+ <translation>Š±Š°Š·Š¾Š²Ń‹Š¹</translation>
+ </message>
+ <message>
+ <source>Network: %ls
+</source>
+ <translation type="vanished">Š”ŠµŃ‚ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <source>IPv6 Enabled: %s
+</source>
+ <translation type="vanished">IPv6 Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½: %s
+</translation>
+ </message>
+ <message>
+ <source>IPv6 Prefix: %ls
+</source>
+ <translation type="vanished">IPv6 ŠæрŠµŃ„ŠøŠŗс: %ls
+</translation>
+ </message>
+ <message>
+ <source>DHCP Enabled: %s
+</source>
+ <translation type="vanished">DHCP Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½: %s
+</translation>
+ </message>
+ <message>
+ <source>Port-forwarding (ipv4)
+</source>
+ <translation type="vanished">ŠŸŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ ŠæŠ¾Ń€Ń‚Š¾Š² (ipv4)
+</translation>
+ </message>
+ <message>
+ <source>Port-forwarding (ipv6)
+</source>
+ <translation type="vanished">ŠŸŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ ŠæŠ¾Ń€Ń‚Š¾Š² (ipv6)
+</translation>
+ </message>
+ <message>
+ <source>loopback mappings (ipv4)
+</source>
+ <translation type="vanished">Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š¹ ŠæŠµŃ‚Š»Šø (ipv4)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2388"/>
+ <source>Unknown subcommand &quot;%s&quot;.</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š° &quot;%s&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2399"/>
+ <source>Missing subcommand for &quot;list&quot; command.
+</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š° Š“Š»Ń ŠŗŠ¾Š¼Š°Š½Š“ы &quot;list&quot;.
+</translation>
+ </message>
+</context>
+<context>
+ <name>Metrics</name>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="90"/>
+ <source>Invalid machine name: &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń Š¼Š°ŃˆŠøŠ½Ń‹: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="128"/>
+ <source>host</source>
+ <translation>хŠ¾ŃŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="138"/>
+ <source>unknown</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="149"/>
+ <source>The following metrics were modified:
+
+Object Metric
+---------- --------------------
+</source>
+ <translation>Š”Š»ŠµŠ“ующŠøŠµ Š¼ŠµŃ‚Ń€ŠøŠŗŠø ŠøŠ·Š¼ŠµŠ½ŠµŠ½Ń‹:
+
+ŠžŠ±ŃŠŠµŠŗт ŠœŠµŃ‚Ń€ŠøŠŗŠ°
+---------- --------------------
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="163"/>
+ <source>No metrics match the specified filter!</source>
+ <translation>ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ Š¼ŠµŃ‚Ń€ŠøŠŗ, ŠæŠ¾Š“хŠ¾Š“ящŠøх ŠæŠ¾Š“ уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ фŠøŠ»ŃŒŃ‚Ń€!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="197"/>
+ <source>Object Metric Unit Minimum Maximum Period Count Description
+--------------- ---------------------------------------- ---- ---------- ---------- ---------- ---------- -----------
+</source>
+ <translation>ŠžŠ±ŃŠŠµŠŗт ŠœŠµŃ‚Ń€ŠøŠŗŠ° Š•Š“. ŠœŠøŠ½ ŠœŠ°Šŗс ŠŸŠµŃ€ŠøŠ¾Š“ ŠšŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠžŠæŠøсŠ°Š½ŠøŠµ
+--------------- ---------------------------------------- ---- ---------- ---------- ---------- ---------- -----------
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="240"/>
+ <location filename="../VBoxManageMetrics.cpp" line="249"/>
+ <location filename="../VBoxManageMetrics.cpp" line="412"/>
+ <location filename="../VBoxManageMetrics.cpp" line="421"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="243"/>
+ <location filename="../VBoxManageMetrics.cpp" line="415"/>
+ <source>Invalid value for &apos;period&apos; parameter: &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š“Š»Ń ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š° &apos;period&apos;: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="252"/>
+ <location filename="../VBoxManageMetrics.cpp" line="424"/>
+ <source>Invalid value for &apos;samples&apos; parameter: &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š“Š»Ń ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š° &apos;samples&apos;: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="319"/>
+ <source>Object Metric Values
+--------------- ---------------------------------------- --------------------------------------------
+</source>
+ <translation>ŠžŠ±ŃŠŠµŠŗт ŠœŠµŃ‚Ń€ŠøŠŗŠ° Š—Š½Š°Ń‡ŠµŠ½Šøя
+--------------- ---------------------------------------- --------------------------------------------
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="483"/>
+ <source>The background process holding collected metrics will shutdown
+in few seconds, discarding all collected data and parameters.</source>
+ <translation>Š¤Š¾Š½Š¾Š²Ń‹Š¹ ŠæрŠ¾Ń†ŠµŃŃ, уŠ“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‰ŠøŠ¹ сŠ¾Š±Ń€Š°Š½Š½Ń‹Šµ Š¼ŠµŃ‚Ń€ŠøŠŗŠø Š·Š°Š²ŠµŃ€ŃˆŠøтся Š²
+тŠµŃ‡ŠµŠ½ŠøŠµ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøх сŠµŠŗуŠ½Š“, тŠµŃ€ŃŃ Š²ŃŠµ сŠ¾Š±Ń€Š°Š½Š½Ń‹Šµ Š“Š°Š½Š½Ń‹Šµ Šø
+ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="492"/>
+ <source>Time stamp Object Metric Value
+</source>
+ <translation>Š’Ń€ŠµŠ¼Ń ŠžŠ±ŃŠŠµŠŗт ŠœŠµŃ‚Ń€ŠøŠŗŠ° Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="639"/>
+ <source>Subcommand missing</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="658"/>
+ <source>Invalid subcommand &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠæŠ¾Š“ŠŗŠ¾Š¼Š°Š½Š“Š° &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>Misc</name>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="66"/>
+ <location filename="../VBoxManageMisc.cpp" line="760"/>
+ <location filename="../VBoxManageMisc.cpp" line="789"/>
+ <location filename="../VBoxManageMisc.cpp" line="824"/>
+ <location filename="../VBoxManageMisc.cpp" line="950"/>
+ <source>Incorrect number of parameters</source>
+ <translation>ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="79"/>
+ <location filename="../VBoxManageMisc.cpp" line="799"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ ŠøŠ¼Ń фŠ°Š¹Š»Š° &quot;%s&quot; Š² Š°Š±ŃŠ¾Š»ŃŽŃ‚Š½Ń‹Š¹ Šæуть: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="125"/>
+ <location filename="../VBoxManageMisc.cpp" line="354"/>
+ <location filename="../VBoxManageMisc.cpp" line="530"/>
+ <location filename="../VBoxManageMisc.cpp" line="1075"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="132"/>
+ <location filename="../VBoxManageMisc.cpp" line="683"/>
+ <source>Invalid option -%c</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń Š¾ŠæцŠøя -%c</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="133"/>
+ <location filename="../VBoxManageMisc.cpp" line="685"/>
+ <source>Invalid option case %i</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š²Š°Ń€ŠøŠ°Š½Ń‚ Š¾ŠæцŠøŠø %i</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="136"/>
+ <location filename="../VBoxManageMisc.cpp" line="688"/>
+ <source>unknown option: %s
+</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="139"/>
+ <location filename="../VBoxManageMisc.cpp" line="692"/>
+ <source>error: %Rrs</source>
+ <translation>Š¾ŃˆŠøŠ±ŠŗŠ°: %Rrs</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="145"/>
+ <location filename="../VBoxManageMisc.cpp" line="370"/>
+ <location filename="../VBoxManageMisc.cpp" line="540"/>
+ <source>VM name required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠøŠ¼Ń Š’Šœ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="162"/>
+ <source>Machine delete failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть Š¼Š°ŃˆŠøŠ½Ńƒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="256"/>
+ <source>Parameter --name is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --name</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="298"/>
+ <source>Virtual machine &apos;%ls&apos; is created%s.
+UUID: %s
+Settings file: &apos;%ls&apos;
+</source>
+ <translation>Š’ŠøртуŠ°Š»ŃŒŠ½Š°Ń Š¼Š°ŃˆŠøŠ½Š° &apos;%ls&apos; сŠ¾Š·Š“Š°Š½Š°%s.
+UUID: %s
+Š¤Š°Š¹Š» Š½Š°ŃŃ‚Ń€Š¾ŠµŠŗ: &apos;%ls&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="301"/>
+ <source> and registered</source>
+ <translation> Šø Š·Š°Ń€ŠµŠ³ŠøстрŠøрŠ¾Š²Š°Š½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="343"/>
+ <location filename="../VBoxManageMisc.cpp" line="1388"/>
+ <source>RTPathAbs(%s,,) failed with rc=%Rrc</source>
+ <translation>RTPathAbs(%s,,) Š·Š°Š²ŠµŃ€ŃˆŠµŠ½ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ rc=%Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="394"/>
+ <source>Move VM failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠµŃ€ŠµŠ¼ŠµŃŃ‚Šøть Š’Šœ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="399"/>
+ <source>Machine has been successfully moved into %s
+</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° усŠæŠµŃˆŠ½Š¾ ŠæŠµŃ€ŠµŠ¼ŠµŃ‰ŠµŠ½Š° Š² %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="400"/>
+ <source>the same location</source>
+ <translation>тŠ¾ Š¶Šµ Š¼ŠµŃŃ‚Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="510"/>
+ <source>Invalid clone mode &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ рŠµŠ¶ŠøŠ¼ ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Š½Šøя &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="515"/>
+ <source>Invalid clone options &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Šµ Š¾ŠæцŠøŠø ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Š½Šøя &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="562"/>
+ <source>%s Clone</source>
+ <translation>ŠšŠ»Š¾Š½ %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="596"/>
+ <source>Clone VM failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Ń‚ŃŒ Š’Šœ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="603"/>
+ <source>Machine has been successfully cloned as &quot;%ls&quot;
+</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° усŠæŠµŃˆŠ½Š¾ ŠŗŠ»Š¾Š½ŠøрŠ¾Š²Š°Š½Š° ŠŗŠ°Šŗ &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="672"/>
+ <source>Parameter to option --putenv must not contain any newline character</source>
+ <translation>ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€ Šŗ Š¾ŠæцŠøŠø --putenv Š½Šµ Š“Š¾Š»Š¶ŠµŠ½ сŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ ŠæŠµŃ€ŠµŠ²Š¾Š“Š¾Š² стрŠ¾ŠŗŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="698"/>
+ <source>at least one VM name or uuid required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся хŠ¾Ń‚я Š±Ń‹ Š¾Š“Š½Š¾ ŠøŠ¼Ń Š’Šœ ŠøŠ»Šø uuid</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="716"/>
+ <source>Waiting for VM &quot;%s&quot; to power on...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ Š·Š°ŠæусŠŗŠ° Š’Šœ &quot;%s&quot;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="731"/>
+ <source>VM &quot;%s&quot; has been successfully started.
+</source>
+ <translation>Š’Šœ &quot;%s&quot; усŠæŠµŃˆŠ½Š¾ Š·Š°ŠæущŠµŠ½Š°.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="844"/>
+ <location filename="../VBoxManageMisc.cpp" line="880"/>
+ <source>Key: %ls, Value: %ls
+</source>
+ <translation>ŠšŠ»ŃŽŃ‡: %ls, Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="853"/>
+ <location filename="../VBoxManageMisc.cpp" line="889"/>
+ <source>Value: %ls
+</source>
+ <translation>Š—Š½Š°Ń‡ŠµŠ½ŠøŠµ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="855"/>
+ <location filename="../VBoxManageMisc.cpp" line="891"/>
+ <source>No value set!
+</source>
+ <translation>ŠŠµ Š·Š°Š“Š°Š½Š¾ ŠŗŠ°ŠŗŠ¾Šµ-Š»ŠøŠ±Š¾ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ!
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="903"/>
+ <location filename="../VBoxManageMisc.cpp" line="1315"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="916"/>
+ <location filename="../VBoxManageMisc.cpp" line="938"/>
+ <source>Too many parameters</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="972"/>
+ <source>Invalid hwvirtexclusive argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ hwvirtexclusive &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="979"/>
+ <source>Warning: &apos;vrdpauthlibrary&apos; is deprecated. Use &apos;vrdeauthlibrary&apos;.
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: &apos;vrdpauthlibrary&apos; устŠ°Ń€ŠµŠ». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;vrdeauthlibrary&apos;.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1009"/>
+ <source>Error parsing Log history count &apos;%s&apos;</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ рŠ°Š·Š¼ŠµŃ€Š° ŠøстŠ¾Ń€ŠøŠø Š¶ŃƒŃ€Š½Š°Š»Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1044"/>
+ <source>Unknown proxy mode: &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Ń‹Š¹ рŠµŠ¶ŠøŠ¼ ŠæрŠ¾ŠŗсŠø: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1138"/>
+ <location filename="../VBoxManageMisc.cpp" line="1250"/>
+ <source>Machine name is given more than once: first &apos;%s&apos;, then &apos;%s&apos;</source>
+ <translation>Š˜Š¼Ń Š¼Š°ŃˆŠøŠ½Ń‹ Š“Š°Š½Š¾ Š±Š¾Š»ŠµŠµ Š¾Š“Š½Š¾Š³Š¾ рŠ°Š·Š°: сŠ½Š°Ń‡Š°Š»Š° &apos;%s&apos;, Š·Š°Ń‚ŠµŠ¼ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1148"/>
+ <location filename="../VBoxManageMisc.cpp" line="1260"/>
+ <source>No machine was specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š° Š¼Š°ŃˆŠøŠ½Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1151"/>
+ <location filename="../VBoxManageMisc.cpp" line="1262"/>
+ <source>No shared folder name (--name) was given</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń Š¾Š±Ń‰ŠµŠ¹ ŠæŠ°ŠæŠŗŠø (--name)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1153"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains space</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń Š¾Š±Ń‰ŠµŠ¹ ŠæŠ°ŠæŠŗŠø &apos;%s&apos;: сŠ¾Š“ŠµŃ€Š¶Šøт ŠæрŠ¾Š±ŠµŠ»Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1155"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains tabs</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń Š¾Š±Ń‰ŠµŠ¹ ŠæŠ°ŠæŠŗŠø &apos;%s&apos;: сŠ¾Š“ŠµŃ€Š¶Šøт тŠ°Š±ŃƒŠ»ŃŃ†Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1157"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains newline</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń Š¾Š±Ń‰ŠµŠ¹ ŠæŠ°ŠæŠŗŠø &apos;%s&apos;: сŠ¾Š“ŠµŃ€Š¶Šøт ŠæŠµŃ€ŠµŠ²Š¾Š“ы стрŠ¾Šŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1160"/>
+ <source>No host path (--hostpath) was given</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ Šæуть хŠ¾ŃŃ‚Š° (--hostpath)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1164"/>
+ <source>RTAbsPath failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTAbsPath Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1187"/>
+ <source>Machine &apos;%s&apos; is not currently running.</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° &apos;%s&apos; сŠµŠ¹Ń‡Š°Ń Š½Šµ Š·Š°ŠæущŠµŠ½Š°.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1283"/>
+ <source>Machine &apos;%s&apos; is not currently running.
+</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° &apos;%s&apos; сŠµŠ¹Ń‡Š°Ń Š½Šµ Š·Š°ŠæущŠµŠ½Š°.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1374"/>
+ <location filename="../VBoxManageMisc.cpp" line="1459"/>
+ <source>Too many extension pack names given to &quot;extpack uninstall&quot;</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠøŠ¼ŠµŠ½ ŠæŠ°ŠŗŠµŃ‚Š¾Š² рŠ°ŃŃˆŠøрŠµŠ½ŠøŠ¹ уŠŗŠ°Š·Š°Š½Š¾ Š“Š»Ń &quot;extpack uninstall&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1383"/>
+ <source>No extension pack name was given to &quot;extpack install&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠ°ŠŗŠµŃ‚Š° рŠ°ŃŃˆŠøрŠµŠ½Šøя Š“Š»Ń &quot;extpack install&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1412"/>
+ <source>License accepted.
+</source>
+ <translation>Š›ŠøцŠµŠ½Š·Šøя ŠæрŠøŠ½ŃŃ‚Š°.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1416"/>
+ <source>Do you agree to these license terms and conditions (y/n)? </source>
+ <translation>Š’Ń‹ сŠ¾Š³Š»Š°ŃŠ½Ń‹ с этŠøŠ¼Šø Š¾ŠæрŠµŠ“ŠµŠ»ŠµŠ½ŠøяŠ¼Šø Šø усŠ»Š¾Š²ŠøяŠ¼Šø Š»ŠøцŠµŠ½Š·ŠøŠø (y/n)? </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1421"/>
+ <source>Installation of &quot;%ls&quot; aborted.
+</source>
+ <translation>Š£ŃŃ‚Š°Š½Š¾Š²ŠŗŠ° &quot;%ls&quot; ŠæрŠµŃ€Š²Š°Š½Š°.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1425"/>
+ <source>License accepted. For batch installation add
+--accept-license=%s
+to the VBoxManage command line.
+
+</source>
+ <translation>Š›ŠøцŠµŠ½Š·Šøя ŠæрŠøŠ½ŃŃ‚Š°. Š”Š»Ń ŠæŠ°ŠŗŠµŃ‚Š½Š¾Š¹ устŠ°Š½Š¾Š²ŠŗŠø Š“Š¾Š±Š°Š²ŃŒŃ‚Šµ
+--accept-license=%s
+Š² ŠŗŠ¾Š¼Š°Š½Š“Š½ŃƒŃŽ стрŠ¾Šŗу VBoxManage.
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1433"/>
+ <source>Failed to install &quot;%s&quot;</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ устŠ°Š½Š¾Š²Šøть &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1435"/>
+ <source>Successfully installed &quot;%ls&quot;.
+</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ устŠ°Š½Š¾Š²Š»ŠµŠ½Š¾ &quot;%ls&quot;.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1468"/>
+ <source>No extension pack name was given to &quot;extpack uninstall&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠ°ŠŗŠµŃ‚Š° рŠ°ŃŃˆŠøрŠµŠ½Šøя Š“Š»Ń &quot;extpack uninstall&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1474"/>
+ <source>Failed to uninstall &quot;%s&quot;</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1476"/>
+ <source>Successfully uninstalled &quot;%s&quot;.
+</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ уŠ“Š°Š»ŠµŠ½Š¾ &quot;%s&quot;.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1484"/>
+ <source>Successfully performed extension pack cleanup
+</source>
+ <translation>Š£ŃŠæŠµŃˆŠ½Š¾ ŠæрŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½Š° Š¾Ń‡ŠøстŠŗŠ° ŠæŠ°ŠŗŠµŃ‚Š° рŠ°ŃŃˆŠøрŠµŠ½Šøя
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1526"/>
+ <location filename="../VBoxManageMisc.cpp" line="1679"/>
+ <location filename="../VBoxManageMisc.cpp" line="1718"/>
+ <location filename="../VBoxManageMisc.cpp" line="1731"/>
+ <location filename="../VBoxManageMisc.cpp" line="1766"/>
+ <location filename="../VBoxManageMisc.cpp" line="1777"/>
+ <location filename="../VBoxManageMisc.cpp" line="1784"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation>RTPathAbs Š·Š°Š²ŠµŃ€ŃˆŠøŠ»ŃŃ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹ Š½Š° &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1542"/>
+ <source>No ISO specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ ISO</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1587"/>
+ <source>Detected &apos;%s&apos; to be:
+</source>
+ <translation>ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Š½Ń‹Š¹ &apos;%s&apos;:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1588"/>
+ <source> OS TypeId = %ls
+ OS Version = %ls
+ OS Flavor = %ls
+ OS Languages = %ls
+ OS Hints = %ls
+</source>
+ <translation> ID тŠøŠæŠ° ŠžŠ” = %ls
+ Š’ŠµŃ€ŃŠøя ŠžŠ” = %ls
+ ŠžŃŠ¾Š±ŠµŠ½Š½Š¾ŃŃ‚ŃŒ ŠžŠ” = %ls
+ ŠÆŠ·Ń‹ŠŗŠø ŠžŠ” = %ls
+ ŠŸŠ¾Š“сŠŗŠ°Š·ŠŗŠø ŠžŠ” = %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1671"/>
+ <source>VM name/UUID given more than once!</source>
+ <translation>Š˜Š¼Ń Š’Šœ/UUID уŠŗŠ°Š·Š°Š½Ń‹ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ рŠ°Š·!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1813"/>
+ <source>Missing VM name/UUID</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ¼Ń Š’Šœ/UUID</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1865"/>
+ <source>Machine &apos;%ls&apos; is currently running</source>
+ <translation>ŠœŠ°ŃˆŠøŠ½Š° &apos;%ls&apos; сŠµŠ¹Ń‡Š°Ń рŠ°Š±Š¾Ń‚Š°ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1871"/>
+ <source>%s unattended installation of %s in machine &apos;%ls&apos; (%ls).
+</source>
+ <translation>%s unattended устŠ°Š½Š¾Š²ŠŗŠ° %s Š² Š¼Š°ŃˆŠøŠ½Ńƒ &apos;%ls&apos; (%ls).
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1872"/>
+ <source>Preparing</source>
+ <translation>ŠŸŠ¾Š“Š³Š¾Ń‚Š¾Š²ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1872"/>
+ <source>Starting</source>
+ <translation>Š—Š°ŠæусŠŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1885"/>
+ <source>Using values:
+</source>
+ <translation>Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŠ¼Ń‹Šµ Š·Š½Š°Ń‡ŠµŠ½Šøя:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1892"/>
+ <location filename="../VBoxManageMisc.cpp" line="1900"/>
+ <location filename="../VBoxManageMisc.cpp" line="1952"/>
+ <source> %32s = failed: %Rhrc
+</source>
+ <translation> %32s = Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾ с Š¾ŃˆŠøŠ±ŠŗŠ¾Š¹: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1955"/>
+ <source> %32 = failed: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1971"/>
+ <source>VM &apos;%ls&apos; (%ls) is ready to be started (e.g. VBoxManage startvm).
+</source>
+ <translation>Š’Šœ &apos;%ls&apos; (%ls) Š³Š¾Ń‚Š¾Š²Š° Šŗ Š·Š°ŠæусŠŗу (Š½Š°ŠæрŠøŠ¼ŠµŃ€, VBoxManage startvm).
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1990"/>
+ <source>Waiting for VM &apos;%ls&apos; to power on...
+</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°Š½ŠøŠµ Š·Š°ŠæусŠŗŠ° Š’Šœ &apos;%ls&apos;...
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2005"/>
+ <source>VM &apos;%ls&apos; (%ls) has been successfully started.
+</source>
+ <translation>Š’Šœ &apos;%ls&apos; (%ls) усŠæŠµŃˆŠ½Š¾ Š·Š°ŠæущŠµŠ½Š°.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2137"/>
+ <location filename="../VBoxManageMisc.cpp" line="2187"/>
+ <location filename="../VBoxManageMisc.cpp" line="2247"/>
+ <location filename="../VBoxManageMisc.cpp" line="2345"/>
+ <source>Parameter --provider is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --provider</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2139"/>
+ <location filename="../VBoxManageMisc.cpp" line="2189"/>
+ <location filename="../VBoxManageMisc.cpp" line="2249"/>
+ <location filename="../VBoxManageMisc.cpp" line="2347"/>
+ <source>Parameter --profile is required</source>
+ <translation>Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ --profile</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2168"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was updated.
+</source>
+ <translation>ŠŸŃ€Š¾Š²Š°Š¹Š“ŠµŃ€ %ls: ŠæрŠ¾Ń„ŠøŠ»ŃŒ &apos;%ls&apos; Š¾Š±Š½Š¾Š²Š»ŠµŠ½.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2210"/>
+ <source>Provider GUID: %ls
+</source>
+ <translation>GUID ŠæрŠ¾Š²Š°Š¹Š“ŠµŃ€Š°: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2226"/>
+ <source>Property: </source>
+ <translation>Š”Š²Š¾Š¹ŃŃ‚Š²Š¾: </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2331"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was added.
+</source>
+ <translation>ŠŸŃ€Š¾Š²Š°Š¹Š“ŠµŃ€ %ls: ŠæрŠ¾Ń„ŠøŠ»ŃŒ &apos;%ls&apos; Š“Š¾Š±Š°Š²Š»ŠµŠ½.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2374"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was deleted.
+</source>
+ <translation>ŠŸŃ€Š¾Š²Š°Š¹Š“ŠµŃ€ %ls: ŠæрŠ¾Ń„ŠøŠ»ŃŒ &apos;%ls&apos; уŠ“Š°Š»ŠµŠ½.
+</translation>
+ </message>
+</context>
+<context>
+ <name>ModifyVM</name>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="467"/>
+ <source>Warning: &apos;--vrdp%s&apos; is deprecated. Use &apos;--vrde%s&apos;.
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: &apos;--vrdp%s&apos; устŠ°Ń€ŠµŠ». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ &apos;--vrde%s&apos;.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="578"/>
+ <source>Invalid %s number %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š½Š¾Š¼ŠµŃ€ %s %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="607"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2089"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="670"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="678"/>
+ <source>Cannot get size of file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="684"/>
+ <source>File &quot;%s&quot; is bigger than 256KByte</source>
+ <translation>Š¤Š°Š¹Š» &quot;%s&quot; Š±Š¾Š»ŃŒŃˆŠµ 256 ŠšŠ‘Š°Š¹Ń‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="692"/>
+ <source>Cannot read contents of file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ фŠ°Š¹Š»Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="743"/>
+ <source>Invalid --firmware argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --firmware &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="814"/>
+ <source>Invalid --paravirtprovider argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --paravirtprovider &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <source>Missing or Invalid argument to &apos;%s&apos;</source>
+ <translation type="vanished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ»Šø Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="841"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="1989"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2381"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2460"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2503"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2939"/>
+ <source>Missing or invalid argument to &apos;%s&apos;</source>
+ <translation type="unfinished">ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ»Šø Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="985"/>
+ <source>Invalid --graphicscontroller argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --graphicscontroller &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1051"/>
+ <source>Invalid --biosbootmenu argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --biosbootmenu &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1075"/>
+ <source>Invalid --biosapic argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --biosapic &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1122"/>
+ <source>Invalid boot device &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š·Š°Š³Ń€ŃƒŠ·Š¾Ń‡Š½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1202"/>
+ <source>Invalid --idecontroller argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --idecontroller &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1232"/>
+ <source>Invalid --usb argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --usb &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1307"/>
+ <source>Invalid --scsitype argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --scsitype &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1362"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="1370"/>
+ <source>Invalid host DVD drive name &quot;%s&quot;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń DVD Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1436"/>
+ <source>Invalid host floppy drive name &quot;%s&quot;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń фŠ»Š¾ŠæŠæŠø Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1516"/>
+ <source>Invalid --nicproperty%d argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --nicproperty%d &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1523"/>
+ <source>Error: Failed to allocate memory for --nicproperty%d &apos;%s&apos;
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ°: ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ Š“Š»Ń --nicproperty%d &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1597"/>
+ <source>Invalid NIC type &apos;%s&apos; specified for NIC %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ NIC &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń NIC %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1632"/>
+ <source>Invalid boot priority &apos;%u&apos; specfied for NIC %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹ ŠæрŠøŠ¾Ń€ŠøтŠµŃ‚ Š·Š°Š³Ń€ŃƒŠ·ŠŗŠø &apos;%u&apos; уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń NIC %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1654"/>
+ <source>Unknown promiscuous mode policy &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń ŠæŠ¾Š»ŠøтŠøŠŗŠ° Š½ŠµŃ€Š°Š·Š±Š¾Ń€Ń‡ŠøŠ²Š¾Š³Š¾ рŠµŠ¶ŠøŠ¼Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1789"/>
+ <source>Invalid type &apos;%s&apos; specfied for NIC %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń NIC %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2073"/>
+ <source>Invalid proto &apos;%s&apos; specfied for NIC %u</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæрŠ¾Ń‚Š¾ŠŗŠ¾Š» &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń NIC %u</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2291"/>
+ <source>Invalid type &apos;%s&apos; specfied for pointing device</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń уŠŗŠ°Š·Š°Ń‚ŠµŠ»ŃŒŠ½Š¾Š³Š¾ устрŠ¾Š¹ŃŃ‚Š²Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2336"/>
+ <source>Invalid type &apos;%s&apos; specfied for keyboard</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ &apos;%s&apos;, уŠŗŠ°Š·Š°Š½Š½Ń‹Š¹ Š“Š»Ń ŠŗŠ»Š°Š²ŠøŠ°Ń‚ŃƒŃ€Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2439"/>
+ <source>Invalid argument to &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2467"/>
+ <source>Error parsing UART I/O base &apos;%s&apos;</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š±Š°Š·Š¾Š²Š¾Š³Š¾ Š°Š“рŠµŃŠ° I/O UART &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2510"/>
+ <source>Error parsing LPT I/O base &apos;%s&apos;</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø рŠ°Š·Š±Š¾Ń€Šµ Š±Š°Š·Š¾Š²Š¾Š³Š¾ Š°Š“рŠµŃŠ° I/O LPT &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2539"/>
+ <source>Invalid --audiocontroller argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --audiocontroller &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2561"/>
+ <source>Invalid --audiocodec argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --audiocodec &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2633"/>
+ <source>Invalid --audio argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --audio &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2673"/>
+ <source>Invalid --clipboard-mode argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --clipboard-mode &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2693"/>
+ <source>Invalid --clipboard-file-transfers argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --clipboard-file-transfers &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2718"/>
+ <source>Invalid --draganddrop argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --draganddrop &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2772"/>
+ <source>Invalid --vrdeproperty argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --vrdeproperty &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2780"/>
+ <source>Error: Failed to allocate memory for VRDE property &apos;%s&apos;
+</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ°: ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š²Ń‹Š“ŠµŠ»Šøть ŠæŠ°Š¼ŃŃ‚ŃŒ ŠæŠ¾Š“ сŠ²Š¾Š¹ŃŃ‚Š²Š¾ VRDE &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2842"/>
+ <source>Invalid --vrdeauthtype argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --vrdeauthtype &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2960"/>
+ <source>Invalid --usbrename parameters, nothing renamed</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Šµ ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры Šŗ --usbrename, Š½ŠøчŠµŠ³Š¾ Š½Šµ ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3164"/>
+ <source>*** I/O APIC must be enabled for ICH9, enabling. ***
+</source>
+ <translation>*** I/O APIC Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š“Š»Ń ICH9, Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ. ***
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3170"/>
+ <source>Invalid --chipset argument &apos;%s&apos; (valid: piix3,ich9)</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --chipset &apos;%s&apos; (Š“Š¾ŠæустŠøŠ¼Ń‹Šµ: piix3,ich9)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3188"/>
+ <source>Invalid --iommu argument &apos;%s&apos; (valid: none,amd,automatic)</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --iommu &apos;%s&apos; (Š“Š¾ŠæустŠøŠ¼Ń‹Šµ: none,amd,automatic)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3197"/>
+ <source>Warning: On Intel hosts, &apos;automatic&apos; will not enable an IOMMU since the Intel IOMMU device is not supported yet.
+</source>
+ <translation>ŠŸŃ€ŠµŠ“уŠæрŠµŠ¶Š“ŠµŠ½ŠøŠµ: ŠŠ° хŠ¾ŃŃ‚Š°Ń… Intel, &apos;automatic&apos; Š½Šµ Š²ŠŗŠ»ŃŽŃ‡Š°ŠµŃ‚ IOMMU, тŠ°Šŗ ŠŗŠ°Šŗ Intel IOMMU устрŠ¾Š¹ŃŃ‚Š²Š° ŠµŃ‰Šµ Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ся.
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3202"/>
+ <source>Invalid --iommu argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --iommu &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3227"/>
+ <source>Invalid --tpm-type argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --tpm-type &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3284"/>
+ <source>Invalid list of screens specified
+</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½ Š½ŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ сŠæŠøсŠ¾Šŗ эŠŗрŠ°Š½Š¾Š²
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3306"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ ŠøŠ¼Ń фŠ°Š¹Š»Š° &quot;%s&quot; Š² Š°Š±ŃŠ¾Š»ŃŽŃ‚Š½Ń‹Š¹ Šæуть
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3336"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="3345"/>
+ <source>Error parsing video resolution &apos;%s&apos; (expected &lt;width&gt;x&lt;height&gt;)</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° рŠ°Š·Š±Š¾Ń€Š° Š²ŠøŠ“ŠµŠ¾ рŠ°Š·Ń€ŠµŃˆŠµŠ½Šøя &apos;%s&apos; (Š¾Š¶ŠøŠ“Š°ŠµŃ‚ся &lt;шŠøрŠøŠ½Š°&gt;x&lt;Š²Ń‹ŃŠ¾Ń‚Š°&gt;)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3420"/>
+ <source>Invalid --autostop-type argument &apos;%s&apos; (valid: disabled, savestate, poweroff, acpishutdown)</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --autostop-type &apos;%s&apos; (Š“Š¾ŠæустŠøŠ¼Ń‹Šµ: disabled, savestate, poweroff, acpishutdown)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3440"/>
+ <source>Invalid --pciattach argument &apos;%s&apos; (valid: &apos;HB:HD.HF@GB:GD.GF&apos; or just &apos;HB:HD.HF&apos;)</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --pciattach &apos;%s&apos; (Š“Š¾ŠæустŠøŠ¼Ń‹Šµ: &apos;HB:HD.HF@GB:GD.GF&apos; ŠøŠ»Šø ŠæрŠ¾ŃŃ‚Š¾ &apos;HB:HD.HF&apos;)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3458"/>
+ <source>Invalid --pcidetach argument &apos;%s&apos; (valid: &apos;HB:HD.HF&apos;)</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --pcidetach &apos;%s&apos; (Š“Š¾ŠæустŠøŠ¼Ń‹Š¹: &apos;HB:HD.HF&apos;)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3492"/>
+ <source>Invalid --vm-process-priority &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ --vm-process-priority &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3521"/>
+ <source>--testing-cfg-dword index %u is out of range: 0 thru 9</source>
+ <translation>Š˜Š½Š“ŠµŠŗс --testing-cfg-dword %u Š²Š½Šµ Š³Ń€Š°Š½Šøц Š“ŠøŠ°ŠæŠ°Š·Š¾Š½Š°: 0 - 9</translation>
+ </message>
+</context>
+<context>
+ <name>Nat</name>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="96"/>
+ <source>Name: %ls
+</source>
+ <translation>Š˜Š¼Ń: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="110"/>
+ <source>Network: %ls
+</source>
+ <translation>Š”ŠµŃ‚ŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="113"/>
+ <source>Gateway: %ls
+</source>
+ <translation>ŠØŠ»ŃŽŠ·: %ls
+</translation>
+ </message>
+ <message>
+ <source>DHCP Sever: %s
+</source>
+ <translation type="vanished">DHCP сŠµŃ€Š²ŠµŃ€: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="119"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>Yes</source>
+ <translation>Š”Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="119"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>No</source>
+ <translation>ŠŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="122"/>
+ <source>IPv6 Prefix: %ls
+</source>
+ <translation>IPv6 ŠæрŠµŃ„ŠøŠŗс: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>IPv6 Default: %s
+</source>
+ <translation>IPv6 ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <source>Enabled: %s
+</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <source>DHCP Server: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="142"/>
+ <source>Port-forwarding (ipv4)
+</source>
+ <translation type="unfinished">ŠŸŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ ŠæŠ¾Ń€Ń‚Š¾Š² (ipv4)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="146"/>
+ <source>Port-forwarding (ipv6)
+</source>
+ <translation type="unfinished">ŠŸŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ ŠæŠ¾Ń€Ń‚Š¾Š² (ipv6)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="150"/>
+ <source>loopback mappings (ipv4)
+</source>
+ <translation type="unfinished">Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š¹ ŠæŠµŃ‚Š»Šø (ipv4)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="166"/>
+ <source>NAT Networks:
+
+</source>
+ <translation>Š”ŠµŃ‚Šø NAT:
+
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>%zu %s found
+</source>
+ <translation>ŠŠ°Š¹Š“ŠµŠ½Š¾ %zu %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>network</source>
+ <translation>сŠµŃ‚ŃŒ</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>networks</source>
+ <translation>
+ <numerusform>сŠµŃ‚ŃŒ</numerusform>
+ <numerusform>сŠµŃ‚Šø</numerusform>
+ <numerusform>сŠµŃ‚ŠµŠ¹</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="206"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="602"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="261"/>
+ <source>You can only specify --netname only once.</source>
+ <translation>--netname Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="267"/>
+ <source>You can only specify --network only once.</source>
+ <translation>--network Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="273"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="279"/>
+ <source>You can specify either --enable or --disable once.</source>
+ <translation>--enable Šø --disable Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="285"/>
+ <source>You can specify --dhcp only once.</source>
+ <translation>--dhcp Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="291"/>
+ <source>You can specify --ipv6 only once.</source>
+ <translation>--ipv6 Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="297"/>
+ <source>You can specify --ipv6-prefix only once.</source>
+ <translation>--ipv6-prefix Š¼Š¾Š¶Š½Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ рŠ°Š·.</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="303"/>
+ <source>You can specify --ipv6-default only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="313"/>
+ <source>loopback couldn&apos;t be deleted on modified
+</source>
+ <translation>Š›Š¾ŠŗŠ°Š»ŃŒŠ½Š°Ń ŠæŠµŃ‚Š»Ń Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠ“Š°Š»ŠµŠ½Š° ŠøŠ»Šø ŠøŠ·Š¼ŠµŠ½ŠµŠ½Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="324"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="362"/>
+ <source>Not enough parŠ°meters
+</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="349"/>
+ <source>Invalid port-forward rule %s
+</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠæрŠ°Š²ŠøŠ»Š¾ ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøя ŠæŠ¾Ń€Ń‚Š¾Š² %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="357"/>
+ <source>Port-forward could be deleted on modify
+</source>
+ <translation>ŠŸŃ€Š°Š²ŠøŠ»Š¾ ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøя ŠæŠ¾Ń€Ń‚Š¾Š² Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ уŠ“Š°Š»ŠµŠ½Š¾ ŠæрŠø ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŠø
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="365"/>
+ <source>Port-forward rule name is too long
+</source>
+ <translation>Š˜Š¼Ń ŠæрŠ°Š²ŠøŠ»Š° ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøя ŠæŠ¾Ń€Ń‚Š¾Š² сŠ»ŠøшŠŗŠ¾Š¼ Š±Š¾Š»ŃŒŃˆŠ¾Šµ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="382"/>
+ <source>You need to specify the --netname option</source>
+ <translation>ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ Š¾ŠæцŠøю --netname</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="388"/>
+ <source>You need to specify the --network option</source>
+ <translation>ŠŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ уŠŗŠ°Š·Š°Ń‚ŃŒ Š¾ŠæцŠøю --network</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="396"/>
+ <source>Unknown operation (:%d)</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæŠµŃ€Š°Ń†Šøя (:%d)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="408"/>
+ <source>NATNetwork server already exists</source>
+ <translation>Š”ŠµŃ€Š²ŠµŃ€ сŠµŃ‚Šø NAT уŠ¶Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="412"/>
+ <source>Failed to create the NAT network service</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ сŠ»ŃƒŠ¶Š±Ńƒ сŠµŃ‚Šø NAT</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="415"/>
+ <source>NATNetwork server does not exist</source>
+ <translation>Š”ŠµŃ€Š²ŠµŃ€ сŠµŃ‚Šø NAT Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="426"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="432"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="444"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="451"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="462"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="470"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="565"/>
+ <source>Failed to set configuration</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†Šøю</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="481"/>
+ <source>Failed to delete pf</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть ŠæрŠ°Š²ŠøŠ»Š¾ ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøя ŠæŠ¾Ń€Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="506"/>
+ <source>Failed to add pf</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š“Š¾Š±Š°Š²Šøть ŠæрŠ°Š²ŠøŠ»Š¾ ŠæŠµŃ€ŠµŠ½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøя ŠæŠ¾Ń€Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="532"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="538"/>
+ <source>invalid loopback string</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń стрŠ¾ŠŗŠ° Š»Š¾ŠŗŠ°Š»ŃŒŠ½Š¾Š¹ ŠæŠµŃ‚Š»Šø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="573"/>
+ <source>Failed to remove nat network</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ уŠ“Š°Š»Šøть сŠµŃ‚ŃŒ NAT</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="580"/>
+ <source>Failed to start network</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°ŠæустŠøть сŠµŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="587"/>
+ <source>Failed to stop network</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š¾ŃŃ‚Š°Š½Š¾Š²Šøть сŠµŃ‚ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="636"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>Nvram</name>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="121"/>
+ <source>No platform key file path was given to &quot;enrollpk&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ Šæуть Šŗ фŠ°Š¹Š»Ńƒ с ŠŗŠ»ŃŽŃ‡Š¾Š¼ ŠæŠ»Š°Ń‚Ń„Š¾Ń€Š¼Ń‹ Š“Š»Ń &quot;enrollpk&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="123"/>
+ <source>No owner UUID was given to &quot;enrollpk&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ UUID Š²Š»Š°Š“ŠµŠ»ŃŒŃ†Š° Š“Š»Ń &quot;enrollpk&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="147"/>
+ <source>Cannot read contents of file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠµŃŃ‚ŃŒ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ фŠ°Š¹Š»Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="150"/>
+ <source>File &quot;%s&quot; is bigger than 32KByte</source>
+ <translation>Š¤Š°Š¹Š» &quot;%s&quot; Š±Š¾Š»ŃŒŃˆŠµ 32 ŠšŠ‘Š°Š¹Ń‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="153"/>
+ <source>Cannot get size of file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š»ŃƒŃ‡Šøть рŠ°Š·Š¼ŠµŃ€ фŠ°Š¹Š»Š° &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="158"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š¾Ń‚Šŗрыть фŠ°Š¹Š» &quot;%s&quot;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="250"/>
+ <source>No variable name was given to &quot;queryvar&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠµŃ€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“Š»Ń &quot;queryvar&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="277"/>
+ <source>Error writing to &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø Š·Š°ŠæŠøсŠø Š² &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="282"/>
+ <location filename="../VBoxManageModifyNvram.cpp" line="411"/>
+ <source>Error opening &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø Š¾Ń‚ŠŗрытŠøŠø &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="329"/>
+ <source>No variable name was given to &quot;deletevar&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠµŃ€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“Š»Ń &quot;deletevar&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="331"/>
+ <source>No owner UUID was given to &quot;deletevar&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ UUID Š²Š»Š°Š“ŠµŠ»ŃŒŃ†Š° Š“Š»Ń &quot;deletevar&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="381"/>
+ <source>No variable name was given to &quot;changevar&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠæŠµŃ€ŠµŠ¼ŠµŠ½Š½Š¾Š¹ Š“Š»Ń &quot;changevar&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="383"/>
+ <source>No variable data filename was given to &quot;changevar&quot;</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń фŠ°Š¹Š»Š° с Š“Š°Š½Š½Ń‹Š¼Šø Š“Š»Ń &quot;changevar&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="407"/>
+ <source>Error reading from &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° ŠæрŠø чтŠµŠ½ŠøŠø ŠøŠ· &apos;%s&apos;: %Rrc</translation>
+ </message>
+</context>
+<context>
+ <name>Snapshot</name>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="198"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="520"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="594"/>
+ <source>This machine does not have any snapshots
+</source>
+ <translation>Š£ этŠ¾Š¹ Š¼Š°ŃˆŠøŠ½Ń‹ Š½ŠµŃ‚ сŠ½ŠøŠ¼ŠŗŠ¾Š²
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="254"/>
+ <source>[%RI32] Images and snapshots for medium &quot;%ls&quot;
+</source>
+ <translation>[%RI32] ŠžŠ±Ń€Š°Š·Ń‹ Šø сŠ½ŠøŠ¼ŠŗŠø Š½Š¾ŃŠøтŠµŠ»Ń &quot;%ls&quot;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="329"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="359"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="561"/>
+ <source>Missing snapshot name</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠøŠ¼Ń сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="404"/>
+ <source>Invalid unique name description &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š¾ŠæŠøсŠ°Š½ŠøŠµ уŠ½ŠøŠŗŠ°Š»ŃŒŠ½Š¾Š³Š¾ ŠøŠ¼ŠµŠ½Šø &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="467"/>
+ <source>Failed to generate a unique snapshot name</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃ‚ сŠ³ŠµŠ½ŠµŃ€ŠøрŠ¾Š²Š°Ń‚ŃŒ уŠ½ŠøŠŗŠ°Š»ŃŒŠ½Š¾Šµ ŠøŠ¼Ń сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="483"/>
+ <source>Snapshot taken. UUID: %ls
+</source>
+ <translation>Š”Š½ŠøŠ¼Š¾Šŗ сŠ“ŠµŠ»Š°Š½. UUID: %ls
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="485"/>
+ <source>Failed to take snapshot</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ“ŠµŠ»Š°Ń‚ŃŒ сŠ½ŠøŠ¼Š¾Šŗ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="500"/>
+ <source>Too many arguments</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="508"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="628"/>
+ <source>Expecting snapshot name only</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся тŠ¾Š»ŃŒŠŗŠ¾ ŠøŠ¼Ń сŠ½ŠøŠ¼ŠŗŠ°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="539"/>
+ <source>%s snapshot &apos;%ls&apos; (%ls)
+</source>
+ <translation>%s сŠ½ŠøŠ¼ŠŗŠ° &apos;%ls&apos; (%ls)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="540"/>
+ <source>Deleting</source>
+ <translation>Š£Š“Š°Š»ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="540"/>
+ <source>Restoring</source>
+ <translation>Š’Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½ŠøŠµ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="554"/>
+ <source>Snapshot operation failed</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Š²ŠµŃŃ‚Šø Š¾ŠæŠµŃ€Š°Ń†Šøю Š½Š°Š“ сŠ½ŠøŠ¼ŠŗŠ¾Š¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="652"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>Storage</name>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="166"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1180"/>
+ <source>Invalid --type argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --type &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="305"/>
+ <source>Invalid medium type &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ тŠøŠæ Š½Š¾ŃŠøтŠµŠ»Ń &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="327"/>
+ <source>Storage controller name not specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š° Š½Š¾ŃŠøтŠµŠ»ŠµŠ¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="347"/>
+ <source>Drive passthrough state cannot be changed while the VM is running
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ ŠæряŠ¼Š¾Š³Š¾ Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ Š“ŠøсŠŗу Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½Š¾ ŠæŠ¾ŠŗŠ° рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ Š’Šœ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="349"/>
+ <source>Bandwidth group cannot be changed while the VM is running
+</source>
+ <translation>Š“Ń€ŃƒŠæŠæ ŠæŠ¾Š»Š¾ŃŃ‹ ŠæрŠ¾ŠæусŠŗŠ°Š½Šøя Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½Š° ŠæŠ¾ŠŗŠ° рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ Š’Šœ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="356"/>
+ <source>Could not find a controller named &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€ с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="370"/>
+ <source>Port not specified</source>
+ <translation>ŠŸŠ¾Ń€Ń‚ Š½Šµ уŠŗŠ°Š·Š°Š½</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="377"/>
+ <source>Device not specified</source>
+ <translation>Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ Š½Šµ уŠŗŠ°Š·Š°Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="441"/>
+ <source>No DVD/Floppy Drive attached to the controller &apos;%s&apos;at the port: %u, device: %u</source>
+ <translation>ŠŠ° ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€ &apos;%s&apos; ŠæŠ¾Ń€Ń‚ %u устрŠ¾Š¹ŃŃ‚Š²Š¾: %u Š½Šµ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾ ŠŗŠ°ŠŗŠøх Š»ŠøŠ±Š¾ DVD ŠøŠ»Šø Š¤Š»Š¾ŠæŠæŠø Š“ŠøсŠŗŠ¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="461"/>
+ <source>The attachment is not supported by the storage controller &apos;%s&apos;</source>
+ <translation>ŠŸŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ Š“Š°Š½Š½Š¾Š³Š¾ устрŠ¾Š¹ŃŃ‚Š²Š° Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š¼ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="516"/>
+ <source>Cannot find the Guest Additions ISO image
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ISO Š¾Š±Ń€Š°Š· Š”Š¾ŠæŠ¾Š»Š½ŠµŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŠµŠ²Š¾Š¹ ŠžŠ”
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="542"/>
+ <source>Argument --type must be specified
+</source>
+ <translation>ŠŃ€Š³ŃƒŠ¼ŠµŠ½Ń‚ --type Š“Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ уŠŗŠ°Š·Š°Š½
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="556"/>
+ <source>The given attachment is not supported by the storage controller &apos;%s&apos;</source>
+ <translation>Š£ŠŗŠ°Š·Š°Š½Š½Š¾Šµ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ устрŠ¾Š¹ŃŃ‚Š²Š° Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š¾Š¼ Š½Š¾ŃŠøтŠµŠ»ŠµŠ¹ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="578"/>
+ <location filename="../VBoxManageStorageController.cpp" line="582"/>
+ <source>Invalid host DVD drive name &quot;%s&quot;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń DVD Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="591"/>
+ <source>Invalid host floppy drive name &quot;%s&quot;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠøŠ¼Ń фŠ»Š¾ŠæŠæŠø Š“ŠøсŠŗŠ¾Š²Š¾Š“Š° хŠ¾ŃŃ‚Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="598"/>
+ <source>Parameters --server and --target are required for iSCSI media</source>
+ <translation>Š”Š»Ń iSCSI Š½Š¾ŃŠøтŠµŠ»ŠµŠ¹ трŠµŠ±ŃƒŃŽŃ‚ся ŠæŠ°Ń€Š°Š¼ŠµŃ‚ры --server Šø --target</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="665"/>
+ <source>iSCSI disk created. UUID: %s
+</source>
+ <translation>Š”Š¾Š·Š“Š°Š½ iSCSI Š“ŠøсŠŗ. UUID: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="676"/>
+ <source>Missing --medium argument</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ --medium</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="685"/>
+ <source>Invalid UUID or filename &quot;%s&quot;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ UUID ŠøŠ»Šø ŠøŠ¼Ń фŠ°Š¹Š»Š° &quot;%s&quot;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="695"/>
+ <source>Failed to set the medium/parent medium UUID</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ UUID Š½Š¾ŃŠøтŠµŠ»Ń ŠøŠ»Šø UUID рŠ¾Š“ŠøтŠµŠ»ŃŒŃŠŗŠ¾Š³Š¾ Š½Š¾ŃŠøтŠµŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="709"/>
+ <source>Failed to set the medium type</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ Š·Š°Š“Š°Ń‚ŃŒ тŠøŠæ Š½Š¾ŃŠøтŠµŠ»Ń</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="804"/>
+ <source>Invalid --passthrough argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --passthrough &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="807"/>
+ <location filename="../VBoxManageStorageController.cpp" line="833"/>
+ <location filename="../VBoxManageStorageController.cpp" line="859"/>
+ <location filename="../VBoxManageStorageController.cpp" line="885"/>
+ <location filename="../VBoxManageStorageController.cpp" line="911"/>
+ <source>Couldn&apos;t find the controller attachment for the controller &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµ Šŗ ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Ńƒ &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="830"/>
+ <source>Invalid --tempeject argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --tempeject &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="856"/>
+ <source>Invalid --nonrotational argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --nonrotational &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="882"/>
+ <source>Invalid --discard argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --discard &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="908"/>
+ <source>Invalid --hotpluggable argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --hotpluggable &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="990"/>
+ <source>Too few parameters</source>
+ <translation>Š”Š»ŠøшŠŗŠ¾Š¼ Š¼Š°Š»Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1056"/>
+ <source>Storage controller name not specified
+</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½Š¾ ŠøŠ¼Ń ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€Š° Š½Š¾ŃŠøтŠµŠ»ŠµŠ¹
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1119"/>
+ <source>Invalid --add argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --add &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1186"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1205"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1236"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1262"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1281"/>
+ <source>Couldn&apos;t find the controller with the name: &apos;%s&apos;
+</source>
+ <translation>ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø ŠŗŠ¾Š½Ń‚Ń€Š¾Š»Š»ŠµŃ€ с ŠøŠ¼ŠµŠ½ŠµŠ¼ &apos;%s&apos;
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1230"/>
+ <source>Invalid --hostiocache argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --hostiocache &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1256"/>
+ <source>Invalid --bootable argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --bootable &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>UpdateCheck</name>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="81"/>
+ <source>Enabled: %s
+</source>
+ <translation>Š’ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="82"/>
+ <source>yes</source>
+ <translation>Š“Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="82"/>
+ <source>no</source>
+ <translation>Š½ŠµŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="89"/>
+ <source>Count: %u
+</source>
+ <translation>ŠšŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾: %u
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="99"/>
+ <source>Frequency: never
+</source>
+ <translation>Š§Š°ŃŃ‚Š¾Ń‚Š°: Š½ŠøŠŗŠ¾Š³Š“Š°
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="101"/>
+ <source>Frequency: every day
+</source>
+ <translation>Š§Š°ŃŃ‚Š¾Ń‚Š°: ŠŗŠ°Š¶Š“ыŠ¹ Š“ŠµŠ½ŃŒ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="103"/>
+ <source>Frequency: every %u days
+</source>
+ <translation>Š§Š°ŃŃ‚Š¾Ń‚Š°: ŠŗŠ°Š¶Š“ыŠ¹ %u Š“ŠµŠ½ŃŒ
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="112"/>
+ <source>Stable - new minor and maintenance releases</source>
+ <translation>Š”тŠ°Š±ŠøŠ»ŃŒŠ½Ń‹Šµ - Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ Šø ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="116"/>
+ <source>All releases - new minor, maintenance, and major releases</source>
+ <translation>Š’сŠµ рŠµŠ»ŠøŠ·Ń‹ - Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ, ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ Šø Š¼Š°Š¶Š¾Ń€Š½Ń‹Šµ рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="120"/>
+ <source>With Betas - new minor, maintenance, major, and beta releases</source>
+ <translation>Š” Š±ŠµŃ‚Š°Š¼Šø - Š½Š¾Š²Ń‹Šµ Š¼ŠøŠ½Š¾Ń€Š½Ń‹Šµ, ŠŗŠ¾Ń€Ń€ŠµŠŗтŠøрующŠøŠµ, Š¼Š°Š¶Š¾Ń€Š½Ń‹Šµ Šø Š±ŠµŃ‚Š° рŠµŠ»ŠøŠ·Ń‹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="125"/>
+ <source>Unset</source>
+ <translation>ŠŠµ Š·Š°Š“Š°Š½Š¾</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="132"/>
+ <source>Channel: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="189"/>
+ <source>Unknown channel specified: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="258"/>
+ <source>Checking for a new %ls version...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="269"/>
+ <source>Failed to create update progress object: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="277"/>
+ <source>Checking for update failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="296"/>
+ <source>A new version of %ls has been released! Version %ls is available at virtualbox.org.
+You can download this version here: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="312"/>
+ <source>You are already running the most recent version of %ls.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="324"/>
+ <source>Something went wrong while checking for updates!
+Please check network connection and try again later.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Target: %s
+</source>
+ <translation type="vanished">Š¦ŠµŠ»ŃŒ: %s
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="140"/>
+ <source>Last Check Date: %ls
+</source>
+ <translation>ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŃŃ Š“Š°Ń‚Š° ŠæрŠ¾Š²ŠµŃ€ŠŗŠø: %ls
+</translation>
+ </message>
+ <message>
+ <source>Unknown target specified: &apos;%s&apos;</source>
+ <translation type="vanished">Š£ŠŗŠ°Š·Š°Š½Š° Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń цŠµŠ»ŃŒ: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="195"/>
+ <source>The update frequency cannot be zero</source>
+ <translation>Š§Š°ŃŃ‚Š¾Ń‚Š° Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ Š½ŃƒŠ»ŠµŠ²Š¾Š¹</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="206"/>
+ <source>No change requested</source>
+ <translation>ŠŠµ Š·Š°ŠæрŠ¾ŃˆŠµŠ½Š¾ ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŠ¹</translation>
+ </message>
+ <message>
+ <source>Checking for a new VirtualBox version...
+</source>
+ <translation type="vanished">ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° Š½Š° Š½Š°Š»ŠøчŠøŠµ Š½Š¾Š²Š¾Š¹ Š²ŠµŃ€ŃŠøŠø VirtualBox...
+</translation>
+ </message>
+ <message>
+ <source>VirtualBox update checking has been disabled.
+</source>
+ <translation type="vanished">ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŠ¹ VirtualBox Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š°.
+</translation>
+ </message>
+ <message>
+ <source>Failed to create ptrProgress object: %Rhrc
+</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±ŃŠŠµŠŗт ptrProgress: %Rhrc
+</translation>
+ </message>
+ <message>
+ <source>Check for update failed.</source>
+ <translation type="vanished">ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠ¾Š²ŠµŃ€Šøть Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя.</translation>
+ </message>
+ <message>
+ <source>A new version of VirtualBox has been released! Version %ls is available at virtualbox.org.
+You can download this version here: %ls
+</source>
+ <translation type="vanished">Š’Ń‹ŠæущŠµŠ½Š° Š½Š¾Š²Š°Ń Š²ŠµŃ€ŃŠøя VirtualBox! Š’ŠµŃ€ŃŠøя %ls Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° Š½Š° сŠ°Š¹Ń‚Šµ virtualbox.org.
+Š’Ń‹ Š¼Š¾Š¶ŠµŃ‚Šµ Š·Š°Š³Ń€ŃƒŠ·Šøть эту Š²ŠµŃ€ŃŠøю Š·Š“ŠµŃŃŒ: %ls
+</translation>
+ </message>
+ <message>
+ <source>You are already running the most recent version of VirtualBox.
+</source>
+ <translation type="vanished">Š’Ń‹ уŠ¶Šµ ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚Šµ ŠæŠ¾ŃŠ»ŠµŠ“Š½ŃŽŃŽ Š²ŠµŃ€ŃŠøю VirtualBox.
+</translation>
+ </message>
+</context>
+<context>
+ <name>Usb</name>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="178"/>
+ <location filename="../VBoxManageUSB.cpp" line="214"/>
+ <location filename="../VBoxManageUSB.cpp" line="216"/>
+ <location filename="../VBoxManageUSB.cpp" line="373"/>
+ <location filename="../VBoxManageUSB.cpp" line="571"/>
+ <source>Not enough parameters</source>
+ <translation>ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="199"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="203"/>
+ <source>Invalid index &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠøŠ½Š“ŠµŠŗс &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="231"/>
+ <location filename="../VBoxManageUSB.cpp" line="246"/>
+ <location filename="../VBoxManageUSB.cpp" line="254"/>
+ <location filename="../VBoxManageUSB.cpp" line="267"/>
+ <location filename="../VBoxManageUSB.cpp" line="275"/>
+ <location filename="../VBoxManageUSB.cpp" line="283"/>
+ <location filename="../VBoxManageUSB.cpp" line="291"/>
+ <location filename="../VBoxManageUSB.cpp" line="299"/>
+ <location filename="../VBoxManageUSB.cpp" line="307"/>
+ <location filename="../VBoxManageUSB.cpp" line="315"/>
+ <location filename="../VBoxManageUSB.cpp" line="323"/>
+ <location filename="../VBoxManageUSB.cpp" line="336"/>
+ <location filename="../VBoxManageUSB.cpp" line="381"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation>ŠžŃ‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="261"/>
+ <source>Invalid --active argument &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚ Šŗ --active &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="328"/>
+ <source>Failed to convert the --maskedinterfaces value &apos;%s&apos; to a number, vrc=%Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæрŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ --maskedinterfaces &apos;%s&apos; Š² чŠøсŠ»Š¾, vrc=%Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="343"/>
+ <source>Invalid USB filter action &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ Š“ŠµŠ¹ŃŃ‚Š²ŠøŠµ USB фŠøŠ»ŃŒŃ‚Ń€Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="346"/>
+ <source>Unknown option &apos;%s&apos;</source>
+ <translation>ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š°Ń Š¾ŠæцŠøя &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="363"/>
+ <location filename="../VBoxManageUSB.cpp" line="395"/>
+ <source>Mandatory options not supplied</source>
+ <translation>ŠŠµ ŠæрŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŠµŠ½Ń‹ Š¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Šµ Š¾ŠæцŠøŠø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="581"/>
+ <source>Invalid number of parameters</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="596"/>
+ <source>Parameter &quot;%s&quot; is invalid</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Ń‹Š¹ ŠæŠ°Ń€Š°Š¼ŠµŃ‚Ń€ &apos;%s&apos;</translation>
+ </message>
+</context>
+<context>
+ <name>Utils</name>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="102"/>
+ <source>type bridged</source>
+ <translation>тŠøŠæŠ° сŠµŃ‚ŠµŠ²Š¾Š¹ Š¼Š¾ŃŃ‚</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="106"/>
+ <source>type host-only</source>
+ <translation>тŠøŠæŠ° Š²ŠøртуŠ°Š»ŃŒŠ½Š°Ń сŠµŃ‚ŃŒ хŠ¾ŃŃ‚Š°</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="111"/>
+ <source>unknown type %RU32</source>
+ <translation>Š½ŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾Š³Š¾ тŠøŠæŠ° %RU32</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="116"/>
+ <source>Interface &quot;%s&quot; is of %s</source>
+ <translation>Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń &quot;%s&quot; %s</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="120"/>
+ <source>Interface &quot;%s&quot; doesn&apos;t seem to exist</source>
+ <translation>ŠšŠ°Š¶ŠµŃ‚ся, ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń &quot;%s&quot; Š½Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚</translation>
+ </message>
+</context>
+<context>
+ <name>VBoxManage</name>
+ <message>
+ <location filename="../VBoxManage.cpp" line="327"/>
+ <location filename="../VBoxManage.cpp" line="495"/>
+ <source>Progress object failure: %Rhrc
+</source>
+ <translation>ŠžŃ‚ŠŗŠ°Š· Š¾Š±ŃŠŠµŠŗтŠ° ŠæрŠ¾Š³Ń€ŠµŃŃŠ°: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="344"/>
+ <source>Failed to get progress description: %Rhrc
+</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠæŠ¾Š»ŃƒŃ‡Šøть Š¾ŠæŠøсŠ°Š½ŠøŠµ ŠæрŠ¾Š³Ń€ŠµŃŃŠ°: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="411"/>
+ <source>(%u/%u) %ls %02u%% =&gt; %02u%% (%d s remaining)
+</source>
+ <translation>(%u/%u) %ls %02u%% =&gt; %02u%% (%d сŠµŠŗ Š¾ŃŃ‚Š°Š»Š¾ŃŃŒ)
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="481"/>
+ <source>CANCELED
+</source>
+ <translation>ŠžŠ¢ŠœŠ•ŠŠ•ŠŠž
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="485"/>
+ <source>Progress state: %Rhrc
+</source>
+ <translation>Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ ŠæрŠ¾Š³Ń€ŠµŃŃŠ°: %Rhrc
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="672"/>
+ <source>Password expected</source>
+ <translation>ŠžŠ¶ŠøŠ“Š°ŠµŃ‚ся ŠæŠ°Ń€Š¾Š»ŃŒ</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="680"/>
+ <source>No password file specified</source>
+ <translation>ŠŠµ уŠŗŠ°Š·Š°Š½ фŠ°Š¹Š» с ŠæŠ°Ń€Š¾Š»ŠµŠ¼</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="687"/>
+ <source>Only one response file allowed</source>
+ <translation>Š Š°Š·Ń€ŠµŃˆŠ°ŠµŃ‚ся тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“ŠøŠ½ фŠ°Š¹Š» Š¾Ń‚Š²ŠµŃ‚Š¾Š²</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="695"/>
+ <source>Error reading response file &apos;%s&apos;: %Rrc</source>
+ <translation>ŠžŃˆŠøŠ±ŠŗŠ° чтŠµŠ½Šøя фŠ°Š¹Š»Š° Š¾Ń‚Š²ŠµŃ‚Š¾Š² &apos;%s&apos;: %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="700"/>
+ <source>Invalid response file (&apos;%s&apos;) encoding: %Rrc</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠŗŠ¾Š“ŠøрŠ¾Š²ŠŗŠ° фŠ°Š¹Š»Š° Š¾Ń‚Š²ŠµŃ‚Š¾Š² (&apos;%s&apos;): %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="708"/>
+ <source>Failed to parse response file &apos;%s&apos; (bourne shell style): %Rrc</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ фŠ°Š¹Š» Š¾Ń‚Š²ŠµŃ‚Š¾Š² &apos;%s&apos; (стŠøŠ»ŃŒ bourne shell): %Rrc</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="714"/>
+ <source>out of memory</source>
+ <translation>Š½Šµ хŠ²Š°Ń‚Š°ŠµŃ‚ ŠæŠ°Š¼ŃŃ‚Šø</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="755"/>
+ <source>commands:
+</source>
+ <translation>ŠŗŠ¾Š¼Š°Š½Š“ы:
+</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="762"/>
+ <source>Invalid command &apos;%s&apos;</source>
+ <translation>ŠŠµŠ“Š¾ŠæустŠøŠ¼Š°Ń ŠŗŠ¾Š¼Š°Š½Š“Š° &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="781"/>
+ <source>Failed to initialize COM because the global settings directory &apos;%s&apos; is not accessible!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·ŠøрŠ¾Š²Š°Ń‚ŃŒ COM, ŠæŠ¾Ń‚Š¾Š¼Ńƒ чтŠ¾ Š“ŠøрŠµŠŗтŠ¾Ń€Šøя Š³Š»Š¾Š±Š°Š»ŃŒŠ½Ń‹Ń… Š½Š°ŃŃ‚Ń€Š¾ŠµŠŗ &apos;%s&apos; Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š°!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="784"/>
+ <source>Failed to initialize COM! (hrc=%Rhrc)</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ ŠøŠ½ŠøцŠøŠ°Š»ŠøŠ·ŠøрŠ¾Š²Š°Ń‚ŃŒ COM! (hrc=%Rhrc)</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="867"/>
+ <source>Failed to create a session object!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±ŃŠŠµŠŗт сŠµŃŃŠøŠø!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="877"/>
+ <source>Failed to create the VirtualBox object!</source>
+ <translation>ŠŠµ уŠ“Š°Š»Š¾ŃŃŒ сŠ¾Š·Š“Š°Ń‚ŃŒ Š¾Š±ŃŠŠµŠŗт VirtualBox!</translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="881"/>
+ <source>Most likely, the VirtualBox COM server is not running or failed to start.</source>
+ <translation>ŠŠ°ŠøŠ±Š¾Š»ŠµŠµ Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾, чтŠ¾ COM сŠµŃ€Š²ŠµŃ€ VirtualBox Š½Šµ Š·Š°ŠæущŠµŠ½ ŠøŠ»Šø Š½Šµ сŠ¼Š¾Š³ Š·Š°ŠæустŠøться.</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_xx_YY.ts b/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_xx_YY.ts
new file mode 100644
index 00000000..d3e72f7b
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/nls/VBoxManageNls_xx_YY.ts
@@ -0,0 +1,10640 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1">
+<context>
+ <name>Appliance</name>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="256"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1551"/>
+ <source>Option &quot;%s&quot; can&apos;t be used together with &quot;--cloud&quot; option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="259"/>
+ <location filename="../VBoxManageAppliance.cpp" line="334"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1554"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1637"/>
+ <source>Value of option &quot;%s&quot; is out of range.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="268"/>
+ <location filename="../VBoxManageAppliance.cpp" line="275"/>
+ <location filename="../VBoxManageAppliance.cpp" line="289"/>
+ <location filename="../VBoxManageAppliance.cpp" line="303"/>
+ <location filename="../VBoxManageAppliance.cpp" line="317"/>
+ <location filename="../VBoxManageAppliance.cpp" line="324"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1562"/>
+ <source>Option &quot;%s&quot; requires preceding --vsys or --cloud option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="282"/>
+ <location filename="../VBoxManageAppliance.cpp" line="296"/>
+ <location filename="../VBoxManageAppliance.cpp" line="310"/>
+ <location filename="../VBoxManageAppliance.cpp" line="331"/>
+ <location filename="../VBoxManageAppliance.cpp" line="342"/>
+ <location filename="../VBoxManageAppliance.cpp" line="352"/>
+ <location filename="../VBoxManageAppliance.cpp" line="362"/>
+ <location filename="../VBoxManageAppliance.cpp" line="372"/>
+ <location filename="../VBoxManageAppliance.cpp" line="382"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1569"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1576"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1583"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1590"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1597"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1604"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1611"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1618"/>
+ <source>Option &quot;%s&quot; requires preceding --vsys option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="345"/>
+ <location filename="../VBoxManageAppliance.cpp" line="355"/>
+ <location filename="../VBoxManageAppliance.cpp" line="365"/>
+ <location filename="../VBoxManageAppliance.cpp" line="375"/>
+ <location filename="../VBoxManageAppliance.cpp" line="385"/>
+ <source>Option &quot;%s&quot; requires preceding --unit option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="392"/>
+ <source>Invalid import options &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="401"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1634"/>
+ <source>Option &quot;%s&quot; can&apos;t be used together with &quot;--vsys&quot; option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="410"/>
+ <location filename="../VBoxManageAppliance.cpp" line="417"/>
+ <location filename="../VBoxManageAppliance.cpp" line="424"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1646"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1653"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1660"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1667"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1674"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1681"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1688"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1695"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1702"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1709"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1716"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1723"/>
+ <location filename="../VBoxManageAppliance.cpp" line="1730"/>
+ <source>Option &quot;%s&quot; requires preceding --cloud option.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="433"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="440"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="442"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="445"/>
+ <source>unknown option: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="449"/>
+ <source>error: %Rrs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="455"/>
+ <source>Not enough arguments for &quot;import&quot; command.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="477"/>
+ <source>Not enough arguments for import from the Cloud.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="500"/>
+ <source>Appliance read failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="512"/>
+ <source>Interpreting %ls...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="544"/>
+ <source>Disks:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="565"/>
+ <source>Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="600"/>
+ <source>Virtual system %u:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="630"/>
+ <source>%2u: OS type specified with --ostype: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="634"/>
+ <source>%2u: Suggested OS type: &quot;%ls&quot;
+ (change with &quot;--vsys %u --ostype &lt;type&gt;&quot;; use &quot;list ostypes&quot; to list all possible values)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="643"/>
+ <source>%2u: VM name specified with --vmname: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="647"/>
+ <source>%2u: Suggested VM name &quot;%ls&quot;
+ (change with &quot;--vsys %u --vmname &lt;name&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="653"/>
+ <source>%2u: Product (ignored): %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="658"/>
+ <source>%2u: ProductUrl (ignored): %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="663"/>
+ <source>%2u: Vendor (ignored): %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="668"/>
+ <source>%2u: VendorUrl (ignored): %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="673"/>
+ <source>%2u: Version (ignored): %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="681"/>
+ <source>%2u: Description specified with --description: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="685"/>
+ <source>%2u: Description &quot;%ls&quot;
+ (change with &quot;--vsys %u --description &lt;desc&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="696"/>
+ <source>%2u: End-user license agreement
+ (accept with &quot;--vsys %u --eula accept&quot;):
+
+%ls
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="703"/>
+ <source>%2u: End-user license agreement (accepted)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="708"/>
+ <source>Argument to --eula must be either &quot;show&quot; or &quot;accept&quot;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="711"/>
+ <source>%2u: End-user license agreement
+ (display with &quot;--vsys %u --eula show&quot;;
+ accept with &quot;--vsys %u --eula accept&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="727"/>
+ <source>%2u: No. of CPUs specified with --cpus: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="731"/>
+ <source>Argument to --cpus option must be a number greater than %d and less than %d.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="735"/>
+ <source>%2u: Number of CPUs: %ls
+ (change with &quot;--vsys %u --cpus &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="747"/>
+ <source>%2u: Guest memory specified with --memory: %ls MB
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="751"/>
+ <source>Argument to --memory option must be a non-negative number.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="754"/>
+ <source>%2u: Guest memory: %ls MB
+ (change with &quot;--vsys %u --memory &lt;MB&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="762"/>
+ <source>%2u: IDE controller, type %ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="768"/>
+ <source>%2u: IDE controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="778"/>
+ <source>%2u: SATA controller, type %ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="784"/>
+ <source>%2u: SATA controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="794"/>
+ <source>%2u: SAS controller, type %ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="800"/>
+ <source>%2u: SAS controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="810"/>
+ <source>%2u: SCSI controller, type %ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="821"/>
+ <source>%2u: SCSI controller, type set with --unit %u --scsitype: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="827"/>
+ <source>%2u: SCSI controller, type %ls
+ (change with &quot;--vsys %u --unit %u --scsitype {BusLogic|LsiLogic}&quot;;
+ disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="839"/>
+ <source>%2u: VirtioSCSI controller, type %ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="845"/>
+ <source>%2u: VirtioSCSI controller, type %ls
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="855"/>
+ <source>%2u: Hard disk image: source image=%ls -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="870"/>
+ <source>Option --ImportToVDI can not be used together with a manually set target path.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="898"/>
+ <source>Invalid controller value: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="903"/>
+ <location filename="../VBoxManageAppliance.cpp" line="970"/>
+ <source>Invalid storage controller specified: %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="916"/>
+ <source>Invalid port value: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="931"/>
+ <source>Failed to extract controller value from ExtraConfig: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="937"/>
+ <source>Failed to extract channel value from ExtraConfig: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="963"/>
+ <source>Device already attached to controller %u at this port (%u) location.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1001"/>
+ <source>Illegal port value: %u. For %ls controllers the only valid values are 0 to %lu (inclusive)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1023"/>
+ <source>%2u: Hard disk image specified with --disk: source image=%ls, target path=%ls, %s
+ (change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1035"/>
+ <source>%2u: Hard disk image specified with --disk and --controller: source image=%ls, target path=%ls, %s
+ (change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1045"/>
+ <source>%2u: Hard disk image specified with --disk and --port: source image=%ls, target path=%ls, %s
+ (change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1055"/>
+ <source>%2u: Hard disk image specified with --controller and --port: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1065"/>
+ <source>%2u: Hard disk image specified with --port: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1077"/>
+ <source>%2u: Hard disk image specified with --controller: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1089"/>
+ <source>%2u: Hard disk image specified with --disk and --controller and --port: source image=%ls, target path=%ls, %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1174"/>
+ <source>%2u: Hard disk image: source image=%ls, target path=%ls, %s
+ (change target path with &quot;--vsys %u --unit %u --disk path&quot;;
+ change controller with &quot;--vsys %u --unit %u --controller &lt;index&gt;&quot;;
+ change controller port with &quot;--vsys %u --unit %u --port &lt;n&gt;&quot;;
+ disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1191"/>
+ <source>%2u: CD-ROM -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1196"/>
+ <source>%2u: CD-ROM
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1204"/>
+ <source>%2u: Floppy -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1209"/>
+ <source>%2u: Floppy
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1215"/>
+ <source>%2u: Network adapter: orig %ls, config %ls, extra %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1225"/>
+ <source>%2u: USB controller -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1230"/>
+ <source>%2u: USB controller
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1238"/>
+ <source>%2u: Sound card &quot;%ls&quot; -- disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1244"/>
+ <source>%2u: Sound card (appliance expects &quot;%ls&quot;, can change on import)
+ (disable with &quot;--vsys %u --unit %u --ignore&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1256"/>
+ <source>%2u: VM settings file name specified with --settingsfile: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1260"/>
+ <source>%2u: Suggested VM settings file name &quot;%ls&quot;
+ (change with &quot;--vsys %u --settingsfile &lt;filename&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1269"/>
+ <source>%2u: VM base folder specified with --basefolder: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1273"/>
+ <source>%2u: Suggested VM base folder &quot;%ls&quot;
+ (change with &quot;--vsys %u --basefolder &lt;path&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1282"/>
+ <source>%2u: VM group specified with --group: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1286"/>
+ <source>%2u: Suggested VM group &quot;%ls&quot;
+ (change with &quot;--vsys %u --group &lt;group&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1292"/>
+ <source>%2u: Suggested cloud shape &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1300"/>
+ <source>%2u: Cloud bucket id specified with --cloudbucket: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1304"/>
+ <source>%2u: Suggested cloud bucket id &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudbucket &lt;id&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1313"/>
+ <source>%2u: Cloud profile name specified with --cloudprofile: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1317"/>
+ <source>%2u: Suggested cloud profile name &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudprofile &lt;id&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1326"/>
+ <source>%2u: Cloud instance id specified with --cloudinstanceid: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1330"/>
+ <source>%2u: Suggested cloud instance id &quot;%ls&quot;
+ (change with &quot;--cloud %u --cloudinstanceid &lt;id&gt;&quot;)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1336"/>
+ <source>%2u: Suggested cloud base image id &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1384"/>
+ <source>Cannot import until the license agreement listed above is accepted.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1386"/>
+ <source>Cannot import until the %c license agreements listed above are accepted.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1397"/>
+ <source>Appliance import failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1400"/>
+ <source>Successfully imported the appliance.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1517"/>
+ <source>You can only specify --output once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1625"/>
+ <source>Invalid export options &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1751"/>
+ <source>unhandled option: -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1753"/>
+ <source>unhandled option: %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1756"/>
+ <source>unknown option: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1771"/>
+ <source>At least one machine must be specified with the export command.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1775"/>
+ <source>Missing --output argument with export command.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="1789"/>
+ <source>Invalid index %RI32 with -vsys option; you specified only %zu virtual system(s).</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1878"/>
+ <source>Cannot read license file &quot;%s&quot; which should be included in the virtual system %u.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1941"/>
+ <source>Enter the passwords for the following identifiers to export the apppliance:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1948"/>
+ <source>Password ID %s:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="1978"/>
+ <source>Appliance write failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="1981"/>
+ <source>Successfully exported %d machine(s).
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2037"/>
+ <source>Creating a cloud instance...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2042"/>
+ <source>Creating the cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2054"/>
+ <source>A cloud instance with id &apos;%s&apos; (provider &apos;%s&apos;) was created
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2107"/>
+ <source>Failed to open OVA &apos;%s&apos; for updating: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2113"/>
+ <source>Failed to open OVA &apos;%s&apos; as a TAR file: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2120"/>
+ <source>Scanning OVA &apos;%s&apos; for a manifest and signature...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2136"/>
+ <source>RTVfsFsStrmNext returned %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2152"/>
+ <source>OVA contains multiple manifests! first: %s second: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2156"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2194"/>
+ <source>Unsupported OVA file ordering! Signature file (&apos;%s&apos;) as succeeded by &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2161"/>
+ <source>Found manifest file: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2170"/>
+ <source>Failed to memorize the manifest: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2173"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2414"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2488"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2647"/>
+ <source>Out of memory!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2181"/>
+ <source>Multiple signature files! (%s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2185"/>
+ <source>Found existing signature file: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2210"/>
+ <source>The OVA contains no manifest and cannot be signed!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2213"/>
+ <source>The OVA is already signed (&apos;%s&apos;)! (Use the --force option to force re-signing it.)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2233"/>
+ <source>Writing &apos;%s&apos; to the OVA...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2243"/>
+ <source>RTZipTarFsStreamTruncate failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2252"/>
+ <source>RTVfsFileSeek(hVfsFileSignature) failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2258"/>
+ <source>RTVfsFsStrmAdd(&apos;%s&apos;) failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2265"/>
+ <source>RTVfsFsStrmEnd failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2301"/>
+ <source> Successfully decoded the PKCS#7/CMS signature...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2317"/>
+ <source> Successfully verified the PKCS#7/CMS signature</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2320"/>
+ <source>Failed to verify the PKCS#7/CMS signature: %Rrc%RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2324"/>
+ <source>RTCrPkcs7SignedData_CheckSanity failed on PKCS#7/CMS signature: %Rrc%RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2329"/>
+ <source>PKCS#7/CMS signature inner ContentType isn&apos;t &apos;data&apos; but: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2333"/>
+ <source>PKCS#7/CMD signature is not &apos;signedData&apos;: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2374"/>
+ <source>RTCrPkcs7ContentInfo_Clone failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2378"/>
+ <source>RTCrPkcs7ContentInfo_DecodeAsn1 failed to decode PKCS#7/CMS signature: %Rrc%RTemi</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2409"/>
+ <source>Manifest is too big: %#RX64 bytes, max 4MiB</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2434"/>
+ <source>RTCrStoreCertAddFromFile failed on &apos;%s&apos;: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2440"/>
+ <source>RTCrStoreCreateInMem failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2471"/>
+ <source>Created PKCS#7/CMS signature: %zu bytes, %s.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2474"/>
+ <source>Using SHA-1 instead of SHA-3 for the PKCS#7/CMS signature.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2483"/>
+ <source>RTCrPemWriteBlobToVfsFile failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2491"/>
+ <source>RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2495"/>
+ <source>RTVfsFileReadAt failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2548"/>
+ <source>Unsupported digest type: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2557"/>
+ <source>Failed to create digest for %s: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageAppliance.cpp" line="2583"/>
+ <source>Created OVA signature: %zu bytes, %s</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2596"/>
+ <source> Successfully decoded and verified the OVA signature.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2627"/>
+ <source>Failed to write certificate to signature file: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2631"/>
+ <source>Failed to produce signature file: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2635"/>
+ <source>RTVfsMemFileCreate failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2638"/>
+ <source>Encountered a problem when validating the signature we just created: %Rrc%#RTeim
+Please make sure the certificate and private key matches.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2643"/>
+ <source>2nd RTCrPkixPubKeySignDigest call failed: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2650"/>
+ <source>RTCrPkixPubKeySignDigest failed: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2653"/>
+ <source>Failed to create digest %s: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2717"/>
+ <location filename="../VBoxManageAppliance.cpp" line="2724"/>
+ <source>Password is given more than once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2742"/>
+ <source>Unknown digest type: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2755"/>
+ <source>Too many intermediate certificates: max %zu</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2791"/>
+ <source>No OVA file was specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2793"/>
+ <source>No signing certificate (--certificate=&lt;file&gt;) was specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2795"/>
+ <source>No signing private key (--private-key=&lt;file&gt;) was specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2799"/>
+ <source>The specified OVA file was not found: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2801"/>
+ <source>The specified certificate file was not found: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2803"/>
+ <source>The specified private key file was not found: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2824"/>
+ <source>Error reading certificate from &apos;%s&apos;: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2833"/>
+ <source>Successfully read the certificate and private key.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2859"/>
+ <source>Successfully signed &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageAppliance.cpp" line="2865"/>
+ <source>Error reading the private key from %s: %Rrc%#RTeim</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BWControl</name>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="65"/>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="88"/>
+ <source>Limit is too big
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="75"/>
+ <source>Invalid unit suffix. Valid suffixes are: k, m, g, K, M, G
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="79"/>
+ <source>Trailing spaces in limit!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="81"/>
+ <source>No digits in limit specifier
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="83"/>
+ <source>Invalid limit specifier
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="86"/>
+ <source>Limit cannot be negative
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="114"/>
+ <source>Bandwidth group name must not be empty!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="174"/>
+ <source>Invalid bandwidth group type
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="318"/>
+ <source>Too few parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="320"/>
+ <source>Too many parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="341"/>
+ <source>Bandwidth groups cannot be created while the VM is running
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="350"/>
+ <source>Bandwidth groups cannot be deleted while the VM is running
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageBandwidthControl.cpp" line="361"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Cloud</name>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="74"/>
+ <source>Parameter --provider is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="79"/>
+ <source>Parameter --profile is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="164"/>
+ <source>Unknown cloud instance state &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="210"/>
+ <location filename="../VBoxManageCloud.cpp" line="371"/>
+ <source>Parameter &apos;compartment&apos; is empty or absent.
+Trying to get the compartment from the passed cloud profile &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="219"/>
+ <location filename="../VBoxManageCloud.cpp" line="380"/>
+ <source>Found the compartment &apos;%s&apos;:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="221"/>
+ <location filename="../VBoxManageCloud.cpp" line="382"/>
+ <source>Parameter --compartment-id is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="238"/>
+ <source>Reply is in the form &apos;instance name&apos; = &apos;instance id&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="247"/>
+ <source>Failed to list instances</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="256"/>
+ <source>The list of the instances for the cloud profile &apos;%ls&apos;
+and compartment &apos;%s&apos;:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="324"/>
+ <source>Unknown cloud image state &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="399"/>
+ <source>Reply is in the form &apos;image name&apos; = &apos;image id&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="407"/>
+ <source>Failed to list images</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="416"/>
+ <source>The list of the images for the cloud profile &apos;%ls&apos;
+and compartment &apos;%s&apos;:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="473"/>
+ <location filename="../VBoxManageCloud.cpp" line="553"/>
+ <location filename="../VBoxManageCloud.cpp" line="747"/>
+ <location filename="../VBoxManageCloud.cpp" line="898"/>
+ <location filename="../VBoxManageCloud.cpp" line="980"/>
+ <location filename="../VBoxManageCloud.cpp" line="1062"/>
+ <location filename="../VBoxManageCloud.cpp" line="1159"/>
+ <location filename="../VBoxManageCloud.cpp" line="1236"/>
+ <location filename="../VBoxManageCloud.cpp" line="1342"/>
+ <location filename="../VBoxManageCloud.cpp" line="1537"/>
+ <location filename="../VBoxManageCloud.cpp" line="1622"/>
+ <location filename="../VBoxManageCloud.cpp" line="1713"/>
+ <location filename="../VBoxManageCloud.cpp" line="1808"/>
+ <source>Empty command parameter list, show help.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="663"/>
+ <source>Warning!!! Public SSH key doesn&apos;t present in the passed arguments...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="666"/>
+ <source>Parameters --image-id and --boot-volume-id are mutually exclusive. Only one of them must be presented.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="670"/>
+ <source>Missing parameter --image-id or --boot-volume-id. One of them must be presented.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="692"/>
+ <source>Checking the cloud image with id &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="700"/>
+ <source>Checking the cloud image failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="706"/>
+ <source>Creating cloud instance with name &apos;%s&apos; from the image &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="709"/>
+ <source>Creating cloud instance with name &apos;%s&apos; from the boot volume &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="715"/>
+ <source>Creating cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="718"/>
+ <source>Cloud instance was created successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="762"/>
+ <location filename="../VBoxManageCloud.cpp" line="913"/>
+ <location filename="../VBoxManageCloud.cpp" line="995"/>
+ <location filename="../VBoxManageCloud.cpp" line="1077"/>
+ <location filename="../VBoxManageCloud.cpp" line="1386"/>
+ <location filename="../VBoxManageCloud.cpp" line="1728"/>
+ <source>Duplicate parameter: --id</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="766"/>
+ <location filename="../VBoxManageCloud.cpp" line="917"/>
+ <location filename="../VBoxManageCloud.cpp" line="999"/>
+ <location filename="../VBoxManageCloud.cpp" line="1081"/>
+ <location filename="../VBoxManageCloud.cpp" line="1390"/>
+ <location filename="../VBoxManageCloud.cpp" line="1732"/>
+ <source>Empty parameter: --id</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="787"/>
+ <location filename="../VBoxManageCloud.cpp" line="938"/>
+ <location filename="../VBoxManageCloud.cpp" line="1020"/>
+ <location filename="../VBoxManageCloud.cpp" line="1102"/>
+ <location filename="../VBoxManageCloud.cpp" line="1439"/>
+ <location filename="../VBoxManageCloud.cpp" line="1754"/>
+ <source>Missing parameter: --id</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="795"/>
+ <source>Getting information about cloud instance with id %s...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="796"/>
+ <source>Reply is in the form &apos;setting name&apos; = &apos;value&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="817"/>
+ <source>Getting information about cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="819"/>
+ <source>Cloud instance info (provider &apos;%s&apos;):
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="830"/>
+ <source>Availability domain = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="830"/>
+ <source>Availability domain wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="831"/>
+ <source>Instance displayed name = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="831"/>
+ <source>Instance displayed name wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="832"/>
+ <source>Instance state = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="832"/>
+ <source>Instance state wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="833"/>
+ <source>Instance Id = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="833"/>
+ <source>Instance Id wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="834"/>
+ <source>Instance name = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="834"/>
+ <source>Instance name wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="835"/>
+ <source>Bootable image Id = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="836"/>
+ <source>Image Id whom the instance is booted up wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="837"/>
+ <source>Shape of the instance = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="838"/>
+ <source>The shape of the instance wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="839"/>
+ <source>Type of guest OS = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="839"/>
+ <source>Type of guest OS wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="840"/>
+ <source>RAM = %ls MB
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="840"/>
+ <source>Value for RAM wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="841"/>
+ <source>CPUs = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="841"/>
+ <source>Numbers of CPUs weren&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="842"/>
+ <source>Instance public IP = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="842"/>
+ <source>Public IP wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="843"/>
+ <source>Free-form tags or metadata weren&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="844"/>
+ <source>Cloud-init script wasn&apos;t found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="946"/>
+ <source>Starting cloud instance with id %s...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="953"/>
+ <source>Starting the cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="956"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was started
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1028"/>
+ <source>Pausing cloud instance with id %s...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1035"/>
+ <source>Pause the cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1038"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was paused
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1111"/>
+ <source>Terminating cloud instance with id %s...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1118"/>
+ <source>Termination the cloud instance failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1121"/>
+ <source>Cloud instance with id %s (provider = &apos;%s&apos;, profile = &apos;%s&apos;) was terminated
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1293"/>
+ <source>Conflicting parameters: --instance-id and --object-name can&apos;t be used together. Choose one.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1302"/>
+ <source>Creating cloud image with name &apos;%s&apos; from the instance &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1305"/>
+ <source>Creating cloud image with name &apos;%s&apos; from the object &apos;%s&apos; in the bucket &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1313"/>
+ <source>Creating cloud image failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1316"/>
+ <source>Cloud image was created successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1362"/>
+ <source>Duplicate parameter: --bucket-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1366"/>
+ <source>Empty parameter: --bucket-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1374"/>
+ <source>Duplicate parameter: --object-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1378"/>
+ <source>Empty parameter: --object-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1398"/>
+ <source>Duplicate parameter: --display-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1402"/>
+ <source>Empty parameter: --display-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1410"/>
+ <source>Duplicate parameter: --launch-mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1414"/>
+ <source>Empty parameter: --launch-mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1444"/>
+ <source>Missing parameter: --bucket-name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1464"/>
+ <source>Exporting image &apos;%s&apos; to the Cloud with name &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1467"/>
+ <source>Exporting image &apos;%s&apos; to the Cloud with default name
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1495"/>
+ <source>Image %s was found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1502"/>
+ <source>Process of exporting the image to the Cloud was interrupted. The image wasn&apos;t found.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1511"/>
+ <source>Export the image to the Cloud failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1514"/>
+ <source>Export the image to the Cloud was successfull
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1587"/>
+ <source>Creating an object &apos;%s&apos; from the cloud image &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1594"/>
+ <source>Cloud image import failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1598"/>
+ <source>Cloud image was imported successfully. Find the downloaded object with the name %s in the system temp folder (find the possible environment variables like TEMP, TMP and etc.)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1658"/>
+ <source>Getting information about the cloud image with id &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1664"/>
+ <source>Reply is in the form &apos;image property&apos; = &apos;value&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1672"/>
+ <source>Getting information about the cloud image failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1678"/>
+ <source>General information about the image:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1763"/>
+ <source>Deleting cloud image with id %s...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1770"/>
+ <source>Deleting cloud image failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1773"/>
+ <source>Cloud image was deleted successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1956"/>
+ <location filename="../VBoxManageCloud.cpp" line="2007"/>
+ <location filename="../VBoxManageCloud.cpp" line="2081"/>
+ <location filename="../VBoxManageCloud.cpp" line="2128"/>
+ <source>Missing --name parameter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1958"/>
+ <source>Missing --network-id parameter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="1970"/>
+ <source>Cloud network was created successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2015"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>State: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>Enabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2018"/>
+ <source>Disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2021"/>
+ <source>CloudProvider: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2024"/>
+ <source>CloudProfile: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2027"/>
+ <source>CloudNetworkId: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2029"/>
+ <source>VBoxNetworkName: %ls
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2091"/>
+ <source>Cloud network %ls was updated successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2141"/>
+ <source>Cloud network %ls was deleted successfully
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2209"/>
+ <source>Setting up tunnel network in the cloud...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2235"/>
+ <source>Setting up cloud network environment failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloud.cpp" line="2239"/>
+ <source>Cloud network environment was set up successfully. Tunnel network id is: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CloudMachine</name>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="172"/>
+ <source>cloud: no providers available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="178"/>
+ <source>cloud: multiple providers available, &apos;--provider&apos; option is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="231"/>
+ <source>cloud: no profiles exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="237"/>
+ <source>cloud: multiple profiles exist, &apos;--profile&apos; option is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="363"/>
+ <source>ambiguous name: %ls and %ls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="419"/>
+ <source>only one machine can be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="467"/>
+ <source>not a valid uuid: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="530"/>
+ <source>machine not specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="536"/>
+ <source>machine name is empty</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="547"/>
+ <source>unable to find machine with id %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="557"/>
+ <source>unable to find machine with name %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="567"/>
+ <source>unable to find machine %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="639"/>
+ <source>cloud machine: RTGetOptInit: %Rra</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="654"/>
+ <location filename="../VBoxManageCloudMachine.cpp" line="789"/>
+ <source>Invalid sub-command: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="700"/>
+ <source>cloud machine: internal error: %d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="705"/>
+ <source>cloud machine: command required
+Try &apos;--help&apos; for more information.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="757"/>
+ <source>cloud machine list: unexpected machine argument</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="765"/>
+ <source>cloud machine list: RTGetOptInit: %Rra</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="987"/>
+ <source>machine is not accessible</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1017"/>
+ <source>State: Invalid (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1021"/>
+ <source>State: Provisioning (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1025"/>
+ <source>State: Running (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1029"/>
+ <source>State: Starting (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1033"/>
+ <source>State: Stopping (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1037"/>
+ <source>State: Stopped (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1041"/>
+ <source>State: CreatingImage (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1045"/>
+ <source>State: Terminating (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1049"/>
+ <source>State: Terminated (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1053"/>
+ <source>State: Unknown state (%RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1062"/>
+ <source>null details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1109"/>
+ <source>%ls: unable to convert to boolean value
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1135"/>
+ <source>%ls: unable to convert to string value
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1177"/>
+ <source>%ls: unable to convert to integer value
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1203"/>
+ <source>%ls: unable to convert to choice value
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1213"/>
+ <source>%ls: values: %Rhra</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1223"/>
+ <source>%ls: selectedIndex: %Rhra</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1231"/>
+ <source>%ls: selected index %RI64 out of range [0, %zu)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageCloudMachine.cpp" line="1243"/>
+ <source>unknown value type %RU32
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ControlVM</name>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="65"/>
+ <source>Invalid %s number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="222"/>
+ <source>Failed to send a scancode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageControlVM.cpp" line="323"/>
+ <source>Out of memory allocating %d bytes.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="326"/>
+ <source>File size %RI64 is greater than %RI64: &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="329"/>
+ <source>Cannot get size of file &apos;%s&apos;: %Rrc.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="334"/>
+ <source>Cannot open file &apos;%s&apos;: %Rrc.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="351"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1372"/>
+ <source>Not enough parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="371"/>
+ <source>Machine &apos;%s&apos; is not currently running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="397"/>
+ <location filename="../VBoxManageControlVM.cpp" line="411"/>
+ <location filename="../VBoxManageControlVM.cpp" line="425"/>
+ <location filename="../VBoxManageControlVM.cpp" line="487"/>
+ <location filename="../VBoxManageControlVM.cpp" line="558"/>
+ <location filename="../VBoxManageControlVM.cpp" line="782"/>
+ <location filename="../VBoxManageControlVM.cpp" line="802"/>
+ <location filename="../VBoxManageControlVM.cpp" line="840"/>
+ <location filename="../VBoxManageControlVM.cpp" line="884"/>
+ <location filename="../VBoxManageControlVM.cpp" line="925"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1019"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1081"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1131"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1160"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1172"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1184"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1197"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1208"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1237"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1266"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1297"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1318"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1992"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2115"/>
+ <source>Missing argument to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="444"/>
+ <location filename="../VBoxManageControlVM.cpp" line="468"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2226"/>
+ <source>Invalid value &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="453"/>
+ <location filename="../VBoxManageControlVM.cpp" line="477"/>
+ <source>Audio adapter not enabled in VM configuration.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="498"/>
+ <location filename="../VBoxManageControlVM.cpp" line="528"/>
+ <source>Missing argument to &apos;%s %s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="513"/>
+ <location filename="../VBoxManageControlVM.cpp" line="536"/>
+ <source>Invalid &apos;%s %s&apos; argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="547"/>
+ <location filename="../VBoxManageControlVM.cpp" line="574"/>
+ <source>Invalid &apos;%s&apos; argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="591"/>
+ <source>Failed to power off machine.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="611"/>
+ <source>Machine in invalid state %d -- %s.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="634"/>
+ <source>Failed to save machine state.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="665"/>
+ <location filename="../VBoxManageControlVM.cpp" line="700"/>
+ <location filename="../VBoxManageControlVM.cpp" line="754"/>
+ <location filename="../VBoxManageControlVM.cpp" line="775"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1478"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1500"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1624"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1658"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1755"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2001"/>
+ <source>Guest not running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="686"/>
+ <source>Current installed Guest Additions don&apos;t support rebooting the guest.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="688"/>
+ <source>Current installed Guest Additions don&apos;t support shutting down the guest.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="707"/>
+ <source>Missing argument to &apos;%s&apos;. Expected IBM PC AT set 2 keyboard scancode(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="727"/>
+ <source>Converting &apos;%s&apos; returned %Rrc!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="736"/>
+ <source>&apos;%s&apos; is not a hex byte!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="761"/>
+ <source>Missing argument to &apos;%s&apos;. Expected ASCII string(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="814"/>
+ <source>Invalid link state &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="860"/>
+ <source>Filename not specified for NIC %lu.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="868"/>
+ <source>The NIC %d is currently disabled and thus its tracefile can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="901"/>
+ <source>Invalid nictrace%lu argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="909"/>
+ <source>The NIC %d is currently disabled and thus its trace flag can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="961"/>
+ <source>Missing or invalid argument to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="996"/>
+ <source>Wrong rule proto &apos;%s&apos; specified -- only &apos;udp&apos; and &apos;tcp&apos; are allowed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1050"/>
+ <source>Invalid nicproperty%d argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1057"/>
+ <source>Failed to allocate memory for nicproperty%d &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1065"/>
+ <source>The NIC %d is currently disabled and thus its properties can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1105"/>
+ <source>Unknown promiscuous mode policy &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1115"/>
+ <source>The NIC %d is currently disabled and thus its promiscuous mode can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1217"/>
+ <source>Invalid type &apos;%s&apos; specfied for NIC %lu.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1225"/>
+ <source>The NIC %d is currently disabled and thus its attachment type can&apos;t be changed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1233"/>
+ <source>&apos;vrdp&apos; is deprecated. Use &apos;vrde&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1249"/>
+ <source>Invalid remote desktop server state &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1262"/>
+ <source>&apos;vrdpport&apos; is deprecated. Use &apos;vrdeport&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1293"/>
+ <source>&apos;vrdpvideochannelquality&apos; is deprecated. Use &apos;vrdevideochannelquality&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1344"/>
+ <source>Invalid vrdeproperty argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1351"/>
+ <source>Failed to allocate memory for VRDE property &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1378"/>
+ <source>Wrong number of arguments.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1392"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1587"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2259"/>
+ <source>Invalid parameter &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1425"/>
+ <source>Zero UUID argument &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1444"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1491"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1542"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1599"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1638"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1735"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1787"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1821"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1840"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1854"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1888"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1910"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1932"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1954"/>
+ <location filename="../VBoxManageControlVM.cpp" line="1978"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2048"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2093"/>
+ <source>Incorrect number of parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1462"/>
+ <source>Either &quot;yes&quot; or &quot;no&quot; is expected.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1527"/>
+ <source>Display status must be &lt;on&gt; or &lt;off&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1647"/>
+ <source>Error parsing guest memory balloon size &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1728"/>
+ <source>Teleportation failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1746"/>
+ <source>Error parsing display number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1769"/>
+ <source>Failed to create file &apos;%s&apos; (%Rrc).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1776"/>
+ <source>Failed to write screenshot to file &apos;%s&apos; (%Rrc).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1827"/>
+ <source>Error parsing list of screen IDs &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1863"/>
+ <source>Error parsing video width &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1872"/>
+ <source>Error parsing video height &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1897"/>
+ <source>Error parsing video rate &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1919"/>
+ <source>Error parsing video FPS &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1941"/>
+ <source>Error parsing maximum time &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="1963"/>
+ <source>Error parsing maximum file size &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2037"/>
+ <source>Invalid argument to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2059"/>
+ <source>Invalid parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2072"/>
+ <source>Enter password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2081"/>
+ <source>Failed to read new password from file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2129"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2144"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2185"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2198"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2219"/>
+ <location filename="../VBoxManageControlVM.cpp" line="2239"/>
+ <source>Incorrect arguments to &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2205"/>
+ <source>Invalid vm-process-priority &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageControlVM.cpp" line="2248"/>
+ <source>Invalid autostart delay number &apos;%s&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DHCPServer</name>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="65"/>
+ <source>Either --network or --interface, not both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="70"/>
+ <source>Either --interface or --network, not both</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="180"/>
+ <source>Failed to locate host-only interface &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="194"/>
+ <source>Failed to find DHCP server for network &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="196"/>
+ <source>Failed to find DHCP server for host-only interface &apos;%s&apos; (network &apos;%ls&apos;)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="200"/>
+ <location filename="../VBoxManageDHCPServer.cpp" line="890"/>
+ <source>You need to specify either --network or --interface to identify the DHCP server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="474"/>
+ <source>Incomplete option sequence preseeding &apos;--global&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="480"/>
+ <source>Incomplete option sequence preseeding &apos;--group&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="482"/>
+ <source>Group name cannot be empty</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="488"/>
+ <source>Incomplete option sequence preseeding &apos;--mac-address&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="495"/>
+ <source>Incomplete option sequence preseeding &apos;--vm&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="501"/>
+ <source>--nic option requires a --vm preceeding selecting the VM it should apply to</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="503"/>
+ <source>Incomplete option sequence preseeding &apos;--nic=%u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="505"/>
+ <source>invalid NIC number: %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="540"/>
+ <source>Malformed hex string given to --set-opt-hex %u: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="555"/>
+ <source>--del-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="567"/>
+ <source>--unforce-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="571"/>
+ <source>--unsuppress-opt does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="629"/>
+ <source>--zap-options does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="671"/>
+ <source>--remove-config does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="673"/>
+ <source>--remove-config cannot be applied to the global config</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="686"/>
+ <source>--fixed-address can only be applied to a VM NIC or an MAC address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="720"/>
+ <source>A group must be selected to perform condition alterations.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="722"/>
+ <source>Condition value cannot be empty</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="815"/>
+ <source>Could not find any condition of type %d with value &apos;%s&apos; to delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="823"/>
+ <source>--zap-conditions can only be with a group selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="842"/>
+ <source>Incomplete option sequence preseeding &apos;--id=%u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="849"/>
+ <source>--value without --id=dhcp-opt-no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="863"/>
+ <source>--remove does not apply to the &apos;add&apos; subcommand</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="865"/>
+ <source>--remove without --id=dhcp-opt-no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="895"/>
+ <source>Missing required option: --ip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="897"/>
+ <source>Missing required option: --netmask</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="899"/>
+ <source>Missing required option: --lowerip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="901"/>
+ <source>Missing required option: --upperip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="919"/>
+ <source>Could not find interface &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="923"/>
+ <source>Could not get network name for the interface &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="934"/>
+ <source>DHCP server already exists</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="938"/>
+ <source>Failed to create the DHCP server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="941"/>
+ <source>DHCP server does not exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="973"/>
+ <source>Failed to set configuration (%ls, %ls, %ls, %ls)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1025"/>
+ <source>Failed to remove server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1092"/>
+ <source>Failed to start the server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1136"/>
+ <source>Failed to restart the server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1180"/>
+ <source>Failed to stop the server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1227"/>
+ <source>You need to specify a MAC address too look for</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDHCPServer.cpp" line="1255"/>
+ <source>IP Address: %ls
+MAC Address: %RTmac
+State: %ls
+Issued: %s (%RU64)
+Expire: %s (%RU64)
+TTL: %RU64 sec, currently %RU64 sec left
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DebugVM</name>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="115"/>
+ <source>The getregisters sub-command takes at least one register name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="156"/>
+ <source>Must specify info item to display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="303"/>
+ <source>The --compression option has already been given</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="308"/>
+ <source>The --filename option has already been given</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="317"/>
+ <source>The --filename option is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="325"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="351"/>
+ <source>Detected: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="371"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="372"/>
+ <source>Version: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="450"/>
+ <source>setregisters expects input on the form &apos;register=value&apos; got &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="462"/>
+ <source>Out of memory
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="474"/>
+ <source>The setregisters sub-command takes at least one register name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="483"/>
+ <source>Successfully set %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDebugVM.cpp" line="489"/>
+ <source>Successfully set %u registers
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="516"/>
+ <source>export %s=&apos;%ls&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="518"/>
+ <source>set %s=%ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="533"/>
+ <source>Debug logger settings:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="557"/>
+ <source>Release logger settings:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="631"/>
+ <source>The show sub-command has no idea what &apos;%s&apos; might be</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="705"/>
+ <source>====================== CPU #%u ======================
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="752"/>
+ <source>Multiple --pattern options are not permitted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="766"/>
+ <source>The --reset and --descriptions options does not mix</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="836"/>
+ <source>The --filename is missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDebugVM.cpp" line="960"/>
+ <source>Machine &apos;%s&apos; is not currently running.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Disk</name>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="64"/>
+ <source>Error code %Rrc at %s(%u) in function %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="184"/>
+ <location filename="../VBoxManageDisk.cpp" line="219"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="288"/>
+ <source>Out of memory copying &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="328"/>
+ <location filename="../VBoxManageDisk.cpp" line="334"/>
+ <location filename="../VBoxManageDisk.cpp" line="340"/>
+ <location filename="../VBoxManageDisk.cpp" line="699"/>
+ <location filename="../VBoxManageDisk.cpp" line="705"/>
+ <location filename="../VBoxManageDisk.cpp" line="711"/>
+ <location filename="../VBoxManageDisk.cpp" line="1025"/>
+ <location filename="../VBoxManageDisk.cpp" line="1031"/>
+ <location filename="../VBoxManageDisk.cpp" line="1037"/>
+ <location filename="../VBoxManageDisk.cpp" line="1660"/>
+ <location filename="../VBoxManageDisk.cpp" line="1666"/>
+ <location filename="../VBoxManageDisk.cpp" line="1672"/>
+ <location filename="../VBoxManageDisk.cpp" line="1772"/>
+ <location filename="../VBoxManageDisk.cpp" line="1778"/>
+ <location filename="../VBoxManageDisk.cpp" line="1784"/>
+ <source>Only one command can be specified: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="371"/>
+ <source>Invalid key value pair: No &apos;=&apos;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="387"/>
+ <source>Cannot open replacement value file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="403"/>
+ <source>Error reading replacement MBR file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="406"/>
+ <source>Out of memory reading &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="410"/>
+ <source>Replacement value file &apos;%s&apos; is to big: %Rhcb, max 16MiB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="414"/>
+ <source>Cannot get the size of the value file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="433"/>
+ <location filename="../VBoxManageDisk.cpp" line="1060"/>
+ <location filename="../VBoxManageDisk.cpp" line="1245"/>
+ <location filename="../VBoxManageDisk.cpp" line="2585"/>
+ <source>Invalid medium variant &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="437"/>
+ <location filename="../VBoxManageDisk.cpp" line="799"/>
+ <location filename="../VBoxManageDisk.cpp" line="1069"/>
+ <location filename="../VBoxManageDisk.cpp" line="1261"/>
+ <location filename="../VBoxManageDisk.cpp" line="1680"/>
+ <location filename="../VBoxManageDisk.cpp" line="1796"/>
+ <location filename="../VBoxManageDisk.cpp" line="2008"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="443"/>
+ <location filename="../VBoxManageDisk.cpp" line="806"/>
+ <location filename="../VBoxManageDisk.cpp" line="1687"/>
+ <location filename="../VBoxManageDisk.cpp" line="1803"/>
+ <location filename="../VBoxManageDisk.cpp" line="2015"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="445"/>
+ <location filename="../VBoxManageDisk.cpp" line="808"/>
+ <location filename="../VBoxManageDisk.cpp" line="1689"/>
+ <location filename="../VBoxManageDisk.cpp" line="1805"/>
+ <location filename="../VBoxManageDisk.cpp" line="2017"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="448"/>
+ <location filename="../VBoxManageDisk.cpp" line="811"/>
+ <location filename="../VBoxManageDisk.cpp" line="1692"/>
+ <location filename="../VBoxManageDisk.cpp" line="1808"/>
+ <location filename="../VBoxManageDisk.cpp" line="2020"/>
+ <source>unknown option: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="452"/>
+ <location filename="../VBoxManageDisk.cpp" line="815"/>
+ <location filename="../VBoxManageDisk.cpp" line="1085"/>
+ <location filename="../VBoxManageDisk.cpp" line="1696"/>
+ <location filename="../VBoxManageDisk.cpp" line="1812"/>
+ <location filename="../VBoxManageDisk.cpp" line="2024"/>
+ <source>error: %Rrs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="463"/>
+ <location filename="../VBoxManageDisk.cpp" line="483"/>
+ <source>Parameters --filename is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="465"/>
+ <source>Parameters --size is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="486"/>
+ <source>Creating a differencing medium is only supported for hard disks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="505"/>
+ <source>Invalid parent hard disk reference, avoiding crash</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="588"/>
+ <source>The %s is not found in the property list of the requested medium format.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="598"/>
+ <source>Base64 encoding of the property %s failed. (%Rhrc)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="622"/>
+ <source>Failed to create medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="630"/>
+ <source>Medium created. UUID: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="718"/>
+ <source>Invalid medium type &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="725"/>
+ <source>Invalid autoreset parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="748"/>
+ <source>Invalid --property argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="755"/>
+ <source>Error: Failed to allocate memory for medium property &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="823"/>
+ <location filename="../VBoxManageDisk.cpp" line="1705"/>
+ <location filename="../VBoxManageDisk.cpp" line="1820"/>
+ <source>Medium name or UUID required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="834"/>
+ <source>No operation specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="855"/>
+ <source>Invalid medium reference, avoiding crash</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="876"/>
+ <source>Error: Attempt to resize the medium from %RU64.%RU64 MB to %RU64.%RU64 MB. Use --resizebyte if this is intended!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="910"/>
+ <source>Compact medium operation is not implemented!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="912"/>
+ <source>Compact medium operation for this format is not implemented yet!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="914"/>
+ <source>Failed to compact medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="916"/>
+ <source>Failed to compact medium!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="929"/>
+ <source>Failed to resize medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="931"/>
+ <source>Resize medium operation is not implemented!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="933"/>
+ <source>Resize medium operation for this format is not implemented yet!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="935"/>
+ <source>Failed to resize medium!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="951"/>
+ <source>Failed to move medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="957"/>
+ <source>Move medium with UUID %s finished
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="970"/>
+ <source>Set new location of medium with UUID %s finished
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="977"/>
+ <source>Medium description has been changed.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1076"/>
+ <source>unhandled option: -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1078"/>
+ <source>unhandled option: %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1081"/>
+ <source>unknown option: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1092"/>
+ <source>Mandatory UUID or input file parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1094"/>
+ <source>Mandatory output file parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1096"/>
+ <source>Specified options which cannot be used with --existing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1184"/>
+ <source>Failed to clone medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1189"/>
+ <source>Clone medium created in format &apos;%ls&apos;. UUID: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1233"/>
+ <source>Invalid UUID &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1270"/>
+ <source>Incorrect number of parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1271"/>
+ <source>Converting from raw image file=&quot;%s&quot; to file=&quot;%s&quot;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1293"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1305"/>
+ <source>Cannot get image size for file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="1309"/>
+ <source>Creating %s image with size %RU64 bytes (%RU64MB)...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1310"/>
+ <source>fixed</source>
+ <comment>adjective</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1310"/>
+ <source>dynamic</source>
+ <comment>adjective</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1313"/>
+ <source>Converted image from %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1317"/>
+ <source>Cannot create the virtual disk container: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1335"/>
+ <source>Cannot create the disk image &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1345"/>
+ <source>Out of memory allocating buffers for image &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1364"/>
+ <source>Failed to write to disk image &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1393"/>
+ <source>Parent UUID: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1398"/>
+ <location filename="../VBoxManageDisk.cpp" line="1445"/>
+ <location filename="../VBoxManageDisk.cpp" line="1500"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1402"/>
+ <source>not created</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1405"/>
+ <source>created</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1408"/>
+ <source>locked read</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1411"/>
+ <source>locked write</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1414"/>
+ <source>inaccessible</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1417"/>
+ <source>creating</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1420"/>
+ <source>deleting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1426"/>
+ <source>State: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1432"/>
+ <source>Access Error: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1440"/>
+ <source>Description: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1450"/>
+ <source>normal (differencing)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1452"/>
+ <source>normal (base)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1455"/>
+ <source>immutable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1458"/>
+ <source>writethrough</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1461"/>
+ <source>shareable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1464"/>
+ <source>readonly</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1467"/>
+ <source>multiattach</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1473"/>
+ <source>Type: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>Auto-Reset: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>on</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1480"/>
+ <source>off</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1485"/>
+ <source>Location: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1489"/>
+ <source>Storage format: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1504"/>
+ <source>split2G</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1507"/>
+ <source>streamOptimized</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1510"/>
+ <source>ESX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1513"/>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1516"/>
+ <source>dynamic</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1518"/>
+ <source>fixed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1520"/>
+ <source>differencing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1521"/>
+ <source>Format variant: %s %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1526"/>
+ <source>Capacity: %lld MBytes
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1531"/>
+ <source>Size on disk: %lld MBytes
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1539"/>
+ <source>Encryption: enabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1542"/>
+ <source>Cipher: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1543"/>
+ <source>Password ID: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1547"/>
+ <source>Encryption: disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1563"/>
+ <source>Property: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1584"/>
+ <source>In use by VMs: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1619"/>
+ <source>Child UUIDs: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1725"/>
+ <source>base</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1845"/>
+ <source>Failed to delete medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1848"/>
+ <source>Failed to delete medium. Error code %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1884"/>
+ <source>unexpected parameter %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1897"/>
+ <source>Missing action</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1903"/>
+ <source>Invalid action given: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="1909"/>
+ <source>Invalid number of arguments given for action: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2029"/>
+ <source>Disk name or UUID required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2032"/>
+ <source>No password specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2036"/>
+ <source>A new password must always have a valid identifier set at the same time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2043"/>
+ <source>Enter new password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2052"/>
+ <source>Failed to read new password from file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2063"/>
+ <source>Enter old password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2072"/>
+ <source>Failed to read old password from file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2085"/>
+ <location filename="../VBoxManageDisk.cpp" line="2144"/>
+ <source>Invalid hard disk reference, avoiding crash</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2096"/>
+ <source>Encrypt hard disk operation is not implemented!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2098"/>
+ <source>Encrypt hard disk operation for this cipher is not implemented yet!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2100"/>
+ <source>Failed to encrypt hard disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2102"/>
+ <source>Failed to encrypt hard disk!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2116"/>
+ <source>Invalid number of arguments: %d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2123"/>
+ <source>Enter password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2132"/>
+ <source>Failed to read password from file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2148"/>
+ <source>The given password is correct
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2226"/>
+ <source>No medium specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2237"/>
+ <source>Enter encryption password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2389"/>
+ <location filename="../VBoxManageDisk.cpp" line="2610"/>
+ <source>Error opening &apos;%s&apos; for writing: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2405"/>
+ <source>Specified offset (%#RX64) is beyond the end of the medium (%#RX64)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="2435"/>
+ <source>Read(%zu bytes at %#RX64)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2464"/>
+ <source>********** &lt;ditto x %RU64&gt;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2513"/>
+ <location filename="../VBoxManageDisk.cpp" line="2654"/>
+ <source>Error writing to &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageDisk.cpp" line="2521"/>
+ <source>Expected read() at offset %RU64 (%#RX64) to return %#zx bytes, only got %#zx!
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageDisk.cpp" line="2537"/>
+ <location filename="../VBoxManageDisk.cpp" line="2675"/>
+ <source>Error closing &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>GuestCtrl</name>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="276"/>
+ <source>Unable to install console control handler, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="303"/>
+ <source>Unable to uninstall console control handler, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="332"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="398"/>
+ <source>starting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="334"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="367"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="400"/>
+ <source>started</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="336"/>
+ <source>paused</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="338"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="402"/>
+ <source>terminating</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="340"/>
+ <source>successfully terminated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="342"/>
+ <source>terminated by signal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="344"/>
+ <source>abnormally aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="346"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="375"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="406"/>
+ <source>timed out</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="348"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="408"/>
+ <source>timed out, hanging</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="350"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="410"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="435"/>
+ <source>killed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="352"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="373"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="412"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="437"/>
+ <source>error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="356"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="387"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="416"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="441"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="451"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="464"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="369"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="404"/>
+ <source>terminated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="371"/>
+ <source>status changed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="377"/>
+ <source>stdin ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="379"/>
+ <source>data on stdout</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="381"/>
+ <source>data on stderr</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="383"/>
+ <source>waiting flag not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="427"/>
+ <source>opening</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="429"/>
+ <source>open</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="431"/>
+ <source>closing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="433"/>
+ <source>closed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="452"/>
+ <source>fifo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="453"/>
+ <source>char-device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="454"/>
+ <source>directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="455"/>
+ <source>block-device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="456"/>
+ <source>file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="457"/>
+ <source>symlink</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="458"/>
+ <source>socket</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="459"/>
+ <source>white-out</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="478"/>
+ <source>Error details:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="483"/>
+ <source>Object has indicated no error (%Rhrc)!?
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="515"/>
+ <source>Could not lookup progress information
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="574"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3247"/>
+ <source>Out of memory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="602"/>
+ <source>The --username|-u option is ignored by &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="609"/>
+ <source>Password is given more than once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="613"/>
+ <source>The --password option is ignored by &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="620"/>
+ <source>The --password-file|-p option is ignored by &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="627"/>
+ <source>The --domain option is ignored by &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="692"/>
+ <source>Failed to get a IConsole pointer for the machine. Is it still running?
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="697"/>
+ <source>Machine &quot;%s&quot; is not running (currently %s)!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="726"/>
+ <source>[%RU32] VBoxManage Guest Control [%s] - %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="728"/>
+ <source>No enough memory for session name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="734"/>
+ <source>Creating guest session as user &apos;%s&apos;...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="745"/>
+ <source>Out of memory setting up IGuest::CreateSession call</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="754"/>
+ <source>Waiting for guest session to start...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="766"/>
+ <source>Out of memory setting up IGuestSession::WaitForArray call</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="782"/>
+ <source>Successfully started guest session (ID %RU32)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="791"/>
+ <source>Error starting guest session (current status is: %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="792"/>
+ <source>&lt;unknown&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="851"/>
+ <source>No user name specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="891"/>
+ <source>Closing guest session ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="897"/>
+ <source>Guest session detached
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1058"/>
+ <source>Unable to write output, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1088"/>
+ <source>Unsupported %s line ending conversion</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1093"/>
+ <source>Error getting %s handle: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1216"/>
+ <source>Invalid argument variable[=value]: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1226"/>
+ <source>Warning: Deprecated option &quot;--no-profile&quot; specified
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1292"/>
+ <source>No executable specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1344"/>
+ <source>Starting guest process ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1346"/>
+ <source>Starting guest process (within %ums)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1368"/>
+ <source>Process &apos;%s&apos; (PID %RU32) started
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1373"/>
+ <source>[%RU32 - Session %RU32]
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1394"/>
+ <source>waitResult: %d
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1410"/>
+ <source>Process terminated
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1487"/>
+ <source>Process execution aborted!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1493"/>
+ <source>Process successfully started!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1507"/>
+ <source>Exit code=%u (Status=%u [%s])
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1516"/>
+ <source>Process timed out (guest side) and %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1518"/>
+ <source>failed to terminate so far</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1518"/>
+ <source>was terminated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1524"/>
+ <source>Process now is in status [%s] (unexpected)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1532"/>
+ <source>Process monitor loop quit with vrc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1538"/>
+ <source>Process monitor loop timed out
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1641"/>
+ <source>No sources specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1649"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2201"/>
+ <source>No destination specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1658"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1762"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1671"/>
+ <source>Copying from host to guest ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1673"/>
+ <source>Copying from guest to host ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1685"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1759"/>
+ <source>RTPathQueryInfo failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1703"/>
+ <source>Destination must be a directory!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1735"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1796"/>
+ <source>File &apos;%s&apos; -&gt; &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1744"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1782"/>
+ <source>Directory &apos;%s&apos; -&gt; &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1756"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1805"/>
+ <source>Not a file or directory: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1811"/>
+ <source>FsObjQueryInfo failed on &apos;%s&apos;: %Rhrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1825"/>
+ <source>File copy failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1894"/>
+ <source>Creating %RU32 directories...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1898"/>
+ <source>mkdir was interrupted by Ctrl-C (%u left)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1911"/>
+ <source>Creating directory &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1922"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2006"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2127"/>
+ <source>Out of memory
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1932"/>
+ <source>No directory to create specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1980"/>
+ <source>Removing %RU32 directory tree(s)...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1983"/>
+ <source>Removing %RU32 directorie(s)...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1988"/>
+ <source>rmdir was interrupted by Ctrl-C (%u left)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="1999"/>
+ <source>Removing directory &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2018"/>
+ <source>Recursively removing directory &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2036"/>
+ <source>Directory deletion failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2042"/>
+ <source>Out of memory during recursive rmdir
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2060"/>
+ <source>No directory to remove specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2100"/>
+ <source>Removing %RU32 file(s)...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2104"/>
+ <source>rm was interrupted by Ctrl-C (%u left)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2115"/>
+ <source>Removing file &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2137"/>
+ <source>No file to remove specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2195"/>
+ <source>Failed to initialize, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2199"/>
+ <source>No source(s) to move specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2220"/>
+ <source>Destination does not exist
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2230"/>
+ <source>Destination must be a directory when specifying multiple sources
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2234"/>
+ <source>Unable to determine destination type: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2243"/>
+ <source>Renaming %RU32 %s ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2244"/>
+ <source>sources</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2244"/>
+ <source>source</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2259"/>
+ <source>Cannot stat &quot;%s&quot;: No such file or directory
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2276"/>
+ <source>Renaming %s &quot;%s&quot; to &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2277"/>
+ <source>directory</source>
+ <comment>object</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2277"/>
+ <source>file</source>
+ <comment>object</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2296"/>
+ <source>Warning: Not all sources were renamed
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2355"/>
+ <source>More than one template specified!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2364"/>
+ <source>No template specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2367"/>
+ <source>Creating temporary files is currently not supported!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2379"/>
+ <source>Creating temporary directory from template &apos;%s&apos; in directory &apos;%s&apos; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2382"/>
+ <source>Creating temporary directory from template &apos;%s&apos; in default temporary directory ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2385"/>
+ <source>Creating temporary file from template &apos;%s&apos; in directory &apos;%s&apos; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2388"/>
+ <source>Creating temporary file from template &apos;%s&apos; in default temporary directory ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2401"/>
+ <source>Directory name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2444"/>
+ <source>Command &quot;%s&quot; not implemented yet!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2452"/>
+ <source>Nothing to stat!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2465"/>
+ <source>Checking for element &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2475"/>
+ <source>Failed to stat &apos;%s&apos;: No such file
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2480"/>
+ <source> File: &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2515"/>
+ <source> Size: %-17RU64 Alloc: %-19RU64 Type: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2517"/>
+ <source>Device: %#-17RX32 INode: %-18RU64 Links: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2528"/>
+ <source> Mode: %-16s Attrib: %-17s Dev ID: %#RX32
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2530"/>
+ <source> Mode: %-16s Attrib: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2532"/>
+ <source> Owner: %4d/%-12ls Group: %4d/%ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2536"/>
+ <source> Birth: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2538"/>
+ <source>Change: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2540"/>
+ <source>Modify: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2542"/>
+ <source>Access: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2595"/>
+ <source>Current run level is %RU32
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2602"/>
+ <source>Waiting for run level %RU32 ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2615"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3565"/>
+ <source>Waiting failed with %Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2621"/>
+ <source>Run level %RU32 reached
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2630"/>
+ <source>Run level %RU32 not reached within time
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2716"/>
+ <source>RTPathAbsCxx failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2745"/>
+ <source>Updating Guest Additions ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2761"/>
+ <source>No Guest Additions source found or specified, aborting
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2766"/>
+ <source>Source &quot;%s&quot; does not exist!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2777"/>
+ <source>OS type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2782"/>
+ <source>Additions run level:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2794"/>
+ <source>Additions version:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2802"/>
+ <source>Using source: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2811"/>
+ <source>Waiting for current Guest Additions inside VM getting ready for updating ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2832"/>
+ <source>Guest Additions %lsr%RU64 currently installed, waiting for Guest Additions installer to start ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2856"/>
+ <source>Guest Additions update failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2861"/>
+ <source>Guest Additions update successful.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2866"/>
+ <source>Rebooting guest ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2874"/>
+ <source>Current installed Guest Additions don&apos;t support automatic rebooting. Please reboot manually.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2886"/>
+ <source>Waiting for new Guest Additions inside VM getting ready ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2894"/>
+ <source>Verifying Guest Additions update ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2913"/>
+ <source>Old Guest Additions: %ls%RU64
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2915"/>
+ <source>New Guest Additions: %ls%RU64
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2920"/>
+ <source>
+Error updating Guest Additions, please check guest installer log
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2925"/>
+ <source>
+WARNING: Guest Additions were downgraded
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="2932"/>
+ <source>The guest needs to be restarted in order to make use of the updated Guest Additions.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3005"/>
+ <source>Invalid run level specified. Valid values are: system, userland, desktop</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3019"/>
+ <source>Missing run level to wait for</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3066"/>
+ <source>Unknown list: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3076"/>
+ <source>Missing list name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3097"/>
+ <source>Active guest sessions:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3116"/>
+ <source>
+ Session #%-3zu ID=%-3RU32 User=%-16ls Status=[%s] Name=%ls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3139"/>
+ <source>
+ Process #%-03zu PID=%-6RU32 Status=[%s] Command=%ls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3167"/>
+ <source>
+ File #%-03zu ID=%-6RU32 Status=[%s] Name=%ls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3178"/>
+ <source>
+
+Total guest sessions: %zu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3180"/>
+ <source>Total guest processes: %zu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3182"/>
+ <source>Total guest files: %zu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3185"/>
+ <source>No active guest sessions found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3251"/>
+ <source>Invalid PID value: 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3254"/>
+ <source>Error parsing PID value: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3264"/>
+ <source>At least one PID must be specified to kill!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3268"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3422"/>
+ <source>No session ID specified!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3272"/>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3426"/>
+ <source>Either session ID or name (pattern) must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3335"/>
+ <source>Terminating process (PID %RU32) (session ID %RU32) ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3343"/>
+ <source>No matching process(es) for session ID %RU32 found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3355"/>
+ <source>No matching session(s) found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3358"/>
+ <source>%RU32 process(es) terminated
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3464"/>
+ <source>Closing guest session ID=#%RU32 &quot;%s&quot; ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3468"/>
+ <source>Guest session successfully closed
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3476"/>
+ <source>No guest session(s) found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3554"/>
+ <source>Waiting for events ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3709"/>
+ <source>Unknown sub-command: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3718"/>
+ <source>Missing sub-command</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrl.cpp" line="3720"/>
+ <source>Missing VM name and sub-command</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>GuestCtrlLsnr</name>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="106"/>
+ <source>File ID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="162"/>
+ <source>Process PID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="254"/>
+ <source>File &quot;%s&quot; %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="256"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="320"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="461"/>
+ <source>registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="256"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="320"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="461"/>
+ <source>unregistered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="260"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="324"/>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="465"/>
+ <source>Registering ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="283"/>
+ <source>Unregistering file ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="318"/>
+ <source>Process &quot;%s&quot; %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="347"/>
+ <source>Unregistering process ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="384"/>
+ <source>Session ID=%RU32 &quot;%s&quot; changed status to [%s]
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="459"/>
+ <source>Session ID=%RU32 &quot;%s&quot; %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="490"/>
+ <source>Unregistering ...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestCtrlListener.cpp" line="552"/>
+ <source>Reached run level %RU32
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>GuestProp</name>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="64"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="125"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="171"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="215"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="304"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="407"/>
+ <location filename="../VBoxManageGuestProp.cpp" line="422"/>
+ <source>Incorrect parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="84"/>
+ <source>No value set!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="86"/>
+ <source>Value: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="89"/>
+ <source>Timestamp: %lld
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="90"/>
+ <source>Flags: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="251"/>
+ <source>No properties found.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="253"/>
+ <source>Name: %ls, value: %ls, timestamp: %lld, flags: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="362"/>
+ <source>Property %ls was deleted
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="364"/>
+ <source>Name: %ls, value: %ls, flags: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageGuestProp.cpp" line="381"/>
+ <source>Time out or interruption while waiting for a notification.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Help</name>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="139"/>
+ <source>Usage - %s%s:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="142"/>
+ <source>Usage:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="231"/>
+ <source>No subcommand specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="257"/>
+ <source>Unknown subcommand: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="290"/>
+ <source>Too many parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="397"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="401"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="403"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="406"/>
+ <source>Unknown option: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="408"/>
+ <source>Invalid argument format: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="432"/>
+ <source>Missing the %u%s value for option %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="434"/>
+ <source>st</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="435"/>
+ <source>nd</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="436"/>
+ <source>rd</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHelp.cpp" line="437"/>
+ <source>th</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HostOnly</name>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="95"/>
+ <source>Failed to create the host-only adapter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="104"/>
+ <source>Interface &apos;%ls&apos; was successfully created
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="123"/>
+ <location filename="../VBoxManageHostonly.cpp" line="214"/>
+ <source>Only one interface name can be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="131"/>
+ <source>No interface name was specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="149"/>
+ <source>Failed to remove the host-only adapter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="193"/>
+ <source>The --ip option is specified more than once</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="198"/>
+ <source>The --netmask option is specified more than once</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="203"/>
+ <source>The --ipv6 option is specified more than once</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="208"/>
+ <source>The --netmasklengthv6 option is specified more than once</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="224"/>
+ <source>You can not use --dhcp with static ip configuration parameters: --ip, --netmask, --ipv6 and --netmasklengthv6.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="226"/>
+ <source>You can not use ipv4 configuration (--ip and --netmask) with ipv6 (--ipv6 and --netmasklengthv6) simultaneously.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="234"/>
+ <source>Could not find interface &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="250"/>
+ <source>IPv6 setting is not supported for this adapter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="259"/>
+ <source>Neither -dhcp nor -ip nor -ipv6 was specfified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="268"/>
+ <location filename="../VBoxManageHostonly.cpp" line="514"/>
+ <source>No sub-command specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="289"/>
+ <location filename="../VBoxManageHostonly.cpp" line="533"/>
+ <source>Unknown sub-command &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="410"/>
+ <source>The --name parameter must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="412"/>
+ <source>The --netmask parameter must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="414"/>
+ <source>The --lower-ip parameter must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="416"/>
+ <source>The --upper-ip parameter must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageHostonly.cpp" line="447"/>
+ <location filename="../VBoxManageHostonly.cpp" line="503"/>
+ <source>Either --name or --id parameter must be specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Info</name>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="85"/>
+ <location filename="../VBoxManageInfo.cpp" line="108"/>
+ <location filename="../VBoxManageInfo.cpp" line="131"/>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <location filename="../VBoxManageInfo.cpp" line="2349"/>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>enabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="85"/>
+ <location filename="../VBoxManageInfo.cpp" line="108"/>
+ <location filename="../VBoxManageInfo.cpp" line="131"/>
+ <location filename="../VBoxManageInfo.cpp" line="1263"/>
+ <location filename="../VBoxManageInfo.cpp" line="1317"/>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <location filename="../VBoxManageInfo.cpp" line="2350"/>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="284"/>
+ <source> %sName: %ls (UUID: %s)%s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="290"/>
+ <source> %sDescription: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="292"/>
+ <source> %sDescription:
+%ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="341"/>
+ <source>powered off</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="343"/>
+ <source>saved</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="345"/>
+ <source>teleported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="347"/>
+ <source>aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="349"/>
+ <source>aborted-saved</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="351"/>
+ <source>running</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="353"/>
+ <location filename="../VBoxManageInfo.cpp" line="399"/>
+ <source>paused</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="355"/>
+ <source>guru meditation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="357"/>
+ <source>teleporting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="359"/>
+ <source>live snapshotting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="361"/>
+ <source>starting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="363"/>
+ <source>stopping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="365"/>
+ <source>saving</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="367"/>
+ <source>restoring</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="369"/>
+ <source>teleporting paused vm</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="371"/>
+ <source>teleporting (incoming)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="373"/>
+ <source>deleting snapshot live</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="375"/>
+ <source>deleting snapshot live paused</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="377"/>
+ <source>online snapshotting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="379"/>
+ <source>restoring snapshot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="381"/>
+ <source>deleting snapshot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="383"/>
+ <source>setting up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="385"/>
+ <source>offline snapshotting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="389"/>
+ <location filename="../VBoxManageInfo.cpp" line="416"/>
+ <location filename="../VBoxManageInfo.cpp" line="446"/>
+ <location filename="../VBoxManageInfo.cpp" line="699"/>
+ <location filename="../VBoxManageInfo.cpp" line="1186"/>
+ <location filename="../VBoxManageInfo.cpp" line="1206"/>
+ <location filename="../VBoxManageInfo.cpp" line="1806"/>
+ <location filename="../VBoxManageInfo.cpp" line="1860"/>
+ <location filename="../VBoxManageInfo.cpp" line="2412"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="397"/>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>not active</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="401"/>
+ <source>pre-initializing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="403"/>
+ <source>initializing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="405"/>
+ <source>active/running</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="407"/>
+ <source>terminating</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="409"/>
+ <source>terminated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="411"/>
+ <source>failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="692"/>
+ <location filename="../VBoxManageInfo.cpp" line="1404"/>
+ <location filename="../VBoxManageInfo.cpp" line="2139"/>
+ <source>Null</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="693"/>
+ <source>Disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="694"/>
+ <location filename="../VBoxManageInfo.cpp" line="1295"/>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="709"/>
+ <location filename="../VBoxManageInfo.cpp" line="2693"/>
+ <source>&lt;none&gt;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="732"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: none (disabled)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="780"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: %RI64 %s (%RI64 %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="784"/>
+ <source>#%zu: Name: &apos;%ls&apos;, Type: %s, Limit: %RI64 %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="813"/>
+ <source>Name: &apos;%ls&apos;, Host path: &apos;%ls&apos; (%s), %s%s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="814"/>
+ <source>writable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="814"/>
+ <source>readonly</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="815"/>
+ <source>, auto-mount</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="817"/>
+ <source>, mount-point: &apos;%ls&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="840"/>
+ <source>VendorId:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="841"/>
+ <source>ProductId:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="850"/>
+ <source>Revision:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="852"/>
+ <source>Manufacturer:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="853"/>
+ <source>Product:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="854"/>
+ <source>SerialNumber:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="855"/>
+ <source>Address:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="862"/>
+ <location filename="../VBoxManageInfo.cpp" line="1542"/>
+ <location filename="../VBoxManageInfo.cpp" line="2572"/>
+ <location filename="../VBoxManageInfo.cpp" line="2985"/>
+ <source>&lt;none&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="920"/>
+ <source> Port %u, Unit %u: UUID: %ls%s%s%s%s%s%s
+ Location: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="922"/>
+ <source>, passthrough enabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="923"/>
+ <location filename="../VBoxManageInfo.cpp" line="966"/>
+ <source>, temp eject</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="924"/>
+ <location filename="../VBoxManageInfo.cpp" line="967"/>
+ <source>, ejected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="925"/>
+ <source>, hot-pluggable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="926"/>
+ <source>, non-rotational (SSD)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="927"/>
+ <source>, discards unused blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="965"/>
+ <source> Port %u, Unit %u: Empty%s%s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="979"/>
+ <source> Port %u, Unit %u: GetMedium failed: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="995"/>
+ <location filename="../VBoxManageInfo.cpp" line="1027"/>
+ <location filename="../VBoxManageInfo.cpp" line="1914"/>
+ <location filename="../VBoxManageInfo.cpp" line="1950"/>
+ <source>None</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1000"/>
+ <source>Automatic</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1015"/>
+ <location filename="../VBoxManageInfo.cpp" line="1057"/>
+ <location filename="../VBoxManageInfo.cpp" line="1428"/>
+ <location filename="../VBoxManageInfo.cpp" line="1908"/>
+ <location filename="../VBoxManageInfo.cpp" line="1945"/>
+ <location filename="../VBoxManageInfo.cpp" line="2124"/>
+ <location filename="../VBoxManageInfo.cpp" line="2125"/>
+ <location filename="../VBoxManageInfo.cpp" line="2126"/>
+ <location filename="../VBoxManageInfo.cpp" line="2269"/>
+ <location filename="../VBoxManageInfo.cpp" line="2298"/>
+ <source>Unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1032"/>
+ <source>Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1037"/>
+ <source>Legacy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1042"/>
+ <source>Minimal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1106"/>
+ <source>&quot;&lt;inaccessible&gt;&quot; {%s}
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1112"/>
+ <source>Name: &lt;inaccessible!&gt;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1121"/>
+ <source>Config file: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1124"/>
+ <source>Access error details:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1144"/>
+ <source>Name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1145"/>
+ <source>Groups:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1151"/>
+ <location filename="../VBoxManageInfo.cpp" line="1153"/>
+ <source>Guest OS:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1155"/>
+ <source>Config file:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1156"/>
+ <source>Snapshot folder:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1157"/>
+ <source>Log folder:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1158"/>
+ <source>Hardware UUID:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1159"/>
+ <source>Memory size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1160"/>
+ <source>Page Fusion:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1163"/>
+ <source>VRAM size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1164"/>
+ <source>CPU exec cap:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1165"/>
+ <source>HPET:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1166"/>
+ <source>CPUProfile:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1177"/>
+ <source>invalid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1189"/>
+ <source>Chipset:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1209"/>
+ <source>Firmware:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1211"/>
+ <source>Number of CPUs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1213"/>
+ <source>Long Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1214"/>
+ <source>Triple Fault Reset:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1217"/>
+ <source>Nested VT-x/AMD-V:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1218"/>
+ <source>CPUID Portability Level:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1221"/>
+ <source>CPUID overrides:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1234"/>
+ <source>Leaf no. EAX EBX ECX EDX
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1246"/>
+ <source>None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1269"/>
+ <source>menu only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1275"/>
+ <source>message and menu</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1277"/>
+ <source>Boot menu mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1289"/>
+ <source>Floppy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1293"/>
+ <source>HardDisk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1299"/>
+ <source>Shared Folder</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1301"/>
+ <source>Not Assigned</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1302"/>
+ <source>Boot Device %u:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1333"/>
+ <source>BIOS APIC mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1335"/>
+ <source>Time offset:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1335"/>
+ <source>ms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1339"/>
+ <source>BIOS NVRAM File:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1340"/>
+ <source>RTC:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1340"/>
+ <source>local time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1341"/>
+ <source>Hardware Virtualization:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1342"/>
+ <source>Nested Paging:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1343"/>
+ <source>Large Pages:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1345"/>
+ <source>VT-x Unrestricted Exec.:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1346"/>
+ <source>AMD-V Virt. Vmsave/Vmload:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1358"/>
+ <source>Paravirt. Provider:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1363"/>
+ <source>Effective Paravirt. Prov.:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1368"/>
+ <source>Paravirt. Debug:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1391"/>
+ <source>%-28s %s (since %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1391"/>
+ <source>State:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1435"/>
+ <source>Graphics Controller:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1438"/>
+ <source>Monitor count:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1439"/>
+ <source>3D Acceleration:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1441"/>
+ <source>2D Video Acceleration:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1443"/>
+ <source>Teleporter Enabled:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1444"/>
+ <source>Teleporter Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1445"/>
+ <source>Teleporter Address:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1446"/>
+ <source>Teleporter Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1447"/>
+ <source>Tracing Enabled:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1448"/>
+ <source>Allow Tracing to Access VM:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1449"/>
+ <source>Tracing Configuration:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1450"/>
+ <source>Autostart Enabled:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1451"/>
+ <source>Autostart Delay:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1452"/>
+ <source>Default Frontend:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1463"/>
+ <source>flat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1469"/>
+ <source>low</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1475"/>
+ <source>normal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1481"/>
+ <source>high</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1487"/>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1490"/>
+ <source>VM process priority:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1502"/>
+ <location filename="../VBoxManageInfo.cpp" line="1542"/>
+ <source>Storage Controllers:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1532"/>
+ <source>#%u: &apos;%ls&apos;, Type: %s, Instance: %u, Ports: %u (max %u), %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1534"/>
+ <source>Bootable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1534"/>
+ <source>Not bootable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1561"/>
+ <source>NIC %u:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1570"/>
+ <location filename="../VBoxManageInfo.cpp" line="1992"/>
+ <location filename="../VBoxManageInfo.cpp" line="2098"/>
+ <location filename="../VBoxManageInfo.cpp" line="2459"/>
+ <location filename="../VBoxManageInfo.cpp" line="2491"/>
+ <source>%-28s disabled
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1587"/>
+ <location filename="../VBoxManageInfo.cpp" line="1892"/>
+ <location filename="../VBoxManageInfo.cpp" line="1897"/>
+ <source>none</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1655"/>
+ <source>%sNIC %d Rule(%d): name = %s, protocol = %s, host ip = %s, host port = %s, guest ip = %s, guest port = %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1678"/>
+ <source>NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1694"/>
+ <source>Bridged Interface &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1708"/>
+ <source>Internal Network &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1722"/>
+ <source>Host-only Interface &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1737"/>
+ <source>Generic &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1766"/>
+ <source>NAT Network &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1781"/>
+ <source>Host Only Network &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1797"/>
+ <source>Cloud Network &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1820"/>
+ <source>deny</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1821"/>
+ <source>allow-vms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1822"/>
+ <source>allow-all</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1888"/>
+ <source>%-28s MAC: %ls, Attachment: %s, Cable connected: %s, Trace: %s (file: %ls), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s, Bandwidth group: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1890"/>
+ <location filename="../VBoxManageInfo.cpp" line="1891"/>
+ <location filename="../VBoxManageInfo.cpp" line="2452"/>
+ <location filename="../VBoxManageInfo.cpp" line="2453"/>
+ <source>on</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1890"/>
+ <location filename="../VBoxManageInfo.cpp" line="1891"/>
+ <location filename="../VBoxManageInfo.cpp" line="2452"/>
+ <location filename="../VBoxManageInfo.cpp" line="2453"/>
+ <source>off</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1918"/>
+ <source>PS/2 Mouse</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1922"/>
+ <source>USB Mouse</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1926"/>
+ <source>USB Tablet</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1930"/>
+ <source>USB Tablet and PS/2 Mouse</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1934"/>
+ <source>USB Multi-Touch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1940"/>
+ <source>Pointing Device:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1954"/>
+ <source>PS/2 Keyboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1958"/>
+ <source>USB Keyboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1962"/>
+ <source>USB and PS/2 Keyboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1968"/>
+ <source>Keyboard Device:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="1982"/>
+ <source>UART %u:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2011"/>
+ <location filename="../VBoxManageInfo.cpp" line="2111"/>
+ <source>%-28s I/O base: %#06x, IRQ: %d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2019"/>
+ <source>, disconnected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2026"/>
+ <source>, attached to raw file &apos;%ls&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2034"/>
+ <source>, attached to tcp (%s) &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2035"/>
+ <location filename="../VBoxManageInfo.cpp" line="2043"/>
+ <source>server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2035"/>
+ <location filename="../VBoxManageInfo.cpp" line="2043"/>
+ <source>client</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2042"/>
+ <source>, attached to pipe (%s) &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2050"/>
+ <source>, attached to device &apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2088"/>
+ <source>LPT %u:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2115"/>
+ <source>, attached to device &apos;%ls&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2240"/>
+ <source>Audio:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2242"/>
+ <source> (Driver: %s, Controller: %s, Codec: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2245"/>
+ <source>Audio playback:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2246"/>
+ <source>Audio capture:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2260"/>
+ <location filename="../VBoxManageInfo.cpp" line="2289"/>
+ <source>HostToGuest</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2263"/>
+ <location filename="../VBoxManageInfo.cpp" line="2292"/>
+ <source>GuestToHost</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2266"/>
+ <location filename="../VBoxManageInfo.cpp" line="2295"/>
+ <source>Bidirectional</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2272"/>
+ <source>Clipboard Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2274"/>
+ <source>Clipboard file transfers:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2301"/>
+ <source>Drag and drop Mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2312"/>
+ <source>Session name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2345"/>
+ <source>unknown status</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2348"/>
+ <source>blank</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2353"/>
+ <source>Video mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2394"/>
+ <source>null</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2400"/>
+ <source>external</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2406"/>
+ <source>guest</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2451"/>
+ <source>%-28s enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2455"/>
+ <source>VRDE port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2457"/>
+ <source>%-28s enabled (Quality %ls)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2457"/>
+ <location filename="../VBoxManageInfo.cpp" line="2459"/>
+ <source>Video redirection:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2479"/>
+ <source>%-28s: %-10lS = &lt;not set&gt;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2479"/>
+ <location filename="../VBoxManageInfo.cpp" line="2481"/>
+ <source>VRDE property</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2546"/>
+ <source>USB Device Filters:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2552"/>
+ <source>Index:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source> Active:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source>yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2553"/>
+ <source>no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2554"/>
+ <source> Name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2555"/>
+ <source> VendorId:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2556"/>
+ <source> ProductId:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2557"/>
+ <source> Revision:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2558"/>
+ <source> Manufacturer:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2559"/>
+ <source> Product:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2560"/>
+ <source> Remote:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2561"/>
+ <source> Serial Number:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2567"/>
+ <source>Masked Interfaces:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2572"/>
+ <source>USB Device Filters:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2580"/>
+ <source>Available remote USB devices:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2588"/>
+ <source>Currently attached USB devices:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2604"/>
+ <source>
+Attached physical PCI devices:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2623"/>
+ <source> Host device %ls at %s attached as %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2639"/>
+ <source>Bandwidth groups:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2652"/>
+ <source>Shared folders:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2662"/>
+ <source>global mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2674"/>
+ <source>machine mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2686"/>
+ <source>transient mapping</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <source>VRDE Connection:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2738"/>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>active</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2739"/>
+ <source>Clients so far:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2746"/>
+ <source>Start time:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2749"/>
+ <source>Last started:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2751"/>
+ <source>Last ended:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2761"/>
+ <source>Sent:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2761"/>
+ <location filename="../VBoxManageInfo.cpp" line="2763"/>
+ <location filename="../VBoxManageInfo.cpp" line="2765"/>
+ <location filename="../VBoxManageInfo.cpp" line="2767"/>
+ <source>Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2762"/>
+ <source>Average speed:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2762"/>
+ <location filename="../VBoxManageInfo.cpp" line="2766"/>
+ <source>B/s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2763"/>
+ <source>Sent total:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2765"/>
+ <source>Received:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2766"/>
+ <source>Speed:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2767"/>
+ <source>Received total:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2771"/>
+ <source>User name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2772"/>
+ <source>Domain:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2773"/>
+ <source>Client name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2774"/>
+ <source>Client IP:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2775"/>
+ <source>Client version:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2776"/>
+ <source>Encryption:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2828"/>
+ <source>Capturing:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2830"/>
+ <source>Capture audio:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2840"/>
+ <source>Capture screens:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2841"/>
+ <source>Capture file:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2843"/>
+ <source>Capture dimensions:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2844"/>
+ <source>Capture rate:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2844"/>
+ <location filename="../VBoxManageInfo.cpp" line="2845"/>
+ <source>kbps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2845"/>
+ <source>Capture FPS:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2846"/>
+ <source>Capture options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2863"/>
+ <source>Description:
+%ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2881"/>
+ <source>VMMDev Testing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2882"/>
+ <location filename="../VBoxManageInfo.cpp" line="2884"/>
+ <source>misconfigured</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2907"/>
+ <source>* Snapshots:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2916"/>
+ <source>* Guest:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2919"/>
+ <source>Configured memory balloon:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2919"/>
+ <source>MB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2927"/>
+ <source>OS type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2932"/>
+ <source>Additions run level:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2944"/>
+ <source>Additions version:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2953"/>
+ <location filename="../VBoxManageInfo.cpp" line="2985"/>
+ <source>Guest Facilities:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="2973"/>
+ <source>Facility &quot;%ls&quot;: %s (last update: %s)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3044"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3054"/>
+ <source>VM name or UUID required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageInfo.cpp" line="3065"/>
+ <source>Option --log is exclusive</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Internal</name>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="169"/>
+ <source>Usage: VBoxManage internalcommands &lt;command&gt; [command arguments]
+
+Commands:
+
+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%sWARNING: This is a development tool and shall only be used to analyse
+ problems. It is completely unsupported and will change in
+ incompatible ways without warning.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="180"/>
+ <source> loadmap &lt;vmname|uuid&gt; &lt;symfile&gt; &lt;address&gt; [module] [subtrahend] [segment]
+ This will instruct DBGF to load the given map file
+ during initialization. (See also loadmap in the debugger.)
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="187"/>
+ <source> loadsyms &lt;vmname|uuid&gt; &lt;symfile&gt; [delta] [module] [module address]
+ This will instruct DBGF to load the given symbol file
+ during initialization.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="194"/>
+ <source> sethduuid &lt;filepath&gt; [&lt;uuid&gt;]
+ Assigns a new UUID to the given image file. This way, multiple copies
+ of a container can be registered.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="201"/>
+ <source> sethdparentuuid &lt;filepath&gt; &lt;uuid&gt;
+ Assigns a new parent UUID to the given image file.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="207"/>
+ <source> dumphdinfo &lt;filepath&gt;
+ Prints information about the image at the given location.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="213"/>
+ <source> listpartitions -rawdisk &lt;diskname&gt;
+ Lists all partitions on &lt;diskname&gt;.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="219"/>
+ <source> createrawvmdk -filename &lt;filename&gt; -rawdisk &lt;diskname&gt;
+ [-partitions &lt;list of partition numbers&gt; [-mbr &lt;filename&gt;] ]
+ [-relative]
+ Creates a new VMDK image which gives access to an entire host disk (if
+ the parameter -partitions is not specified) or some partitions of a
+ host disk. If access to individual partitions is granted, then the
+ parameter -mbr can be used to specify an alternative MBR to be used
+ (the partitioning information in the MBR file is ignored).
+ The diskname is on Linux e.g. /dev/sda, and on Windows e.g.
+ \\.\PhysicalDrive0).
+ On Linux or FreeBSD host the parameter -relative causes a VMDK file to
+ be created which refers to individual partitions instead to the entire
+ disk.
+ The necessary partition numbers can be queried with
+ VBoxManage internalcommands listpartitions
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="238"/>
+ <source> renamevmdk -from &lt;filename&gt; -to &lt;filename&gt;
+ Renames an existing VMDK image, including the base file and all its extents.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="245"/>
+ <source> converttoraw [-format &lt;fileformat&gt;] &lt;filename&gt; &lt;outputfile&gt;|stdout
+ Convert image to raw, writing to file or stdout.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="251"/>
+ <source> converttoraw [-format &lt;fileformat&gt;] &lt;filename&gt; &lt;outputfile&gt;
+ Convert image to raw, writing to file.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="259"/>
+ <source> converthd [-srcformat VDI|VMDK|VHD|RAW]
+ [-dstformat VDI|VMDK|VHD|RAW]
+ &lt;inputfile&gt; &lt;outputfile&gt;
+ converts hard disk images between formats
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="267"/>
+ <source> repairhd [-dry-run]
+ [-format VDI|VMDK|VHD|...]
+ &lt;filename&gt;
+ Tries to repair corrupted disk images
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="276"/>
+ <source> modinstall
+ Installs the necessary driver for the host OS
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="282"/>
+ <source> moduninstall
+ Deinstalls the driver
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="292"/>
+ <source> debuglog &lt;vmname|uuid&gt; [--enable|--disable] [--flags todo]
+ [--groups todo] [--destinations todo]
+ Controls debug logging.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="299"/>
+ <source> passwordhash &lt;password&gt;
+ Generates a password hash.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="305"/>
+ <source> gueststats &lt;vmname|uuid&gt; [--interval &lt;seconds&gt;]
+ Obtains and prints internal guest statistics.
+ Sets the update interval if specified.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="451"/>
+ <source>Cannot find unique key for &apos;%s&apos;!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="514"/>
+ <source>Failed to delete key &apos;%s&apos; from &apos;%s&apos;, string conversion error %Rrc!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="538"/>
+ <source>Failed to set &apos;%s/%s/%s&apos; to &apos;%s&apos;! hrc=%#x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="606"/>
+ <location filename="../VBoxInternalManage.cpp" line="683"/>
+ <source>Missing the filename argument!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="614"/>
+ <source>Failed to read delta &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="626"/>
+ <location filename="../VBoxInternalManage.cpp" line="691"/>
+ <source>Failed to read module address &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="634"/>
+ <source>Failed to read module size &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="688"/>
+ <source>Missing the module address argument!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="702"/>
+ <source>Failed to read subtrahend &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="710"/>
+ <source>Failed to read segment number &apos;%s&apos;, rc=%Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="737"/>
+ <source>Error code %Rrc at %s(%u) in function %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="760"/>
+ <location filename="../VBoxInternalManage.cpp" line="774"/>
+ <location filename="../VBoxInternalManage.cpp" line="832"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="765"/>
+ <location filename="../VBoxInternalManage.cpp" line="776"/>
+ <source>Invalid UUID parameter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="780"/>
+ <source>Invalid invocation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="788"/>
+ <location filename="../VBoxInternalManage.cpp" line="841"/>
+ <source>Format autodetect failed: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="803"/>
+ <location filename="../VBoxInternalManage.cpp" line="856"/>
+ <location filename="../VBoxInternalManage.cpp" line="1958"/>
+ <location filename="../VBoxInternalManage.cpp" line="2056"/>
+ <location filename="../VBoxInternalManage.cpp" line="2130"/>
+ <source>Cannot create the virtual disk container: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="808"/>
+ <location filename="../VBoxInternalManage.cpp" line="861"/>
+ <source>Cannot open the image: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="815"/>
+ <source>Cannot set a new UUID: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="817"/>
+ <source>UUID changed to: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="942"/>
+ <source>The GPT header seems corrupt because it contains too many entries</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="949"/>
+ <source>Allocating memory for the GPT partitions entries failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="958"/>
+ <source>Reading the partition table failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1042"/>
+ <source>More than one extended partition</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1060"/>
+ <source>Inconsistency for logical partition start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1072"/>
+ <source>Logical partition without magic</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1079"/>
+ <source>Logical partition with type 0 encountered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1096"/>
+ <source>Invalid partition start offset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1116"/>
+ <source>Logical partition chain broken</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1139"/>
+ <source>Two partitions start at the same place</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1144"/>
+ <source>Partition starts at sector 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1180"/>
+ <source>Overlapping GPT partitions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1196"/>
+ <source>Overlapping MBR partitions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1219"/>
+ <location filename="../VBoxInternalManage.cpp" line="1304"/>
+ <location filename="../VBoxInternalManage.cpp" line="1313"/>
+ <location filename="../VBoxInternalManage.cpp" line="1322"/>
+ <location filename="../VBoxInternalManage.cpp" line="1331"/>
+ <location filename="../VBoxInternalManage.cpp" line="2018"/>
+ <location filename="../VBoxInternalManage.cpp" line="2027"/>
+ <location filename="../VBoxInternalManage.cpp" line="2088"/>
+ <location filename="../VBoxInternalManage.cpp" line="2251"/>
+ <location filename="../VBoxInternalManage.cpp" line="2260"/>
+ <location filename="../VBoxInternalManage.cpp" line="2385"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="368"/>
+ <location filename="../VBoxInternalManage.cpp" line="1226"/>
+ <location filename="../VBoxInternalManage.cpp" line="1343"/>
+ <location filename="../VBoxInternalManage.cpp" line="2034"/>
+ <location filename="../VBoxInternalManage.cpp" line="2107"/>
+ <location filename="../VBoxInternalManage.cpp" line="2275"/>
+ <location filename="../VBoxInternalManage.cpp" line="2396"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="327"/>
+ <source>
+Syntax error: %N
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="372"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="373"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="376"/>
+ <source>Unknown option: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="378"/>
+ <source>Invalid argument format: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1231"/>
+ <location filename="../VBoxInternalManage.cpp" line="1349"/>
+ <source>Mandatory parameter -rawdisk missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1236"/>
+ <source>Cannot open the raw disk: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1242"/>
+ <source>Number Type StartCHS EndCHS Size (MiB) Start (Sect)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1347"/>
+ <source>Mandatory parameter -filename missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1352"/>
+ <source>The parameter -mbr is only valid when the parameter -partitions is also present</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1361"/>
+ <source>Cannot open the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1390"/>
+ <source>File &apos;%s&apos; is no fixed/removable medium device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1407"/>
+ <source>The -relative parameter is invalid for raw disk %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1421"/>
+ <source>Cannot get the geometry of the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1428"/>
+ <location filename="../VBoxInternalManage.cpp" line="1477"/>
+ <location filename="../VBoxInternalManage.cpp" line="1602"/>
+ <source>The -relative parameter is invalid for raw images</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1462"/>
+ <location filename="../VBoxInternalManage.cpp" line="1556"/>
+ <location filename="../VBoxInternalManage.cpp" line="1627"/>
+ <source>Cannot get the size of the raw disk &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1472"/>
+ <location filename="../VBoxInternalManage.cpp" line="1527"/>
+ <location filename="../VBoxInternalManage.cpp" line="1565"/>
+ <source>Failed to get size of file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1484"/>
+ <source>File &apos;%s&apos; is no block device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1492"/>
+ <location filename="../VBoxInternalManage.cpp" line="1541"/>
+ <location filename="../VBoxInternalManage.cpp" line="1579"/>
+ <location filename="../VBoxInternalManage.cpp" line="1618"/>
+ <source>Failed to get file informtation for raw disk &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1509"/>
+ <source>Cannot get the block size for file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1517"/>
+ <location filename="../VBoxInternalManage.cpp" line="1594"/>
+ <source>Cannot get the block count for file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1533"/>
+ <source>File &apos;%s&apos; is neither block device nor regular file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1571"/>
+ <source>File &apos;%s&apos; is no block or char device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1610"/>
+ <source>File &apos;%s&apos; is neither character device nor regular file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1635"/>
+ <source>Detected size of raw disk &apos;%s&apos; is %RU64, an invalid value</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1667"/>
+ <source>Incorrect value in partitions parameter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1681"/>
+ <source>Incorrect separator in partitions parameter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1691"/>
+ <source>Cannot read the partition information from &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1706"/>
+ <source>It is not possible (and necessary) to explicitly give access to the extended partition %u. If required, enable access to all logical partitions inside this extended partition.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1726"/>
+ <location filename="../VBoxInternalManage.cpp" line="1794"/>
+ <source>Out of memory allocating the partition list for &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1742"/>
+ <source>Out of memory allocating the partition descriptor for &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1751"/>
+ <source>Cannot read partition data from raw device &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1763"/>
+ <source>Cannot open replacement MBR file &apos;%s&apos; specified with -mbr: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1771"/>
+ <source>Cannot read replacement MBR file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1837"/>
+ <source>Cannot create reference to individual partition %u, rc=%Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1852"/>
+ <source>Cannot create reference to individual partition %u (numbered %u), rc=%Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1914"/>
+ <source>MBR/EPT overlaps with data area</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1920"/>
+ <source>GPT overlaps with data area</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1977"/>
+ <source>Cannot create the raw disk VMDK: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="1980"/>
+ <source>RAW host disk access VMDK file %s created successfully.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2002"/>
+ <source>The raw disk vmdk file was not created</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2039"/>
+ <source>Mandatory parameter -from missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2041"/>
+ <source>Mandatory parameter -to missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2065"/>
+ <source>Cannot rename the image: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2068"/>
+ <source>Cannot create the source image: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2112"/>
+ <source>Mandatory filename parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2114"/>
+ <source>Mandatory outputfile parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2142"/>
+ <source>Cannot create destination file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2161"/>
+ <location filename="../VBoxInternalManage.cpp" line="2304"/>
+ <location filename="../VBoxInternalManage.cpp" line="2424"/>
+ <source>No file format specified and autodetect failed - please specify format: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2164"/>
+ <source>Only converting harddisk images is supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2179"/>
+ <location filename="../VBoxInternalManage.cpp" line="2323"/>
+ <source>Cannot open the source image: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxInternalManage.cpp" line="2189"/>
+ <source>Converting image &quot;%s&quot; with size %RU64 bytes (%RU64MB) to raw...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2211"/>
+ <source>Cannot copy image data: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2223"/>
+ <source>Out of memory allocating read buffer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2280"/>
+ <location filename="../VBoxInternalManage.cpp" line="2401"/>
+ <source>Mandatory input image parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2282"/>
+ <source>Mandatory output image parameter missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2315"/>
+ <source>Cannot create the source virtual disk container: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2334"/>
+ <source>Cannot create the destination virtual disk container: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxInternalManage.cpp" line="2339"/>
+ <source>Converting image &quot;%s&quot; with size %RU64 bytes (%RU64MB)...
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2348"/>
+ <source>Cannot copy the image: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2476"/>
+ <location filename="../VBoxInternalManage.cpp" line="2611"/>
+ <source>Missing VM name/UUID</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2576"/>
+ <source>One or more of the requested features are not implemented! Feel free to do this.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2592"/>
+ <source>password to hash required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2598"/>
+ <source>Password hash: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2641"/>
+ <source>Invalid update interval specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2643"/>
+ <source>argc=%d interval=%u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2694"/>
+ <source>Command missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxInternalManage.cpp" line="2734"/>
+ <source>Invalid command &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>List</name>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="54"/>
+ <location filename="../VBoxManageList.cpp" line="68"/>
+ <location filename="../VBoxManageList.cpp" line="94"/>
+ <location filename="../VBoxManageList.cpp" line="853"/>
+ <location filename="../VBoxManageList.cpp" line="864"/>
+ <source>Unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="59"/>
+ <location filename="../VBoxManageList.cpp" line="73"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="66"/>
+ <source>Up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="67"/>
+ <source>Down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="81"/>
+ <source>HardDisk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="83"/>
+ <source>Floppy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="86"/>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="88"/>
+ <source>SharedFolder</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="89"/>
+ <source>Graphics3D</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="111"/>
+ <location filename="../VBoxManageList.cpp" line="149"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="156"/>
+ <location filename="../VBoxManageList.cpp" line="215"/>
+ <location filename="../VBoxManageList.cpp" line="261"/>
+ <location filename="../VBoxManageList.cpp" line="1340"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="162"/>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>Enabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="162"/>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>Disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="166"/>
+ <source>IPAddress: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="169"/>
+ <location filename="../VBoxManageList.cpp" line="225"/>
+ <source>NetworkMask: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="172"/>
+ <source>IPV6Address: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="175"/>
+ <source>IPV6NetworkMaskPrefixLength: %d
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="178"/>
+ <source>HardwareAddress: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="181"/>
+ <source>MediumType: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <source>Wireless: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>Yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="184"/>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>No</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="187"/>
+ <source>Status: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="190"/>
+ <location filename="../VBoxManageList.cpp" line="236"/>
+ <location filename="../VBoxManageList.cpp" line="279"/>
+ <source>VBoxNetworkName: %ls
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="221"/>
+ <location filename="../VBoxManageList.cpp" line="267"/>
+ <source>State: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="228"/>
+ <source>LowerIP: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="231"/>
+ <source>UpperIP: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="271"/>
+ <source>CloudProvider: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="274"/>
+ <source>CloudProfile: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="277"/>
+ <source>CloudNetworkId: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="301"/>
+ <source>HW virtualization</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="303"/>
+ <source>long mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="304"/>
+ <source>nested paging</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="305"/>
+ <source>unrestricted guest</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="306"/>
+ <source>nested HW virtualization</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="307"/>
+ <source>virt. vmsave/vmload</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="313"/>
+ <source>Host Information:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="319"/>
+ <source>Host time: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="323"/>
+ <source>Processor online count: %lu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="326"/>
+ <source>Processor count: %lu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="329"/>
+ <source>Processor online core count: %lu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="332"/>
+ <source>Processor core count: %lu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <source>Processor supports %s: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <location filename="../VBoxManageList.cpp" line="1803"/>
+ <location filename="../VBoxManageList.cpp" line="1808"/>
+ <source>yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="337"/>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <location filename="../VBoxManageList.cpp" line="1803"/>
+ <location filename="../VBoxManageList.cpp" line="1808"/>
+ <source>no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="344"/>
+ <source>Processor#%u speed: %lu MHz
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="346"/>
+ <source>Processor#%u speed: unknown
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="349"/>
+ <source>Processor#%u description: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="354"/>
+ <source>Memory size: %lu MByte
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="358"/>
+ <source>Memory available: %lu MByte
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="362"/>
+ <source>Operating system: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="366"/>
+ <source>Operating system version: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="424"/>
+ <source>Supported hard disk backends:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="443"/>
+ <source>Backend %u: id=&apos;%ls&apos; description=&apos;%ls&apos; capabilities=%#06x extensions=&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="472"/>
+ <source> properties=(</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="477"/>
+ <source>
+ name=&apos;%ls&apos; desc=&apos;%ls&apos; type=</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="481"/>
+ <source>int</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="482"/>
+ <source>byte</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="483"/>
+ <source>string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="488"/>
+ <source> flags=%#04x</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="489"/>
+ <source> default=&apos;%ls&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="515"/>
+ <source>Host USB Devices:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="519"/>
+ <location filename="../VBoxManageList.cpp" line="657"/>
+ <source>&lt;none&gt;
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="543"/>
+ <source>UUID: %s
+VendorId: %#06x (%04X)
+ProductId: %#06x (%04X)
+Revision: %u.%u (%02u%02u)
+Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="559"/>
+ <source>Low</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="562"/>
+ <source>Full</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="565"/>
+ <source>High</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="568"/>
+ <source>Super</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="571"/>
+ <source>SuperPlus</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="578"/>
+ <source>USB version/speed: %u/%s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="587"/>
+ <source>Manufacturer: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="591"/>
+ <source>Product: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="594"/>
+ <source>SerialNumber: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="597"/>
+ <source>Address: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="600"/>
+ <source>Port path: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="609"/>
+ <source>Not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="612"/>
+ <source>Unavailable</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="615"/>
+ <source>Busy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="618"/>
+ <source>Available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="621"/>
+ <source>Held</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="624"/>
+ <source>Captured</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="630"/>
+ <source>Current State: %s
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="647"/>
+ <source>Global USB Device Filters:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="667"/>
+ <source>Index: %zu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="671"/>
+ <source>Active: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="675"/>
+ <source>&lt;invalid&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="679"/>
+ <source>Ignore</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="682"/>
+ <source>Hold</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="687"/>
+ <source>Action: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="691"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="693"/>
+ <source>VendorId: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="695"/>
+ <source>ProductId: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="697"/>
+ <source>Revision: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="699"/>
+ <source>Manufacturer: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="701"/>
+ <source>Product: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="703"/>
+ <source>Serial Number: %ls
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="728"/>
+ <source>API version: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="731"/>
+ <source>Minimum guest RAM size: %u Megabytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="733"/>
+ <source>Maximum guest RAM size: %u Megabytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="735"/>
+ <source>Minimum video RAM size: %u Megabytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="737"/>
+ <source>Maximum video RAM size: %u Megabytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="739"/>
+ <source>Maximum guest monitor count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="741"/>
+ <source>Minimum guest CPU count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="743"/>
+ <source>Maximum guest CPU count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="745"/>
+ <source>Virtual disk limit (info): %lld Bytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="747"/>
+ <source>Maximum Serial Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="749"/>
+ <source>Maximum Parallel Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="751"/>
+ <source>Maximum Boot Position: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="753"/>
+ <source>Maximum PIIX3 Network Adapter count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="755"/>
+ <source>Maximum ICH9 Network Adapter count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="757"/>
+ <source>Maximum PIIX3 IDE Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="759"/>
+ <source>Maximum ICH9 IDE Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="761"/>
+ <source>Maximum IDE Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="763"/>
+ <source>Maximum Devices per IDE Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="765"/>
+ <source>Maximum PIIX3 SATA Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="767"/>
+ <source>Maximum ICH9 SATA Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="769"/>
+ <source>Maximum SATA Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="771"/>
+ <source>Maximum Devices per SATA Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="773"/>
+ <source>Maximum PIIX3 SCSI Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="775"/>
+ <source>Maximum ICH9 SCSI Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="777"/>
+ <source>Maximum SCSI Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="779"/>
+ <source>Maximum Devices per SCSI Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="781"/>
+ <source>Maximum SAS PIIX3 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="783"/>
+ <source>Maximum SAS ICH9 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="785"/>
+ <source>Maximum SAS Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="787"/>
+ <source>Maximum Devices per SAS Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="789"/>
+ <source>Maximum NVMe PIIX3 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="791"/>
+ <source>Maximum NVMe ICH9 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="793"/>
+ <source>Maximum NVMe Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="795"/>
+ <source>Maximum Devices per NVMe Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="797"/>
+ <source>Maximum virtio-scsi PIIX3 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="799"/>
+ <source>Maximum virtio-scsi ICH9 Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="801"/>
+ <source>Maximum virtio-scsi Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="803"/>
+ <source>Maximum Devices per virtio-scsi Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="805"/>
+ <source>Maximum PIIX3 Floppy Controllers:%u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="807"/>
+ <source>Maximum ICH9 Floppy Controllers: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="809"/>
+ <source>Maximum Floppy Port count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="811"/>
+ <source>Maximum Devices per Floppy Port: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="814"/>
+ <source>Free disk space warning at: %u Bytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="816"/>
+ <source>Free disk space warning at: %u %%
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="818"/>
+ <source>Free disk space error at: %u Bytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="820"/>
+ <source>Free disk space error at: %u %%
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="823"/>
+ <source>Default machine folder: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="825"/>
+ <source>Raw-mode Supported: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <source>Exclusive HW virtualization use: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <location filename="../VBoxManageList.cpp" line="1867"/>
+ <location filename="../VBoxManageList.cpp" line="1871"/>
+ <source>on</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="827"/>
+ <location filename="../VBoxManageList.cpp" line="1867"/>
+ <location filename="../VBoxManageList.cpp" line="1871"/>
+ <source>off</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="829"/>
+ <source>Default hard disk format: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="831"/>
+ <source>VRDE auth library: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="833"/>
+ <source>Webservice auth. library: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="835"/>
+ <source>Remote desktop ExtPack: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="837"/>
+ <source>Log history count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="839"/>
+ <source>Default frontend: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="844"/>
+ <source>Null</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="855"/>
+ <source>Default audio driver: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="857"/>
+ <source>Autostart database path: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="859"/>
+ <source>Default Guest Additions ISO: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="861"/>
+ <source>Logging Level: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="867"/>
+ <source>System</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="868"/>
+ <source>NoProxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="869"/>
+ <source>Manual</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="874"/>
+ <source>Proxy Mode: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="876"/>
+ <source>Proxy URL: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="908"/>
+ <source>Stable: new minor and maintenance releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="911"/>
+ <source>All releases: new minor, maintenance, and major releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="914"/>
+ <source>With Betas: new minor, maintenance, major, and beta releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="917"/>
+ <source>Unset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="924"/>
+ <source>Last check date: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="879"/>
+ <source>User language: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="889"/>
+ <source>Enabled: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="892"/>
+ <source>Check count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="895"/>
+ <source>Check frequency: never
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="897"/>
+ <source>Check frequency: every day
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="899"/>
+ <source>Check frequency: every %u days
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="920"/>
+ <source>Channel: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="922"/>
+ <source>Repository: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="952"/>
+ <source> minLeaseTime: default
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="954"/>
+ <source> minLeaseTime: %u sec
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="959"/>
+ <source> defaultLeaseTime: default
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="961"/>
+ <source> defaultLeaseTime: %u sec
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="966"/>
+ <source> maxLeaseTime: default
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="968"/>
+ <source> maxLeaseTime: %u sec
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="974"/>
+ <source> Forced options: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="976"/>
+ <source> Forced options: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="979"/>
+ <source> Forced options: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="987"/>
+ <source> Suppressed opt.s: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="989"/>
+ <source> Suppressed opts.: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="992"/>
+ <source> Suppressed opts.: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1004"/>
+ <source> DHCP options: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1007"/>
+ <source> DHCP options: Return count mismatch: %zu, %zu, %zu
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1012"/>
+ <source> DHCP options: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1019"/>
+ <source> %3d/legacy: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1053"/>
+ <source>NetworkName: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1059"/>
+ <source>LowerIPAddress: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1062"/>
+ <source>UpperIPAddress: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1065"/>
+ <source>NetworkMask: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1069"/>
+ <source>Enabled: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1072"/>
+ <source>Global Configuration:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1087"/>
+ <source>Groups: %Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1089"/>
+ <source>Groups: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1095"/>
+ <source>Group: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1100"/>
+ <source> Conditions: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1102"/>
+ <source> Conditions: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1112"/>
+ <source> Conditions: %s %s %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1113"/>
+ <source>include</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1113"/>
+ <source>exclude</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1135"/>
+ <source>Individual Configs: %Rrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1137"/>
+ <source>Individual Configs: None
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1148"/>
+ <source>Individual Config: MAC %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1158"/>
+ <source>Individual Config: VM NIC: %ls slot %u, MAC %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1161"/>
+ <source>Individual Config: VM NIC: %ls slot %u, MAC %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1166"/>
+ <source> Fixed Address: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1168"/>
+ <source> Fixed Address: dynamic
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1194"/>
+ <source>Extension Packs: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1220"/>
+ <source>Pack no.%2zu: %ls
+Version: %ls
+Revision: %u
+Edition: %ls
+Description: %ls
+VRDE Module: %ls
+Usable: %RTbool
+Why unusable: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1276"/>
+ <source>Video Input Devices: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1305"/>
+ <source>Supported %d screen shot formats:
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1334"/>
+ <source>Supported %d cloud providers:
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1342"/>
+ <source>Short Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1378"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1381"/>
+ <source>Provider GUID: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1397"/>
+ <source>Property: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1435"/>
+ <source>CPU Profile #%02zu:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1436"/>
+ <source> Architecture: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1437"/>
+ <source> Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1439"/>
+ <source> Full Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1689"/>
+ <source>%sDrive: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1691"/>
+ <source>%sDrive: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1696"/>
+ <source>Model: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1698"/>
+ <source>Model: &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1700"/>
+ <source>Model: unknown/inaccessible
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1710"/>
+ <source>Further disk and partitioning information is not available for drive &quot;%ls&quot;. (E_ACCESSDENIED)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1723"/>
+ <source>Size: %llu bytes (%Rhcb)
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1725"/>
+ <source>Size: %Rhcb
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1728"/>
+ <source>Size: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageList.cpp" line="1735"/>
+ <source>Sector Size: %u bytes
+</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1738"/>
+ <source>Sector Size: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1745"/>
+ <source>Scheme: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1748"/>
+ <source>Scheme: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1756"/>
+ <source>Partitions: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1760"/>
+ <source>Partitions: None (or not able to grok them).
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1764"/>
+ <source>Partitions: First Last
+## Type Byte Size Byte Offset Cyl/Head/Sec Cyl/Head/Sec Active
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1767"/>
+ <source>Partitions: First Last
+## Type Size Start Cyl/Head/Sec Cyl/Head/Sec Active
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1826"/>
+ <source>Partitions:
+## %-*s Uuid Byte Size Byte Offset Active Name
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1829"/>
+ <location filename="../VBoxManageList.cpp" line="1834"/>
+ <source>Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="1831"/>
+ <source>Partitions:
+## %-*s Uuid Size Start Active Name
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2043"/>
+ <source>Description: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2046"/>
+ <source>Family ID: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2049"/>
+ <source>Family Desc: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2052"/>
+ <source>64 bit: %RTbool
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2075"/>
+ <location filename="../VBoxManageList.cpp" line="2097"/>
+ <source>Name: %ls
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2134"/>
+ <source>Host CPUIDs:
+
+Leaf no. EAX EBX ECX EDX
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2166"/>
+ <source>base</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2388"/>
+ <source>Unknown subcommand &quot;%s&quot;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageList.cpp" line="2399"/>
+ <source>Missing subcommand for &quot;list&quot; command.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Metrics</name>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="90"/>
+ <source>Invalid machine name: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="128"/>
+ <source>host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="138"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="149"/>
+ <source>The following metrics were modified:
+
+Object Metric
+---------- --------------------
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="163"/>
+ <source>No metrics match the specified filter!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="197"/>
+ <source>Object Metric Unit Minimum Maximum Period Count Description
+--------------- ---------------------------------------- ---- ---------- ---------- ---------- ---------- -----------
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="240"/>
+ <location filename="../VBoxManageMetrics.cpp" line="249"/>
+ <location filename="../VBoxManageMetrics.cpp" line="412"/>
+ <location filename="../VBoxManageMetrics.cpp" line="421"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="243"/>
+ <location filename="../VBoxManageMetrics.cpp" line="415"/>
+ <source>Invalid value for &apos;period&apos; parameter: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="252"/>
+ <location filename="../VBoxManageMetrics.cpp" line="424"/>
+ <source>Invalid value for &apos;samples&apos; parameter: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="319"/>
+ <source>Object Metric Values
+--------------- ---------------------------------------- --------------------------------------------
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="483"/>
+ <source>The background process holding collected metrics will shutdown
+in few seconds, discarding all collected data and parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="492"/>
+ <source>Time stamp Object Metric Value
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="639"/>
+ <source>Subcommand missing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMetrics.cpp" line="658"/>
+ <source>Invalid subcommand &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Misc</name>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="66"/>
+ <location filename="../VBoxManageMisc.cpp" line="760"/>
+ <location filename="../VBoxManageMisc.cpp" line="789"/>
+ <location filename="../VBoxManageMisc.cpp" line="824"/>
+ <location filename="../VBoxManageMisc.cpp" line="950"/>
+ <source>Incorrect number of parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="79"/>
+ <location filename="../VBoxManageMisc.cpp" line="799"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="125"/>
+ <location filename="../VBoxManageMisc.cpp" line="354"/>
+ <location filename="../VBoxManageMisc.cpp" line="530"/>
+ <location filename="../VBoxManageMisc.cpp" line="1075"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="132"/>
+ <location filename="../VBoxManageMisc.cpp" line="683"/>
+ <source>Invalid option -%c</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="133"/>
+ <location filename="../VBoxManageMisc.cpp" line="685"/>
+ <source>Invalid option case %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="136"/>
+ <location filename="../VBoxManageMisc.cpp" line="688"/>
+ <source>unknown option: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="139"/>
+ <location filename="../VBoxManageMisc.cpp" line="692"/>
+ <source>error: %Rrs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="145"/>
+ <location filename="../VBoxManageMisc.cpp" line="370"/>
+ <location filename="../VBoxManageMisc.cpp" line="540"/>
+ <source>VM name required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="162"/>
+ <source>Machine delete failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="256"/>
+ <source>Parameter --name is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="298"/>
+ <source>Virtual machine &apos;%ls&apos; is created%s.
+UUID: %s
+Settings file: &apos;%ls&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="301"/>
+ <source> and registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="343"/>
+ <location filename="../VBoxManageMisc.cpp" line="1388"/>
+ <source>RTPathAbs(%s,,) failed with rc=%Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="394"/>
+ <source>Move VM failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="399"/>
+ <source>Machine has been successfully moved into %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="400"/>
+ <source>the same location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="510"/>
+ <source>Invalid clone mode &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="515"/>
+ <source>Invalid clone options &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="562"/>
+ <source>%s Clone</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="596"/>
+ <source>Clone VM failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="603"/>
+ <source>Machine has been successfully cloned as &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="672"/>
+ <source>Parameter to option --putenv must not contain any newline character</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="698"/>
+ <source>at least one VM name or uuid required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="716"/>
+ <source>Waiting for VM &quot;%s&quot; to power on...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="731"/>
+ <source>VM &quot;%s&quot; has been successfully started.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="844"/>
+ <location filename="../VBoxManageMisc.cpp" line="880"/>
+ <source>Key: %ls, Value: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="853"/>
+ <location filename="../VBoxManageMisc.cpp" line="889"/>
+ <source>Value: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="855"/>
+ <location filename="../VBoxManageMisc.cpp" line="891"/>
+ <source>No value set!
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="903"/>
+ <location filename="../VBoxManageMisc.cpp" line="1315"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="916"/>
+ <location filename="../VBoxManageMisc.cpp" line="938"/>
+ <source>Too many parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="972"/>
+ <source>Invalid hwvirtexclusive argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="979"/>
+ <source>Warning: &apos;vrdpauthlibrary&apos; is deprecated. Use &apos;vrdeauthlibrary&apos;.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1009"/>
+ <source>Error parsing Log history count &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1044"/>
+ <source>Unknown proxy mode: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1138"/>
+ <location filename="../VBoxManageMisc.cpp" line="1250"/>
+ <source>Machine name is given more than once: first &apos;%s&apos;, then &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1148"/>
+ <location filename="../VBoxManageMisc.cpp" line="1260"/>
+ <source>No machine was specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1151"/>
+ <location filename="../VBoxManageMisc.cpp" line="1262"/>
+ <source>No shared folder name (--name) was given</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1153"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains space</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1155"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains tabs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1157"/>
+ <source>Invalid shared folder name &apos;%s&apos;: contains newline</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1160"/>
+ <source>No host path (--hostpath) was given</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1164"/>
+ <source>RTAbsPath failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1187"/>
+ <source>Machine &apos;%s&apos; is not currently running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1283"/>
+ <source>Machine &apos;%s&apos; is not currently running.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1374"/>
+ <location filename="../VBoxManageMisc.cpp" line="1459"/>
+ <source>Too many extension pack names given to &quot;extpack uninstall&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1383"/>
+ <source>No extension pack name was given to &quot;extpack install&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1412"/>
+ <source>License accepted.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1416"/>
+ <source>Do you agree to these license terms and conditions (y/n)? </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1421"/>
+ <source>Installation of &quot;%ls&quot; aborted.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1425"/>
+ <source>License accepted. For batch installation add
+--accept-license=%s
+to the VBoxManage command line.
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1433"/>
+ <source>Failed to install &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1435"/>
+ <source>Successfully installed &quot;%ls&quot;.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1468"/>
+ <source>No extension pack name was given to &quot;extpack uninstall&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1474"/>
+ <source>Failed to uninstall &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1476"/>
+ <source>Successfully uninstalled &quot;%s&quot;.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1484"/>
+ <source>Successfully performed extension pack cleanup
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1526"/>
+ <location filename="../VBoxManageMisc.cpp" line="1679"/>
+ <location filename="../VBoxManageMisc.cpp" line="1718"/>
+ <location filename="../VBoxManageMisc.cpp" line="1731"/>
+ <location filename="../VBoxManageMisc.cpp" line="1766"/>
+ <location filename="../VBoxManageMisc.cpp" line="1777"/>
+ <location filename="../VBoxManageMisc.cpp" line="1784"/>
+ <source>RTPathAbs failed on &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1542"/>
+ <source>No ISO specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1587"/>
+ <source>Detected &apos;%s&apos; to be:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1588"/>
+ <source> OS TypeId = %ls
+ OS Version = %ls
+ OS Flavor = %ls
+ OS Languages = %ls
+ OS Hints = %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1671"/>
+ <source>VM name/UUID given more than once!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1813"/>
+ <source>Missing VM name/UUID</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1865"/>
+ <source>Machine &apos;%ls&apos; is currently running</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1871"/>
+ <source>%s unattended installation of %s in machine &apos;%ls&apos; (%ls).
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1872"/>
+ <source>Preparing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1872"/>
+ <source>Starting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1885"/>
+ <source>Using values:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1892"/>
+ <location filename="../VBoxManageMisc.cpp" line="1900"/>
+ <location filename="../VBoxManageMisc.cpp" line="1952"/>
+ <source> %32s = failed: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1955"/>
+ <source> %32 = failed: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1971"/>
+ <source>VM &apos;%ls&apos; (%ls) is ready to be started (e.g. VBoxManage startvm).
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="1990"/>
+ <source>Waiting for VM &apos;%ls&apos; to power on...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2005"/>
+ <source>VM &apos;%ls&apos; (%ls) has been successfully started.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2137"/>
+ <location filename="../VBoxManageMisc.cpp" line="2187"/>
+ <location filename="../VBoxManageMisc.cpp" line="2247"/>
+ <location filename="../VBoxManageMisc.cpp" line="2345"/>
+ <source>Parameter --provider is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2139"/>
+ <location filename="../VBoxManageMisc.cpp" line="2189"/>
+ <location filename="../VBoxManageMisc.cpp" line="2249"/>
+ <location filename="../VBoxManageMisc.cpp" line="2347"/>
+ <source>Parameter --profile is required</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2168"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was updated.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2210"/>
+ <source>Provider GUID: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2226"/>
+ <source>Property: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2331"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was added.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageMisc.cpp" line="2374"/>
+ <source>Provider %ls: profile &apos;%ls&apos; was deleted.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ModifyVM</name>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="467"/>
+ <source>Warning: &apos;--vrdp%s&apos; is deprecated. Use &apos;--vrde%s&apos;.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="578"/>
+ <source>Invalid %s number %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="607"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2089"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="670"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="678"/>
+ <source>Cannot get size of file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="684"/>
+ <source>File &quot;%s&quot; is bigger than 256KByte</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="692"/>
+ <source>Cannot read contents of file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="743"/>
+ <source>Invalid --firmware argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="814"/>
+ <source>Invalid --paravirtprovider argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="841"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="1989"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2381"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2460"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2503"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="2939"/>
+ <source>Missing or invalid argument to &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="985"/>
+ <source>Invalid --graphicscontroller argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1051"/>
+ <source>Invalid --biosbootmenu argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1075"/>
+ <source>Invalid --biosapic argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1122"/>
+ <source>Invalid boot device &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1202"/>
+ <source>Invalid --idecontroller argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1232"/>
+ <source>Invalid --usb argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1307"/>
+ <source>Invalid --scsitype argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1362"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="1370"/>
+ <source>Invalid host DVD drive name &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1436"/>
+ <source>Invalid host floppy drive name &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1516"/>
+ <source>Invalid --nicproperty%d argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1523"/>
+ <source>Error: Failed to allocate memory for --nicproperty%d &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1597"/>
+ <source>Invalid NIC type &apos;%s&apos; specified for NIC %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1632"/>
+ <source>Invalid boot priority &apos;%u&apos; specfied for NIC %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1654"/>
+ <source>Unknown promiscuous mode policy &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="1789"/>
+ <source>Invalid type &apos;%s&apos; specfied for NIC %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2073"/>
+ <source>Invalid proto &apos;%s&apos; specfied for NIC %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2291"/>
+ <source>Invalid type &apos;%s&apos; specfied for pointing device</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2336"/>
+ <source>Invalid type &apos;%s&apos; specfied for keyboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2439"/>
+ <source>Invalid argument to &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2467"/>
+ <source>Error parsing UART I/O base &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2510"/>
+ <source>Error parsing LPT I/O base &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2539"/>
+ <source>Invalid --audiocontroller argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2561"/>
+ <source>Invalid --audiocodec argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2633"/>
+ <source>Invalid --audio argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2673"/>
+ <source>Invalid --clipboard-mode argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2693"/>
+ <source>Invalid --clipboard-file-transfers argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2718"/>
+ <source>Invalid --draganddrop argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2772"/>
+ <source>Invalid --vrdeproperty argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2780"/>
+ <source>Error: Failed to allocate memory for VRDE property &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2842"/>
+ <source>Invalid --vrdeauthtype argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="2960"/>
+ <source>Invalid --usbrename parameters, nothing renamed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3164"/>
+ <source>*** I/O APIC must be enabled for ICH9, enabling. ***
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3170"/>
+ <source>Invalid --chipset argument &apos;%s&apos; (valid: piix3,ich9)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3188"/>
+ <source>Invalid --iommu argument &apos;%s&apos; (valid: none,amd,automatic)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3197"/>
+ <source>Warning: On Intel hosts, &apos;automatic&apos; will not enable an IOMMU since the Intel IOMMU device is not supported yet.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3202"/>
+ <source>Invalid --iommu argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3227"/>
+ <source>Invalid --tpm-type argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3284"/>
+ <source>Invalid list of screens specified
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3306"/>
+ <source>Cannot convert filename &quot;%s&quot; to absolute path
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3336"/>
+ <location filename="../VBoxManageModifyVM.cpp" line="3345"/>
+ <source>Error parsing video resolution &apos;%s&apos; (expected &lt;width&gt;x&lt;height&gt;)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3420"/>
+ <source>Invalid --autostop-type argument &apos;%s&apos; (valid: disabled, savestate, poweroff, acpishutdown)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3440"/>
+ <source>Invalid --pciattach argument &apos;%s&apos; (valid: &apos;HB:HD.HF@GB:GD.GF&apos; or just &apos;HB:HD.HF&apos;)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3458"/>
+ <source>Invalid --pcidetach argument &apos;%s&apos; (valid: &apos;HB:HD.HF&apos;)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3492"/>
+ <source>Invalid --vm-process-priority &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyVM.cpp" line="3521"/>
+ <source>--testing-cfg-dword index %u is out of range: 0 thru 9</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Nat</name>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="96"/>
+ <source>Name: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="110"/>
+ <source>Network: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="113"/>
+ <source>Gateway: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="119"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>Yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="119"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>No</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="122"/>
+ <source>IPv6 Prefix: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="125"/>
+ <source>IPv6 Default: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="106"/>
+ <source>Enabled: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="116"/>
+ <source>DHCP Server: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="142"/>
+ <source>Port-forwarding (ipv4)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="146"/>
+ <source>Port-forwarding (ipv6)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="150"/>
+ <source>loopback mappings (ipv4)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="166"/>
+ <source>NAT Networks:
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>%zu %s found
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../VBoxManageNATNetwork.cpp" line="198"/>
+ <source>networks</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="206"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="602"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="261"/>
+ <source>You can only specify --netname only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="267"/>
+ <source>You can only specify --network only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="273"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="279"/>
+ <source>You can specify either --enable or --disable once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="285"/>
+ <source>You can specify --dhcp only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="291"/>
+ <source>You can specify --ipv6 only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="297"/>
+ <source>You can specify --ipv6-prefix only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="303"/>
+ <source>You can specify --ipv6-default only once.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="313"/>
+ <source>loopback couldn&apos;t be deleted on modified
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="324"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="362"/>
+ <source>Not enough parŠ°meters
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="349"/>
+ <source>Invalid port-forward rule %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="357"/>
+ <source>Port-forward could be deleted on modify
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="365"/>
+ <source>Port-forward rule name is too long
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="382"/>
+ <source>You need to specify the --netname option</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="388"/>
+ <source>You need to specify the --network option</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="396"/>
+ <source>Unknown operation (:%d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="408"/>
+ <source>NATNetwork server already exists</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="412"/>
+ <source>Failed to create the NAT network service</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="415"/>
+ <source>NATNetwork server does not exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="426"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="432"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="444"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="451"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="462"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="470"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="565"/>
+ <source>Failed to set configuration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="481"/>
+ <source>Failed to delete pf</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="506"/>
+ <source>Failed to add pf</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="532"/>
+ <location filename="../VBoxManageNATNetwork.cpp" line="538"/>
+ <source>invalid loopback string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="573"/>
+ <source>Failed to remove nat network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="580"/>
+ <source>Failed to start network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="587"/>
+ <source>Failed to stop network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageNATNetwork.cpp" line="636"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Nvram</name>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="121"/>
+ <source>No platform key file path was given to &quot;enrollpk&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="123"/>
+ <source>No owner UUID was given to &quot;enrollpk&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="147"/>
+ <source>Cannot read contents of file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="150"/>
+ <source>File &quot;%s&quot; is bigger than 32KByte</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="153"/>
+ <source>Cannot get size of file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="158"/>
+ <source>Cannot open file &quot;%s&quot;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="250"/>
+ <source>No variable name was given to &quot;queryvar&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="277"/>
+ <source>Error writing to &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="282"/>
+ <location filename="../VBoxManageModifyNvram.cpp" line="411"/>
+ <source>Error opening &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="329"/>
+ <source>No variable name was given to &quot;deletevar&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="331"/>
+ <source>No owner UUID was given to &quot;deletevar&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="381"/>
+ <source>No variable name was given to &quot;changevar&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="383"/>
+ <source>No variable data filename was given to &quot;changevar&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageModifyNvram.cpp" line="407"/>
+ <source>Error reading from &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Snapshot</name>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="198"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="520"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="594"/>
+ <source>This machine does not have any snapshots
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="254"/>
+ <source>[%RI32] Images and snapshots for medium &quot;%ls&quot;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="329"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="359"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="561"/>
+ <source>Missing snapshot name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="404"/>
+ <source>Invalid unique name description &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="467"/>
+ <source>Failed to generate a unique snapshot name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="483"/>
+ <source>Snapshot taken. UUID: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="485"/>
+ <source>Failed to take snapshot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="500"/>
+ <source>Too many arguments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="508"/>
+ <location filename="../VBoxManageSnapshot.cpp" line="628"/>
+ <source>Expecting snapshot name only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="539"/>
+ <source>%s snapshot &apos;%ls&apos; (%ls)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="540"/>
+ <source>Deleting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="540"/>
+ <source>Restoring</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="554"/>
+ <source>Snapshot operation failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageSnapshot.cpp" line="652"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Storage</name>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="166"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1180"/>
+ <source>Invalid --type argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="305"/>
+ <source>Invalid medium type &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="327"/>
+ <source>Storage controller name not specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="347"/>
+ <source>Drive passthrough state cannot be changed while the VM is running
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="349"/>
+ <source>Bandwidth group cannot be changed while the VM is running
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="356"/>
+ <source>Could not find a controller named &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="370"/>
+ <source>Port not specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="377"/>
+ <source>Device not specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="441"/>
+ <source>No DVD/Floppy Drive attached to the controller &apos;%s&apos;at the port: %u, device: %u</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="461"/>
+ <source>The attachment is not supported by the storage controller &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="516"/>
+ <source>Cannot find the Guest Additions ISO image
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="542"/>
+ <source>Argument --type must be specified
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="556"/>
+ <source>The given attachment is not supported by the storage controller &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="578"/>
+ <location filename="../VBoxManageStorageController.cpp" line="582"/>
+ <source>Invalid host DVD drive name &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="591"/>
+ <source>Invalid host floppy drive name &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="598"/>
+ <source>Parameters --server and --target are required for iSCSI media</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="665"/>
+ <source>iSCSI disk created. UUID: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="676"/>
+ <source>Missing --medium argument</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="685"/>
+ <source>Invalid UUID or filename &quot;%s&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="695"/>
+ <source>Failed to set the medium/parent medium UUID</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="709"/>
+ <source>Failed to set the medium type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="804"/>
+ <source>Invalid --passthrough argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="807"/>
+ <location filename="../VBoxManageStorageController.cpp" line="833"/>
+ <location filename="../VBoxManageStorageController.cpp" line="859"/>
+ <location filename="../VBoxManageStorageController.cpp" line="885"/>
+ <location filename="../VBoxManageStorageController.cpp" line="911"/>
+ <source>Couldn&apos;t find the controller attachment for the controller &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="830"/>
+ <source>Invalid --tempeject argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="856"/>
+ <source>Invalid --nonrotational argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="882"/>
+ <source>Invalid --discard argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="908"/>
+ <source>Invalid --hotpluggable argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="990"/>
+ <source>Too few parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1056"/>
+ <source>Storage controller name not specified
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1119"/>
+ <source>Invalid --add argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1186"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1205"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1236"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1262"/>
+ <location filename="../VBoxManageStorageController.cpp" line="1281"/>
+ <source>Couldn&apos;t find the controller with the name: &apos;%s&apos;
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1230"/>
+ <source>Invalid --hostiocache argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageStorageController.cpp" line="1256"/>
+ <source>Invalid --bootable argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>UpdateCheck</name>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="81"/>
+ <source>Enabled: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="82"/>
+ <source>yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="82"/>
+ <source>no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="89"/>
+ <source>Count: %u
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="99"/>
+ <source>Frequency: never
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="101"/>
+ <source>Frequency: every day
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="103"/>
+ <source>Frequency: every %u days
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="112"/>
+ <source>Stable - new minor and maintenance releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="116"/>
+ <source>All releases - new minor, maintenance, and major releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="120"/>
+ <source>With Betas - new minor, maintenance, major, and beta releases</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="125"/>
+ <source>Unset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="132"/>
+ <source>Channel: %s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="189"/>
+ <source>Unknown channel specified: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="258"/>
+ <source>Checking for a new %ls version...
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="269"/>
+ <source>Failed to create update progress object: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="277"/>
+ <source>Checking for update failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="296"/>
+ <source>A new version of %ls has been released! Version %ls is available at virtualbox.org.
+You can download this version here: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="312"/>
+ <source>You are already running the most recent version of %ls.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="324"/>
+ <source>Something went wrong while checking for updates!
+Please check network connection and try again later.
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="140"/>
+ <source>Last Check Date: %ls
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="195"/>
+ <source>The update frequency cannot be zero</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUpdateCheck.cpp" line="206"/>
+ <source>No change requested</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Usb</name>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="178"/>
+ <location filename="../VBoxManageUSB.cpp" line="214"/>
+ <location filename="../VBoxManageUSB.cpp" line="216"/>
+ <location filename="../VBoxManageUSB.cpp" line="373"/>
+ <location filename="../VBoxManageUSB.cpp" line="571"/>
+ <source>Not enough parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="199"/>
+ <source>Invalid parameter &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="203"/>
+ <source>Invalid index &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="231"/>
+ <location filename="../VBoxManageUSB.cpp" line="246"/>
+ <location filename="../VBoxManageUSB.cpp" line="254"/>
+ <location filename="../VBoxManageUSB.cpp" line="267"/>
+ <location filename="../VBoxManageUSB.cpp" line="275"/>
+ <location filename="../VBoxManageUSB.cpp" line="283"/>
+ <location filename="../VBoxManageUSB.cpp" line="291"/>
+ <location filename="../VBoxManageUSB.cpp" line="299"/>
+ <location filename="../VBoxManageUSB.cpp" line="307"/>
+ <location filename="../VBoxManageUSB.cpp" line="315"/>
+ <location filename="../VBoxManageUSB.cpp" line="323"/>
+ <location filename="../VBoxManageUSB.cpp" line="336"/>
+ <location filename="../VBoxManageUSB.cpp" line="381"/>
+ <source>Missing argument to &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="261"/>
+ <source>Invalid --active argument &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="328"/>
+ <source>Failed to convert the --maskedinterfaces value &apos;%s&apos; to a number, vrc=%Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="343"/>
+ <source>Invalid USB filter action &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="346"/>
+ <source>Unknown option &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="363"/>
+ <location filename="../VBoxManageUSB.cpp" line="395"/>
+ <source>Mandatory options not supplied</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="581"/>
+ <source>Invalid number of parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUSB.cpp" line="596"/>
+ <source>Parameter &quot;%s&quot; is invalid</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Utils</name>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="102"/>
+ <source>type bridged</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="106"/>
+ <source>type host-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="111"/>
+ <source>unknown type %RU32</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="116"/>
+ <source>Interface &quot;%s&quot; is of %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManageUtils.cpp" line="120"/>
+ <source>Interface &quot;%s&quot; doesn&apos;t seem to exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>VBoxManage</name>
+ <message>
+ <location filename="../VBoxManage.cpp" line="327"/>
+ <location filename="../VBoxManage.cpp" line="495"/>
+ <source>Progress object failure: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="344"/>
+ <source>Failed to get progress description: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="411"/>
+ <source>(%u/%u) %ls %02u%% =&gt; %02u%% (%d s remaining)
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="481"/>
+ <source>CANCELED
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="485"/>
+ <source>Progress state: %Rhrc
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="672"/>
+ <source>Password expected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="680"/>
+ <source>No password file specified</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="687"/>
+ <source>Only one response file allowed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="695"/>
+ <source>Error reading response file &apos;%s&apos;: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="700"/>
+ <source>Invalid response file (&apos;%s&apos;) encoding: %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="708"/>
+ <source>Failed to parse response file &apos;%s&apos; (bourne shell style): %Rrc</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="714"/>
+ <source>out of memory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="755"/>
+ <source>commands:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="762"/>
+ <source>Invalid command &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="781"/>
+ <source>Failed to initialize COM because the global settings directory &apos;%s&apos; is not accessible!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="784"/>
+ <source>Failed to initialize COM! (hrc=%Rhrc)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="867"/>
+ <source>Failed to create a session object!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="877"/>
+ <source>Failed to create the VirtualBox object!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../VBoxManage.cpp" line="881"/>
+ <source>Most likely, the VirtualBox COM server is not running or failed to start.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>