VirtualBox

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

Last change on this file since 81644 was 81603, checked in by vboxsync, 5 years ago

Main: Added PCnet-ISA/NE2100/Am79C960 to the API (the device side is long in place).

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