VirtualBox

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

Last change on this file since 52312 was 52037, checked in by vboxsync, 10 years ago

Frontends/VBoxManage: add the forgotten "modifyvm --description" option to the help output and fix a minor VRDP port info glitch

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 112.3 KB
Line 
1/* $Id: VBoxManageInfo.cpp 52037 2014-07-15 13:07:29Z 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 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin);
1685 if (rc == E_ACCESSDENIED)
1686 break; /* VM not powered up */
1687 if (FAILED(rc))
1688 {
1689 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1690 GluePrintErrorInfo(info);
1691 return rc;
1692 }
1693 if (details == VMINFO_MACHINEREADABLE)
1694 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1695 else
1696 RTPrintf("Video mode: %dx%dx%d at %d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1697 }
1698 while (0);
1699 }
1700
1701 /*
1702 * Remote Desktop
1703 */
1704 ComPtr<IVRDEServer> vrdeServer;
1705 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1706 if (SUCCEEDED(rc) && vrdeServer)
1707 {
1708 BOOL fEnabled = false;
1709 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1710 if (fEnabled)
1711 {
1712 LONG currentPort = -1;
1713 Bstr ports;
1714 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1715 Bstr address;
1716 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1717 BOOL fMultiCon;
1718 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1719 BOOL fReuseCon;
1720 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1721 Bstr videoChannel;
1722 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1723 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1724 || (videoChannel == "1");
1725 Bstr videoChannelQuality;
1726 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1727 AuthType_T authType;
1728 const char *strAuthType;
1729 vrdeServer->COMGETTER(AuthType)(&authType);
1730 switch (authType)
1731 {
1732 case AuthType_Null:
1733 strAuthType = "null";
1734 break;
1735 case AuthType_External:
1736 strAuthType = "external";
1737 break;
1738 case AuthType_Guest:
1739 strAuthType = "guest";
1740 break;
1741 default:
1742 strAuthType = "unknown";
1743 break;
1744 }
1745 if (console)
1746 {
1747 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1748 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1749 if (!vrdeServerInfo.isNull())
1750 {
1751 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1752 if (rc == E_ACCESSDENIED)
1753 {
1754 currentPort = -1; /* VM not powered up */
1755 }
1756 else if (FAILED(rc))
1757 {
1758 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1759 GluePrintErrorInfo(info);
1760 return rc;
1761 }
1762 }
1763 }
1764 if (details == VMINFO_MACHINEREADABLE)
1765 {
1766 RTPrintf("vrde=\"on\"\n");
1767 RTPrintf("vrdeport=%d\n", currentPort);
1768 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1769 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1770 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1771 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1772 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1773 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1774 if (fVideoChannel)
1775 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1776 }
1777 else
1778 {
1779 if (address.isEmpty())
1780 address = "0.0.0.0";
1781 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);
1782 if (console && currentPort != -1 && currentPort != 0)
1783 RTPrintf("VRDE port: %d\n", currentPort);
1784 if (fVideoChannel)
1785 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1786 else
1787 RTPrintf("Video redirection: disabled\n");
1788 }
1789 com::SafeArray<BSTR> aProperties;
1790 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1791 {
1792 unsigned i;
1793 for (i = 0; i < aProperties.size(); ++i)
1794 {
1795 Bstr value;
1796 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1797 if (details == VMINFO_MACHINEREADABLE)
1798 {
1799 if (value.isEmpty())
1800 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1801 else
1802 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1803 }
1804 else
1805 {
1806 if (value.isEmpty())
1807 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1808 else
1809 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1810 }
1811 }
1812 }
1813 }
1814 else
1815 {
1816 if (details == VMINFO_MACHINEREADABLE)
1817 RTPrintf("vrde=\"off\"\n");
1818 else
1819 RTPrintf("VRDE: disabled\n");
1820 }
1821 }
1822
1823 /*
1824 * USB.
1825 */
1826 SafeIfaceArray<IUSBController> USBCtlColl;
1827 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
1828 if (SUCCEEDED(rc))
1829 {
1830 bool fOhciEnabled = false;
1831 bool fEhciEnabled = false;
1832 bool fXhciEnabled = false;
1833
1834 for (unsigned i = 0; i < USBCtlColl.size(); i++)
1835 {
1836 USBControllerType_T enmType;
1837
1838 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
1839 if (SUCCEEDED(rc))
1840 {
1841 switch (enmType)
1842 {
1843 case USBControllerType_OHCI:
1844 fOhciEnabled = true;
1845 break;
1846 case USBControllerType_EHCI:
1847 fEhciEnabled = true;
1848 break;
1849 case USBControllerType_XHCI:
1850 fXhciEnabled = true;
1851 break;
1852 default:
1853 break;
1854 }
1855 }
1856 }
1857
1858 if (details == VMINFO_MACHINEREADABLE)
1859 RTPrintf("usb=\"%s\"\n", fOhciEnabled ? "on" : "off");
1860 else
1861 RTPrintf("USB: %s\n", fOhciEnabled ? "enabled" : "disabled");
1862
1863 if (details == VMINFO_MACHINEREADABLE)
1864 RTPrintf("ehci=\"%s\"\n", fEhciEnabled ? "on" : "off");
1865 else
1866 RTPrintf("EHCI: %s\n", fEhciEnabled ? "enabled" : "disabled");
1867
1868 if (details == VMINFO_MACHINEREADABLE)
1869 RTPrintf("xhci=\"%s\"\n", fXhciEnabled ? "on" : "off");
1870 else
1871 RTPrintf("XHCI: %s\n", fXhciEnabled ? "enabled" : "disabled");
1872 }
1873
1874 ComPtr<IUSBDeviceFilters> USBFlts;
1875 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
1876 if (SUCCEEDED(rc))
1877 {
1878 SafeIfaceArray <IUSBDeviceFilter> Coll;
1879 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1880 if (SUCCEEDED(rc))
1881 {
1882 if (details != VMINFO_MACHINEREADABLE)
1883 RTPrintf("\nUSB Device Filters:\n\n");
1884
1885 if (Coll.size() == 0)
1886 {
1887 if (details != VMINFO_MACHINEREADABLE)
1888 RTPrintf("<none>\n\n");
1889 }
1890 else
1891 {
1892 for (size_t index = 0; index < Coll.size(); ++index)
1893 {
1894 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1895
1896 /* Query info. */
1897
1898 if (details != VMINFO_MACHINEREADABLE)
1899 RTPrintf("Index: %zu\n", index);
1900
1901 BOOL bActive = FALSE;
1902 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1903 if (details == VMINFO_MACHINEREADABLE)
1904 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1905 else
1906 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1907
1908 Bstr bstr;
1909 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1910 if (details == VMINFO_MACHINEREADABLE)
1911 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1912 else
1913 RTPrintf("Name: %ls\n", bstr.raw());
1914 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1915 if (details == VMINFO_MACHINEREADABLE)
1916 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1917 else
1918 RTPrintf("VendorId: %ls\n", bstr.raw());
1919 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1920 if (details == VMINFO_MACHINEREADABLE)
1921 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
1922 else
1923 RTPrintf("ProductId: %ls\n", bstr.raw());
1924 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1925 if (details == VMINFO_MACHINEREADABLE)
1926 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
1927 else
1928 RTPrintf("Revision: %ls\n", bstr.raw());
1929 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1930 if (details == VMINFO_MACHINEREADABLE)
1931 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1932 else
1933 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1934 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1935 if (details == VMINFO_MACHINEREADABLE)
1936 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1937 else
1938 RTPrintf("Product: %ls\n", bstr.raw());
1939 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1940 if (details == VMINFO_MACHINEREADABLE)
1941 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
1942 else
1943 RTPrintf("Remote: %ls\n", bstr.raw());
1944 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1945 if (details == VMINFO_MACHINEREADABLE)
1946 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1947 else
1948 RTPrintf("Serial Number: %ls\n", bstr.raw());
1949 if (details != VMINFO_MACHINEREADABLE)
1950 {
1951 ULONG fMaskedIfs;
1952 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1953 if (fMaskedIfs)
1954 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1955 RTPrintf("\n");
1956 }
1957 }
1958 }
1959 }
1960
1961 if (console)
1962 {
1963 /* scope */
1964 {
1965 if (details != VMINFO_MACHINEREADABLE)
1966 RTPrintf("Available remote USB devices:\n\n");
1967
1968 SafeIfaceArray <IHostUSBDevice> coll;
1969 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1970
1971 if (coll.size() == 0)
1972 {
1973 if (details != VMINFO_MACHINEREADABLE)
1974 RTPrintf("<none>\n\n");
1975 }
1976 else
1977 {
1978 for (size_t index = 0; index < coll.size(); ++index)
1979 {
1980 ComPtr<IHostUSBDevice> dev = coll[index];
1981
1982 /* Query info. */
1983 Bstr id;
1984 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1985 USHORT usVendorId;
1986 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1987 USHORT usProductId;
1988 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1989 USHORT bcdRevision;
1990 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1991
1992 if (details == VMINFO_MACHINEREADABLE)
1993 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
1994 "USBRemoteVendorId%zu=\"%#06x\"\n"
1995 "USBRemoteProductId%zu=\"%#06x\"\n"
1996 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1997 index + 1, Utf8Str(id).c_str(),
1998 index + 1, usVendorId,
1999 index + 1, usProductId,
2000 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2001 else
2002 RTPrintf("UUID: %s\n"
2003 "VendorId: %#06x (%04X)\n"
2004 "ProductId: %#06x (%04X)\n"
2005 "Revision: %u.%u (%02u%02u)\n",
2006 Utf8Str(id).c_str(),
2007 usVendorId, usVendorId, usProductId, usProductId,
2008 bcdRevision >> 8, bcdRevision & 0xff,
2009 bcdRevision >> 8, bcdRevision & 0xff);
2010
2011 /* optional stuff. */
2012 Bstr bstr;
2013 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2014 if (!bstr.isEmpty())
2015 {
2016 if (details == VMINFO_MACHINEREADABLE)
2017 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2018 else
2019 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2020 }
2021 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2022 if (!bstr.isEmpty())
2023 {
2024 if (details == VMINFO_MACHINEREADABLE)
2025 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2026 else
2027 RTPrintf("Product: %ls\n", bstr.raw());
2028 }
2029 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2030 if (!bstr.isEmpty())
2031 {
2032 if (details == VMINFO_MACHINEREADABLE)
2033 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2034 else
2035 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2036 }
2037 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2038 if (!bstr.isEmpty())
2039 {
2040 if (details == VMINFO_MACHINEREADABLE)
2041 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2042 else
2043 RTPrintf("Address: %ls\n", bstr.raw());
2044 }
2045
2046 if (details != VMINFO_MACHINEREADABLE)
2047 RTPrintf("\n");
2048 }
2049 }
2050 }
2051
2052 /* scope */
2053 {
2054 if (details != VMINFO_MACHINEREADABLE)
2055 RTPrintf("Currently Attached USB Devices:\n\n");
2056
2057 SafeIfaceArray <IUSBDevice> coll;
2058 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2059
2060 if (coll.size() == 0)
2061 {
2062 if (details != VMINFO_MACHINEREADABLE)
2063 RTPrintf("<none>\n\n");
2064 }
2065 else
2066 {
2067 for (size_t index = 0; index < coll.size(); ++index)
2068 {
2069 ComPtr<IUSBDevice> dev = coll[index];
2070
2071 /* Query info. */
2072 Bstr id;
2073 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
2074 USHORT usVendorId;
2075 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
2076 USHORT usProductId;
2077 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
2078 USHORT bcdRevision;
2079 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2080
2081 if (details == VMINFO_MACHINEREADABLE)
2082 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
2083 "USBAttachedVendorId%zu=\"%#06x\"\n"
2084 "USBAttachedProductId%zu=\"%#06x\"\n"
2085 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
2086 index + 1, Utf8Str(id).c_str(),
2087 index + 1, usVendorId,
2088 index + 1, usProductId,
2089 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2090 else
2091 RTPrintf("UUID: %s\n"
2092 "VendorId: %#06x (%04X)\n"
2093 "ProductId: %#06x (%04X)\n"
2094 "Revision: %u.%u (%02u%02u)\n",
2095 Utf8Str(id).c_str(),
2096 usVendorId, usVendorId, usProductId, usProductId,
2097 bcdRevision >> 8, bcdRevision & 0xff,
2098 bcdRevision >> 8, bcdRevision & 0xff);
2099
2100 /* optional stuff. */
2101 Bstr bstr;
2102 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2103 if (!bstr.isEmpty())
2104 {
2105 if (details == VMINFO_MACHINEREADABLE)
2106 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2107 else
2108 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2109 }
2110 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2111 if (!bstr.isEmpty())
2112 {
2113 if (details == VMINFO_MACHINEREADABLE)
2114 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2115 else
2116 RTPrintf("Product: %ls\n", bstr.raw());
2117 }
2118 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2119 if (!bstr.isEmpty())
2120 {
2121 if (details == VMINFO_MACHINEREADABLE)
2122 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2123 else
2124 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2125 }
2126 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2127 if (!bstr.isEmpty())
2128 {
2129 if (details == VMINFO_MACHINEREADABLE)
2130 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2131 else
2132 RTPrintf("Address: %ls\n", bstr.raw());
2133 }
2134
2135 if (details != VMINFO_MACHINEREADABLE)
2136 RTPrintf("\n");
2137 }
2138 }
2139 }
2140 }
2141 } /* USB */
2142
2143#ifdef VBOX_WITH_PCI_PASSTHROUGH
2144 /* Host PCI passthrough devices */
2145 {
2146 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2147 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2148 if (SUCCEEDED(rc))
2149 {
2150 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2151 {
2152 RTPrintf("\nAttached physical PCI devices:\n\n");
2153 }
2154
2155 for (size_t index = 0; index < assignments.size(); ++index)
2156 {
2157 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2158 char szHostPCIAddress[32], szGuestPCIAddress[32];
2159 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2160 Bstr DevName;
2161
2162 Assignment->COMGETTER(Name)(DevName.asOutParam());
2163 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2164 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2165 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2166 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2167
2168 if (details == VMINFO_MACHINEREADABLE)
2169 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2170 else
2171 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2172 }
2173
2174 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2175 {
2176 RTPrintf("\n");
2177 }
2178 }
2179 }
2180 /* Host PCI passthrough devices */
2181#endif
2182
2183 /*
2184 * Bandwidth groups
2185 */
2186 if (details != VMINFO_MACHINEREADABLE)
2187 RTPrintf("Bandwidth groups: ");
2188 {
2189 ComPtr<IBandwidthControl> bwCtrl;
2190 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2191
2192 rc = showBandwidthGroups(bwCtrl, details);
2193 }
2194
2195
2196 /*
2197 * Shared folders
2198 */
2199 if (details != VMINFO_MACHINEREADABLE)
2200 RTPrintf("Shared folders: ");
2201 uint32_t numSharedFolders = 0;
2202#if 0 // not yet implemented
2203 /* globally shared folders first */
2204 {
2205 SafeIfaceArray <ISharedFolder> sfColl;
2206 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2207 for (size_t i = 0; i < sfColl.size(); ++i)
2208 {
2209 ComPtr<ISharedFolder> sf = sfColl[i];
2210 Bstr name, hostPath;
2211 sf->COMGETTER(Name)(name.asOutParam());
2212 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2213 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2214 ++numSharedFolders;
2215 }
2216 }
2217#endif
2218 /* now VM mappings */
2219 {
2220 com::SafeIfaceArray <ISharedFolder> folders;
2221
2222 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2223
2224 for (size_t i = 0; i < folders.size(); ++i)
2225 {
2226 ComPtr<ISharedFolder> sf = folders[i];
2227
2228 Bstr name, hostPath;
2229 BOOL writable;
2230 sf->COMGETTER(Name)(name.asOutParam());
2231 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2232 sf->COMGETTER(Writable)(&writable);
2233 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2234 RTPrintf("\n\n");
2235 if (details == VMINFO_MACHINEREADABLE)
2236 {
2237 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2238 name.raw());
2239 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2240 hostPath.raw());
2241 }
2242 else
2243 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2244 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2245 ++numSharedFolders;
2246 }
2247 }
2248 /* transient mappings */
2249 if (console)
2250 {
2251 com::SafeIfaceArray <ISharedFolder> folders;
2252
2253 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2254
2255 for (size_t i = 0; i < folders.size(); ++i)
2256 {
2257 ComPtr<ISharedFolder> sf = folders[i];
2258
2259 Bstr name, hostPath;
2260 sf->COMGETTER(Name)(name.asOutParam());
2261 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2262 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2263 RTPrintf("\n\n");
2264 if (details == VMINFO_MACHINEREADABLE)
2265 {
2266 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2267 name.raw());
2268 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2269 hostPath.raw());
2270 }
2271 else
2272 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2273 ++numSharedFolders;
2274 }
2275 }
2276 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2277 RTPrintf("<none>\n");
2278 if (details != VMINFO_MACHINEREADABLE)
2279 RTPrintf("\n");
2280
2281 if (console)
2282 {
2283 /*
2284 * Live VRDE info.
2285 */
2286 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2287 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2288 BOOL Active = FALSE;
2289 ULONG NumberOfClients = 0;
2290 LONG64 BeginTime = 0;
2291 LONG64 EndTime = 0;
2292 LONG64 BytesSent = 0;
2293 LONG64 BytesSentTotal = 0;
2294 LONG64 BytesReceived = 0;
2295 LONG64 BytesReceivedTotal = 0;
2296 Bstr User;
2297 Bstr Domain;
2298 Bstr ClientName;
2299 Bstr ClientIP;
2300 ULONG ClientVersion = 0;
2301 ULONG EncryptionStyle = 0;
2302
2303 if (!vrdeServerInfo.isNull())
2304 {
2305 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2306 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2307 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2308 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2309 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2310 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2311 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2312 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2313 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2314 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2315 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2316 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2317 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2318 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2319 }
2320
2321 if (details == VMINFO_MACHINEREADABLE)
2322 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2323 else
2324 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2325
2326 if (details == VMINFO_MACHINEREADABLE)
2327 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2328 else
2329 RTPrintf("Clients so far: %d\n", NumberOfClients);
2330
2331 if (NumberOfClients > 0)
2332 {
2333 char timestr[128];
2334
2335 if (Active)
2336 {
2337 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2338 if (details == VMINFO_MACHINEREADABLE)
2339 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2340 else
2341 RTPrintf("Start time: %s\n", timestr);
2342 }
2343 else
2344 {
2345 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2346 if (details == VMINFO_MACHINEREADABLE)
2347 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2348 else
2349 RTPrintf("Last started: %s\n", timestr);
2350 makeTimeStr(timestr, sizeof(timestr), EndTime);
2351 if (details == VMINFO_MACHINEREADABLE)
2352 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2353 else
2354 RTPrintf("Last ended: %s\n", timestr);
2355 }
2356
2357 int64_t ThroughputSend = 0;
2358 int64_t ThroughputReceive = 0;
2359 if (EndTime != BeginTime)
2360 {
2361 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2362 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2363 }
2364
2365 if (details == VMINFO_MACHINEREADABLE)
2366 {
2367 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2368 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2369 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2370
2371 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2372 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2373 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2374 }
2375 else
2376 {
2377 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2378 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2379 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2380
2381 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2382 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2383 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2384 }
2385
2386 if (Active)
2387 {
2388 if (details == VMINFO_MACHINEREADABLE)
2389 {
2390 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2391 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2392 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2393 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2394 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2395 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2396 }
2397 else
2398 {
2399 RTPrintf("User name: %ls\n", User.raw());
2400 RTPrintf("Domain: %ls\n", Domain.raw());
2401 RTPrintf("Client name: %ls\n", ClientName.raw());
2402 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2403 RTPrintf("Client version: %d\n", ClientVersion);
2404 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2405 }
2406 }
2407 }
2408
2409 if (details != VMINFO_MACHINEREADABLE)
2410 RTPrintf("\n");
2411 }
2412
2413 {
2414 /* Video capture */
2415 BOOL bActive = FALSE;
2416 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2417 com::SafeArray<BOOL> screens;
2418 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2419 ULONG Width;
2420 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2421 ULONG Height;
2422 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2423 ULONG Rate;
2424 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2425 ULONG Fps;
2426 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2427 Bstr File;
2428 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2429 if (details == VMINFO_MACHINEREADABLE)
2430 {
2431 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2432 RTPrintf("vcpscreens=");
2433 bool fComma = false;
2434 for (unsigned i = 0; i < screens.size(); i++)
2435 if (screens[i])
2436 {
2437 RTPrintf("%s%u", fComma ? "," : "", i);
2438 fComma = true;
2439 }
2440 RTPrintf("\n");
2441 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2442 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2443 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2444 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2445 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2446 }
2447 else
2448 {
2449 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2450 RTPrintf("Capture screens: ");
2451 bool fComma = false;
2452 for (unsigned i = 0; i < screens.size(); i++)
2453 if (screens[i])
2454 {
2455 RTPrintf("%s%u", fComma ? "," : "", i);
2456 fComma = true;
2457 }
2458 RTPrintf("\n");
2459 RTPrintf("Capture file: %ls\n", File.raw());
2460 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2461 RTPrintf("Capture rate: %u kbps\n", Rate);
2462 RTPrintf("Capture FPS: %u\n", Fps);
2463 RTPrintf("\n");
2464 }
2465 }
2466
2467 if ( details == VMINFO_STANDARD
2468 || details == VMINFO_FULL
2469 || details == VMINFO_MACHINEREADABLE)
2470 {
2471 Bstr description;
2472 machine->COMGETTER(Description)(description.asOutParam());
2473 if (!description.isEmpty())
2474 {
2475 if (details == VMINFO_MACHINEREADABLE)
2476 RTPrintf("description=\"%ls\"\n", description.raw());
2477 else
2478 RTPrintf("Description:\n%ls\n", description.raw());
2479 }
2480 }
2481
2482 if (details != VMINFO_MACHINEREADABLE)
2483 RTPrintf("Guest:\n\n");
2484
2485 ULONG guestVal;
2486 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2487 if (SUCCEEDED(rc))
2488 {
2489 if (details == VMINFO_MACHINEREADABLE)
2490 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2491 else
2492 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2493 }
2494
2495 if (console)
2496 {
2497 ComPtr<IGuest> guest;
2498 rc = console->COMGETTER(Guest)(guest.asOutParam());
2499 if (SUCCEEDED(rc) && !guest.isNull())
2500 {
2501 Bstr guestString;
2502 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2503 if ( SUCCEEDED(rc)
2504 && !guestString.isEmpty())
2505 {
2506 if (details == VMINFO_MACHINEREADABLE)
2507 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2508 else
2509 RTPrintf("OS type: %ls\n", guestString.raw());
2510 }
2511
2512 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2513 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2514 if (SUCCEEDED(rc))
2515 {
2516 if (details == VMINFO_MACHINEREADABLE)
2517 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2518 else
2519 RTPrintf("Additions run level: %u\n", guestRunLevel);
2520 }
2521
2522 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2523 if ( SUCCEEDED(rc)
2524 && !guestString.isEmpty())
2525 {
2526 ULONG uRevision;
2527 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2528 if (FAILED(rc))
2529 uRevision = 0;
2530
2531 if (details == VMINFO_MACHINEREADABLE)
2532 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2533 else
2534 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2535 }
2536
2537 if (details != VMINFO_MACHINEREADABLE)
2538 RTPrintf("\nGuest Facilities:\n\n");
2539
2540 /* Print information about known Guest Additions facilities: */
2541 SafeIfaceArray <IAdditionsFacility> collFac;
2542 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2543 LONG64 lLastUpdatedMS;
2544 char szLastUpdated[32];
2545 AdditionsFacilityStatus_T curStatus;
2546 for (size_t index = 0; index < collFac.size(); ++index)
2547 {
2548 ComPtr<IAdditionsFacility> fac = collFac[index];
2549 if (fac)
2550 {
2551 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2552 if (!guestString.isEmpty())
2553 {
2554 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2555 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2556 if (details == VMINFO_MACHINEREADABLE)
2557 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2558 guestString.raw(), curStatus, lLastUpdatedMS);
2559 else
2560 {
2561 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2562 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2563 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2564 }
2565 }
2566 else
2567 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2568 }
2569 else
2570 AssertMsgFailed(("Invalid facility returned!\n"));
2571 }
2572 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2573 RTPrintf("No active facilities.\n");
2574 }
2575 }
2576
2577 if (details != VMINFO_MACHINEREADABLE)
2578 RTPrintf("\n");
2579
2580 /*
2581 * snapshots
2582 */
2583 ComPtr<ISnapshot> snapshot;
2584 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2585 if (SUCCEEDED(rc) && snapshot)
2586 {
2587 ComPtr<ISnapshot> currentSnapshot;
2588 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2589 if (SUCCEEDED(rc))
2590 {
2591 if (details != VMINFO_MACHINEREADABLE)
2592 RTPrintf("Snapshots:\n\n");
2593 showSnapshots(snapshot, currentSnapshot, details);
2594 }
2595 }
2596
2597 if (details != VMINFO_MACHINEREADABLE)
2598 RTPrintf("\n");
2599 return S_OK;
2600}
2601
2602#if defined(_MSC_VER)
2603# pragma optimize("", on)
2604#endif
2605
2606static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2607{
2608 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2609 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2610 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2611 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2612 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2613};
2614
2615int handleShowVMInfo(HandlerArg *a)
2616{
2617 HRESULT rc;
2618 const char *VMNameOrUuid = NULL;
2619 bool fLog = false;
2620 uint32_t uLogIdx = 0;
2621 bool fDetails = false;
2622 bool fMachinereadable = false;
2623
2624 int c;
2625 RTGETOPTUNION ValueUnion;
2626 RTGETOPTSTATE GetState;
2627 // start at 0 because main() has hacked both the argc and argv given to us
2628 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2629 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2630 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2631 {
2632 switch (c)
2633 {
2634 case 'D': // --details
2635 fDetails = true;
2636 break;
2637
2638 case 'M': // --machinereadable
2639 fMachinereadable = true;
2640 break;
2641
2642 case 'l': // --log
2643 fLog = true;
2644 uLogIdx = ValueUnion.u32;
2645 break;
2646
2647 case VINF_GETOPT_NOT_OPTION:
2648 if (!VMNameOrUuid)
2649 VMNameOrUuid = ValueUnion.psz;
2650 else
2651 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2652 break;
2653
2654 default:
2655 if (c > 0)
2656 {
2657 if (RT_C_IS_PRINT(c))
2658 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2659 else
2660 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2661 }
2662 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2663 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2664 else if (ValueUnion.pDef)
2665 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2666 else
2667 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2668 }
2669 }
2670
2671 /* check for required options */
2672 if (!VMNameOrUuid)
2673 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2674
2675 /* try to find the given machine */
2676 ComPtr<IMachine> machine;
2677 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2678 machine.asOutParam()));
2679 if (FAILED(rc))
2680 return 1;
2681
2682 /* Printing the log is exclusive. */
2683 if (fLog && (fMachinereadable || fDetails))
2684 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2685
2686 if (fLog)
2687 {
2688 ULONG64 uOffset = 0;
2689 SafeArray<BYTE> aLogData;
2690 ULONG cbLogData;
2691 while (true)
2692 {
2693 /* Reset the array */
2694 aLogData.setNull();
2695 /* Fetch a chunk of the log file */
2696 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2697 ComSafeArrayAsOutParam(aLogData)));
2698 cbLogData = aLogData.size();
2699 if (cbLogData == 0)
2700 break;
2701 /* aLogData has a platform dependent line ending, standardize on
2702 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2703 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2704 ULONG cbLogDataPrint = cbLogData;
2705 for (BYTE *s = aLogData.raw(), *d = s;
2706 s - aLogData.raw() < (ssize_t)cbLogData;
2707 s++, d++)
2708 {
2709 if (*s == '\r')
2710 {
2711 /* skip over CR, adjust destination */
2712 d--;
2713 cbLogDataPrint--;
2714 }
2715 else if (s != d)
2716 *d = *s;
2717 }
2718 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2719 uOffset += cbLogData;
2720 }
2721 }
2722 else
2723 {
2724 /* 2nd option can be -details or -argdump */
2725 VMINFO_DETAILS details = VMINFO_NONE;
2726 if (fMachinereadable)
2727 details = VMINFO_MACHINEREADABLE;
2728 else if (fDetails)
2729 details = VMINFO_FULL;
2730 else
2731 details = VMINFO_STANDARD;
2732
2733 ComPtr<IConsole> console;
2734
2735 /* open an existing session for the VM */
2736 rc = machine->LockMachine(a->session, LockType_Shared);
2737 if (SUCCEEDED(rc))
2738 /* get the session machine */
2739 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2740 if (SUCCEEDED(rc))
2741 /* get the session console */
2742 rc = a->session->COMGETTER(Console)(console.asOutParam());
2743
2744 rc = showVMInfo(a->virtualBox, machine, details, console);
2745
2746 if (console)
2747 a->session->UnlockMachine();
2748 }
2749
2750 return SUCCEEDED(rc) ? 0 : 1;
2751}
2752
2753#endif /* !VBOX_ONLY_DOCS */
2754/* 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