VirtualBox

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

Last change on this file since 53099 was 52978, checked in by vboxsync, 11 years ago

IDisplay::GetScreenResolution returns status of the guest monitor.

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

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