VirtualBox

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

Last change on this file since 44623 was 44028, checked in by vboxsync, 12 years ago

Frontends/VBoxManage: improve snapshot information, unify wrappers for opening a medium object, cleanup

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