VirtualBox

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

Last change on this file since 50837 was 50721, checked in by vboxsync, 11 years ago

Updated USB configuration.

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

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