VirtualBox

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

Last change on this file since 46911 was 46667, checked in by vboxsync, 11 years ago

Main/idl: clarify IMachine.videoCaptureFile to be an absolute path, and many naming convention cleanups for method/attribute names starting with an uppercase letter or containing an acronym
Main/xml/Settings.cpp: clean up default video capture file handling and related path conversions, version handling of the new functionality
Main/Machine: handle default value for video capture file better, store relative path in settings if possible, cleanups
Main/src-client/VideoRec.cpp: do not overwrite a file ever
Main/Display: generate a unique name if there is a collision, matching cleanups for name changes
Frontends/VirtualBox: matching name changes
Frontends/VBoxManage: matching name changes, fixing the machine readable output

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 108.7 KB
Line 
1/* $Id: VBoxManageInfo.cpp 46667 2013-06-19 15:30:23Z 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 default:
1222 break;
1223 }
1224 if (details == VMINFO_MACHINEREADABLE)
1225 RTPrintf("hidpointing=\"%s\"\n", pszMrHID);
1226 else
1227 RTPrintf("Pointing Device: %s\n", pszHID);
1228
1229 /* Keyboard device information */
1230 KeyboardHIDType_T aKeyboardHID;
1231 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1232 pszHID = "Unknown";
1233 pszMrHID = "unknown";
1234 switch (aKeyboardHID)
1235 {
1236 case KeyboardHIDType_None:
1237 pszHID = "None";
1238 pszMrHID = "none";
1239 break;
1240 case KeyboardHIDType_PS2Keyboard:
1241 pszHID = "PS/2 Keyboard";
1242 pszMrHID = "ps2kbd";
1243 break;
1244 case KeyboardHIDType_USBKeyboard:
1245 pszHID = "USB Keyboard";
1246 pszMrHID = "usbkbd";
1247 break;
1248 case KeyboardHIDType_ComboKeyboard:
1249 pszHID = "USB and PS/2 Keyboard";
1250 pszMrHID = "combokbd";
1251 break;
1252 default:
1253 break;
1254 }
1255 if (details == VMINFO_MACHINEREADABLE)
1256 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHID);
1257 else
1258 RTPrintf("Keyboard Device: %s\n", pszHID);
1259
1260 ComPtr<ISystemProperties> sysProps;
1261 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1262
1263 /* get the maximum amount of UARTs */
1264 ULONG maxUARTs = 0;
1265 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1266 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1267 {
1268 ComPtr<ISerialPort> uart;
1269 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1270 if (SUCCEEDED(rc) && uart)
1271 {
1272 /* show the config of this UART */
1273 BOOL fEnabled;
1274 uart->COMGETTER(Enabled)(&fEnabled);
1275 if (!fEnabled)
1276 {
1277 if (details == VMINFO_MACHINEREADABLE)
1278 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1279 else
1280 RTPrintf("UART %d: disabled\n", currentUART + 1);
1281 }
1282 else
1283 {
1284 ULONG ulIRQ, ulIOBase;
1285 PortMode_T HostMode;
1286 Bstr path;
1287 BOOL fServer;
1288 uart->COMGETTER(IRQ)(&ulIRQ);
1289 uart->COMGETTER(IOBase)(&ulIOBase);
1290 uart->COMGETTER(Path)(path.asOutParam());
1291 uart->COMGETTER(Server)(&fServer);
1292 uart->COMGETTER(HostMode)(&HostMode);
1293
1294 if (details == VMINFO_MACHINEREADABLE)
1295 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1296 ulIOBase, ulIRQ);
1297 else
1298 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1299 currentUART + 1, ulIOBase, ulIRQ);
1300 switch (HostMode)
1301 {
1302 default:
1303 case PortMode_Disconnected:
1304 if (details == VMINFO_MACHINEREADABLE)
1305 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1306 else
1307 RTPrintf(", disconnected\n");
1308 break;
1309 case PortMode_RawFile:
1310 if (details == VMINFO_MACHINEREADABLE)
1311 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1312 path.raw());
1313 else
1314 RTPrintf(", attached to raw file '%ls'\n",
1315 path.raw());
1316 break;
1317 case PortMode_HostPipe:
1318 if (details == VMINFO_MACHINEREADABLE)
1319 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1320 fServer ? "server" : "client", path.raw());
1321 else
1322 RTPrintf(", attached to pipe (%s) '%ls'\n",
1323 fServer ? "server" : "client", path.raw());
1324 break;
1325 case PortMode_HostDevice:
1326 if (details == VMINFO_MACHINEREADABLE)
1327 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1328 path.raw());
1329 else
1330 RTPrintf(", attached to device '%ls'\n", path.raw());
1331 break;
1332 }
1333 }
1334 }
1335 }
1336
1337 /* get the maximum amount of LPTs */
1338 ULONG maxLPTs = 0;
1339 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1340 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1341 {
1342 ComPtr<IParallelPort> lpt;
1343 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1344 if (SUCCEEDED(rc) && lpt)
1345 {
1346 /* show the config of this LPT */
1347 BOOL fEnabled;
1348 lpt->COMGETTER(Enabled)(&fEnabled);
1349 if (!fEnabled)
1350 {
1351 if (details == VMINFO_MACHINEREADABLE)
1352 RTPrintf("lpt%d=\"off\"\n", currentLPT + 1);
1353 else
1354 RTPrintf("LPT %d: disabled\n", currentLPT + 1);
1355 }
1356 else
1357 {
1358 ULONG ulIRQ, ulIOBase;
1359 Bstr path;
1360 lpt->COMGETTER(IRQ)(&ulIRQ);
1361 lpt->COMGETTER(IOBase)(&ulIOBase);
1362 lpt->COMGETTER(Path)(path.asOutParam());
1363
1364 if (details == VMINFO_MACHINEREADABLE)
1365 RTPrintf("lpt%d=\"%#06x,%d\"\n", currentLPT + 1,
1366 ulIOBase, ulIRQ);
1367 else
1368 RTPrintf("LPT %d: I/O base: %#06x, IRQ: %d",
1369 currentLPT + 1, ulIOBase, ulIRQ);
1370 if (details == VMINFO_MACHINEREADABLE)
1371 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1,
1372 path.raw());
1373 else
1374 RTPrintf(", attached to device '%ls'\n", path.raw());
1375 }
1376 }
1377 }
1378
1379 ComPtr<IAudioAdapter> AudioAdapter;
1380 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1381 if (SUCCEEDED(rc))
1382 {
1383 const char *pszDrv = "Unknown";
1384 const char *pszCtrl = "Unknown";
1385 BOOL fEnabled;
1386 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1387 if (SUCCEEDED(rc) && fEnabled)
1388 {
1389 AudioDriverType_T enmDrvType;
1390 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1391 switch (enmDrvType)
1392 {
1393 case AudioDriverType_Null:
1394 if (details == VMINFO_MACHINEREADABLE)
1395 pszDrv = "null";
1396 else
1397 pszDrv = "Null";
1398 break;
1399 case AudioDriverType_WinMM:
1400 if (details == VMINFO_MACHINEREADABLE)
1401 pszDrv = "winmm";
1402 else
1403 pszDrv = "WINMM";
1404 break;
1405 case AudioDriverType_DirectSound:
1406 if (details == VMINFO_MACHINEREADABLE)
1407 pszDrv = "dsound";
1408 else
1409 pszDrv = "DSOUND";
1410 break;
1411 case AudioDriverType_OSS:
1412 if (details == VMINFO_MACHINEREADABLE)
1413 pszDrv = "oss";
1414 else
1415 pszDrv = "OSS";
1416 break;
1417 case AudioDriverType_ALSA:
1418 if (details == VMINFO_MACHINEREADABLE)
1419 pszDrv = "alsa";
1420 else
1421 pszDrv = "ALSA";
1422 break;
1423 case AudioDriverType_Pulse:
1424 if (details == VMINFO_MACHINEREADABLE)
1425 pszDrv = "pulse";
1426 else
1427 pszDrv = "PulseAudio";
1428 break;
1429 case AudioDriverType_CoreAudio:
1430 if (details == VMINFO_MACHINEREADABLE)
1431 pszDrv = "coreaudio";
1432 else
1433 pszDrv = "CoreAudio";
1434 break;
1435 case AudioDriverType_SolAudio:
1436 if (details == VMINFO_MACHINEREADABLE)
1437 pszDrv = "solaudio";
1438 else
1439 pszDrv = "SolAudio";
1440 break;
1441 default:
1442 if (details == VMINFO_MACHINEREADABLE)
1443 pszDrv = "unknown";
1444 break;
1445 }
1446 AudioControllerType_T enmCtrlType;
1447 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1448 switch (enmCtrlType)
1449 {
1450 case AudioControllerType_AC97:
1451 if (details == VMINFO_MACHINEREADABLE)
1452 pszCtrl = "ac97";
1453 else
1454 pszCtrl = "AC97";
1455 break;
1456 case AudioControllerType_SB16:
1457 if (details == VMINFO_MACHINEREADABLE)
1458 pszCtrl = "sb16";
1459 else
1460 pszCtrl = "SB16";
1461 break;
1462 case AudioControllerType_HDA:
1463 if (details == VMINFO_MACHINEREADABLE)
1464 pszCtrl = "hda";
1465 else
1466 pszCtrl = "HDA";
1467 break;
1468 }
1469 }
1470 else
1471 fEnabled = FALSE;
1472 if (details == VMINFO_MACHINEREADABLE)
1473 {
1474 if (fEnabled)
1475 RTPrintf("audio=\"%s\"\n", pszDrv);
1476 else
1477 RTPrintf("audio=\"none\"\n");
1478 }
1479 else
1480 {
1481 RTPrintf("Audio: %s",
1482 fEnabled ? "enabled" : "disabled");
1483 if (fEnabled)
1484 RTPrintf(" (Driver: %s, Controller: %s)",
1485 pszDrv, pszCtrl);
1486 RTPrintf("\n");
1487 }
1488 }
1489
1490 /* Shared clipboard */
1491 {
1492 const char *psz = "Unknown";
1493 ClipboardMode_T enmMode;
1494 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1495 switch (enmMode)
1496 {
1497 case ClipboardMode_Disabled:
1498 if (details == VMINFO_MACHINEREADABLE)
1499 psz = "disabled";
1500 else
1501 psz = "disabled";
1502 break;
1503 case ClipboardMode_HostToGuest:
1504 if (details == VMINFO_MACHINEREADABLE)
1505 psz = "hosttoguest";
1506 else
1507 psz = "HostToGuest";
1508 break;
1509 case ClipboardMode_GuestToHost:
1510 if (details == VMINFO_MACHINEREADABLE)
1511 psz = "guesttohost";
1512 else
1513 psz = "GuestToHost";
1514 break;
1515 case ClipboardMode_Bidirectional:
1516 if (details == VMINFO_MACHINEREADABLE)
1517 psz = "bidirectional";
1518 else
1519 psz = "Bidirectional";
1520 break;
1521 default:
1522 if (details == VMINFO_MACHINEREADABLE)
1523 psz = "unknown";
1524 break;
1525 }
1526 if (details == VMINFO_MACHINEREADABLE)
1527 RTPrintf("clipboard=\"%s\"\n", psz);
1528 else
1529 RTPrintf("Clipboard Mode: %s\n", psz);
1530 }
1531
1532 /* Drag'n'drop */
1533 {
1534 const char *psz = "Unknown";
1535 DragAndDropMode_T enmMode;
1536 rc = machine->COMGETTER(DragAndDropMode)(&enmMode);
1537 switch (enmMode)
1538 {
1539 case DragAndDropMode_Disabled:
1540 if (details == VMINFO_MACHINEREADABLE)
1541 psz = "disabled";
1542 else
1543 psz = "disabled";
1544 break;
1545 case DragAndDropMode_HostToGuest:
1546 if (details == VMINFO_MACHINEREADABLE)
1547 psz = "hosttoguest";
1548 else
1549 psz = "HostToGuest";
1550 break;
1551 case DragAndDropMode_GuestToHost:
1552 if (details == VMINFO_MACHINEREADABLE)
1553 psz = "guesttohost";
1554 else
1555 psz = "GuestToHost";
1556 break;
1557 case DragAndDropMode_Bidirectional:
1558 if (details == VMINFO_MACHINEREADABLE)
1559 psz = "bidirectional";
1560 else
1561 psz = "Bidirectional";
1562 break;
1563 default:
1564 if (details == VMINFO_MACHINEREADABLE)
1565 psz = "unknown";
1566 break;
1567 }
1568 if (details == VMINFO_MACHINEREADABLE)
1569 RTPrintf("draganddrop=\"%s\"\n", psz);
1570 else
1571 RTPrintf("Drag'n'drop Mode: %s\n", psz);
1572 }
1573
1574 {
1575 SessionState_T sessState;
1576 rc = machine->COMGETTER(SessionState)(&sessState);
1577 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1578 {
1579 Bstr sessType;
1580 rc = machine->COMGETTER(SessionType)(sessType.asOutParam());
1581 if (SUCCEEDED(rc) && !sessType.isEmpty())
1582 {
1583 if (details == VMINFO_MACHINEREADABLE)
1584 RTPrintf("SessionType=\"%ls\"\n", sessType.raw());
1585 else
1586 RTPrintf("Session type: %ls\n", sessType.raw());
1587 }
1588 }
1589 }
1590
1591 if (console)
1592 {
1593 do
1594 {
1595 ComPtr<IDisplay> display;
1596 rc = console->COMGETTER(Display)(display.asOutParam());
1597 if (rc == E_ACCESSDENIED || display.isNull())
1598 break; /* VM not powered up */
1599 if (FAILED(rc))
1600 {
1601 com::GlueHandleComError(console, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1602 return rc;
1603 }
1604 ULONG xRes, yRes, bpp;
1605 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp);
1606 if (rc == E_ACCESSDENIED)
1607 break; /* VM not powered up */
1608 if (FAILED(rc))
1609 {
1610 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1611 GluePrintErrorInfo(info);
1612 return rc;
1613 }
1614 if (details == VMINFO_MACHINEREADABLE)
1615 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1616 else
1617 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1618 }
1619 while (0);
1620 }
1621
1622 /*
1623 * Remote Desktop
1624 */
1625 ComPtr<IVRDEServer> vrdeServer;
1626 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1627 if (SUCCEEDED(rc) && vrdeServer)
1628 {
1629 BOOL fEnabled = false;
1630 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1631 if (fEnabled)
1632 {
1633 LONG currentPort = -1;
1634 Bstr ports;
1635 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1636 Bstr address;
1637 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1638 BOOL fMultiCon;
1639 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1640 BOOL fReuseCon;
1641 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1642 Bstr videoChannel;
1643 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1644 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1645 || (videoChannel == "1");
1646 Bstr videoChannelQuality;
1647 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1648 AuthType_T authType;
1649 const char *strAuthType;
1650 vrdeServer->COMGETTER(AuthType)(&authType);
1651 switch (authType)
1652 {
1653 case AuthType_Null:
1654 strAuthType = "null";
1655 break;
1656 case AuthType_External:
1657 strAuthType = "external";
1658 break;
1659 case AuthType_Guest:
1660 strAuthType = "guest";
1661 break;
1662 default:
1663 strAuthType = "unknown";
1664 break;
1665 }
1666 if (console)
1667 {
1668 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1669 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1670 if (!vrdeServerInfo.isNull())
1671 {
1672 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1673 if (rc == E_ACCESSDENIED)
1674 {
1675 currentPort = -1; /* VM not powered up */
1676 }
1677 if (FAILED(rc))
1678 {
1679 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1680 GluePrintErrorInfo(info);
1681 return rc;
1682 }
1683 }
1684 }
1685 if (details == VMINFO_MACHINEREADABLE)
1686 {
1687 RTPrintf("vrde=\"on\"\n");
1688 RTPrintf("vrdeport=%d\n", currentPort);
1689 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1690 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1691 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1692 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1693 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1694 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1695 if (fVideoChannel)
1696 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1697 }
1698 else
1699 {
1700 if (address.isEmpty())
1701 address = "0.0.0.0";
1702 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);
1703 if (console && currentPort != -1 && currentPort != 0)
1704 RTPrintf("VRDE port: %d\n", currentPort);
1705 if (fVideoChannel)
1706 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1707 else
1708 RTPrintf("Video redirection: disabled\n");
1709 }
1710 com::SafeArray<BSTR> aProperties;
1711 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1712 {
1713 unsigned i;
1714 for (i = 0; i < aProperties.size(); ++i)
1715 {
1716 Bstr value;
1717 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1718 if (details == VMINFO_MACHINEREADABLE)
1719 {
1720 if (value.isEmpty())
1721 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1722 else
1723 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1724 }
1725 else
1726 {
1727 if (value.isEmpty())
1728 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1729 else
1730 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1731 }
1732 }
1733 }
1734 }
1735 else
1736 {
1737 if (details == VMINFO_MACHINEREADABLE)
1738 RTPrintf("vrde=\"off\"\n");
1739 else
1740 RTPrintf("VRDE: disabled\n");
1741 }
1742 }
1743
1744 /*
1745 * USB.
1746 */
1747 ComPtr<IUSBController> USBCtl;
1748 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1749 if (SUCCEEDED(rc))
1750 {
1751 BOOL fEnabled;
1752 BOOL fEHCIEnabled;
1753 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1754 if (FAILED(rc))
1755 fEnabled = false;
1756 if (details == VMINFO_MACHINEREADABLE)
1757 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1758 else
1759 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1760
1761 rc = USBCtl->COMGETTER(EnabledEHCI)(&fEHCIEnabled);
1762 if (FAILED(rc))
1763 fEHCIEnabled = false;
1764 if (details == VMINFO_MACHINEREADABLE)
1765 RTPrintf("ehci=\"%s\"\n", fEHCIEnabled ? "on" : "off");
1766 else
1767 RTPrintf("EHCI: %s\n", fEHCIEnabled ? "enabled" : "disabled");
1768
1769 SafeIfaceArray <IUSBDeviceFilter> Coll;
1770 rc = USBCtl->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1771 if (SUCCEEDED(rc))
1772 {
1773 if (details != VMINFO_MACHINEREADABLE)
1774 RTPrintf("\nUSB Device Filters:\n\n");
1775
1776 if (Coll.size() == 0)
1777 {
1778 if (details != VMINFO_MACHINEREADABLE)
1779 RTPrintf("<none>\n\n");
1780 }
1781 else
1782 {
1783 for (size_t index = 0; index < Coll.size(); ++index)
1784 {
1785 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1786
1787 /* Query info. */
1788
1789 if (details != VMINFO_MACHINEREADABLE)
1790 RTPrintf("Index: %zu\n", index);
1791
1792 BOOL bActive = FALSE;
1793 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1794 if (details == VMINFO_MACHINEREADABLE)
1795 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1796 else
1797 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1798
1799 Bstr bstr;
1800 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1801 if (details == VMINFO_MACHINEREADABLE)
1802 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1803 else
1804 RTPrintf("Name: %ls\n", bstr.raw());
1805 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1806 if (details == VMINFO_MACHINEREADABLE)
1807 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1808 else
1809 RTPrintf("VendorId: %ls\n", bstr.raw());
1810 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1811 if (details == VMINFO_MACHINEREADABLE)
1812 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
1813 else
1814 RTPrintf("ProductId: %ls\n", bstr.raw());
1815 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1816 if (details == VMINFO_MACHINEREADABLE)
1817 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
1818 else
1819 RTPrintf("Revision: %ls\n", bstr.raw());
1820 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1821 if (details == VMINFO_MACHINEREADABLE)
1822 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1823 else
1824 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1825 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1826 if (details == VMINFO_MACHINEREADABLE)
1827 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1828 else
1829 RTPrintf("Product: %ls\n", bstr.raw());
1830 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1831 if (details == VMINFO_MACHINEREADABLE)
1832 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
1833 else
1834 RTPrintf("Remote: %ls\n", bstr.raw());
1835 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1836 if (details == VMINFO_MACHINEREADABLE)
1837 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1838 else
1839 RTPrintf("Serial Number: %ls\n", bstr.raw());
1840 if (details != VMINFO_MACHINEREADABLE)
1841 {
1842 ULONG fMaskedIfs;
1843 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1844 if (fMaskedIfs)
1845 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1846 RTPrintf("\n");
1847 }
1848 }
1849 }
1850 }
1851
1852 if (console)
1853 {
1854 /* scope */
1855 {
1856 if (details != VMINFO_MACHINEREADABLE)
1857 RTPrintf("Available remote USB devices:\n\n");
1858
1859 SafeIfaceArray <IHostUSBDevice> coll;
1860 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1861
1862 if (coll.size() == 0)
1863 {
1864 if (details != VMINFO_MACHINEREADABLE)
1865 RTPrintf("<none>\n\n");
1866 }
1867 else
1868 {
1869 for (size_t index = 0; index < coll.size(); ++index)
1870 {
1871 ComPtr <IHostUSBDevice> dev = coll[index];
1872
1873 /* Query info. */
1874 Bstr id;
1875 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1876 USHORT usVendorId;
1877 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1878 USHORT usProductId;
1879 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1880 USHORT bcdRevision;
1881 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1882
1883 if (details == VMINFO_MACHINEREADABLE)
1884 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
1885 "USBRemoteVendorId%zu=\"%#06x\"\n"
1886 "USBRemoteProductId%zu=\"%#06x\"\n"
1887 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1888 index + 1, Utf8Str(id).c_str(),
1889 index + 1, usVendorId,
1890 index + 1, usProductId,
1891 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1892 else
1893 RTPrintf("UUID: %s\n"
1894 "VendorId: %#06x (%04X)\n"
1895 "ProductId: %#06x (%04X)\n"
1896 "Revision: %u.%u (%02u%02u)\n",
1897 Utf8Str(id).c_str(),
1898 usVendorId, usVendorId, usProductId, usProductId,
1899 bcdRevision >> 8, bcdRevision & 0xff,
1900 bcdRevision >> 8, bcdRevision & 0xff);
1901
1902 /* optional stuff. */
1903 Bstr bstr;
1904 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1905 if (!bstr.isEmpty())
1906 {
1907 if (details == VMINFO_MACHINEREADABLE)
1908 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1909 else
1910 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1911 }
1912 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1913 if (!bstr.isEmpty())
1914 {
1915 if (details == VMINFO_MACHINEREADABLE)
1916 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1917 else
1918 RTPrintf("Product: %ls\n", bstr.raw());
1919 }
1920 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1921 if (!bstr.isEmpty())
1922 {
1923 if (details == VMINFO_MACHINEREADABLE)
1924 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1925 else
1926 RTPrintf("SerialNumber: %ls\n", bstr.raw());
1927 }
1928 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1929 if (!bstr.isEmpty())
1930 {
1931 if (details == VMINFO_MACHINEREADABLE)
1932 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
1933 else
1934 RTPrintf("Address: %ls\n", bstr.raw());
1935 }
1936
1937 if (details != VMINFO_MACHINEREADABLE)
1938 RTPrintf("\n");
1939 }
1940 }
1941 }
1942
1943 /* scope */
1944 {
1945 if (details != VMINFO_MACHINEREADABLE)
1946 RTPrintf("Currently Attached USB Devices:\n\n");
1947
1948 SafeIfaceArray <IUSBDevice> coll;
1949 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1950
1951 if (coll.size() == 0)
1952 {
1953 if (details != VMINFO_MACHINEREADABLE)
1954 RTPrintf("<none>\n\n");
1955 }
1956 else
1957 {
1958 for (size_t index = 0; index < coll.size(); ++index)
1959 {
1960 ComPtr <IUSBDevice> dev = coll[index];
1961
1962 /* Query info. */
1963 Bstr id;
1964 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1965 USHORT usVendorId;
1966 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1967 USHORT usProductId;
1968 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1969 USHORT bcdRevision;
1970 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1971
1972 if (details == VMINFO_MACHINEREADABLE)
1973 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
1974 "USBAttachedVendorId%zu=\"%#06x\"\n"
1975 "USBAttachedProductId%zu=\"%#06x\"\n"
1976 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
1977 index + 1, Utf8Str(id).c_str(),
1978 index + 1, usVendorId,
1979 index + 1, usProductId,
1980 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1981 else
1982 RTPrintf("UUID: %s\n"
1983 "VendorId: %#06x (%04X)\n"
1984 "ProductId: %#06x (%04X)\n"
1985 "Revision: %u.%u (%02u%02u)\n",
1986 Utf8Str(id).c_str(),
1987 usVendorId, usVendorId, usProductId, usProductId,
1988 bcdRevision >> 8, bcdRevision & 0xff,
1989 bcdRevision >> 8, bcdRevision & 0xff);
1990
1991 /* optional stuff. */
1992 Bstr bstr;
1993 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1994 if (!bstr.isEmpty())
1995 {
1996 if (details == VMINFO_MACHINEREADABLE)
1997 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1998 else
1999 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2000 }
2001 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2002 if (!bstr.isEmpty())
2003 {
2004 if (details == VMINFO_MACHINEREADABLE)
2005 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2006 else
2007 RTPrintf("Product: %ls\n", bstr.raw());
2008 }
2009 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2010 if (!bstr.isEmpty())
2011 {
2012 if (details == VMINFO_MACHINEREADABLE)
2013 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2014 else
2015 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2016 }
2017 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2018 if (!bstr.isEmpty())
2019 {
2020 if (details == VMINFO_MACHINEREADABLE)
2021 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2022 else
2023 RTPrintf("Address: %ls\n", bstr.raw());
2024 }
2025
2026 if (details != VMINFO_MACHINEREADABLE)
2027 RTPrintf("\n");
2028 }
2029 }
2030 }
2031 }
2032 } /* USB */
2033
2034#ifdef VBOX_WITH_PCI_PASSTHROUGH
2035 /* Host PCI passthrough devices */
2036 {
2037 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2038 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2039 if (SUCCEEDED(rc))
2040 {
2041 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2042 {
2043 RTPrintf("\nAttached physical PCI devices:\n\n");
2044 }
2045
2046 for (size_t index = 0; index < assignments.size(); ++index)
2047 {
2048 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2049 char szHostPCIAddress[32], szGuestPCIAddress[32];
2050 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2051 Bstr DevName;
2052
2053 Assignment->COMGETTER(Name)(DevName.asOutParam());
2054 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2055 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2056 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2057 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2058
2059 if (details == VMINFO_MACHINEREADABLE)
2060 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2061 else
2062 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2063 }
2064
2065 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2066 {
2067 RTPrintf("\n");
2068 }
2069 }
2070 }
2071 /* Host PCI passthrough devices */
2072#endif
2073
2074 /*
2075 * Bandwidth groups
2076 */
2077 if (details != VMINFO_MACHINEREADABLE)
2078 RTPrintf("Bandwidth groups: ");
2079 {
2080 ComPtr<IBandwidthControl> bwCtrl;
2081 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2082
2083 rc = showBandwidthGroups(bwCtrl, details);
2084 }
2085
2086
2087 /*
2088 * Shared folders
2089 */
2090 if (details != VMINFO_MACHINEREADABLE)
2091 RTPrintf("Shared folders: ");
2092 uint32_t numSharedFolders = 0;
2093#if 0 // not yet implemented
2094 /* globally shared folders first */
2095 {
2096 SafeIfaceArray <ISharedFolder> sfColl;
2097 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2098 for (size_t i = 0; i < sfColl.size(); ++i)
2099 {
2100 ComPtr<ISharedFolder> sf = sfColl[i];
2101 Bstr name, hostPath;
2102 sf->COMGETTER(Name)(name.asOutParam());
2103 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2104 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2105 ++numSharedFolders;
2106 }
2107 }
2108#endif
2109 /* now VM mappings */
2110 {
2111 com::SafeIfaceArray <ISharedFolder> folders;
2112
2113 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2114
2115 for (size_t i = 0; i < folders.size(); ++i)
2116 {
2117 ComPtr <ISharedFolder> sf = folders[i];
2118
2119 Bstr name, hostPath;
2120 BOOL writable;
2121 sf->COMGETTER(Name)(name.asOutParam());
2122 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2123 sf->COMGETTER(Writable)(&writable);
2124 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2125 RTPrintf("\n\n");
2126 if (details == VMINFO_MACHINEREADABLE)
2127 {
2128 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2129 name.raw());
2130 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2131 hostPath.raw());
2132 }
2133 else
2134 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2135 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2136 ++numSharedFolders;
2137 }
2138 }
2139 /* transient mappings */
2140 if (console)
2141 {
2142 com::SafeIfaceArray <ISharedFolder> folders;
2143
2144 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2145
2146 for (size_t i = 0; i < folders.size(); ++i)
2147 {
2148 ComPtr <ISharedFolder> sf = folders[i];
2149
2150 Bstr name, hostPath;
2151 sf->COMGETTER(Name)(name.asOutParam());
2152 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2153 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2154 RTPrintf("\n\n");
2155 if (details == VMINFO_MACHINEREADABLE)
2156 {
2157 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2158 name.raw());
2159 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2160 hostPath.raw());
2161 }
2162 else
2163 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2164 ++numSharedFolders;
2165 }
2166 }
2167 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2168 RTPrintf("<none>\n");
2169 if (details != VMINFO_MACHINEREADABLE)
2170 RTPrintf("\n");
2171
2172 if (console)
2173 {
2174 /*
2175 * Live VRDE info.
2176 */
2177 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2178 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2179 BOOL Active = FALSE;
2180 ULONG NumberOfClients = 0;
2181 LONG64 BeginTime = 0;
2182 LONG64 EndTime = 0;
2183 LONG64 BytesSent = 0;
2184 LONG64 BytesSentTotal = 0;
2185 LONG64 BytesReceived = 0;
2186 LONG64 BytesReceivedTotal = 0;
2187 Bstr User;
2188 Bstr Domain;
2189 Bstr ClientName;
2190 Bstr ClientIP;
2191 ULONG ClientVersion = 0;
2192 ULONG EncryptionStyle = 0;
2193
2194 if (!vrdeServerInfo.isNull())
2195 {
2196 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2197 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2198 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2199 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2200 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2201 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2202 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2203 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2204 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2205 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2206 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2207 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2208 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2209 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2210 }
2211
2212 if (details == VMINFO_MACHINEREADABLE)
2213 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2214 else
2215 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2216
2217 if (details == VMINFO_MACHINEREADABLE)
2218 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2219 else
2220 RTPrintf("Clients so far: %d\n", NumberOfClients);
2221
2222 if (NumberOfClients > 0)
2223 {
2224 char timestr[128];
2225
2226 if (Active)
2227 {
2228 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2229 if (details == VMINFO_MACHINEREADABLE)
2230 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2231 else
2232 RTPrintf("Start time: %s\n", timestr);
2233 }
2234 else
2235 {
2236 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2237 if (details == VMINFO_MACHINEREADABLE)
2238 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2239 else
2240 RTPrintf("Last started: %s\n", timestr);
2241 makeTimeStr(timestr, sizeof(timestr), EndTime);
2242 if (details == VMINFO_MACHINEREADABLE)
2243 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2244 else
2245 RTPrintf("Last ended: %s\n", timestr);
2246 }
2247
2248 int64_t ThroughputSend = 0;
2249 int64_t ThroughputReceive = 0;
2250 if (EndTime != BeginTime)
2251 {
2252 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2253 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2254 }
2255
2256 if (details == VMINFO_MACHINEREADABLE)
2257 {
2258 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2259 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2260 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2261
2262 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2263 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2264 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2265 }
2266 else
2267 {
2268 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2269 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2270 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2271
2272 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2273 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2274 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2275 }
2276
2277 if (Active)
2278 {
2279 if (details == VMINFO_MACHINEREADABLE)
2280 {
2281 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2282 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2283 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2284 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2285 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2286 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2287 }
2288 else
2289 {
2290 RTPrintf("User name: %ls\n", User.raw());
2291 RTPrintf("Domain: %ls\n", Domain.raw());
2292 RTPrintf("Client name: %ls\n", ClientName.raw());
2293 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2294 RTPrintf("Client version: %d\n", ClientVersion);
2295 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2296 }
2297 }
2298 }
2299
2300 if (details != VMINFO_MACHINEREADABLE)
2301 RTPrintf("\n");
2302 }
2303
2304 {
2305 /* Video capture */
2306 BOOL bActive = FALSE;
2307 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2308 com::SafeArray<BOOL> screens;
2309 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2310 ULONG Width;
2311 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2312 ULONG Height;
2313 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2314 ULONG Rate;
2315 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2316 ULONG Fps;
2317 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2318 Bstr File;
2319 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2320 if (details == VMINFO_MACHINEREADABLE)
2321 {
2322 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2323 RTPrintf("vcpscreens=");
2324 bool fComma = false;
2325 for (unsigned i = 0; i < screens.size(); i++)
2326 if (screens[i])
2327 {
2328 RTPrintf("%s%u", fComma ? "," : "", i);
2329 fComma = true;
2330 }
2331 RTPrintf("\n");
2332 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2333 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2334 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2335 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2336 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2337 }
2338 else
2339 {
2340 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2341 RTPrintf("Capture screens: ");
2342 bool fComma = false;
2343 for (unsigned i = 0; i < screens.size(); i++)
2344 if (screens[i])
2345 {
2346 RTPrintf("%s%u", fComma ? "," : "", i);
2347 fComma = true;
2348 }
2349 RTPrintf("\n");
2350 RTPrintf("Capture file: %ls\n", File.raw());
2351 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2352 RTPrintf("Capture rate: %u kbps\n", Rate);
2353 RTPrintf("Capture FPS: %u\n", Fps);
2354 RTPrintf("\n");
2355 }
2356 }
2357
2358 if ( details == VMINFO_STANDARD
2359 || details == VMINFO_FULL
2360 || details == VMINFO_MACHINEREADABLE)
2361 {
2362 Bstr description;
2363 machine->COMGETTER(Description)(description.asOutParam());
2364 if (!description.isEmpty())
2365 {
2366 if (details == VMINFO_MACHINEREADABLE)
2367 RTPrintf("description=\"%ls\"\n", description.raw());
2368 else
2369 RTPrintf("Description:\n%ls\n", description.raw());
2370 }
2371 }
2372
2373 if (details != VMINFO_MACHINEREADABLE)
2374 RTPrintf("Guest:\n\n");
2375
2376 ULONG guestVal;
2377 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2378 if (SUCCEEDED(rc))
2379 {
2380 if (details == VMINFO_MACHINEREADABLE)
2381 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2382 else
2383 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2384 }
2385
2386 if (console)
2387 {
2388 ComPtr<IGuest> guest;
2389 rc = console->COMGETTER(Guest)(guest.asOutParam());
2390 if (SUCCEEDED(rc) && !guest.isNull())
2391 {
2392 Bstr guestString;
2393 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2394 if ( SUCCEEDED(rc)
2395 && !guestString.isEmpty())
2396 {
2397 if (details == VMINFO_MACHINEREADABLE)
2398 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2399 else
2400 RTPrintf("OS type: %ls\n", guestString.raw());
2401 }
2402
2403 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2404 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2405 if (SUCCEEDED(rc))
2406 {
2407 if (details == VMINFO_MACHINEREADABLE)
2408 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2409 else
2410 RTPrintf("Additions run level: %u\n", guestRunLevel);
2411 }
2412
2413 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2414 if ( SUCCEEDED(rc)
2415 && !guestString.isEmpty())
2416 {
2417 ULONG uRevision;
2418 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2419 if (FAILED(rc))
2420 uRevision = 0;
2421
2422 if (details == VMINFO_MACHINEREADABLE)
2423 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2424 else
2425 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2426 }
2427
2428 if (details != VMINFO_MACHINEREADABLE)
2429 RTPrintf("\nGuest Facilities:\n\n");
2430
2431 /* Print information about known Guest Additions facilities: */
2432 SafeIfaceArray <IAdditionsFacility> collFac;
2433 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2434 LONG64 lLastUpdatedMS;
2435 char szLastUpdated[32];
2436 AdditionsFacilityStatus_T curStatus;
2437 for (size_t index = 0; index < collFac.size(); ++index)
2438 {
2439 ComPtr<IAdditionsFacility> fac = collFac[index];
2440 if (fac)
2441 {
2442 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2443 if (!guestString.isEmpty())
2444 {
2445 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2446 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2447 if (details == VMINFO_MACHINEREADABLE)
2448 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2449 guestString.raw(), curStatus, lLastUpdatedMS);
2450 else
2451 {
2452 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2453 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2454 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2455 }
2456 }
2457 else
2458 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2459 }
2460 else
2461 AssertMsgFailed(("Invalid facility returned!\n"));
2462 }
2463 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2464 RTPrintf("No active facilities.\n");
2465 }
2466 }
2467
2468 if (details != VMINFO_MACHINEREADABLE)
2469 RTPrintf("\n");
2470
2471 /*
2472 * snapshots
2473 */
2474 ComPtr<ISnapshot> snapshot;
2475 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2476 if (SUCCEEDED(rc) && snapshot)
2477 {
2478 ComPtr<ISnapshot> currentSnapshot;
2479 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2480 if (SUCCEEDED(rc))
2481 {
2482 if (details != VMINFO_MACHINEREADABLE)
2483 RTPrintf("Snapshots:\n\n");
2484 showSnapshots(snapshot, currentSnapshot, details);
2485 }
2486 }
2487
2488 if (details != VMINFO_MACHINEREADABLE)
2489 RTPrintf("\n");
2490 return S_OK;
2491}
2492
2493#if defined(_MSC_VER)
2494# pragma optimize("", on)
2495#endif
2496
2497static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2498{
2499 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2500 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2501 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2502 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2503 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2504};
2505
2506int handleShowVMInfo(HandlerArg *a)
2507{
2508 HRESULT rc;
2509 const char *VMNameOrUuid = NULL;
2510 bool fLog = false;
2511 uint32_t uLogIdx = 0;
2512 bool fDetails = false;
2513 bool fMachinereadable = false;
2514
2515 int c;
2516 RTGETOPTUNION ValueUnion;
2517 RTGETOPTSTATE GetState;
2518 // start at 0 because main() has hacked both the argc and argv given to us
2519 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2520 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2521 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2522 {
2523 switch (c)
2524 {
2525 case 'D': // --details
2526 fDetails = true;
2527 break;
2528
2529 case 'M': // --machinereadable
2530 fMachinereadable = true;
2531 break;
2532
2533 case 'l': // --log
2534 fLog = true;
2535 uLogIdx = ValueUnion.u32;
2536 break;
2537
2538 case VINF_GETOPT_NOT_OPTION:
2539 if (!VMNameOrUuid)
2540 VMNameOrUuid = ValueUnion.psz;
2541 else
2542 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2543 break;
2544
2545 default:
2546 if (c > 0)
2547 {
2548 if (RT_C_IS_PRINT(c))
2549 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2550 else
2551 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2552 }
2553 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2554 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2555 else if (ValueUnion.pDef)
2556 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2557 else
2558 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2559 }
2560 }
2561
2562 /* check for required options */
2563 if (!VMNameOrUuid)
2564 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2565
2566 /* try to find the given machine */
2567 ComPtr <IMachine> machine;
2568 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2569 machine.asOutParam()));
2570 if (FAILED(rc))
2571 return 1;
2572
2573 /* Printing the log is exclusive. */
2574 if (fLog && (fMachinereadable || fDetails))
2575 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2576
2577 if (fLog)
2578 {
2579 ULONG64 uOffset = 0;
2580 SafeArray<BYTE> aLogData;
2581 ULONG cbLogData;
2582 while (true)
2583 {
2584 /* Reset the array */
2585 aLogData.setNull();
2586 /* Fetch a chunk of the log file */
2587 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2588 ComSafeArrayAsOutParam(aLogData)));
2589 cbLogData = aLogData.size();
2590 if (cbLogData == 0)
2591 break;
2592 /* aLogData has a platform dependent line ending, standardize on
2593 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2594 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2595 ULONG cbLogDataPrint = cbLogData;
2596 for (BYTE *s = aLogData.raw(), *d = s;
2597 s - aLogData.raw() < (ssize_t)cbLogData;
2598 s++, d++)
2599 {
2600 if (*s == '\r')
2601 {
2602 /* skip over CR, adjust destination */
2603 d--;
2604 cbLogDataPrint--;
2605 }
2606 else if (s != d)
2607 *d = *s;
2608 }
2609 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2610 uOffset += cbLogData;
2611 }
2612 }
2613 else
2614 {
2615 /* 2nd option can be -details or -argdump */
2616 VMINFO_DETAILS details = VMINFO_NONE;
2617 if (fMachinereadable)
2618 details = VMINFO_MACHINEREADABLE;
2619 else if (fDetails)
2620 details = VMINFO_FULL;
2621 else
2622 details = VMINFO_STANDARD;
2623
2624 ComPtr<IConsole> console;
2625
2626 /* open an existing session for the VM */
2627 rc = machine->LockMachine(a->session, LockType_Shared);
2628 if (SUCCEEDED(rc))
2629 /* get the session machine */
2630 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2631 if (SUCCEEDED(rc))
2632 /* get the session console */
2633 rc = a->session->COMGETTER(Console)(console.asOutParam());
2634
2635 rc = showVMInfo(a->virtualBox, machine, details, console);
2636
2637 if (console)
2638 a->session->UnlockMachine();
2639 }
2640
2641 return SUCCEEDED(rc) ? 0 : 1;
2642}
2643
2644#endif /* !VBOX_ONLY_DOCS */
2645/* 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