VirtualBox

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

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

Main,VBoxManage,docs: bandwidth units changed to bytes (#5582)

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

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