VirtualBox

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

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

Main,Frontends: IDisplay::GetScreenResolution returns the screen origin.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 109.5 KB
Line 
1/* $Id: VBoxManageInfo.cpp 47774 2013-08-15 15:13:01Z 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 LONG xOrigin, yOrigin;
1610 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin);
1611 if (rc == E_ACCESSDENIED)
1612 break; /* VM not powered up */
1613 if (FAILED(rc))
1614 {
1615 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1616 GluePrintErrorInfo(info);
1617 return rc;
1618 }
1619 if (details == VMINFO_MACHINEREADABLE)
1620 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1621 else
1622 RTPrintf("Video mode: %dx%dx%d at %d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1623 }
1624 while (0);
1625 }
1626
1627 /*
1628 * Remote Desktop
1629 */
1630 ComPtr<IVRDEServer> vrdeServer;
1631 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1632 if (SUCCEEDED(rc) && vrdeServer)
1633 {
1634 BOOL fEnabled = false;
1635 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1636 if (fEnabled)
1637 {
1638 LONG currentPort = -1;
1639 Bstr ports;
1640 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1641 Bstr address;
1642 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1643 BOOL fMultiCon;
1644 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1645 BOOL fReuseCon;
1646 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1647 Bstr videoChannel;
1648 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1649 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1650 || (videoChannel == "1");
1651 Bstr videoChannelQuality;
1652 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1653 AuthType_T authType;
1654 const char *strAuthType;
1655 vrdeServer->COMGETTER(AuthType)(&authType);
1656 switch (authType)
1657 {
1658 case AuthType_Null:
1659 strAuthType = "null";
1660 break;
1661 case AuthType_External:
1662 strAuthType = "external";
1663 break;
1664 case AuthType_Guest:
1665 strAuthType = "guest";
1666 break;
1667 default:
1668 strAuthType = "unknown";
1669 break;
1670 }
1671 if (console)
1672 {
1673 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1674 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1675 if (!vrdeServerInfo.isNull())
1676 {
1677 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1678 if (rc == E_ACCESSDENIED)
1679 {
1680 currentPort = -1; /* VM not powered up */
1681 }
1682 if (FAILED(rc))
1683 {
1684 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1685 GluePrintErrorInfo(info);
1686 return rc;
1687 }
1688 }
1689 }
1690 if (details == VMINFO_MACHINEREADABLE)
1691 {
1692 RTPrintf("vrde=\"on\"\n");
1693 RTPrintf("vrdeport=%d\n", currentPort);
1694 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1695 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1696 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1697 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1698 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1699 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1700 if (fVideoChannel)
1701 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1702 }
1703 else
1704 {
1705 if (address.isEmpty())
1706 address = "0.0.0.0";
1707 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);
1708 if (console && currentPort != -1 && currentPort != 0)
1709 RTPrintf("VRDE port: %d\n", currentPort);
1710 if (fVideoChannel)
1711 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1712 else
1713 RTPrintf("Video redirection: disabled\n");
1714 }
1715 com::SafeArray<BSTR> aProperties;
1716 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1717 {
1718 unsigned i;
1719 for (i = 0; i < aProperties.size(); ++i)
1720 {
1721 Bstr value;
1722 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1723 if (details == VMINFO_MACHINEREADABLE)
1724 {
1725 if (value.isEmpty())
1726 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1727 else
1728 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1729 }
1730 else
1731 {
1732 if (value.isEmpty())
1733 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1734 else
1735 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1736 }
1737 }
1738 }
1739 }
1740 else
1741 {
1742 if (details == VMINFO_MACHINEREADABLE)
1743 RTPrintf("vrde=\"off\"\n");
1744 else
1745 RTPrintf("VRDE: disabled\n");
1746 }
1747 }
1748
1749 /*
1750 * USB.
1751 */
1752 SafeIfaceArray<IUSBController> USBCtlColl;
1753 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
1754 if (SUCCEEDED(rc))
1755 {
1756 bool fOhciEnabled = false;
1757 bool fEhciEnabled = false;
1758
1759 for (unsigned i = 0; i < USBCtlColl.size(); i++)
1760 {
1761 USBControllerType_T enmType;
1762
1763 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
1764 if (SUCCEEDED(rc))
1765 {
1766 switch (enmType)
1767 {
1768 case USBControllerType_OHCI:
1769 fOhciEnabled = true;
1770 break;
1771 case USBControllerType_EHCI:
1772 fEhciEnabled = true;
1773 break;
1774 default:
1775 break;
1776 }
1777 }
1778 }
1779
1780 if (details == VMINFO_MACHINEREADABLE)
1781 RTPrintf("usb=\"%s\"\n", fOhciEnabled ? "on" : "off");
1782 else
1783 RTPrintf("USB: %s\n", fOhciEnabled ? "enabled" : "disabled");
1784
1785 if (details == VMINFO_MACHINEREADABLE)
1786 RTPrintf("ehci=\"%s\"\n", fEhciEnabled ? "on" : "off");
1787 else
1788 RTPrintf("EHCI: %s\n", fEhciEnabled ? "enabled" : "disabled");
1789 }
1790
1791 ComPtr<IUSBDeviceFilters> USBFlts;
1792 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
1793 if (SUCCEEDED(rc))
1794 {
1795 SafeIfaceArray <IUSBDeviceFilter> Coll;
1796 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1797 if (SUCCEEDED(rc))
1798 {
1799 if (details != VMINFO_MACHINEREADABLE)
1800 RTPrintf("\nUSB Device Filters:\n\n");
1801
1802 if (Coll.size() == 0)
1803 {
1804 if (details != VMINFO_MACHINEREADABLE)
1805 RTPrintf("<none>\n\n");
1806 }
1807 else
1808 {
1809 for (size_t index = 0; index < Coll.size(); ++index)
1810 {
1811 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1812
1813 /* Query info. */
1814
1815 if (details != VMINFO_MACHINEREADABLE)
1816 RTPrintf("Index: %zu\n", index);
1817
1818 BOOL bActive = FALSE;
1819 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1820 if (details == VMINFO_MACHINEREADABLE)
1821 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1822 else
1823 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1824
1825 Bstr bstr;
1826 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1827 if (details == VMINFO_MACHINEREADABLE)
1828 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1829 else
1830 RTPrintf("Name: %ls\n", bstr.raw());
1831 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1832 if (details == VMINFO_MACHINEREADABLE)
1833 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1834 else
1835 RTPrintf("VendorId: %ls\n", bstr.raw());
1836 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1837 if (details == VMINFO_MACHINEREADABLE)
1838 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
1839 else
1840 RTPrintf("ProductId: %ls\n", bstr.raw());
1841 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1842 if (details == VMINFO_MACHINEREADABLE)
1843 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
1844 else
1845 RTPrintf("Revision: %ls\n", bstr.raw());
1846 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1847 if (details == VMINFO_MACHINEREADABLE)
1848 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1849 else
1850 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1851 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1852 if (details == VMINFO_MACHINEREADABLE)
1853 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1854 else
1855 RTPrintf("Product: %ls\n", bstr.raw());
1856 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1857 if (details == VMINFO_MACHINEREADABLE)
1858 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
1859 else
1860 RTPrintf("Remote: %ls\n", bstr.raw());
1861 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1862 if (details == VMINFO_MACHINEREADABLE)
1863 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1864 else
1865 RTPrintf("Serial Number: %ls\n", bstr.raw());
1866 if (details != VMINFO_MACHINEREADABLE)
1867 {
1868 ULONG fMaskedIfs;
1869 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1870 if (fMaskedIfs)
1871 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1872 RTPrintf("\n");
1873 }
1874 }
1875 }
1876 }
1877
1878 if (console)
1879 {
1880 /* scope */
1881 {
1882 if (details != VMINFO_MACHINEREADABLE)
1883 RTPrintf("Available remote USB devices:\n\n");
1884
1885 SafeIfaceArray <IHostUSBDevice> coll;
1886 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1887
1888 if (coll.size() == 0)
1889 {
1890 if (details != VMINFO_MACHINEREADABLE)
1891 RTPrintf("<none>\n\n");
1892 }
1893 else
1894 {
1895 for (size_t index = 0; index < coll.size(); ++index)
1896 {
1897 ComPtr <IHostUSBDevice> dev = coll[index];
1898
1899 /* Query info. */
1900 Bstr id;
1901 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1902 USHORT usVendorId;
1903 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1904 USHORT usProductId;
1905 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1906 USHORT bcdRevision;
1907 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1908
1909 if (details == VMINFO_MACHINEREADABLE)
1910 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
1911 "USBRemoteVendorId%zu=\"%#06x\"\n"
1912 "USBRemoteProductId%zu=\"%#06x\"\n"
1913 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1914 index + 1, Utf8Str(id).c_str(),
1915 index + 1, usVendorId,
1916 index + 1, usProductId,
1917 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1918 else
1919 RTPrintf("UUID: %s\n"
1920 "VendorId: %#06x (%04X)\n"
1921 "ProductId: %#06x (%04X)\n"
1922 "Revision: %u.%u (%02u%02u)\n",
1923 Utf8Str(id).c_str(),
1924 usVendorId, usVendorId, usProductId, usProductId,
1925 bcdRevision >> 8, bcdRevision & 0xff,
1926 bcdRevision >> 8, bcdRevision & 0xff);
1927
1928 /* optional stuff. */
1929 Bstr bstr;
1930 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1931 if (!bstr.isEmpty())
1932 {
1933 if (details == VMINFO_MACHINEREADABLE)
1934 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1935 else
1936 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1937 }
1938 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1939 if (!bstr.isEmpty())
1940 {
1941 if (details == VMINFO_MACHINEREADABLE)
1942 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1943 else
1944 RTPrintf("Product: %ls\n", bstr.raw());
1945 }
1946 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1947 if (!bstr.isEmpty())
1948 {
1949 if (details == VMINFO_MACHINEREADABLE)
1950 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1951 else
1952 RTPrintf("SerialNumber: %ls\n", bstr.raw());
1953 }
1954 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1955 if (!bstr.isEmpty())
1956 {
1957 if (details == VMINFO_MACHINEREADABLE)
1958 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
1959 else
1960 RTPrintf("Address: %ls\n", bstr.raw());
1961 }
1962
1963 if (details != VMINFO_MACHINEREADABLE)
1964 RTPrintf("\n");
1965 }
1966 }
1967 }
1968
1969 /* scope */
1970 {
1971 if (details != VMINFO_MACHINEREADABLE)
1972 RTPrintf("Currently Attached USB Devices:\n\n");
1973
1974 SafeIfaceArray <IUSBDevice> coll;
1975 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1976
1977 if (coll.size() == 0)
1978 {
1979 if (details != VMINFO_MACHINEREADABLE)
1980 RTPrintf("<none>\n\n");
1981 }
1982 else
1983 {
1984 for (size_t index = 0; index < coll.size(); ++index)
1985 {
1986 ComPtr <IUSBDevice> dev = coll[index];
1987
1988 /* Query info. */
1989 Bstr id;
1990 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1991 USHORT usVendorId;
1992 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1993 USHORT usProductId;
1994 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1995 USHORT bcdRevision;
1996 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1997
1998 if (details == VMINFO_MACHINEREADABLE)
1999 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
2000 "USBAttachedVendorId%zu=\"%#06x\"\n"
2001 "USBAttachedProductId%zu=\"%#06x\"\n"
2002 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
2003 index + 1, Utf8Str(id).c_str(),
2004 index + 1, usVendorId,
2005 index + 1, usProductId,
2006 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2007 else
2008 RTPrintf("UUID: %s\n"
2009 "VendorId: %#06x (%04X)\n"
2010 "ProductId: %#06x (%04X)\n"
2011 "Revision: %u.%u (%02u%02u)\n",
2012 Utf8Str(id).c_str(),
2013 usVendorId, usVendorId, usProductId, usProductId,
2014 bcdRevision >> 8, bcdRevision & 0xff,
2015 bcdRevision >> 8, bcdRevision & 0xff);
2016
2017 /* optional stuff. */
2018 Bstr bstr;
2019 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2020 if (!bstr.isEmpty())
2021 {
2022 if (details == VMINFO_MACHINEREADABLE)
2023 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2024 else
2025 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2026 }
2027 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2028 if (!bstr.isEmpty())
2029 {
2030 if (details == VMINFO_MACHINEREADABLE)
2031 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2032 else
2033 RTPrintf("Product: %ls\n", bstr.raw());
2034 }
2035 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2036 if (!bstr.isEmpty())
2037 {
2038 if (details == VMINFO_MACHINEREADABLE)
2039 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2040 else
2041 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2042 }
2043 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2044 if (!bstr.isEmpty())
2045 {
2046 if (details == VMINFO_MACHINEREADABLE)
2047 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2048 else
2049 RTPrintf("Address: %ls\n", bstr.raw());
2050 }
2051
2052 if (details != VMINFO_MACHINEREADABLE)
2053 RTPrintf("\n");
2054 }
2055 }
2056 }
2057 }
2058 } /* USB */
2059
2060#ifdef VBOX_WITH_PCI_PASSTHROUGH
2061 /* Host PCI passthrough devices */
2062 {
2063 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2064 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2065 if (SUCCEEDED(rc))
2066 {
2067 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2068 {
2069 RTPrintf("\nAttached physical PCI devices:\n\n");
2070 }
2071
2072 for (size_t index = 0; index < assignments.size(); ++index)
2073 {
2074 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2075 char szHostPCIAddress[32], szGuestPCIAddress[32];
2076 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2077 Bstr DevName;
2078
2079 Assignment->COMGETTER(Name)(DevName.asOutParam());
2080 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2081 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2082 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2083 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2084
2085 if (details == VMINFO_MACHINEREADABLE)
2086 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2087 else
2088 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2089 }
2090
2091 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2092 {
2093 RTPrintf("\n");
2094 }
2095 }
2096 }
2097 /* Host PCI passthrough devices */
2098#endif
2099
2100 /*
2101 * Bandwidth groups
2102 */
2103 if (details != VMINFO_MACHINEREADABLE)
2104 RTPrintf("Bandwidth groups: ");
2105 {
2106 ComPtr<IBandwidthControl> bwCtrl;
2107 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2108
2109 rc = showBandwidthGroups(bwCtrl, details);
2110 }
2111
2112
2113 /*
2114 * Shared folders
2115 */
2116 if (details != VMINFO_MACHINEREADABLE)
2117 RTPrintf("Shared folders: ");
2118 uint32_t numSharedFolders = 0;
2119#if 0 // not yet implemented
2120 /* globally shared folders first */
2121 {
2122 SafeIfaceArray <ISharedFolder> sfColl;
2123 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2124 for (size_t i = 0; i < sfColl.size(); ++i)
2125 {
2126 ComPtr<ISharedFolder> sf = sfColl[i];
2127 Bstr name, hostPath;
2128 sf->COMGETTER(Name)(name.asOutParam());
2129 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2130 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2131 ++numSharedFolders;
2132 }
2133 }
2134#endif
2135 /* now VM mappings */
2136 {
2137 com::SafeIfaceArray <ISharedFolder> folders;
2138
2139 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2140
2141 for (size_t i = 0; i < folders.size(); ++i)
2142 {
2143 ComPtr <ISharedFolder> sf = folders[i];
2144
2145 Bstr name, hostPath;
2146 BOOL writable;
2147 sf->COMGETTER(Name)(name.asOutParam());
2148 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2149 sf->COMGETTER(Writable)(&writable);
2150 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2151 RTPrintf("\n\n");
2152 if (details == VMINFO_MACHINEREADABLE)
2153 {
2154 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2155 name.raw());
2156 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2157 hostPath.raw());
2158 }
2159 else
2160 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2161 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2162 ++numSharedFolders;
2163 }
2164 }
2165 /* transient mappings */
2166 if (console)
2167 {
2168 com::SafeIfaceArray <ISharedFolder> folders;
2169
2170 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2171
2172 for (size_t i = 0; i < folders.size(); ++i)
2173 {
2174 ComPtr <ISharedFolder> sf = folders[i];
2175
2176 Bstr name, hostPath;
2177 sf->COMGETTER(Name)(name.asOutParam());
2178 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2179 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2180 RTPrintf("\n\n");
2181 if (details == VMINFO_MACHINEREADABLE)
2182 {
2183 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2184 name.raw());
2185 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2186 hostPath.raw());
2187 }
2188 else
2189 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2190 ++numSharedFolders;
2191 }
2192 }
2193 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2194 RTPrintf("<none>\n");
2195 if (details != VMINFO_MACHINEREADABLE)
2196 RTPrintf("\n");
2197
2198 if (console)
2199 {
2200 /*
2201 * Live VRDE info.
2202 */
2203 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2204 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2205 BOOL Active = FALSE;
2206 ULONG NumberOfClients = 0;
2207 LONG64 BeginTime = 0;
2208 LONG64 EndTime = 0;
2209 LONG64 BytesSent = 0;
2210 LONG64 BytesSentTotal = 0;
2211 LONG64 BytesReceived = 0;
2212 LONG64 BytesReceivedTotal = 0;
2213 Bstr User;
2214 Bstr Domain;
2215 Bstr ClientName;
2216 Bstr ClientIP;
2217 ULONG ClientVersion = 0;
2218 ULONG EncryptionStyle = 0;
2219
2220 if (!vrdeServerInfo.isNull())
2221 {
2222 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2223 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2224 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2225 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2226 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2227 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2228 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2229 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2230 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2231 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2232 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2233 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2234 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2235 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2236 }
2237
2238 if (details == VMINFO_MACHINEREADABLE)
2239 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2240 else
2241 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2242
2243 if (details == VMINFO_MACHINEREADABLE)
2244 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2245 else
2246 RTPrintf("Clients so far: %d\n", NumberOfClients);
2247
2248 if (NumberOfClients > 0)
2249 {
2250 char timestr[128];
2251
2252 if (Active)
2253 {
2254 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2255 if (details == VMINFO_MACHINEREADABLE)
2256 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2257 else
2258 RTPrintf("Start time: %s\n", timestr);
2259 }
2260 else
2261 {
2262 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2263 if (details == VMINFO_MACHINEREADABLE)
2264 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2265 else
2266 RTPrintf("Last started: %s\n", timestr);
2267 makeTimeStr(timestr, sizeof(timestr), EndTime);
2268 if (details == VMINFO_MACHINEREADABLE)
2269 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2270 else
2271 RTPrintf("Last ended: %s\n", timestr);
2272 }
2273
2274 int64_t ThroughputSend = 0;
2275 int64_t ThroughputReceive = 0;
2276 if (EndTime != BeginTime)
2277 {
2278 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2279 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2280 }
2281
2282 if (details == VMINFO_MACHINEREADABLE)
2283 {
2284 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2285 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2286 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2287
2288 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2289 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2290 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2291 }
2292 else
2293 {
2294 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2295 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2296 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2297
2298 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2299 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2300 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2301 }
2302
2303 if (Active)
2304 {
2305 if (details == VMINFO_MACHINEREADABLE)
2306 {
2307 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2308 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2309 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2310 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2311 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2312 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2313 }
2314 else
2315 {
2316 RTPrintf("User name: %ls\n", User.raw());
2317 RTPrintf("Domain: %ls\n", Domain.raw());
2318 RTPrintf("Client name: %ls\n", ClientName.raw());
2319 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2320 RTPrintf("Client version: %d\n", ClientVersion);
2321 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2322 }
2323 }
2324 }
2325
2326 if (details != VMINFO_MACHINEREADABLE)
2327 RTPrintf("\n");
2328 }
2329
2330 {
2331 /* Video capture */
2332 BOOL bActive = FALSE;
2333 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2334 com::SafeArray<BOOL> screens;
2335 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2336 ULONG Width;
2337 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2338 ULONG Height;
2339 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2340 ULONG Rate;
2341 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2342 ULONG Fps;
2343 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2344 Bstr File;
2345 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2346 if (details == VMINFO_MACHINEREADABLE)
2347 {
2348 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2349 RTPrintf("vcpscreens=");
2350 bool fComma = false;
2351 for (unsigned i = 0; i < screens.size(); i++)
2352 if (screens[i])
2353 {
2354 RTPrintf("%s%u", fComma ? "," : "", i);
2355 fComma = true;
2356 }
2357 RTPrintf("\n");
2358 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2359 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2360 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2361 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2362 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2363 }
2364 else
2365 {
2366 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2367 RTPrintf("Capture screens: ");
2368 bool fComma = false;
2369 for (unsigned i = 0; i < screens.size(); i++)
2370 if (screens[i])
2371 {
2372 RTPrintf("%s%u", fComma ? "," : "", i);
2373 fComma = true;
2374 }
2375 RTPrintf("\n");
2376 RTPrintf("Capture file: %ls\n", File.raw());
2377 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2378 RTPrintf("Capture rate: %u kbps\n", Rate);
2379 RTPrintf("Capture FPS: %u\n", Fps);
2380 RTPrintf("\n");
2381 }
2382 }
2383
2384 if ( details == VMINFO_STANDARD
2385 || details == VMINFO_FULL
2386 || details == VMINFO_MACHINEREADABLE)
2387 {
2388 Bstr description;
2389 machine->COMGETTER(Description)(description.asOutParam());
2390 if (!description.isEmpty())
2391 {
2392 if (details == VMINFO_MACHINEREADABLE)
2393 RTPrintf("description=\"%ls\"\n", description.raw());
2394 else
2395 RTPrintf("Description:\n%ls\n", description.raw());
2396 }
2397 }
2398
2399 if (details != VMINFO_MACHINEREADABLE)
2400 RTPrintf("Guest:\n\n");
2401
2402 ULONG guestVal;
2403 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2404 if (SUCCEEDED(rc))
2405 {
2406 if (details == VMINFO_MACHINEREADABLE)
2407 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2408 else
2409 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2410 }
2411
2412 if (console)
2413 {
2414 ComPtr<IGuest> guest;
2415 rc = console->COMGETTER(Guest)(guest.asOutParam());
2416 if (SUCCEEDED(rc) && !guest.isNull())
2417 {
2418 Bstr guestString;
2419 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2420 if ( SUCCEEDED(rc)
2421 && !guestString.isEmpty())
2422 {
2423 if (details == VMINFO_MACHINEREADABLE)
2424 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2425 else
2426 RTPrintf("OS type: %ls\n", guestString.raw());
2427 }
2428
2429 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2430 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2431 if (SUCCEEDED(rc))
2432 {
2433 if (details == VMINFO_MACHINEREADABLE)
2434 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2435 else
2436 RTPrintf("Additions run level: %u\n", guestRunLevel);
2437 }
2438
2439 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2440 if ( SUCCEEDED(rc)
2441 && !guestString.isEmpty())
2442 {
2443 ULONG uRevision;
2444 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2445 if (FAILED(rc))
2446 uRevision = 0;
2447
2448 if (details == VMINFO_MACHINEREADABLE)
2449 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2450 else
2451 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2452 }
2453
2454 if (details != VMINFO_MACHINEREADABLE)
2455 RTPrintf("\nGuest Facilities:\n\n");
2456
2457 /* Print information about known Guest Additions facilities: */
2458 SafeIfaceArray <IAdditionsFacility> collFac;
2459 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2460 LONG64 lLastUpdatedMS;
2461 char szLastUpdated[32];
2462 AdditionsFacilityStatus_T curStatus;
2463 for (size_t index = 0; index < collFac.size(); ++index)
2464 {
2465 ComPtr<IAdditionsFacility> fac = collFac[index];
2466 if (fac)
2467 {
2468 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2469 if (!guestString.isEmpty())
2470 {
2471 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2472 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2473 if (details == VMINFO_MACHINEREADABLE)
2474 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2475 guestString.raw(), curStatus, lLastUpdatedMS);
2476 else
2477 {
2478 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2479 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2480 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2481 }
2482 }
2483 else
2484 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2485 }
2486 else
2487 AssertMsgFailed(("Invalid facility returned!\n"));
2488 }
2489 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2490 RTPrintf("No active facilities.\n");
2491 }
2492 }
2493
2494 if (details != VMINFO_MACHINEREADABLE)
2495 RTPrintf("\n");
2496
2497 /*
2498 * snapshots
2499 */
2500 ComPtr<ISnapshot> snapshot;
2501 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2502 if (SUCCEEDED(rc) && snapshot)
2503 {
2504 ComPtr<ISnapshot> currentSnapshot;
2505 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2506 if (SUCCEEDED(rc))
2507 {
2508 if (details != VMINFO_MACHINEREADABLE)
2509 RTPrintf("Snapshots:\n\n");
2510 showSnapshots(snapshot, currentSnapshot, details);
2511 }
2512 }
2513
2514 if (details != VMINFO_MACHINEREADABLE)
2515 RTPrintf("\n");
2516 return S_OK;
2517}
2518
2519#if defined(_MSC_VER)
2520# pragma optimize("", on)
2521#endif
2522
2523static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2524{
2525 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2526 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2527 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2528 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2529 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2530};
2531
2532int handleShowVMInfo(HandlerArg *a)
2533{
2534 HRESULT rc;
2535 const char *VMNameOrUuid = NULL;
2536 bool fLog = false;
2537 uint32_t uLogIdx = 0;
2538 bool fDetails = false;
2539 bool fMachinereadable = false;
2540
2541 int c;
2542 RTGETOPTUNION ValueUnion;
2543 RTGETOPTSTATE GetState;
2544 // start at 0 because main() has hacked both the argc and argv given to us
2545 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2546 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2547 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2548 {
2549 switch (c)
2550 {
2551 case 'D': // --details
2552 fDetails = true;
2553 break;
2554
2555 case 'M': // --machinereadable
2556 fMachinereadable = true;
2557 break;
2558
2559 case 'l': // --log
2560 fLog = true;
2561 uLogIdx = ValueUnion.u32;
2562 break;
2563
2564 case VINF_GETOPT_NOT_OPTION:
2565 if (!VMNameOrUuid)
2566 VMNameOrUuid = ValueUnion.psz;
2567 else
2568 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2569 break;
2570
2571 default:
2572 if (c > 0)
2573 {
2574 if (RT_C_IS_PRINT(c))
2575 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2576 else
2577 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2578 }
2579 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2580 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2581 else if (ValueUnion.pDef)
2582 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2583 else
2584 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2585 }
2586 }
2587
2588 /* check for required options */
2589 if (!VMNameOrUuid)
2590 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2591
2592 /* try to find the given machine */
2593 ComPtr <IMachine> machine;
2594 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2595 machine.asOutParam()));
2596 if (FAILED(rc))
2597 return 1;
2598
2599 /* Printing the log is exclusive. */
2600 if (fLog && (fMachinereadable || fDetails))
2601 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2602
2603 if (fLog)
2604 {
2605 ULONG64 uOffset = 0;
2606 SafeArray<BYTE> aLogData;
2607 ULONG cbLogData;
2608 while (true)
2609 {
2610 /* Reset the array */
2611 aLogData.setNull();
2612 /* Fetch a chunk of the log file */
2613 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2614 ComSafeArrayAsOutParam(aLogData)));
2615 cbLogData = aLogData.size();
2616 if (cbLogData == 0)
2617 break;
2618 /* aLogData has a platform dependent line ending, standardize on
2619 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2620 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2621 ULONG cbLogDataPrint = cbLogData;
2622 for (BYTE *s = aLogData.raw(), *d = s;
2623 s - aLogData.raw() < (ssize_t)cbLogData;
2624 s++, d++)
2625 {
2626 if (*s == '\r')
2627 {
2628 /* skip over CR, adjust destination */
2629 d--;
2630 cbLogDataPrint--;
2631 }
2632 else if (s != d)
2633 *d = *s;
2634 }
2635 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2636 uOffset += cbLogData;
2637 }
2638 }
2639 else
2640 {
2641 /* 2nd option can be -details or -argdump */
2642 VMINFO_DETAILS details = VMINFO_NONE;
2643 if (fMachinereadable)
2644 details = VMINFO_MACHINEREADABLE;
2645 else if (fDetails)
2646 details = VMINFO_FULL;
2647 else
2648 details = VMINFO_STANDARD;
2649
2650 ComPtr<IConsole> console;
2651
2652 /* open an existing session for the VM */
2653 rc = machine->LockMachine(a->session, LockType_Shared);
2654 if (SUCCEEDED(rc))
2655 /* get the session machine */
2656 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2657 if (SUCCEEDED(rc))
2658 /* get the session console */
2659 rc = a->session->COMGETTER(Console)(console.asOutParam());
2660
2661 rc = showVMInfo(a->virtualBox, machine, details, console);
2662
2663 if (console)
2664 a->session->UnlockMachine();
2665 }
2666
2667 return SUCCEEDED(rc) ? 0 : 1;
2668}
2669
2670#endif /* !VBOX_ONLY_DOCS */
2671/* 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