VirtualBox

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

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

Frontends/VBoxManage: show execution cap in the detailed VM info

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 95.2 KB
Line 
1/* $Id: VBoxManageInfo.cpp 37671 2011-06-28 18:36:47Z 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 rc = machine->GetMedium(storageCtlName.raw(), i, k,
776 medium.asOutParam());
777 if (SUCCEEDED(rc) && medium)
778 {
779 BOOL fPassthrough;
780 ComPtr<IMediumAttachment> mediumAttach;
781
782 rc = machine->GetMediumAttachment(storageCtlName.raw(),
783 i, k,
784 mediumAttach.asOutParam());
785 if (SUCCEEDED(rc) && mediumAttach)
786 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
787
788 medium->COMGETTER(Location)(filePath.asOutParam());
789 medium->COMGETTER(Id)(uuid.asOutParam());
790
791 if (details == VMINFO_MACHINEREADABLE)
792 {
793 RTPrintf("\"%lS-%d-%d\"=\"%lS\"\n", storageCtlName.raw(),
794 i, k, filePath.raw());
795 RTPrintf("\"%lS-ImageUUID-%d-%d\"=\"%s\"\n",
796 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
797 if (fPassthrough)
798 RTPrintf("\"%lS-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
799 fPassthrough ? "on" : "off");
800 }
801 else
802 {
803 RTPrintf("%lS (%d, %d): %lS (UUID: %s)",
804 storageCtlName.raw(), i, k, filePath.raw(),
805 Utf8Str(uuid).c_str());
806 if (fPassthrough)
807 RTPrintf(" (passthrough enabled)");
808 RTPrintf("\n");
809 }
810 }
811 else if (SUCCEEDED(rc))
812 {
813 if (details == VMINFO_MACHINEREADABLE)
814 RTPrintf("\"%lS-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
815 else
816 RTPrintf("%lS (%d, %d): Empty\n", storageCtlName.raw(), i, k);
817 }
818 else
819 {
820 if (details == VMINFO_MACHINEREADABLE)
821 RTPrintf("\"%lS-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
822 }
823 }
824 }
825 }
826
827 /* get the maximum amount of NICS */
828 ULONG maxNICs = getMaxNics(virtualBox, machine);
829
830 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
831 {
832 ComPtr<INetworkAdapter> nic;
833 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
834 if (SUCCEEDED(rc) && nic)
835 {
836 BOOL fEnabled;
837 nic->COMGETTER(Enabled)(&fEnabled);
838 if (!fEnabled)
839 {
840 if (details == VMINFO_MACHINEREADABLE)
841 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
842 else
843 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
844 }
845 else
846 {
847 Bstr strMACAddress;
848 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
849 Utf8Str strAttachment;
850 Utf8Str strNatSettings = "";
851 Utf8Str strNatForwardings = "";
852 NetworkAttachmentType_T attachment;
853 nic->COMGETTER(AttachmentType)(&attachment);
854 switch (attachment)
855 {
856 case NetworkAttachmentType_Null:
857 if (details == VMINFO_MACHINEREADABLE)
858 strAttachment = "null";
859 else
860 strAttachment = "none";
861 break;
862
863 case NetworkAttachmentType_NAT:
864 {
865 Bstr strNetwork;
866 ComPtr<INATEngine> driver;
867 nic->COMGETTER(NatDriver)(driver.asOutParam());
868 driver->COMGETTER(Network)(strNetwork.asOutParam());
869 com::SafeArray<BSTR> forwardings;
870 driver->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
871 strNatForwardings = "";
872 for (size_t i = 0; i < forwardings.size(); ++i)
873 {
874 bool fSkip = false;
875 uint16_t port = 0;
876 BSTR r = forwardings[i];
877 Utf8Str utf = Utf8Str(r);
878 Utf8Str strName;
879 Utf8Str strProto;
880 Utf8Str strHostPort;
881 Utf8Str strHostIP;
882 Utf8Str strGuestPort;
883 Utf8Str strGuestIP;
884 size_t pos, ppos;
885 pos = ppos = 0;
886 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
887 do { \
888 pos = str.find(",", ppos); \
889 if (pos == Utf8Str::npos) \
890 { \
891 Log(( #res " extracting from %s is failed\n", str.c_str())); \
892 fSkip = true; \
893 } \
894 res = str.substr(ppos, pos - ppos); \
895 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
896 ppos = pos + 1; \
897 } while (0)
898 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
899 if (fSkip) continue;
900 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
901 if (fSkip) continue;
902 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
903 if (fSkip) continue;
904 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
905 if (fSkip) continue;
906 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
907 if (fSkip) continue;
908 strGuestPort = utf.substr(ppos, utf.length() - ppos);
909 #undef ITERATE_TO_NEXT_TERM
910 switch (strProto.toUInt32())
911 {
912 case NATProtocol_TCP:
913 strProto = "tcp";
914 break;
915 case NATProtocol_UDP:
916 strProto = "udp";
917 break;
918 default:
919 strProto = "unk";
920 break;
921 }
922 if (details == VMINFO_MACHINEREADABLE)
923 {
924 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
925 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
926 strHostIP.c_str(), strHostPort.c_str(),
927 strGuestIP.c_str(), strGuestPort.c_str());
928 }
929 else
930 {
931 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
932 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
933 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
934 strHostIP.c_str(), strHostPort.c_str(),
935 strGuestIP.c_str(), strGuestPort.c_str());
936 }
937 }
938 ULONG mtu = 0;
939 ULONG sockSnd = 0;
940 ULONG sockRcv = 0;
941 ULONG tcpSnd = 0;
942 ULONG tcpRcv = 0;
943 driver->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
944
945 if (details == VMINFO_MACHINEREADABLE)
946 {
947 RTPrintf("natnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
948 strAttachment = "nat";
949 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
950 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
951 }
952 else
953 {
954 strAttachment = "NAT";
955 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
956 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
957 }
958 break;
959 }
960
961 case NetworkAttachmentType_Bridged:
962 {
963 Bstr strBridgeAdp;
964 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
965 if (details == VMINFO_MACHINEREADABLE)
966 {
967 RTPrintf("bridgeadapter%d=\"%lS\"\n", currentNIC + 1, strBridgeAdp.raw());
968 strAttachment = "bridged";
969 }
970 else
971 strAttachment = Utf8StrFmt("Bridged Interface '%lS'", strBridgeAdp.raw());
972 break;
973 }
974
975 case NetworkAttachmentType_Internal:
976 {
977 Bstr strNetwork;
978 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
979 if (details == VMINFO_MACHINEREADABLE)
980 {
981 RTPrintf("intnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
982 strAttachment = "intnet";
983 }
984 else
985 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
986 break;
987 }
988
989 case NetworkAttachmentType_HostOnly:
990 {
991 Bstr strHostonlyAdp;
992 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
993 if (details == VMINFO_MACHINEREADABLE)
994 {
995 RTPrintf("hostonlyadapter%d=\"%lS\"\n", currentNIC + 1, strHostonlyAdp.raw());
996 strAttachment = "hostonly";
997 }
998 else
999 strAttachment = Utf8StrFmt("Host-only Interface '%lS'", strHostonlyAdp.raw());
1000 break;
1001 }
1002 case NetworkAttachmentType_Generic:
1003 {
1004 Bstr strGenericDriver;
1005 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1006 if (details == VMINFO_MACHINEREADABLE)
1007 {
1008 RTPrintf("generic%d=\"%lS\"\n", currentNIC + 1, strGenericDriver.raw());
1009 strAttachment = "Generic";
1010 }
1011 else
1012 {
1013 strAttachment = Utf8StrFmt("Generic '%lS'", strGenericDriver.raw());
1014
1015 // show the generic properties
1016 com::SafeArray<BSTR> aProperties;
1017 com::SafeArray<BSTR> aValues;
1018 rc = nic->GetProperties(NULL,
1019 ComSafeArrayAsOutParam(aProperties),
1020 ComSafeArrayAsOutParam(aValues));
1021 if (SUCCEEDED(rc))
1022 {
1023 strAttachment += " { ";
1024 for (unsigned i = 0; i < aProperties.size(); ++i)
1025 strAttachment += Utf8StrFmt(!i ? "%lS='%lS'" : ", %lS='%lS'",
1026 aProperties[i], aValues[i]);
1027 strAttachment += " }";
1028 }
1029 }
1030 break;
1031 }
1032 default:
1033 strAttachment = "unknown";
1034 break;
1035 }
1036
1037 /* cable connected */
1038 BOOL fConnected;
1039 nic->COMGETTER(CableConnected)(&fConnected);
1040
1041 /* promisc policy */
1042 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1043 CHECK_ERROR2_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1044 const char *pszPromiscuousGuestPolicy;
1045 switch (enmPromiscModePolicy)
1046 {
1047 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1048 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1049 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1050 default: AssertFailedReturn(VERR_INTERNAL_ERROR_4);
1051 }
1052
1053 /* trace stuff */
1054 BOOL fTraceEnabled;
1055 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1056 Bstr traceFile;
1057 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1058
1059 /* NIC type */
1060 NetworkAdapterType_T NICType;
1061 nic->COMGETTER(AdapterType)(&NICType);
1062 const char *pszNICType;
1063 switch (NICType)
1064 {
1065 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1066 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1067#ifdef VBOX_WITH_E1000
1068 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1069 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1070 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1071#endif
1072#ifdef VBOX_WITH_VIRTIO
1073 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1074#endif
1075 default: AssertFailed(); pszNICType = "unknown"; break;
1076 }
1077
1078 /* reported line speed */
1079 ULONG ulLineSpeed;
1080 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1081
1082 /* boot priority of the adapter */
1083 ULONG ulBootPriority;
1084 nic->COMGETTER(BootPriority)(&ulBootPriority);
1085
1086 if (details == VMINFO_MACHINEREADABLE)
1087 {
1088 RTPrintf("macaddress%d=\"%lS\"\n", currentNIC + 1, strMACAddress.raw());
1089 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1090 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1091 }
1092 else
1093 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",
1094 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
1095 fConnected ? "on" : "off",
1096 fTraceEnabled ? "on" : "off",
1097 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1098 pszNICType,
1099 ulLineSpeed / 1000,
1100 (int)ulBootPriority,
1101 pszPromiscuousGuestPolicy);
1102 if (strNatSettings.length())
1103 RTPrintf(strNatSettings.c_str());
1104 if (strNatForwardings.length())
1105 RTPrintf(strNatForwardings.c_str());
1106 }
1107 }
1108 }
1109
1110 /* Pointing device information */
1111 PointingHidType_T aPointingHid;
1112 const char *pszHid = "Unknown";
1113 const char *pszMrHid = "unknown";
1114 machine->COMGETTER(PointingHidType)(&aPointingHid);
1115 switch (aPointingHid)
1116 {
1117 case PointingHidType_None:
1118 pszHid = "None";
1119 pszMrHid = "none";
1120 break;
1121 case PointingHidType_PS2Mouse:
1122 pszHid = "PS/2 Mouse";
1123 pszMrHid = "ps2mouse";
1124 break;
1125 case PointingHidType_USBMouse:
1126 pszHid = "USB Mouse";
1127 pszMrHid = "usbmouse";
1128 break;
1129 case PointingHidType_USBTablet:
1130 pszHid = "USB Tablet";
1131 pszMrHid = "usbtablet";
1132 break;
1133 case PointingHidType_ComboMouse:
1134 pszHid = "USB Tablet and PS/2 Mouse";
1135 pszMrHid = "combomouse";
1136 break;
1137 default:
1138 break;
1139 }
1140 if (details == VMINFO_MACHINEREADABLE)
1141 RTPrintf("hidpointing=\"%s\"\n", pszMrHid);
1142 else
1143 RTPrintf("Pointing Device: %s\n", pszHid);
1144
1145 /* Keyboard device information */
1146 KeyboardHidType_T aKeyboardHid;
1147 machine->COMGETTER(KeyboardHidType)(&aKeyboardHid);
1148 pszHid = "Unknown";
1149 pszMrHid = "unknown";
1150 switch (aKeyboardHid)
1151 {
1152 case KeyboardHidType_None:
1153 pszHid = "None";
1154 pszMrHid = "none";
1155 break;
1156 case KeyboardHidType_PS2Keyboard:
1157 pszHid = "PS/2 Keyboard";
1158 pszMrHid = "ps2kbd";
1159 break;
1160 case KeyboardHidType_USBKeyboard:
1161 pszHid = "USB Keyboard";
1162 pszMrHid = "usbkbd";
1163 break;
1164 case KeyboardHidType_ComboKeyboard:
1165 pszHid = "USB and PS/2 Keyboard";
1166 pszMrHid = "combokbd";
1167 break;
1168 default:
1169 break;
1170 }
1171 if (details == VMINFO_MACHINEREADABLE)
1172 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHid);
1173 else
1174 RTPrintf("Keyboard Device: %s\n", pszHid);
1175
1176 /* get the maximum amount of UARTs */
1177 ComPtr<ISystemProperties> sysProps;
1178 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1179
1180 ULONG maxUARTs = 0;
1181 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1182 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1183 {
1184 ComPtr<ISerialPort> uart;
1185 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1186 if (SUCCEEDED(rc) && uart)
1187 {
1188 BOOL fEnabled;
1189 uart->COMGETTER(Enabled)(&fEnabled);
1190 if (!fEnabled)
1191 {
1192 if (details == VMINFO_MACHINEREADABLE)
1193 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1194 else
1195 RTPrintf("UART %d: disabled\n", currentUART + 1);
1196 }
1197 else
1198 {
1199 ULONG ulIRQ, ulIOBase;
1200 PortMode_T HostMode;
1201 Bstr path;
1202 BOOL fServer;
1203 uart->COMGETTER(IRQ)(&ulIRQ);
1204 uart->COMGETTER(IOBase)(&ulIOBase);
1205 uart->COMGETTER(Path)(path.asOutParam());
1206 uart->COMGETTER(Server)(&fServer);
1207 uart->COMGETTER(HostMode)(&HostMode);
1208
1209 if (details == VMINFO_MACHINEREADABLE)
1210 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1211 ulIOBase, ulIRQ);
1212 else
1213 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1214 currentUART + 1, ulIOBase, ulIRQ);
1215 switch (HostMode)
1216 {
1217 default:
1218 case PortMode_Disconnected:
1219 if (details == VMINFO_MACHINEREADABLE)
1220 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1221 else
1222 RTPrintf(", disconnected\n");
1223 break;
1224 case PortMode_RawFile:
1225 if (details == VMINFO_MACHINEREADABLE)
1226 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
1227 path.raw());
1228 else
1229 RTPrintf(", attached to raw file '%lS'\n",
1230 path.raw());
1231 break;
1232 case PortMode_HostPipe:
1233 if (details == VMINFO_MACHINEREADABLE)
1234 RTPrintf("uartmode%d=\"%s,%lS\"\n", currentUART + 1,
1235 fServer ? "server" : "client", path.raw());
1236 else
1237 RTPrintf(", attached to pipe (%s) '%lS'\n",
1238 fServer ? "server" : "client", path.raw());
1239 break;
1240 case PortMode_HostDevice:
1241 if (details == VMINFO_MACHINEREADABLE)
1242 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
1243 path.raw());
1244 else
1245 RTPrintf(", attached to device '%lS'\n", path.raw());
1246 break;
1247 }
1248 }
1249 }
1250 }
1251
1252 ComPtr<IAudioAdapter> AudioAdapter;
1253 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1254 if (SUCCEEDED(rc))
1255 {
1256 const char *pszDrv = "Unknown";
1257 const char *pszCtrl = "Unknown";
1258 BOOL fEnabled;
1259 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1260 if (SUCCEEDED(rc) && fEnabled)
1261 {
1262 AudioDriverType_T enmDrvType;
1263 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1264 switch (enmDrvType)
1265 {
1266 case AudioDriverType_Null:
1267 if (details == VMINFO_MACHINEREADABLE)
1268 pszDrv = "null";
1269 else
1270 pszDrv = "Null";
1271 break;
1272 case AudioDriverType_WinMM:
1273 if (details == VMINFO_MACHINEREADABLE)
1274 pszDrv = "winmm";
1275 else
1276 pszDrv = "WINMM";
1277 break;
1278 case AudioDriverType_DirectSound:
1279 if (details == VMINFO_MACHINEREADABLE)
1280 pszDrv = "dsound";
1281 else
1282 pszDrv = "DSOUND";
1283 break;
1284 case AudioDriverType_OSS:
1285 if (details == VMINFO_MACHINEREADABLE)
1286 pszDrv = "oss";
1287 else
1288 pszDrv = "OSS";
1289 break;
1290 case AudioDriverType_ALSA:
1291 if (details == VMINFO_MACHINEREADABLE)
1292 pszDrv = "alsa";
1293 else
1294 pszDrv = "ALSA";
1295 break;
1296 case AudioDriverType_Pulse:
1297 if (details == VMINFO_MACHINEREADABLE)
1298 pszDrv = "pulse";
1299 else
1300 pszDrv = "PulseAudio";
1301 break;
1302 case AudioDriverType_CoreAudio:
1303 if (details == VMINFO_MACHINEREADABLE)
1304 pszDrv = "coreaudio";
1305 else
1306 pszDrv = "CoreAudio";
1307 break;
1308 case AudioDriverType_SolAudio:
1309 if (details == VMINFO_MACHINEREADABLE)
1310 pszDrv = "solaudio";
1311 else
1312 pszDrv = "SolAudio";
1313 break;
1314 default:
1315 if (details == VMINFO_MACHINEREADABLE)
1316 pszDrv = "unknown";
1317 break;
1318 }
1319 AudioControllerType_T enmCtrlType;
1320 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1321 switch (enmCtrlType)
1322 {
1323 case AudioControllerType_AC97:
1324 if (details == VMINFO_MACHINEREADABLE)
1325 pszCtrl = "ac97";
1326 else
1327 pszCtrl = "AC97";
1328 break;
1329 case AudioControllerType_SB16:
1330 if (details == VMINFO_MACHINEREADABLE)
1331 pszCtrl = "sb16";
1332 else
1333 pszCtrl = "SB16";
1334 break;
1335 case AudioControllerType_HDA:
1336 if (details == VMINFO_MACHINEREADABLE)
1337 pszCtrl = "hda";
1338 else
1339 pszCtrl = "HDA";
1340 break;
1341 }
1342 }
1343 else
1344 fEnabled = FALSE;
1345 if (details == VMINFO_MACHINEREADABLE)
1346 {
1347 if (fEnabled)
1348 RTPrintf("audio=\"%s\"\n", pszDrv);
1349 else
1350 RTPrintf("audio=\"none\"\n");
1351 }
1352 else
1353 {
1354 RTPrintf("Audio: %s",
1355 fEnabled ? "enabled" : "disabled");
1356 if (fEnabled)
1357 RTPrintf(" (Driver: %s, Controller: %s)",
1358 pszDrv, pszCtrl);
1359 RTPrintf("\n");
1360 }
1361 }
1362
1363 /* Shared clipboard */
1364 {
1365 const char *psz = "Unknown";
1366 ClipboardMode_T enmMode;
1367 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1368 switch (enmMode)
1369 {
1370 case ClipboardMode_Disabled:
1371 if (details == VMINFO_MACHINEREADABLE)
1372 psz = "disabled";
1373 else
1374 psz = "disabled";
1375 break;
1376 case ClipboardMode_HostToGuest:
1377 if (details == VMINFO_MACHINEREADABLE)
1378 psz = "hosttoguest";
1379 else
1380 psz = "HostToGuest";
1381 break;
1382 case ClipboardMode_GuestToHost:
1383 if (details == VMINFO_MACHINEREADABLE)
1384 psz = "guesttohost";
1385 else
1386 psz = "GuestToHost";
1387 break;
1388 case ClipboardMode_Bidirectional:
1389 if (details == VMINFO_MACHINEREADABLE)
1390 psz = "bidirectional";
1391 else
1392 psz = "Bidirectional";
1393 break;
1394 default:
1395 if (details == VMINFO_MACHINEREADABLE)
1396 psz = "unknown";
1397 break;
1398 }
1399 if (details == VMINFO_MACHINEREADABLE)
1400 RTPrintf("clipboard=\"%s\"\n", psz);
1401 else
1402 RTPrintf("Clipboard Mode: %s\n", psz);
1403 }
1404
1405 if (console)
1406 {
1407 ComPtr<IDisplay> display;
1408 CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
1409 do
1410 {
1411 ULONG xRes, yRes, bpp;
1412 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp);
1413 if (rc == E_ACCESSDENIED)
1414 break; /* VM not powered up */
1415 if (FAILED(rc))
1416 {
1417 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1418 GluePrintErrorInfo(info);
1419 return rc;
1420 }
1421 if (details == VMINFO_MACHINEREADABLE)
1422 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1423 else
1424 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1425 }
1426 while (0);
1427 }
1428
1429 /*
1430 * Remote Desktop
1431 */
1432 ComPtr<IVRDEServer> vrdeServer;
1433 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1434 if (SUCCEEDED(rc) && vrdeServer)
1435 {
1436 BOOL fEnabled = false;
1437 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1438 if (fEnabled)
1439 {
1440 LONG currentPort = -1;
1441 Bstr ports;
1442 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1443 Bstr address;
1444 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1445 BOOL fMultiCon;
1446 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1447 BOOL fReuseCon;
1448 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1449 Bstr videoChannel;
1450 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1451 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1452 || (videoChannel == "1");
1453 Bstr videoChannelQuality;
1454 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1455 AuthType_T authType;
1456 const char *strAuthType;
1457 vrdeServer->COMGETTER(AuthType)(&authType);
1458 switch (authType)
1459 {
1460 case AuthType_Null:
1461 strAuthType = "null";
1462 break;
1463 case AuthType_External:
1464 strAuthType = "external";
1465 break;
1466 case AuthType_Guest:
1467 strAuthType = "guest";
1468 break;
1469 default:
1470 strAuthType = "unknown";
1471 break;
1472 }
1473 if (console)
1474 {
1475 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1476 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1477 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1478 if (rc == E_ACCESSDENIED)
1479 {
1480 currentPort = -1; /* VM not powered up */
1481 }
1482 if (FAILED(rc))
1483 {
1484 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1485 GluePrintErrorInfo(info);
1486 return rc;
1487 }
1488 }
1489 if (details == VMINFO_MACHINEREADABLE)
1490 {
1491 RTPrintf("vrde=\"on\"\n");
1492 RTPrintf("vrdeport=%d\n", currentPort);
1493 RTPrintf("vrdeports=\"%lS\"\n", ports.raw());
1494 RTPrintf("vrdeaddress=\"%lS\"\n", address.raw());
1495 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1496 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1497 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1498 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1499 if (fVideoChannel)
1500 RTPrintf("vrdevideochannelquality=\"%lS\"\n", videoChannelQuality.raw());
1501 }
1502 else
1503 {
1504 if (address.isEmpty())
1505 address = "0.0.0.0";
1506 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);
1507 if (console && currentPort != -1 && currentPort != 0)
1508 RTPrintf("VRDE port: %d\n", currentPort);
1509 if (fVideoChannel)
1510 RTPrintf("Video redirection: enabled (Quality %lS)\n", videoChannelQuality.raw());
1511 else
1512 RTPrintf("Video redirection: disabled\n");
1513 }
1514 com::SafeArray<BSTR> aProperties;
1515 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1516 {
1517 unsigned i;
1518 for (i = 0; i < aProperties.size(); ++i)
1519 {
1520 Bstr value;
1521 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1522 if (details == VMINFO_MACHINEREADABLE)
1523 {
1524 if (value.isEmpty())
1525 RTPrintf("vrdeproperty[%lS]=<not set>\n", aProperties[i]);
1526 else
1527 RTPrintf("vrdeproperty[%lS]=\"%lS\"\n", aProperties[i], value.raw());
1528 }
1529 else
1530 {
1531 if (value.isEmpty())
1532 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1533 else
1534 RTPrintf("VRDE property: %-10lS = \"%lS\"\n", aProperties[i], value.raw());
1535 }
1536 }
1537 }
1538 }
1539 else
1540 {
1541 if (details == VMINFO_MACHINEREADABLE)
1542 RTPrintf("vrde=\"off\"\n");
1543 else
1544 RTPrintf("VRDE: disabled\n");
1545 }
1546 }
1547
1548 /*
1549 * USB.
1550 */
1551 ComPtr<IUSBController> USBCtl;
1552 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1553 if (SUCCEEDED(rc))
1554 {
1555 BOOL fEnabled;
1556 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1557 if (FAILED(rc))
1558 fEnabled = false;
1559 if (details == VMINFO_MACHINEREADABLE)
1560 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1561 else
1562 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1563
1564 SafeIfaceArray <IUSBDeviceFilter> Coll;
1565 rc = USBCtl->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1566 if (SUCCEEDED(rc))
1567 {
1568 if (details != VMINFO_MACHINEREADABLE)
1569 RTPrintf("\nUSB Device Filters:\n\n");
1570
1571 if (Coll.size() == 0)
1572 {
1573 if (details != VMINFO_MACHINEREADABLE)
1574 RTPrintf("<none>\n\n");
1575 }
1576 else
1577 {
1578 for (size_t index = 0; index < Coll.size(); ++index)
1579 {
1580 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1581
1582 /* Query info. */
1583
1584 if (details != VMINFO_MACHINEREADABLE)
1585 RTPrintf("Index: %zu\n", index);
1586
1587 BOOL bActive = FALSE;
1588 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1589 if (details == VMINFO_MACHINEREADABLE)
1590 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1591 else
1592 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1593
1594 Bstr bstr;
1595 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1596 if (details == VMINFO_MACHINEREADABLE)
1597 RTPrintf("USBFilterName%zu=\"%lS\"\n", index + 1, bstr.raw());
1598 else
1599 RTPrintf("Name: %lS\n", bstr.raw());
1600 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1601 if (details == VMINFO_MACHINEREADABLE)
1602 RTPrintf("USBFilterVendorId%zu=\"%lS\"\n", index + 1, bstr.raw());
1603 else
1604 RTPrintf("VendorId: %lS\n", bstr.raw());
1605 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1606 if (details == VMINFO_MACHINEREADABLE)
1607 RTPrintf("USBFilterProductId%zu=\"%lS\"\n", index + 1, bstr.raw());
1608 else
1609 RTPrintf("ProductId: %lS\n", bstr.raw());
1610 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1611 if (details == VMINFO_MACHINEREADABLE)
1612 RTPrintf("USBFilterRevision%zu=\"%lS\"\n", index + 1, bstr.raw());
1613 else
1614 RTPrintf("Revision: %lS\n", bstr.raw());
1615 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1616 if (details == VMINFO_MACHINEREADABLE)
1617 RTPrintf("USBFilterManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1618 else
1619 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1620 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1621 if (details == VMINFO_MACHINEREADABLE)
1622 RTPrintf("USBFilterProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1623 else
1624 RTPrintf("Product: %lS\n", bstr.raw());
1625 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1626 if (details == VMINFO_MACHINEREADABLE)
1627 RTPrintf("USBFilterRemote%zu=\"%lS\"\n", index + 1, bstr.raw());
1628 else
1629 RTPrintf("Remote: %lS\n", bstr.raw());
1630 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1631 if (details == VMINFO_MACHINEREADABLE)
1632 RTPrintf("USBFilterSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1633 else
1634 RTPrintf("Serial Number: %lS\n", bstr.raw());
1635 if (details != VMINFO_MACHINEREADABLE)
1636 {
1637 ULONG fMaskedIfs;
1638 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1639 if (fMaskedIfs)
1640 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1641 RTPrintf("\n");
1642 }
1643 }
1644 }
1645 }
1646
1647 if (console)
1648 {
1649 /* scope */
1650 {
1651 if (details != VMINFO_MACHINEREADABLE)
1652 RTPrintf("Available remote USB devices:\n\n");
1653
1654 SafeIfaceArray <IHostUSBDevice> coll;
1655 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1656
1657 if (coll.size() == 0)
1658 {
1659 if (details != VMINFO_MACHINEREADABLE)
1660 RTPrintf("<none>\n\n");
1661 }
1662 else
1663 {
1664 for (size_t index = 0; index < coll.size(); ++index)
1665 {
1666 ComPtr <IHostUSBDevice> dev = coll[index];
1667
1668 /* Query info. */
1669 Bstr id;
1670 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1671 USHORT usVendorId;
1672 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1673 USHORT usProductId;
1674 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1675 USHORT bcdRevision;
1676 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1677
1678 if (details == VMINFO_MACHINEREADABLE)
1679 RTPrintf("USBRemoteUUID%zu=\"%S\"\n"
1680 "USBRemoteVendorId%zu=\"%#06x\"\n"
1681 "USBRemoteProductId%zu=\"%#06x\"\n"
1682 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1683 index + 1, Utf8Str(id).c_str(),
1684 index + 1, usVendorId,
1685 index + 1, usProductId,
1686 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1687 else
1688 RTPrintf("UUID: %S\n"
1689 "VendorId: %#06x (%04X)\n"
1690 "ProductId: %#06x (%04X)\n"
1691 "Revision: %u.%u (%02u%02u)\n",
1692 Utf8Str(id).c_str(),
1693 usVendorId, usVendorId, usProductId, usProductId,
1694 bcdRevision >> 8, bcdRevision & 0xff,
1695 bcdRevision >> 8, bcdRevision & 0xff);
1696
1697 /* optional stuff. */
1698 Bstr bstr;
1699 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1700 if (!bstr.isEmpty())
1701 {
1702 if (details == VMINFO_MACHINEREADABLE)
1703 RTPrintf("USBRemoteManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1704 else
1705 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1706 }
1707 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1708 if (!bstr.isEmpty())
1709 {
1710 if (details == VMINFO_MACHINEREADABLE)
1711 RTPrintf("USBRemoteProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1712 else
1713 RTPrintf("Product: %lS\n", bstr.raw());
1714 }
1715 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1716 if (!bstr.isEmpty())
1717 {
1718 if (details == VMINFO_MACHINEREADABLE)
1719 RTPrintf("USBRemoteSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1720 else
1721 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1722 }
1723 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1724 if (!bstr.isEmpty())
1725 {
1726 if (details == VMINFO_MACHINEREADABLE)
1727 RTPrintf("USBRemoteAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1728 else
1729 RTPrintf("Address: %lS\n", bstr.raw());
1730 }
1731
1732 if (details != VMINFO_MACHINEREADABLE)
1733 RTPrintf("\n");
1734 }
1735 }
1736 }
1737
1738 /* scope */
1739 {
1740 if (details != VMINFO_MACHINEREADABLE)
1741 RTPrintf("Currently Attached USB Devices:\n\n");
1742
1743 SafeIfaceArray <IUSBDevice> coll;
1744 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1745
1746 if (coll.size() == 0)
1747 {
1748 if (details != VMINFO_MACHINEREADABLE)
1749 RTPrintf("<none>\n\n");
1750 }
1751 else
1752 {
1753 for (size_t index = 0; index < coll.size(); ++index)
1754 {
1755 ComPtr <IUSBDevice> dev = coll[index];
1756
1757 /* Query info. */
1758 Bstr id;
1759 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1760 USHORT usVendorId;
1761 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1762 USHORT usProductId;
1763 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1764 USHORT bcdRevision;
1765 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1766
1767 if (details == VMINFO_MACHINEREADABLE)
1768 RTPrintf("USBAttachedUUID%zu=\"%S\"\n"
1769 "USBAttachedVendorId%zu=\"%#06x\"\n"
1770 "USBAttachedProductId%zu=\"%#06x\"\n"
1771 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
1772 index + 1, Utf8Str(id).c_str(),
1773 index + 1, usVendorId,
1774 index + 1, usProductId,
1775 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1776 else
1777 RTPrintf("UUID: %S\n"
1778 "VendorId: %#06x (%04X)\n"
1779 "ProductId: %#06x (%04X)\n"
1780 "Revision: %u.%u (%02u%02u)\n",
1781 Utf8Str(id).c_str(),
1782 usVendorId, usVendorId, usProductId, usProductId,
1783 bcdRevision >> 8, bcdRevision & 0xff,
1784 bcdRevision >> 8, bcdRevision & 0xff);
1785
1786 /* optional stuff. */
1787 Bstr bstr;
1788 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1789 if (!bstr.isEmpty())
1790 {
1791 if (details == VMINFO_MACHINEREADABLE)
1792 RTPrintf("USBAttachedManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1793 else
1794 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1795 }
1796 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1797 if (!bstr.isEmpty())
1798 {
1799 if (details == VMINFO_MACHINEREADABLE)
1800 RTPrintf("USBAttachedProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1801 else
1802 RTPrintf("Product: %lS\n", bstr.raw());
1803 }
1804 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1805 if (!bstr.isEmpty())
1806 {
1807 if (details == VMINFO_MACHINEREADABLE)
1808 RTPrintf("USBAttachedSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1809 else
1810 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1811 }
1812 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1813 if (!bstr.isEmpty())
1814 {
1815 if (details == VMINFO_MACHINEREADABLE)
1816 RTPrintf("USBAttachedAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1817 else
1818 RTPrintf("Address: %lS\n", bstr.raw());
1819 }
1820
1821 if (details != VMINFO_MACHINEREADABLE)
1822 RTPrintf("\n");
1823 }
1824 }
1825 }
1826 }
1827 } /* USB */
1828
1829#ifdef VBOX_WITH_PCI_PASSTHROUGH
1830 /* Host PCI passthrough devices */
1831 {
1832 SafeIfaceArray <IPciDeviceAttachment> assignments;
1833 rc = machine->COMGETTER(PciDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
1834 if (SUCCEEDED(rc))
1835 {
1836 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
1837 {
1838 RTPrintf("\nAttached physical PCI devices:\n\n");
1839 }
1840
1841 for (size_t index = 0; index < assignments.size(); ++index)
1842 {
1843 ComPtr<IPciDeviceAttachment> Assignment = assignments[index];
1844 char szHostPciAddress[32], szGuestPciAddress[32];
1845 LONG iHostPciAddress = -1, iGuestPciAddress = -1;
1846 Bstr DevName;
1847
1848 Assignment->COMGETTER(Name)(DevName.asOutParam());
1849 Assignment->COMGETTER(HostAddress)(&iHostPciAddress);
1850 Assignment->COMGETTER(GuestAddress)(&iGuestPciAddress);
1851 PciBusAddress().fromLong(iHostPciAddress).format(szHostPciAddress, sizeof(szHostPciAddress));
1852 PciBusAddress().fromLong(iGuestPciAddress).format(szGuestPciAddress, sizeof(szGuestPciAddress));
1853
1854 if (details == VMINFO_MACHINEREADABLE)
1855 RTPrintf("AttachedHostPci=%s,%s\n", szHostPciAddress, szGuestPciAddress);
1856 else
1857 RTPrintf(" Host device %lS at %s attached as %s\n", DevName.raw(), szHostPciAddress, szGuestPciAddress);
1858 }
1859
1860 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
1861 {
1862 RTPrintf("\n");
1863 }
1864 }
1865 }
1866 /* Host PCI passthrough devices */
1867#endif
1868
1869 /*
1870 * Shared folders
1871 */
1872 if (details != VMINFO_MACHINEREADABLE)
1873 RTPrintf("Shared folders: ");
1874 uint32_t numSharedFolders = 0;
1875#if 0 // not yet implemented
1876 /* globally shared folders first */
1877 {
1878 SafeIfaceArray <ISharedFolder> sfColl;
1879 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
1880 for (size_t i = 0; i < sfColl.size(); ++i)
1881 {
1882 ComPtr<ISharedFolder> sf = sfColl[i];
1883 Bstr name, hostPath;
1884 sf->COMGETTER(Name)(name.asOutParam());
1885 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1886 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
1887 ++numSharedFolders;
1888 }
1889 }
1890#endif
1891 /* now VM mappings */
1892 {
1893 com::SafeIfaceArray <ISharedFolder> folders;
1894
1895 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1896
1897 for (size_t i = 0; i < folders.size(); ++i)
1898 {
1899 ComPtr <ISharedFolder> sf = folders[i];
1900
1901 Bstr name, hostPath;
1902 BOOL writable;
1903 sf->COMGETTER(Name)(name.asOutParam());
1904 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1905 sf->COMGETTER(Writable)(&writable);
1906 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1907 RTPrintf("\n\n");
1908 if (details == VMINFO_MACHINEREADABLE)
1909 {
1910 RTPrintf("SharedFolderNameMachineMapping%zu=\"%lS\"\n", i + 1,
1911 name.raw());
1912 RTPrintf("SharedFolderPathMachineMapping%zu=\"%lS\"\n", i + 1,
1913 hostPath.raw());
1914 }
1915 else
1916 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
1917 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
1918 ++numSharedFolders;
1919 }
1920 }
1921 /* transient mappings */
1922 if (console)
1923 {
1924 com::SafeIfaceArray <ISharedFolder> folders;
1925
1926 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1927
1928 for (size_t i = 0; i < folders.size(); ++i)
1929 {
1930 ComPtr <ISharedFolder> sf = folders[i];
1931
1932 Bstr name, hostPath;
1933 sf->COMGETTER(Name)(name.asOutParam());
1934 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1935 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1936 RTPrintf("\n\n");
1937 if (details == VMINFO_MACHINEREADABLE)
1938 {
1939 RTPrintf("SharedFolderNameTransientMapping%zu=\"%lS\"\n", i + 1,
1940 name.raw());
1941 RTPrintf("SharedFolderPathTransientMapping%zu=\"%lS\"\n", i + 1,
1942 hostPath.raw());
1943 }
1944 else
1945 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
1946 ++numSharedFolders;
1947 }
1948 }
1949 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1950 RTPrintf("<none>\n");
1951 if (details != VMINFO_MACHINEREADABLE)
1952 RTPrintf("\n");
1953
1954 if (console)
1955 {
1956 /*
1957 * Live VRDE info.
1958 */
1959 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1960 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1961 BOOL Active;
1962 ULONG NumberOfClients;
1963 LONG64 BeginTime;
1964 LONG64 EndTime;
1965 LONG64 BytesSent;
1966 LONG64 BytesSentTotal;
1967 LONG64 BytesReceived;
1968 LONG64 BytesReceivedTotal;
1969 Bstr User;
1970 Bstr Domain;
1971 Bstr ClientName;
1972 Bstr ClientIP;
1973 ULONG ClientVersion;
1974 ULONG EncryptionStyle;
1975
1976 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
1977 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
1978 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
1979 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
1980 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
1981 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
1982 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
1983 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
1984 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
1985 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
1986 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
1987 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
1988 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
1989 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
1990
1991 if (details == VMINFO_MACHINEREADABLE)
1992 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
1993 else
1994 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
1995
1996 if (details == VMINFO_MACHINEREADABLE)
1997 RTPrintf("VRDEClients=%d\n", NumberOfClients);
1998 else
1999 RTPrintf("Clients so far: %d\n", NumberOfClients);
2000
2001 if (NumberOfClients > 0)
2002 {
2003 char timestr[128];
2004
2005 if (Active)
2006 {
2007 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2008 if (details == VMINFO_MACHINEREADABLE)
2009 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2010 else
2011 RTPrintf("Start time: %s\n", timestr);
2012 }
2013 else
2014 {
2015 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2016 if (details == VMINFO_MACHINEREADABLE)
2017 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2018 else
2019 RTPrintf("Last started: %s\n", timestr);
2020 makeTimeStr(timestr, sizeof(timestr), EndTime);
2021 if (details == VMINFO_MACHINEREADABLE)
2022 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2023 else
2024 RTPrintf("Last ended: %s\n", timestr);
2025 }
2026
2027 int64_t ThroughputSend = 0;
2028 int64_t ThroughputReceive = 0;
2029 if (EndTime != BeginTime)
2030 {
2031 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2032 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2033 }
2034
2035 if (details == VMINFO_MACHINEREADABLE)
2036 {
2037 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2038 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2039 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2040
2041 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2042 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2043 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2044 }
2045 else
2046 {
2047 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2048 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2049 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2050
2051 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2052 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2053 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2054 }
2055
2056 if (Active)
2057 {
2058 if (details == VMINFO_MACHINEREADABLE)
2059 {
2060 RTPrintf("VRDEUserName=\"%lS\"\n", User.raw());
2061 RTPrintf("VRDEDomain=\"%lS\"\n", Domain.raw());
2062 RTPrintf("VRDEClientName=\"%lS\"\n", ClientName.raw());
2063 RTPrintf("VRDEClientIP=\"%lS\"\n", ClientIP.raw());
2064 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2065 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2066 }
2067 else
2068 {
2069 RTPrintf("User name: %lS\n", User.raw());
2070 RTPrintf("Domain: %lS\n", Domain.raw());
2071 RTPrintf("Client name: %lS\n", ClientName.raw());
2072 RTPrintf("Client IP: %lS\n", ClientIP.raw());
2073 RTPrintf("Client version: %d\n", ClientVersion);
2074 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2075 }
2076 }
2077 }
2078
2079 if (details != VMINFO_MACHINEREADABLE)
2080 RTPrintf("\n");
2081 }
2082
2083 if ( details == VMINFO_STANDARD
2084 || details == VMINFO_FULL
2085 || details == VMINFO_MACHINEREADABLE)
2086 {
2087 Bstr description;
2088 machine->COMGETTER(Description)(description.asOutParam());
2089 if (!description.isEmpty())
2090 {
2091 if (details == VMINFO_MACHINEREADABLE)
2092 RTPrintf("description=\"%lS\"\n", description.raw());
2093 else
2094 RTPrintf("Description:\n%lS\n", description.raw());
2095 }
2096 }
2097
2098
2099 if (details != VMINFO_MACHINEREADABLE)
2100 RTPrintf("Guest:\n\n");
2101
2102 ULONG guestVal;
2103 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2104 if (SUCCEEDED(rc))
2105 {
2106 if (details == VMINFO_MACHINEREADABLE)
2107 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2108 else
2109 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2110 }
2111
2112 if (console)
2113 {
2114 ComPtr<IGuest> guest;
2115 rc = console->COMGETTER(Guest)(guest.asOutParam());
2116 if (SUCCEEDED(rc))
2117 {
2118 Bstr guestString;
2119 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2120 if ( SUCCEEDED(rc)
2121 && !guestString.isEmpty())
2122 {
2123 if (details == VMINFO_MACHINEREADABLE)
2124 RTPrintf("GuestOSType=\"%lS\"\n", guestString.raw());
2125 else
2126 RTPrintf("OS type: %lS\n", guestString.raw());
2127 }
2128
2129 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2130 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2131 if (SUCCEEDED(rc))
2132 {
2133 if (details == VMINFO_MACHINEREADABLE)
2134 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2135 else
2136 RTPrintf("Additions run level: %u\n", guestRunLevel);
2137 }
2138
2139 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2140 if ( SUCCEEDED(rc)
2141 && !guestString.isEmpty())
2142 {
2143 if (details == VMINFO_MACHINEREADABLE)
2144 RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw());
2145 else
2146 RTPrintf("Additions version: %lS\n\n", guestString.raw());
2147 }
2148
2149 if (details != VMINFO_MACHINEREADABLE)
2150 RTPrintf("\nGuest Facilities:\n\n");
2151
2152 /* Print information about known Guest Additions facilities: */
2153 SafeIfaceArray <IAdditionsFacility> collFac;
2154 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2155 LONG64 lLastUpdatedMS;
2156 char szLastUpdated[32];
2157 AdditionsFacilityStatus_T curStatus;
2158 for (size_t index = 0; index < collFac.size(); ++index)
2159 {
2160 ComPtr<IAdditionsFacility> fac = collFac[index];
2161 if (fac)
2162 {
2163 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2164 if (!guestString.isEmpty())
2165 {
2166 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2167 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2168 if (details == VMINFO_MACHINEREADABLE)
2169 RTPrintf("GuestAdditionsFacility_%lS=%u,%lld\n",
2170 guestString.raw(), curStatus, lLastUpdatedMS);
2171 else
2172 {
2173 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2174 RTPrintf("Facility \"%lS\": %s (last update: %s)\n",
2175 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2176 }
2177 }
2178 else
2179 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2180 }
2181 else
2182 AssertMsgFailed(("Invalid facility returned!\n"));
2183 }
2184 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2185 RTPrintf("No active facilities.\n");
2186 }
2187 }
2188
2189 if (details != VMINFO_MACHINEREADABLE)
2190 RTPrintf("\n");
2191
2192 /*
2193 * snapshots
2194 */
2195 ComPtr<ISnapshot> snapshot;
2196 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2197 if (SUCCEEDED(rc) && snapshot)
2198 {
2199 ComPtr<ISnapshot> currentSnapshot;
2200 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2201 if (SUCCEEDED(rc))
2202 {
2203 if (details != VMINFO_MACHINEREADABLE)
2204 RTPrintf("Snapshots:\n\n");
2205 showSnapshots(snapshot, currentSnapshot, details);
2206 }
2207 }
2208
2209 if (details != VMINFO_MACHINEREADABLE)
2210 RTPrintf("\n");
2211 return S_OK;
2212}
2213
2214#if defined(_MSC_VER)
2215# pragma optimize("", on)
2216#endif
2217
2218static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2219{
2220 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2221 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2222 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2223 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2224 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2225};
2226
2227int handleShowVMInfo(HandlerArg *a)
2228{
2229 HRESULT rc;
2230 const char *VMNameOrUuid = NULL;
2231 bool fLog = false;
2232 uint32_t uLogIdx = 0;
2233 bool fDetails = false;
2234 bool fMachinereadable = false;
2235
2236 int c;
2237 RTGETOPTUNION ValueUnion;
2238 RTGETOPTSTATE GetState;
2239 // start at 0 because main() has hacked both the argc and argv given to us
2240 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2241 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2242 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2243 {
2244 switch (c)
2245 {
2246 case 'D': // --details
2247 fDetails = true;
2248 break;
2249
2250 case 'M': // --machinereadable
2251 fMachinereadable = true;
2252 break;
2253
2254 case 'l': // --log
2255 fLog = true;
2256 uLogIdx = ValueUnion.u32;
2257 break;
2258
2259 case VINF_GETOPT_NOT_OPTION:
2260 if (!VMNameOrUuid)
2261 VMNameOrUuid = ValueUnion.psz;
2262 else
2263 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2264 break;
2265
2266 default:
2267 if (c > 0)
2268 {
2269 if (RT_C_IS_PRINT(c))
2270 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2271 else
2272 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2273 }
2274 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2275 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2276 else if (ValueUnion.pDef)
2277 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2278 else
2279 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2280 }
2281 }
2282
2283 /* check for required options */
2284 if (!VMNameOrUuid)
2285 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2286
2287 /* try to find the given machine */
2288 ComPtr <IMachine> machine;
2289 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2290 machine.asOutParam()));
2291 if (FAILED(rc))
2292 return 1;
2293
2294 /* Printing the log is exclusive. */
2295 if (fLog && (fMachinereadable || fDetails))
2296 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2297
2298 if (fLog)
2299 {
2300 ULONG64 uOffset = 0;
2301 SafeArray<BYTE> aLogData;
2302 ULONG cbLogData;
2303 while (true)
2304 {
2305 /* Reset the array */
2306 aLogData.setNull();
2307 /* Fetch a chunk of the log file */
2308 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2309 ComSafeArrayAsOutParam(aLogData)));
2310 cbLogData = aLogData.size();
2311 if (cbLogData == 0)
2312 break;
2313 /* aLogData has a platform dependent line ending, standardize on
2314 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2315 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2316 ULONG cbLogDataPrint = cbLogData;
2317 for (BYTE *s = aLogData.raw(), *d = s;
2318 s - aLogData.raw() < (ssize_t)cbLogData;
2319 s++, d++)
2320 {
2321 if (*s == '\r')
2322 {
2323 /* skip over CR, adjust destination */
2324 d--;
2325 cbLogDataPrint--;
2326 }
2327 else if (s != d)
2328 *d = *s;
2329 }
2330 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2331 uOffset += cbLogData;
2332 }
2333 }
2334 else
2335 {
2336 /* 2nd option can be -details or -argdump */
2337 VMINFO_DETAILS details = VMINFO_NONE;
2338 if (fMachinereadable)
2339 details = VMINFO_MACHINEREADABLE;
2340 else if (fDetails)
2341 details = VMINFO_FULL;
2342 else
2343 details = VMINFO_STANDARD;
2344
2345 ComPtr<IConsole> console;
2346
2347 /* open an existing session for the VM */
2348 rc = machine->LockMachine(a->session, LockType_Shared);
2349 if (SUCCEEDED(rc))
2350 /* get the session machine */
2351 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2352 if (SUCCEEDED(rc))
2353 /* get the session console */
2354 rc = a->session->COMGETTER(Console)(console.asOutParam());
2355
2356 rc = showVMInfo(a->virtualBox, machine, details, console);
2357
2358 if (console)
2359 a->session->UnlockMachine();
2360 }
2361
2362 return SUCCEEDED(rc) ? 0 : 1;
2363}
2364
2365#endif /* !VBOX_ONLY_DOCS */
2366/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

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