VirtualBox

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

Last change on this file since 59381 was 59269, checked in by vboxsync, 9 years ago

gcc warnings

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