VirtualBox

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

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

Frontends/VBoxManage: adapt to reduced Console functionality, do not call things which are no longer there (and would be ignored anyway)

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

© 2023 Oracle
ContactPrivacy policyTerms of Use