VirtualBox

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

Last change on this file since 37722 was 37695, checked in by vboxsync, 14 years ago

Main/MediumAttachment+Machine: maintain a flag whether the medium was ejected, and add a method to query this information

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