VirtualBox

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

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

VBoxManage: use common code in bandwidthctl and showvminfo to list groups, fixed machine readable list (#5582)

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