VirtualBox

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

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

Main/USB: USB Controller implementation rework. Moved filter handling into a separate interface

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