VirtualBox

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

Last change on this file since 91396 was 91363, checked in by vboxsync, 3 years ago

FE/VBoxSDL+VirtualBox,Main/Console+Machine+VirtualBox.xidl: VMs which
crash while restoring from the 'Saved' state shouldn't lose their saved
state file. bugref:1484

A new machine state named 'AbortedSaved' has been added which a VM will
enter if it crashes when restoring from the 'Saved' state before the
'Running' state has been reached. A VM in the 'AbortedSaved' machine
state will have its saved state file preserved so that the VM can still be
restored once the cause of the failure to powerUp() and reach the
'Running' state has been resolved.

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