1
/* $Id: VBoxManageMisc.cpp $ */
3
* VBoxManage - VirtualBox's command-line interface.
7
* Copyright (C) 2006-2009 Sun Microsystems, Inc.
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.
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.
23
/*******************************************************************************
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>
35
#include <VBox/com/VirtualBox.h>
39
#endif /* !VBOX_ONLY_DOCS */
42
#include <iprt/buildconfig.h>
43
#include <iprt/cidr.h>
44
#include <iprt/ctype.h>
48
#include <iprt/file.h>
49
#include <iprt/initterm.h>
50
#include <iprt/param.h>
51
#include <iprt/path.h>
52
#include <iprt/stream.h>
53
#include <iprt/string.h>
54
#include <iprt/stdarg.h>
55
#include <iprt/thread.h>
56
#include <iprt/uuid.h>
57
#include <iprt/getopt.h>
58
#include <iprt/ctype.h>
59
#include <VBox/version.h>
62
#include "VBoxManage.h"
68
int handleRegisterVM(HandlerArg *a)
73
return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");
75
ComPtr<IMachine> machine;
76
/** @todo Ugly hack to get both the API interpretation of relative paths
77
* and the client's interpretation of relative paths. Remove after the API
78
* has been redesigned. */
79
rc = a->virtualBox->OpenMachine(Bstr(a->argv[0]), machine.asOutParam());
80
if (rc == VBOX_E_FILE_ERROR)
82
char szVMFileAbs[RTPATH_MAX] = "";
83
int vrc = RTPathAbs(a->argv[0], szVMFileAbs, sizeof(szVMFileAbs));
86
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", a->argv[0]);
89
CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(szVMFileAbs), machine.asOutParam()));
92
CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(a->argv[0]), machine.asOutParam()));
96
CHECK_ERROR(a->virtualBox, RegisterMachine(machine));
98
return SUCCEEDED(rc) ? 0 : 1;
101
static const RTGETOPTDEF g_aUnregisterVMOptions[] =
103
{ "--delete", 'd', RTGETOPT_REQ_NOTHING },
104
{ "-delete", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
107
int handleUnregisterVM(HandlerArg *a)
110
const char *VMName = NULL;
111
bool fDelete = false;
114
RTGETOPTUNION ValueUnion;
115
RTGETOPTSTATE GetState;
116
// start at 0 because main() has hacked both the argc and argv given to us
117
RTGetOptInit(&GetState, a->argc, a->argv, g_aUnregisterVMOptions, RT_ELEMENTS(g_aUnregisterVMOptions), 0, 0 /* fFlags */);
118
while ((c = RTGetOpt(&GetState, &ValueUnion)))
122
case 'd': // --delete
126
case VINF_GETOPT_NOT_OPTION:
128
VMName = ValueUnion.psz;
130
return errorSyntax(USAGE_UNREGISTERVM, "Invalid parameter '%s'", ValueUnion.psz);
136
if (RT_C_IS_PRINT(c))
137
return errorSyntax(USAGE_UNREGISTERVM, "Invalid option -%c", c);
139
return errorSyntax(USAGE_UNREGISTERVM, "Invalid option case %i", c);
141
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
142
return errorSyntax(USAGE_UNREGISTERVM, "unknown option: %s\n", ValueUnion.psz);
143
else if (ValueUnion.pDef)
144
return errorSyntax(USAGE_UNREGISTERVM, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
146
return errorSyntax(USAGE_UNREGISTERVM, "error: %Rrs", c);
150
/* check for required options */
152
return errorSyntax(USAGE_UNREGISTERVM, "VM name required");
154
ComPtr<IMachine> machine;
155
/* assume it's a UUID */
156
rc = a->virtualBox->GetMachine(Guid(VMName).toUtf16(), machine.asOutParam());
157
if (FAILED(rc) || !machine)
160
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMName), machine.asOutParam()));
165
machine->COMGETTER(Id)(uuid.asOutParam());
167
CHECK_ERROR(a->virtualBox, UnregisterMachine(uuid, machine.asOutParam()));
168
if (SUCCEEDED(rc) && machine && fDelete)
169
CHECK_ERROR(machine, DeleteSettings());
171
return SUCCEEDED(rc) ? 0 : 1;
174
int handleCreateVM(HandlerArg *a)
182
bool fRegister = false;
185
for (int i = 0; i < a->argc; i++)
187
if ( !strcmp(a->argv[i], "--basefolder")
188
|| !strcmp(a->argv[i], "-basefolder"))
190
if (a->argc <= i + 1)
191
return errorArgument("Missing argument to '%s'", a->argv[i]);
193
baseFolder = a->argv[i];
195
else if ( !strcmp(a->argv[i], "--settingsfile")
196
|| !strcmp(a->argv[i], "-settingsfile"))
198
if (a->argc <= i + 1)
199
return errorArgument("Missing argument to '%s'", a->argv[i]);
201
settingsFile = a->argv[i];
203
else if ( !strcmp(a->argv[i], "--name")
204
|| !strcmp(a->argv[i], "-name"))
206
if (a->argc <= i + 1)
207
return errorArgument("Missing argument to '%s'", a->argv[i]);
211
else if ( !strcmp(a->argv[i], "--ostype")
212
|| !strcmp(a->argv[i], "-ostype"))
214
if (a->argc <= i + 1)
215
return errorArgument("Missing argument to '%s'", a->argv[i]);
217
osTypeId = a->argv[i];
219
else if ( !strcmp(a->argv[i], "--uuid")
220
|| !strcmp(a->argv[i], "-uuid"))
222
if (a->argc <= i + 1)
223
return errorArgument("Missing argument to '%s'", a->argv[i]);
225
if (RT_FAILURE(RTUuidFromStr(&id, a->argv[i])))
226
return errorArgument("Invalid UUID format %s\n", a->argv[i]);
228
else if ( !strcmp(a->argv[i], "--register")
229
|| !strcmp(a->argv[i], "-register"))
234
return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
237
return errorSyntax(USAGE_CREATEVM, "Parameter --name is required");
239
if (!!baseFolder && !!settingsFile)
240
return errorSyntax(USAGE_CREATEVM, "Either --basefolder or --settingsfile must be specified");
244
ComPtr<IMachine> machine;
247
CHECK_ERROR_BREAK(a->virtualBox,
248
CreateMachine(name, osTypeId, baseFolder, Guid(id).toUtf16(), machine.asOutParam()));
250
CHECK_ERROR_BREAK(a->virtualBox,
251
CreateLegacyMachine(name, osTypeId, settingsFile, Guid(id).toUtf16(), machine.asOutParam()));
253
CHECK_ERROR_BREAK(machine, SaveSettings());
256
CHECK_ERROR_BREAK(a->virtualBox, RegisterMachine(machine));
259
CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam()));
260
CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam()));
261
RTPrintf("Virtual machine '%ls' is created%s.\n"
263
"Settings file: '%ls'\n",
264
name.raw(), fRegister ? " and registered" : "",
265
Utf8Str(uuid).raw(), settingsFile.raw());
269
return SUCCEEDED(rc) ? 0 : 1;
272
int handleStartVM(HandlerArg *a)
275
const char *VMName = NULL;
276
Bstr sessionType = "gui";
278
static const RTGETOPTDEF s_aStartVMOptions[] =
280
{ "--type", 't', RTGETOPT_REQ_STRING },
281
{ "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
284
RTGETOPTUNION ValueUnion;
285
RTGETOPTSTATE GetState;
286
// start at 0 because main() has hacked both the argc and argv given to us
287
RTGetOptInit(&GetState, a->argc, a->argv, s_aStartVMOptions, RT_ELEMENTS(s_aStartVMOptions), 0, 0 /* fFlags */);
288
while ((c = RTGetOpt(&GetState, &ValueUnion)))
293
if (!RTStrICmp(ValueUnion.psz, "gui"))
297
#ifdef VBOX_WITH_VBOXSDL
298
else if (!RTStrICmp(ValueUnion.psz, "sdl"))
303
#ifdef VBOX_WITH_VRDP
304
else if (!RTStrICmp(ValueUnion.psz, "vrdp"))
306
sessionType = "vrdp";
309
#ifdef VBOX_WITH_HEADLESS
310
else if (!RTStrICmp(ValueUnion.psz, "capture"))
312
sessionType = "capture";
314
else if (!RTStrICmp(ValueUnion.psz, "headless"))
316
sessionType = "headless";
320
return errorArgument("Invalid session type '%s'", ValueUnion.psz);
323
case VINF_GETOPT_NOT_OPTION:
325
VMName = ValueUnion.psz;
327
return errorSyntax(USAGE_STARTVM, "Invalid parameter '%s'", ValueUnion.psz);
333
if (RT_C_IS_PRINT(c))
334
return errorSyntax(USAGE_STARTVM, "Invalid option -%c", c);
336
return errorSyntax(USAGE_STARTVM, "Invalid option case %i", c);
338
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
339
return errorSyntax(USAGE_STARTVM, "unknown option: %s\n", ValueUnion.psz);
340
else if (ValueUnion.pDef)
341
return errorSyntax(USAGE_STARTVM, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
343
return errorSyntax(USAGE_STARTVM, "error: %Rrs", c);
347
/* check for required options */
349
return errorSyntax(USAGE_STARTVM, "VM name required");
351
ComPtr<IMachine> machine;
352
/* assume it's a UUID */
353
rc = a->virtualBox->GetMachine(Guid(VMName).toUtf16(), machine.asOutParam());
354
if (FAILED(rc) || !machine)
357
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMName), machine.asOutParam()));
362
machine->COMGETTER(Id)(uuid.asOutParam());
366
#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
367
/* make sure the VM process will start on the same display as VBoxManage */
369
const char *pszDisplay = RTEnvGet("DISPLAY");
371
str = Utf8StrFmt("DISPLAY=%s\n", pszDisplay);
372
const char *pszXAuth = RTEnvGet("XAUTHORITY");
374
str.append(Utf8StrFmt("XAUTHORITY=%s\n", pszXAuth));
377
ComPtr<IProgress> progress;
378
CHECK_ERROR_RET(a->virtualBox, OpenRemoteSession(a->session, uuid, sessionType,
379
env, progress.asOutParam()), rc);
380
RTPrintf("Waiting for the remote session to open...\n");
381
CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1);
384
CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc);
388
CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
391
ComPtr <IVirtualBoxErrorInfo> errorInfo;
392
CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1);
393
ErrorInfo info (errorInfo);
394
com::GluePrintErrorInfo(info);
398
RTPrintf("Remote session has been successfully opened.\n");
402
/* it's important to always close sessions */
405
return SUCCEEDED(rc) ? 0 : 1;
408
int handleDiscardState(HandlerArg *a)
413
return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");
415
ComPtr<IMachine> machine;
416
/* assume it's a UUID */
417
rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
418
if (FAILED(rc) || !machine)
421
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
427
/* we have to open a session for this task */
429
machine->COMGETTER(Id)(guid.asOutParam());
430
CHECK_ERROR_BREAK(a->virtualBox, OpenSession(a->session, guid));
433
ComPtr<IConsole> console;
434
CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
435
CHECK_ERROR_BREAK(console, ForgetSavedState(true));
437
CHECK_ERROR_BREAK(a->session, Close());
441
return SUCCEEDED(rc) ? 0 : 1;
444
int handleAdoptdState(HandlerArg *a)
449
return errorSyntax(USAGE_ADOPTSTATE, "Incorrect number of parameters");
451
ComPtr<IMachine> machine;
452
/* assume it's a UUID */
453
rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
454
if (FAILED(rc) || !machine)
457
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
463
/* we have to open a session for this task */
465
machine->COMGETTER(Id)(guid.asOutParam());
466
CHECK_ERROR_BREAK(a->virtualBox, OpenSession(a->session, guid));
469
ComPtr<IConsole> console;
470
CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
471
CHECK_ERROR_BREAK(console, AdoptSavedState(Bstr(a->argv[1])));
473
CHECK_ERROR_BREAK(a->session, Close());
477
return SUCCEEDED(rc) ? 0 : 1;
480
int handleGetExtraData(HandlerArg *a)
485
return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");
488
if (!strcmp(a->argv[0], "global"))
491
if (!strcmp(a->argv[1], "enumerate"))
493
SafeArray<BSTR> aKeys;
494
CHECK_ERROR(a->virtualBox, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
500
Bstr bstrKey(aKeys[i]);
502
CHECK_ERROR(a->virtualBox, GetExtraData(bstrKey, bstrValue.asOutParam()));
504
RTPrintf("Key: %lS, Value: %lS\n", bstrKey.raw(), bstrValue.raw());
510
CHECK_ERROR(a->virtualBox, GetExtraData(Bstr(a->argv[1]), value.asOutParam()));
511
if (!value.isEmpty())
512
RTPrintf("Value: %lS\n", value.raw());
514
RTPrintf("No value set!\n");
519
ComPtr<IMachine> machine;
520
/* assume it's a UUID */
521
rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
522
if (FAILED(rc) || !machine)
525
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
530
if (!strcmp(a->argv[1], "enumerate"))
532
SafeArray<BSTR> aKeys;
533
CHECK_ERROR(machine, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
539
Bstr bstrKey(aKeys[i]);
541
CHECK_ERROR(machine, GetExtraData(bstrKey, bstrValue.asOutParam()));
543
RTPrintf("Key: %lS, Value: %lS\n", bstrKey.raw(), bstrValue.raw());
549
CHECK_ERROR(machine, GetExtraData(Bstr(a->argv[1]), value.asOutParam()));
550
if (!value.isEmpty())
551
RTPrintf("Value: %lS\n", value.raw());
553
RTPrintf("No value set!\n");
557
return SUCCEEDED(rc) ? 0 : 1;
560
int handleSetExtraData(HandlerArg *a)
565
return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");
568
if (!strcmp(a->argv[0], "global"))
571
CHECK_ERROR(a->virtualBox, SetExtraData(Bstr(a->argv[1]), NULL));
572
else if (a->argc == 3)
573
CHECK_ERROR(a->virtualBox, SetExtraData(Bstr(a->argv[1]), Bstr(a->argv[2])));
575
return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
579
ComPtr<IMachine> machine;
580
/* assume it's a UUID */
581
rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
582
if (FAILED(rc) || !machine)
585
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
590
CHECK_ERROR(machine, SetExtraData(Bstr(a->argv[1]), NULL));
591
else if (a->argc == 3)
592
CHECK_ERROR(machine, SetExtraData(Bstr(a->argv[1]), Bstr(a->argv[2])));
594
return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
597
return SUCCEEDED(rc) ? 0 : 1;
600
int handleSetProperty(HandlerArg *a)
604
/* there must be two arguments: property name and value */
606
return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");
608
ComPtr<ISystemProperties> systemProperties;
609
a->virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
611
if (!strcmp(a->argv[0], "hdfolder"))
613
/* reset to default? */
614
if (!strcmp(a->argv[1], "default"))
615
CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(NULL));
617
CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(Bstr(a->argv[1])));
619
else if (!strcmp(a->argv[0], "machinefolder"))
621
/* reset to default? */
622
if (!strcmp(a->argv[1], "default"))
623
CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
625
CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(a->argv[1])));
627
else if (!strcmp(a->argv[0], "vrdpauthlibrary"))
629
/* reset to default? */
630
if (!strcmp(a->argv[1], "default"))
631
CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));
633
CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(a->argv[1])));
635
else if (!strcmp(a->argv[0], "websrvauthlibrary"))
637
/* reset to default? */
638
if (!strcmp(a->argv[1], "default"))
639
CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));
641
CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(a->argv[1])));
643
else if (!strcmp(a->argv[0], "loghistorycount"))
647
vrc = RTStrToUInt32Ex(a->argv[1], NULL, 0, &uVal);
648
if (vrc != VINF_SUCCESS)
649
return errorArgument("Error parsing Log history count '%s'", a->argv[1]);
650
CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));
653
return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", a->argv[0]);
655
return SUCCEEDED(rc) ? 0 : 1;
658
int handleSharedFolder(HandlerArg *a)
662
/* we need at least a command and target */
664
return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
666
ComPtr<IMachine> machine;
667
/* assume it's a UUID */
668
rc = a->virtualBox->GetMachine(Bstr(a->argv[1]), machine.asOutParam());
669
if (FAILED(rc) || !machine)
672
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[1]), machine.asOutParam()));
677
machine->COMGETTER(Id)(uuid.asOutParam());
679
if (!strcmp(a->argv[0], "add"))
681
/* we need at least four more parameters */
683
return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");
686
char *hostpath = NULL;
687
bool fTransient = false;
688
bool fWritable = true;
690
for (int i = 2; i < a->argc; i++)
692
if ( !strcmp(a->argv[i], "--name")
693
|| !strcmp(a->argv[i], "-name"))
695
if (a->argc <= i + 1 || !*a->argv[i+1])
696
return errorArgument("Missing argument to '%s'", a->argv[i]);
700
else if ( !strcmp(a->argv[i], "--hostpath")
701
|| !strcmp(a->argv[i], "-hostpath"))
703
if (a->argc <= i + 1 || !*a->argv[i+1])
704
return errorArgument("Missing argument to '%s'", a->argv[i]);
706
hostpath = a->argv[i];
708
else if ( !strcmp(a->argv[i], "--readonly")
709
|| !strcmp(a->argv[i], "-readonly"))
713
else if ( !strcmp(a->argv[i], "--transient")
714
|| !strcmp(a->argv[i], "-transient"))
719
return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
722
if (NULL != strstr(name, " "))
723
return errorSyntax(USAGE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");
725
/* required arguments */
726
if (!name || !hostpath)
728
return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters --name and --hostpath are required");
733
ComPtr <IConsole> console;
735
/* open an existing session for the VM */
736
CHECK_ERROR_RET(a->virtualBox, OpenExistingSession(a->session, uuid), 1);
737
/* get the session machine */
738
CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
739
/* get the session console */
740
CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
742
CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
749
/* open a session for the VM */
750
CHECK_ERROR_RET(a->virtualBox, OpenSession(a->session, uuid), 1);
752
/* get the mutable session machine */
753
a->session->COMGETTER(Machine)(machine.asOutParam());
755
CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
758
CHECK_ERROR(machine, SaveSettings());
763
else if (!strcmp(a->argv[0], "remove"))
765
/* we need at least two more parameters */
767
return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");
770
bool fTransient = false;
772
for (int i = 2; i < a->argc; i++)
774
if ( !strcmp(a->argv[i], "--name")
775
|| !strcmp(a->argv[i], "-name"))
777
if (a->argc <= i + 1 || !*a->argv[i+1])
778
return errorArgument("Missing argument to '%s'", a->argv[i]);
782
else if ( !strcmp(a->argv[i], "--transient")
783
|| !strcmp(a->argv[i], "-transient"))
788
return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
791
/* required arguments */
793
return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter --name is required");
797
ComPtr <IConsole> console;
799
/* open an existing session for the VM */
800
CHECK_ERROR_RET(a->virtualBox, OpenExistingSession(a->session, uuid), 1);
801
/* get the session machine */
802
CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
803
/* get the session console */
804
CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
806
CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));
813
/* open a session for the VM */
814
CHECK_ERROR_RET(a->virtualBox, OpenSession(a->session, uuid), 1);
816
/* get the mutable session machine */
817
a->session->COMGETTER(Machine)(machine.asOutParam());
819
CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));
821
/* commit and close the session */
822
CHECK_ERROR(machine, SaveSettings());
827
return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(a->argv[0]).raw());
832
int handleVMStatistics(HandlerArg *a)
836
/* at least one option: the UUID or name of the VM */
838
return errorSyntax(USAGE_VM_STATISTICS, "Incorrect number of parameters");
840
/* try to find the given machine */
841
ComPtr <IMachine> machine;
842
Bstr uuid (a->argv[0]);
843
if (!Guid (a->argv[0]).isEmpty())
844
CHECK_ERROR(a->virtualBox, GetMachine(uuid, machine.asOutParam()));
847
CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
849
machine->COMGETTER(Id)(uuid.asOutParam());
854
/* parse arguments. */
856
bool fWithDescriptions = false;
857
const char *pszPattern = NULL; /* all */
858
for (int i = 1; i < a->argc; i++)
860
if ( !strcmp(a->argv[i], "--pattern")
861
|| !strcmp(a->argv[i], "-pattern"))
864
return errorSyntax(USAGE_VM_STATISTICS, "Multiple --patterns options is not permitted");
865
if (i + 1 >= a->argc)
866
return errorArgument("Missing argument to '%s'", a->argv[i]);
867
pszPattern = a->argv[++i];
869
else if ( !strcmp(a->argv[i], "--descriptions")
870
|| !strcmp(a->argv[i], "-descriptions"))
871
fWithDescriptions = true;
872
/* add: --file <filename> and --formatted */
873
else if ( !strcmp(a->argv[i], "--reset")
874
|| !strcmp(a->argv[i], "-reset"))
877
return errorSyntax(USAGE_VM_STATISTICS, "Unknown option '%s'", a->argv[i]);
879
if (fReset && fWithDescriptions)
880
return errorSyntax(USAGE_VM_STATISTICS, "The --reset and --descriptions options does not mix");
883
/* open an existing session for the VM. */
884
CHECK_ERROR(a->virtualBox, OpenExistingSession(a->session, uuid));
887
/* get the session console. */
888
ComPtr <IConsole> console;
889
CHECK_ERROR(a->session, COMGETTER(Console)(console.asOutParam()));
892
/* get the machine debugger. */
893
ComPtr <IMachineDebugger> debugger;
894
CHECK_ERROR(console, COMGETTER(Debugger)(debugger.asOutParam()));
898
CHECK_ERROR(debugger, ResetStats(Bstr(pszPattern)));
902
CHECK_ERROR(debugger, GetStats(Bstr(pszPattern), fWithDescriptions, stats.asOutParam()));
909
RTPrintf("%ls\n", stats.raw());
917
return SUCCEEDED(rc) ? 0 : 1;