VirtualBox

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

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

VBoxManageInfo.cpp: build fix.

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