VirtualBox

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

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

VBoxManage: split 'guestcontrol' help into sub categories

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 110.2 KB
Line 
1/* $Id: VBoxManageInfo.cpp 49621 2013-11-22 11:15:41Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'showvminfo' command and helper routines.
4 */
5
6/*
7 * Copyright (C) 2006-2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_ONLY_DOCS
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <VBox/com/com.h>
24#include <VBox/com/string.h>
25#include <VBox/com/Guid.h>
26#include <VBox/com/array.h>
27#include <VBox/com/ErrorInfo.h>
28#include <VBox/com/errorprint.h>
29
30#include <VBox/com/VirtualBox.h>
31
32#ifdef VBOX_WITH_PCI_PASSTHROUGH
33#include <VBox/pci.h>
34#endif
35
36#include <VBox/log.h>
37#include <iprt/stream.h>
38#include <iprt/time.h>
39#include <iprt/string.h>
40#include <iprt/getopt.h>
41#include <iprt/ctype.h>
42
43#include "VBoxManage.h"
44using namespace com;
45
46
47// funcs
48///////////////////////////////////////////////////////////////////////////////
49
50HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
51 ComPtr<ISnapshot> &currentSnapshot,
52 VMINFO_DETAILS details,
53 const Utf8Str &prefix /* = ""*/,
54 int level /*= 0*/)
55{
56 /* start with the root */
57 Bstr name;
58 Bstr uuid;
59 Bstr description;
60 CHECK_ERROR2_RET(rootSnapshot, COMGETTER(Name)(name.asOutParam()), hrcCheck);
61 CHECK_ERROR2_RET(rootSnapshot, COMGETTER(Id)(uuid.asOutParam()), hrcCheck);
62 CHECK_ERROR2_RET(rootSnapshot, COMGETTER(Description)(description.asOutParam()), hrcCheck);
63 bool fCurrent = (rootSnapshot == currentSnapshot);
64 if (details == VMINFO_MACHINEREADABLE)
65 {
66 /* print with hierarchical numbering */
67 RTPrintf("SnapshotName%s=\"%ls\"\n", prefix.c_str(), name.raw());
68 RTPrintf("SnapshotUUID%s=\"%s\"\n", prefix.c_str(), Utf8Str(uuid).c_str());
69 if (!description.isEmpty())
70 RTPrintf("SnapshotDescription%s=\"%ls\"\n", prefix.c_str(), description.raw());
71 if (fCurrent)
72 {
73 RTPrintf("CurrentSnapshotName=\"%ls\"\n", name.raw());
74 RTPrintf("CurrentSnapshotUUID=\"%s\"\n", Utf8Str(uuid).c_str());
75 RTPrintf("CurrentSnapshotNode=\"SnapshotName%s\"\n", prefix.c_str());
76 }
77 }
78 else
79 {
80 /* print with indentation */
81 RTPrintf(" %sName: %ls (UUID: %s)%s\n",
82 prefix.c_str(),
83 name.raw(),
84 Utf8Str(uuid).c_str(),
85 (fCurrent) ? " *" : "");
86 if (!description.isEmpty())
87 RTPrintf(" %sDescription:\n%ls\n", prefix.c_str(), description.raw());
88 }
89
90 /* get the children */
91 HRESULT hrc = S_OK;
92 SafeIfaceArray <ISnapshot> coll;
93 CHECK_ERROR2_RET(rootSnapshot,COMGETTER(Children)(ComSafeArrayAsOutParam(coll)), hrcCheck);
94 if (!coll.isNull())
95 {
96 for (size_t index = 0; index < coll.size(); ++index)
97 {
98 ComPtr<ISnapshot> snapshot = coll[index];
99 if (snapshot)
100 {
101 Utf8Str newPrefix;
102 if (details == VMINFO_MACHINEREADABLE)
103 newPrefix = Utf8StrFmt("%s-%d", prefix.c_str(), index + 1);
104 else
105 {
106 newPrefix = Utf8StrFmt("%s ", prefix.c_str());
107 }
108
109 /* recursive call */
110 HRESULT hrc2 = showSnapshots(snapshot, currentSnapshot, details, newPrefix, level + 1);
111 if (FAILED(hrc2))
112 hrc = hrc2;
113 }
114 }
115 }
116 return hrc;
117}
118
119static void makeTimeStr(char *s, int cb, int64_t millies)
120{
121 RTTIME t;
122 RTTIMESPEC ts;
123
124 RTTimeSpecSetMilli(&ts, millies);
125
126 RTTimeExplode(&t, &ts);
127
128 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
129 t.i32Year, t.u8Month, t.u8MonthDay,
130 t.u8Hour, t.u8Minute, t.u8Second);
131}
132
133const char *machineStateToName(MachineState_T machineState, bool fShort)
134{
135 switch (machineState)
136 {
137 case MachineState_PoweredOff:
138 return fShort ? "poweroff" : "powered off";
139 case MachineState_Saved:
140 return "saved";
141 case MachineState_Aborted:
142 return "aborted";
143 case MachineState_Teleported:
144 return "teleported";
145 case MachineState_Running:
146 return "running";
147 case MachineState_Paused:
148 return "paused";
149 case MachineState_Stuck:
150 return fShort ? "gurumeditation" : "guru meditation";
151 case MachineState_LiveSnapshotting:
152 return fShort ? "livesnapshotting" : "live snapshotting";
153 case MachineState_Teleporting:
154 return "teleporting";
155 case MachineState_Starting:
156 return "starting";
157 case MachineState_Stopping:
158 return "stopping";
159 case MachineState_Saving:
160 return "saving";
161 case MachineState_Restoring:
162 return "restoring";
163 case MachineState_TeleportingPausedVM:
164 return fShort ? "teleportingpausedvm" : "teleporting paused vm";
165 case MachineState_TeleportingIn:
166 return fShort ? "teleportingin" : "teleporting (incoming)";
167 case MachineState_RestoringSnapshot:
168 return fShort ? "restoringsnapshot" : "restoring snapshot";
169 case MachineState_DeletingSnapshot:
170 return fShort ? "deletingsnapshot" : "deleting snapshot";
171 case MachineState_DeletingSnapshotOnline:
172 return fShort ? "deletingsnapshotlive" : "deleting snapshot live";
173 case MachineState_DeletingSnapshotPaused:
174 return fShort ? "deletingsnapshotlivepaused" : "deleting snapshot live paused";
175 case MachineState_SettingUp:
176 return fShort ? "settingup" : "setting up";
177 default:
178 break;
179 }
180 return "unknown";
181}
182
183const char *facilityStateToName(AdditionsFacilityStatus_T faStatus, bool fShort)
184{
185 switch (faStatus)
186 {
187 case AdditionsFacilityStatus_Inactive:
188 return fShort ? "inactive" : "not active";
189 case AdditionsFacilityStatus_Paused:
190 return "paused";
191 case AdditionsFacilityStatus_PreInit:
192 return fShort ? "preinit" : "pre-initializing";
193 case AdditionsFacilityStatus_Init:
194 return fShort ? "init" : "initializing";
195 case AdditionsFacilityStatus_Active:
196 return fShort ? "active" : "active/running";
197 case AdditionsFacilityStatus_Terminating:
198 return "terminating";
199 case AdditionsFacilityStatus_Terminated:
200 return "terminated";
201 case AdditionsFacilityStatus_Failed:
202 return "failed";
203 case AdditionsFacilityStatus_Unknown:
204 default:
205 break;
206 }
207 return "unknown";
208}
209
210/**
211 * This takes care of escaping double quotes and slashes that the string might
212 * contain.
213 *
214 * @param pszName The variable name.
215 * @param pbstrValue The value.
216 */
217static void outputMachineReadableString(const char *pszName, Bstr const *pbstrValue)
218{
219 Assert(strpbrk(pszName, "\"\\") == NULL);
220
221 com::Utf8Str strValue(*pbstrValue);
222 if ( strValue.isEmpty()
223 || ( !strValue.count('"')
224 && !strValue.count('\\')))
225 RTPrintf("%s=\"%s\"\n", pszName, strValue.c_str());
226 else
227 {
228 /* The value needs escaping. */
229 RTPrintf("%s=\"", pszName);
230 const char *psz = strValue.c_str();
231 for (;;)
232 {
233 const char *pszNext = strpbrk(psz, "\"\\");
234 if (!pszNext)
235 {
236 RTPrintf("%s", psz);
237 break;
238 }
239 RTPrintf("%.*s\\%c", pszNext - psz, psz, *pszNext);
240 psz = pszNext + 1;
241 }
242 RTPrintf("\"\n");
243 }
244}
245
246/**
247 * Converts bandwidth group type to a string.
248 * @returns String representation.
249 * @param enmType Bandwidth control group type.
250 */
251inline const char * bwGroupTypeToString(BandwidthGroupType_T enmType)
252{
253 switch (enmType)
254 {
255 case BandwidthGroupType_Disk: return "Disk";
256 case BandwidthGroupType_Network: return "Network";
257 }
258 return "unknown";
259}
260
261HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
262 VMINFO_DETAILS details)
263{
264 int rc = S_OK;
265 SafeIfaceArray<IBandwidthGroup> bwGroups;
266
267 CHECK_ERROR_RET(bwCtrl, GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)), rc);
268
269 if (bwGroups.size() && details != VMINFO_MACHINEREADABLE)
270 RTPrintf("\n\n");
271 for (size_t i = 0; i < bwGroups.size(); i++)
272 {
273 Bstr strName;
274 LONG64 cMaxBytesPerSec;
275 BandwidthGroupType_T enmType;
276
277 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), rc);
278 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Type)(&enmType), rc);
279 CHECK_ERROR_RET(bwGroups[i], COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec), rc);
280
281 const char *pszType = bwGroupTypeToString(enmType);
282 if (details == VMINFO_MACHINEREADABLE)
283 RTPrintf("BandwidthGroup%zu=%ls,%s,%lld\n", i, strName.raw(), pszType, cMaxBytesPerSec);
284 else
285 {
286 const char *pszUnits = "";
287 LONG64 cBytes = cMaxBytesPerSec;
288 if (cBytes == 0)
289 {
290 RTPrintf("Name: '%ls', Type: %s, Limit: none (disabled)\n", strName.raw(), pszType);
291 continue;
292 }
293 else if (!(cBytes % _1G))
294 {
295 pszUnits = "G";
296 cBytes /= _1G;
297 }
298 else if (!(cBytes % _1M))
299 {
300 pszUnits = "M";
301 cBytes /= _1M;
302 }
303 else if (!(cBytes % _1K))
304 {
305 pszUnits = "K";
306 cBytes /= _1K;
307 }
308 const char *pszNetUnits = NULL;
309 if (enmType == BandwidthGroupType_Network)
310 {
311 /*
312 * We want to report network rate limit in bits/s, not bytes.
313 * Only if it cannot be express it in kilobits we will fall
314 * back to reporting it in bytes.
315 */
316 LONG64 cBits = cMaxBytesPerSec;
317 if (!(cBits % 125))
318 {
319 cBits /= 125;
320 pszNetUnits = "k";
321 if (!(cBits % 1000000))
322 {
323 cBits /= 1000000;
324 pszNetUnits = "g";
325 }
326 else if (!(cBits % 1000))
327 {
328 cBits /= 1000;
329 pszNetUnits = "m";
330 }
331 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbits/sec (%lld %sbytes/sec)\n", strName.raw(), pszType, cBits, pszNetUnits, cBytes, pszUnits);
332 }
333 }
334 if (!pszNetUnits)
335 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbytes/sec\n", strName.raw(), pszType, cBytes, pszUnits);
336 }
337 }
338 if (details != VMINFO_MACHINEREADABLE)
339 RTPrintf(bwGroups.size() != 0 ? "\n" : "<none>\n\n");
340
341 return rc;
342}
343
344
345/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
346 time. MSC 7.1/32 doesn't have quite as much trouble with it, but still
347 sufficient to qualify for this hack as well since this code isn't performance
348 critical and probably won't gain much from the extra optimizing in real life. */
349#if defined(_MSC_VER)
350# pragma optimize("g", off)
351#endif
352
353HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
354 ComPtr<IMachine> machine,
355 VMINFO_DETAILS details /*= VMINFO_NONE*/,
356 ComPtr<IConsole> console /*= ComPtr<IConsole> ()*/)
357{
358 HRESULT rc;
359
360#define SHOW_BOOLEAN_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
361 SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_szMachine, a_szHuman, "on", "off")
362
363#define SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szTrue, a_szFalse) \
364 do \
365 { \
366 BOOL f; \
367 CHECK_ERROR2_RET(a_pObj, COMGETTER(a_Prop)(&f), hrcCheck); \
368 if (details == VMINFO_MACHINEREADABLE) \
369 RTPrintf( a_szMachine "=\"%s\"\n", f ? "on" : "off"); \
370 else \
371 RTPrintf("%-16s %s\n", a_szHuman ":", f ? a_szTrue : a_szFalse); \
372 } while (0)
373
374#define SHOW_BOOLEAN_METHOD(a_pObj, a_Invocation, a_szMachine, a_szHuman) \
375 do \
376 { \
377 BOOL f; \
378 CHECK_ERROR2_RET(a_pObj, a_Invocation, hrcCheck); \
379 if (details == VMINFO_MACHINEREADABLE) \
380 RTPrintf( a_szMachine "=\"%s\"\n", f ? "on" : "off"); \
381 else \
382 RTPrintf("%-16s %s\n", a_szHuman ":", f ? "on" : "off"); \
383 } while (0)
384
385#define SHOW_STRING_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
386 do \
387 { \
388 Bstr bstr; \
389 CHECK_ERROR2_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
390 if (details == VMINFO_MACHINEREADABLE) \
391 outputMachineReadableString(a_szMachine, &bstr); \
392 else \
393 RTPrintf("%-16s %ls\n", a_szHuman ":", bstr.raw()); \
394 } while (0)
395
396#define SHOW_STRINGARRAY_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
397 do \
398 { \
399 SafeArray<BSTR> array; \
400 CHECK_ERROR2_RET(a_pObj, COMGETTER(a_Prop)(ComSafeArrayAsOutParam(array)), hrcCheck); \
401 Utf8Str str; \
402 for (size_t i = 0; i < array.size(); i++) \
403 { \
404 if (i != 0) \
405 str.append(","); \
406 str.append(Utf8Str(array[i]).c_str()); \
407 } \
408 Bstr bstr(str); \
409 if (details == VMINFO_MACHINEREADABLE) \
410 outputMachineReadableString(a_szMachine, &bstr); \
411 else \
412 RTPrintf("%-16s %ls\n", a_szHuman ":", bstr.raw()); \
413 } while (0)
414
415#define SHOW_UUID_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman) \
416 SHOW_STRING_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman)
417
418#define SHOW_ULONG_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szUnit) \
419 do \
420 { \
421 ULONG u32; \
422 CHECK_ERROR2_RET(a_pObj, COMGETTER(a_Prop)(&u32), hrcCheck); \
423 if (details == VMINFO_MACHINEREADABLE) \
424 RTPrintf(a_szMachine "=%u\n", u32); \
425 else \
426 RTPrintf("%-16s %u" a_szUnit "\n", a_szHuman ":", u32); \
427 } while (0)
428
429#define SHOW_LONG64_PROP(a_pObj, a_Prop, a_szMachine, a_szHuman, a_szUnit) \
430 do \
431 { \
432 LONG64 i64; \
433 CHECK_ERROR2_RET(a_pObj, COMGETTER(a_Prop)(&i64), hrcCheck); \
434 if (details == VMINFO_MACHINEREADABLE) \
435 RTPrintf(a_szHuman "=%lld", i64); \
436 else \
437 RTPrintf("%-16s %'lld" a_szUnit "\n", a_szHuman ":", i64); \
438 } while (0)
439
440 /*
441 * The rules for output in -argdump format:
442 * 1) the key part (the [0-9a-zA-Z_\-]+ string before the '=' delimiter)
443 * is all lowercase for "VBoxManage modifyvm" parameters. Any
444 * other values printed are in CamelCase.
445 * 2) strings (anything non-decimal) are printed surrounded by
446 * double quotes '"'. If the strings themselves contain double
447 * quotes, these characters are escaped by '\'. Any '\' character
448 * in the original string is also escaped by '\'.
449 * 3) numbers (containing just [0-9\-]) are written out unchanged.
450 */
451
452 BOOL fAccessible;
453 CHECK_ERROR2_RET(machine, COMGETTER(Accessible)(&fAccessible), hrcCheck);
454 if (!fAccessible)
455 {
456 Bstr uuid;
457 machine->COMGETTER(Id)(uuid.asOutParam());
458 if (details == VMINFO_COMPACT)
459 RTPrintf("\"<inaccessible>\" {%s}\n", Utf8Str(uuid).c_str());
460 else
461 {
462 if (details == VMINFO_MACHINEREADABLE)
463 RTPrintf("name=\"<inaccessible>\"\n");
464 else
465 RTPrintf("Name: <inaccessible!>\n");
466 if (details == VMINFO_MACHINEREADABLE)
467 RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
468 else
469 RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
470 if (details != VMINFO_MACHINEREADABLE)
471 {
472 Bstr settingsFilePath;
473 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
474 RTPrintf("Config file: %ls\n", settingsFilePath.raw());
475 ComPtr<IVirtualBoxErrorInfo> accessError;
476 rc = machine->COMGETTER(AccessError)(accessError.asOutParam());
477 RTPrintf("Access error details:\n");
478 ErrorInfo ei(accessError);
479 GluePrintErrorInfo(ei);
480 RTPrintf("\n");
481 }
482 }
483 return S_OK;
484 }
485
486 if (details == VMINFO_COMPACT)
487 {
488 Bstr machineName;
489 machine->COMGETTER(Name)(machineName.asOutParam());
490 Bstr uuid;
491 machine->COMGETTER(Id)(uuid.asOutParam());
492
493 RTPrintf("\"%ls\" {%s}\n", machineName.raw(), Utf8Str(uuid).c_str());
494 return S_OK;
495 }
496
497 SHOW_STRING_PROP( machine, Name, "name", "Name");
498
499 Bstr osTypeId;
500 CHECK_ERROR2_RET(machine, COMGETTER(OSTypeId)(osTypeId.asOutParam()), hrcCheck);
501 ComPtr<IGuestOSType> osType;
502 CHECK_ERROR2_RET(virtualBox, GetGuestOSType(osTypeId.raw(), osType.asOutParam()), hrcCheck);
503 SHOW_STRINGARRAY_PROP( machine, Groups, "groups", "Groups");
504 SHOW_STRING_PROP( osType, Description, "ostype", "Guest OS");
505 SHOW_UUID_PROP( machine, Id, "UUID", "UUID");
506 SHOW_STRING_PROP( machine, SettingsFilePath, "CfgFile", "Config file");
507 SHOW_STRING_PROP( machine, SnapshotFolder, "SnapFldr", "Snapshot folder");
508 SHOW_STRING_PROP( machine, LogFolder, "LogFldr", "Log folder");
509 SHOW_UUID_PROP( machine, HardwareUUID, "hardwareuuid", "Hardware UUID");
510 SHOW_ULONG_PROP( machine, MemorySize, "memory", "Memory size", "MB");
511 SHOW_BOOLEAN_PROP( machine, PageFusionEnabled, "pagefusion", "Page Fusion");
512 SHOW_ULONG_PROP( machine, VRAMSize, "vram", "VRAM size", "MB");
513 SHOW_ULONG_PROP( machine, CPUExecutionCap, "cpuexecutioncap", "CPU exec cap", "%%");
514 SHOW_BOOLEAN_PROP( machine, HPETEnabled, "hpet", "HPET");
515
516 ChipsetType_T chipsetType;
517 CHECK_ERROR2_RET(machine, COMGETTER(ChipsetType)(&chipsetType), hrcCheck);
518 const char *pszChipsetType;
519 switch (chipsetType)
520 {
521 case ChipsetType_Null: pszChipsetType = "invalid"; break;
522 case ChipsetType_PIIX3: pszChipsetType = "piix3"; break;
523 case ChipsetType_ICH9: pszChipsetType = "ich9"; break;
524 default: AssertFailed(); pszChipsetType = "unknown"; break;
525 }
526 if (details == VMINFO_MACHINEREADABLE)
527 RTPrintf("chipset=\"%s\"\n", pszChipsetType);
528 else
529 RTPrintf("Chipset: %s\n", pszChipsetType);
530
531 FirmwareType_T firmwareType;
532 CHECK_ERROR2_RET(machine, COMGETTER(FirmwareType)(&firmwareType), hrcCheck);
533 const char *pszFirmwareType;
534 switch (firmwareType)
535 {
536 case FirmwareType_BIOS: pszFirmwareType = "BIOS"; break;
537 case FirmwareType_EFI: pszFirmwareType = "EFI"; break;
538 case FirmwareType_EFI32: pszFirmwareType = "EFI32"; break;
539 case FirmwareType_EFI64: pszFirmwareType = "EFI64"; break;
540 case FirmwareType_EFIDUAL: pszFirmwareType = "EFIDUAL"; break;
541 default: AssertFailed(); pszFirmwareType = "unknown"; break;
542 }
543 if (details == VMINFO_MACHINEREADABLE)
544 RTPrintf("firmware=\"%s\"\n", pszFirmwareType);
545 else
546 RTPrintf("Firmware: %s\n", pszFirmwareType);
547
548 SHOW_ULONG_PROP( machine, CPUCount, "cpus", "Number of CPUs", "");
549 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_PAE, &f), "pae", "PAE");
550 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_LongMode, &f), "longmode", "Long Mode");
551 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_Synthetic, &f), "synthcpu", "Synthetic CPU");
552
553 if (details != VMINFO_MACHINEREADABLE)
554 RTPrintf("CPUID overrides: ");
555 ULONG cFound = 0;
556 static uint32_t const s_auCpuIdRanges[] =
557 {
558 UINT32_C(0x00000000), UINT32_C(0x0000000a),
559 UINT32_C(0x80000000), UINT32_C(0x8000000a)
560 };
561 for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
562 for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
563 {
564 ULONG uEAX, uEBX, uECX, uEDX;
565 rc = machine->GetCPUIDLeaf(uLeaf, &uEAX, &uEBX, &uECX, &uEDX);
566 if (SUCCEEDED(rc))
567 {
568 if (details == VMINFO_MACHINEREADABLE)
569 RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x", uLeaf, uEAX, uEBX, uECX, uEDX);
570 else
571 {
572 if (!cFound)
573 RTPrintf("Leaf no. EAX EBX ECX EDX\n");
574 RTPrintf(" %08x %08x %08x %08x %08x\n", uLeaf, uEAX, uEBX, uECX, uEDX);
575 }
576 cFound++;
577 }
578 }
579 if (!cFound && details != VMINFO_MACHINEREADABLE)
580 RTPrintf("None\n");
581
582 ComPtr<IBIOSSettings> biosSettings;
583 CHECK_ERROR2_RET(machine, COMGETTER(BIOSSettings)(biosSettings.asOutParam()), hrcCheck);
584
585 BIOSBootMenuMode_T bootMenuMode;
586 CHECK_ERROR2_RET(biosSettings, COMGETTER(BootMenuMode)(&bootMenuMode), hrcCheck);
587 const char *pszBootMenu;
588 switch (bootMenuMode)
589 {
590 case BIOSBootMenuMode_Disabled:
591 pszBootMenu = "disabled";
592 break;
593 case BIOSBootMenuMode_MenuOnly:
594 if (details == VMINFO_MACHINEREADABLE)
595 pszBootMenu = "menuonly";
596 else
597 pszBootMenu = "menu only";
598 break;
599 default:
600 if (details == VMINFO_MACHINEREADABLE)
601 pszBootMenu = "messageandmenu";
602 else
603 pszBootMenu = "message and menu";
604 }
605 if (details == VMINFO_MACHINEREADABLE)
606 RTPrintf("bootmenu=\"%s\"\n", pszBootMenu);
607 else
608 RTPrintf("Boot menu mode: %s\n", pszBootMenu);
609
610 ComPtr<ISystemProperties> systemProperties;
611 CHECK_ERROR2_RET(virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck);
612 ULONG maxBootPosition = 0;
613 CHECK_ERROR2_RET(systemProperties, COMGETTER(MaxBootPosition)(&maxBootPosition), hrcCheck);
614 for (ULONG i = 1; i <= maxBootPosition; i++)
615 {
616 DeviceType_T bootOrder;
617 CHECK_ERROR2_RET(machine, GetBootOrder(i, &bootOrder), hrcCheck);
618 if (bootOrder == DeviceType_Floppy)
619 {
620 if (details == VMINFO_MACHINEREADABLE)
621 RTPrintf("boot%d=\"floppy\"\n", i);
622 else
623 RTPrintf("Boot Device (%d): Floppy\n", i);
624 }
625 else if (bootOrder == DeviceType_DVD)
626 {
627 if (details == VMINFO_MACHINEREADABLE)
628 RTPrintf("boot%d=\"dvd\"\n", i);
629 else
630 RTPrintf("Boot Device (%d): DVD\n", i);
631 }
632 else if (bootOrder == DeviceType_HardDisk)
633 {
634 if (details == VMINFO_MACHINEREADABLE)
635 RTPrintf("boot%d=\"disk\"\n", i);
636 else
637 RTPrintf("Boot Device (%d): HardDisk\n", i);
638 }
639 else if (bootOrder == DeviceType_Network)
640 {
641 if (details == VMINFO_MACHINEREADABLE)
642 RTPrintf("boot%d=\"net\"\n", i);
643 else
644 RTPrintf("Boot Device (%d): Network\n", i);
645 }
646 else if (bootOrder == DeviceType_USB)
647 {
648 if (details == VMINFO_MACHINEREADABLE)
649 RTPrintf("boot%d=\"usb\"\n", i);
650 else
651 RTPrintf("Boot Device (%d): USB\n", i);
652 }
653 else if (bootOrder == DeviceType_SharedFolder)
654 {
655 if (details == VMINFO_MACHINEREADABLE)
656 RTPrintf("boot%d=\"sharedfolder\"\n", i);
657 else
658 RTPrintf("Boot Device (%d): Shared Folder\n", i);
659 }
660 else
661 {
662 if (details == VMINFO_MACHINEREADABLE)
663 RTPrintf("boot%d=\"none\"\n", i);
664 else
665 RTPrintf("Boot Device (%d): Not Assigned\n", i);
666 }
667 }
668
669 SHOW_BOOLEAN_PROP(biosSettings, ACPIEnabled, "acpi", "ACPI");
670 SHOW_BOOLEAN_PROP(biosSettings, IOAPICEnabled, "ioapic", "IOAPIC");
671 SHOW_LONG64_PROP(biosSettings, TimeOffset, "biossystemtimeoffset", "Time offset", "ms");
672 SHOW_BOOLEAN_PROP_EX(machine, RTCUseUTC, "rtcuseutc", "RTC", "UTC", "local time");
673 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &f), "hwvirtex", "Hardw. virt.ext");
674 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", "Nested Paging");
675 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", "Large Pages");
676 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID");
677 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", "VT-x unr. exec.");
678
679 MachineState_T machineState;
680 CHECK_ERROR2_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
681 const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
682
683 LONG64 stateSince;
684 machine->COMGETTER(LastStateChange)(&stateSince);
685 RTTIMESPEC timeSpec;
686 RTTimeSpecSetMilli(&timeSpec, stateSince);
687 char pszTime[30] = {0};
688 RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
689 if (details == VMINFO_MACHINEREADABLE)
690 {
691 RTPrintf("VMState=\"%s\"\n", pszState);
692 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
693
694 Bstr stateFile;
695 machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
696 if (!stateFile.isEmpty())
697 RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
698 }
699 else
700 RTPrintf("State: %s (since %s)\n", pszState, pszTime);
701
702 SHOW_ULONG_PROP( machine, MonitorCount, "monitorcount", "Monitor count", "");
703 SHOW_BOOLEAN_PROP( machine, Accelerate3DEnabled, "accelerate3d", "3D Acceleration");
704#ifdef VBOX_WITH_VIDEOHWACCEL
705 SHOW_BOOLEAN_PROP( machine, Accelerate2DVideoEnabled, "accelerate2dvideo", "2D Video Acceleration");
706#endif
707 SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", "Teleporter Enabled");
708 SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", "Teleporter Port", "");
709 SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", "Teleporter Address");
710 SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", "Teleporter Password");
711 SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", "Tracing Enabled");
712 SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", "Allow Tracing to Access VM");
713 SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", "Tracing Configuration");
714 SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", "Autostart Enabled");
715 SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", "Autostart Delay", "");
716 SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", "Default Frontend");
717
718/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
719 * checking where missing. */
720 /*
721 * Storage Controllers and their attached Mediums.
722 */
723 com::SafeIfaceArray<IStorageController> storageCtls;
724 CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
725 for (size_t i = 0; i < storageCtls.size(); ++ i)
726 {
727 ComPtr<IStorageController> storageCtl = storageCtls[i];
728 StorageControllerType_T enmCtlType = StorageControllerType_Null;
729 const char *pszCtl = NULL;
730 ULONG ulValue = 0;
731 BOOL fBootable = FALSE;
732 Bstr storageCtlName;
733
734 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
735 if (details == VMINFO_MACHINEREADABLE)
736 RTPrintf("storagecontrollername%u=\"%ls\"\n", i, storageCtlName.raw());
737 else
738 RTPrintf("Storage Controller Name (%u): %ls\n", i, storageCtlName.raw());
739
740 storageCtl->COMGETTER(ControllerType)(&enmCtlType);
741 switch (enmCtlType)
742 {
743 case StorageControllerType_LsiLogic:
744 pszCtl = "LsiLogic";
745 break;
746 case StorageControllerType_LsiLogicSas:
747 pszCtl = "LsiLogicSas";
748 break;
749 case StorageControllerType_BusLogic:
750 pszCtl = "BusLogic";
751 break;
752 case StorageControllerType_IntelAhci:
753 pszCtl = "IntelAhci";
754 break;
755 case StorageControllerType_PIIX3:
756 pszCtl = "PIIX3";
757 break;
758 case StorageControllerType_PIIX4:
759 pszCtl = "PIIX4";
760 break;
761 case StorageControllerType_ICH6:
762 pszCtl = "ICH6";
763 break;
764 case StorageControllerType_I82078:
765 pszCtl = "I82078";
766 break;
767 case StorageControllerType_USB:
768 pszCtl = "USB";
769 break;
770
771 default:
772 pszCtl = "unknown";
773 }
774 if (details == VMINFO_MACHINEREADABLE)
775 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
776 else
777 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
778
779 storageCtl->COMGETTER(Instance)(&ulValue);
780 if (details == VMINFO_MACHINEREADABLE)
781 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
782 else
783 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
784
785 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
786 if (details == VMINFO_MACHINEREADABLE)
787 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
788 else
789 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
790
791 storageCtl->COMGETTER(PortCount)(&ulValue);
792 if (details == VMINFO_MACHINEREADABLE)
793 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
794 else
795 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
796
797 storageCtl->COMGETTER(Bootable)(&fBootable);
798 if (details == VMINFO_MACHINEREADABLE)
799 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
800 else
801 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
802 }
803
804 for (size_t j = 0; j < storageCtls.size(); ++ j)
805 {
806 ComPtr<IStorageController> storageCtl = storageCtls[j];
807 ComPtr<IMedium> medium;
808 Bstr storageCtlName;
809 Bstr filePath;
810 ULONG cDevices;
811 ULONG cPorts;
812
813 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
814 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
815 storageCtl->COMGETTER(PortCount)(&cPorts);
816
817 for (ULONG i = 0; i < cPorts; ++ i)
818 {
819 for (ULONG k = 0; k < cDevices; ++ k)
820 {
821 ComPtr<IMediumAttachment> mediumAttach;
822 machine->GetMediumAttachment(storageCtlName.raw(),
823 i, k,
824 mediumAttach.asOutParam());
825 BOOL fIsEjected = FALSE;
826 BOOL fTempEject = FALSE;
827 DeviceType_T devType = DeviceType_Null;
828 if (mediumAttach)
829 {
830 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
831 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
832 mediumAttach->COMGETTER(Type)(&devType);
833 }
834 rc = machine->GetMedium(storageCtlName.raw(), i, k,
835 medium.asOutParam());
836 if (SUCCEEDED(rc) && medium)
837 {
838 BOOL fPassthrough = FALSE;
839
840 if (mediumAttach)
841 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
842
843 medium->COMGETTER(Location)(filePath.asOutParam());
844 Bstr uuid;
845 medium->COMGETTER(Id)(uuid.asOutParam());
846
847 if (details == VMINFO_MACHINEREADABLE)
848 {
849 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
850 i, k, filePath.raw());
851 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
852 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
853 if (fPassthrough)
854 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
855 fPassthrough ? "on" : "off");
856 if (devType == DeviceType_DVD)
857 {
858 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
859 fTempEject ? "on" : "off");
860 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
861 fIsEjected ? "on" : "off");
862 }
863 }
864 else
865 {
866 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
867 storageCtlName.raw(), i, k, filePath.raw(),
868 Utf8Str(uuid).c_str());
869 if (fPassthrough)
870 RTPrintf(" (passthrough enabled)");
871 if (fTempEject)
872 RTPrintf(" (temp eject)");
873 if (fIsEjected)
874 RTPrintf(" (ejected)");
875 RTPrintf("\n");
876 }
877 }
878 else if (SUCCEEDED(rc))
879 {
880 if (details == VMINFO_MACHINEREADABLE)
881 {
882 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
883 if (devType == DeviceType_DVD)
884 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
885 fIsEjected ? "on" : "off");
886 }
887 else
888 {
889 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
890 if (fTempEject)
891 RTPrintf(" (temp eject)");
892 if (fIsEjected)
893 RTPrintf(" (ejected)");
894 RTPrintf("\n");
895 }
896 }
897 else
898 {
899 if (details == VMINFO_MACHINEREADABLE)
900 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
901 }
902 }
903 }
904 }
905
906 /* get the maximum amount of NICS */
907 ULONG maxNICs = getMaxNics(virtualBox, machine);
908
909 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
910 {
911 ComPtr<INetworkAdapter> nic;
912 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
913 if (SUCCEEDED(rc) && nic)
914 {
915 BOOL fEnabled;
916 nic->COMGETTER(Enabled)(&fEnabled);
917 if (!fEnabled)
918 {
919 if (details == VMINFO_MACHINEREADABLE)
920 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
921 else
922 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
923 }
924 else
925 {
926 Bstr strMACAddress;
927 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
928 Utf8Str strAttachment;
929 Utf8Str strNatSettings = "";
930 Utf8Str strNatForwardings = "";
931 NetworkAttachmentType_T attachment;
932 nic->COMGETTER(AttachmentType)(&attachment);
933 switch (attachment)
934 {
935 case NetworkAttachmentType_Null:
936 if (details == VMINFO_MACHINEREADABLE)
937 strAttachment = "null";
938 else
939 strAttachment = "none";
940 break;
941
942 case NetworkAttachmentType_NAT:
943 {
944 Bstr strNetwork;
945 ComPtr<INATEngine> engine;
946 nic->COMGETTER(NATEngine)(engine.asOutParam());
947 engine->COMGETTER(Network)(strNetwork.asOutParam());
948 com::SafeArray<BSTR> forwardings;
949 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
950 strNatForwardings = "";
951 for (size_t i = 0; i < forwardings.size(); ++i)
952 {
953 bool fSkip = false;
954 uint16_t port = 0;
955 BSTR r = forwardings[i];
956 Utf8Str utf = Utf8Str(r);
957 Utf8Str strName;
958 Utf8Str strProto;
959 Utf8Str strHostPort;
960 Utf8Str strHostIP;
961 Utf8Str strGuestPort;
962 Utf8Str strGuestIP;
963 size_t pos, ppos;
964 pos = ppos = 0;
965 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
966 do { \
967 pos = str.find(",", ppos); \
968 if (pos == Utf8Str::npos) \
969 { \
970 Log(( #res " extracting from %s is failed\n", str.c_str())); \
971 fSkip = true; \
972 } \
973 res = str.substr(ppos, pos - ppos); \
974 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
975 ppos = pos + 1; \
976 } while (0)
977 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
978 if (fSkip) continue;
979 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
980 if (fSkip) continue;
981 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
982 if (fSkip) continue;
983 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
984 if (fSkip) continue;
985 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
986 if (fSkip) continue;
987 strGuestPort = utf.substr(ppos, utf.length() - ppos);
988 #undef ITERATE_TO_NEXT_TERM
989 switch (strProto.toUInt32())
990 {
991 case NATProtocol_TCP:
992 strProto = "tcp";
993 break;
994 case NATProtocol_UDP:
995 strProto = "udp";
996 break;
997 default:
998 strProto = "unk";
999 break;
1000 }
1001 if (details == VMINFO_MACHINEREADABLE)
1002 {
1003 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
1004 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
1005 strHostIP.c_str(), strHostPort.c_str(),
1006 strGuestIP.c_str(), strGuestPort.c_str());
1007 }
1008 else
1009 {
1010 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
1011 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1012 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
1013 strHostIP.c_str(), strHostPort.c_str(),
1014 strGuestIP.c_str(), strGuestPort.c_str());
1015 }
1016 }
1017 ULONG mtu = 0;
1018 ULONG sockSnd = 0;
1019 ULONG sockRcv = 0;
1020 ULONG tcpSnd = 0;
1021 ULONG tcpRcv = 0;
1022 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1023
1024 if (details == VMINFO_MACHINEREADABLE)
1025 {
1026 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1027 strAttachment = "nat";
1028 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1029 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1030 }
1031 else
1032 {
1033 strAttachment = "NAT";
1034 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1035 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1036 }
1037 break;
1038 }
1039
1040 case NetworkAttachmentType_Bridged:
1041 {
1042 Bstr strBridgeAdp;
1043 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1044 if (details == VMINFO_MACHINEREADABLE)
1045 {
1046 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1047 strAttachment = "bridged";
1048 }
1049 else
1050 strAttachment = Utf8StrFmt("Bridged Interface '%ls'", strBridgeAdp.raw());
1051 break;
1052 }
1053
1054 case NetworkAttachmentType_Internal:
1055 {
1056 Bstr strNetwork;
1057 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1058 if (details == VMINFO_MACHINEREADABLE)
1059 {
1060 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1061 strAttachment = "intnet";
1062 }
1063 else
1064 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1065 break;
1066 }
1067
1068 case NetworkAttachmentType_HostOnly:
1069 {
1070 Bstr strHostonlyAdp;
1071 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1072 if (details == VMINFO_MACHINEREADABLE)
1073 {
1074 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1075 strAttachment = "hostonly";
1076 }
1077 else
1078 strAttachment = Utf8StrFmt("Host-only Interface '%ls'", strHostonlyAdp.raw());
1079 break;
1080 }
1081
1082 case NetworkAttachmentType_Generic:
1083 {
1084 Bstr strGenericDriver;
1085 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1086 if (details == VMINFO_MACHINEREADABLE)
1087 {
1088 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1089 strAttachment = "Generic";
1090 }
1091 else
1092 {
1093 strAttachment = Utf8StrFmt("Generic '%ls'", strGenericDriver.raw());
1094
1095 // show the generic properties
1096 com::SafeArray<BSTR> aProperties;
1097 com::SafeArray<BSTR> aValues;
1098 rc = nic->GetProperties(NULL,
1099 ComSafeArrayAsOutParam(aProperties),
1100 ComSafeArrayAsOutParam(aValues));
1101 if (SUCCEEDED(rc))
1102 {
1103 strAttachment += " { ";
1104 for (unsigned i = 0; i < aProperties.size(); ++i)
1105 strAttachment += Utf8StrFmt(!i ? "%ls='%ls'" : ", %ls='%ls'",
1106 aProperties[i], aValues[i]);
1107 strAttachment += " }";
1108 }
1109 }
1110 break;
1111 }
1112
1113 case NetworkAttachmentType_NATNetwork:
1114 {
1115 Bstr strNetwork;
1116 nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
1117 if (details == VMINFO_MACHINEREADABLE)
1118 {
1119 RTPrintf("nat-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1120 strAttachment = "natnetwork";
1121 }
1122 else
1123 strAttachment = Utf8StrFmt("NAT Network '%s'", Utf8Str(strNetwork).c_str());
1124 break;
1125 }
1126
1127 default:
1128 strAttachment = "unknown";
1129 break;
1130 }
1131
1132 /* cable connected */
1133 BOOL fConnected;
1134 nic->COMGETTER(CableConnected)(&fConnected);
1135
1136 /* promisc policy */
1137 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1138 CHECK_ERROR2_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1139 const char *pszPromiscuousGuestPolicy;
1140 switch (enmPromiscModePolicy)
1141 {
1142 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1143 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1144 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1145 default: AssertFailedReturn(E_INVALIDARG);
1146 }
1147
1148 /* trace stuff */
1149 BOOL fTraceEnabled;
1150 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1151 Bstr traceFile;
1152 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1153
1154 /* NIC type */
1155 NetworkAdapterType_T NICType;
1156 nic->COMGETTER(AdapterType)(&NICType);
1157 const char *pszNICType;
1158 switch (NICType)
1159 {
1160 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1161 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1162#ifdef VBOX_WITH_E1000
1163 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1164 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1165 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1166#endif
1167#ifdef VBOX_WITH_VIRTIO
1168 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1169#endif
1170 default: AssertFailed(); pszNICType = "unknown"; break;
1171 }
1172
1173 /* reported line speed */
1174 ULONG ulLineSpeed;
1175 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1176
1177 /* boot priority of the adapter */
1178 ULONG ulBootPriority;
1179 nic->COMGETTER(BootPriority)(&ulBootPriority);
1180
1181 /* bandwidth group */
1182 ComObjPtr<IBandwidthGroup> pBwGroup;
1183 Bstr strBwGroup;
1184 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1185 if (!pBwGroup.isNull())
1186 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1187
1188 if (details == VMINFO_MACHINEREADABLE)
1189 {
1190 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1191 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1192 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1193 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1194 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1195 }
1196 else
1197 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",
1198 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
1199 fConnected ? "on" : "off",
1200 fTraceEnabled ? "on" : "off",
1201 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1202 pszNICType,
1203 ulLineSpeed / 1000,
1204 (int)ulBootPriority,
1205 pszPromiscuousGuestPolicy,
1206 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1207 if (strNatSettings.length())
1208 RTPrintf(strNatSettings.c_str());
1209 if (strNatForwardings.length())
1210 RTPrintf(strNatForwardings.c_str());
1211 }
1212 }
1213 }
1214
1215 /* Pointing device information */
1216 PointingHIDType_T aPointingHID;
1217 const char *pszHID = "Unknown";
1218 const char *pszMrHID = "unknown";
1219 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1220 switch (aPointingHID)
1221 {
1222 case PointingHIDType_None:
1223 pszHID = "None";
1224 pszMrHID = "none";
1225 break;
1226 case PointingHIDType_PS2Mouse:
1227 pszHID = "PS/2 Mouse";
1228 pszMrHID = "ps2mouse";
1229 break;
1230 case PointingHIDType_USBMouse:
1231 pszHID = "USB Mouse";
1232 pszMrHID = "usbmouse";
1233 break;
1234 case PointingHIDType_USBTablet:
1235 pszHID = "USB Tablet";
1236 pszMrHID = "usbtablet";
1237 break;
1238 case PointingHIDType_ComboMouse:
1239 pszHID = "USB Tablet and PS/2 Mouse";
1240 pszMrHID = "combomouse";
1241 break;
1242 case PointingHIDType_USBMultiTouch:
1243 pszHID = "USB Multi-Touch";
1244 pszMrHID = "usbmultitouch";
1245 break;
1246 default:
1247 break;
1248 }
1249 if (details == VMINFO_MACHINEREADABLE)
1250 RTPrintf("hidpointing=\"%s\"\n", pszMrHID);
1251 else
1252 RTPrintf("Pointing Device: %s\n", pszHID);
1253
1254 /* Keyboard device information */
1255 KeyboardHIDType_T aKeyboardHID;
1256 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1257 pszHID = "Unknown";
1258 pszMrHID = "unknown";
1259 switch (aKeyboardHID)
1260 {
1261 case KeyboardHIDType_None:
1262 pszHID = "None";
1263 pszMrHID = "none";
1264 break;
1265 case KeyboardHIDType_PS2Keyboard:
1266 pszHID = "PS/2 Keyboard";
1267 pszMrHID = "ps2kbd";
1268 break;
1269 case KeyboardHIDType_USBKeyboard:
1270 pszHID = "USB Keyboard";
1271 pszMrHID = "usbkbd";
1272 break;
1273 case KeyboardHIDType_ComboKeyboard:
1274 pszHID = "USB and PS/2 Keyboard";
1275 pszMrHID = "combokbd";
1276 break;
1277 default:
1278 break;
1279 }
1280 if (details == VMINFO_MACHINEREADABLE)
1281 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHID);
1282 else
1283 RTPrintf("Keyboard Device: %s\n", pszHID);
1284
1285 ComPtr<ISystemProperties> sysProps;
1286 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1287
1288 /* get the maximum amount of UARTs */
1289 ULONG maxUARTs = 0;
1290 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1291 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1292 {
1293 ComPtr<ISerialPort> uart;
1294 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1295 if (SUCCEEDED(rc) && uart)
1296 {
1297 /* show the config of this UART */
1298 BOOL fEnabled;
1299 uart->COMGETTER(Enabled)(&fEnabled);
1300 if (!fEnabled)
1301 {
1302 if (details == VMINFO_MACHINEREADABLE)
1303 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1304 else
1305 RTPrintf("UART %d: disabled\n", currentUART + 1);
1306 }
1307 else
1308 {
1309 ULONG ulIRQ, ulIOBase;
1310 PortMode_T HostMode;
1311 Bstr path;
1312 BOOL fServer;
1313 uart->COMGETTER(IRQ)(&ulIRQ);
1314 uart->COMGETTER(IOBase)(&ulIOBase);
1315 uart->COMGETTER(Path)(path.asOutParam());
1316 uart->COMGETTER(Server)(&fServer);
1317 uart->COMGETTER(HostMode)(&HostMode);
1318
1319 if (details == VMINFO_MACHINEREADABLE)
1320 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1321 ulIOBase, ulIRQ);
1322 else
1323 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1324 currentUART + 1, ulIOBase, ulIRQ);
1325 switch (HostMode)
1326 {
1327 default:
1328 case PortMode_Disconnected:
1329 if (details == VMINFO_MACHINEREADABLE)
1330 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1331 else
1332 RTPrintf(", disconnected\n");
1333 break;
1334 case PortMode_RawFile:
1335 if (details == VMINFO_MACHINEREADABLE)
1336 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1337 path.raw());
1338 else
1339 RTPrintf(", attached to raw file '%ls'\n",
1340 path.raw());
1341 break;
1342 case PortMode_HostPipe:
1343 if (details == VMINFO_MACHINEREADABLE)
1344 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1345 fServer ? "server" : "client", path.raw());
1346 else
1347 RTPrintf(", attached to pipe (%s) '%ls'\n",
1348 fServer ? "server" : "client", path.raw());
1349 break;
1350 case PortMode_HostDevice:
1351 if (details == VMINFO_MACHINEREADABLE)
1352 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1353 path.raw());
1354 else
1355 RTPrintf(", attached to device '%ls'\n", path.raw());
1356 break;
1357 }
1358 }
1359 }
1360 }
1361
1362 /* get the maximum amount of LPTs */
1363 ULONG maxLPTs = 0;
1364 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1365 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1366 {
1367 ComPtr<IParallelPort> lpt;
1368 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1369 if (SUCCEEDED(rc) && lpt)
1370 {
1371 /* show the config of this LPT */
1372 BOOL fEnabled;
1373 lpt->COMGETTER(Enabled)(&fEnabled);
1374 if (!fEnabled)
1375 {
1376 if (details == VMINFO_MACHINEREADABLE)
1377 RTPrintf("lpt%d=\"off\"\n", currentLPT + 1);
1378 else
1379 RTPrintf("LPT %d: disabled\n", currentLPT + 1);
1380 }
1381 else
1382 {
1383 ULONG ulIRQ, ulIOBase;
1384 Bstr path;
1385 lpt->COMGETTER(IRQ)(&ulIRQ);
1386 lpt->COMGETTER(IOBase)(&ulIOBase);
1387 lpt->COMGETTER(Path)(path.asOutParam());
1388
1389 if (details == VMINFO_MACHINEREADABLE)
1390 RTPrintf("lpt%d=\"%#06x,%d\"\n", currentLPT + 1,
1391 ulIOBase, ulIRQ);
1392 else
1393 RTPrintf("LPT %d: I/O base: %#06x, IRQ: %d",
1394 currentLPT + 1, ulIOBase, ulIRQ);
1395 if (details == VMINFO_MACHINEREADABLE)
1396 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1,
1397 path.raw());
1398 else
1399 RTPrintf(", attached to device '%ls'\n", path.raw());
1400 }
1401 }
1402 }
1403
1404 ComPtr<IAudioAdapter> AudioAdapter;
1405 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1406 if (SUCCEEDED(rc))
1407 {
1408 const char *pszDrv = "Unknown";
1409 const char *pszCtrl = "Unknown";
1410 BOOL fEnabled;
1411 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1412 if (SUCCEEDED(rc) && fEnabled)
1413 {
1414 AudioDriverType_T enmDrvType;
1415 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1416 switch (enmDrvType)
1417 {
1418 case AudioDriverType_Null:
1419 if (details == VMINFO_MACHINEREADABLE)
1420 pszDrv = "null";
1421 else
1422 pszDrv = "Null";
1423 break;
1424 case AudioDriverType_WinMM:
1425 if (details == VMINFO_MACHINEREADABLE)
1426 pszDrv = "winmm";
1427 else
1428 pszDrv = "WINMM";
1429 break;
1430 case AudioDriverType_DirectSound:
1431 if (details == VMINFO_MACHINEREADABLE)
1432 pszDrv = "dsound";
1433 else
1434 pszDrv = "DSOUND";
1435 break;
1436 case AudioDriverType_OSS:
1437 if (details == VMINFO_MACHINEREADABLE)
1438 pszDrv = "oss";
1439 else
1440 pszDrv = "OSS";
1441 break;
1442 case AudioDriverType_ALSA:
1443 if (details == VMINFO_MACHINEREADABLE)
1444 pszDrv = "alsa";
1445 else
1446 pszDrv = "ALSA";
1447 break;
1448 case AudioDriverType_Pulse:
1449 if (details == VMINFO_MACHINEREADABLE)
1450 pszDrv = "pulse";
1451 else
1452 pszDrv = "PulseAudio";
1453 break;
1454 case AudioDriverType_CoreAudio:
1455 if (details == VMINFO_MACHINEREADABLE)
1456 pszDrv = "coreaudio";
1457 else
1458 pszDrv = "CoreAudio";
1459 break;
1460 case AudioDriverType_SolAudio:
1461 if (details == VMINFO_MACHINEREADABLE)
1462 pszDrv = "solaudio";
1463 else
1464 pszDrv = "SolAudio";
1465 break;
1466 default:
1467 if (details == VMINFO_MACHINEREADABLE)
1468 pszDrv = "unknown";
1469 break;
1470 }
1471 AudioControllerType_T enmCtrlType;
1472 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1473 switch (enmCtrlType)
1474 {
1475 case AudioControllerType_AC97:
1476 if (details == VMINFO_MACHINEREADABLE)
1477 pszCtrl = "ac97";
1478 else
1479 pszCtrl = "AC97";
1480 break;
1481 case AudioControllerType_SB16:
1482 if (details == VMINFO_MACHINEREADABLE)
1483 pszCtrl = "sb16";
1484 else
1485 pszCtrl = "SB16";
1486 break;
1487 case AudioControllerType_HDA:
1488 if (details == VMINFO_MACHINEREADABLE)
1489 pszCtrl = "hda";
1490 else
1491 pszCtrl = "HDA";
1492 break;
1493 }
1494 }
1495 else
1496 fEnabled = FALSE;
1497 if (details == VMINFO_MACHINEREADABLE)
1498 {
1499 if (fEnabled)
1500 RTPrintf("audio=\"%s\"\n", pszDrv);
1501 else
1502 RTPrintf("audio=\"none\"\n");
1503 }
1504 else
1505 {
1506 RTPrintf("Audio: %s",
1507 fEnabled ? "enabled" : "disabled");
1508 if (fEnabled)
1509 RTPrintf(" (Driver: %s, Controller: %s)",
1510 pszDrv, pszCtrl);
1511 RTPrintf("\n");
1512 }
1513 }
1514
1515 /* Shared clipboard */
1516 {
1517 const char *psz = "Unknown";
1518 ClipboardMode_T enmMode;
1519 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1520 switch (enmMode)
1521 {
1522 case ClipboardMode_Disabled:
1523 if (details == VMINFO_MACHINEREADABLE)
1524 psz = "disabled";
1525 else
1526 psz = "disabled";
1527 break;
1528 case ClipboardMode_HostToGuest:
1529 if (details == VMINFO_MACHINEREADABLE)
1530 psz = "hosttoguest";
1531 else
1532 psz = "HostToGuest";
1533 break;
1534 case ClipboardMode_GuestToHost:
1535 if (details == VMINFO_MACHINEREADABLE)
1536 psz = "guesttohost";
1537 else
1538 psz = "GuestToHost";
1539 break;
1540 case ClipboardMode_Bidirectional:
1541 if (details == VMINFO_MACHINEREADABLE)
1542 psz = "bidirectional";
1543 else
1544 psz = "Bidirectional";
1545 break;
1546 default:
1547 if (details == VMINFO_MACHINEREADABLE)
1548 psz = "unknown";
1549 break;
1550 }
1551 if (details == VMINFO_MACHINEREADABLE)
1552 RTPrintf("clipboard=\"%s\"\n", psz);
1553 else
1554 RTPrintf("Clipboard Mode: %s\n", psz);
1555 }
1556
1557 /* Drag'n'drop */
1558 {
1559 const char *psz = "Unknown";
1560 DragAndDropMode_T enmMode;
1561 rc = machine->COMGETTER(DragAndDropMode)(&enmMode);
1562 switch (enmMode)
1563 {
1564 case DragAndDropMode_Disabled:
1565 if (details == VMINFO_MACHINEREADABLE)
1566 psz = "disabled";
1567 else
1568 psz = "disabled";
1569 break;
1570 case DragAndDropMode_HostToGuest:
1571 if (details == VMINFO_MACHINEREADABLE)
1572 psz = "hosttoguest";
1573 else
1574 psz = "HostToGuest";
1575 break;
1576 case DragAndDropMode_GuestToHost:
1577 if (details == VMINFO_MACHINEREADABLE)
1578 psz = "guesttohost";
1579 else
1580 psz = "GuestToHost";
1581 break;
1582 case DragAndDropMode_Bidirectional:
1583 if (details == VMINFO_MACHINEREADABLE)
1584 psz = "bidirectional";
1585 else
1586 psz = "Bidirectional";
1587 break;
1588 default:
1589 if (details == VMINFO_MACHINEREADABLE)
1590 psz = "unknown";
1591 break;
1592 }
1593 if (details == VMINFO_MACHINEREADABLE)
1594 RTPrintf("draganddrop=\"%s\"\n", psz);
1595 else
1596 RTPrintf("Drag'n'drop Mode: %s\n", psz);
1597 }
1598
1599 {
1600 SessionState_T sessState;
1601 rc = machine->COMGETTER(SessionState)(&sessState);
1602 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1603 {
1604 Bstr sessType;
1605 rc = machine->COMGETTER(SessionType)(sessType.asOutParam());
1606 if (SUCCEEDED(rc) && !sessType.isEmpty())
1607 {
1608 if (details == VMINFO_MACHINEREADABLE)
1609 RTPrintf("SessionType=\"%ls\"\n", sessType.raw());
1610 else
1611 RTPrintf("Session type: %ls\n", sessType.raw());
1612 }
1613 }
1614 }
1615
1616 if (console)
1617 {
1618 do
1619 {
1620 ComPtr<IDisplay> display;
1621 rc = console->COMGETTER(Display)(display.asOutParam());
1622 if (rc == E_ACCESSDENIED || display.isNull())
1623 break; /* VM not powered up */
1624 if (FAILED(rc))
1625 {
1626 com::GlueHandleComError(console, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1627 return rc;
1628 }
1629 ULONG xRes, yRes, bpp;
1630 LONG xOrigin, yOrigin;
1631 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin);
1632 if (rc == E_ACCESSDENIED)
1633 break; /* VM not powered up */
1634 if (FAILED(rc))
1635 {
1636 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1637 GluePrintErrorInfo(info);
1638 return rc;
1639 }
1640 if (details == VMINFO_MACHINEREADABLE)
1641 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1642 else
1643 RTPrintf("Video mode: %dx%dx%d at %d,%d\n", xRes, yRes, bpp, xOrigin, yOrigin);
1644 }
1645 while (0);
1646 }
1647
1648 /*
1649 * Remote Desktop
1650 */
1651 ComPtr<IVRDEServer> vrdeServer;
1652 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1653 if (SUCCEEDED(rc) && vrdeServer)
1654 {
1655 BOOL fEnabled = false;
1656 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1657 if (fEnabled)
1658 {
1659 LONG currentPort = -1;
1660 Bstr ports;
1661 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1662 Bstr address;
1663 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1664 BOOL fMultiCon;
1665 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1666 BOOL fReuseCon;
1667 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1668 Bstr videoChannel;
1669 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1670 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1671 || (videoChannel == "1");
1672 Bstr videoChannelQuality;
1673 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1674 AuthType_T authType;
1675 const char *strAuthType;
1676 vrdeServer->COMGETTER(AuthType)(&authType);
1677 switch (authType)
1678 {
1679 case AuthType_Null:
1680 strAuthType = "null";
1681 break;
1682 case AuthType_External:
1683 strAuthType = "external";
1684 break;
1685 case AuthType_Guest:
1686 strAuthType = "guest";
1687 break;
1688 default:
1689 strAuthType = "unknown";
1690 break;
1691 }
1692 if (console)
1693 {
1694 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1695 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1696 if (!vrdeServerInfo.isNull())
1697 {
1698 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1699 if (rc == E_ACCESSDENIED)
1700 {
1701 currentPort = -1; /* VM not powered up */
1702 }
1703 if (FAILED(rc))
1704 {
1705 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1706 GluePrintErrorInfo(info);
1707 return rc;
1708 }
1709 }
1710 }
1711 if (details == VMINFO_MACHINEREADABLE)
1712 {
1713 RTPrintf("vrde=\"on\"\n");
1714 RTPrintf("vrdeport=%d\n", currentPort);
1715 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
1716 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
1717 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1718 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1719 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1720 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1721 if (fVideoChannel)
1722 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
1723 }
1724 else
1725 {
1726 if (address.isEmpty())
1727 address = "0.0.0.0";
1728 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);
1729 if (console && currentPort != -1 && currentPort != 0)
1730 RTPrintf("VRDE port: %d\n", currentPort);
1731 if (fVideoChannel)
1732 RTPrintf("Video redirection: enabled (Quality %ls)\n", videoChannelQuality.raw());
1733 else
1734 RTPrintf("Video redirection: disabled\n");
1735 }
1736 com::SafeArray<BSTR> aProperties;
1737 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1738 {
1739 unsigned i;
1740 for (i = 0; i < aProperties.size(); ++i)
1741 {
1742 Bstr value;
1743 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1744 if (details == VMINFO_MACHINEREADABLE)
1745 {
1746 if (value.isEmpty())
1747 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
1748 else
1749 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
1750 }
1751 else
1752 {
1753 if (value.isEmpty())
1754 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1755 else
1756 RTPrintf("VRDE property: %-10lS = \"%ls\"\n", aProperties[i], value.raw());
1757 }
1758 }
1759 }
1760 }
1761 else
1762 {
1763 if (details == VMINFO_MACHINEREADABLE)
1764 RTPrintf("vrde=\"off\"\n");
1765 else
1766 RTPrintf("VRDE: disabled\n");
1767 }
1768 }
1769
1770 /*
1771 * USB.
1772 */
1773 SafeIfaceArray<IUSBController> USBCtlColl;
1774 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
1775 if (SUCCEEDED(rc))
1776 {
1777 bool fOhciEnabled = false;
1778 bool fEhciEnabled = false;
1779
1780 for (unsigned i = 0; i < USBCtlColl.size(); i++)
1781 {
1782 USBControllerType_T enmType;
1783
1784 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
1785 if (SUCCEEDED(rc))
1786 {
1787 switch (enmType)
1788 {
1789 case USBControllerType_OHCI:
1790 fOhciEnabled = true;
1791 break;
1792 case USBControllerType_EHCI:
1793 fEhciEnabled = true;
1794 break;
1795 default:
1796 break;
1797 }
1798 }
1799 }
1800
1801 if (details == VMINFO_MACHINEREADABLE)
1802 RTPrintf("usb=\"%s\"\n", fOhciEnabled ? "on" : "off");
1803 else
1804 RTPrintf("USB: %s\n", fOhciEnabled ? "enabled" : "disabled");
1805
1806 if (details == VMINFO_MACHINEREADABLE)
1807 RTPrintf("ehci=\"%s\"\n", fEhciEnabled ? "on" : "off");
1808 else
1809 RTPrintf("EHCI: %s\n", fEhciEnabled ? "enabled" : "disabled");
1810 }
1811
1812 ComPtr<IUSBDeviceFilters> USBFlts;
1813 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
1814 if (SUCCEEDED(rc))
1815 {
1816 SafeIfaceArray <IUSBDeviceFilter> Coll;
1817 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1818 if (SUCCEEDED(rc))
1819 {
1820 if (details != VMINFO_MACHINEREADABLE)
1821 RTPrintf("\nUSB Device Filters:\n\n");
1822
1823 if (Coll.size() == 0)
1824 {
1825 if (details != VMINFO_MACHINEREADABLE)
1826 RTPrintf("<none>\n\n");
1827 }
1828 else
1829 {
1830 for (size_t index = 0; index < Coll.size(); ++index)
1831 {
1832 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1833
1834 /* Query info. */
1835
1836 if (details != VMINFO_MACHINEREADABLE)
1837 RTPrintf("Index: %zu\n", index);
1838
1839 BOOL bActive = FALSE;
1840 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1841 if (details == VMINFO_MACHINEREADABLE)
1842 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1843 else
1844 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1845
1846 Bstr bstr;
1847 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1848 if (details == VMINFO_MACHINEREADABLE)
1849 RTPrintf("USBFilterName%zu=\"%ls\"\n", index + 1, bstr.raw());
1850 else
1851 RTPrintf("Name: %ls\n", bstr.raw());
1852 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1853 if (details == VMINFO_MACHINEREADABLE)
1854 RTPrintf("USBFilterVendorId%zu=\"%ls\"\n", index + 1, bstr.raw());
1855 else
1856 RTPrintf("VendorId: %ls\n", bstr.raw());
1857 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1858 if (details == VMINFO_MACHINEREADABLE)
1859 RTPrintf("USBFilterProductId%zu=\"%ls\"\n", index + 1, bstr.raw());
1860 else
1861 RTPrintf("ProductId: %ls\n", bstr.raw());
1862 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1863 if (details == VMINFO_MACHINEREADABLE)
1864 RTPrintf("USBFilterRevision%zu=\"%ls\"\n", index + 1, bstr.raw());
1865 else
1866 RTPrintf("Revision: %ls\n", bstr.raw());
1867 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1868 if (details == VMINFO_MACHINEREADABLE)
1869 RTPrintf("USBFilterManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1870 else
1871 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1872 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1873 if (details == VMINFO_MACHINEREADABLE)
1874 RTPrintf("USBFilterProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1875 else
1876 RTPrintf("Product: %ls\n", bstr.raw());
1877 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1878 if (details == VMINFO_MACHINEREADABLE)
1879 RTPrintf("USBFilterRemote%zu=\"%ls\"\n", index + 1, bstr.raw());
1880 else
1881 RTPrintf("Remote: %ls\n", bstr.raw());
1882 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1883 if (details == VMINFO_MACHINEREADABLE)
1884 RTPrintf("USBFilterSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1885 else
1886 RTPrintf("Serial Number: %ls\n", bstr.raw());
1887 if (details != VMINFO_MACHINEREADABLE)
1888 {
1889 ULONG fMaskedIfs;
1890 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1891 if (fMaskedIfs)
1892 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1893 RTPrintf("\n");
1894 }
1895 }
1896 }
1897 }
1898
1899 if (console)
1900 {
1901 /* scope */
1902 {
1903 if (details != VMINFO_MACHINEREADABLE)
1904 RTPrintf("Available remote USB devices:\n\n");
1905
1906 SafeIfaceArray <IHostUSBDevice> coll;
1907 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1908
1909 if (coll.size() == 0)
1910 {
1911 if (details != VMINFO_MACHINEREADABLE)
1912 RTPrintf("<none>\n\n");
1913 }
1914 else
1915 {
1916 for (size_t index = 0; index < coll.size(); ++index)
1917 {
1918 ComPtr<IHostUSBDevice> dev = coll[index];
1919
1920 /* Query info. */
1921 Bstr id;
1922 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1923 USHORT usVendorId;
1924 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1925 USHORT usProductId;
1926 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1927 USHORT bcdRevision;
1928 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1929
1930 if (details == VMINFO_MACHINEREADABLE)
1931 RTPrintf("USBRemoteUUID%zu=\"%s\"\n"
1932 "USBRemoteVendorId%zu=\"%#06x\"\n"
1933 "USBRemoteProductId%zu=\"%#06x\"\n"
1934 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1935 index + 1, Utf8Str(id).c_str(),
1936 index + 1, usVendorId,
1937 index + 1, usProductId,
1938 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1939 else
1940 RTPrintf("UUID: %s\n"
1941 "VendorId: %#06x (%04X)\n"
1942 "ProductId: %#06x (%04X)\n"
1943 "Revision: %u.%u (%02u%02u)\n",
1944 Utf8Str(id).c_str(),
1945 usVendorId, usVendorId, usProductId, usProductId,
1946 bcdRevision >> 8, bcdRevision & 0xff,
1947 bcdRevision >> 8, bcdRevision & 0xff);
1948
1949 /* optional stuff. */
1950 Bstr bstr;
1951 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1952 if (!bstr.isEmpty())
1953 {
1954 if (details == VMINFO_MACHINEREADABLE)
1955 RTPrintf("USBRemoteManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
1956 else
1957 RTPrintf("Manufacturer: %ls\n", bstr.raw());
1958 }
1959 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1960 if (!bstr.isEmpty())
1961 {
1962 if (details == VMINFO_MACHINEREADABLE)
1963 RTPrintf("USBRemoteProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
1964 else
1965 RTPrintf("Product: %ls\n", bstr.raw());
1966 }
1967 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1968 if (!bstr.isEmpty())
1969 {
1970 if (details == VMINFO_MACHINEREADABLE)
1971 RTPrintf("USBRemoteSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
1972 else
1973 RTPrintf("SerialNumber: %ls\n", bstr.raw());
1974 }
1975 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1976 if (!bstr.isEmpty())
1977 {
1978 if (details == VMINFO_MACHINEREADABLE)
1979 RTPrintf("USBRemoteAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
1980 else
1981 RTPrintf("Address: %ls\n", bstr.raw());
1982 }
1983
1984 if (details != VMINFO_MACHINEREADABLE)
1985 RTPrintf("\n");
1986 }
1987 }
1988 }
1989
1990 /* scope */
1991 {
1992 if (details != VMINFO_MACHINEREADABLE)
1993 RTPrintf("Currently Attached USB Devices:\n\n");
1994
1995 SafeIfaceArray <IUSBDevice> coll;
1996 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1997
1998 if (coll.size() == 0)
1999 {
2000 if (details != VMINFO_MACHINEREADABLE)
2001 RTPrintf("<none>\n\n");
2002 }
2003 else
2004 {
2005 for (size_t index = 0; index < coll.size(); ++index)
2006 {
2007 ComPtr<IUSBDevice> dev = coll[index];
2008
2009 /* Query info. */
2010 Bstr id;
2011 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
2012 USHORT usVendorId;
2013 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
2014 USHORT usProductId;
2015 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
2016 USHORT bcdRevision;
2017 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2018
2019 if (details == VMINFO_MACHINEREADABLE)
2020 RTPrintf("USBAttachedUUID%zu=\"%s\"\n"
2021 "USBAttachedVendorId%zu=\"%#06x\"\n"
2022 "USBAttachedProductId%zu=\"%#06x\"\n"
2023 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
2024 index + 1, Utf8Str(id).c_str(),
2025 index + 1, usVendorId,
2026 index + 1, usProductId,
2027 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
2028 else
2029 RTPrintf("UUID: %s\n"
2030 "VendorId: %#06x (%04X)\n"
2031 "ProductId: %#06x (%04X)\n"
2032 "Revision: %u.%u (%02u%02u)\n",
2033 Utf8Str(id).c_str(),
2034 usVendorId, usVendorId, usProductId, usProductId,
2035 bcdRevision >> 8, bcdRevision & 0xff,
2036 bcdRevision >> 8, bcdRevision & 0xff);
2037
2038 /* optional stuff. */
2039 Bstr bstr;
2040 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
2041 if (!bstr.isEmpty())
2042 {
2043 if (details == VMINFO_MACHINEREADABLE)
2044 RTPrintf("USBAttachedManufacturer%zu=\"%ls\"\n", index + 1, bstr.raw());
2045 else
2046 RTPrintf("Manufacturer: %ls\n", bstr.raw());
2047 }
2048 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
2049 if (!bstr.isEmpty())
2050 {
2051 if (details == VMINFO_MACHINEREADABLE)
2052 RTPrintf("USBAttachedProduct%zu=\"%ls\"\n", index + 1, bstr.raw());
2053 else
2054 RTPrintf("Product: %ls\n", bstr.raw());
2055 }
2056 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
2057 if (!bstr.isEmpty())
2058 {
2059 if (details == VMINFO_MACHINEREADABLE)
2060 RTPrintf("USBAttachedSerialNumber%zu=\"%ls\"\n", index + 1, bstr.raw());
2061 else
2062 RTPrintf("SerialNumber: %ls\n", bstr.raw());
2063 }
2064 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
2065 if (!bstr.isEmpty())
2066 {
2067 if (details == VMINFO_MACHINEREADABLE)
2068 RTPrintf("USBAttachedAddress%zu=\"%ls\"\n", index + 1, bstr.raw());
2069 else
2070 RTPrintf("Address: %ls\n", bstr.raw());
2071 }
2072
2073 if (details != VMINFO_MACHINEREADABLE)
2074 RTPrintf("\n");
2075 }
2076 }
2077 }
2078 }
2079 } /* USB */
2080
2081#ifdef VBOX_WITH_PCI_PASSTHROUGH
2082 /* Host PCI passthrough devices */
2083 {
2084 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2085 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2086 if (SUCCEEDED(rc))
2087 {
2088 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2089 {
2090 RTPrintf("\nAttached physical PCI devices:\n\n");
2091 }
2092
2093 for (size_t index = 0; index < assignments.size(); ++index)
2094 {
2095 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2096 char szHostPCIAddress[32], szGuestPCIAddress[32];
2097 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2098 Bstr DevName;
2099
2100 Assignment->COMGETTER(Name)(DevName.asOutParam());
2101 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2102 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2103 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2104 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2105
2106 if (details == VMINFO_MACHINEREADABLE)
2107 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2108 else
2109 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2110 }
2111
2112 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2113 {
2114 RTPrintf("\n");
2115 }
2116 }
2117 }
2118 /* Host PCI passthrough devices */
2119#endif
2120
2121 /*
2122 * Bandwidth groups
2123 */
2124 if (details != VMINFO_MACHINEREADABLE)
2125 RTPrintf("Bandwidth groups: ");
2126 {
2127 ComPtr<IBandwidthControl> bwCtrl;
2128 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2129
2130 rc = showBandwidthGroups(bwCtrl, details);
2131 }
2132
2133
2134 /*
2135 * Shared folders
2136 */
2137 if (details != VMINFO_MACHINEREADABLE)
2138 RTPrintf("Shared folders: ");
2139 uint32_t numSharedFolders = 0;
2140#if 0 // not yet implemented
2141 /* globally shared folders first */
2142 {
2143 SafeIfaceArray <ISharedFolder> sfColl;
2144 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2145 for (size_t i = 0; i < sfColl.size(); ++i)
2146 {
2147 ComPtr<ISharedFolder> sf = sfColl[i];
2148 Bstr name, hostPath;
2149 sf->COMGETTER(Name)(name.asOutParam());
2150 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2151 RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
2152 ++numSharedFolders;
2153 }
2154 }
2155#endif
2156 /* now VM mappings */
2157 {
2158 com::SafeIfaceArray <ISharedFolder> folders;
2159
2160 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2161
2162 for (size_t i = 0; i < folders.size(); ++i)
2163 {
2164 ComPtr<ISharedFolder> sf = folders[i];
2165
2166 Bstr name, hostPath;
2167 BOOL writable;
2168 sf->COMGETTER(Name)(name.asOutParam());
2169 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2170 sf->COMGETTER(Writable)(&writable);
2171 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2172 RTPrintf("\n\n");
2173 if (details == VMINFO_MACHINEREADABLE)
2174 {
2175 RTPrintf("SharedFolderNameMachineMapping%zu=\"%ls\"\n", i + 1,
2176 name.raw());
2177 RTPrintf("SharedFolderPathMachineMapping%zu=\"%ls\"\n", i + 1,
2178 hostPath.raw());
2179 }
2180 else
2181 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
2182 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2183 ++numSharedFolders;
2184 }
2185 }
2186 /* transient mappings */
2187 if (console)
2188 {
2189 com::SafeIfaceArray <ISharedFolder> folders;
2190
2191 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2192
2193 for (size_t i = 0; i < folders.size(); ++i)
2194 {
2195 ComPtr<ISharedFolder> sf = folders[i];
2196
2197 Bstr name, hostPath;
2198 sf->COMGETTER(Name)(name.asOutParam());
2199 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2200 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2201 RTPrintf("\n\n");
2202 if (details == VMINFO_MACHINEREADABLE)
2203 {
2204 RTPrintf("SharedFolderNameTransientMapping%zu=\"%ls\"\n", i + 1,
2205 name.raw());
2206 RTPrintf("SharedFolderPathTransientMapping%zu=\"%ls\"\n", i + 1,
2207 hostPath.raw());
2208 }
2209 else
2210 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
2211 ++numSharedFolders;
2212 }
2213 }
2214 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2215 RTPrintf("<none>\n");
2216 if (details != VMINFO_MACHINEREADABLE)
2217 RTPrintf("\n");
2218
2219 if (console)
2220 {
2221 /*
2222 * Live VRDE info.
2223 */
2224 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2225 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2226 BOOL Active = FALSE;
2227 ULONG NumberOfClients = 0;
2228 LONG64 BeginTime = 0;
2229 LONG64 EndTime = 0;
2230 LONG64 BytesSent = 0;
2231 LONG64 BytesSentTotal = 0;
2232 LONG64 BytesReceived = 0;
2233 LONG64 BytesReceivedTotal = 0;
2234 Bstr User;
2235 Bstr Domain;
2236 Bstr ClientName;
2237 Bstr ClientIP;
2238 ULONG ClientVersion = 0;
2239 ULONG EncryptionStyle = 0;
2240
2241 if (!vrdeServerInfo.isNull())
2242 {
2243 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2244 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2245 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2246 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2247 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2248 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2249 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2250 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2251 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2252 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2253 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2254 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2255 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2256 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2257 }
2258
2259 if (details == VMINFO_MACHINEREADABLE)
2260 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2261 else
2262 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2263
2264 if (details == VMINFO_MACHINEREADABLE)
2265 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2266 else
2267 RTPrintf("Clients so far: %d\n", NumberOfClients);
2268
2269 if (NumberOfClients > 0)
2270 {
2271 char timestr[128];
2272
2273 if (Active)
2274 {
2275 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2276 if (details == VMINFO_MACHINEREADABLE)
2277 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2278 else
2279 RTPrintf("Start time: %s\n", timestr);
2280 }
2281 else
2282 {
2283 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2284 if (details == VMINFO_MACHINEREADABLE)
2285 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2286 else
2287 RTPrintf("Last started: %s\n", timestr);
2288 makeTimeStr(timestr, sizeof(timestr), EndTime);
2289 if (details == VMINFO_MACHINEREADABLE)
2290 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2291 else
2292 RTPrintf("Last ended: %s\n", timestr);
2293 }
2294
2295 int64_t ThroughputSend = 0;
2296 int64_t ThroughputReceive = 0;
2297 if (EndTime != BeginTime)
2298 {
2299 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2300 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2301 }
2302
2303 if (details == VMINFO_MACHINEREADABLE)
2304 {
2305 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2306 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2307 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2308
2309 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2310 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2311 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2312 }
2313 else
2314 {
2315 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2316 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2317 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2318
2319 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2320 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2321 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2322 }
2323
2324 if (Active)
2325 {
2326 if (details == VMINFO_MACHINEREADABLE)
2327 {
2328 RTPrintf("VRDEUserName=\"%ls\"\n", User.raw());
2329 RTPrintf("VRDEDomain=\"%ls\"\n", Domain.raw());
2330 RTPrintf("VRDEClientName=\"%ls\"\n", ClientName.raw());
2331 RTPrintf("VRDEClientIP=\"%ls\"\n", ClientIP.raw());
2332 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2333 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2334 }
2335 else
2336 {
2337 RTPrintf("User name: %ls\n", User.raw());
2338 RTPrintf("Domain: %ls\n", Domain.raw());
2339 RTPrintf("Client name: %ls\n", ClientName.raw());
2340 RTPrintf("Client IP: %ls\n", ClientIP.raw());
2341 RTPrintf("Client version: %d\n", ClientVersion);
2342 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2343 }
2344 }
2345 }
2346
2347 if (details != VMINFO_MACHINEREADABLE)
2348 RTPrintf("\n");
2349 }
2350
2351 {
2352 /* Video capture */
2353 BOOL bActive = FALSE;
2354 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&bActive), rc);
2355 com::SafeArray<BOOL> screens;
2356 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
2357 ULONG Width;
2358 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
2359 ULONG Height;
2360 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
2361 ULONG Rate;
2362 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
2363 ULONG Fps;
2364 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
2365 Bstr File;
2366 CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(File.asOutParam()), rc);
2367 if (details == VMINFO_MACHINEREADABLE)
2368 {
2369 RTPrintf("vcpenabled=\"%s\"\n", bActive ? "on" : "off");
2370 RTPrintf("vcpscreens=");
2371 bool fComma = false;
2372 for (unsigned i = 0; i < screens.size(); i++)
2373 if (screens[i])
2374 {
2375 RTPrintf("%s%u", fComma ? "," : "", i);
2376 fComma = true;
2377 }
2378 RTPrintf("\n");
2379 RTPrintf("vcpfile=\"%ls\"\n", File.raw());
2380 RTPrintf("vcpwidth=%u\n", (unsigned)Width);
2381 RTPrintf("vcpheight=%u\n", (unsigned)Height);
2382 RTPrintf("vcprate=%u\n", (unsigned)Rate);
2383 RTPrintf("vcpfps=%u\n", (unsigned)Fps);
2384 }
2385 else
2386 {
2387 RTPrintf("Video capturing: %s\n", bActive ? "active" : "not active");
2388 RTPrintf("Capture screens: ");
2389 bool fComma = false;
2390 for (unsigned i = 0; i < screens.size(); i++)
2391 if (screens[i])
2392 {
2393 RTPrintf("%s%u", fComma ? "," : "", i);
2394 fComma = true;
2395 }
2396 RTPrintf("\n");
2397 RTPrintf("Capture file: %ls\n", File.raw());
2398 RTPrintf("Capture dimensions: %ux%u\n", Width, Height);
2399 RTPrintf("Capture rate: %u kbps\n", Rate);
2400 RTPrintf("Capture FPS: %u\n", Fps);
2401 RTPrintf("\n");
2402 }
2403 }
2404
2405 if ( details == VMINFO_STANDARD
2406 || details == VMINFO_FULL
2407 || details == VMINFO_MACHINEREADABLE)
2408 {
2409 Bstr description;
2410 machine->COMGETTER(Description)(description.asOutParam());
2411 if (!description.isEmpty())
2412 {
2413 if (details == VMINFO_MACHINEREADABLE)
2414 RTPrintf("description=\"%ls\"\n", description.raw());
2415 else
2416 RTPrintf("Description:\n%ls\n", description.raw());
2417 }
2418 }
2419
2420 if (details != VMINFO_MACHINEREADABLE)
2421 RTPrintf("Guest:\n\n");
2422
2423 ULONG guestVal;
2424 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2425 if (SUCCEEDED(rc))
2426 {
2427 if (details == VMINFO_MACHINEREADABLE)
2428 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2429 else
2430 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2431 }
2432
2433 if (console)
2434 {
2435 ComPtr<IGuest> guest;
2436 rc = console->COMGETTER(Guest)(guest.asOutParam());
2437 if (SUCCEEDED(rc) && !guest.isNull())
2438 {
2439 Bstr guestString;
2440 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2441 if ( SUCCEEDED(rc)
2442 && !guestString.isEmpty())
2443 {
2444 if (details == VMINFO_MACHINEREADABLE)
2445 RTPrintf("GuestOSType=\"%ls\"\n", guestString.raw());
2446 else
2447 RTPrintf("OS type: %ls\n", guestString.raw());
2448 }
2449
2450 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2451 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2452 if (SUCCEEDED(rc))
2453 {
2454 if (details == VMINFO_MACHINEREADABLE)
2455 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2456 else
2457 RTPrintf("Additions run level: %u\n", guestRunLevel);
2458 }
2459
2460 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2461 if ( SUCCEEDED(rc)
2462 && !guestString.isEmpty())
2463 {
2464 ULONG uRevision;
2465 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2466 if (FAILED(rc))
2467 uRevision = 0;
2468
2469 if (details == VMINFO_MACHINEREADABLE)
2470 RTPrintf("GuestAdditionsVersion=\"%ls r%u\"\n", guestString.raw(), uRevision);
2471 else
2472 RTPrintf("Additions version: %ls r%u\n\n", guestString.raw(), uRevision);
2473 }
2474
2475 if (details != VMINFO_MACHINEREADABLE)
2476 RTPrintf("\nGuest Facilities:\n\n");
2477
2478 /* Print information about known Guest Additions facilities: */
2479 SafeIfaceArray <IAdditionsFacility> collFac;
2480 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2481 LONG64 lLastUpdatedMS;
2482 char szLastUpdated[32];
2483 AdditionsFacilityStatus_T curStatus;
2484 for (size_t index = 0; index < collFac.size(); ++index)
2485 {
2486 ComPtr<IAdditionsFacility> fac = collFac[index];
2487 if (fac)
2488 {
2489 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2490 if (!guestString.isEmpty())
2491 {
2492 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2493 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2494 if (details == VMINFO_MACHINEREADABLE)
2495 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2496 guestString.raw(), curStatus, lLastUpdatedMS);
2497 else
2498 {
2499 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2500 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2501 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2502 }
2503 }
2504 else
2505 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2506 }
2507 else
2508 AssertMsgFailed(("Invalid facility returned!\n"));
2509 }
2510 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2511 RTPrintf("No active facilities.\n");
2512 }
2513 }
2514
2515 if (details != VMINFO_MACHINEREADABLE)
2516 RTPrintf("\n");
2517
2518 /*
2519 * snapshots
2520 */
2521 ComPtr<ISnapshot> snapshot;
2522 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2523 if (SUCCEEDED(rc) && snapshot)
2524 {
2525 ComPtr<ISnapshot> currentSnapshot;
2526 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2527 if (SUCCEEDED(rc))
2528 {
2529 if (details != VMINFO_MACHINEREADABLE)
2530 RTPrintf("Snapshots:\n\n");
2531 showSnapshots(snapshot, currentSnapshot, details);
2532 }
2533 }
2534
2535 if (details != VMINFO_MACHINEREADABLE)
2536 RTPrintf("\n");
2537 return S_OK;
2538}
2539
2540#if defined(_MSC_VER)
2541# pragma optimize("", on)
2542#endif
2543
2544static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2545{
2546 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2547 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2548 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2549 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2550 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2551};
2552
2553int handleShowVMInfo(HandlerArg *a)
2554{
2555 HRESULT rc;
2556 const char *VMNameOrUuid = NULL;
2557 bool fLog = false;
2558 uint32_t uLogIdx = 0;
2559 bool fDetails = false;
2560 bool fMachinereadable = false;
2561
2562 int c;
2563 RTGETOPTUNION ValueUnion;
2564 RTGETOPTSTATE GetState;
2565 // start at 0 because main() has hacked both the argc and argv given to us
2566 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2567 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2568 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2569 {
2570 switch (c)
2571 {
2572 case 'D': // --details
2573 fDetails = true;
2574 break;
2575
2576 case 'M': // --machinereadable
2577 fMachinereadable = true;
2578 break;
2579
2580 case 'l': // --log
2581 fLog = true;
2582 uLogIdx = ValueUnion.u32;
2583 break;
2584
2585 case VINF_GETOPT_NOT_OPTION:
2586 if (!VMNameOrUuid)
2587 VMNameOrUuid = ValueUnion.psz;
2588 else
2589 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2590 break;
2591
2592 default:
2593 if (c > 0)
2594 {
2595 if (RT_C_IS_PRINT(c))
2596 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2597 else
2598 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2599 }
2600 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2601 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2602 else if (ValueUnion.pDef)
2603 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2604 else
2605 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2606 }
2607 }
2608
2609 /* check for required options */
2610 if (!VMNameOrUuid)
2611 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2612
2613 /* try to find the given machine */
2614 ComPtr<IMachine> machine;
2615 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2616 machine.asOutParam()));
2617 if (FAILED(rc))
2618 return 1;
2619
2620 /* Printing the log is exclusive. */
2621 if (fLog && (fMachinereadable || fDetails))
2622 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2623
2624 if (fLog)
2625 {
2626 ULONG64 uOffset = 0;
2627 SafeArray<BYTE> aLogData;
2628 ULONG cbLogData;
2629 while (true)
2630 {
2631 /* Reset the array */
2632 aLogData.setNull();
2633 /* Fetch a chunk of the log file */
2634 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2635 ComSafeArrayAsOutParam(aLogData)));
2636 cbLogData = aLogData.size();
2637 if (cbLogData == 0)
2638 break;
2639 /* aLogData has a platform dependent line ending, standardize on
2640 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2641 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2642 ULONG cbLogDataPrint = cbLogData;
2643 for (BYTE *s = aLogData.raw(), *d = s;
2644 s - aLogData.raw() < (ssize_t)cbLogData;
2645 s++, d++)
2646 {
2647 if (*s == '\r')
2648 {
2649 /* skip over CR, adjust destination */
2650 d--;
2651 cbLogDataPrint--;
2652 }
2653 else if (s != d)
2654 *d = *s;
2655 }
2656 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2657 uOffset += cbLogData;
2658 }
2659 }
2660 else
2661 {
2662 /* 2nd option can be -details or -argdump */
2663 VMINFO_DETAILS details = VMINFO_NONE;
2664 if (fMachinereadable)
2665 details = VMINFO_MACHINEREADABLE;
2666 else if (fDetails)
2667 details = VMINFO_FULL;
2668 else
2669 details = VMINFO_STANDARD;
2670
2671 ComPtr<IConsole> console;
2672
2673 /* open an existing session for the VM */
2674 rc = machine->LockMachine(a->session, LockType_Shared);
2675 if (SUCCEEDED(rc))
2676 /* get the session machine */
2677 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2678 if (SUCCEEDED(rc))
2679 /* get the session console */
2680 rc = a->session->COMGETTER(Console)(console.asOutParam());
2681
2682 rc = showVMInfo(a->virtualBox, machine, details, console);
2683
2684 if (console)
2685 a->session->UnlockMachine();
2686 }
2687
2688 return SUCCEEDED(rc) ? 0 : 1;
2689}
2690
2691#endif /* !VBOX_ONLY_DOCS */
2692/* 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