VirtualBox

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

Last change on this file since 45559 was 44948, checked in by vboxsync, 12 years ago

Main/SystemProperties+Machine: new config setting for default VM frontend.
Frontend/VirtualBox+VBoxManage: changes to use the default VM frontend when starting a VM, other minor cleanups
Main/xml/*.xsd: attempt to bring the XML schema close to reality
doc/manual: document the new possibilities, and fix a few long standing inaccuracies

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