VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp@ 24912

Last change on this file since 24912 was 24912, checked in by vboxsync, 14 years ago

VBoxManage: A little clean up in progress.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
RevLine 
[12599]1/* $Id: VBoxManage.cpp 24912 2009-11-24 14:35:31Z vboxsync $ */
[1]2/** @file
[12599]3 * VBoxManage - VirtualBox's command-line interface.
[1]4 */
5
6/*
[16485]7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
[1]8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
[5999]12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
[8155]16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
[1]20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
[11703]26#ifndef VBOX_ONLY_DOCS
[24907]27# include <VBox/com/com.h>
28# include <VBox/com/string.h>
29# include <VBox/com/Guid.h>
30# include <VBox/com/array.h>
31# include <VBox/com/ErrorInfo.h>
32# include <VBox/com/errorprint.h>
33# include <VBox/com/EventQueue.h>
[1]34
[24907]35# include <VBox/com/VirtualBox.h>
[1]36
[24907]37# include <vector>
38# include <list>
[11765]39#endif /* !VBOX_ONLY_DOCS */
[1]40
[24907]41#include <VBox/err.h>
42#include <VBox/version.h>
43
[22562]44#include <iprt/buildconfig.h>
[14619]45#include <iprt/env.h>
[14613]46#include <iprt/initterm.h>
[1]47#include <iprt/stream.h>
48#include <iprt/string.h>
49
50#include "VBoxManage.h"
51
52
[24901]53/*******************************************************************************
54* Global Variables *
55*******************************************************************************/
[18396]56/*extern*/ bool g_fDetailedProgress = false;
57
58
59#ifndef VBOX_ONLY_DOCS
60/**
61 * Print out progress on the console
62 */
[24879]63HRESULT showProgress(ComPtr<IProgress> progress)
[18396]64{
[24907]65 using namespace com;
66
[18396]67 BOOL fCompleted;
68 ULONG ulCurrentPercent;
69 ULONG ulLastPercent = 0;
70
71 ULONG ulCurrentOperationPercent;
[18516]72 ULONG ulLastOperationPercent = (ULONG)-1;
[18396]73
74 ULONG ulLastOperation = (ULONG)-1;
75 Bstr bstrOperationDescription;
76
77 ULONG cOperations;
78 progress->COMGETTER(OperationCount)(&cOperations);
79
80 if (!g_fDetailedProgress)
81 {
82 RTPrintf("0%%...");
83 RTStrmFlush(g_pStdOut);
84 }
85
86 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
87 {
88 ULONG ulOperation;
89 progress->COMGETTER(Operation)(&ulOperation);
90
91 progress->COMGETTER(Percent(&ulCurrentPercent));
92 progress->COMGETTER(OperationPercent(&ulCurrentOperationPercent));
93
94 if (g_fDetailedProgress)
95 {
96 if (ulLastOperation != ulOperation)
97 {
98 progress->COMGETTER(OperationDescription(bstrOperationDescription.asOutParam()));
99 ulLastPercent = (ULONG)-1; // force print
100 ulLastOperation = ulOperation;
101 }
102
103 if ( (ulCurrentPercent != ulLastPercent)
104 || (ulCurrentOperationPercent != ulLastOperationPercent)
105 )
106 {
[18406]107 LONG lSecsRem;
108 progress->COMGETTER(TimeRemaining)(&lSecsRem);
109
110 RTPrintf("(%ld/%ld) %ls %ld%% => %ld%% (%d s remaining)\n", ulOperation + 1, cOperations, bstrOperationDescription.raw(), ulCurrentOperationPercent, ulCurrentPercent, lSecsRem);
[18396]111 ulLastPercent = ulCurrentPercent;
112 ulLastOperationPercent = ulCurrentOperationPercent;
113 }
114 }
115 else
116 {
117 /* did we cross a 10% mark? */
[24912]118 if (ulCurrentPercent / 10 > ulLastPercent / 10)
[18396]119 {
120 /* make sure to also print out missed steps */
121 for (ULONG curVal = (ulLastPercent / 10) * 10 + 10; curVal <= (ulCurrentPercent / 10) * 10; curVal += 10)
122 {
123 if (curVal < 100)
124 {
125 RTPrintf("%ld%%...", curVal);
126 RTStrmFlush(g_pStdOut);
127 }
128 }
129 ulLastPercent = (ulCurrentPercent / 10) * 10;
130 }
131 }
132 if (fCompleted)
133 break;
134
135 /* make sure the loop is not too tight */
136 progress->WaitForCompletion(100);
137 }
138
139 /* complete the line. */
[24879]140 LONG iRc = E_FAIL;
[19311]141 if (SUCCEEDED(progress->COMGETTER(ResultCode)(&iRc)))
[18396]142 {
[19311]143 if (SUCCEEDED(iRc))
[18396]144 RTPrintf("100%%\n");
145 else
146 RTPrintf("FAILED\n");
147 }
148 else
149 RTPrintf("\n");
150 RTStrmFlush(g_pStdOut);
[21612]151 return iRc;
[18396]152}
[11703]153#endif /* !VBOX_ONLY_DOCS */
[11384]154
[1]155
156int main(int argc, char *argv[])
157{
158 /*
159 * Before we do anything, init the runtime without loading
160 * the support driver.
161 */
[11822]162 RTR3Init();
[1]163
[3077]164 bool fShowLogo = true;
165 int iCmd = 1;
166 int iCmdArg;
[1]167
[7379]168 /* global options */
[3077]169 for (int i = 1; i < argc || argc <= iCmd; i++)
[1]170 {
[3077]171 if ( argc <= iCmd
[18782]172 || !strcmp(argv[i], "help")
173 || !strcmp(argv[i], "-?")
174 || !strcmp(argv[i], "-h")
175 || !strcmp(argv[i], "-help")
176 || !strcmp(argv[i], "--help"))
[3077]177 {
178 showLogo();
179 printUsage(USAGE_ALL);
180 return 0;
181 }
[24901]182
183 if ( !strcmp(argv[i], "-v")
184 || !strcmp(argv[i], "-version")
185 || !strcmp(argv[i], "-Version")
186 || !strcmp(argv[i], "--version"))
[3730]187 {
188 /* Print version number, and do nothing else. */
[22562]189 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
[14615]190 return 0;
[3730]191 }
[24901]192
193 if ( !strcmp(argv[i], "--dumpopts")
194 || !strcmp(argv[i], "-dumpopts"))
[7379]195 {
196 /* Special option to dump really all commands,
197 * even the ones not understood on this platform. */
198 printUsage(USAGE_DUMPOPTS);
199 return 0;
200 }
[24901]201
202 if ( !strcmp(argv[i], "--nologo")
203 || !strcmp(argv[i], "-nologo")
204 || !strcmp(argv[i], "-q"))
[3077]205 {
206 /* suppress the logo */
207 fShowLogo = false;
208 iCmd++;
209 }
210 else
211 {
212 break;
213 }
[1]214 }
215
[3077]216 iCmdArg = iCmd + 1;
[1]217
[3077]218 if (fShowLogo)
219 showLogo();
220
[1]221
[11703]222#ifdef VBOX_ONLY_DOCS
223 int rc = 0;
224#else /* !VBOX_ONLY_DOCS */
[24907]225 using namespace com;
[11703]226 HRESULT rc = 0;
227
[16530]228 rc = com::Initialize();
229 if (FAILED(rc))
230 {
231 RTPrintf("ERROR: failed to initialize COM!\n");
232 return rc;
233 }
[1]234
235 /*
236 * The input is in the host OS'es codepage (NT guarantees ACP).
237 * For VBox we use UTF-8 and convert to UCS-2 when calling (XP)COM APIs.
238 * For simplicity, just convert the argv[] array here.
239 */
[3077]240 for (int i = iCmdArg; i < argc; i++)
[1]241 {
242 char *converted;
243 RTStrCurrentCPToUtf8(&converted, argv[i]);
244 argv[i] = converted;
245 }
246
247 do
248 {
249 // scopes all the stuff till shutdown
250 ////////////////////////////////////////////////////////////////////////////
251
[15602]252 /* convertfromraw: does not need a VirtualBox instantiation. */
253 if (argc >= iCmdArg && ( !strcmp(argv[iCmd], "convertfromraw")
254 || !strcmp(argv[iCmd], "convertdd")))
[15366]255 {
[15602]256 rc = handleConvertFromRaw(argc - iCmdArg, argv + iCmdArg);
[15366]257 break;
258 }
259
[16530]260 ComPtr<IVirtualBox> virtualBox;
261 ComPtr<ISession> session;
[1]262
[16530]263 rc = virtualBox.createLocalObject(CLSID_VirtualBox);
[1]264 if (FAILED(rc))
[16530]265 RTPrintf("ERROR: failed to create the VirtualBox object!\n");
266 else
[1]267 {
[16530]268 rc = session.createInprocObject(CLSID_Session);
269 if (FAILED(rc))
270 RTPrintf("ERROR: failed to create a session object!\n");
271 }
[1]272
[16530]273 if (FAILED(rc))
274 {
[1]275 com::ErrorInfo info;
276 if (!info.isFullAvailable() && !info.isBasicAvailable())
[16530]277 {
278 com::GluePrintRCMessage(rc);
279 RTPrintf("Most likely, the VirtualBox COM server is not running or failed to start.\n");
280 }
[1]281 else
[20928]282 com::GluePrintErrorInfo(info);
[1]283 break;
284 }
285
[16052]286 HandlerArg handlerArg = { 0, NULL, virtualBox, session };
287
[1]288 /*
289 * All registered command handlers
290 */
[24901]291 static const struct
[1]292 {
[2333]293 const char *command;
[24901]294 int (*handler)(HandlerArg *a);
295 } s_commandHandlers[] =
[1]296 {
297 { "internalcommands", handleInternalCommands },
298 { "list", handleList },
299 { "showvminfo", handleShowVMInfo },
300 { "registervm", handleRegisterVM },
301 { "unregistervm", handleUnregisterVM },
[13580]302 { "createhd", handleCreateHardDisk },
303 { "createvdi", handleCreateHardDisk }, /* backward compatiblity */
304 { "modifyhd", handleModifyHardDisk },
305 { "modifyvdi", handleModifyHardDisk }, /* backward compatiblity */
[15366]306 { "clonehd", handleCloneHardDisk },
307 { "clonevdi", handleCloneHardDisk }, /* backward compatiblity */
[1]308 { "addiscsidisk", handleAddiSCSIDisk },
309 { "createvm", handleCreateVM },
310 { "modifyvm", handleModifyVM },
311 { "startvm", handleStartVM },
312 { "controlvm", handleControlVM },
313 { "discardstate", handleDiscardState },
[5391]314 { "adoptstate", handleAdoptdState },
[1]315 { "snapshot", handleSnapshot },
[13580]316 { "openmedium", handleOpenMedium },
317 { "registerimage", handleOpenMedium }, /* backward compatiblity */
318 { "closemedium", handleCloseMedium },
319 { "unregisterimage", handleCloseMedium }, /* backward compatiblity */
[23902]320 { "storageattach", handleStorageAttach },
[23802]321 { "storagectl", handleStorageController },
[13580]322 { "showhdinfo", handleShowHardDiskInfo },
323 { "showvdiinfo", handleShowHardDiskInfo }, /* backward compatiblity */
[1]324 { "getextradata", handleGetExtraData },
325 { "setextradata", handleSetExtraData },
326 { "setproperty", handleSetProperty },
327 { "usbfilter", handleUSBFilter },
328 { "sharedfolder", handleSharedFolder },
[5204]329 { "vmstatistics", handleVMStatistics },
[10797]330#ifdef VBOX_WITH_GUEST_PROPS
[10826]331 { "guestproperty", handleGuestProperty },
[24901]332#endif
[11384]333 { "metrics", handleMetrics },
[16485]334 { "import", handleImportAppliance },
[17033]335 { "export", handleExportAppliance },
[24901]336#ifdef VBOX_WITH_NETFLT
[17419]337 { "hostonlyif", handleHostonlyIf },
[18072]338#endif
[18023]339 { "dhcpserver", handleDHCPServer},
[1]340 { NULL, NULL }
341 };
342
343 int commandIndex;
[24901]344 for (commandIndex = 0; s_commandHandlers[commandIndex].command != NULL; commandIndex++)
[1]345 {
[24901]346 if (!strcmp(s_commandHandlers[commandIndex].command, argv[iCmd]))
[1]347 {
[16052]348 handlerArg.argc = argc - iCmdArg;
349 handlerArg.argv = &argv[iCmdArg];
[17079]350
[24901]351 rc = s_commandHandlers[commandIndex].handler(&handlerArg);
[1]352 break;
353 }
354 }
[24901]355 if (!s_commandHandlers[commandIndex].command)
[1]356 {
[3077]357 rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).raw());
[1]358 }
359
[5391]360 /* Although all handlers should always close the session if they open it,
361 * we do it here just in case if some of the handlers contains a bug --
362 * leaving the direct session not closed will turn the machine state to
363 * Aborted which may have unwanted side effects like killing the saved
364 * state file (if the machine was in the Saved state before). */
365 session->Close();
[1]366
[22911]367 EventQueue::getMainEventQueue()->processEventQueue(0);
[1]368 // end "all-stuff" scope
369 ////////////////////////////////////////////////////////////////////////////
[23934]370 } while (0);
[1]371
372 com::Shutdown();
[11703]373#endif /* !VBOX_ONLY_DOCS */
[1]374
375 /*
376 * Free converted argument vector
377 */
[3077]378 for (int i = iCmdArg; i < argc; i++)
[1]379 RTStrFree(argv[i]);
380
[11703]381 return rc != 0;
[1]382}
[24907]383
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use