VBoxManage.cpp revision 230bd8589bba39933ac5ec21482d6186d675e604
1633838b8255282d10af15c5c84cee5a51466712Bob Halley/* $Id$ */
a7c412f37cc73d0332887a746e81220cbf09dd00Mark Andrews/** @file
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * VBoxManage - VirtualBox's command-line interface.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater
1633838b8255282d10af15c5c84cee5a51466712Bob Halley/*
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * Copyright (C) 2006-2010 Oracle Corporation
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * This file is part of VirtualBox Open Source Edition (OSE), as
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * available from http://www.virtualbox.org. This file is free software;
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * you can redistribute it and/or modify it under the terms of the GNU
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * General Public License (GPL) as published by the Free Software
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Foundation, in version 2 as it comes in the "COPYING" file of the
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley */
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*******************************************************************************
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein* Header Files *
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence*******************************************************************************/
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley#ifndef VBOX_ONLY_DOCS
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley# include <VBox/com/com.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley# include <VBox/com/string.h>
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence# include <VBox/com/Guid.h>
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt# include <VBox/com/array.h>
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews# include <VBox/com/ErrorInfo.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence# include <VBox/com/errorprint.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley# include <VBox/com/EventQueue.h>
6e3a8256eed85f6704861d269ccfb35bdaeed5ffDavid Lawrence
6e3a8256eed85f6704861d269ccfb35bdaeed5ffDavid Lawrence# include <VBox/com/VirtualBox.h>
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#endif /* !VBOX_ONLY_DOCS */
33f87146a856eb6c3dfd55a8ee9c173c94f82150Andreas Gustafsson
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews#include <VBox/err.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <VBox/version.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <iprt/asm.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley#include <iprt/buildconfig.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <iprt/initterm.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <iprt/stream.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <iprt/string.h>
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence#include <signal.h>
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence#include "VBoxManage.h"
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence/*******************************************************************************
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence* Global Variables *
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews*******************************************************************************/
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews/*extern*/ bool g_fDetailedProgress = false;
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#ifndef VBOX_ONLY_DOCS
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/** Set by the signal handler. */
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleystatic volatile bool g_fCanceled = false;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrews/**
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrews * Signal handler that sets g_fCanceled.
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley *
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * This can be executed on any thread in the process, on Windows it may even be
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * a thread dedicated to delivering this signal. Do not doing anything
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * unnecessary here.
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews */
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrewsstatic void showProgressSignalHandler(int iSignal)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews{
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews NOREF(iSignal);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews ASMAtomicWriteBool(&g_fCanceled, true);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews}
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews/**
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * Print out progress on the console.
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews *
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * This runs the main event queue every now and then to prevent piling up
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * unhandled things (which doesn't cause real problems, just makes things
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * react a little slower than in the ideal case).
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews */
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark AndrewsHRESULT showProgress(ComPtr<IProgress> progress)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews{
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews using namespace com;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews BOOL fCompleted = FALSE;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson ULONG ulCurrentPercent = 0;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews ULONG ulLastPercent = 0;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews ULONG ulLastOperationPercent = (ULONG)-1;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
3740b569ae76295b941d57a724a43beb75b533baBob Halley ULONG ulLastOperation = (ULONG)-1;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence Bstr bstrOperationDescription;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley EventQueue::getMainEventQueue()->processEventQueue(0);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ULONG cOperations = 1;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley HRESULT hrc = progress->COMGETTER(OperationCount)(&cOperations);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (FAILED(hrc))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley RTStrmPrintf(g_pStdErr, "Progress object failure: %Rhrc\n", hrc);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley RTStrmFlush(g_pStdErr);
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson return hrc;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (!g_fDetailedProgress)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley RTStrmPrintf(g_pStdErr, "0%%...");
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley RTStrmFlush(g_pStdErr);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley }
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley /* setup signal handling if cancelable */
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley bool fCanceledAlready = false;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley BOOL fCancelable;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(Cancelable)(&fCancelable);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (FAILED(hrc))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley fCancelable = FALSE;
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrews if (fCancelable)
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrews {
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley signal(SIGINT, showProgressSignalHandler);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence#ifdef SIGBREAK
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence signal(SIGBREAK, showProgressSignalHandler);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence#endif
232fd751edcb5dd2b1fd2666e039efe83d2e2b55Michael Sawyer }
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence hrc = progress->COMGETTER(Completed(&fCompleted));
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence while (SUCCEEDED(hrc))
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence progress->COMGETTER(Percent(&ulCurrentPercent));
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
3740b569ae76295b941d57a724a43beb75b533baBob Halley if (g_fDetailedProgress)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ULONG ulOperation = 1;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(Operation)(&ulOperation);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (FAILED(hrc))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley break;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ULONG ulCurrentOperationPercent = 0;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(OperationPercent(&ulCurrentOperationPercent));
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson if (FAILED(hrc))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley break;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (ulLastOperation != ulOperation)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(OperationDescription(bstrOperationDescription.asOutParam()));
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (FAILED(hrc))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley break;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ulLastPercent = (ULONG)-1; // force print
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ulLastOperation = ulOperation;
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews }
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley if ( ulCurrentPercent != ulLastPercent
94e25967cda41b886e33ec254b917d21df21a187Bob Halley || ulCurrentOperationPercent != ulLastOperationPercent
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews )
94e25967cda41b886e33ec254b917d21df21a187Bob Halley {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley LONG lSecsRem = 0;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence progress->COMGETTER(TimeRemaining)(&lSecsRem);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews RTStrmPrintf(g_pStdErr, "(%u/%u) %ls %02u%% => %02u%% (%d s remaining)\n", ulOperation + 1, cOperations, bstrOperationDescription.raw(), ulCurrentOperationPercent, ulCurrentPercent, lSecsRem);
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews ulLastPercent = ulCurrentPercent;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley ulLastOperationPercent = ulCurrentOperationPercent;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* did we cross a 10% mark? */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (ulCurrentPercent / 10 > ulLastPercent / 10)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* make sure to also print out missed steps */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence for (ULONG curVal = (ulLastPercent / 10) * 10 + 10; curVal <= (ulCurrentPercent / 10) * 10; curVal += 10)
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (curVal < 100)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews {
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews RTStrmPrintf(g_pStdErr, "%u%%...", curVal);
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews RTStrmFlush(g_pStdErr);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews ulLastPercent = (ulCurrentPercent / 10) * 10;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (fCompleted)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence break;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrews /* process async cancelation */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (g_fCanceled && !fCanceledAlready)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->Cancel();
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (SUCCEEDED(hrc))
94e25967cda41b886e33ec254b917d21df21a187Bob Halley fCanceledAlready = true;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley else
94e25967cda41b886e33ec254b917d21df21a187Bob Halley g_fCanceled = false;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson /* make sure the loop is not too tight */
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley progress->WaitForCompletion(100);
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley EventQueue::getMainEventQueue()->processEventQueue(0);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley hrc = progress->COMGETTER(Completed(&fCompleted));
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* undo signal handling */
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley if (fCancelable)
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews signal(SIGINT, SIG_DFL);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#ifdef SIGBREAK
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley signal(SIGBREAK, SIG_DFL);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#endif
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* complete the line. */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence LONG iRc = E_FAIL;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence hrc = progress->COMGETTER(ResultCode)(&iRc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (SUCCEEDED(hrc))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (SUCCEEDED(iRc))
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews RTStrmPrintf(g_pStdErr, "100%%\n");
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews else if (g_fCanceled)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews RTStrmPrintf(g_pStdErr, "CANCELED\n");
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (!g_fDetailedProgress)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews RTStrmPrintf(g_pStdErr, "\n");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmPrintf(g_pStdErr, "Progress state: %Rhrc\n", iRc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence hrc = iRc;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (!g_fDetailedProgress)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmPrintf(g_pStdErr, "\n");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmPrintf(g_pStdErr, "Progress object failure: %Rhrc\n", hrc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmFlush(g_pStdErr);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley return hrc;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence}
9e8947d9e606b967d0792d0ab1ee7afac5e5f39dMark Andrews
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#ifdef RT_OS_WINDOWS
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence// Required for ATL
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halleystatic CComModule _Module;
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#endif
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#endif /* !VBOX_ONLY_DOCS */
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonint main(int argc, char *argv[])
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley{
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
94e25967cda41b886e33ec254b917d21df21a187Bob Halley * Before we do anything, init the runtime without loading
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley * the support driver.
94e25967cda41b886e33ec254b917d21df21a187Bob Halley */
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley RTR3InitExe(argc, &argv, 0);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley /*
94e25967cda41b886e33ec254b917d21df21a187Bob Halley * Parse the global options
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley */
94e25967cda41b886e33ec254b917d21df21a187Bob Halley bool fShowLogo = false;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley bool fShowHelp = false;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley int iCmd = 1;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley int iCmdArg;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson for (int i = 1; i < argc || argc <= iCmd; i++)
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if ( argc <= iCmd
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "help")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-?")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-h")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-help")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "--help"))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (i >= argc - 1)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence showLogo(g_pStdOut);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence printUsage(USAGE_ALL, g_pStdOut);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return 0;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley fShowLogo = true;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley fShowHelp = true;
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson iCmd++;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley continue;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ( !strcmp(argv[i], "-v")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-version")
94e25967cda41b886e33ec254b917d21df21a187Bob Halley || !strcmp(argv[i], "-Version")
94e25967cda41b886e33ec254b917d21df21a187Bob Halley || !strcmp(argv[i], "--version"))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson /* Print version number, and do nothing else. */
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson return 0;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ( !strcmp(argv[i], "--dumpopts")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-dumpopts"))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* Special option to dump really all commands,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * even the ones not understood on this platform. */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence printUsage(USAGE_DUMPOPTS, g_pStdOut);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return 0;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley }
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
94e25967cda41b886e33ec254b917d21df21a187Bob Halley if ( !strcmp(argv[i], "--nologo")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[i], "-nologo")
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley || !strcmp(argv[i], "-q"))
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley {
94e25967cda41b886e33ec254b917d21df21a187Bob Halley /* suppress the logo */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence fShowLogo = false;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence iCmd++;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence else if ( !strcmp(argv[i], "--detailed-progress")
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence || !strcmp(argv[i], "-d"))
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson {
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence /* detailed progress report */
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence g_fDetailedProgress = true;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence iCmd++;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence break;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence }
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence }
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence iCmdArg = iCmd + 1;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence if (fShowLogo)
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence showLogo(g_pStdOut);
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews#ifndef VBOX_ONLY_DOCS
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence /*
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence * Initialize COM.
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence */
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence using namespace com;
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence HRESULT hrc = com::Initialize();
ae5df22719a9e2c252ea1fcccd2cadb44c8bd8d4Mark Andrews if (FAILED(hrc))
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence RTEXITCODE rcExit = RTEXITCODE_FAILURE;
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence do
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence {
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence ///////////////////////////////////////////////////////////////////////////
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence // scopes all the stuff till shutdown
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * convertfromraw: does not need a VirtualBox instantiation.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (argc >= iCmdArg && ( !strcmp(argv[iCmd], "convertfromraw")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence || !strcmp(argv[iCmd], "convertdd")))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence rcExit = handleConvertFromRaw(argc - iCmdArg, argv + iCmdArg);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence break;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Get the remote VirtualBox object and create a local session object.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ComPtr<IVirtualBox> virtualBox;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ComPtr<ISession> session;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence hrc = virtualBox.createLocalObject(CLSID_VirtualBox);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (FAILED(hrc))
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence RTMsgError("Failed to create the VirtualBox object!");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence else
269c07173e24d7811e2fd09304023e3104fcbe0bMark Andrews {
269c07173e24d7811e2fd09304023e3104fcbe0bMark Andrews hrc = session.createInprocObject(CLSID_Session);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (FAILED(hrc))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTMsgError("Failed to create a session object!");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (FAILED(hrc))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence com::ErrorInfo info;
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User if (!info.isFullAvailable() && !info.isBasicAvailable())
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence com::GluePrintRCMessage(hrc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence com::GluePrintErrorInfo(info);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence break;
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence }
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence /*
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * All registered command handlers
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence static const struct
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence {
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence const char *command;
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson USAGECATEGORY help;
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson int (*handler)(HandlerArg *a);
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson } s_commandHandlers[] =
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson {
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "internalcommands", 0, handleInternalCommands },
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "list", USAGE_LIST, handleList },
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson { "showvminfo", USAGE_SHOWVMINFO, handleShowVMInfo },
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson { "registervm", USAGE_REGISTERVM, handleRegisterVM },
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "unregistervm", USAGE_UNREGISTERVM, handleUnregisterVM },
c36f45e354c0d5b6ab9f821bfe315d0ce9d95a29Mark Andrews { "clonevm", USAGE_CLONEVM, handleCloneVM },
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson { "createhd", USAGE_CREATEHD, handleCreateHardDisk },
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson { "createvdi", USAGE_CREATEHD, handleCreateHardDisk }, /* backward compatibility */
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson { "modifyhd", USAGE_MODIFYHD, handleModifyHardDisk },
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson { "modifyvdi", USAGE_MODIFYHD, handleModifyHardDisk }, /* backward compatibility */
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson { "clonehd", USAGE_CLONEHD, handleCloneHardDisk },
6475e22cc98c2386d0a259089e959bf8616f661dAutomatic Updater { "clonevdi", USAGE_CLONEHD, handleCloneHardDisk }, /* backward compatibility */
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "createvm", USAGE_CREATEVM, handleCreateVM },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "modifyvm", USAGE_MODIFYVM, handleModifyVM },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "startvm", USAGE_STARTVM, handleStartVM },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "controlvm", USAGE_CONTROLVM, handleControlVM },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "discardstate", USAGE_DISCARDSTATE, handleDiscardState },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "adoptstate", USAGE_ADOPTSTATE, handleAdoptState },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "snapshot", USAGE_SNAPSHOT, handleSnapshot },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "closemedium", USAGE_CLOSEMEDIUM, handleCloseMedium },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "storageattach", USAGE_STORAGEATTACH, handleStorageAttach },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "storagectl", USAGE_STORAGECONTROLLER, handleStorageController },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "showhdinfo", USAGE_SHOWHDINFO, handleShowHardDiskInfo },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "showvdiinfo", USAGE_SHOWHDINFO, handleShowHardDiskInfo }, /* backward compatibility */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "getextradata", USAGE_GETEXTRADATA, handleGetExtraData },
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews { "setextradata", USAGE_SETEXTRADATA, handleSetExtraData },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "setproperty", USAGE_SETPROPERTY, handleSetProperty },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "usbfilter", USAGE_USBFILTER, handleUSBFilter },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "sharedfolder", USAGE_SHAREDFOLDER, handleSharedFolder },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#ifdef VBOX_WITH_GUEST_PROPS
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "guestproperty", USAGE_GUESTPROPERTY, handleGuestProperty },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#endif
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#ifdef VBOX_WITH_GUEST_CONTROL
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "guestcontrol", USAGE_GUESTCONTROL, handleGuestControl },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#endif
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "metrics", USAGE_METRICS, handleMetrics },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "import", USAGE_IMPORTAPPLIANCE, handleImportAppliance },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "export", USAGE_EXPORTAPPLIANCE, handleExportAppliance },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#ifdef VBOX_WITH_NETFLT
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "hostonlyif", USAGE_HOSTONLYIFS, handleHostonlyIf },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#endif
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "dhcpserver", USAGE_DHCPSERVER, handleDHCPServer},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "extpack", USAGE_EXTPACK, handleExtPack},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "bandwidthctl", USAGE_BANDWIDTHCONTROL, handleBandwidthControl},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "debugvm", USAGE_DEBUGVM, handleDebugVM},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { NULL, 0, NULL }
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt };
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt HandlerArg handlerArg = { 0, NULL, virtualBox, session };
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt int commandIndex;
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt for (commandIndex = 0; s_commandHandlers[commandIndex].command != NULL; commandIndex++)
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt {
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt if (!strcmp(s_commandHandlers[commandIndex].command, argv[iCmd]))
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt {
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt handlerArg.argc = argc - iCmdArg;
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt handlerArg.argv = &argv[iCmdArg];
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt if ( fShowHelp
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt || ( argc - iCmdArg == 0
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt && s_commandHandlers[commandIndex].help))
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt {
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt printUsage(s_commandHandlers[commandIndex].help, g_pStdOut);
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt rcExit = RTEXITCODE_FAILURE; /* error */
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt }
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt else
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt rcExit = (RTEXITCODE)s_commandHandlers[commandIndex].handler(&handlerArg); /** @todo Change to return RTEXITCODE. */
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt break;
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt }
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt }
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (!s_commandHandlers[commandIndex].command)
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews /* Help topics. */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (fShowHelp && !strcmp(argv[iCmd], "commands"))
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews RTPrintf("commands:\n");
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews for (unsigned i = 0; i < RT_ELEMENTS(s_commandHandlers) - 1; i++)
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if ( i == 0 /* skip backwards compatibility entries */
96ea71632887c58a9d00f47eb318bf76b35903c3Mark Andrews || s_commandHandlers[i].help != s_commandHandlers[i - 1].help)
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews RTPrintf(" %s\n", s_commandHandlers[i].command);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews }
else
rcExit = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).c_str());
}
/* 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();
EventQueue::getMainEventQueue()->processEventQueue(0);
// end "all-stuff" scope
///////////////////////////////////////////////////////////////////////////
} while (0);
com::Shutdown();
return rcExit;
#else /* VBOX_ONLY_DOCS */
return RTEXITCODE_SUCCESS;
#endif /* VBOX_ONLY_DOCS */
}