VirtualBox

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

Last change on this file since 64104 was 64104, checked in by vboxsync, 8 years ago

VBoxManage: GuestMonitorStatus_Blank for VM info

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