VirtualBox

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

Last change on this file since 67954 was 66830, checked in by vboxsync, 7 years ago

VBoxManage: Adjustments for Visual C++ v12 / Visual Studio 2013. Dropped warning 4748.

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