VirtualBox

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

Last change on this file since 60901 was 60410, checked in by vboxsync, 9 years ago

IMachine: Added CPUProfile attribute (read/write string). Added a modifyvm option for setting it. Show non-default values in showvminfo, but always show it starting with 6.0.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 115.2 KB
Line 
1/* $Id: VBoxManageInfo.cpp 60410 2016-04-10 15:42:46Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'showvminfo' command and helper routines.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
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
18#ifndef VBOX_ONLY_DOCS
19
20
21/*********************************************************************************************************************************
22* Header Files *
23*********************************************************************************************************************************/
24#include <VBox/com/com.h>
25#include <VBox/com/string.h>
26#include <VBox/com/Guid.h>
27#include <VBox/com/array.h>
28#include <VBox/com/ErrorInfo.h>
29#include <VBox/com/errorprint.h>
30
31#include <VBox/com/VirtualBox.h>
32
33#ifdef VBOX_WITH_PCI_PASSTHROUGH
34#include <VBox/pci.h>
35#endif
36
37#include <VBox/log.h>
38#include <VBox/version.h>
39#include <iprt/stream.h>
40#include <iprt/time.h>
41#include <iprt/string.h>
42#include <iprt/getopt.h>
43#include <iprt/ctype.h>
44
45#include "VBoxManage.h"
46using namespace com;
47
48
49// funcs
50///////////////////////////////////////////////////////////////////////////////
51
52HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
53 ComPtr<ISnapshot> &currentSnapshot,
54 VMINFO_DETAILS details,
55 const Utf8Str &prefix /* = ""*/,
56 int level /*= 0*/)
57{
58 /* start with the root */
59 Bstr name;
60 Bstr uuid;
61 Bstr description;
62 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Name)(name.asOutParam()), hrcCheck);
63 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Id)(uuid.asOutParam()), hrcCheck);
64 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Description)(description.asOutParam()), hrcCheck);
65 bool fCurrent = (rootSnapshot == currentSnapshot);
66 if (details == VMINFO_MACHINEREADABLE)
67 {
68 /* print with hierarchical numbering */
69 RTPrintf("SnapshotName%s=\"%ls\"\n", prefix.c_str(), name.raw());
70 RTPrintf("SnapshotUUID%s=\"%s\"\n", prefix.c_str(), Utf8Str(uuid).c_str());
71 if (!description.isEmpty())
72 RTPrintf("SnapshotDescription%s=\"%ls\"\n", prefix.c_str(), description.raw());
73 if (fCurrent)
74 {
75 RTPrintf("CurrentSnapshotName=\"%ls\"\n", name.raw());
76 RTPrintf("CurrentSnapshotUUID=\"%s\"\n", Utf8Str(uuid).c_str());
77 RTPrintf("CurrentSnapshotNode=\"SnapshotName%s\"\n", prefix.c_str());
78 }
79 }
80 else
81 {
82 /* print with indentation */
83 RTPrintf(" %sName: %ls (UUID: %s)%s\n",
84 prefix.c_str(),
85 name.raw(),
86 Utf8Str(uuid).c_str(),
87 (fCurrent) ? " *" : "");
88 if (!description.isEmpty())
89 RTPrintf(" %sDescription:\n%ls\n", prefix.c_str(), description.raw());
90 }
91
92 /* get the children */
93 HRESULT hrc = S_OK;
94 SafeIfaceArray <ISnapshot> coll;
95 CHECK_ERROR2I_RET(rootSnapshot,COMGETTER(Children)(ComSafeArrayAsOutParam(coll)), hrcCheck);
96 if (!coll.isNull())
97 {
98 for (size_t index = 0; index < coll.size(); ++index)
99 {
100 ComPtr<ISnapshot> snapshot = coll[index];
101 if (snapshot)
102 {
103 Utf8Str newPrefix;
104 if (details == VMINFO_MACHINEREADABLE)
105 newPrefix = Utf8StrFmt("%s-%d", prefix.c_str(), index + 1);
106 else
107 {
108 newPrefix = Utf8StrFmt("%s ", prefix.c_str());
109 }
110
111 /* recursive call */
112 HRESULT hrc2 = showSnapshots(snapshot, currentSnapshot, details, newPrefix, level + 1);
113 if (FAILED(hrc2))
114 hrc = hrc2;
115 }
116 }
117 }
118 return hrc;
119}
120
121static void makeTimeStr(char *s, int cb, int64_t millies)
122{
123 RTTIME t;
124 RTTIMESPEC ts;
125
126 RTTimeSpecSetMilli(&ts, millies);
127
128 RTTimeExplode(&t, &ts);
129
130 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
131 t.i32Year, t.u8Month, t.u8MonthDay,
132 t.u8Hour, t.u8Minute, t.u8Second);
133}
134
135const char *machineStateToName(MachineState_T machineState, bool fShort)
136{
137 switch (machineState)
138 {
139 case MachineState_PoweredOff:
140 return fShort ? "poweroff" : "powered off";
141 case MachineState_Saved:
142 return "saved";
143 case MachineState_Teleported:
144 return "teleported";
145 case MachineState_Aborted:
146 return "aborted";
147 case MachineState_Running:
148 return "running";
149 case MachineState_Paused:
150 return "paused";
151 case MachineState_Stuck:
152 return fShort ? "gurumeditation" : "guru meditation";
153 case MachineState_Teleporting:
154 return "teleporting";
155 case MachineState_LiveSnapshotting:
156 return fShort ? "livesnapshotting" : "live snapshotting";
157 case MachineState_Starting:
158 return "starting";
159 case MachineState_Stopping:
160 return "stopping";
161 case MachineState_Saving:
162 return "saving";
163 case MachineState_Restoring:
164 return "restoring";
165 case MachineState_TeleportingPausedVM:
166 return fShort ? "teleportingpausedvm" : "teleporting paused vm";
167 case MachineState_TeleportingIn:
168 return fShort ? "teleportingin" : "teleporting (incoming)";
169 case MachineState_FaultTolerantSyncing:
170 return fShort ? "faulttolerantsyncing" : "fault tolerant syncing";
171 case MachineState_DeletingSnapshotOnline:
172 return fShort ? "deletingsnapshotlive" : "deleting snapshot live";
173 case MachineState_DeletingSnapshotPaused:
174 return fShort ? "deletingsnapshotlivepaused" : "deleting snapshot live paused";
175 case MachineState_OnlineSnapshotting:
176 return fShort ? "onlinesnapshotting" : "online snapshotting";
177 case MachineState_RestoringSnapshot:
178 return fShort ? "restoringsnapshot" : "restoring snapshot";
179 case MachineState_DeletingSnapshot:
180 return fShort ? "deletingsnapshot" : "deleting snapshot";
181 case MachineState_SettingUp:
182 return fShort ? "settingup" : "setting up";
183 case MachineState_Snapshotting:
184 return fShort ? "snapshotting" : "offline snapshotting";
185 default:
186 break;
187 }
188 return "unknown";
189}
190
191const char *facilityStateToName(AdditionsFacilityStatus_T faStatus, bool fShort)
192{
193 switch (faStatus)
194 {
195 case AdditionsFacilityStatus_Inactive:
196 return fShort ? "inactive" : "not active";
197 case AdditionsFacilityStatus_Paused:
198 return "paused";
199 case AdditionsFacilityStatus_PreInit:
200 return fShort ? "preinit" : "pre-initializing";
201 case AdditionsFacilityStatus_Init:
202 return fShort ? "init" : "initializing";
203 case AdditionsFacilityStatus_Active:
204 return fShort ? "active" : "active/running";
205 case AdditionsFacilityStatus_Terminating:
206 return "terminating";
207 case AdditionsFacilityStatus_Terminated:
208 return "terminated";
209 case AdditionsFacilityStatus_Failed:
210 return "failed";
211 case AdditionsFacilityStatus_Unknown:
212 default:
213 break;
214 }
215 return "unknown";
216}
217
218/**
219 * This takes care of escaping double quotes and slashes that the string might
220 * contain.
221 *
222 * @param pszName The variable name.
223 * @param pbstrValue The value.
224 */
225static void outputMachineReadableString(const char *pszName, Bstr const *pbstrValue)
226{
227 Assert(strpbrk(pszName, "\"\\") == NULL);
228
229 com::Utf8Str strValue(*pbstrValue);
230 if ( strValue.isEmpty()
231 || ( !strValue.count('"')
232 && !strValue.count('\\')))
233 RTPrintf("%s=\"%s\"\n", pszName, strValue.c_str());
234 else
235 {
236 /* The value needs escaping. */
237 RTPrintf("%s=\"", pszName);
238 const char *psz = strValue.c_str();
239 for (;;)
240 {
241 const char *pszNext = strpbrk(psz, "\"\\");
242 if (!pszNext)
243 {
244 RTPrintf("%s", psz);
245 break;
246 }
247 RTPrintf("%.*s\\%c", pszNext - psz, psz, *pszNext);
248 psz = pszNext + 1;
249 }
250 RTPrintf("\"\n");
251 }
252}
253
254/**
255 * Converts bandwidth group type to a string.
256 * @returns String representation.
257 * @param enmType Bandwidth control group type.
258 */
259inline const char * bwGroupTypeToString(BandwidthGroupType_T enmType)
260{
261 switch (enmType)
262 {
263 case BandwidthGroupType_Disk: return "Disk";
264 case BandwidthGroupType_Network: return "Network";
265 }
266 return "unknown";
267}
268
269HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
270 VMINFO_DETAILS details)
271{
272 int rc = S_OK;
273 SafeIfaceArray<IBandwidthGroup> bwGroups;
274
275 CHECK_ERROR_RET(bwCtrl, GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)), rc);
276
277 if (bwGroups.size() && details != VMINFO_MACHINEREADABLE)
278 RTPrintf("\n\n");
279 for (size_t i = 0; i < bwGroups.size(); i++)
280 {
281 Bstr strName;
282 LONG64 cMaxBytesPerSec;
283 BandwidthGroupType_T enmType;
284
285 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), rc);
286 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Type)(&enmType), rc);
287 CHECK_ERROR_RET(bwGroups[i], COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec), rc);
288
289 const char *pszType = bwGroupTypeToString(enmType);
290 if (details == VMINFO_MACHINEREADABLE)
291 RTPrintf("BandwidthGroup%zu=%ls,%s,%lld\n", i, strName.raw(), pszType, cMaxBytesPerSec);
292 else
293 {
294 const char *pszUnits = "";
295 LONG64 cBytes = cMaxBytesPerSec;
296 if (cBytes == 0)
297 {
298 RTPrintf("Name: '%ls', Type: %s, Limit: none (disabled)\n", strName.raw(), pszType);
299 continue;
300 }
301 else if (!(cBytes % _1G))
302 {
303 pszUnits = "G";
304 cBytes /= _1G;
305 }
306 else if (!(cBytes % _1M))
307 {
308 pszUnits = "M";
309 cBytes /= _1M;
310 }
311 else if (!(cBytes % _1K))
312 {
313 pszUnits = "K";
314 cBytes /= _1K;
315 }
316 const char *pszNetUnits = NULL;
317 if (enmType == BandwidthGroupType_Network)
318 {
319 /*
320 * We want to report network rate limit in bits/s, not bytes.
321 * Only if it cannot be express it in kilobits we will fall
322 * back to reporting it in bytes.
323 */
324 LONG64 cBits = cMaxBytesPerSec;
325 if (!(cBits % 125))
326 {
327 cBits /= 125;
328 pszNetUnits = "k";
329 if (!(cBits % 1000000))
330 {
331 cBits /= 1000000;
332 pszNetUnits = "g";
333 }
334 else if (!(cBits % 1000))
335 {
336 cBits /= 1000;
337 pszNetUnits = "m";
338 }
339 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbits/sec (%lld %sbytes/sec)\n", strName.raw(), pszType, cBits, pszNetUnits, cBytes, pszUnits);
340 }
341 }
342 if (!pszNetUnits)
343 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbytes/sec\n", strName.raw(), pszType, cBytes, pszUnits);
344 }
345 }
346 if (details != VMINFO_MACHINEREADABLE)
347 RTPrintf(bwGroups.size() != 0 ? "\n" : "<none>\n\n");
348
349 return rc;
350}
351
352static const char *paravirtProviderToString(ParavirtProvider_T provider, VMINFO_DETAILS details)
353{
354 switch (provider)
355 {
356 case ParavirtProvider_None:
357 if (details == VMINFO_MACHINEREADABLE)
358 return "none";
359 return "None";
360
361 case ParavirtProvider_Default:
362 if (details == VMINFO_MACHINEREADABLE)
363 return "default";
364 return "Default";
365
366 case ParavirtProvider_Legacy:
367 if (details == VMINFO_MACHINEREADABLE)
368 return "legacy";
369 return "Legacy";
370
371 case ParavirtProvider_Minimal:
372 if (details == VMINFO_MACHINEREADABLE)
373 return "minimal";
374 return "Minimal";
375
376 case ParavirtProvider_HyperV:
377 if (details == VMINFO_MACHINEREADABLE)
378 return "hyperv";
379 return "HyperV";
380
381 case ParavirtProvider_KVM:
382 if (details == VMINFO_MACHINEREADABLE)
383 return "kvm";
384 return "KVM";
385
386 default:
387 if (details == VMINFO_MACHINEREADABLE)
388 return "unknown";
389 return "Unknown";
390 }
391}
392
393
394/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
395 time. MSC 7.1/32 doesn't have quite as much trouble with it, but still
396 sufficient to qualify for this hack as well since this code isn't performance
397 critical and probably won't gain much from the extra optimizing in real life. */
398#if defined(_MSC_VER)
399# pragma optimize("g", off)
400#endif
401
402HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
403 ComPtr<IMachine> machine,
404 ComPtr<ISession> pSession,
405 VMINFO_DETAILS details /*= VMINFO_NONE*/)
406{
407 HRESULT rc;
408 ComPtr<IConsole> pConsole;
409 if (pSession)
410 pSession->COMGETTER(Console)(pConsole.asOutParam());
411
412#define SHOW_BOOLEAN_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
413 SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_szMachine, a_szHuman, "on", "off")
414
415#define SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szTrue, a_szFalse) \
416 do \
417 { \
418 BOOL f; \
419 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&f), hrcCheck); \
420 if (details == VMINFO_MACHINEREADABLE) \
421 RTPrintf( a_szMachine "=\"%s\"\n", f ? "on" : "off"); \
422 else \
423 RTPrintf("%-16s %s\n", a_szHuman ":", f ? a_szTrue : a_szFalse); \
424 } while (0)
425
426#define SHOW_BOOLEAN_METHOD(a_pObj, a_Invocation, a_szMachine, a_szHuman) \
427 do \
428 { \
429 BOOL f; \
430 CHECK_ERROR2I_RET(a_pObj, a_Invocation, hrcCheck); \
431 if (details == VMINFO_MACHINEREADABLE) \
432 RTPrintf( a_szMachine "=\"%s\"\n", f ? "on" : "off"); \
433 else \
434 RTPrintf("%-16s %s\n", a_szHuman ":", f ? "on" : "off"); \
435 } while (0)
436
437#define SHOW_STRING_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
438 do \
439 { \
440 Bstr bstr; \
441 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
442 if (details == VMINFO_MACHINEREADABLE) \
443 outputMachineReadableString(a_szMachine, &bstr); \
444 else \
445 RTPrintf("%-16s %ls\n", a_szHuman ":", bstr.raw()); \
446 } while (0)
447
448 /** @def SHOW_STRING_PROP_MAJ
449 * For not breaking the output in a dot release we don't show default values. */
450#define SHOW_STRING_PROP_MAJ(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szUnless, a_uMajorVer) \
451 do \
452 { \
453 Bstr bstr; \
454 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
455 if ((a_uMajorVer) <= VBOX_VERSION_MAJOR || !bstr.equals(a_szUnless)) \
456 { \
457 if (details == VMINFO_MACHINEREADABLE)\
458 outputMachineReadableString(a_szMachine, &bstr); \
459 else \
460 RTPrintf("%-16s %ls\n", a_szHuman ":", bstr.raw()); \
461 } \
462 } while (0)
463
464#define SHOW_STRINGARRAY_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
465 do \
466 { \
467 SafeArray<BSTR> array; \
468 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(ComSafeArrayAsOutParam(array)), hrcCheck); \
469 Utf8Str str; \
470 for (size_t i = 0; i < array.size(); i++) \
471 { \
472 if (i != 0) \
473 str.append(","); \
474 str.append(Utf8Str(array[i]).c_str()); \
475 } \
476 Bstr bstr(str); \
477 if (details == VMINFO_MACHINEREADABLE) \
478 outputMachineReadableString(a_szMachine, &bstr); \
479 else \
480 RTPrintf("%-16s %ls\n", a_szHuman ":", bstr.raw()); \
481 } while (0)
482
483#define SHOW_UUID_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
484 SHOW_STRING_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman)
485
486#define SHOW_ULONG_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szUnit) \
487 do \
488 { \
489 ULONG u32; \
490 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&u32), hrcCheck); \
491 if (details == VMINFO_MACHINEREADABLE) \
492 RTPrintf(a_szMachine "=%u\n", u32); \
493 else \
494 RTPrintf("%-16s %u" a_szUnit "\n", a_szHuman ":", u32); \
495 } while (0)
496
497#define SHOW_LONG64_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szUnit) \
498 do \
499 { \
500 LONG64 i64; \
501 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&i64), hrcCheck); \
502 if (details == VMINFO_MACHINEREADABLE) \
503 RTPrintf(a_szMachine "=%lld\n", i64); \
504 else \
505 RTPrintf("%-16s %'lld" a_szUnit "\n", a_szHuman ":", i64); \
506 } while (0)
507
508 /*
509 * The rules for output in -argdump format:
510 * 1) the key part (the [0-9a-zA-Z_\-]+ string before the '=' delimiter)
511 * is all lowercase for "VBoxManage modifyvm" parameters. Any
512 * other values printed are in CamelCase.
513 * 2) strings (anything non-decimal) are printed surrounded by
514 * double quotes '"'. If the strings themselves contain double
515 * quotes, these characters are escaped by '\'. Any '\' character
516 * in the original string is also escaped by '\'.
517 * 3) numbers (containing just [0-9\-]) are written out unchanged.
518 */
519
520 BOOL fAccessible;
521 CHECK_ERROR2I_RET(machine, COMGETTER(Accessible)(&fAccessible), hrcCheck);
522 if (!fAccessible)
523 {
524 Bstr uuid;
525 machine->COMGETTER(Id)(uuid.asOutParam());
526 if (details == VMINFO_COMPACT)
527 RTPrintf("\"<inaccessible>\" {%s}\n", Utf8Str(uuid).c_str());
528 else
529 {
530 if (details == VMINFO_MACHINEREADABLE)
531 RTPrintf("name=\"<inaccessible>\"\n");
532 else
533 RTPrintf("Name: <inaccessible!>\n");
534 if (details == VMINFO_MACHINEREADABLE)
535 RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
536 else
537 RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
538 if (details != VMINFO_MACHINEREADABLE)
539 {
540 Bstr settingsFilePath;
541 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
542 RTPrintf("Config file: %ls\n", settingsFilePath.raw());
543 ComPtr<IVirtualBoxErrorInfo> accessError;
544 rc = machine->COMGETTER(AccessError)(accessError.asOutParam());
545 RTPrintf("Access error details:\n");
546 ErrorInfo ei(accessError);
547 GluePrintErrorInfo(ei);
548 RTPrintf("\n");
549 }
550 }
551 return S_OK;
552 }
553
554 if (details == VMINFO_COMPACT)
555 {
556 Bstr machineName;
557 machine->COMGETTER(Name)(machineName.asOutParam());
558 Bstr uuid;
559 machine->COMGETTER(Id)(uuid.asOutParam());
560
561 RTPrintf("\"%ls\" {%s}\n", machineName.raw(), Utf8Str(uuid).c_str());
562 return S_OK;
563 }
564
565 SHOW_STRING_PROP( machine, Name, "name", "Name");
566
567 Bstr osTypeId;
568 CHECK_ERROR2I_RET(machine, COMGETTER(OSTypeId)(osTypeId.asOutParam()), hrcCheck);
569 ComPtr<IGuestOSType> osType;
570 CHECK_ERROR2I_RET(pVirtualBox, GetGuestOSType(osTypeId.raw(), osType.asOutParam()), hrcCheck);
571 SHOW_STRINGARRAY_PROP( machine, Groups, "groups", "Groups");
572 SHOW_STRING_PROP( osType, Description, "ostype", "Guest OS");
573 SHOW_UUID_PROP( machine, Id, "UUID", "UUID");
574 SHOW_STRING_PROP( machine, SettingsFilePath, "CfgFile", "Config file");
575 SHOW_STRING_PROP( machine, SnapshotFolder, "SnapFldr", "Snapshot folder");
576 SHOW_STRING_PROP( machine, LogFolder, "LogFldr", "Log folder");
577 SHOW_UUID_PROP( machine, HardwareUUID, "hardwareuuid", "Hardware UUID");
578 SHOW_ULONG_PROP( machine, MemorySize, "memory", "Memory size", "MB");
579 SHOW_BOOLEAN_PROP( machine, PageFusionEnabled, "pagefusion", "Page Fusion");
580 SHOW_ULONG_PROP( machine, VRAMSize, "vram", "VRAM size", "MB");
581 SHOW_ULONG_PROP( machine, CPUExecutionCap, "cpuexecutioncap", "CPU exec cap", "%%");
582 SHOW_BOOLEAN_PROP( machine, HPETEnabled, "hpet", "HPET");
583 SHOW_STRING_PROP_MAJ( machine, CPUProfile, "cpu-profile", "CPUProfile", "host", 6);
584
585 ChipsetType_T chipsetType;
586 CHECK_ERROR2I_RET(machine, COMGETTER(ChipsetType)(&chipsetType), hrcCheck);
587 const char *pszChipsetType;
588 switch (chipsetType)
589 {
590 case ChipsetType_Null: pszChipsetType = "invalid"; break;
591 case ChipsetType_PIIX3: pszChipsetType = "piix3"; break;
592 case ChipsetType_ICH9: pszChipsetType = "ich9"; break;
593 default: AssertFailed(); pszChipsetType = "unknown"; break;
594 }
595 if (details == VMINFO_MACHINEREADABLE)
596 RTPrintf("chipset=\"%s\"\n", pszChipsetType);
597 else
598 RTPrintf("Chipset: %s\n", pszChipsetType);
599
600 FirmwareType_T firmwareType;
601 CHECK_ERROR2I_RET(machine, COMGETTER(FirmwareType)(&firmwareType), hrcCheck);
602 const char *pszFirmwareType;
603 switch (firmwareType)
604 {
605 case FirmwareType_BIOS: pszFirmwareType = "BIOS"; break;
606 case FirmwareType_EFI: pszFirmwareType = "EFI"; break;
607 case FirmwareType_EFI32: pszFirmwareType = "EFI32"; break;
608 case FirmwareType_EFI64: pszFirmwareType = "EFI64"; break;
609 case FirmwareType_EFIDUAL: pszFirmwareType = "EFIDUAL"; break;
610 default: AssertFailed(); pszFirmwareType = "unknown"; break;
611 }
612 if (details == VMINFO_MACHINEREADABLE)
613 RTPrintf("firmware=\"%s\"\n", pszFirmwareType);
614 else
615 RTPrintf("Firmware: %s\n", pszFirmwareType);
616
617 SHOW_ULONG_PROP( machine, CPUCount, "cpus", "Number of CPUs", "");
618 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_PAE, &f), "pae", "PAE");
619 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_LongMode, &f), "longmode", "Long Mode");
620 SHOW_ULONG_PROP( machine, CPUIDPortabilityLevel, "cpuid-portability-level", "CPUID Portability Level", "");
621
622 if (details != VMINFO_MACHINEREADABLE)
623 RTPrintf("CPUID overrides: ");
624 ULONG cFound = 0;
625 static uint32_t const s_auCpuIdRanges[] =
626 {
627 UINT32_C(0x00000000), UINT32_C(0x0000000a),
628 UINT32_C(0x80000000), UINT32_C(0x8000000a)
629 };
630 for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
631 for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
632 {
633 ULONG uEAX, uEBX, uECX, uEDX;
634 rc = machine->GetCPUIDLeaf(uLeaf, &uEAX, &uEBX, &uECX, &uEDX);
635 if (SUCCEEDED(rc))
636 {
637 if (details == VMINFO_MACHINEREADABLE)
638 RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x", uLeaf, uEAX, uEBX, uECX, uEDX);
639 else
640 {
641 if (!cFound)
642 RTPrintf("Leaf no. EAX EBX ECX EDX\n");
643 RTPrintf(" %08x %08x %08x %08x %08x\n", uLeaf, uEAX, uEBX, uECX, uEDX);
644 }
645 cFound++;
646 }
647 }
648 if (!cFound && details != VMINFO_MACHINEREADABLE)
649 RTPrintf("None\n");
650
651 ComPtr<IBIOSSettings> biosSettings;
652 CHECK_ERROR2I_RET(machine, COMGETTER(BIOSSettings)(biosSettings.asOutParam()), hrcCheck);
653
654 BIOSBootMenuMode_T bootMenuMode;
655 CHECK_ERROR2I_RET(biosSettings, COMGETTER(BootMenuMode)(&bootMenuMode), hrcCheck);
656 const char *pszBootMenu;
657 switch (bootMenuMode)
658 {
659 case BIOSBootMenuMode_Disabled:
660 pszBootMenu = "disabled";
661 break;
662 case BIOSBootMenuMode_MenuOnly:
663 if (details == VMINFO_MACHINEREADABLE)
664 pszBootMenu = "menuonly";
665 else
666 pszBootMenu = "menu only";
667 break;
668 default:
669 if (details == VMINFO_MACHINEREADABLE)
670 pszBootMenu = "messageandmenu";
671 else
672 pszBootMenu = "message and menu";
673 }
674 if (details == VMINFO_MACHINEREADABLE)
675 RTPrintf("bootmenu=\"%s\"\n", pszBootMenu);
676 else
677 RTPrintf("Boot menu mode: %s\n", pszBootMenu);
678
679 ComPtr<ISystemProperties> systemProperties;
680 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck);
681 ULONG maxBootPosition = 0;
682 CHECK_ERROR2I_RET(systemProperties, COMGETTER(MaxBootPosition)(&maxBootPosition), hrcCheck);
683 for (ULONG i = 1; i <= maxBootPosition; i++)
684 {
685 DeviceType_T bootOrder;
686 CHECK_ERROR2I_RET(machine, GetBootOrder(i, &bootOrder), hrcCheck);
687 if (bootOrder == DeviceType_Floppy)
688 {
689 if (details == VMINFO_MACHINEREADABLE)
690 RTPrintf("boot%d=\"floppy\"\n", i);
691 else
692 RTPrintf("Boot Device (%d): Floppy\n", i);
693 }
694 else if (bootOrder == DeviceType_DVD)
695 {
696 if (details == VMINFO_MACHINEREADABLE)
697 RTPrintf("boot%d=\"dvd\"\n", i);
698 else
699 RTPrintf("Boot Device (%d): DVD\n", i);
700 }
701 else if (bootOrder == DeviceType_HardDisk)
702 {
703 if (details == VMINFO_MACHINEREADABLE)
704 RTPrintf("boot%d=\"disk\"\n", i);
705 else
706 RTPrintf("Boot Device (%d): HardDisk\n", i);
707 }
708 else if (bootOrder == DeviceType_Network)
709 {
710 if (details == VMINFO_MACHINEREADABLE)
711 RTPrintf("boot%d=\"net\"\n", i);
712 else
713 RTPrintf("Boot Device (%d): Network\n", i);
714 }
715 else if (bootOrder == DeviceType_USB)
716 {
717 if (details == VMINFO_MACHINEREADABLE)
718 RTPrintf("boot%d=\"usb\"\n", i);
719 else
720 RTPrintf("Boot Device (%d): USB\n", i);
721 }
722 else if (bootOrder == DeviceType_SharedFolder)
723 {
724 if (details == VMINFO_MACHINEREADABLE)
725 RTPrintf("boot%d=\"sharedfolder\"\n", i);
726 else
727 RTPrintf("Boot Device (%d): Shared Folder\n", i);
728 }
729 else
730 {
731 if (details == VMINFO_MACHINEREADABLE)
732 RTPrintf("boot%d=\"none\"\n", i);
733 else
734 RTPrintf("Boot Device (%d): Not Assigned\n", i);
735 }
736 }
737
738 SHOW_BOOLEAN_PROP(biosSettings, ACPIEnabled, "acpi", "ACPI");
739 SHOW_BOOLEAN_PROP(biosSettings, IOAPICEnabled, "ioapic", "IOAPIC");
740 SHOW_LONG64_PROP(biosSettings, TimeOffset, "biossystemtimeoffset", "Time offset", "ms");
741 SHOW_BOOLEAN_PROP_EX(machine, RTCUseUTC, "rtcuseutc", "RTC", "UTC", "local time");
742 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &f), "hwvirtex", "Hardw. virt.ext");
743 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", "Nested Paging");
744 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", "Large Pages");
745 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID");
746 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", "VT-x unr. exec.");
747
748 ParavirtProvider_T paravirtProvider;
749 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtProvider)(&paravirtProvider), hrcCheck);
750 const char *pszParavirtProvider = paravirtProviderToString(paravirtProvider, details);
751 if (details == VMINFO_MACHINEREADABLE)
752 RTPrintf("paravirtprovider=\"%s\"\n", pszParavirtProvider);
753 else
754 RTPrintf("Paravirt. Provider: %s\n", pszParavirtProvider);
755
756 ParavirtProvider_T effParavirtProvider;
757 CHECK_ERROR2I_RET(machine, GetEffectiveParavirtProvider(&effParavirtProvider), hrcCheck);
758 const char *pszEffParavirtProvider = paravirtProviderToString(effParavirtProvider, details);
759 if (details == VMINFO_MACHINEREADABLE)
760 RTPrintf("effparavirtprovider=\"%s\"\n", pszEffParavirtProvider);
761 else
762 RTPrintf("Effective Paravirt. Provider: %s\n", pszEffParavirtProvider);
763
764 Bstr paravirtDebug;
765 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtDebug)(paravirtDebug.asOutParam()), hrcCheck);
766 if (paravirtDebug.isNotEmpty())
767 {
768 if (details == VMINFO_MACHINEREADABLE)
769 RTPrintf("paravirtdebug=\"%ls\"\n", paravirtDebug.raw());
770 else
771 RTPrintf("Paravirt. Debug: %ls\n", paravirtDebug.raw());
772 }
773
774 MachineState_T machineState;
775 CHECK_ERROR2I_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
776 const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
777
778 LONG64 stateSince;
779 machine->COMGETTER(LastStateChange)(&stateSince);
780 RTTIMESPEC timeSpec;
781 RTTimeSpecSetMilli(&timeSpec, stateSince);
782 char pszTime[30] = {0};
783 RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
784 if (details == VMINFO_MACHINEREADABLE)
785 {
786 RTPrintf("VMState=\"%s\"\n", pszState);
787 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
788
789 Bstr stateFile;
790 machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
791 if (!stateFile.isEmpty())
792 RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
793 }
794 else
795 RTPrintf("State: %s (since %s)\n", pszState, pszTime);
796
797 SHOW_ULONG_PROP( machine, MonitorCount, "monitorcount", "Monitor count", "");
798 SHOW_BOOLEAN_PROP( machine, Accelerate3DEnabled, "accelerate3d", "3D Acceleration");
799#ifdef VBOX_WITH_VIDEOHWACCEL
800 SHOW_BOOLEAN_PROP( machine, Accelerate2DVideoEnabled, "accelerate2dvideo", "2D Video Acceleration");
801#endif
802 SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", "Teleporter Enabled");
803 SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", "Teleporter Port", "");
804 SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", "Teleporter Address");
805 SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", "Teleporter Password");
806 SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", "Tracing Enabled");
807 SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", "Allow Tracing to Access VM");
808 SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", "Tracing Configuration");
809 SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", "Autostart Enabled");
810 SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", "Autostart Delay", "");
811 SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", "Default Frontend");
812
813/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
814 * checking where missing. */
815 /*
816 * Storage Controllers and their attached Mediums.
817 */
818 com::SafeIfaceArray<IStorageController> storageCtls;
819 CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
820 for (size_t i = 0; i < storageCtls.size(); ++ i)
821 {
822 ComPtr<IStorageController> storageCtl = storageCtls[i];
823 StorageControllerType_T enmCtlType = StorageControllerType_Null;
824 const char *pszCtl = NULL;
825 ULONG ulValue = 0;
826 BOOL fBootable = FALSE;
827 Bstr storageCtlName;
828
829 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
830 if (details == VMINFO_MACHINEREADABLE)
831 RTPrintf("storagecontrollername%u=\"%ls\"\n", i, storageCtlName.raw());
832 else
833 RTPrintf("Storage Controller Name (%u): %ls\n", i, storageCtlName.raw());
834
835 storageCtl->COMGETTER(ControllerType)(&enmCtlType);
836 switch (enmCtlType)
837 {
838 case StorageControllerType_LsiLogic:
839 pszCtl = "LsiLogic";
840 break;
841 case StorageControllerType_LsiLogicSas:
842 pszCtl = "LsiLogicSas";
843 break;
844 case StorageControllerType_BusLogic:
845 pszCtl = "BusLogic";
846 break;
847 case StorageControllerType_IntelAhci:
848 pszCtl = "IntelAhci";
849 break;
850 case StorageControllerType_PIIX3:
851 pszCtl = "PIIX3";
852 break;
853 case StorageControllerType_PIIX4:
854 pszCtl = "PIIX4";
855 break;
856 case StorageControllerType_ICH6:
857 pszCtl = "ICH6";
858 break;
859 case StorageControllerType_I82078:
860 pszCtl = "I82078";
861 break;
862 case StorageControllerType_USB:
863 pszCtl = "USB";
864 break;
865
866 default:
867 pszCtl = "unknown";
868 }
869 if (details == VMINFO_MACHINEREADABLE)
870 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
871 else
872 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
873
874 storageCtl->COMGETTER(Instance)(&ulValue);
875 if (details == VMINFO_MACHINEREADABLE)
876 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
877 else
878 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
879
880 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
881 if (details == VMINFO_MACHINEREADABLE)
882 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
883 else
884 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
885
886 storageCtl->COMGETTER(PortCount)(&ulValue);
887 if (details == VMINFO_MACHINEREADABLE)
888 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
889 else
890 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
891
892 storageCtl->COMGETTER(Bootable)(&fBootable);
893 if (details == VMINFO_MACHINEREADABLE)
894 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
895 else
896 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
897 }
898
899 for (size_t j = 0; j < storageCtls.size(); ++ j)
900 {
901 ComPtr<IStorageController> storageCtl = storageCtls[j];
902 ComPtr<IMedium> medium;
903 Bstr storageCtlName;
904 Bstr filePath;
905 ULONG cDevices;
906 ULONG cPorts;
907
908 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
909 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
910 storageCtl->COMGETTER(PortCount)(&cPorts);
911
912 for (ULONG i = 0; i < cPorts; ++ i)
913 {
914 for (ULONG k = 0; k < cDevices; ++ k)
915 {
916 ComPtr<IMediumAttachment> mediumAttach;
917 machine->GetMediumAttachment(storageCtlName.raw(),
918 i, k,
919 mediumAttach.asOutParam());
920 BOOL fIsEjected = FALSE;
921 BOOL fTempEject = FALSE;
922 DeviceType_T devType = DeviceType_Null;
923 if (mediumAttach)
924 {
925 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
926 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
927 mediumAttach->COMGETTER(Type)(&devType);
928 }
929 rc = machine->GetMedium(storageCtlName.raw(), i, k,
930 medium.asOutParam());
931 if (SUCCEEDED(rc) && medium)
932 {
933 BOOL fPassthrough = FALSE;
934
935 if (mediumAttach)
936 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
937
938 medium->COMGETTER(Location)(filePath.asOutParam());
939 Bstr uuid;
940 medium->COMGETTER(Id)(uuid.asOutParam());
941
942 if (details == VMINFO_MACHINEREADABLE)
943 {
944 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
945 i, k, filePath.raw());
946 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
947 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
948 if (fPassthrough)
949 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
950 fPassthrough ? "on" : "off");
951 if (devType == DeviceType_DVD)
952 {
953 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
954 fTempEject ? "on" : "off");
955 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
956 fIsEjected ? "on" : "off");
957 }
958 }
959 else
960 {
961 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
962 storageCtlName.raw(), i, k, filePath.raw(),
963 Utf8Str(uuid).c_str());
964 if (fPassthrough)
965 RTPrintf(" (passthrough enabled)");
966 if (fTempEject)
967 RTPrintf(" (temp eject)");
968 if (fIsEjected)
969 RTPrintf(" (ejected)");
970 RTPrintf("\n");
971 }
972 }
973 else if (SUCCEEDED(rc))
974 {
975 if (details == VMINFO_MACHINEREADABLE)
976 {
977 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
978 if (devType == DeviceType_DVD)
979 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
980 fIsEjected ? "on" : "off");
981 }
982 else
983 {
984 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
985 if (fTempEject)
986 RTPrintf(" (temp eject)");
987 if (fIsEjected)
988 RTPrintf(" (ejected)");
989 RTPrintf("\n");
990 }
991 }
992 else
993 {
994 if (details == VMINFO_MACHINEREADABLE)
995 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
996 }
997 }
998 }
999 }
1000
1001 /* get the maximum amount of NICS */
1002 ULONG maxNICs = getMaxNics(pVirtualBox, machine);
1003
1004 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
1005 {
1006 ComPtr<INetworkAdapter> nic;
1007 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
1008 if (SUCCEEDED(rc) && nic)
1009 {
1010 BOOL fEnabled;
1011 nic->COMGETTER(Enabled)(&fEnabled);
1012 if (!fEnabled)
1013 {
1014 if (details == VMINFO_MACHINEREADABLE)
1015 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
1016 else
1017 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
1018 }
1019 else
1020 {
1021 Bstr strMACAddress;
1022 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
1023 Utf8Str strAttachment;
1024 Utf8Str strNatSettings = "";
1025 Utf8Str strNatForwardings = "";
1026 NetworkAttachmentType_T attachment;
1027 nic->COMGETTER(AttachmentType)(&attachment);
1028 switch (attachment)
1029 {
1030 case NetworkAttachmentType_Null:
1031 if (details == VMINFO_MACHINEREADABLE)
1032 strAttachment = "null";
1033 else
1034 strAttachment = "none";
1035 break;
1036
1037 case NetworkAttachmentType_NAT:
1038 {
1039 Bstr strNetwork;
1040 ComPtr<INATEngine> engine;
1041 nic->COMGETTER(NATEngine)(engine.asOutParam());
1042 engine->COMGETTER(Network)(strNetwork.asOutParam());
1043 com::SafeArray<BSTR> forwardings;
1044 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
1045 strNatForwardings = "";
1046 for (size_t i = 0; i < forwardings.size(); ++i)
1047 {
1048 bool fSkip = false;
1049 uint16_t port = 0;
1050 BSTR r = forwardings[i];
1051 Utf8Str utf = Utf8Str(r);
1052 Utf8Str strName;
1053 Utf8Str strProto;
1054 Utf8Str strHostPort;
1055 Utf8Str strHostIP;
1056 Utf8Str strGuestPort;
1057 Utf8Str strGuestIP;
1058 size_t pos, ppos;
1059 pos = ppos = 0;
1060 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
1061 do { \
1062 pos = str.find(",", ppos); \
1063 if (pos == Utf8Str::npos) \
1064 { \
1065 Log(( #res " extracting from %s is failed\n", str.c_str())); \
1066 fSkip = true; \
1067 } \
1068 res = str.substr(ppos, pos - ppos); \
1069 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
1070 ppos = pos + 1; \
1071 } while (0)
1072 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
1073 if (fSkip) continue;
1074 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
1075 if (fSkip) continue;
1076 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
1077 if (fSkip) continue;
1078 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
1079 if (fSkip) continue;
1080 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
1081 if (fSkip) continue;
1082 strGuestPort = utf.substr(ppos, utf.length() - ppos);
1083 #undef ITERATE_TO_NEXT_TERM
1084 switch (strProto.toUInt32())
1085 {
1086 case NATProtocol_TCP:
1087 strProto = "tcp";
1088 break;
1089 case NATProtocol_UDP:
1090 strProto = "udp";
1091 break;
1092 default:
1093 strProto = "unk";
1094 break;
1095 }
1096 if (details == VMINFO_MACHINEREADABLE)
1097 {
1098 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
1099 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
1100 strHostIP.c_str(), strHostPort.c_str(),
1101 strGuestIP.c_str(), strGuestPort.c_str());
1102 }
1103 else
1104 {
1105 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
1106 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1107 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
1108 strHostIP.c_str(), strHostPort.c_str(),
1109 strGuestIP.c_str(), strGuestPort.c_str());
1110 }
1111 }
1112 ULONG mtu = 0;
1113 ULONG sockSnd = 0;
1114 ULONG sockRcv = 0;
1115 ULONG tcpSnd = 0;
1116 ULONG tcpRcv = 0;
1117 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1118
1119/** @todo r=klaus dnsproxy etc needs to be dumped, too */
1120 if (details == VMINFO_MACHINEREADABLE)
1121 {
1122 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1123 strAttachment = "nat";
1124 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1125 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1126 }
1127 else
1128 {
1129 strAttachment = "NAT";
1130 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1131 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1132 }
1133 break;
1134 }
1135
1136 case NetworkAttachmentType_Bridged:
1137 {
1138 Bstr strBridgeAdp;
1139 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1140 if (details == VMINFO_MACHINEREADABLE)
1141 {
1142 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1143 strAttachment = "bridged";
1144 }
1145 else
1146 strAttachment = Utf8StrFmt("Bridged Interface '%ls'", strBridgeAdp.raw());
1147 break;
1148 }
1149
1150 case NetworkAttachmentType_Internal:
1151 {
1152 Bstr strNetwork;
1153 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1154 if (details == VMINFO_MACHINEREADABLE)
1155 {
1156 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1157 strAttachment = "intnet";
1158 }
1159 else
1160 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1161 break;
1162 }
1163
1164 case NetworkAttachmentType_HostOnly:
1165 {
1166 Bstr strHostonlyAdp;
1167 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1168 if (details == VMINFO_MACHINEREADABLE)
1169 {
1170 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1171 strAttachment = "hostonly";
1172 }
1173 else
1174 strAttachment = Utf8StrFmt("Host-only Interface '%ls'", strHostonlyAdp.raw());
1175 break;
1176 }
1177
1178 case NetworkAttachmentType_Generic:
1179 {
1180 Bstr strGenericDriver;
1181 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1182 if (details == VMINFO_MACHINEREADABLE)
1183 {
1184 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1185 strAttachment = "Generic";
1186 }
1187 else
1188 {
1189 strAttachment = Utf8StrFmt("Generic '%ls'", strGenericDriver.raw());
1190
1191 // show the generic properties
1192 com::SafeArray<BSTR> aProperties;
1193 com::SafeArray<BSTR> aValues;
1194 rc = nic->GetProperties(NULL,
1195 ComSafeArrayAsOutParam(aProperties),
1196 ComSafeArrayAsOutParam(aValues));
1197 if (SUCCEEDED(rc))
1198 {
1199 strAttachment += " { ";
1200 for (unsigned i = 0; i < aProperties.size(); ++i)
1201 strAttachment += Utf8StrFmt(!i ? "%ls='%ls'" : ", %ls='%ls'",
1202 aProperties[i], aValues[i]);
1203 strAttachment += " }";
1204 }
1205 }
1206 break;
1207 }
1208
1209 case NetworkAttachmentType_NATNetwork:
1210 {
1211 Bstr strNetwork;
1212 nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
1213 if (details == VMINFO_MACHINEREADABLE)
1214 {
1215 RTPrintf("nat-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1216 strAttachment = "natnetwork";
1217 }
1218 else
1219 strAttachment = Utf8StrFmt("NAT Network '%s'", Utf8Str(strNetwork).c_str());
1220 break;
1221 }
1222
1223 default:
1224 strAttachment = "unknown";
1225 break;
1226 }
1227
1228 /* cable connected */
1229 BOOL fConnected;
1230 nic->COMGETTER(CableConnected)(&fConnected);
1231
1232 /* promisc policy */
1233 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1234 CHECK_ERROR2I_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1235 const char *pszPromiscuousGuestPolicy;
1236 switch (enmPromiscModePolicy)
1237 {
1238 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1239 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1240 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1241 default: AssertFailedReturn(E_INVALIDARG);
1242 }
1243
1244 /* trace stuff */
1245 BOOL fTraceEnabled;
1246 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1247 Bstr traceFile;
1248 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1249
1250 /* NIC type */
1251 NetworkAdapterType_T NICType;
1252 nic->COMGETTER(AdapterType)(&NICType);
1253 const char *pszNICType;
1254 switch (NICType)
1255 {
1256 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1257 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1258#ifdef VBOX_WITH_E1000
1259 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1260 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1261 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1262#endif
1263#ifdef VBOX_WITH_VIRTIO
1264 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1265#endif
1266 default: AssertFailed(); pszNICType = "unknown"; break;
1267 }
1268
1269 /* reported line speed */
1270 ULONG ulLineSpeed;
1271 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1272
1273 /* boot priority of the adapter */
1274 ULONG ulBootPriority;
1275 nic->COMGETTER(BootPriority)(&ulBootPriority);
1276
1277 /* bandwidth group */
1278 ComObjPtr<IBandwidthGroup> pBwGroup;
1279 Bstr strBwGroup;
1280 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1281 if (!pBwGroup.isNull())
1282 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1283
1284 if (details == VMINFO_MACHINEREADABLE)
1285 {
1286 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1287 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1288 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1289 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1290 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1291 }
1292 else
1293 RTPrintf("NIC %u: MAC: %ls, Attachment: %s, Cable connected: %s, Trace: %s (file: %ls), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s, Bandwidth group: %ls\n",
1294 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
1295 fConnected ? "on" : "off",
1296 fTraceEnabled ? "on" : "off",
1297 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1298 pszNICType,
1299 ulLineSpeed / 1000,
1300 (int)ulBootPriority,
1301 pszPromiscuousGuestPolicy,
1302 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1303 if (strNatSettings.length())
1304 RTPrintf(strNatSettings.c_str());
1305 if (strNatForwardings.length())
1306 RTPrintf(strNatForwardings.c_str());
1307 }
1308 }
1309 }
1310
1311 /* Pointing device information */
1312 PointingHIDType_T aPointingHID;
1313 const char *pszHID = "Unknown";
1314 const char *pszMrHID = "unknown";
1315 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1316 switch (aPointingHID)
1317 {
1318 case PointingHIDType_None:
1319 pszHID = "None";
1320 pszMrHID = "none";
1321 break;
1322 case PointingHIDType_PS2Mouse:
1323 pszHID = "PS/2 Mouse";
1324 pszMrHID = "ps2mouse";
1325 break;
1326 case PointingHIDType_USBMouse:
1327 pszHID = "USB Mouse";
1328 pszMrHID = "usbmouse";
1329 break;
1330 case PointingHIDType_USBTablet:
1331 pszHID = "USB Tablet";
1332 pszMrHID = "usbtablet";
1333 break;
1334 case PointingHIDType_ComboMouse:
1335 pszHID = "USB Tablet and PS/2 Mouse";
1336 pszMrHID = "combomouse";
1337 break;
1338 case PointingHIDType_USBMultiTouch:
1339 pszHID = "USB Multi-Touch";
1340 pszMrHID = "usbmultitouch";
1341 break;
1342 default:
1343 break;
1344 }
1345 if (details == VMINFO_MACHINEREADABLE)
1346 RTPrintf("hidpointing=\"%s\"\n", pszMrHID);
1347 else
1348 RTPrintf("Pointing Device: %s\n", pszHID);
1349
1350 /* Keyboard device information */
1351 KeyboardHIDType_T aKeyboardHID;
1352 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1353 pszHID = "Unknown";
1354 pszMrHID = "unknown";
1355 switch (aKeyboardHID)
1356 {
1357 case KeyboardHIDType_None:
1358 pszHID = "None";
1359 pszMrHID = "none";
1360 break;
1361 case KeyboardHIDType_PS2Keyboard:
1362 pszHID = "PS/2 Keyboard";
1363 pszMrHID = "ps2kbd";
1364 break;
1365 case KeyboardHIDType_USBKeyboard:
1366 pszHID = "USB Keyboard";
1367 pszMrHID = "usbkbd";
1368 break;
1369 case KeyboardHIDType_ComboKeyboard:
1370 pszHID = "USB and PS/2 Keyboard";
1371 pszMrHID = "combokbd";
1372 break;
1373 default:
1374 break;
1375 }
1376 if (details == VMINFO_MACHINEREADABLE)
1377 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHID);
1378 else
1379 RTPrintf("Keyboard Device: %s\n", pszHID);
1380
1381 ComPtr<ISystemProperties> sysProps;
1382 pVirtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1383
1384 /* get the maximum amount of UARTs */
1385 ULONG maxUARTs = 0;
1386 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1387 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1388 {
1389 ComPtr<ISerialPort> uart;
1390 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1391 if (SUCCEEDED(rc) && uart)
1392 {
1393 /* show the config of this UART */
1394 BOOL fEnabled;
1395 uart->COMGETTER(Enabled)(&fEnabled);
1396 if (!fEnabled)
1397 {
1398 if (details == VMINFO_MACHINEREADABLE)
1399 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1400 else
1401 RTPrintf("UART %d: disabled\n", currentUART + 1);
1402 }
1403 else
1404 {
1405 ULONG ulIRQ, ulIOBase;
1406 PortMode_T HostMode;
1407 Bstr path;
1408 BOOL fServer;
1409 uart->COMGETTER(IRQ)(&ulIRQ);
1410 uart->COMGETTER(IOBase)(&ulIOBase);
1411 uart->COMGETTER(Path)(path.asOutParam());
1412 uart->COMGETTER(Server)(&fServer);
1413 uart->COMGETTER(HostMode)(&HostMode);
1414
1415 if (details == VMINFO_MACHINEREADABLE)
1416 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1417 ulIOBase, ulIRQ);
1418 else
1419 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1420 currentUART + 1, ulIOBase, ulIRQ);
1421 switch (HostMode)
1422 {
1423 default:
1424 case PortMode_Disconnected:
1425 if (details == VMINFO_MACHINEREADABLE)
1426 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1427 else
1428 RTPrintf(", disconnected\n");
1429 break;
1430 case PortMode_RawFile:
1431 if (details == VMINFO_MACHINEREADABLE)
1432 RTPrintf("uartmode%d=\"file,%ls\"\n", currentUART + 1,
1433 path.raw());
1434 else
1435 RTPrintf(", attached to raw file '%ls'\n",
1436 path.raw());
1437 break;
1438 case PortMode_TCP:
1439 if (details == VMINFO_MACHINEREADABLE)
1440 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1441 fServer ? "tcpserver" : "tcpclient", path.raw());
1442 else
1443 RTPrintf(", attached to tcp (%s) '%ls'\n",
1444 fServer ? "server" : "client", path.raw());
1445 break;
1446 case PortMode_HostPipe:
1447 if (details == VMINFO_MACHINEREADABLE)
1448 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1449 fServer ? "server" : "client", path.raw());
1450 else
1451 RTPrintf(", attached to pipe (%s) '%ls'\n",
1452 fServer ? "server" : "client", path.raw());
1453 break;
1454 case PortMode_HostDevice:
1455 if (details == VMINFO_MACHINEREADABLE)
1456 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1457 path.raw());
1458 else
1459 RTPrintf(", attached to device '%ls'\n", path.raw());
1460 break;
1461 }
1462 }
1463 }
1464 }
1465
1466 /* get the maximum amount of LPTs */
1467 ULONG maxLPTs = 0;
1468 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1469 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1470 {
1471 ComPtr<IParallelPort> lpt;
1472 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1473 if (SUCCEEDED(rc) && lpt)
1474 {
1475 /* show the config of this LPT */
1476 BOOL fEnabled;
1477 lpt->COMGETTER(Enabled)(&fEnabled);
1478 if (!fEnabled)
1479 {
1480 if (details == VMINFO_MACHINEREADABLE)
1481 RTPrintf("lpt%d=\"off\"\n", currentLPT + 1);
1482 else
1483 RTPrintf("LPT %d: disabled\n", currentLPT + 1);
1484 }
1485 else
1486 {
1487 ULONG ulIRQ, ulIOBase;
1488 Bstr path;
1489 lpt->COMGETTER(IRQ)(&ulIRQ);
1490 lpt->COMGETTER(IOBase)(&ulIOBase);
1491 lpt->COMGETTER(Path)(path.asOutParam());
1492
1493 if (details == VMINFO_MACHINEREADABLE)
1494 RTPrintf("lpt%d=\"%#06x,%d\"\n", currentLPT + 1,
1495 ulIOBase, ulIRQ);
1496 else
1497 RTPrintf("LPT %d: I/O base: %#06x, IRQ: %d",
1498 currentLPT + 1, ulIOBase, ulIRQ);
1499 if (details == VMINFO_MACHINEREADABLE)
1500 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1,
1501 path.raw());
1502 else
1503 RTPrintf(", attached to device '%ls'\n", path.raw());
1504 }
1505 }
1506 }
1507
1508 ComPtr<IAudioAdapter> AudioAdapter;
1509 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1510 if (SUCCEEDED(rc))
1511 {
1512 const char *pszDrv = "Unknown";
1513 const char *pszCtrl = "Unknown";
1514 const char *pszCodec = "Unknown";
1515 BOOL fEnabled;
1516 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1517 if (SUCCEEDED(rc) && fEnabled)
1518 {
1519 AudioDriverType_T enmDrvType;
1520 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1521 switch (enmDrvType)
1522 {
1523 case AudioDriverType_Null:
1524 if (details == VMINFO_MACHINEREADABLE)
1525 pszDrv = "null";
1526 else
1527 pszDrv = "Null";
1528 break;
1529 case AudioDriverType_WinMM:
1530 if (details == VMINFO_MACHINEREADABLE)
1531 pszDrv = "winmm";
1532 else
1533 pszDrv = "WINMM";
1534 break;
1535 case AudioDriverType_DirectSound:
1536 if (details == VMINFO_MACHINEREADABLE)
1537 pszDrv = "dsound";
1538 else
1539 pszDrv = "DSOUND";
1540 break;
1541 case AudioDriverType_OSS:
1542 if (details == VMINFO_MACHINEREADABLE)
1543 pszDrv = "oss";
1544 else
1545 pszDrv = "OSS";
1546 break;
1547 case AudioDriverType_ALSA:
1548 if (details == VMINFO_MACHINEREADABLE)
1549 pszDrv = "alsa";
1550 else
1551 pszDrv = "ALSA";
1552 break;
1553 case AudioDriverType_Pulse:
1554 if (details == VMINFO_MACHINEREADABLE)
1555 pszDrv = "pulse";
1556 else
1557 pszDrv = "PulseAudio";
1558 break;
1559 case AudioDriverType_CoreAudio:
1560 if (details == VMINFO_MACHINEREADABLE)
1561 pszDrv = "coreaudio";
1562 else
1563 pszDrv = "CoreAudio";
1564 break;
1565 case AudioDriverType_SolAudio:
1566 if (details == VMINFO_MACHINEREADABLE)
1567 pszDrv = "solaudio";
1568 else
1569 pszDrv = "SolAudio";
1570 break;
1571 default:
1572 if (details == VMINFO_MACHINEREADABLE)
1573 pszDrv = "unknown";
1574 break;
1575 }
1576 AudioControllerType_T enmCtrlType;
1577 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1578 switch (enmCtrlType)
1579 {
1580 case AudioControllerType_AC97:
1581 if (details == VMINFO_MACHINEREADABLE)
1582 pszCtrl = "ac97";
1583 else
1584 pszCtrl = "AC97";
1585 break;
1586 case AudioControllerType_SB16:
1587 if (details == VMINFO_MACHINEREADABLE)
1588 pszCtrl = "sb16";
1589 else
1590 pszCtrl = "SB16";
1591 break;
1592 case AudioControllerType_HDA:
1593 if (details == VMINFO_MACHINEREADABLE)
1594 pszCtrl = "hda";
1595 else
1596 pszCtrl = "HDA";
1597 break;
1598 }
1599 AudioCodecType_T enmCodecType;
1600 rc = AudioAdapter->COMGETTER(AudioCodec)(&enmCodecType);
1601 switch (enmCodecType)
1602 {
1603 case AudioCodecType_SB16:
1604 pszCodec = "SB16";
1605 break;
1606 case AudioCodecType_STAC9700:
1607 pszCodec = "STAC9700";
1608 break;
1609 case AudioCodecType_AD1980:
1610 pszCodec = "AD1980";
1611 break;
1612 case AudioCodecType_STAC9221:
1613 pszCodec = "STAC9221";
1614 break;
1615 }
1616 }
1617 else
1618 fEnabled = FALSE;
1619 if (details == VMINFO_MACHINEREADABLE)
1620 {
1621 if (fEnabled)
1622 RTPrintf("audio=\"%s\"\n", pszDrv);
1623 else
1624 RTPrintf("audio=\"none\"\n");
1625 }
1626 else
1627 {
1628 RTPrintf("Audio: %s",
1629 fEnabled ? "enabled" : "disabled");
1630 if (fEnabled)
1631 RTPrintf(" (Driver: %s, Controller: %s, Codec: %s)",
1632 pszDrv, pszCtrl, pszCodec);
1633 RTPrintf("\n");
1634 }
1635 }
1636
1637 /* Shared clipboard */
1638 {
1639 const char *psz = "Unknown";
1640 ClipboardMode_T enmMode;
1641 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1642 switch (enmMode)
1643 {
1644 case ClipboardMode_Disabled:
1645 if (details == VMINFO_MACHINEREADABLE)
1646 psz = "disabled";
1647 else
1648 psz = "disabled";
1649 break;
1650 case ClipboardMode_HostToGuest:
1651 if (details == VMINFO_MACHINEREADABLE)
1652 psz = "hosttoguest";
1653 else
1654 psz = "HostToGuest";
1655 break;
1656 case ClipboardMode_GuestToHost:
1657 if (details == VMINFO_MACHINEREADABLE)
1658 psz = "guesttohost";
1659 else
1660 psz = "GuestToHost";
1661 break;
1662 case ClipboardMode_Bidirectional:
1663 if (details == VMINFO_MACHINEREADABLE)
1664 psz = "bidirectional";
1665 else
1666 psz = "Bidirectional";
1667 break;
1668 default:
1669 if (details == VMINFO_MACHINEREADABLE)
1670 psz = "unknown";
1671 break;
1672 }
1673 if (details == VMINFO_MACHINEREADABLE)
1674 RTPrintf("clipboard=\"%s\"\n", psz);
1675 else
1676 RTPrintf("Clipboard Mode: %s\n", psz);
1677 }
1678
1679 /* Drag and drop */
1680 {
1681 const char *psz = "Unknown";
1682 DnDMode_T enmMode;
1683 rc = machine->COMGETTER(DnDMode)(&enmMode);
1684 switch (enmMode)
1685 {
1686 case DnDMode_Disabled:
1687 if (details == VMINFO_MACHINEREADABLE)
1688 psz = "disabled";
1689 else
1690 psz = "disabled";
1691 break;
1692 case DnDMode_HostToGuest:
1693 if (details == VMINFO_MACHINEREADABLE)
1694 psz = "hosttoguest";
1695 else
1696 psz = "HostToGuest";
1697 break;
1698 case DnDMode_GuestToHost:
1699 if (details == VMINFO_MACHINEREADABLE)
1700 psz = "guesttohost";
1701 else
1702 psz = "GuestToHost";
1703 break;
1704 case DnDMode_Bidirectional:
1705 if (details == VMINFO_MACHINEREADABLE)
1706 psz = "bidirectional";
1707 else
1708 psz = "Bidirectional";
1709 break;
1710 default:
1711 if (details == VMINFO_MACHINEREADABLE)
1712 psz = "unknown";
1713 break;
1714 }
1715 if (details == VMINFO_MACHINEREADABLE)
1716 RTPrintf("draganddrop=\"%s\"\n", psz);
1717 else
1718 RTPrintf("Drag and drop Mode: %s\n", psz);
1719 }
1720
1721 {
1722 SessionState_T sessState;
1723 rc = machine->COMGETTER(SessionState)(&sessState);
1724 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1725 {
1726 Bstr sessName;
1727 rc = machine->COMGETTER(SessionName)(sessName.asOutParam());
1728 if (SUCCEEDED(rc) && !sessName.isEmpty())
1729 {
1730 if (details == VMINFO_MACHINEREADABLE)
1731 RTPrintf("SessionName=\"%ls\"\n", sessName.raw());
1732 else
1733 RTPrintf("Session name: %ls\n", sessName.raw());
1734 }
1735 }
1736 }
1737
1738 if (pConsole)
1739 {
1740 do
1741 {
1742 ComPtr<IDisplay> display;
1743 rc = pConsole->COMGETTER(Display)(display.asOutParam());
1744 if (rc == E_ACCESSDENIED || display.isNull())
1745 break; /* VM not powered up */
1746 if (FAILED(rc))
1747 {
1748 com::GlueHandleComError(pConsole, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1749 return rc;
1750 }
1751 ULONG xRes, yRes, bpp;
1752 LONG xOrigin, yOrigin;
1753 GuestMonitorStatus_T monitorStatus;
1754 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin, &monitorStatus);
1755 if (rc == E_ACCESSDENIED)
1756 break; /* VM not powered up */
1757 if (FAILED(rc))
1758 {
1759 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1760 GluePrintErrorInfo(info);
1761 return rc;
1762 }
1763 if (details == VMINFO_MACHINEREADABLE)
1764 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d %d\n", xRes, yRes, bpp, xOrigin, yOrigin, monitorStatus);
1765 else
1766 {
1767 const char *pszMonitorStatus = "unknown status";
1768 switch (monitorStatus)
1769 {
1770 case GuestMonitorStatus_Enabled: pszMonitorStatus = "enabled"; break;
1771 case GuestMonitorStatus_Disabled: pszMonitorStatus = "disabled"; break;
1772 default: break;
1773 }
1774 RTPrintf("Video mode: %dx%dx%d at %d,%d %s\n", xRes, yRes, bpp, xOrigin, yOrigin, pszMonitorStatus);
1775 }
1776 }
1777 while (0);
1778 }
1779
1780 /*
1781 * Remote Desktop
1782 */
1783 ComPtr<IVRDEServer> vrdeServer;
1784 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1785 if (SUCCEEDED(rc) && vrdeServer)
1786 {
1787 BOOL fEnabled = false;
1788 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1789 if (fEnabled)
1790 {
1791 LONG currentPort = -1;
1792 Bstr ports;
1793 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1794 Bstr address;
1795 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1796 BOOL fMultiCon;
1797 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1798 BOOL fReuseCon;
1799 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1800 Bstr videoChannel;
1801 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1802 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1803 || (videoChannel == "1");
1804 Bstr videoChannelQuality;
1805 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1806 AuthType_T authType;
1807 const char *strAuthType;
1808 vrdeServer->COMGETTER(AuthType)(&authType);
1809 switch (authType)
1810 {
1811 case AuthType_Null:
1812 strAuthType = "null";
1813 break;
1814 case AuthType_External:
1815 strAuthType = "external";
1816 break;
1817 case AuthType_Guest:
1818 strAuthType = "guest";
1819 break;
1820 default:
1821 strAuthType = "unknown";
1822 break;
1823 }
1824 if (pConsole)
1825 {
1826 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1827 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1828 if (!vrdeServerInfo.isNull())
1829 {
1830 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1831 if (rc == E_ACCESSDENIED)
1832 {
1833 currentPort = -1; /* VM not powered up */
1834 }
1835 else if (FAILED(rc))
1836 {
1837 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1838 GluePrintErrorInfo(info);
1839 return rc;
1840 }
1841 }
1842 }
1843 if (details == VMINFO_MACHINEREADABLE)
1844 {
1845 RTPrintf("vrde=\"on\"\n");
1846 RTPrintf("vrdeport=%d\n", currentPort);
1847 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1848 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1849 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1850 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1851 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1852 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1853 if (fVideoChannel)
1854 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1855 }
1856 else
1857 {
1858 if (address.isEmpty())
1859 address = "0.0.0.0";
1860 RTPrintf("VRDE: enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)\n", address.raw(), ports.raw(), fMultiCon ? "on" : "off", fReuseCon ? "on" : "off", strAuthType);
1861 if (pConsole && currentPort != -1 && currentPort != 0)
1862 RTPrintf("VRDE port: %d\n", currentPort);
1863 if (fVideoChannel)
1864 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1865 else
1866 RTPrintf("Video redirection: disabled\n");
1867 }
1868 com::SafeArray<BSTR> aProperties;
1869 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1870 {
1871 unsigned i;
1872 for (i = 0; i < aProperties.size(); ++i)
1873 {
1874 Bstr value;
1875 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1876 if (details == VMINFO_MACHINEREADABLE)
1877 {
1878 if (value.isEmpty())
1879 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1880 else
1881 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1882 }
1883 else
1884 {
1885 if (value.isEmpty())
1886 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1887 else
1888 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1889 }
1890 }
1891 }
1892 }
1893 else
1894 {
1895 if (details == VMINFO_MACHINEREADABLE)
1896 RTPrintf("vrde=\"off\"\n");
1897 else
1898 RTPrintf("VRDE: disabled\n");
1899 }
1900 }
1901
1902 /*
1903 * USB.
1904 */
1905 SafeIfaceArray<IUSBController> USBCtlColl;
1906 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
1907 if (SUCCEEDED(rc))
1908 {
1909 bool fOhciEnabled = false;
1910 bool fEhciEnabled = false;
1911 bool fXhciEnabled = false;
1912
1913 for (unsigned i = 0; i < USBCtlColl.size(); i++)
1914 {
1915 USBControllerType_T enmType;
1916
1917 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
1918 if (SUCCEEDED(rc))
1919 {
1920 switch (enmType)
1921 {
1922 case USBControllerType_OHCI:
1923 fOhciEnabled = true;
1924 break;
1925 case USBControllerType_EHCI:
1926 fEhciEnabled = true;
1927 break;
1928 case USBControllerType_XHCI:
1929 fXhciEnabled = true;
1930 break;
1931 default:
1932 break;
1933 }
1934 }
1935 }
1936
1937 if (details == VMINFO_MACHINEREADABLE)
1938 RTPrintf("usb=\"%s\"\n", fOhciEnabled ? "on" : "off");
1939 else
1940 RTPrintf("USB: %s\n", fOhciEnabled ? "enabled" : "disabled");
1941
1942 if (details == VMINFO_MACHINEREADABLE)
1943 RTPrintf("ehci=\"%s\"\n", fEhciEnabled ? "on" : "off");
1944 else
1945 RTPrintf("EHCI: %s\n", fEhciEnabled ? "enabled" : "disabled");
1946
1947 if (details == VMINFO_MACHINEREADABLE)
1948 RTPrintf("xhci=\"%s\"\n", fXhciEnabled ? "on" : "off");
1949 else
1950 RTPrintf("XHCI: %s\n", fXhciEnabled ? "enabled" : "disabled");
1951 }
1952
1953 ComPtr<IUSBDeviceFilters> USBFlts;
1954 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
1955 if (SUCCEEDED(rc))
1956 {
1957 SafeIfaceArray <IUSBDeviceFilter> Coll;
1958 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1959 if (SUCCEEDED(rc))
1960 {
1961 if (details != VMINFO_MACHINEREADABLE)
1962 RTPrintf("\nUSB Device Filters:\n\n");
1963
1964 if (Coll.size() == 0)
1965 {
1966 if (details != VMINFO_MACHINEREADABLE)
1967 RTPrintf("<none>\n\n");
1968 }
1969 else
1970 {
1971 for (size_t index = 0; index < Coll.size(); ++index)
1972 {
1973 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1974
1975 /* Query info. */
1976
1977 if (details != VMINFO_MACHINEREADABLE)
1978 RTPrintf("Index: %zu\n", index);
1979
1980 BOOL bActive = FALSE;
1981 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1982 if (details == VMINFO_MACHINEREADABLE)
1983 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1984 else
1985 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1986
1987 Bstr bstr;
1988 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1989 if (details == VMINFO_MACHINEREADABLE)
1990 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1991 else
1992 RTPrintf("Name: %ls\n", bstr.raw());
1993 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1994 if (details == VMINFO_MACHINEREADABLE)
1995 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1996 else
1997 RTPrintf("VendorId: %ls\n", bstr.raw());
1998 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1999 if (details == VMINFO_MACHINEREADABLE)
2000 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
2001 else
2002 RTPrintf("ProductId: %ls\n", bstr.raw());
2003 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
2004 if (details == VMINFO_MACHINEREADABLE)
2005 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
2006 else
2007 RTPrintf("Revision: %ls\n", bstr.raw());
2008 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2009 if (details == VMINFO_MACHINEREADABLE)
2010 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2011 else
2012 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2013 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
2014 if (details == VMINFO_MACHINEREADABLE)
2015 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2016 else
2017 RTPrintf("Product: %ls\n", bstr.raw());
2018 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
2019 if (details == VMINFO_MACHINEREADABLE)
2020 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
2021 else
2022 RTPrintf("Remote: %ls\n", bstr.raw());
2023 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2024 if (details == VMINFO_MACHINEREADABLE)
2025 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2026 else
2027 RTPrintf("Serial Number: %ls\n", bstr.raw());
2028 if (details != VMINFO_MACHINEREADABLE)
2029 {
2030 ULONG fMaskedIfs;
2031 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
2032 if (fMaskedIfs)
2033 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
2034 RTPrintf("\n");
2035 }
2036 }
2037 }
2038 }
2039
2040 if (pConsole)
2041 {
2042 /* scope */
2043 {
2044 if (details != VMINFO_MACHINEREADABLE)
2045 RTPrintf("Available remote USB devices:\n\n");
2046
2047 SafeIfaceArray <IHostUSBDevice> coll;
2048 CHECK_ERROR_RET(pConsole, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2049
2050 if (coll.size() == 0)
2051 {
2052 if (details != VMINFO_MACHINEREADABLE)
2053 RTPrintf("<none>\n\n");
2054 }
2055 else
2056 {
2057 for (size_t index = 0; index < coll.size(); ++index)
2058 {
2059 ComPtr<IHostUSBDevice> dev = coll[index];
2060
2061 /* Query info. */
2062 Bstr id;
2063 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
2064 USHORT usVendorId;
2065 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
2066 USHORT usProductId;
2067 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
2068 USHORT bcdRevision;
2069 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2070
2071 if (details == VMINFO_MACHINEREADABLE)
2072 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
2073 "USBRemoteVendorId%zu=\"%#06x\"\n"
2074 "USBRemoteProductId%zu=\"%#06x\"\n"
2075 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
2076 index + 1, Utf8Str(id).c_str(),
2077 index + 1, usVendorId,
2078 index + 1, usProductId,
2079 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2080 else
2081 RTPrintf("UUID: %s\n"
2082 "VendorId: %#06x (%04X)\n"
2083 "ProductId: %#06x (%04X)\n"
2084 "Revision: %u.%u (%02u%02u)\n",
2085 Utf8Str(id).c_str(),
2086 usVendorId, usVendorId, usProductId, usProductId,
2087 bcdRevision >> 8, bcdRevision & 0xff,
2088 bcdRevision >> 8, bcdRevision & 0xff);
2089
2090 /* optional stuff. */
2091 Bstr bstr;
2092 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2093 if (!bstr.isEmpty())
2094 {
2095 if (details == VMINFO_MACHINEREADABLE)
2096 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2097 else
2098 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2099 }
2100 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2101 if (!bstr.isEmpty())
2102 {
2103 if (details == VMINFO_MACHINEREADABLE)
2104 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2105 else
2106 RTPrintf("Product: %ls\n", bstr.raw());
2107 }
2108 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2109 if (!bstr.isEmpty())
2110 {
2111 if (details == VMINFO_MACHINEREADABLE)
2112 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2113 else
2114 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2115 }
2116 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2117 if (!bstr.isEmpty())
2118 {
2119 if (details == VMINFO_MACHINEREADABLE)
2120 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2121 else
2122 RTPrintf("Address: %ls\n", bstr.raw());
2123 }
2124
2125 if (details != VMINFO_MACHINEREADABLE)
2126 RTPrintf("\n");
2127 }
2128 }
2129 }
2130
2131 /* scope */
2132 {
2133 if (details != VMINFO_MACHINEREADABLE)
2134 RTPrintf("Currently Attached USB Devices:\n\n");
2135
2136 SafeIfaceArray <IUSBDevice> coll;
2137 CHECK_ERROR_RET(pConsole, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2138
2139 if (coll.size() == 0)
2140 {
2141 if (details != VMINFO_MACHINEREADABLE)
2142 RTPrintf("<none>\n\n");
2143 }
2144 else
2145 {
2146 for (size_t index = 0; index < coll.size(); ++index)
2147 {
2148 ComPtr<IUSBDevice> dev = coll[index];
2149
2150 /* Query info. */
2151 Bstr id;
2152 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
2153 USHORT usVendorId;
2154 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
2155 USHORT usProductId;
2156 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
2157 USHORT bcdRevision;
2158 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2159
2160 if (details == VMINFO_MACHINEREADABLE)
2161 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
2162 "USBAttachedVendorId%zu=\"%#06x\"\n"
2163 "USBAttachedProductId%zu=\"%#06x\"\n"
2164 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
2165 index + 1, Utf8Str(id).c_str(),
2166 index + 1, usVendorId,
2167 index + 1, usProductId,
2168 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2169 else
2170 RTPrintf("UUID: %s\n"
2171 "VendorId: %#06x (%04X)\n"
2172 "ProductId: %#06x (%04X)\n"
2173 "Revision: %u.%u (%02u%02u)\n",
2174 Utf8Str(id).c_str(),
2175 usVendorId, usVendorId, usProductId, usProductId,
2176 bcdRevision >> 8, bcdRevision & 0xff,
2177 bcdRevision >> 8, bcdRevision & 0xff);
2178
2179 /* optional stuff. */
2180 Bstr bstr;
2181 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2182 if (!bstr.isEmpty())
2183 {
2184 if (details == VMINFO_MACHINEREADABLE)
2185 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2186 else
2187 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2188 }
2189 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2190 if (!bstr.isEmpty())
2191 {
2192 if (details == VMINFO_MACHINEREADABLE)
2193 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2194 else
2195 RTPrintf("Product: %ls\n", bstr.raw());
2196 }
2197 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2198 if (!bstr.isEmpty())
2199 {
2200 if (details == VMINFO_MACHINEREADABLE)
2201 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2202 else
2203 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2204 }
2205 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2206 if (!bstr.isEmpty())
2207 {
2208 if (details == VMINFO_MACHINEREADABLE)
2209 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2210 else
2211 RTPrintf("Address: %ls\n", bstr.raw());
2212 }
2213
2214 if (details != VMINFO_MACHINEREADABLE)
2215 RTPrintf("\n");
2216 }
2217 }
2218 }
2219 }
2220 } /* USB */
2221
2222#ifdef VBOX_WITH_PCI_PASSTHROUGH
2223 /* Host PCI passthrough devices */
2224 {
2225 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2226 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2227 if (SUCCEEDED(rc))
2228 {
2229 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2230 {
2231 RTPrintf("\nAttached physical PCI devices:\n\n");
2232 }
2233
2234 for (size_t index = 0; index < assignments.size(); ++index)
2235 {
2236 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2237 char szHostPCIAddress[32], szGuestPCIAddress[32];
2238 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2239 Bstr DevName;
2240
2241 Assignment->COMGETTER(Name)(DevName.asOutParam());
2242 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2243 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2244 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2245 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2246
2247 if (details == VMINFO_MACHINEREADABLE)
2248 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2249 else
2250 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2251 }
2252
2253 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2254 {
2255 RTPrintf("\n");
2256 }
2257 }
2258 }
2259 /* Host PCI passthrough devices */
2260#endif
2261
2262 /*
2263 * Bandwidth groups
2264 */
2265 if (details != VMINFO_MACHINEREADABLE)
2266 RTPrintf("Bandwidth groups: ");
2267 {
2268 ComPtr<IBandwidthControl> bwCtrl;
2269 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2270
2271 rc = showBandwidthGroups(bwCtrl, details);
2272 }
2273
2274
2275 /*
2276 * Shared folders
2277 */
2278 if (details != VMINFO_MACHINEREADABLE)
2279 RTPrintf("Shared folders: ");
2280 uint32_t numSharedFolders = 0;
2281#if 0 // not yet implemented
2282 /* globally shared folders first */
2283 {
2284 SafeIfaceArray <ISharedFolder> sfColl;
2285 CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2286 for (size_t i = 0; i < sfColl.size(); ++i)
2287 {
2288 ComPtr<ISharedFolder> sf = sfColl[i];
2289 Bstr name, hostPath;
2290 sf->COMGETTER(Name)(name.asOutParam());
2291 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2292 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2293 ++numSharedFolders;
2294 }
2295 }
2296#endif
2297 /* now VM mappings */
2298 {
2299 com::SafeIfaceArray <ISharedFolder> folders;
2300
2301 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2302
2303 for (size_t i = 0; i < folders.size(); ++i)
2304 {
2305 ComPtr<ISharedFolder> sf = folders[i];
2306
2307 Bstr name, hostPath;
2308 BOOL writable;
2309 sf->COMGETTER(Name)(name.asOutParam());
2310 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2311 sf->COMGETTER(Writable)(&writable);
2312 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2313 RTPrintf("\n\n");
2314 if (details == VMINFO_MACHINEREADABLE)
2315 {
2316 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2317 name.raw());
2318 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2319 hostPath.raw());
2320 }
2321 else
2322 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2323 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2324 ++numSharedFolders;
2325 }
2326 }
2327 /* transient mappings */
2328 if (pConsole)
2329 {
2330 com::SafeIfaceArray <ISharedFolder> folders;
2331
2332 CHECK_ERROR_RET(pConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2333
2334 for (size_t i = 0; i < folders.size(); ++i)
2335 {
2336 ComPtr<ISharedFolder> sf = folders[i];
2337
2338 Bstr name, hostPath;
2339 sf->COMGETTER(Name)(name.asOutParam());
2340 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2341 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2342 RTPrintf("\n\n");
2343 if (details == VMINFO_MACHINEREADABLE)
2344 {
2345 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2346 name.raw());
2347 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2348 hostPath.raw());
2349 }
2350 else
2351 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2352 ++numSharedFolders;
2353 }
2354 }
2355 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2356 RTPrintf("<none>\n");
2357 if (details != VMINFO_MACHINEREADABLE)
2358 RTPrintf("\n");
2359
2360 if (pConsole)
2361 {
2362 /*
2363 * Live VRDE info.
2364 */
2365 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2366 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2367 BOOL Active = FALSE;
2368 ULONG NumberOfClients = 0;
2369 LONG64 BeginTime = 0;
2370 LONG64 EndTime = 0;
2371 LONG64 BytesSent = 0;
2372 LONG64 BytesSentTotal = 0;
2373 LONG64 BytesReceived = 0;
2374 LONG64 BytesReceivedTotal = 0;
2375 Bstr User;
2376 Bstr Domain;
2377 Bstr ClientName;
2378 Bstr ClientIP;
2379 ULONG ClientVersion = 0;
2380 ULONG EncryptionStyle = 0;
2381
2382 if (!vrdeServerInfo.isNull())
2383 {
2384 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2385 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2386 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2387 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2388 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2389 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2390 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2391 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2392 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2393 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2394 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2395 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2396 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2397 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2398 }
2399
2400 if (details == VMINFO_MACHINEREADABLE)
2401 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2402 else
2403 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2404
2405 if (details == VMINFO_MACHINEREADABLE)
2406 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2407 else
2408 RTPrintf("Clients so far: %d\n", NumberOfClients);
2409
2410 if (NumberOfClients > 0)
2411 {
2412 char timestr[128];
2413
2414 if (Active)
2415 {
2416 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2417 if (details == VMINFO_MACHINEREADABLE)
2418 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2419 else
2420 RTPrintf("Start time: %s\n", timestr);
2421 }
2422 else
2423 {
2424 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2425 if (details == VMINFO_MACHINEREADABLE)
2426 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2427 else
2428 RTPrintf("Last started: %s\n", timestr);
2429 makeTimeStr(timestr, sizeof(timestr), EndTime);
2430 if (details == VMINFO_MACHINEREADABLE)
2431 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2432 else
2433 RTPrintf("Last ended: %s\n", timestr);
2434 }
2435
2436 int64_t ThroughputSend = 0;
2437 int64_t ThroughputReceive = 0;
2438 if (EndTime != BeginTime)
2439 {
2440 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2441 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2442 }
2443
2444 if (details == VMINFO_MACHINEREADABLE)
2445 {
2446 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2447 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2448 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2449
2450 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2451 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2452 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2453 }
2454 else
2455 {
2456 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2457 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2458 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2459
2460 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2461 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2462 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2463 }
2464
2465 if (Active)
2466 {
2467 if (details == VMINFO_MACHINEREADABLE)
2468 {
2469 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2470 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2471 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2472 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2473 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2474 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2475 }
2476 else
2477 {
2478 RTPrintf("User name: %ls\n", User.raw());
2479 RTPrintf("Domain: %ls\n", Domain.raw());
2480 RTPrintf("Client name: %ls\n", ClientName.raw());
2481 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2482 RTPrintf("Client version: %d\n", ClientVersion);
2483 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2484 }
2485 }
2486 }
2487
2488 if (details != VMINFO_MACHINEREADABLE)
2489 RTPrintf("\n");
2490 }
2491
2492 {
2493 /* Video capture */
2494 BOOL bActive = FALSE;
2495 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2496 com::SafeArray<BOOL> screens;
2497 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2498 ULONG Width;
2499 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2500 ULONG Height;
2501 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2502 ULONG Rate;
2503 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2504 ULONG Fps;
2505 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2506 Bstr File;
2507 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2508 if (details == VMINFO_MACHINEREADABLE)
2509 {
2510 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2511 RTPrintf("vcpscreens=");
2512 bool fComma = false;
2513 for (unsigned i = 0; i < screens.size(); i++)
2514 if (screens[i])
2515 {
2516 RTPrintf("%s%u", fComma ? "," : "", i);
2517 fComma = true;
2518 }
2519 RTPrintf("\n");
2520 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2521 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2522 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2523 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2524 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2525 }
2526 else
2527 {
2528 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2529 RTPrintf("Capture screens: ");
2530 bool fComma = false;
2531 for (unsigned i = 0; i < screens.size(); i++)
2532 if (screens[i])
2533 {
2534 RTPrintf("%s%u", fComma ? "," : "", i);
2535 fComma = true;
2536 }
2537 RTPrintf("\n");
2538 RTPrintf("Capture file: %ls\n", File.raw());
2539 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2540 RTPrintf("Capture rate: %u kbps\n", Rate);
2541 RTPrintf("Capture FPS: %u\n", Fps);
2542 RTPrintf("\n");
2543 }
2544 }
2545
2546 if ( details == VMINFO_STANDARD
2547 || details == VMINFO_FULL
2548 || details == VMINFO_MACHINEREADABLE)
2549 {
2550 Bstr description;
2551 machine->COMGETTER(Description)(description.asOutParam());
2552 if (!description.isEmpty())
2553 {
2554 if (details == VMINFO_MACHINEREADABLE)
2555 RTPrintf("description=\"%ls\"\n", description.raw());
2556 else
2557 RTPrintf("Description:\n%ls\n", description.raw());
2558 }
2559 }
2560
2561 if (details != VMINFO_MACHINEREADABLE)
2562 RTPrintf("Guest:\n\n");
2563
2564 ULONG guestVal;
2565 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2566 if (SUCCEEDED(rc))
2567 {
2568 if (details == VMINFO_MACHINEREADABLE)
2569 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2570 else
2571 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2572 }
2573
2574 if (pConsole)
2575 {
2576 ComPtr<IGuest> guest;
2577 rc = pConsole->COMGETTER(Guest)(guest.asOutParam());
2578 if (SUCCEEDED(rc) && !guest.isNull())
2579 {
2580 Bstr guestString;
2581 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2582 if ( SUCCEEDED(rc)
2583 && !guestString.isEmpty())
2584 {
2585 if (details == VMINFO_MACHINEREADABLE)
2586 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2587 else
2588 RTPrintf("OS type: %ls\n", guestString.raw());
2589 }
2590
2591 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2592 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2593 if (SUCCEEDED(rc))
2594 {
2595 if (details == VMINFO_MACHINEREADABLE)
2596 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2597 else
2598 RTPrintf("Additions run level: %u\n", guestRunLevel);
2599 }
2600
2601 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2602 if ( SUCCEEDED(rc)
2603 && !guestString.isEmpty())
2604 {
2605 ULONG uRevision;
2606 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2607 if (FAILED(rc))
2608 uRevision = 0;
2609
2610 if (details == VMINFO_MACHINEREADABLE)
2611 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2612 else
2613 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2614 }
2615
2616 if (details != VMINFO_MACHINEREADABLE)
2617 RTPrintf("\nGuest Facilities:\n\n");
2618
2619 /* Print information about known Guest Additions facilities: */
2620 SafeIfaceArray <IAdditionsFacility> collFac;
2621 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2622 LONG64 lLastUpdatedMS;
2623 char szLastUpdated[32];
2624 AdditionsFacilityStatus_T curStatus;
2625 for (size_t index = 0; index < collFac.size(); ++index)
2626 {
2627 ComPtr<IAdditionsFacility> fac = collFac[index];
2628 if (fac)
2629 {
2630 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2631 if (!guestString.isEmpty())
2632 {
2633 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2634 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2635 if (details == VMINFO_MACHINEREADABLE)
2636 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2637 guestString.raw(), curStatus, lLastUpdatedMS);
2638 else
2639 {
2640 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2641 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2642 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2643 }
2644 }
2645 else
2646 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2647 }
2648 else
2649 AssertMsgFailed(("Invalid facility returned!\n"));
2650 }
2651 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2652 RTPrintf("No active facilities.\n");
2653 }
2654 }
2655
2656 if (details != VMINFO_MACHINEREADABLE)
2657 RTPrintf("\n");
2658
2659 /*
2660 * snapshots
2661 */
2662 ComPtr<ISnapshot> snapshot;
2663 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2664 if (SUCCEEDED(rc) && snapshot)
2665 {
2666 ComPtr<ISnapshot> currentSnapshot;
2667 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2668 if (SUCCEEDED(rc))
2669 {
2670 if (details != VMINFO_MACHINEREADABLE)
2671 RTPrintf("Snapshots:\n\n");
2672 showSnapshots(snapshot, currentSnapshot, details);
2673 }
2674 }
2675
2676 if (details != VMINFO_MACHINEREADABLE)
2677 RTPrintf("\n");
2678 return S_OK;
2679}
2680
2681#if defined(_MSC_VER)
2682# pragma optimize("", on)
2683#endif
2684
2685static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2686{
2687 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2688 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2689 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2690 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2691 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2692};
2693
2694RTEXITCODE handleShowVMInfo(HandlerArg *a)
2695{
2696 HRESULT rc;
2697 const char *VMNameOrUuid = NULL;
2698 bool fLog = false;
2699 uint32_t uLogIdx = 0;
2700 bool fDetails = false;
2701 bool fMachinereadable = false;
2702
2703 int c;
2704 RTGETOPTUNION ValueUnion;
2705 RTGETOPTSTATE GetState;
2706 // start at 0 because main() has hacked both the argc and argv given to us
2707 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2708 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2709 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2710 {
2711 switch (c)
2712 {
2713 case 'D': // --details
2714 fDetails = true;
2715 break;
2716
2717 case 'M': // --machinereadable
2718 fMachinereadable = true;
2719 break;
2720
2721 case 'l': // --log
2722 fLog = true;
2723 uLogIdx = ValueUnion.u32;
2724 break;
2725
2726 case VINF_GETOPT_NOT_OPTION:
2727 if (!VMNameOrUuid)
2728 VMNameOrUuid = ValueUnion.psz;
2729 else
2730 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2731 break;
2732
2733 default:
2734 return errorGetOpt(USAGE_SHOWVMINFO, c, &ValueUnion);
2735 }
2736 }
2737
2738 /* check for required options */
2739 if (!VMNameOrUuid)
2740 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2741
2742 /* try to find the given machine */
2743 ComPtr<IMachine> machine;
2744 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2745 machine.asOutParam()));
2746 if (FAILED(rc))
2747 return RTEXITCODE_FAILURE;
2748
2749 /* Printing the log is exclusive. */
2750 if (fLog && (fMachinereadable || fDetails))
2751 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2752
2753 if (fLog)
2754 {
2755 ULONG64 uOffset = 0;
2756 SafeArray<BYTE> aLogData;
2757 size_t cbLogData;
2758 while (true)
2759 {
2760 /* Reset the array */
2761 aLogData.setNull();
2762 /* Fetch a chunk of the log file */
2763 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2764 ComSafeArrayAsOutParam(aLogData)));
2765 cbLogData = aLogData.size();
2766 if (cbLogData == 0)
2767 break;
2768 /* aLogData has a platform dependent line ending, standardize on
2769 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2770 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2771 size_t cbLogDataPrint = cbLogData;
2772 for (BYTE *s = aLogData.raw(), *d = s;
2773 s - aLogData.raw() < (ssize_t)cbLogData;
2774 s++, d++)
2775 {
2776 if (*s == '\r')
2777 {
2778 /* skip over CR, adjust destination */
2779 d--;
2780 cbLogDataPrint--;
2781 }
2782 else if (s != d)
2783 *d = *s;
2784 }
2785 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2786 uOffset += cbLogData;
2787 }
2788 }
2789 else
2790 {
2791 /* 2nd option can be -details or -argdump */
2792 VMINFO_DETAILS details = VMINFO_NONE;
2793 if (fMachinereadable)
2794 details = VMINFO_MACHINEREADABLE;
2795 else if (fDetails)
2796 details = VMINFO_FULL;
2797 else
2798 details = VMINFO_STANDARD;
2799
2800 /* open an existing session for the VM */
2801 rc = machine->LockMachine(a->session, LockType_Shared);
2802 if (SUCCEEDED(rc))
2803 /* get the session machine */
2804 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2805
2806 rc = showVMInfo(a->virtualBox, machine, a->session, details);
2807
2808 a->session->UnlockMachine();
2809 }
2810
2811 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
2812}
2813
2814#endif /* !VBOX_ONLY_DOCS */
2815/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette