VirtualBox

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

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

forgotten file

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.0 KB
RevLine 
[12599]1/* $Id: VBoxManageMisc.cpp 25377 2009-12-14 19:28:05Z 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
[1]27#include <VBox/com/com.h>
28#include <VBox/com/string.h>
29#include <VBox/com/Guid.h>
[7379]30#include <VBox/com/array.h>
[1]31#include <VBox/com/ErrorInfo.h>
[20928]32#include <VBox/com/errorprint.h>
[1]33#include <VBox/com/EventQueue.h>
34
35#include <VBox/com/VirtualBox.h>
36
37#include <vector>
[7379]38#include <list>
[11765]39#endif /* !VBOX_ONLY_DOCS */
[1]40
[14619]41#include <iprt/asm.h>
[22562]42#include <iprt/buildconfig.h>
[14619]43#include <iprt/cidr.h>
44#include <iprt/ctype.h>
45#include <iprt/dir.h>
46#include <iprt/env.h>
47#include <VBox/err.h>
48#include <iprt/file.h>
[14613]49#include <iprt/initterm.h>
[14619]50#include <iprt/param.h>
51#include <iprt/path.h>
[1]52#include <iprt/stream.h>
53#include <iprt/string.h>
[14613]54#include <iprt/stdarg.h>
[14619]55#include <iprt/thread.h>
[1]56#include <iprt/uuid.h>
[18782]57#include <iprt/getopt.h>
58#include <iprt/ctype.h>
[1]59#include <VBox/version.h>
[14814]60#include <VBox/log.h>
[1]61
62#include "VBoxManage.h"
63
64using namespace com;
65
[18396]66
67
[24907]68int handleRegisterVM(HandlerArg *a)
[18396]69{
[1]70 HRESULT rc;
71
[16052]72 if (a->argc != 1)
[1]73 return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");
74
75 ComPtr<IMachine> machine;
[18819]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)
81 {
82 char szVMFileAbs[RTPATH_MAX] = "";
83 int vrc = RTPathAbs(a->argv[0], szVMFileAbs, sizeof(szVMFileAbs));
84 if (RT_FAILURE(vrc))
85 {
86 RTPrintf("Cannot convert filename \"%s\" to absolute path\n", a->argv[0]);
87 return 1;
88 }
89 CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(szVMFileAbs), machine.asOutParam()));
90 }
[18901]91 else if (FAILED(rc))
[18819]92 CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(a->argv[0]), machine.asOutParam()));
[1]93 if (SUCCEEDED(rc))
94 {
95 ASSERT(machine);
[16052]96 CHECK_ERROR(a->virtualBox, RegisterMachine(machine));
[1]97 }
98 return SUCCEEDED(rc) ? 0 : 1;
99}
100
[18782]101static const RTGETOPTDEF g_aUnregisterVMOptions[] =
102{
[18783]103 { "--delete", 'd', RTGETOPT_REQ_NOTHING },
104 { "-delete", 'd', RTGETOPT_REQ_NOTHING }, // deprecated
[18782]105};
106
[24907]107int handleUnregisterVM(HandlerArg *a)
[1]108{
109 HRESULT rc;
[18782]110 const char *VMName = NULL;
111 bool fDelete = false;
[1]112
[18782]113 int c;
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)))
119 {
120 switch (c)
121 {
122 case 'd': // --delete
123 fDelete = true;
124 break;
[1]125
[18782]126 case VINF_GETOPT_NOT_OPTION:
127 if (!VMName)
128 VMName = ValueUnion.psz;
129 else
130 return errorSyntax(USAGE_UNREGISTERVM, "Invalid parameter '%s'", ValueUnion.psz);
131 break;
132
133 default:
134 if (c > 0)
135 {
136 if (RT_C_IS_PRINT(c))
137 return errorSyntax(USAGE_UNREGISTERVM, "Invalid option -%c", c);
138 else
139 return errorSyntax(USAGE_UNREGISTERVM, "Invalid option case %i", c);
140 }
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);
145 else
146 return errorSyntax(USAGE_UNREGISTERVM, "error: %Rrs", c);
147 }
148 }
149
150 /* check for required options */
151 if (!VMName)
152 return errorSyntax(USAGE_UNREGISTERVM, "VM name required");
153
[1]154 ComPtr<IMachine> machine;
155 /* assume it's a UUID */
[19239]156 rc = a->virtualBox->GetMachine(Guid(VMName).toUtf16(), machine.asOutParam());
[1]157 if (FAILED(rc) || !machine)
158 {
159 /* must be a name */
[18782]160 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMName), machine.asOutParam()));
[1]161 }
162 if (machine)
163 {
[19239]164 Bstr uuid;
[1]165 machine->COMGETTER(Id)(uuid.asOutParam());
166 machine = NULL;
[16052]167 CHECK_ERROR(a->virtualBox, UnregisterMachine(uuid, machine.asOutParam()));
[18782]168 if (SUCCEEDED(rc) && machine && fDelete)
169 CHECK_ERROR(machine, DeleteSettings());
[1]170 }
171 return SUCCEEDED(rc) ? 0 : 1;
172}
173
[24907]174int handleCreateVM(HandlerArg *a)
[1]175{
176 HRESULT rc;
177 Bstr baseFolder;
178 Bstr settingsFile;
179 Bstr name;
[14664]180 Bstr osTypeId;
[5292]181 RTUUID id;
[1]182 bool fRegister = false;
183
[6858]184 RTUuidClear(&id);
[16052]185 for (int i = 0; i < a->argc; i++)
[1]186 {
[18782]187 if ( !strcmp(a->argv[i], "--basefolder")
188 || !strcmp(a->argv[i], "-basefolder"))
[1]189 {
[16052]190 if (a->argc <= i + 1)
191 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]192 i++;
[16052]193 baseFolder = a->argv[i];
[1]194 }
[18782]195 else if ( !strcmp(a->argv[i], "--settingsfile")
196 || !strcmp(a->argv[i], "-settingsfile"))
[1]197 {
[16052]198 if (a->argc <= i + 1)
199 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]200 i++;
[16052]201 settingsFile = a->argv[i];
[1]202 }
[18782]203 else if ( !strcmp(a->argv[i], "--name")
204 || !strcmp(a->argv[i], "-name"))
[1]205 {
[16052]206 if (a->argc <= i + 1)
207 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]208 i++;
[16052]209 name = a->argv[i];
[1]210 }
[18782]211 else if ( !strcmp(a->argv[i], "--ostype")
212 || !strcmp(a->argv[i], "-ostype"))
[14664]213 {
[16052]214 if (a->argc <= i + 1)
215 return errorArgument("Missing argument to '%s'", a->argv[i]);
[14664]216 i++;
[16052]217 osTypeId = a->argv[i];
[14664]218 }
[18782]219 else if ( !strcmp(a->argv[i], "--uuid")
220 || !strcmp(a->argv[i], "-uuid"))
[5292]221 {
[16052]222 if (a->argc <= i + 1)
223 return errorArgument("Missing argument to '%s'", a->argv[i]);
[5292]224 i++;
[16052]225 if (RT_FAILURE(RTUuidFromStr(&id, a->argv[i])))
226 return errorArgument("Invalid UUID format %s\n", a->argv[i]);
[5292]227 }
[18782]228 else if ( !strcmp(a->argv[i], "--register")
229 || !strcmp(a->argv[i], "-register"))
[1]230 {
231 fRegister = true;
232 }
233 else
[16052]234 return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
[1]235 }
236 if (!name)
[18782]237 return errorSyntax(USAGE_CREATEVM, "Parameter --name is required");
[8373]238
[1]239 if (!!baseFolder && !!settingsFile)
[18782]240 return errorSyntax(USAGE_CREATEVM, "Either --basefolder or --settingsfile must be specified");
[1]241
242 do
243 {
244 ComPtr<IMachine> machine;
245
246 if (!settingsFile)
[16052]247 CHECK_ERROR_BREAK(a->virtualBox,
[19239]248 CreateMachine(name, osTypeId, baseFolder, Guid(id).toUtf16(), machine.asOutParam()));
[1]249 else
[16052]250 CHECK_ERROR_BREAK(a->virtualBox,
[19239]251 CreateLegacyMachine(name, osTypeId, settingsFile, Guid(id).toUtf16(), machine.asOutParam()));
[1]252
253 CHECK_ERROR_BREAK(machine, SaveSettings());
254 if (fRegister)
255 {
[16052]256 CHECK_ERROR_BREAK(a->virtualBox, RegisterMachine(machine));
[1]257 }
[19239]258 Bstr uuid;
[1]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"
262 "UUID: %s\n"
263 "Settings file: '%ls'\n",
264 name.raw(), fRegister ? " and registered" : "",
[19239]265 Utf8Str(uuid).raw(), settingsFile.raw());
[1]266 }
267 while (0);
268
269 return SUCCEEDED(rc) ? 0 : 1;
270}
271
[24907]272int handleStartVM(HandlerArg *a)
[1]273{
274 HRESULT rc;
[18782]275 const char *VMName = NULL;
276 Bstr sessionType = "gui";
[1]277
[24903]278 static const RTGETOPTDEF s_aStartVMOptions[] =
279 {
280 { "--type", 't', RTGETOPT_REQ_STRING },
281 { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
282 };
[18782]283 int c;
284 RTGETOPTUNION ValueUnion;
285 RTGETOPTSTATE GetState;
286 // start at 0 because main() has hacked both the argc and argv given to us
[24903]287 RTGetOptInit(&GetState, a->argc, a->argv, s_aStartVMOptions, RT_ELEMENTS(s_aStartVMOptions), 0, 0 /* fFlags */);
[18782]288 while ((c = RTGetOpt(&GetState, &ValueUnion)))
289 {
290 switch (c)
291 {
292 case 't': // --type
293 if (!RTStrICmp(ValueUnion.psz, "gui"))
294 {
295 sessionType = "gui";
296 }
297#ifdef VBOX_WITH_VBOXSDL
298 else if (!RTStrICmp(ValueUnion.psz, "sdl"))
299 {
300 sessionType = "sdl";
301 }
302#endif
303#ifdef VBOX_WITH_VRDP
304 else if (!RTStrICmp(ValueUnion.psz, "vrdp"))
305 {
306 sessionType = "vrdp";
307 }
308#endif
[20313]309#ifdef VBOX_WITH_HEADLESS
[18782]310 else if (!RTStrICmp(ValueUnion.psz, "capture"))
311 {
312 sessionType = "capture";
313 }
[20313]314 else if (!RTStrICmp(ValueUnion.psz, "headless"))
315 {
316 sessionType = "headless";
317 }
318#endif
[18782]319 else
320 return errorArgument("Invalid session type '%s'", ValueUnion.psz);
321 break;
[1]322
[18782]323 case VINF_GETOPT_NOT_OPTION:
324 if (!VMName)
325 VMName = ValueUnion.psz;
326 else
327 return errorSyntax(USAGE_STARTVM, "Invalid parameter '%s'", ValueUnion.psz);
328 break;
329
330 default:
331 if (c > 0)
332 {
333 if (RT_C_IS_PRINT(c))
334 return errorSyntax(USAGE_STARTVM, "Invalid option -%c", c);
335 else
336 return errorSyntax(USAGE_STARTVM, "Invalid option case %i", c);
337 }
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);
342 else
343 return errorSyntax(USAGE_STARTVM, "error: %Rrs", c);
344 }
345 }
346
347 /* check for required options */
348 if (!VMName)
349 return errorSyntax(USAGE_STARTVM, "VM name required");
350
[1]351 ComPtr<IMachine> machine;
352 /* assume it's a UUID */
[19239]353 rc = a->virtualBox->GetMachine(Guid(VMName).toUtf16(), machine.asOutParam());
[1]354 if (FAILED(rc) || !machine)
355 {
356 /* must be a name */
[18782]357 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMName), machine.asOutParam()));
[1]358 }
359 if (machine)
360 {
[19239]361 Bstr uuid;
[1]362 machine->COMGETTER(Id)(uuid.asOutParam());
363
364
[4064]365 Bstr env;
[18782]366#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
[4064]367 /* make sure the VM process will start on the same display as VBoxManage */
[23285]368 Utf8Str str;
369 const char *pszDisplay = RTEnvGet("DISPLAY");
[23287]370 if (pszDisplay)
371 str = Utf8StrFmt("DISPLAY=%s\n", pszDisplay);
[23285]372 const char *pszXAuth = RTEnvGet("XAUTHORITY");
373 if (pszXAuth)
374 str.append(Utf8StrFmt("XAUTHORITY=%s\n", pszXAuth));
[23286]375 env = str;
[4064]376#endif
[1]377 ComPtr<IProgress> progress;
[16052]378 CHECK_ERROR_RET(a->virtualBox, OpenRemoteSession(a->session, uuid, sessionType,
379 env, progress.asOutParam()), rc);
[1]380 RTPrintf("Waiting for the remote session to open...\n");
381 CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1);
382
383 BOOL completed;
384 CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc);
385 ASSERT(completed);
386
[20220]387 LONG iRc;
[19311]388 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
389 if (FAILED(iRc))
[1]390 {
391 ComPtr <IVirtualBoxErrorInfo> errorInfo;
392 CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1);
393 ErrorInfo info (errorInfo);
[20928]394 com::GluePrintErrorInfo(info);
[1]395 }
396 else
397 {
398 RTPrintf("Remote session has been successfully opened.\n");
399 }
400 }
401
402 /* it's important to always close sessions */
[16052]403 a->session->Close();
[1]404
405 return SUCCEEDED(rc) ? 0 : 1;
406}
407
[24907]408int handleDiscardState(HandlerArg *a)
[1]409{
410 HRESULT rc;
411
[16052]412 if (a->argc != 1)
[1]413 return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");
414
415 ComPtr<IMachine> machine;
416 /* assume it's a UUID */
[19239]417 rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
[1]418 if (FAILED(rc) || !machine)
419 {
420 /* must be a name */
[16052]421 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
[1]422 }
423 if (machine)
424 {
425 do
426 {
427 /* we have to open a session for this task */
[19239]428 Bstr guid;
[1]429 machine->COMGETTER(Id)(guid.asOutParam());
[16052]430 CHECK_ERROR_BREAK(a->virtualBox, OpenSession(a->session, guid));
[5391]431 do
432 {
433 ComPtr<IConsole> console;
[16052]434 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
[20928]435 CHECK_ERROR_BREAK(console, ForgetSavedState(true));
[23934]436 } while (0);
[16052]437 CHECK_ERROR_BREAK(a->session, Close());
[23934]438 } while (0);
[1]439 }
440
441 return SUCCEEDED(rc) ? 0 : 1;
442}
443
[25377]444int handleAdoptState(HandlerArg *a)
[5391]445{
446 HRESULT rc;
447
[16052]448 if (a->argc != 2)
[5391]449 return errorSyntax(USAGE_ADOPTSTATE, "Incorrect number of parameters");
450
451 ComPtr<IMachine> machine;
452 /* assume it's a UUID */
[19239]453 rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
[5391]454 if (FAILED(rc) || !machine)
455 {
456 /* must be a name */
[16052]457 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
[5391]458 }
459 if (machine)
460 {
461 do
462 {
463 /* we have to open a session for this task */
[19239]464 Bstr guid;
[5391]465 machine->COMGETTER(Id)(guid.asOutParam());
[16052]466 CHECK_ERROR_BREAK(a->virtualBox, OpenSession(a->session, guid));
[5391]467 do
468 {
469 ComPtr<IConsole> console;
[16052]470 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
[23934]471 CHECK_ERROR_BREAK(console, AdoptSavedState(Bstr(a->argv[1])));
472 } while (0);
[16052]473 CHECK_ERROR_BREAK(a->session, Close());
[23934]474 } while (0);
[5391]475 }
476
477 return SUCCEEDED(rc) ? 0 : 1;
478}
479
[24907]480int handleGetExtraData(HandlerArg *a)
[1]481{
482 HRESULT rc = S_OK;
483
[16052]484 if (a->argc != 2)
[1]485 return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");
[8373]486
[1]487 /* global data? */
[18782]488 if (!strcmp(a->argv[0], "global"))
[1]489 {
490 /* enumeration? */
[18782]491 if (!strcmp(a->argv[1], "enumerate"))
[1]492 {
[22173]493 SafeArray<BSTR> aKeys;
494 CHECK_ERROR(a->virtualBox, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
[1]495
[22173]496 for (size_t i = 0;
497 i < aKeys.size();
498 ++i)
[1]499 {
[22173]500 Bstr bstrKey(aKeys[i]);
501 Bstr bstrValue;
502 CHECK_ERROR(a->virtualBox, GetExtraData(bstrKey, bstrValue.asOutParam()));
[1]503
[22173]504 RTPrintf("Key: %lS, Value: %lS\n", bstrKey.raw(), bstrValue.raw());
505 }
[1]506 }
507 else
508 {
509 Bstr value;
[16052]510 CHECK_ERROR(a->virtualBox, GetExtraData(Bstr(a->argv[1]), value.asOutParam()));
[20977]511 if (!value.isEmpty())
[1]512 RTPrintf("Value: %lS\n", value.raw());
513 else
514 RTPrintf("No value set!\n");
515 }
516 }
517 else
518 {
519 ComPtr<IMachine> machine;
520 /* assume it's a UUID */
[19239]521 rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
[1]522 if (FAILED(rc) || !machine)
523 {
524 /* must be a name */
[16052]525 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
[1]526 }
527 if (machine)
528 {
529 /* enumeration? */
[18782]530 if (!strcmp(a->argv[1], "enumerate"))
[1]531 {
[22173]532 SafeArray<BSTR> aKeys;
533 CHECK_ERROR(machine, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys)));
[1]534
[22173]535 for (size_t i = 0;
536 i < aKeys.size();
537 ++i)
[1]538 {
[22173]539 Bstr bstrKey(aKeys[i]);
540 Bstr bstrValue;
541 CHECK_ERROR(machine, GetExtraData(bstrKey, bstrValue.asOutParam()));
[1]542
[22173]543 RTPrintf("Key: %lS, Value: %lS\n", bstrKey.raw(), bstrValue.raw());
544 }
[1]545 }
546 else
547 {
548 Bstr value;
[16052]549 CHECK_ERROR(machine, GetExtraData(Bstr(a->argv[1]), value.asOutParam()));
[20977]550 if (!value.isEmpty())
[1]551 RTPrintf("Value: %lS\n", value.raw());
552 else
553 RTPrintf("No value set!\n");
554 }
555 }
556 }
557 return SUCCEEDED(rc) ? 0 : 1;
558}
559
[24907]560int handleSetExtraData(HandlerArg *a)
[1]561{
562 HRESULT rc = S_OK;
563
[16052]564 if (a->argc < 2)
[1]565 return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");
[8373]566
[1]567 /* global data? */
[18782]568 if (!strcmp(a->argv[0], "global"))
[1]569 {
[16052]570 if (a->argc < 3)
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])));
[1]574 else
[947]575 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
[1]576 }
577 else
578 {
579 ComPtr<IMachine> machine;
580 /* assume it's a UUID */
[19239]581 rc = a->virtualBox->GetMachine(Bstr(a->argv[0]), machine.asOutParam());
[1]582 if (FAILED(rc) || !machine)
583 {
584 /* must be a name */
[16052]585 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
[1]586 }
587 if (machine)
588 {
[16052]589 if (a->argc < 3)
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])));
[1]593 else
[947]594 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
[1]595 }
596 }
597 return SUCCEEDED(rc) ? 0 : 1;
598}
599
[24907]600int handleSetProperty(HandlerArg *a)
[1]601{
602 HRESULT rc;
603
604 /* there must be two arguments: property name and value */
[16052]605 if (a->argc != 2)
[1]606 return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");
[8373]607
[1]608 ComPtr<ISystemProperties> systemProperties;
[16052]609 a->virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
[1]610
[18782]611 if (!strcmp(a->argv[0], "hdfolder"))
[1]612 {
613 /* reset to default? */
[18782]614 if (!strcmp(a->argv[1], "default"))
[13580]615 CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(NULL));
[1]616 else
[16052]617 CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(Bstr(a->argv[1])));
[1]618 }
[18782]619 else if (!strcmp(a->argv[0], "machinefolder"))
[1]620 {
621 /* reset to default? */
[18782]622 if (!strcmp(a->argv[1], "default"))
[1]623 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
624 else
[16052]625 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(a->argv[1])));
[1]626 }
[18782]627 else if (!strcmp(a->argv[0], "vrdpauthlibrary"))
[1]628 {
629 /* reset to default? */
[18782]630 if (!strcmp(a->argv[1], "default"))
[1]631 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));
632 else
[16052]633 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(a->argv[1])));
[1]634 }
[18782]635 else if (!strcmp(a->argv[0], "websrvauthlibrary"))
[5771]636 {
637 /* reset to default? */
[18782]638 if (!strcmp(a->argv[1], "default"))
[5771]639 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));
640 else
[16052]641 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(a->argv[1])));
[5771]642 }
[18782]643 else if (!strcmp(a->argv[0], "loghistorycount"))
[5150]644 {
645 uint32_t uVal;
646 int vrc;
[16052]647 vrc = RTStrToUInt32Ex(a->argv[1], NULL, 0, &uVal);
[5150]648 if (vrc != VINF_SUCCESS)
[16052]649 return errorArgument("Error parsing Log history count '%s'", a->argv[1]);
[5150]650 CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));
651 }
[1]652 else
[16052]653 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", a->argv[0]);
[1]654
655 return SUCCEEDED(rc) ? 0 : 1;
656}
657
[24907]658int handleSharedFolder(HandlerArg *a)
[1]659{
660 HRESULT rc;
661
662 /* we need at least a command and target */
[16052]663 if (a->argc < 2)
[1]664 return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
665
666 ComPtr<IMachine> machine;
667 /* assume it's a UUID */
[19239]668 rc = a->virtualBox->GetMachine(Bstr(a->argv[1]), machine.asOutParam());
[1]669 if (FAILED(rc) || !machine)
670 {
671 /* must be a name */
[16052]672 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[1]), machine.asOutParam()));
[1]673 }
674 if (!machine)
675 return 1;
[19239]676 Bstr uuid;
[1]677 machine->COMGETTER(Id)(uuid.asOutParam());
678
[18782]679 if (!strcmp(a->argv[0], "add"))
[1]680 {
681 /* we need at least four more parameters */
[16052]682 if (a->argc < 5)
[1]683 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");
684
685 char *name = NULL;
686 char *hostpath = NULL;
687 bool fTransient = false;
[6384]688 bool fWritable = true;
[1]689
[16052]690 for (int i = 2; i < a->argc; i++)
[1]691 {
[18782]692 if ( !strcmp(a->argv[i], "--name")
693 || !strcmp(a->argv[i], "-name"))
[1]694 {
[16052]695 if (a->argc <= i + 1 || !*a->argv[i+1])
696 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]697 i++;
[16052]698 name = a->argv[i];
[1]699 }
[18782]700 else if ( !strcmp(a->argv[i], "--hostpath")
701 || !strcmp(a->argv[i], "-hostpath"))
[1]702 {
[16052]703 if (a->argc <= i + 1 || !*a->argv[i+1])
704 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]705 i++;
[16052]706 hostpath = a->argv[i];
[1]707 }
[18782]708 else if ( !strcmp(a->argv[i], "--readonly")
709 || !strcmp(a->argv[i], "-readonly"))
[6384]710 {
711 fWritable = false;
712 }
[18782]713 else if ( !strcmp(a->argv[i], "--transient")
714 || !strcmp(a->argv[i], "-transient"))
[1]715 {
716 fTransient = true;
717 }
718 else
[16052]719 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
[1]720 }
721
[9551]722 if (NULL != strstr(name, " "))
723 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");
724
[1]725 /* required arguments */
726 if (!name || !hostpath)
727 {
[18782]728 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters --name and --hostpath are required");
[1]729 }
730
731 if (fTransient)
732 {
733 ComPtr <IConsole> console;
734
735 /* open an existing session for the VM */
[23934]736 CHECK_ERROR_RET(a->virtualBox, OpenExistingSession(a->session, uuid), 1);
[1]737 /* get the session machine */
[16052]738 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
[1]739 /* get the session console */
[16052]740 CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
[1]741
[6384]742 CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
[1]743
744 if (console)
[16052]745 a->session->Close();
[1]746 }
747 else
748 {
749 /* open a session for the VM */
[23934]750 CHECK_ERROR_RET(a->virtualBox, OpenSession(a->session, uuid), 1);
[1]751
752 /* get the mutable session machine */
[16052]753 a->session->COMGETTER(Machine)(machine.asOutParam());
[1]754
[6384]755 CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
[1]756
[1026]757 if (SUCCEEDED(rc))
758 CHECK_ERROR(machine, SaveSettings());
759
[16052]760 a->session->Close();
[1]761 }
762 }
[18782]763 else if (!strcmp(a->argv[0], "remove"))
[1]764 {
765 /* we need at least two more parameters */
[16052]766 if (a->argc < 3)
[1]767 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");
768
769 char *name = NULL;
770 bool fTransient = false;
771
[16052]772 for (int i = 2; i < a->argc; i++)
[1]773 {
[18782]774 if ( !strcmp(a->argv[i], "--name")
775 || !strcmp(a->argv[i], "-name"))
[1]776 {
[16052]777 if (a->argc <= i + 1 || !*a->argv[i+1])
778 return errorArgument("Missing argument to '%s'", a->argv[i]);
[1]779 i++;
[16052]780 name = a->argv[i];
[1]781 }
[18782]782 else if ( !strcmp(a->argv[i], "--transient")
783 || !strcmp(a->argv[i], "-transient"))
[1]784 {
785 fTransient = true;
786 }
787 else
[16052]788 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(a->argv[i]).raw());
[1]789 }
790
791 /* required arguments */
792 if (!name)
[18782]793 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter --name is required");
[1]794
795 if (fTransient)
796 {
797 ComPtr <IConsole> console;
798
799 /* open an existing session for the VM */
[23934]800 CHECK_ERROR_RET(a->virtualBox, OpenExistingSession(a->session, uuid), 1);
[1]801 /* get the session machine */
[16052]802 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(machine.asOutParam()), 1);
[1]803 /* get the session console */
[16052]804 CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), 1);
[1]805
806 CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));
807
808 if (console)
[16052]809 a->session->Close();
[1]810 }
811 else
812 {
813 /* open a session for the VM */
[23934]814 CHECK_ERROR_RET(a->virtualBox, OpenSession(a->session, uuid), 1);
[1]815
816 /* get the mutable session machine */
[16052]817 a->session->COMGETTER(Machine)(machine.asOutParam());
[1]818
819 CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));
820
821 /* commit and close the session */
822 CHECK_ERROR(machine, SaveSettings());
[16052]823 a->session->Close();
[1]824 }
825 }
826 else
[16052]827 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(a->argv[0]).raw());
[8373]828
[1]829 return 0;
830}
831
[24907]832int handleVMStatistics(HandlerArg *a)
[5204]833{
834 HRESULT rc;
835
836 /* at least one option: the UUID or name of the VM */
[16052]837 if (a->argc < 1)
[5204]838 return errorSyntax(USAGE_VM_STATISTICS, "Incorrect number of parameters");
839
840 /* try to find the given machine */
841 ComPtr <IMachine> machine;
[19239]842 Bstr uuid (a->argv[0]);
[20294]843 if (!Guid (a->argv[0]).isEmpty())
[16052]844 CHECK_ERROR(a->virtualBox, GetMachine(uuid, machine.asOutParam()));
[5204]845 else
846 {
[16052]847 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()));
[5204]848 if (SUCCEEDED (rc))
849 machine->COMGETTER(Id)(uuid.asOutParam());
850 }
851 if (FAILED(rc))
852 return 1;
853
[5253]854 /* parse arguments. */
855 bool fReset = false;
[5204]856 bool fWithDescriptions = false;
857 const char *pszPattern = NULL; /* all */
[16052]858 for (int i = 1; i < a->argc; i++)
[5204]859 {
[18782]860 if ( !strcmp(a->argv[i], "--pattern")
861 || !strcmp(a->argv[i], "-pattern"))
[5204]862 {
863 if (pszPattern)
[18782]864 return errorSyntax(USAGE_VM_STATISTICS, "Multiple --patterns options is not permitted");
[16052]865 if (i + 1 >= a->argc)
866 return errorArgument("Missing argument to '%s'", a->argv[i]);
867 pszPattern = a->argv[++i];
[5204]868 }
[18782]869 else if ( !strcmp(a->argv[i], "--descriptions")
870 || !strcmp(a->argv[i], "-descriptions"))
[5204]871 fWithDescriptions = true;
[18782]872 /* add: --file <filename> and --formatted */
873 else if ( !strcmp(a->argv[i], "--reset")
874 || !strcmp(a->argv[i], "-reset"))
[5253]875 fReset = true;
[5204]876 else
[16052]877 return errorSyntax(USAGE_VM_STATISTICS, "Unknown option '%s'", a->argv[i]);
[5204]878 }
[5253]879 if (fReset && fWithDescriptions)
[18782]880 return errorSyntax(USAGE_VM_STATISTICS, "The --reset and --descriptions options does not mix");
[5204]881
[5253]882
[5204]883 /* open an existing session for the VM. */
[16052]884 CHECK_ERROR(a->virtualBox, OpenExistingSession(a->session, uuid));
[5204]885 if (SUCCEEDED(rc))
886 {
887 /* get the session console. */
888 ComPtr <IConsole> console;
[16052]889 CHECK_ERROR(a->session, COMGETTER(Console)(console.asOutParam()));
[5204]890 if (SUCCEEDED(rc))
891 {
892 /* get the machine debugger. */
893 ComPtr <IMachineDebugger> debugger;
894 CHECK_ERROR(console, COMGETTER(Debugger)(debugger.asOutParam()));
895 if (SUCCEEDED(rc))
896 {
[5253]897 if (fReset)
[15051]898 CHECK_ERROR(debugger, ResetStats(Bstr(pszPattern)));
[5253]899 else
[5204]900 {
901 Bstr stats;
[15051]902 CHECK_ERROR(debugger, GetStats(Bstr(pszPattern), fWithDescriptions, stats.asOutParam()));
[5204]903 if (SUCCEEDED(rc))
904 {
[5253]905 /* if (fFormatted)
906 { big mess }
907 else
908 */
[5204]909 RTPrintf("%ls\n", stats.raw());
910 }
911 }
912 }
[16052]913 a->session->Close();
[5204]914 }
915 }
916
917 return SUCCEEDED(rc) ? 0 : 1;
918}
[11384]919
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use