VirtualBox

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

Last change on this file since 43422 was 43422, checked in by vboxsync, 12 years ago

VBoxManage: showvminfo --machinereadable: added a few missing items

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

© 2023 Oracle
ContactPrivacy policyTerms of Use