VirtualBox

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

Last change on this file since 47403 was 47401, checked in by vboxsync, 11 years ago

Main,Frontends: Second step of USB controller rework. There is one controller instance for every USB controller now. Adapt frontends and testsuite to work with the changed API

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 109.4 KB
Line 
1/* $Id: VBoxManageInfo.cpp 47401 2013-07-25 19:12:24Z 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_Exclusive, &f), "hwvirtexexcl", "Hardw. virt.ext exclusive");
675 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", "Nested Paging");
676 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", "Large Pages");
677 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID");
678 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", "VT-x unr. exec.");
679
680 MachineState_T machineState;
681 CHECK_ERROR2_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
682 const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
683
684 LONG64 stateSince;
685 machine->COMGETTER(LastStateChange)(&stateSince);
686 RTTIMESPEC timeSpec;
687 RTTimeSpecSetMilli(&timeSpec, stateSince);
688 char pszTime[30] = {0};
689 RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
690 if (details == VMINFO_MACHINEREADABLE)
691 {
692 RTPrintf("VMState=\"%s\"\n", pszState);
693 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
694
695 Bstr stateFile;
696 machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
697 if (!stateFile.isEmpty())
698 RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
699 }
700 else
701 RTPrintf("State: %s (since %s)\n", pszState, pszTime);
702
703 SHOW_ULONG_PROP( machine, MonitorCount, "monitorcount", "Monitor count", "");
704 SHOW_BOOLEAN_PROP( machine, Accelerate3DEnabled, "accelerate3d", "3D Acceleration");
705#ifdef VBOX_WITH_VIDEOHWACCEL
706 SHOW_BOOLEAN_PROP( machine, Accelerate2DVideoEnabled, "accelerate2dvideo", "2D Video Acceleration");
707#endif
708 SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", "Teleporter Enabled");
709 SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", "Teleporter Port", "");
710 SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", "Teleporter Address");
711 SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", "Teleporter Password");
712 SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", "Tracing Enabled");
713 SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", "Allow Tracing to Access VM");
714 SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", "Tracing Configuration");
715 SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", "Autostart Enabled");
716 SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", "Autostart Delay", "");
717 SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", "Default Frontend");
718
719/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
720 * checking where missing. */
721 /*
722 * Storage Controllers and their attached Mediums.
723 */
724 com::SafeIfaceArray<IStorageController> storageCtls;
725 CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
726 for (size_t i = 0; i < storageCtls.size(); ++ i)
727 {
728 ComPtr<IStorageController> storageCtl = storageCtls[i];
729 StorageControllerType_T enmCtlType = StorageControllerType_Null;
730 const char *pszCtl = NULL;
731 ULONG ulValue = 0;
732 BOOL fBootable = FALSE;
733 Bstr storageCtlName;
734
735 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
736 if (details == VMINFO_MACHINEREADABLE)
737 RTPrintf("storagecontrollername%u=\"%ls\"\n", i, storageCtlName.raw());
738 else
739 RTPrintf("Storage Controller Name (%u): %ls\n", i, storageCtlName.raw());
740
741 storageCtl->COMGETTER(ControllerType)(&enmCtlType);
742 switch (enmCtlType)
743 {
744 case StorageControllerType_LsiLogic:
745 pszCtl = "LsiLogic";
746 break;
747 case StorageControllerType_BusLogic:
748 pszCtl = "BusLogic";
749 break;
750 case StorageControllerType_IntelAhci:
751 pszCtl = "IntelAhci";
752 break;
753 case StorageControllerType_PIIX3:
754 pszCtl = "PIIX3";
755 break;
756 case StorageControllerType_PIIX4:
757 pszCtl = "PIIX4";
758 break;
759 case StorageControllerType_ICH6:
760 pszCtl = "ICH6";
761 break;
762 case StorageControllerType_I82078:
763 pszCtl = "I82078";
764 break;
765
766 default:
767 pszCtl = "unknown";
768 }
769 if (details == VMINFO_MACHINEREADABLE)
770 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
771 else
772 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
773
774 storageCtl->COMGETTER(Instance)(&ulValue);
775 if (details == VMINFO_MACHINEREADABLE)
776 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
777 else
778 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
779
780 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
781 if (details == VMINFO_MACHINEREADABLE)
782 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
783 else
784 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
785
786 storageCtl->COMGETTER(PortCount)(&ulValue);
787 if (details == VMINFO_MACHINEREADABLE)
788 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
789 else
790 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
791
792 storageCtl->COMGETTER(Bootable)(&fBootable);
793 if (details == VMINFO_MACHINEREADABLE)
794 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
795 else
796 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
797 }
798
799 for (size_t j = 0; j < storageCtls.size(); ++ j)
800 {
801 ComPtr<IStorageController> storageCtl = storageCtls[j];
802 ComPtr<IMedium> medium;
803 Bstr storageCtlName;
804 Bstr filePath;
805 ULONG cDevices;
806 ULONG cPorts;
807
808 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
809 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
810 storageCtl->COMGETTER(PortCount)(&cPorts);
811
812 for (ULONG i = 0; i < cPorts; ++ i)
813 {
814 for (ULONG k = 0; k < cDevices; ++ k)
815 {
816 ComPtr<IMediumAttachment> mediumAttach;
817 machine->GetMediumAttachment(storageCtlName.raw(),
818 i, k,
819 mediumAttach.asOutParam());
820 BOOL fIsEjected = FALSE;
821 BOOL fTempEject = FALSE;
822 DeviceType_T devType = DeviceType_Null;
823 if (mediumAttach)
824 {
825 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
826 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
827 mediumAttach->COMGETTER(Type)(&devType);
828 }
829 rc = machine->GetMedium(storageCtlName.raw(), i, k,
830 medium.asOutParam());
831 if (SUCCEEDED(rc) && medium)
832 {
833 BOOL fPassthrough = FALSE;
834
835 if (mediumAttach)
836 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
837
838 medium->COMGETTER(Location)(filePath.asOutParam());
839 Bstr uuid;
840 medium->COMGETTER(Id)(uuid.asOutParam());
841
842 if (details == VMINFO_MACHINEREADABLE)
843 {
844 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
845 i, k, filePath.raw());
846 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
847 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
848 if (fPassthrough)
849 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
850 fPassthrough ? "on" : "off");
851 if (devType == DeviceType_DVD)
852 {
853 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
854 fTempEject ? "on" : "off");
855 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
856 fIsEjected ? "on" : "off");
857 }
858 }
859 else
860 {
861 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
862 storageCtlName.raw(), i, k, filePath.raw(),
863 Utf8Str(uuid).c_str());
864 if (fPassthrough)
865 RTPrintf(" (passthrough enabled)");
866 if (fTempEject)
867 RTPrintf(" (temp eject)");
868 if (fIsEjected)
869 RTPrintf(" (ejected)");
870 RTPrintf("\n");
871 }
872 }
873 else if (SUCCEEDED(rc))
874 {
875 if (details == VMINFO_MACHINEREADABLE)
876 {
877 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
878 if (devType == DeviceType_DVD)
879 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
880 fIsEjected ? "on" : "off");
881 }
882 else
883 {
884 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
885 if (fTempEject)
886 RTPrintf(" (temp eject)");
887 if (fIsEjected)
888 RTPrintf(" (ejected)");
889 RTPrintf("\n");
890 }
891 }
892 else
893 {
894 if (details == VMINFO_MACHINEREADABLE)
895 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
896 }
897 }
898 }
899 }
900
901 /* get the maximum amount of NICS */
902 ULONG maxNICs = getMaxNics(virtualBox, machine);
903
904 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
905 {
906 ComPtr<INetworkAdapter> nic;
907 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
908 if (SUCCEEDED(rc) && nic)
909 {
910 BOOL fEnabled;
911 nic->COMGETTER(Enabled)(&fEnabled);
912 if (!fEnabled)
913 {
914 if (details == VMINFO_MACHINEREADABLE)
915 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
916 else
917 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
918 }
919 else
920 {
921 Bstr strMACAddress;
922 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
923 Utf8Str strAttachment;
924 Utf8Str strNatSettings = "";
925 Utf8Str strNatForwardings = "";
926 NetworkAttachmentType_T attachment;
927 nic->COMGETTER(AttachmentType)(&attachment);
928 switch (attachment)
929 {
930 case NetworkAttachmentType_Null:
931 if (details == VMINFO_MACHINEREADABLE)
932 strAttachment = "null";
933 else
934 strAttachment = "none";
935 break;
936
937 case NetworkAttachmentType_NAT:
938 {
939 Bstr strNetwork;
940 ComPtr<INATEngine> engine;
941 nic->COMGETTER(NATEngine)(engine.asOutParam());
942 engine->COMGETTER(Network)(strNetwork.asOutParam());
943 com::SafeArray<BSTR> forwardings;
944 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
945 strNatForwardings = "";
946 for (size_t i = 0; i < forwardings.size(); ++i)
947 {
948 bool fSkip = false;
949 uint16_t port = 0;
950 BSTR r = forwardings[i];
951 Utf8Str utf = Utf8Str(r);
952 Utf8Str strName;
953 Utf8Str strProto;
954 Utf8Str strHostPort;
955 Utf8Str strHostIP;
956 Utf8Str strGuestPort;
957 Utf8Str strGuestIP;
958 size_t pos, ppos;
959 pos = ppos = 0;
960 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
961 do { \
962 pos = str.find(",", ppos); \
963 if (pos == Utf8Str::npos) \
964 { \
965 Log(( #res " extracting from %s is failed\n", str.c_str())); \
966 fSkip = true; \
967 } \
968 res = str.substr(ppos, pos - ppos); \
969 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
970 ppos = pos + 1; \
971 } while (0)
972 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
973 if (fSkip) continue;
974 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
975 if (fSkip) continue;
976 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
977 if (fSkip) continue;
978 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
979 if (fSkip) continue;
980 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
981 if (fSkip) continue;
982 strGuestPort = utf.substr(ppos, utf.length() - ppos);
983 #undef ITERATE_TO_NEXT_TERM
984 switch (strProto.toUInt32())
985 {
986 case NATProtocol_TCP:
987 strProto = "tcp";
988 break;
989 case NATProtocol_UDP:
990 strProto = "udp";
991 break;
992 default:
993 strProto = "unk";
994 break;
995 }
996 if (details == VMINFO_MACHINEREADABLE)
997 {
998 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
999 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
1000 strHostIP.c_str(), strHostPort.c_str(),
1001 strGuestIP.c_str(), strGuestPort.c_str());
1002 }
1003 else
1004 {
1005 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
1006 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1007 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
1008 strHostIP.c_str(), strHostPort.c_str(),
1009 strGuestIP.c_str(), strGuestPort.c_str());
1010 }
1011 }
1012 ULONG mtu = 0;
1013 ULONG sockSnd = 0;
1014 ULONG sockRcv = 0;
1015 ULONG tcpSnd = 0;
1016 ULONG tcpRcv = 0;
1017 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1018
1019 if (details == VMINFO_MACHINEREADABLE)
1020 {
1021 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1022 strAttachment = "nat";
1023 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1024 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1025 }
1026 else
1027 {
1028 strAttachment = "NAT";
1029 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1030 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1031 }
1032 break;
1033 }
1034
1035 case NetworkAttachmentType_Bridged:
1036 {
1037 Bstr strBridgeAdp;
1038 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1039 if (details == VMINFO_MACHINEREADABLE)
1040 {
1041 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1042 strAttachment = "bridged";
1043 }
1044 else
1045 strAttachment = Utf8StrFmt("Bridged Interface '%ls'", strBridgeAdp.raw());
1046 break;
1047 }
1048
1049 case NetworkAttachmentType_Internal:
1050 {
1051 Bstr strNetwork;
1052 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1053 if (details == VMINFO_MACHINEREADABLE)
1054 {
1055 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1056 strAttachment = "intnet";
1057 }
1058 else
1059 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1060 break;
1061 }
1062
1063 case NetworkAttachmentType_HostOnly:
1064 {
1065 Bstr strHostonlyAdp;
1066 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1067 if (details == VMINFO_MACHINEREADABLE)
1068 {
1069 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1070 strAttachment = "hostonly";
1071 }
1072 else
1073 strAttachment = Utf8StrFmt("Host-only Interface '%ls'", strHostonlyAdp.raw());
1074 break;
1075 }
1076 case NetworkAttachmentType_Generic:
1077 {
1078 Bstr strGenericDriver;
1079 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1080 if (details == VMINFO_MACHINEREADABLE)
1081 {
1082 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1083 strAttachment = "Generic";
1084 }
1085 else
1086 {
1087 strAttachment = Utf8StrFmt("Generic '%ls'", strGenericDriver.raw());
1088
1089 // show the generic properties
1090 com::SafeArray<BSTR> aProperties;
1091 com::SafeArray<BSTR> aValues;
1092 rc = nic->GetProperties(NULL,
1093 ComSafeArrayAsOutParam(aProperties),
1094 ComSafeArrayAsOutParam(aValues));
1095 if (SUCCEEDED(rc))
1096 {
1097 strAttachment += " { ";
1098 for (unsigned i = 0; i < aProperties.size(); ++i)
1099 strAttachment += Utf8StrFmt(!i ? "%ls='%ls'" : ", %ls='%ls'",
1100 aProperties[i], aValues[i]);
1101 strAttachment += " }";
1102 }
1103 }
1104 break;
1105 }
1106 default:
1107 strAttachment = "unknown";
1108 break;
1109 }
1110
1111 /* cable connected */
1112 BOOL fConnected;
1113 nic->COMGETTER(CableConnected)(&fConnected);
1114
1115 /* promisc policy */
1116 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1117 CHECK_ERROR2_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1118 const char *pszPromiscuousGuestPolicy;
1119 switch (enmPromiscModePolicy)
1120 {
1121 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1122 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1123 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1124 default: AssertFailedReturn(E_INVALIDARG);
1125 }
1126
1127 /* trace stuff */
1128 BOOL fTraceEnabled;
1129 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1130 Bstr traceFile;
1131 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1132
1133 /* NIC type */
1134 NetworkAdapterType_T NICType;
1135 nic->COMGETTER(AdapterType)(&NICType);
1136 const char *pszNICType;
1137 switch (NICType)
1138 {
1139 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1140 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1141#ifdef VBOX_WITH_E1000
1142 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1143 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1144 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1145#endif
1146#ifdef VBOX_WITH_VIRTIO
1147 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1148#endif
1149 default: AssertFailed(); pszNICType = "unknown"; break;
1150 }
1151
1152 /* reported line speed */
1153 ULONG ulLineSpeed;
1154 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1155
1156 /* boot priority of the adapter */
1157 ULONG ulBootPriority;
1158 nic->COMGETTER(BootPriority)(&ulBootPriority);
1159
1160 /* bandwidth group */
1161 ComObjPtr<IBandwidthGroup> pBwGroup;
1162 Bstr strBwGroup;
1163 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1164 if (!pBwGroup.isNull())
1165 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1166
1167 if (details == VMINFO_MACHINEREADABLE)
1168 {
1169 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1170 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1171 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1172 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1173 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1174 }
1175 else
1176 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",
1177 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
1178 fConnected ? "on" : "off",
1179 fTraceEnabled ? "on" : "off",
1180 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1181 pszNICType,
1182 ulLineSpeed / 1000,
1183 (int)ulBootPriority,
1184 pszPromiscuousGuestPolicy,
1185 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1186 if (strNatSettings.length())
1187 RTPrintf(strNatSettings.c_str());
1188 if (strNatForwardings.length())
1189 RTPrintf(strNatForwardings.c_str());
1190 }
1191 }
1192 }
1193
1194 /* Pointing device information */
1195 PointingHIDType_T aPointingHID;
1196 const char *pszHID = "Unknown";
1197 const char *pszMrHID = "unknown";
1198 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1199 switch (aPointingHID)
1200 {
1201 case PointingHIDType_None:
1202 pszHID = "None";
1203 pszMrHID = "none";
1204 break;
1205 case PointingHIDType_PS2Mouse:
1206 pszHID = "PS/2 Mouse";
1207 pszMrHID = "ps2mouse";
1208 break;
1209 case PointingHIDType_USBMouse:
1210 pszHID = "USB Mouse";
1211 pszMrHID = "usbmouse";
1212 break;
1213 case PointingHIDType_USBTablet:
1214 pszHID = "USB Tablet";
1215 pszMrHID = "usbtablet";
1216 break;
1217 case PointingHIDType_ComboMouse:
1218 pszHID = "USB Tablet and PS/2 Mouse";
1219 pszMrHID = "combomouse";
1220 break;
1221 case PointingHIDType_USBMultiTouch:
1222 pszHID = "USB Multi-Touch";
1223 pszMrHID = "usbmultitouch";
1224 break;
1225 default:
1226 break;
1227 }
1228 if (details == VMINFO_MACHINEREADABLE)
1229 RTPrintf("hidpointing=\"%s\"\n", pszMrHID);
1230 else
1231 RTPrintf("Pointing Device: %s\n", pszHID);
1232
1233 /* Keyboard device information */
1234 KeyboardHIDType_T aKeyboardHID;
1235 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1236 pszHID = "Unknown";
1237 pszMrHID = "unknown";
1238 switch (aKeyboardHID)
1239 {
1240 case KeyboardHIDType_None:
1241 pszHID = "None";
1242 pszMrHID = "none";
1243 break;
1244 case KeyboardHIDType_PS2Keyboard:
1245 pszHID = "PS/2 Keyboard";
1246 pszMrHID = "ps2kbd";
1247 break;
1248 case KeyboardHIDType_USBKeyboard:
1249 pszHID = "USB Keyboard";
1250 pszMrHID = "usbkbd";
1251 break;
1252 case KeyboardHIDType_ComboKeyboard:
1253 pszHID = "USB and PS/2 Keyboard";
1254 pszMrHID = "combokbd";
1255 break;
1256 default:
1257 break;
1258 }
1259 if (details == VMINFO_MACHINEREADABLE)
1260 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHID);
1261 else
1262 RTPrintf("Keyboard Device: %s\n", pszHID);
1263
1264 ComPtr<ISystemProperties> sysProps;
1265 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1266
1267 /* get the maximum amount of UARTs */
1268 ULONG maxUARTs = 0;
1269 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1270 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1271 {
1272 ComPtr<ISerialPort> uart;
1273 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1274 if (SUCCEEDED(rc) && uart)
1275 {
1276 /* show the config of this UART */
1277 BOOL fEnabled;
1278 uart->COMGETTER(Enabled)(&fEnabled);
1279 if (!fEnabled)
1280 {
1281 if (details == VMINFO_MACHINEREADABLE)
1282 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1283 else
1284 RTPrintf("UART %d: disabled\n", currentUART + 1);
1285 }
1286 else
1287 {
1288 ULONG ulIRQ, ulIOBase;
1289 PortMode_T HostMode;
1290 Bstr path;
1291 BOOL fServer;
1292 uart->COMGETTER(IRQ)(&ulIRQ);
1293 uart->COMGETTER(IOBase)(&ulIOBase);
1294 uart->COMGETTER(Path)(path.asOutParam());
1295 uart->COMGETTER(Server)(&fServer);
1296 uart->COMGETTER(HostMode)(&HostMode);
1297
1298 if (details == VMINFO_MACHINEREADABLE)
1299 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1300 ulIOBase, ulIRQ);
1301 else
1302 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1303 currentUART + 1, ulIOBase, ulIRQ);
1304 switch (HostMode)
1305 {
1306 default:
1307 case PortMode_Disconnected:
1308 if (details == VMINFO_MACHINEREADABLE)
1309 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1310 else
1311 RTPrintf(", disconnected\n");
1312 break;
1313 case PortMode_RawFile:
1314 if (details == VMINFO_MACHINEREADABLE)
1315 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1316 path.raw());
1317 else
1318 RTPrintf(", attached to raw file '%ls'\n",
1319 path.raw());
1320 break;
1321 case PortMode_HostPipe:
1322 if (details == VMINFO_MACHINEREADABLE)
1323 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1324 fServer ? "server" : "client", path.raw());
1325 else
1326 RTPrintf(", attached to pipe (%s) '%ls'\n",
1327 fServer ? "server" : "client", path.raw());
1328 break;
1329 case PortMode_HostDevice:
1330 if (details == VMINFO_MACHINEREADABLE)
1331 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1332 path.raw());
1333 else
1334 RTPrintf(", attached to device '%ls'\n", path.raw());
1335 break;
1336 }
1337 }
1338 }
1339 }
1340
1341 /* get the maximum amount of LPTs */
1342 ULONG maxLPTs = 0;
1343 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1344 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1345 {
1346 ComPtr<IParallelPort> lpt;
1347 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1348 if (SUCCEEDED(rc) && lpt)
1349 {
1350 /* show the config of this LPT */
1351 BOOL fEnabled;
1352 lpt->COMGETTER(Enabled)(&fEnabled);
1353 if (!fEnabled)
1354 {
1355 if (details == VMINFO_MACHINEREADABLE)
1356 RTPrintf("lpt%d=\"off\"\n", currentLPT + 1);
1357 else
1358 RTPrintf("LPT %d: disabled\n", currentLPT + 1);
1359 }
1360 else
1361 {
1362 ULONG ulIRQ, ulIOBase;
1363 Bstr path;
1364 lpt->COMGETTER(IRQ)(&ulIRQ);
1365 lpt->COMGETTER(IOBase)(&ulIOBase);
1366 lpt->COMGETTER(Path)(path.asOutParam());
1367
1368 if (details == VMINFO_MACHINEREADABLE)
1369 RTPrintf("lpt%d=\"%#06x,%d\"\n", currentLPT + 1,
1370 ulIOBase, ulIRQ);
1371 else
1372 RTPrintf("LPT %d: I/O base: %#06x, IRQ: %d",
1373 currentLPT + 1, ulIOBase, ulIRQ);
1374 if (details == VMINFO_MACHINEREADABLE)
1375 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1,
1376 path.raw());
1377 else
1378 RTPrintf(", attached to device '%ls'\n", path.raw());
1379 }
1380 }
1381 }
1382
1383 ComPtr<IAudioAdapter> AudioAdapter;
1384 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1385 if (SUCCEEDED(rc))
1386 {
1387 const char *pszDrv = "Unknown";
1388 const char *pszCtrl = "Unknown";
1389 BOOL fEnabled;
1390 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1391 if (SUCCEEDED(rc) && fEnabled)
1392 {
1393 AudioDriverType_T enmDrvType;
1394 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1395 switch (enmDrvType)
1396 {
1397 case AudioDriverType_Null:
1398 if (details == VMINFO_MACHINEREADABLE)
1399 pszDrv = "null";
1400 else
1401 pszDrv = "Null";
1402 break;
1403 case AudioDriverType_WinMM:
1404 if (details == VMINFO_MACHINEREADABLE)
1405 pszDrv = "winmm";
1406 else
1407 pszDrv = "WINMM";
1408 break;
1409 case AudioDriverType_DirectSound:
1410 if (details == VMINFO_MACHINEREADABLE)
1411 pszDrv = "dsound";
1412 else
1413 pszDrv = "DSOUND";
1414 break;
1415 case AudioDriverType_OSS:
1416 if (details == VMINFO_MACHINEREADABLE)
1417 pszDrv = "oss";
1418 else
1419 pszDrv = "OSS";
1420 break;
1421 case AudioDriverType_ALSA:
1422 if (details == VMINFO_MACHINEREADABLE)
1423 pszDrv = "alsa";
1424 else
1425 pszDrv = "ALSA";
1426 break;
1427 case AudioDriverType_Pulse:
1428 if (details == VMINFO_MACHINEREADABLE)
1429 pszDrv = "pulse";
1430 else
1431 pszDrv = "PulseAudio";
1432 break;
1433 case AudioDriverType_CoreAudio:
1434 if (details == VMINFO_MACHINEREADABLE)
1435 pszDrv = "coreaudio";
1436 else
1437 pszDrv = "CoreAudio";
1438 break;
1439 case AudioDriverType_SolAudio:
1440 if (details == VMINFO_MACHINEREADABLE)
1441 pszDrv = "solaudio";
1442 else
1443 pszDrv = "SolAudio";
1444 break;
1445 default:
1446 if (details == VMINFO_MACHINEREADABLE)
1447 pszDrv = "unknown";
1448 break;
1449 }
1450 AudioControllerType_T enmCtrlType;
1451 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1452 switch (enmCtrlType)
1453 {
1454 case AudioControllerType_AC97:
1455 if (details == VMINFO_MACHINEREADABLE)
1456 pszCtrl = "ac97";
1457 else
1458 pszCtrl = "AC97";
1459 break;
1460 case AudioControllerType_SB16:
1461 if (details == VMINFO_MACHINEREADABLE)
1462 pszCtrl = "sb16";
1463 else
1464 pszCtrl = "SB16";
1465 break;
1466 case AudioControllerType_HDA:
1467 if (details == VMINFO_MACHINEREADABLE)
1468 pszCtrl = "hda";
1469 else
1470 pszCtrl = "HDA";
1471 break;
1472 }
1473 }
1474 else
1475 fEnabled = FALSE;
1476 if (details == VMINFO_MACHINEREADABLE)
1477 {
1478 if (fEnabled)
1479 RTPrintf("audio=\"%s\"\n", pszDrv);
1480 else
1481 RTPrintf("audio=\"none\"\n");
1482 }
1483 else
1484 {
1485 RTPrintf("Audio: %s",
1486 fEnabled ? "enabled" : "disabled");
1487 if (fEnabled)
1488 RTPrintf(" (Driver: %s, Controller: %s)",
1489 pszDrv, pszCtrl);
1490 RTPrintf("\n");
1491 }
1492 }
1493
1494 /* Shared clipboard */
1495 {
1496 const char *psz = "Unknown";
1497 ClipboardMode_T enmMode;
1498 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1499 switch (enmMode)
1500 {
1501 case ClipboardMode_Disabled:
1502 if (details == VMINFO_MACHINEREADABLE)
1503 psz = "disabled";
1504 else
1505 psz = "disabled";
1506 break;
1507 case ClipboardMode_HostToGuest:
1508 if (details == VMINFO_MACHINEREADABLE)
1509 psz = "hosttoguest";
1510 else
1511 psz = "HostToGuest";
1512 break;
1513 case ClipboardMode_GuestToHost:
1514 if (details == VMINFO_MACHINEREADABLE)
1515 psz = "guesttohost";
1516 else
1517 psz = "GuestToHost";
1518 break;
1519 case ClipboardMode_Bidirectional:
1520 if (details == VMINFO_MACHINEREADABLE)
1521 psz = "bidirectional";
1522 else
1523 psz = "Bidirectional";
1524 break;
1525 default:
1526 if (details == VMINFO_MACHINEREADABLE)
1527 psz = "unknown";
1528 break;
1529 }
1530 if (details == VMINFO_MACHINEREADABLE)
1531 RTPrintf("clipboard=\"%s\"\n", psz);
1532 else
1533 RTPrintf("Clipboard Mode: %s\n", psz);
1534 }
1535
1536 /* Drag'n'drop */
1537 {
1538 const char *psz = "Unknown";
1539 DragAndDropMode_T enmMode;
1540 rc = machine->COMGETTER(DragAndDropMode)(&enmMode);
1541 switch (enmMode)
1542 {
1543 case DragAndDropMode_Disabled:
1544 if (details == VMINFO_MACHINEREADABLE)
1545 psz = "disabled";
1546 else
1547 psz = "disabled";
1548 break;
1549 case DragAndDropMode_HostToGuest:
1550 if (details == VMINFO_MACHINEREADABLE)
1551 psz = "hosttoguest";
1552 else
1553 psz = "HostToGuest";
1554 break;
1555 case DragAndDropMode_GuestToHost:
1556 if (details == VMINFO_MACHINEREADABLE)
1557 psz = "guesttohost";
1558 else
1559 psz = "GuestToHost";
1560 break;
1561 case DragAndDropMode_Bidirectional:
1562 if (details == VMINFO_MACHINEREADABLE)
1563 psz = "bidirectional";
1564 else
1565 psz = "Bidirectional";
1566 break;
1567 default:
1568 if (details == VMINFO_MACHINEREADABLE)
1569 psz = "unknown";
1570 break;
1571 }
1572 if (details == VMINFO_MACHINEREADABLE)
1573 RTPrintf("draganddrop=\"%s\"\n", psz);
1574 else
1575 RTPrintf("Drag'n'drop Mode: %s\n", psz);
1576 }
1577
1578 {
1579 SessionState_T sessState;
1580 rc = machine->COMGETTER(SessionState)(&sessState);
1581 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1582 {
1583 Bstr sessType;
1584 rc = machine->COMGETTER(SessionType)(sessType.asOutParam());
1585 if (SUCCEEDED(rc) && !sessType.isEmpty())
1586 {
1587 if (details == VMINFO_MACHINEREADABLE)
1588 RTPrintf("SessionType=\"%ls\"\n", sessType.raw());
1589 else
1590 RTPrintf("Session type: %ls\n", sessType.raw());
1591 }
1592 }
1593 }
1594
1595 if (console)
1596 {
1597 do
1598 {
1599 ComPtr<IDisplay> display;
1600 rc = console->COMGETTER(Display)(display.asOutParam());
1601 if (rc == E_ACCESSDENIED || display.isNull())
1602 break; /* VM not powered up */
1603 if (FAILED(rc))
1604 {
1605 com::GlueHandleComError(console, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1606 return rc;
1607 }
1608 ULONG xRes, yRes, bpp;
1609 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp);
1610 if (rc == E_ACCESSDENIED)
1611 break; /* VM not powered up */
1612 if (FAILED(rc))
1613 {
1614 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1615 GluePrintErrorInfo(info);
1616 return rc;
1617 }
1618 if (details == VMINFO_MACHINEREADABLE)
1619 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1620 else
1621 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1622 }
1623 while (0);
1624 }
1625
1626 /*
1627 * Remote Desktop
1628 */
1629 ComPtr<IVRDEServer> vrdeServer;
1630 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1631 if (SUCCEEDED(rc) && vrdeServer)
1632 {
1633 BOOL fEnabled = false;
1634 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1635 if (fEnabled)
1636 {
1637 LONG currentPort = -1;
1638 Bstr ports;
1639 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1640 Bstr address;
1641 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1642 BOOL fMultiCon;
1643 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1644 BOOL fReuseCon;
1645 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1646 Bstr videoChannel;
1647 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1648 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1649 || (videoChannel == "1");
1650 Bstr videoChannelQuality;
1651 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1652 AuthType_T authType;
1653 const char *strAuthType;
1654 vrdeServer->COMGETTER(AuthType)(&authType);
1655 switch (authType)
1656 {
1657 case AuthType_Null:
1658 strAuthType = "null";
1659 break;
1660 case AuthType_External:
1661 strAuthType = "external";
1662 break;
1663 case AuthType_Guest:
1664 strAuthType = "guest";
1665 break;
1666 default:
1667 strAuthType = "unknown";
1668 break;
1669 }
1670 if (console)
1671 {
1672 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1673 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1674 if (!vrdeServerInfo.isNull())
1675 {
1676 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1677 if (rc == E_ACCESSDENIED)
1678 {
1679 currentPort = -1; /* VM not powered up */
1680 }
1681 if (FAILED(rc))
1682 {
1683 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1684 GluePrintErrorInfo(info);
1685 return rc;
1686 }
1687 }
1688 }
1689 if (details == VMINFO_MACHINEREADABLE)
1690 {
1691 RTPrintf("vrde=\"on\"\n");
1692 RTPrintf("vrdeport=%d\n", currentPort);
1693 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1694 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1695 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1696 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1697 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1698 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1699 if (fVideoChannel)
1700 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1701 }
1702 else
1703 {
1704 if (address.isEmpty())
1705 address = "0.0.0.0";
1706 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);
1707 if (console && currentPort != -1 && currentPort != 0)
1708 RTPrintf("VRDE port: %d\n", currentPort);
1709 if (fVideoChannel)
1710 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1711 else
1712 RTPrintf("Video redirection: disabled\n");
1713 }
1714 com::SafeArray<BSTR> aProperties;
1715 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1716 {
1717 unsigned i;
1718 for (i = 0; i < aProperties.size(); ++i)
1719 {
1720 Bstr value;
1721 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1722 if (details == VMINFO_MACHINEREADABLE)
1723 {
1724 if (value.isEmpty())
1725 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1726 else
1727 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1728 }
1729 else
1730 {
1731 if (value.isEmpty())
1732 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1733 else
1734 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1735 }
1736 }
1737 }
1738 }
1739 else
1740 {
1741 if (details == VMINFO_MACHINEREADABLE)
1742 RTPrintf("vrde=\"off\"\n");
1743 else
1744 RTPrintf("VRDE: disabled\n");
1745 }
1746 }
1747
1748 /*
1749 * USB.
1750 */
1751 SafeIfaceArray<IUSBController> USBCtlColl;
1752 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
1753 if (SUCCEEDED(rc))
1754 {
1755 bool fOhciEnabled = false;
1756 bool fEhciEnabled = false;
1757
1758 for (unsigned i = 0; i < USBCtlColl.size(); i++)
1759 {
1760 USBControllerType_T enmType;
1761
1762 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
1763 if (SUCCEEDED(rc))
1764 {
1765 switch (enmType)
1766 {
1767 case USBControllerType_OHCI:
1768 fOhciEnabled = true;
1769 break;
1770 case USBControllerType_EHCI:
1771 fEhciEnabled = true;
1772 break;
1773 default:
1774 break;
1775 }
1776 }
1777 }
1778
1779 if (details == VMINFO_MACHINEREADABLE)
1780 RTPrintf("usb=\"%s\"\n", fOhciEnabled ? "on" : "off");
1781 else
1782 RTPrintf("USB: %s\n", fOhciEnabled ? "enabled" : "disabled");
1783
1784 if (details == VMINFO_MACHINEREADABLE)
1785 RTPrintf("ehci=\"%s\"\n", fEhciEnabled ? "on" : "off");
1786 else
1787 RTPrintf("EHCI: %s\n", fEhciEnabled ? "enabled" : "disabled");
1788 }
1789
1790 ComPtr<IUSBDeviceFilters> USBFlts;
1791 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
1792 if (SUCCEEDED(rc))
1793 {
1794 SafeIfaceArray <IUSBDeviceFilter> Coll;
1795 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1796 if (SUCCEEDED(rc))
1797 {
1798 if (details != VMINFO_MACHINEREADABLE)
1799 RTPrintf("\nUSB Device Filters:\n\n");
1800
1801 if (Coll.size() == 0)
1802 {
1803 if (details != VMINFO_MACHINEREADABLE)
1804 RTPrintf("<none>\n\n");
1805 }
1806 else
1807 {
1808 for (size_t index = 0; index < Coll.size(); ++index)
1809 {
1810 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1811
1812 /* Query info. */
1813
1814 if (details != VMINFO_MACHINEREADABLE)
1815 RTPrintf("Index: %zu\n", index);
1816
1817 BOOL bActive = FALSE;
1818 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1819 if (details == VMINFO_MACHINEREADABLE)
1820 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1821 else
1822 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1823
1824 Bstr bstr;
1825 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1826 if (details == VMINFO_MACHINEREADABLE)
1827 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1828 else
1829 RTPrintf("Name: %ls\n", bstr.raw());
1830 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1831 if (details == VMINFO_MACHINEREADABLE)
1832 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1833 else
1834 RTPrintf("VendorId: %ls\n", bstr.raw());
1835 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1836 if (details == VMINFO_MACHINEREADABLE)
1837 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
1838 else
1839 RTPrintf("ProductId: %ls\n", bstr.raw());
1840 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1841 if (details == VMINFO_MACHINEREADABLE)
1842 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
1843 else
1844 RTPrintf("Revision: %ls\n", bstr.raw());
1845 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1846 if (details == VMINFO_MACHINEREADABLE)
1847 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1848 else
1849 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1850 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1851 if (details == VMINFO_MACHINEREADABLE)
1852 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1853 else
1854 RTPrintf("Product: %ls\n", bstr.raw());
1855 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1856 if (details == VMINFO_MACHINEREADABLE)
1857 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
1858 else
1859 RTPrintf("Remote: %ls\n", bstr.raw());
1860 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1861 if (details == VMINFO_MACHINEREADABLE)
1862 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1863 else
1864 RTPrintf("Serial Number: %ls\n", bstr.raw());
1865 if (details != VMINFO_MACHINEREADABLE)
1866 {
1867 ULONG fMaskedIfs;
1868 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1869 if (fMaskedIfs)
1870 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1871 RTPrintf("\n");
1872 }
1873 }
1874 }
1875 }
1876
1877 if (console)
1878 {
1879 /* scope */
1880 {
1881 if (details != VMINFO_MACHINEREADABLE)
1882 RTPrintf("Available remote USB devices:\n\n");
1883
1884 SafeIfaceArray <IHostUSBDevice> coll;
1885 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1886
1887 if (coll.size() == 0)
1888 {
1889 if (details != VMINFO_MACHINEREADABLE)
1890 RTPrintf("<none>\n\n");
1891 }
1892 else
1893 {
1894 for (size_t index = 0; index < coll.size(); ++index)
1895 {
1896 ComPtr <IHostUSBDevice> dev = coll[index];
1897
1898 /* Query info. */
1899 Bstr id;
1900 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1901 USHORT usVendorId;
1902 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1903 USHORT usProductId;
1904 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1905 USHORT bcdRevision;
1906 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1907
1908 if (details == VMINFO_MACHINEREADABLE)
1909 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
1910 "USBRemoteVendorId%zu=\"%#06x\"\n"
1911 "USBRemoteProductId%zu=\"%#06x\"\n"
1912 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1913 index + 1, Utf8Str(id).c_str(),
1914 index + 1, usVendorId,
1915 index + 1, usProductId,
1916 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1917 else
1918 RTPrintf("UUID: %s\n"
1919 "VendorId: %#06x (%04X)\n"
1920 "ProductId: %#06x (%04X)\n"
1921 "Revision: %u.%u (%02u%02u)\n",
1922 Utf8Str(id).c_str(),
1923 usVendorId, usVendorId, usProductId, usProductId,
1924 bcdRevision >> 8, bcdRevision & 0xff,
1925 bcdRevision >> 8, bcdRevision & 0xff);
1926
1927 /* optional stuff. */
1928 Bstr bstr;
1929 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1930 if (!bstr.isEmpty())
1931 {
1932 if (details == VMINFO_MACHINEREADABLE)
1933 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1934 else
1935 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1936 }
1937 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1938 if (!bstr.isEmpty())
1939 {
1940 if (details == VMINFO_MACHINEREADABLE)
1941 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1942 else
1943 RTPrintf("Product: %ls\n", bstr.raw());
1944 }
1945 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1946 if (!bstr.isEmpty())
1947 {
1948 if (details == VMINFO_MACHINEREADABLE)
1949 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1950 else
1951 RTPrintf("SerialNumber: %ls\n", bstr.raw());
1952 }
1953 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1954 if (!bstr.isEmpty())
1955 {
1956 if (details == VMINFO_MACHINEREADABLE)
1957 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
1958 else
1959 RTPrintf("Address: %ls\n", bstr.raw());
1960 }
1961
1962 if (details != VMINFO_MACHINEREADABLE)
1963 RTPrintf("\n");
1964 }
1965 }
1966 }
1967
1968 /* scope */
1969 {
1970 if (details != VMINFO_MACHINEREADABLE)
1971 RTPrintf("Currently Attached USB Devices:\n\n");
1972
1973 SafeIfaceArray <IUSBDevice> coll;
1974 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1975
1976 if (coll.size() == 0)
1977 {
1978 if (details != VMINFO_MACHINEREADABLE)
1979 RTPrintf("<none>\n\n");
1980 }
1981 else
1982 {
1983 for (size_t index = 0; index < coll.size(); ++index)
1984 {
1985 ComPtr <IUSBDevice> dev = coll[index];
1986
1987 /* Query info. */
1988 Bstr id;
1989 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1990 USHORT usVendorId;
1991 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1992 USHORT usProductId;
1993 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1994 USHORT bcdRevision;
1995 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1996
1997 if (details == VMINFO_MACHINEREADABLE)
1998 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
1999 "USBAttachedVendorId%zu=\"%#06x\"\n"
2000 "USBAttachedProductId%zu=\"%#06x\"\n"
2001 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
2002 index + 1, Utf8Str(id).c_str(),
2003 index + 1, usVendorId,
2004 index + 1, usProductId,
2005 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2006 else
2007 RTPrintf("UUID: %s\n"
2008 "VendorId: %#06x (%04X)\n"
2009 "ProductId: %#06x (%04X)\n"
2010 "Revision: %u.%u (%02u%02u)\n",
2011 Utf8Str(id).c_str(),
2012 usVendorId, usVendorId, usProductId, usProductId,
2013 bcdRevision >> 8, bcdRevision & 0xff,
2014 bcdRevision >> 8, bcdRevision & 0xff);
2015
2016 /* optional stuff. */
2017 Bstr bstr;
2018 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2019 if (!bstr.isEmpty())
2020 {
2021 if (details == VMINFO_MACHINEREADABLE)
2022 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2023 else
2024 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2025 }
2026 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2027 if (!bstr.isEmpty())
2028 {
2029 if (details == VMINFO_MACHINEREADABLE)
2030 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2031 else
2032 RTPrintf("Product: %ls\n", bstr.raw());
2033 }
2034 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2035 if (!bstr.isEmpty())
2036 {
2037 if (details == VMINFO_MACHINEREADABLE)
2038 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2039 else
2040 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2041 }
2042 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2043 if (!bstr.isEmpty())
2044 {
2045 if (details == VMINFO_MACHINEREADABLE)
2046 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2047 else
2048 RTPrintf("Address: %ls\n", bstr.raw());
2049 }
2050
2051 if (details != VMINFO_MACHINEREADABLE)
2052 RTPrintf("\n");
2053 }
2054 }
2055 }
2056 }
2057 } /* USB */
2058
2059#ifdef VBOX_WITH_PCI_PASSTHROUGH
2060 /* Host PCI passthrough devices */
2061 {
2062 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2063 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2064 if (SUCCEEDED(rc))
2065 {
2066 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2067 {
2068 RTPrintf("\nAttached physical PCI devices:\n\n");
2069 }
2070
2071 for (size_t index = 0; index < assignments.size(); ++index)
2072 {
2073 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2074 char szHostPCIAddress[32], szGuestPCIAddress[32];
2075 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2076 Bstr DevName;
2077
2078 Assignment->COMGETTER(Name)(DevName.asOutParam());
2079 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2080 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2081 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2082 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2083
2084 if (details == VMINFO_MACHINEREADABLE)
2085 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2086 else
2087 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2088 }
2089
2090 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2091 {
2092 RTPrintf("\n");
2093 }
2094 }
2095 }
2096 /* Host PCI passthrough devices */
2097#endif
2098
2099 /*
2100 * Bandwidth groups
2101 */
2102 if (details != VMINFO_MACHINEREADABLE)
2103 RTPrintf("Bandwidth groups: ");
2104 {
2105 ComPtr<IBandwidthControl> bwCtrl;
2106 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2107
2108 rc = showBandwidthGroups(bwCtrl, details);
2109 }
2110
2111
2112 /*
2113 * Shared folders
2114 */
2115 if (details != VMINFO_MACHINEREADABLE)
2116 RTPrintf("Shared folders: ");
2117 uint32_t numSharedFolders = 0;
2118#if 0 // not yet implemented
2119 /* globally shared folders first */
2120 {
2121 SafeIfaceArray <ISharedFolder> sfColl;
2122 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2123 for (size_t i = 0; i < sfColl.size(); ++i)
2124 {
2125 ComPtr<ISharedFolder> sf = sfColl[i];
2126 Bstr name, hostPath;
2127 sf->COMGETTER(Name)(name.asOutParam());
2128 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2129 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2130 ++numSharedFolders;
2131 }
2132 }
2133#endif
2134 /* now VM mappings */
2135 {
2136 com::SafeIfaceArray <ISharedFolder> folders;
2137
2138 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2139
2140 for (size_t i = 0; i < folders.size(); ++i)
2141 {
2142 ComPtr <ISharedFolder> sf = folders[i];
2143
2144 Bstr name, hostPath;
2145 BOOL writable;
2146 sf->COMGETTER(Name)(name.asOutParam());
2147 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2148 sf->COMGETTER(Writable)(&writable);
2149 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2150 RTPrintf("\n\n");
2151 if (details == VMINFO_MACHINEREADABLE)
2152 {
2153 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2154 name.raw());
2155 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2156 hostPath.raw());
2157 }
2158 else
2159 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2160 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2161 ++numSharedFolders;
2162 }
2163 }
2164 /* transient mappings */
2165 if (console)
2166 {
2167 com::SafeIfaceArray <ISharedFolder> folders;
2168
2169 CHECK_ERROR_RET(console, 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 sf->COMGETTER(Name)(name.asOutParam());
2177 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2178 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2179 RTPrintf("\n\n");
2180 if (details == VMINFO_MACHINEREADABLE)
2181 {
2182 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2183 name.raw());
2184 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2185 hostPath.raw());
2186 }
2187 else
2188 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2189 ++numSharedFolders;
2190 }
2191 }
2192 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2193 RTPrintf("<none>\n");
2194 if (details != VMINFO_MACHINEREADABLE)
2195 RTPrintf("\n");
2196
2197 if (console)
2198 {
2199 /*
2200 * Live VRDE info.
2201 */
2202 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2203 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2204 BOOL Active = FALSE;
2205 ULONG NumberOfClients = 0;
2206 LONG64 BeginTime = 0;
2207 LONG64 EndTime = 0;
2208 LONG64 BytesSent = 0;
2209 LONG64 BytesSentTotal = 0;
2210 LONG64 BytesReceived = 0;
2211 LONG64 BytesReceivedTotal = 0;
2212 Bstr User;
2213 Bstr Domain;
2214 Bstr ClientName;
2215 Bstr ClientIP;
2216 ULONG ClientVersion = 0;
2217 ULONG EncryptionStyle = 0;
2218
2219 if (!vrdeServerInfo.isNull())
2220 {
2221 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2222 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2223 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2224 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2225 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2226 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2227 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2228 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2229 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2230 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2231 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2232 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2233 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2234 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2235 }
2236
2237 if (details == VMINFO_MACHINEREADABLE)
2238 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2239 else
2240 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2241
2242 if (details == VMINFO_MACHINEREADABLE)
2243 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2244 else
2245 RTPrintf("Clients so far: %d\n", NumberOfClients);
2246
2247 if (NumberOfClients > 0)
2248 {
2249 char timestr[128];
2250
2251 if (Active)
2252 {
2253 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2254 if (details == VMINFO_MACHINEREADABLE)
2255 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2256 else
2257 RTPrintf("Start time: %s\n", timestr);
2258 }
2259 else
2260 {
2261 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2262 if (details == VMINFO_MACHINEREADABLE)
2263 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2264 else
2265 RTPrintf("Last started: %s\n", timestr);
2266 makeTimeStr(timestr, sizeof(timestr), EndTime);
2267 if (details == VMINFO_MACHINEREADABLE)
2268 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2269 else
2270 RTPrintf("Last ended: %s\n", timestr);
2271 }
2272
2273 int64_t ThroughputSend = 0;
2274 int64_t ThroughputReceive = 0;
2275 if (EndTime != BeginTime)
2276 {
2277 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2278 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2279 }
2280
2281 if (details == VMINFO_MACHINEREADABLE)
2282 {
2283 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2284 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2285 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2286
2287 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2288 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2289 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2290 }
2291 else
2292 {
2293 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2294 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2295 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2296
2297 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2298 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2299 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2300 }
2301
2302 if (Active)
2303 {
2304 if (details == VMINFO_MACHINEREADABLE)
2305 {
2306 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2307 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2308 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2309 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2310 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2311 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2312 }
2313 else
2314 {
2315 RTPrintf("User name: %ls\n", User.raw());
2316 RTPrintf("Domain: %ls\n", Domain.raw());
2317 RTPrintf("Client name: %ls\n", ClientName.raw());
2318 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2319 RTPrintf("Client version: %d\n", ClientVersion);
2320 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2321 }
2322 }
2323 }
2324
2325 if (details != VMINFO_MACHINEREADABLE)
2326 RTPrintf("\n");
2327 }
2328
2329 {
2330 /* Video capture */
2331 BOOL bActive = FALSE;
2332 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2333 com::SafeArray<BOOL> screens;
2334 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2335 ULONG Width;
2336 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2337 ULONG Height;
2338 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2339 ULONG Rate;
2340 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2341 ULONG Fps;
2342 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2343 Bstr File;
2344 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2345 if (details == VMINFO_MACHINEREADABLE)
2346 {
2347 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2348 RTPrintf("vcpscreens=");
2349 bool fComma = false;
2350 for (unsigned i = 0; i < screens.size(); i++)
2351 if (screens[i])
2352 {
2353 RTPrintf("%s%u", fComma ? "," : "", i);
2354 fComma = true;
2355 }
2356 RTPrintf("\n");
2357 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2358 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2359 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2360 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2361 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2362 }
2363 else
2364 {
2365 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2366 RTPrintf("Capture screens: ");
2367 bool fComma = false;
2368 for (unsigned i = 0; i < screens.size(); i++)
2369 if (screens[i])
2370 {
2371 RTPrintf("%s%u", fComma ? "," : "", i);
2372 fComma = true;
2373 }
2374 RTPrintf("\n");
2375 RTPrintf("Capture file: %ls\n", File.raw());
2376 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2377 RTPrintf("Capture rate: %u kbps\n", Rate);
2378 RTPrintf("Capture FPS: %u\n", Fps);
2379 RTPrintf("\n");
2380 }
2381 }
2382
2383 if ( details == VMINFO_STANDARD
2384 || details == VMINFO_FULL
2385 || details == VMINFO_MACHINEREADABLE)
2386 {
2387 Bstr description;
2388 machine->COMGETTER(Description)(description.asOutParam());
2389 if (!description.isEmpty())
2390 {
2391 if (details == VMINFO_MACHINEREADABLE)
2392 RTPrintf("description=\"%ls\"\n", description.raw());
2393 else
2394 RTPrintf("Description:\n%ls\n", description.raw());
2395 }
2396 }
2397
2398 if (details != VMINFO_MACHINEREADABLE)
2399 RTPrintf("Guest:\n\n");
2400
2401 ULONG guestVal;
2402 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2403 if (SUCCEEDED(rc))
2404 {
2405 if (details == VMINFO_MACHINEREADABLE)
2406 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2407 else
2408 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2409 }
2410
2411 if (console)
2412 {
2413 ComPtr<IGuest> guest;
2414 rc = console->COMGETTER(Guest)(guest.asOutParam());
2415 if (SUCCEEDED(rc) && !guest.isNull())
2416 {
2417 Bstr guestString;
2418 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2419 if ( SUCCEEDED(rc)
2420 && !guestString.isEmpty())
2421 {
2422 if (details == VMINFO_MACHINEREADABLE)
2423 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2424 else
2425 RTPrintf("OS type: %ls\n", guestString.raw());
2426 }
2427
2428 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2429 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2430 if (SUCCEEDED(rc))
2431 {
2432 if (details == VMINFO_MACHINEREADABLE)
2433 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2434 else
2435 RTPrintf("Additions run level: %u\n", guestRunLevel);
2436 }
2437
2438 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2439 if ( SUCCEEDED(rc)
2440 && !guestString.isEmpty())
2441 {
2442 ULONG uRevision;
2443 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2444 if (FAILED(rc))
2445 uRevision = 0;
2446
2447 if (details == VMINFO_MACHINEREADABLE)
2448 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2449 else
2450 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2451 }
2452
2453 if (details != VMINFO_MACHINEREADABLE)
2454 RTPrintf("\nGuest Facilities:\n\n");
2455
2456 /* Print information about known Guest Additions facilities: */
2457 SafeIfaceArray <IAdditionsFacility> collFac;
2458 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2459 LONG64 lLastUpdatedMS;
2460 char szLastUpdated[32];
2461 AdditionsFacilityStatus_T curStatus;
2462 for (size_t index = 0; index < collFac.size(); ++index)
2463 {
2464 ComPtr<IAdditionsFacility> fac = collFac[index];
2465 if (fac)
2466 {
2467 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2468 if (!guestString.isEmpty())
2469 {
2470 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2471 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2472 if (details == VMINFO_MACHINEREADABLE)
2473 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2474 guestString.raw(), curStatus, lLastUpdatedMS);
2475 else
2476 {
2477 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2478 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2479 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2480 }
2481 }
2482 else
2483 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2484 }
2485 else
2486 AssertMsgFailed(("Invalid facility returned!\n"));
2487 }
2488 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2489 RTPrintf("No active facilities.\n");
2490 }
2491 }
2492
2493 if (details != VMINFO_MACHINEREADABLE)
2494 RTPrintf("\n");
2495
2496 /*
2497 * snapshots
2498 */
2499 ComPtr<ISnapshot> snapshot;
2500 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2501 if (SUCCEEDED(rc) && snapshot)
2502 {
2503 ComPtr<ISnapshot> currentSnapshot;
2504 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2505 if (SUCCEEDED(rc))
2506 {
2507 if (details != VMINFO_MACHINEREADABLE)
2508 RTPrintf("Snapshots:\n\n");
2509 showSnapshots(snapshot, currentSnapshot, details);
2510 }
2511 }
2512
2513 if (details != VMINFO_MACHINEREADABLE)
2514 RTPrintf("\n");
2515 return S_OK;
2516}
2517
2518#if defined(_MSC_VER)
2519# pragma optimize("", on)
2520#endif
2521
2522static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2523{
2524 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2525 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2526 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2527 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2528 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2529};
2530
2531int handleShowVMInfo(HandlerArg *a)
2532{
2533 HRESULT rc;
2534 const char *VMNameOrUuid = NULL;
2535 bool fLog = false;
2536 uint32_t uLogIdx = 0;
2537 bool fDetails = false;
2538 bool fMachinereadable = false;
2539
2540 int c;
2541 RTGETOPTUNION ValueUnion;
2542 RTGETOPTSTATE GetState;
2543 // start at 0 because main() has hacked both the argc and argv given to us
2544 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2545 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2546 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2547 {
2548 switch (c)
2549 {
2550 case 'D': // --details
2551 fDetails = true;
2552 break;
2553
2554 case 'M': // --machinereadable
2555 fMachinereadable = true;
2556 break;
2557
2558 case 'l': // --log
2559 fLog = true;
2560 uLogIdx = ValueUnion.u32;
2561 break;
2562
2563 case VINF_GETOPT_NOT_OPTION:
2564 if (!VMNameOrUuid)
2565 VMNameOrUuid = ValueUnion.psz;
2566 else
2567 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2568 break;
2569
2570 default:
2571 if (c > 0)
2572 {
2573 if (RT_C_IS_PRINT(c))
2574 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2575 else
2576 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2577 }
2578 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2579 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2580 else if (ValueUnion.pDef)
2581 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2582 else
2583 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2584 }
2585 }
2586
2587 /* check for required options */
2588 if (!VMNameOrUuid)
2589 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2590
2591 /* try to find the given machine */
2592 ComPtr <IMachine> machine;
2593 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2594 machine.asOutParam()));
2595 if (FAILED(rc))
2596 return 1;
2597
2598 /* Printing the log is exclusive. */
2599 if (fLog && (fMachinereadable || fDetails))
2600 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2601
2602 if (fLog)
2603 {
2604 ULONG64 uOffset = 0;
2605 SafeArray<BYTE> aLogData;
2606 ULONG cbLogData;
2607 while (true)
2608 {
2609 /* Reset the array */
2610 aLogData.setNull();
2611 /* Fetch a chunk of the log file */
2612 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2613 ComSafeArrayAsOutParam(aLogData)));
2614 cbLogData = aLogData.size();
2615 if (cbLogData == 0)
2616 break;
2617 /* aLogData has a platform dependent line ending, standardize on
2618 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2619 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2620 ULONG cbLogDataPrint = cbLogData;
2621 for (BYTE *s = aLogData.raw(), *d = s;
2622 s - aLogData.raw() < (ssize_t)cbLogData;
2623 s++, d++)
2624 {
2625 if (*s == '\r')
2626 {
2627 /* skip over CR, adjust destination */
2628 d--;
2629 cbLogDataPrint--;
2630 }
2631 else if (s != d)
2632 *d = *s;
2633 }
2634 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2635 uOffset += cbLogData;
2636 }
2637 }
2638 else
2639 {
2640 /* 2nd option can be -details or -argdump */
2641 VMINFO_DETAILS details = VMINFO_NONE;
2642 if (fMachinereadable)
2643 details = VMINFO_MACHINEREADABLE;
2644 else if (fDetails)
2645 details = VMINFO_FULL;
2646 else
2647 details = VMINFO_STANDARD;
2648
2649 ComPtr<IConsole> console;
2650
2651 /* open an existing session for the VM */
2652 rc = machine->LockMachine(a->session, LockType_Shared);
2653 if (SUCCEEDED(rc))
2654 /* get the session machine */
2655 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2656 if (SUCCEEDED(rc))
2657 /* get the session console */
2658 rc = a->session->COMGETTER(Console)(console.asOutParam());
2659
2660 rc = showVMInfo(a->virtualBox, machine, details, console);
2661
2662 if (console)
2663 a->session->UnlockMachine();
2664 }
2665
2666 return SUCCEEDED(rc) ? 0 : 1;
2667}
2668
2669#endif /* !VBOX_ONLY_DOCS */
2670/* 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