VirtualBox

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

Last change on this file since 40418 was 40418, checked in by vboxsync, 13 years ago

Main: Extended IMachine and the settings XML with three tracing related properties.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette