VirtualBox

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

Last change on this file since 53402 was 53266, checked in by vboxsync, 10 years ago

Frontend/VBoxManage: minor cleanup of showVMInfo, and fixing a ULONG/size_t warning

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