VBoxManage.cpp revision 230bd8589bba39933ac5ec21482d6186d675e604
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * VBoxManage - VirtualBox's command-line interface.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * Copyright (C) 2006-2010 Oracle Corporation
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.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*******************************************************************************
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein* Header Files *
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence*******************************************************************************/
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#endif /* !VBOX_ONLY_DOCS */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence/*******************************************************************************
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence* Global Variables *
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews*******************************************************************************/
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/** Set by the signal handler. */
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleystatic volatile bool g_fCanceled = false;
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrews * Signal handler that sets g_fCanceled.
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 Andrewsstatic void showProgressSignalHandler(int iSignal)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * Print out progress on the console.
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 AndrewsHRESULT showProgress(ComPtr<IProgress> progress)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews using namespace com;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley EventQueue::getMainEventQueue()->processEventQueue(0);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley HRESULT hrc = progress->COMGETTER(OperationCount)(&cOperations);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley RTStrmPrintf(g_pStdErr, "Progress object failure: %Rhrc\n", hrc);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley /* setup signal handling if cancelable */
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(Cancelable)(&fCancelable);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence hrc = progress->COMGETTER(Completed(&fCompleted));
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence progress->COMGETTER(Percent(&ulCurrentPercent));
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(Operation)(&ulOperation);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(OperationPercent(&ulCurrentOperationPercent));
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley hrc = progress->COMGETTER(OperationDescription(bstrOperationDescription.asOutParam()));
94e25967cda41b886e33ec254b917d21df21a187Bob Halley || ulCurrentOperationPercent != ulLastOperationPercent
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence progress->COMGETTER(TimeRemaining)(&lSecsRem);
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews RTStrmPrintf(g_pStdErr, "(%u/%u) %ls %02u%% => %02u%% (%d s remaining)\n", ulOperation + 1, cOperations, bstrOperationDescription.raw(), ulCurrentOperationPercent, ulCurrentPercent, lSecsRem);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley ulLastOperationPercent = ulCurrentOperationPercent;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* did we cross a 10% mark? */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (ulCurrentPercent / 10 > ulLastPercent / 10)
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)
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrews /* process async cancelation */
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson /* make sure the loop is not too tight */
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley EventQueue::getMainEventQueue()->processEventQueue(0);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley hrc = progress->COMGETTER(Completed(&fCompleted));
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* undo signal handling */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* complete the line. */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmPrintf(g_pStdErr, "Progress state: %Rhrc\n", iRc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTStrmPrintf(g_pStdErr, "Progress object failure: %Rhrc\n", hrc);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence// Required for ATL
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley#endif /* !VBOX_ONLY_DOCS */
94e25967cda41b886e33ec254b917d21df21a187Bob Halley * Before we do anything, init the runtime without loading
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley * the support driver.
94e25967cda41b886e33ec254b917d21df21a187Bob Halley * Parse the global options
94e25967cda41b886e33ec254b917d21df21a187Bob Halley bool fShowLogo = false;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley bool fShowHelp = false;
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson for (int i = 1; i < argc || argc <= iCmd; i++)
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson /* Print version number, and do nothing else. */
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /* Special option to dump really all commands,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * even the ones not understood on this platform. */
94e25967cda41b886e33ec254b917d21df21a187Bob Halley /* suppress the logo */
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence else if ( !strcmp(argv[i], "--detailed-progress")
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence /* detailed progress report */
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence * Initialize COM.
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence using namespace com;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence ///////////////////////////////////////////////////////////////////////////
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence // scopes all the stuff till shutdown
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * convertfromraw: does not need a VirtualBox instantiation.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (argc >= iCmdArg && ( !strcmp(argv[iCmd], "convertfromraw")
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence rcExit = handleConvertFromRaw(argc - iCmdArg, argv + iCmdArg);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Get the remote VirtualBox object and create a local session object.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence hrc = virtualBox.createLocalObject(CLSID_VirtualBox);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence RTMsgError("Failed to create the VirtualBox object!");
269c07173e24d7811e2fd09304023e3104fcbe0bMark Andrews hrc = session.createInprocObject(CLSID_Session);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTMsgError("Failed to create a session object!");
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User if (!info.isFullAvailable() && !info.isBasicAvailable())
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence * All registered command handlers
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence static const struct
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "internalcommands", 0, handleInternalCommands },
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson { "showvminfo", USAGE_SHOWVMINFO, handleShowVMInfo },
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson { "registervm", USAGE_REGISTERVM, handleRegisterVM },
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson { "unregistervm", USAGE_UNREGISTERVM, handleUnregisterVM },
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 { "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 { "guestproperty", USAGE_GUESTPROPERTY, handleGuestProperty },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "guestcontrol", USAGE_GUESTCONTROL, handleGuestControl },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "import", USAGE_IMPORTAPPLIANCE, handleImportAppliance },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "export", USAGE_EXPORTAPPLIANCE, handleExportAppliance },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "hostonlyif", USAGE_HOSTONLYIFS, handleHostonlyIf },
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "dhcpserver", USAGE_DHCPSERVER, handleDHCPServer},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt { "bandwidthctl", USAGE_BANDWIDTHCONTROL, handleBandwidthControl},
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt HandlerArg handlerArg = { 0, NULL, virtualBox, session };
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt for (commandIndex = 0; s_commandHandlers[commandIndex].command != NULL; commandIndex++)
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt if (!strcmp(s_commandHandlers[commandIndex].command, argv[iCmd]))
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt printUsage(s_commandHandlers[commandIndex].help, g_pStdOut);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt rcExit = (RTEXITCODE)s_commandHandlers[commandIndex].handler(&handlerArg); /** @todo Change to return RTEXITCODE. */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews /* Help topics. */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (fShowHelp && !strcmp(argv[iCmd], "commands"))
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);
return rcExit;
return RTEXITCODE_SUCCESS;