VirtualBox

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

Last change on this file since 48458 was 47991, checked in by vboxsync, 11 years ago

Main: Made the exclusive HW virtualization use setting global rather than per-VM.

  • 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 47991 2013-08-22 14:31:52Z 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_BusLogic:
747 pszCtl = "BusLogic";
748 break;
749 case StorageControllerType_IntelAhci:
750 pszCtl = "IntelAhci";
751 break;
752 case StorageControllerType_PIIX3:
753 pszCtl = "PIIX3";
754 break;
755 case StorageControllerType_PIIX4:
756 pszCtl = "PIIX4";
757 break;
758 case StorageControllerType_ICH6:
759 pszCtl = "ICH6";
760 break;
761 case StorageControllerType_I82078:
762 pszCtl = "I82078";
763 break;
764
765 default:
766 pszCtl = "unknown";
767 }
768 if (details == VMINFO_MACHINEREADABLE)
769 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
770 else
771 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
772
773 storageCtl->COMGETTER(Instance)(&ulValue);
774 if (details == VMINFO_MACHINEREADABLE)
775 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
776 else
777 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
778
779 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
780 if (details == VMINFO_MACHINEREADABLE)
781 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
782 else
783 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
784
785 storageCtl->COMGETTER(PortCount)(&ulValue);
786 if (details == VMINFO_MACHINEREADABLE)
787 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
788 else
789 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
790
791 storageCtl->COMGETTER(Bootable)(&fBootable);
792 if (details == VMINFO_MACHINEREADABLE)
793 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
794 else
795 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
796 }
797
798 for (size_t j = 0; j < storageCtls.size(); ++ j)
799 {
800 ComPtr<IStorageController> storageCtl = storageCtls[j];
801 ComPtr<IMedium> medium;
802 Bstr storageCtlName;
803 Bstr filePath;
804 ULONG cDevices;
805 ULONG cPorts;
806
807 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
808 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
809 storageCtl->COMGETTER(PortCount)(&cPorts);
810
811 for (ULONG i = 0; i < cPorts; ++ i)
812 {
813 for (ULONG k = 0; k < cDevices; ++ k)
814 {
815 ComPtr<IMediumAttachment> mediumAttach;
816 machine->GetMediumAttachment(storageCtlName.raw(),
817 i, k,
818 mediumAttach.asOutParam());
819 BOOL fIsEjected = FALSE;
820 BOOL fTempEject = FALSE;
821 DeviceType_T devType = DeviceType_Null;
822 if (mediumAttach)
823 {
824 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
825 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
826 mediumAttach->COMGETTER(Type)(&devType);
827 }
828 rc = machine->GetMedium(storageCtlName.raw(), i, k,
829 medium.asOutParam());
830 if (SUCCEEDED(rc) && medium)
831 {
832 BOOL fPassthrough = FALSE;
833
834 if (mediumAttach)
835 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
836
837 medium->COMGETTER(Location)(filePath.asOutParam());
838 Bstr uuid;
839 medium->COMGETTER(Id)(uuid.asOutParam());
840
841 if (details == VMINFO_MACHINEREADABLE)
842 {
843 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
844 i, k, filePath.raw());
845 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
846 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
847 if (fPassthrough)
848 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
849 fPassthrough ? "on" : "off");
850 if (devType == DeviceType_DVD)
851 {
852 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
853 fTempEject ? "on" : "off");
854 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
855 fIsEjected ? "on" : "off");
856 }
857 }
858 else
859 {
860 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
861 storageCtlName.raw(), i, k, filePath.raw(),
862 Utf8Str(uuid).c_str());
863 if (fPassthrough)
864 RTPrintf(" (passthrough enabled)");
865 if (fTempEject)
866 RTPrintf(" (temp eject)");
867 if (fIsEjected)
868 RTPrintf(" (ejected)");
869 RTPrintf("\n");
870 }
871 }
872 else if (SUCCEEDED(rc))
873 {
874 if (details == VMINFO_MACHINEREADABLE)
875 {
876 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
877 if (devType == DeviceType_DVD)
878 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
879 fIsEjected ? "on" : "off");
880 }
881 else
882 {
883 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
884 if (fTempEject)
885 RTPrintf(" (temp eject)");
886 if (fIsEjected)
887 RTPrintf(" (ejected)");
888 RTPrintf("\n");
889 }
890 }
891 else
892 {
893 if (details == VMINFO_MACHINEREADABLE)
894 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
895 }
896 }
897 }
898 }
899
900 /* get the maximum amount of NICS */
901 ULONG maxNICs = getMaxNics(virtualBox, machine);
902
903 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
904 {
905 ComPtr<INetworkAdapter> nic;
906 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
907 if (SUCCEEDED(rc) && nic)
908 {
909 BOOL fEnabled;
910 nic->COMGETTER(Enabled)(&fEnabled);
911 if (!fEnabled)
912 {
913 if (details == VMINFO_MACHINEREADABLE)
914 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
915 else
916 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
917 }
918 else
919 {
920 Bstr strMACAddress;
921 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
922 Utf8Str strAttachment;
923 Utf8Str strNatSettings = "";
924 Utf8Str strNatForwardings = "";
925 NetworkAttachmentType_T attachment;
926 nic->COMGETTER(AttachmentType)(&attachment);
927 switch (attachment)
928 {
929 case NetworkAttachmentType_Null:
930 if (details == VMINFO_MACHINEREADABLE)
931 strAttachment = "null";
932 else
933 strAttachment = "none";
934 break;
935
936 case NetworkAttachmentType_NAT:
937 {
938 Bstr strNetwork;
939 ComPtr<INATEngine> engine;
940 nic->COMGETTER(NATEngine)(engine.asOutParam());
941 engine->COMGETTER(Network)(strNetwork.asOutParam());
942 com::SafeArray<BSTR> forwardings;
943 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
944 strNatForwardings = "";
945 for (size_t i = 0; i < forwardings.size(); ++i)
946 {
947 bool fSkip = false;
948 uint16_t port = 0;
949 BSTR r = forwardings[i];
950 Utf8Str utf = Utf8Str(r);
951 Utf8Str strName;
952 Utf8Str strProto;
953 Utf8Str strHostPort;
954 Utf8Str strHostIP;
955 Utf8Str strGuestPort;
956 Utf8Str strGuestIP;
957 size_t pos, ppos;
958 pos = ppos = 0;
959 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
960 do { \
961 pos = str.find(",", ppos); \
962 if (pos == Utf8Str::npos) \
963 { \
964 Log(( #res " extracting from %s is failed\n", str.c_str())); \
965 fSkip = true; \
966 } \
967 res = str.substr(ppos, pos - ppos); \
968 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
969 ppos = pos + 1; \
970 } while (0)
971 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
972 if (fSkip) continue;
973 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
974 if (fSkip) continue;
975 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
976 if (fSkip) continue;
977 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
978 if (fSkip) continue;
979 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
980 if (fSkip) continue;
981 strGuestPort = utf.substr(ppos, utf.length() - ppos);
982 #undef ITERATE_TO_NEXT_TERM
983 switch (strProto.toUInt32())
984 {
985 case NATProtocol_TCP:
986 strProto = "tcp";
987 break;
988 case NATProtocol_UDP:
989 strProto = "udp";
990 break;
991 default:
992 strProto = "unk";
993 break;
994 }
995 if (details == VMINFO_MACHINEREADABLE)
996 {
997 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
998 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
999 strHostIP.c_str(), strHostPort.c_str(),
1000 strGuestIP.c_str(), strGuestPort.c_str());
1001 }
1002 else
1003 {
1004 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
1005 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1006 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
1007 strHostIP.c_str(), strHostPort.c_str(),
1008 strGuestIP.c_str(), strGuestPort.c_str());
1009 }
1010 }
1011 ULONG mtu = 0;
1012 ULONG sockSnd = 0;
1013 ULONG sockRcv = 0;
1014 ULONG tcpSnd = 0;
1015 ULONG tcpRcv = 0;
1016 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1017
1018 if (details == VMINFO_MACHINEREADABLE)
1019 {
1020 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1021 strAttachment = "nat";
1022 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1023 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1024 }
1025 else
1026 {
1027 strAttachment = "NAT";
1028 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1029 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1030 }
1031 break;
1032 }
1033
1034 case NetworkAttachmentType_Bridged:
1035 {
1036 Bstr strBridgeAdp;
1037 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1038 if (details == VMINFO_MACHINEREADABLE)
1039 {
1040 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1041 strAttachment = "bridged";
1042 }
1043 else
1044 strAttachment = Utf8StrFmt("Bridged Interface '%ls'", strBridgeAdp.raw());
1045 break;
1046 }
1047
1048 case NetworkAttachmentType_Internal:
1049 {
1050 Bstr strNetwork;
1051 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1052 if (details == VMINFO_MACHINEREADABLE)
1053 {
1054 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1055 strAttachment = "intnet";
1056 }
1057 else
1058 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1059 break;
1060 }
1061
1062 case NetworkAttachmentType_HostOnly:
1063 {
1064 Bstr strHostonlyAdp;
1065 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1066 if (details == VMINFO_MACHINEREADABLE)
1067 {
1068 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1069 strAttachment = "hostonly";
1070 }
1071 else
1072 strAttachment = Utf8StrFmt("Host-only Interface '%ls'", strHostonlyAdp.raw());
1073 break;
1074 }
1075 case NetworkAttachmentType_Generic:
1076 {
1077 Bstr strGenericDriver;
1078 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1079 if (details == VMINFO_MACHINEREADABLE)
1080 {
1081 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1082 strAttachment = "Generic";
1083 }
1084 else
1085 {
1086 strAttachment = Utf8StrFmt("Generic '%ls'", strGenericDriver.raw());
1087
1088 // show the generic properties
1089 com::SafeArray<BSTR> aProperties;
1090 com::SafeArray<BSTR> aValues;
1091 rc = nic->GetProperties(NULL,
1092 ComSafeArrayAsOutParam(aProperties),
1093 ComSafeArrayAsOutParam(aValues));
1094 if (SUCCEEDED(rc))
1095 {
1096 strAttachment += " { ";
1097 for (unsigned i = 0; i < aProperties.size(); ++i)
1098 strAttachment += Utf8StrFmt(!i ? "%ls='%ls'" : ", %ls='%ls'",
1099 aProperties[i], aValues[i]);
1100 strAttachment += " }";
1101 }
1102 }
1103 break;
1104 }
1105 default:
1106 strAttachment = "unknown";
1107 break;
1108 }
1109
1110 /* cable connected */
1111 BOOL fConnected;
1112 nic->COMGETTER(CableConnected)(&fConnected);
1113
1114 /* promisc policy */
1115 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1116 CHECK_ERROR2_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1117 const char *pszPromiscuousGuestPolicy;
1118 switch (enmPromiscModePolicy)
1119 {
1120 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1121 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1122 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1123 default: AssertFailedReturn(E_INVALIDARG);
1124 }
1125
1126 /* trace stuff */
1127 BOOL fTraceEnabled;
1128 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1129 Bstr traceFile;
1130 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1131
1132 /* NIC type */
1133 NetworkAdapterType_T NICType;
1134 nic->COMGETTER(AdapterType)(&NICType);
1135 const char *pszNICType;
1136 switch (NICType)
1137 {
1138 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1139 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1140#ifdef VBOX_WITH_E1000
1141 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1142 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1143 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1144#endif
1145#ifdef VBOX_WITH_VIRTIO
1146 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1147#endif
1148 default: AssertFailed(); pszNICType = "unknown"; break;
1149 }
1150
1151 /* reported line speed */
1152 ULONG ulLineSpeed;
1153 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1154
1155 /* boot priority of the adapter */
1156 ULONG ulBootPriority;
1157 nic->COMGETTER(BootPriority)(&ulBootPriority);
1158
1159 /* bandwidth group */
1160 ComObjPtr<IBandwidthGroup> pBwGroup;
1161 Bstr strBwGroup;
1162 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1163 if (!pBwGroup.isNull())
1164 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1165
1166 if (details == VMINFO_MACHINEREADABLE)
1167 {
1168 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1169 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1170 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1171 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1172 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1173 }
1174 else
1175 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",
1176 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
1177 fConnected ? "on" : "off",
1178 fTraceEnabled ? "on" : "off",
1179 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1180 pszNICType,
1181 ulLineSpeed / 1000,
1182 (int)ulBootPriority,
1183 pszPromiscuousGuestPolicy,
1184 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1185 if (strNatSettings.length())
1186 RTPrintf(strNatSettings.c_str());
1187 if (strNatForwardings.length())
1188 RTPrintf(strNatForwardings.c_str());
1189 }
1190 }
1191 }
1192
1193 /* Pointing device information */
1194 PointingHIDType_T aPointingHID;
1195 const char *pszHID = "Unknown";
1196 const char *pszMrHID = "unknown";
1197 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1198 switch (aPointingHID)
1199 {
1200 case PointingHIDType_None:
1201 pszHID = "None";
1202 pszMrHID = "none";
1203 break;
1204 case PointingHIDType_PS2Mouse:
1205 pszHID = "PS/2 Mouse";
1206 pszMrHID = "ps2mouse";
1207 break;
1208 case PointingHIDType_USBMouse:
1209 pszHID = "USB Mouse";
1210 pszMrHID = "usbmouse";
1211 break;
1212 case PointingHIDType_USBTablet:
1213 pszHID = "USB Tablet";
1214 pszMrHID = "usbtablet";
1215 break;
1216 case PointingHIDType_ComboMouse:
1217 pszHID = "USB Tablet and PS/2 Mouse";
1218 pszMrHID = "combomouse";
1219 break;
1220 case PointingHIDType_USBMultiTouch:
1221 pszHID = "USB Multi-Touch";
1222 pszMrHID = "usbmultitouch";
1223 break;
1224 default:
1225 break;
1226 }
1227 if (details == VMINFO_MACHINEREADABLE)
1228 RTPrintf("hidpointing=\"%s\"\n", pszMrHID);
1229 else
1230 RTPrintf("Pointing Device: %s\n", pszHID);
1231
1232 /* Keyboard device information */
1233 KeyboardHIDType_T aKeyboardHID;
1234 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1235 pszHID = "Unknown";
1236 pszMrHID = "unknown";
1237 switch (aKeyboardHID)
1238 {
1239 case KeyboardHIDType_None:
1240 pszHID = "None";
1241 pszMrHID = "none";
1242 break;
1243 case KeyboardHIDType_PS2Keyboard:
1244 pszHID = "PS/2 Keyboard";
1245 pszMrHID = "ps2kbd";
1246 break;
1247 case KeyboardHIDType_USBKeyboard:
1248 pszHID = "USB Keyboard";
1249 pszMrHID = "usbkbd";
1250 break;
1251 case KeyboardHIDType_ComboKeyboard:
1252 pszHID = "USB and PS/2 Keyboard";
1253 pszMrHID = "combokbd";
1254 break;
1255 default:
1256 break;
1257 }
1258 if (details == VMINFO_MACHINEREADABLE)
1259 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHID);
1260 else
1261 RTPrintf("Keyboard Device: %s\n", pszHID);
1262
1263 ComPtr<ISystemProperties> sysProps;
1264 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1265
1266 /* get the maximum amount of UARTs */
1267 ULONG maxUARTs = 0;
1268 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1269 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1270 {
1271 ComPtr<ISerialPort> uart;
1272 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1273 if (SUCCEEDED(rc) && uart)
1274 {
1275 /* show the config of this UART */
1276 BOOL fEnabled;
1277 uart->COMGETTER(Enabled)(&fEnabled);
1278 if (!fEnabled)
1279 {
1280 if (details == VMINFO_MACHINEREADABLE)
1281 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1282 else
1283 RTPrintf("UART %d: disabled\n", currentUART + 1);
1284 }
1285 else
1286 {
1287 ULONG ulIRQ, ulIOBase;
1288 PortMode_T HostMode;
1289 Bstr path;
1290 BOOL fServer;
1291 uart->COMGETTER(IRQ)(&ulIRQ);
1292 uart->COMGETTER(IOBase)(&ulIOBase);
1293 uart->COMGETTER(Path)(path.asOutParam());
1294 uart->COMGETTER(Server)(&fServer);
1295 uart->COMGETTER(HostMode)(&HostMode);
1296
1297 if (details == VMINFO_MACHINEREADABLE)
1298 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1299 ulIOBase, ulIRQ);
1300 else
1301 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1302 currentUART + 1, ulIOBase, ulIRQ);
1303 switch (HostMode)
1304 {
1305 default:
1306 case PortMode_Disconnected:
1307 if (details == VMINFO_MACHINEREADABLE)
1308 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1309 else
1310 RTPrintf(", disconnected\n");
1311 break;
1312 case PortMode_RawFile:
1313 if (details == VMINFO_MACHINEREADABLE)
1314 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1315 path.raw());
1316 else
1317 RTPrintf(", attached to raw file '%ls'\n",
1318 path.raw());
1319 break;
1320 case PortMode_HostPipe:
1321 if (details == VMINFO_MACHINEREADABLE)
1322 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1323 fServer ? "server" : "client", path.raw());
1324 else
1325 RTPrintf(", attached to pipe (%s) '%ls'\n",
1326 fServer ? "server" : "client", path.raw());
1327 break;
1328 case PortMode_HostDevice:
1329 if (details == VMINFO_MACHINEREADABLE)
1330 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1331 path.raw());
1332 else
1333 RTPrintf(", attached to device '%ls'\n", path.raw());
1334 break;
1335 }
1336 }
1337 }
1338 }
1339
1340 /* get the maximum amount of LPTs */
1341 ULONG maxLPTs = 0;
1342 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1343 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1344 {
1345 ComPtr<IParallelPort> lpt;
1346 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1347 if (SUCCEEDED(rc) && lpt)
1348 {
1349 /* show the config of this LPT */
1350 BOOL fEnabled;
1351 lpt->COMGETTER(Enabled)(&fEnabled);
1352 if (!fEnabled)
1353 {
1354 if (details == VMINFO_MACHINEREADABLE)
1355 RTPrintf("lpt%d=\"off\"\n", currentLPT + 1);
1356 else
1357 RTPrintf("LPT %d: disabled\n", currentLPT + 1);
1358 }
1359 else
1360 {
1361 ULONG ulIRQ, ulIOBase;
1362 Bstr path;
1363 lpt->COMGETTER(IRQ)(&ulIRQ);
1364 lpt->COMGETTER(IOBase)(&ulIOBase);
1365 lpt->COMGETTER(Path)(path.asOutParam());
1366
1367 if (details == VMINFO_MACHINEREADABLE)
1368 RTPrintf("lpt%d=\"%#06x,%d\"\n", currentLPT + 1,
1369 ulIOBase, ulIRQ);
1370 else
1371 RTPrintf("LPT %d: I/O base: %#06x, IRQ: %d",
1372 currentLPT + 1, ulIOBase, ulIRQ);
1373 if (details == VMINFO_MACHINEREADABLE)
1374 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1,
1375 path.raw());
1376 else
1377 RTPrintf(", attached to device '%ls'\n", path.raw());
1378 }
1379 }
1380 }
1381
1382 ComPtr<IAudioAdapter> AudioAdapter;
1383 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1384 if (SUCCEEDED(rc))
1385 {
1386 const char *pszDrv = "Unknown";
1387 const char *pszCtrl = "Unknown";
1388 BOOL fEnabled;
1389 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1390 if (SUCCEEDED(rc) && fEnabled)
1391 {
1392 AudioDriverType_T enmDrvType;
1393 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1394 switch (enmDrvType)
1395 {
1396 case AudioDriverType_Null:
1397 if (details == VMINFO_MACHINEREADABLE)
1398 pszDrv = "null";
1399 else
1400 pszDrv = "Null";
1401 break;
1402 case AudioDriverType_WinMM:
1403 if (details == VMINFO_MACHINEREADABLE)
1404 pszDrv = "winmm";
1405 else
1406 pszDrv = "WINMM";
1407 break;
1408 case AudioDriverType_DirectSound:
1409 if (details == VMINFO_MACHINEREADABLE)
1410 pszDrv = "dsound";
1411 else
1412 pszDrv = "DSOUND";
1413 break;
1414 case AudioDriverType_OSS:
1415 if (details == VMINFO_MACHINEREADABLE)
1416 pszDrv = "oss";
1417 else
1418 pszDrv = "OSS";
1419 break;
1420 case AudioDriverType_ALSA:
1421 if (details == VMINFO_MACHINEREADABLE)
1422 pszDrv = "alsa";
1423 else
1424 pszDrv = "ALSA";
1425 break;
1426 case AudioDriverType_Pulse:
1427 if (details == VMINFO_MACHINEREADABLE)
1428 pszDrv = "pulse";
1429 else
1430 pszDrv = "PulseAudio";
1431 break;
1432 case AudioDriverType_CoreAudio:
1433 if (details == VMINFO_MACHINEREADABLE)
1434 pszDrv = "coreaudio";
1435 else
1436 pszDrv = "CoreAudio";
1437 break;
1438 case AudioDriverType_SolAudio:
1439 if (details == VMINFO_MACHINEREADABLE)
1440 pszDrv = "solaudio";
1441 else
1442 pszDrv = "SolAudio";
1443 break;
1444 default:
1445 if (details == VMINFO_MACHINEREADABLE)
1446 pszDrv = "unknown";
1447 break;
1448 }
1449 AudioControllerType_T enmCtrlType;
1450 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1451 switch (enmCtrlType)
1452 {
1453 case AudioControllerType_AC97:
1454 if (details == VMINFO_MACHINEREADABLE)
1455 pszCtrl = "ac97";
1456 else
1457 pszCtrl = "AC97";
1458 break;
1459 case AudioControllerType_SB16:
1460 if (details == VMINFO_MACHINEREADABLE)
1461 pszCtrl = "sb16";
1462 else
1463 pszCtrl = "SB16";
1464 break;
1465 case AudioControllerType_HDA:
1466 if (details == VMINFO_MACHINEREADABLE)
1467 pszCtrl = "hda";
1468 else
1469 pszCtrl = "HDA";
1470 break;
1471 }
1472 }
1473 else
1474 fEnabled = FALSE;
1475 if (details == VMINFO_MACHINEREADABLE)
1476 {
1477 if (fEnabled)
1478 RTPrintf("audio=\"%s\"\n", pszDrv);
1479 else
1480 RTPrintf("audio=\"none\"\n");
1481 }
1482 else
1483 {
1484 RTPrintf("Audio: %s",
1485 fEnabled ? "enabled" : "disabled");
1486 if (fEnabled)
1487 RTPrintf(" (Driver: %s, Controller: %s)",
1488 pszDrv, pszCtrl);
1489 RTPrintf("\n");
1490 }
1491 }
1492
1493 /* Shared clipboard */
1494 {
1495 const char *psz = "Unknown";
1496 ClipboardMode_T enmMode;
1497 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1498 switch (enmMode)
1499 {
1500 case ClipboardMode_Disabled:
1501 if (details == VMINFO_MACHINEREADABLE)
1502 psz = "disabled";
1503 else
1504 psz = "disabled";
1505 break;
1506 case ClipboardMode_HostToGuest:
1507 if (details == VMINFO_MACHINEREADABLE)
1508 psz = "hosttoguest";
1509 else
1510 psz = "HostToGuest";
1511 break;
1512 case ClipboardMode_GuestToHost:
1513 if (details == VMINFO_MACHINEREADABLE)
1514 psz = "guesttohost";
1515 else
1516 psz = "GuestToHost";
1517 break;
1518 case ClipboardMode_Bidirectional:
1519 if (details == VMINFO_MACHINEREADABLE)
1520 psz = "bidirectional";
1521 else
1522 psz = "Bidirectional";
1523 break;
1524 default:
1525 if (details == VMINFO_MACHINEREADABLE)
1526 psz = "unknown";
1527 break;
1528 }
1529 if (details == VMINFO_MACHINEREADABLE)
1530 RTPrintf("clipboard=\"%s\"\n", psz);
1531 else
1532 RTPrintf("Clipboard Mode: %s\n", psz);
1533 }
1534
1535 /* Drag'n'drop */
1536 {
1537 const char *psz = "Unknown";
1538 DragAndDropMode_T enmMode;
1539 rc = machine->COMGETTER(DragAndDropMode)(&enmMode);
1540 switch (enmMode)
1541 {
1542 case DragAndDropMode_Disabled:
1543 if (details == VMINFO_MACHINEREADABLE)
1544 psz = "disabled";
1545 else
1546 psz = "disabled";
1547 break;
1548 case DragAndDropMode_HostToGuest:
1549 if (details == VMINFO_MACHINEREADABLE)
1550 psz = "hosttoguest";
1551 else
1552 psz = "HostToGuest";
1553 break;
1554 case DragAndDropMode_GuestToHost:
1555 if (details == VMINFO_MACHINEREADABLE)
1556 psz = "guesttohost";
1557 else
1558 psz = "GuestToHost";
1559 break;
1560 case DragAndDropMode_Bidirectional:
1561 if (details == VMINFO_MACHINEREADABLE)
1562 psz = "bidirectional";
1563 else
1564 psz = "Bidirectional";
1565 break;
1566 default:
1567 if (details == VMINFO_MACHINEREADABLE)
1568 psz = "unknown";
1569 break;
1570 }
1571 if (details == VMINFO_MACHINEREADABLE)
1572 RTPrintf("draganddrop=\"%s\"\n", psz);
1573 else
1574 RTPrintf("Drag'n'drop Mode: %s\n", psz);
1575 }
1576
1577 {
1578 SessionState_T sessState;
1579 rc = machine->COMGETTER(SessionState)(&sessState);
1580 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1581 {
1582 Bstr sessType;
1583 rc = machine->COMGETTER(SessionType)(sessType.asOutParam());
1584 if (SUCCEEDED(rc) && !sessType.isEmpty())
1585 {
1586 if (details == VMINFO_MACHINEREADABLE)
1587 RTPrintf("SessionType=\"%ls\"\n", sessType.raw());
1588 else
1589 RTPrintf("Session type: %ls\n", sessType.raw());
1590 }
1591 }
1592 }
1593
1594 if (console)
1595 {
1596 do
1597 {
1598 ComPtr<IDisplay> display;
1599 rc = console->COMGETTER(Display)(display.asOutParam());
1600 if (rc == E_ACCESSDENIED || display.isNull())
1601 break; /* VM not powered up */
1602 if (FAILED(rc))
1603 {
1604 com::GlueHandleComError(console, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1605 return rc;
1606 }
1607 ULONG xRes, yRes, bpp;
1608 LONG xOrigin, yOrigin;
1609 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin);
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\"@%d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1620 else
1621 RTPrintf("Video mode: %dx%dx%d at %d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
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