VirtualBox

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

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

Main/NetworkAdapter+Machine+Appliance+SystemProperties+Medium+Console+Settings+IDL: make NAT networking a separate network attachment type which improves the user experience, store the necessary settings, plus changing the design of the methods which will move images and entire VMs, they lacked a progress object
Frontends/VirtualBox: adapted fully, can configure NAT networks with proper drop down list support
Frontends/VBoxManage: also supports NAT networks completely, and adds the long missing code to list intnets

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