VirtualBox

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

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

Frontends/VBoxManage: show temp eject config

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