VirtualBox

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

Last change on this file since 41754 was 41584, checked in by vboxsync, 13 years ago

VBoxManage/Info: print <none> when no bandwidth groups defined for VM

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