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
Line 
1/* $Id: VBoxManage.cpp 24912 2009-11-24 14:35:31Z vboxsync $ */
2/** @file
3 * VBoxManage - VirtualBox's command-line interface.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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
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.
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.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#ifndef VBOX_ONLY_DOCS
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>
34
35# include <VBox/com/VirtualBox.h>
36
37# include <vector>
38# include <list>
39#endif /* !VBOX_ONLY_DOCS */
40
41#include <VBox/err.h>
42#include <VBox/version.h>
43
44#include <iprt/buildconfig.h>
45#include <iprt/env.h>
46#include <iprt/initterm.h>
47#include <iprt/stream.h>
48#include <iprt/string.h>
49
50#include "VBoxManage.h"
51
52
53/*******************************************************************************
54* Global Variables *
55*******************************************************************************/
56/*extern*/ bool g_fDetailedProgress = false;
57
58
59#ifndef VBOX_ONLY_DOCS
60/**
61 * Print out progress on the console
62 */
63HRESULT showProgress(ComPtr<IProgress> progress)
64{
65 using namespace com;
66
67 BOOL fCompleted;
68 ULONG ulCurrentPercent;
69 ULONG ulLastPercent = 0;
70
71 ULONG ulCurrentOperationPercent;
72 ULONG ulLastOperationPercent = (ULONG)-1;
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 {
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);
111 ulLastPercent = ulCurrentPercent;
112 ulLastOperationPercent = ulCurrentOperationPercent;
113 }
114 }
115 else
116 {
117 /* did we cross a 10% mark? */
118 if (ulCurrentPercent / 10 > ulLastPercent / 10)
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. */
140 LONG iRc = E_FAIL;
141 if (SUCCEEDED(progress->COMGETTER(ResultCode)(&iRc)))
142 {
143 if (SUCCEEDED(iRc))
144 RTPrintf("100%%\n");
145 else
146 RTPrintf("FAILED\n");
147 }
148 else
149 RTPrintf("\n");
150 RTStrmFlush(g_pStdOut);
151 return iRc;
152}
153#endif /* !VBOX_ONLY_DOCS */
154
155
156int main(int argc, char *argv[])
157{
158 /*
159 * Before we do anything, init the runtime without loading
160 * the support driver.
161 */
162 RTR3Init();
163
164 bool fShowLogo = true;
165 int iCmd = 1;
166 int iCmdArg;
167
168 /* global options */
169 for (int i = 1; i < argc || argc <= iCmd; i++)
170 {
171 if ( argc <= iCmd
172 || !strcmp(argv[i], "help")
173 || !strcmp(argv[i], "-?")
174 || !strcmp(argv[i], "-h")
175 || !strcmp(argv[i], "-help")
176 || !strcmp(argv[i], "--help"))
177 {
178 showLogo();
179 printUsage(USAGE_ALL);
180 return 0;
181 }
182
183 if ( !strcmp(argv[i], "-v")
184 || !strcmp(argv[i], "-version")
185 || !strcmp(argv[i], "-Version")
186 || !strcmp(argv[i], "--version"))
187 {
188 /* Print version number, and do nothing else. */
189 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
190 return 0;
191 }
192
193 if ( !strcmp(argv[i], "--dumpopts")
194 || !strcmp(argv[i], "-dumpopts"))
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 }
201
202 if ( !strcmp(argv[i], "--nologo")
203 || !strcmp(argv[i], "-nologo")
204 || !strcmp(argv[i], "-q"))
205 {
206 /* suppress the logo */
207 fShowLogo = false;
208 iCmd++;
209 }
210 else
211 {
212 break;
213 }
214 }
215
216 iCmdArg = iCmd + 1;
217
218 if (fShowLogo)
219 showLogo();
220
221
222#ifdef VBOX_ONLY_DOCS
223 int rc = 0;
224#else /* !VBOX_ONLY_DOCS */
225 using namespace com;
226 HRESULT rc = 0;
227
228 rc = com::Initialize();
229 if (FAILED(rc))
230 {
231 RTPrintf("ERROR: failed to initialize COM!\n");
232 return rc;
233 }
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 */
240 for (int i = iCmdArg; i < argc; i++)
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
252 /* convertfromraw: does not need a VirtualBox instantiation. */
253 if (argc >= iCmdArg && ( !strcmp(argv[iCmd], "convertfromraw")
254 || !strcmp(argv[iCmd], "convertdd")))
255 {
256 rc = handleConvertFromRaw(argc - iCmdArg, argv + iCmdArg);
257 break;
258 }
259
260 ComPtr<IVirtualBox> virtualBox;
261 ComPtr<ISession> session;
262
263 rc = virtualBox.createLocalObject(CLSID_VirtualBox);
264 if (FAILED(rc))
265 RTPrintf("ERROR: failed to create the VirtualBox object!\n");
266 else
267 {
268 rc = session.createInprocObject(CLSID_Session);
269 if (FAILED(rc))
270 RTPrintf("ERROR: failed to create a session object!\n");
271 }
272
273 if (FAILED(rc))
274 {
275 com::ErrorInfo info;
276 if (!info.isFullAvailable() && !info.isBasicAvailable())
277 {
278 com::GluePrintRCMessage(rc);
279 RTPrintf("Most likely, the VirtualBox COM server is not running or failed to start.\n");
280 }
281 else
282 com::GluePrintErrorInfo(info);
283 break;
284 }
285
286 HandlerArg handlerArg = { 0, NULL, virtualBox, session };
287
288 /*
289 * All registered command handlers
290 */
291 static const struct
292 {
293 const char *command;
294 int (*handler)(HandlerArg *a);
295 } s_commandHandlers[] =
296 {
297 { "internalcommands", handleInternalCommands },
298 { "list", handleList },
299 { "showvminfo", handleShowVMInfo },
300 { "registervm", handleRegisterVM },
301 { "unregistervm", handleUnregisterVM },
302 { "createhd", handleCreateHardDisk },
303 { "createvdi", handleCreateHardDisk }, /* backward compatiblity */
304 { "modifyhd", handleModifyHardDisk },
305 { "modifyvdi", handleModifyHardDisk }, /* backward compatiblity */
306 { "clonehd", handleCloneHardDisk },
307 { "clonevdi", handleCloneHardDisk }, /* backward compatiblity */
308 { "addiscsidisk", handleAddiSCSIDisk },
309 { "createvm", handleCreateVM },
310 { "modifyvm", handleModifyVM },
311 { "startvm", handleStartVM },
312 { "controlvm", handleControlVM },
313 { "discardstate", handleDiscardState },
314 { "adoptstate", handleAdoptdState },
315 { "snapshot", handleSnapshot },
316 { "openmedium", handleOpenMedium },
317 { "registerimage", handleOpenMedium }, /* backward compatiblity */
318 { "closemedium", handleCloseMedium },
319 { "unregisterimage", handleCloseMedium }, /* backward compatiblity */
320 { "storageattach", handleStorageAttach },
321 { "storagectl", handleStorageController },
322 { "showhdinfo", handleShowHardDiskInfo },
323 { "showvdiinfo", handleShowHardDiskInfo }, /* backward compatiblity */
324 { "getextradata", handleGetExtraData },
325 { "setextradata", handleSetExtraData },
326 { "setproperty", handleSetProperty },
327 { "usbfilter", handleUSBFilter },
328 { "sharedfolder", handleSharedFolder },
329 { "vmstatistics", handleVMStatistics },
330#ifdef VBOX_WITH_GUEST_PROPS
331 { "guestproperty", handleGuestProperty },
332#endif
333 { "metrics", handleMetrics },
334 { "import", handleImportAppliance },
335 { "export", handleExportAppliance },
336#ifdef VBOX_WITH_NETFLT
337 { "hostonlyif", handleHostonlyIf },
338#endif
339 { "dhcpserver", handleDHCPServer},
340 { NULL, NULL }
341 };
342
343 int commandIndex;
344 for (commandIndex = 0; s_commandHandlers[commandIndex].command != NULL; commandIndex++)
345 {
346 if (!strcmp(s_commandHandlers[commandIndex].command, argv[iCmd]))
347 {
348 handlerArg.argc = argc - iCmdArg;
349 handlerArg.argv = &argv[iCmdArg];
350
351 rc = s_commandHandlers[commandIndex].handler(&handlerArg);
352 break;
353 }
354 }
355 if (!s_commandHandlers[commandIndex].command)
356 {
357 rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).raw());
358 }
359
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();
366
367 EventQueue::getMainEventQueue()->processEventQueue(0);
368 // end "all-stuff" scope
369 ////////////////////////////////////////////////////////////////////////////
370 } while (0);
371
372 com::Shutdown();
373#endif /* !VBOX_ONLY_DOCS */
374
375 /*
376 * Free converted argument vector
377 */
378 for (int i = iCmdArg; i < argc; i++)
379 RTStrFree(argv[i]);
380
381 return rc != 0;
382}
383
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use