VirtualBox

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

Last change on this file since 55263 was 55259, checked in by vboxsync, 10 years ago

Main/Serial+Devices/Serial: new TCP backend for serial port. Contributed by Alexey Eromenko. Thanks!
Frontends/VirtualBox+VBoxManage: adapted accordingly

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