VirtualBox

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

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

VBoxManage: suppress error message from showvminfo under rare circumstances

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 96.9 KB
Line 
1/* $Id: VBoxManageInfo.cpp 38529 2011-08-25 14:15:29Z 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 do
1440 {
1441 ComPtr<IDisplay> display;
1442 rc = console->COMGETTER(Display)(display.asOutParam());
1443 if (rc == E_ACCESSDENIED)
1444 break; /* VM not powered up */
1445 if (FAILED(rc))
1446 {
1447 com::GlueHandleComError(console, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1448 return rc;
1449 }
1450 ULONG xRes, yRes, bpp;
1451 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp);
1452 if (rc == E_ACCESSDENIED)
1453 break; /* VM not powered up */
1454 if (FAILED(rc))
1455 {
1456 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1457 GluePrintErrorInfo(info);
1458 return rc;
1459 }
1460 if (details == VMINFO_MACHINEREADABLE)
1461 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1462 else
1463 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1464 }
1465 while (0);
1466 }
1467
1468 /*
1469 * Remote Desktop
1470 */
1471 ComPtr<IVRDEServer> vrdeServer;
1472 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1473 if (SUCCEEDED(rc) && vrdeServer)
1474 {
1475 BOOL fEnabled = false;
1476 vrdeServer->COMGETTER(Enabled)(&fEnabled);
1477 if (fEnabled)
1478 {
1479 LONG currentPort = -1;
1480 Bstr ports;
1481 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
1482 Bstr address;
1483 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
1484 BOOL fMultiCon;
1485 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1486 BOOL fReuseCon;
1487 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1488 Bstr videoChannel;
1489 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
1490 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
1491 || (videoChannel == "1");
1492 Bstr videoChannelQuality;
1493 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
1494 AuthType_T authType;
1495 const char *strAuthType;
1496 vrdeServer->COMGETTER(AuthType)(&authType);
1497 switch (authType)
1498 {
1499 case AuthType_Null:
1500 strAuthType = "null";
1501 break;
1502 case AuthType_External:
1503 strAuthType = "external";
1504 break;
1505 case AuthType_Guest:
1506 strAuthType = "guest";
1507 break;
1508 default:
1509 strAuthType = "unknown";
1510 break;
1511 }
1512 if (console)
1513 {
1514 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1515 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
1516 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
1517 if (rc == E_ACCESSDENIED)
1518 {
1519 currentPort = -1; /* VM not powered up */
1520 }
1521 if (FAILED(rc))
1522 {
1523 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
1524 GluePrintErrorInfo(info);
1525 return rc;
1526 }
1527 }
1528 if (details == VMINFO_MACHINEREADABLE)
1529 {
1530 RTPrintf("vrde=\"on\"\n");
1531 RTPrintf("vrdeport=%d\n", currentPort);
1532 RTPrintf("vrdeports=\"%lS\"\n", ports.raw());
1533 RTPrintf("vrdeaddress=\"%lS\"\n", address.raw());
1534 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
1535 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1536 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1537 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1538 if (fVideoChannel)
1539 RTPrintf("vrdevideochannelquality=\"%lS\"\n", videoChannelQuality.raw());
1540 }
1541 else
1542 {
1543 if (address.isEmpty())
1544 address = "0.0.0.0";
1545 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);
1546 if (console && currentPort != -1 && currentPort != 0)
1547 RTPrintf("VRDE port: %d\n", currentPort);
1548 if (fVideoChannel)
1549 RTPrintf("Video redirection: enabled (Quality %lS)\n", videoChannelQuality.raw());
1550 else
1551 RTPrintf("Video redirection: disabled\n");
1552 }
1553 com::SafeArray<BSTR> aProperties;
1554 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
1555 {
1556 unsigned i;
1557 for (i = 0; i < aProperties.size(); ++i)
1558 {
1559 Bstr value;
1560 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
1561 if (details == VMINFO_MACHINEREADABLE)
1562 {
1563 if (value.isEmpty())
1564 RTPrintf("vrdeproperty[%lS]=<not set>\n", aProperties[i]);
1565 else
1566 RTPrintf("vrdeproperty[%lS]=\"%lS\"\n", aProperties[i], value.raw());
1567 }
1568 else
1569 {
1570 if (value.isEmpty())
1571 RTPrintf("VRDE property: %-10lS = <not set>\n", aProperties[i]);
1572 else
1573 RTPrintf("VRDE property: %-10lS = \"%lS\"\n", aProperties[i], value.raw());
1574 }
1575 }
1576 }
1577 }
1578 else
1579 {
1580 if (details == VMINFO_MACHINEREADABLE)
1581 RTPrintf("vrde=\"off\"\n");
1582 else
1583 RTPrintf("VRDE: disabled\n");
1584 }
1585 }
1586
1587 /*
1588 * USB.
1589 */
1590 ComPtr<IUSBController> USBCtl;
1591 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1592 if (SUCCEEDED(rc))
1593 {
1594 BOOL fEnabled;
1595 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1596 if (FAILED(rc))
1597 fEnabled = false;
1598 if (details == VMINFO_MACHINEREADABLE)
1599 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1600 else
1601 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1602
1603 SafeIfaceArray <IUSBDeviceFilter> Coll;
1604 rc = USBCtl->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1605 if (SUCCEEDED(rc))
1606 {
1607 if (details != VMINFO_MACHINEREADABLE)
1608 RTPrintf("\nUSB Device Filters:\n\n");
1609
1610 if (Coll.size() == 0)
1611 {
1612 if (details != VMINFO_MACHINEREADABLE)
1613 RTPrintf("<none>\n\n");
1614 }
1615 else
1616 {
1617 for (size_t index = 0; index < Coll.size(); ++index)
1618 {
1619 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1620
1621 /* Query info. */
1622
1623 if (details != VMINFO_MACHINEREADABLE)
1624 RTPrintf("Index: %zu\n", index);
1625
1626 BOOL bActive = FALSE;
1627 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1628 if (details == VMINFO_MACHINEREADABLE)
1629 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1630 else
1631 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1632
1633 Bstr bstr;
1634 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1635 if (details == VMINFO_MACHINEREADABLE)
1636 RTPrintf("USBFilterName%zu=\"%lS\"\n", index + 1, bstr.raw());
1637 else
1638 RTPrintf("Name: %lS\n", bstr.raw());
1639 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1640 if (details == VMINFO_MACHINEREADABLE)
1641 RTPrintf("USBFilterVendorId%zu=\"%lS\"\n", index + 1, bstr.raw());
1642 else
1643 RTPrintf("VendorId: %lS\n", bstr.raw());
1644 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1645 if (details == VMINFO_MACHINEREADABLE)
1646 RTPrintf("USBFilterProductId%zu=\"%lS\"\n", index + 1, bstr.raw());
1647 else
1648 RTPrintf("ProductId: %lS\n", bstr.raw());
1649 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1650 if (details == VMINFO_MACHINEREADABLE)
1651 RTPrintf("USBFilterRevision%zu=\"%lS\"\n", index + 1, bstr.raw());
1652 else
1653 RTPrintf("Revision: %lS\n", bstr.raw());
1654 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1655 if (details == VMINFO_MACHINEREADABLE)
1656 RTPrintf("USBFilterManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1657 else
1658 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1659 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1660 if (details == VMINFO_MACHINEREADABLE)
1661 RTPrintf("USBFilterProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1662 else
1663 RTPrintf("Product: %lS\n", bstr.raw());
1664 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1665 if (details == VMINFO_MACHINEREADABLE)
1666 RTPrintf("USBFilterRemote%zu=\"%lS\"\n", index + 1, bstr.raw());
1667 else
1668 RTPrintf("Remote: %lS\n", bstr.raw());
1669 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1670 if (details == VMINFO_MACHINEREADABLE)
1671 RTPrintf("USBFilterSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1672 else
1673 RTPrintf("Serial Number: %lS\n", bstr.raw());
1674 if (details != VMINFO_MACHINEREADABLE)
1675 {
1676 ULONG fMaskedIfs;
1677 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1678 if (fMaskedIfs)
1679 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1680 RTPrintf("\n");
1681 }
1682 }
1683 }
1684 }
1685
1686 if (console)
1687 {
1688 /* scope */
1689 {
1690 if (details != VMINFO_MACHINEREADABLE)
1691 RTPrintf("Available remote USB devices:\n\n");
1692
1693 SafeIfaceArray <IHostUSBDevice> coll;
1694 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1695
1696 if (coll.size() == 0)
1697 {
1698 if (details != VMINFO_MACHINEREADABLE)
1699 RTPrintf("<none>\n\n");
1700 }
1701 else
1702 {
1703 for (size_t index = 0; index < coll.size(); ++index)
1704 {
1705 ComPtr <IHostUSBDevice> dev = coll[index];
1706
1707 /* Query info. */
1708 Bstr id;
1709 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1710 USHORT usVendorId;
1711 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1712 USHORT usProductId;
1713 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1714 USHORT bcdRevision;
1715 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1716
1717 if (details == VMINFO_MACHINEREADABLE)
1718 RTPrintf("USBRemoteUUID%zu=\"%S\"\n"
1719 "USBRemoteVendorId%zu=\"%#06x\"\n"
1720 "USBRemoteProductId%zu=\"%#06x\"\n"
1721 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1722 index + 1, Utf8Str(id).c_str(),
1723 index + 1, usVendorId,
1724 index + 1, usProductId,
1725 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1726 else
1727 RTPrintf("UUID: %S\n"
1728 "VendorId: %#06x (%04X)\n"
1729 "ProductId: %#06x (%04X)\n"
1730 "Revision: %u.%u (%02u%02u)\n",
1731 Utf8Str(id).c_str(),
1732 usVendorId, usVendorId, usProductId, usProductId,
1733 bcdRevision >> 8, bcdRevision & 0xff,
1734 bcdRevision >> 8, bcdRevision & 0xff);
1735
1736 /* optional stuff. */
1737 Bstr bstr;
1738 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1739 if (!bstr.isEmpty())
1740 {
1741 if (details == VMINFO_MACHINEREADABLE)
1742 RTPrintf("USBRemoteManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1743 else
1744 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1745 }
1746 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1747 if (!bstr.isEmpty())
1748 {
1749 if (details == VMINFO_MACHINEREADABLE)
1750 RTPrintf("USBRemoteProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1751 else
1752 RTPrintf("Product: %lS\n", bstr.raw());
1753 }
1754 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1755 if (!bstr.isEmpty())
1756 {
1757 if (details == VMINFO_MACHINEREADABLE)
1758 RTPrintf("USBRemoteSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1759 else
1760 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1761 }
1762 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1763 if (!bstr.isEmpty())
1764 {
1765 if (details == VMINFO_MACHINEREADABLE)
1766 RTPrintf("USBRemoteAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1767 else
1768 RTPrintf("Address: %lS\n", bstr.raw());
1769 }
1770
1771 if (details != VMINFO_MACHINEREADABLE)
1772 RTPrintf("\n");
1773 }
1774 }
1775 }
1776
1777 /* scope */
1778 {
1779 if (details != VMINFO_MACHINEREADABLE)
1780 RTPrintf("Currently Attached USB Devices:\n\n");
1781
1782 SafeIfaceArray <IUSBDevice> coll;
1783 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1784
1785 if (coll.size() == 0)
1786 {
1787 if (details != VMINFO_MACHINEREADABLE)
1788 RTPrintf("<none>\n\n");
1789 }
1790 else
1791 {
1792 for (size_t index = 0; index < coll.size(); ++index)
1793 {
1794 ComPtr <IUSBDevice> dev = coll[index];
1795
1796 /* Query info. */
1797 Bstr id;
1798 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1799 USHORT usVendorId;
1800 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1801 USHORT usProductId;
1802 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1803 USHORT bcdRevision;
1804 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1805
1806 if (details == VMINFO_MACHINEREADABLE)
1807 RTPrintf("USBAttachedUUID%zu=\"%S\"\n"
1808 "USBAttachedVendorId%zu=\"%#06x\"\n"
1809 "USBAttachedProductId%zu=\"%#06x\"\n"
1810 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
1811 index + 1, Utf8Str(id).c_str(),
1812 index + 1, usVendorId,
1813 index + 1, usProductId,
1814 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1815 else
1816 RTPrintf("UUID: %S\n"
1817 "VendorId: %#06x (%04X)\n"
1818 "ProductId: %#06x (%04X)\n"
1819 "Revision: %u.%u (%02u%02u)\n",
1820 Utf8Str(id).c_str(),
1821 usVendorId, usVendorId, usProductId, usProductId,
1822 bcdRevision >> 8, bcdRevision & 0xff,
1823 bcdRevision >> 8, bcdRevision & 0xff);
1824
1825 /* optional stuff. */
1826 Bstr bstr;
1827 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1828 if (!bstr.isEmpty())
1829 {
1830 if (details == VMINFO_MACHINEREADABLE)
1831 RTPrintf("USBAttachedManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1832 else
1833 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1834 }
1835 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1836 if (!bstr.isEmpty())
1837 {
1838 if (details == VMINFO_MACHINEREADABLE)
1839 RTPrintf("USBAttachedProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1840 else
1841 RTPrintf("Product: %lS\n", bstr.raw());
1842 }
1843 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1844 if (!bstr.isEmpty())
1845 {
1846 if (details == VMINFO_MACHINEREADABLE)
1847 RTPrintf("USBAttachedSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1848 else
1849 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1850 }
1851 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1852 if (!bstr.isEmpty())
1853 {
1854 if (details == VMINFO_MACHINEREADABLE)
1855 RTPrintf("USBAttachedAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1856 else
1857 RTPrintf("Address: %lS\n", bstr.raw());
1858 }
1859
1860 if (details != VMINFO_MACHINEREADABLE)
1861 RTPrintf("\n");
1862 }
1863 }
1864 }
1865 }
1866 } /* USB */
1867
1868#ifdef VBOX_WITH_PCI_PASSTHROUGH
1869 /* Host PCI passthrough devices */
1870 {
1871 SafeIfaceArray <IPciDeviceAttachment> assignments;
1872 rc = machine->COMGETTER(PciDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
1873 if (SUCCEEDED(rc))
1874 {
1875 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
1876 {
1877 RTPrintf("\nAttached physical PCI devices:\n\n");
1878 }
1879
1880 for (size_t index = 0; index < assignments.size(); ++index)
1881 {
1882 ComPtr<IPciDeviceAttachment> Assignment = assignments[index];
1883 char szHostPciAddress[32], szGuestPciAddress[32];
1884 LONG iHostPciAddress = -1, iGuestPciAddress = -1;
1885 Bstr DevName;
1886
1887 Assignment->COMGETTER(Name)(DevName.asOutParam());
1888 Assignment->COMGETTER(HostAddress)(&iHostPciAddress);
1889 Assignment->COMGETTER(GuestAddress)(&iGuestPciAddress);
1890 PciBusAddress().fromLong(iHostPciAddress).format(szHostPciAddress, sizeof(szHostPciAddress));
1891 PciBusAddress().fromLong(iGuestPciAddress).format(szGuestPciAddress, sizeof(szGuestPciAddress));
1892
1893 if (details == VMINFO_MACHINEREADABLE)
1894 RTPrintf("AttachedHostPci=%s,%s\n", szHostPciAddress, szGuestPciAddress);
1895 else
1896 RTPrintf(" Host device %lS at %s attached as %s\n", DevName.raw(), szHostPciAddress, szGuestPciAddress);
1897 }
1898
1899 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
1900 {
1901 RTPrintf("\n");
1902 }
1903 }
1904 }
1905 /* Host PCI passthrough devices */
1906#endif
1907
1908 /*
1909 * Shared folders
1910 */
1911 if (details != VMINFO_MACHINEREADABLE)
1912 RTPrintf("Shared folders: ");
1913 uint32_t numSharedFolders = 0;
1914#if 0 // not yet implemented
1915 /* globally shared folders first */
1916 {
1917 SafeIfaceArray <ISharedFolder> sfColl;
1918 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
1919 for (size_t i = 0; i < sfColl.size(); ++i)
1920 {
1921 ComPtr<ISharedFolder> sf = sfColl[i];
1922 Bstr name, hostPath;
1923 sf->COMGETTER(Name)(name.asOutParam());
1924 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1925 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
1926 ++numSharedFolders;
1927 }
1928 }
1929#endif
1930 /* now VM mappings */
1931 {
1932 com::SafeIfaceArray <ISharedFolder> folders;
1933
1934 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1935
1936 for (size_t i = 0; i < folders.size(); ++i)
1937 {
1938 ComPtr <ISharedFolder> sf = folders[i];
1939
1940 Bstr name, hostPath;
1941 BOOL writable;
1942 sf->COMGETTER(Name)(name.asOutParam());
1943 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1944 sf->COMGETTER(Writable)(&writable);
1945 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1946 RTPrintf("\n\n");
1947 if (details == VMINFO_MACHINEREADABLE)
1948 {
1949 RTPrintf("SharedFolderNameMachineMapping%zu=\"%lS\"\n", i + 1,
1950 name.raw());
1951 RTPrintf("SharedFolderPathMachineMapping%zu=\"%lS\"\n", i + 1,
1952 hostPath.raw());
1953 }
1954 else
1955 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
1956 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
1957 ++numSharedFolders;
1958 }
1959 }
1960 /* transient mappings */
1961 if (console)
1962 {
1963 com::SafeIfaceArray <ISharedFolder> folders;
1964
1965 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1966
1967 for (size_t i = 0; i < folders.size(); ++i)
1968 {
1969 ComPtr <ISharedFolder> sf = folders[i];
1970
1971 Bstr name, hostPath;
1972 sf->COMGETTER(Name)(name.asOutParam());
1973 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1974 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1975 RTPrintf("\n\n");
1976 if (details == VMINFO_MACHINEREADABLE)
1977 {
1978 RTPrintf("SharedFolderNameTransientMapping%zu=\"%lS\"\n", i + 1,
1979 name.raw());
1980 RTPrintf("SharedFolderPathTransientMapping%zu=\"%lS\"\n", i + 1,
1981 hostPath.raw());
1982 }
1983 else
1984 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
1985 ++numSharedFolders;
1986 }
1987 }
1988 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1989 RTPrintf("<none>\n");
1990 if (details != VMINFO_MACHINEREADABLE)
1991 RTPrintf("\n");
1992
1993 if (console)
1994 {
1995 /*
1996 * Live VRDE info.
1997 */
1998 ComPtr<IVRDEServerInfo> vrdeServerInfo;
1999 CHECK_ERROR_RET(console, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2000 BOOL Active;
2001 ULONG NumberOfClients;
2002 LONG64 BeginTime;
2003 LONG64 EndTime;
2004 LONG64 BytesSent;
2005 LONG64 BytesSentTotal;
2006 LONG64 BytesReceived;
2007 LONG64 BytesReceivedTotal;
2008 Bstr User;
2009 Bstr Domain;
2010 Bstr ClientName;
2011 Bstr ClientIP;
2012 ULONG ClientVersion;
2013 ULONG EncryptionStyle;
2014
2015 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&Active), rc);
2016 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
2017 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2018 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2019 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2020 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2021 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2022 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2023 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2024 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2025 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2026 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2027 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2028 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2029
2030 if (details == VMINFO_MACHINEREADABLE)
2031 RTPrintf("VRDEActiveConnection=\"%s\"\n", Active ? "on": "off");
2032 else
2033 RTPrintf("VRDE Connection: %s\n", Active? "active": "not active");
2034
2035 if (details == VMINFO_MACHINEREADABLE)
2036 RTPrintf("VRDEClients=%d\n", NumberOfClients);
2037 else
2038 RTPrintf("Clients so far: %d\n", NumberOfClients);
2039
2040 if (NumberOfClients > 0)
2041 {
2042 char timestr[128];
2043
2044 if (Active)
2045 {
2046 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2047 if (details == VMINFO_MACHINEREADABLE)
2048 RTPrintf("VRDEStartTime=\"%s\"\n", timestr);
2049 else
2050 RTPrintf("Start time: %s\n", timestr);
2051 }
2052 else
2053 {
2054 makeTimeStr(timestr, sizeof(timestr), BeginTime);
2055 if (details == VMINFO_MACHINEREADABLE)
2056 RTPrintf("VRDELastStartTime=\"%s\"\n", timestr);
2057 else
2058 RTPrintf("Last started: %s\n", timestr);
2059 makeTimeStr(timestr, sizeof(timestr), EndTime);
2060 if (details == VMINFO_MACHINEREADABLE)
2061 RTPrintf("VRDELastEndTime=\"%s\"\n", timestr);
2062 else
2063 RTPrintf("Last ended: %s\n", timestr);
2064 }
2065
2066 int64_t ThroughputSend = 0;
2067 int64_t ThroughputReceive = 0;
2068 if (EndTime != BeginTime)
2069 {
2070 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2071 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2072 }
2073
2074 if (details == VMINFO_MACHINEREADABLE)
2075 {
2076 RTPrintf("VRDEBytesSent=%lld\n", BytesSent);
2077 RTPrintf("VRDEThroughputSend=%lld\n", ThroughputSend);
2078 RTPrintf("VRDEBytesSentTotal=%lld\n", BytesSentTotal);
2079
2080 RTPrintf("VRDEBytesReceived=%lld\n", BytesReceived);
2081 RTPrintf("VRDEThroughputReceive=%lld\n", ThroughputReceive);
2082 RTPrintf("VRDEBytesReceivedTotal=%lld\n", BytesReceivedTotal);
2083 }
2084 else
2085 {
2086 RTPrintf("Sent: %lld Bytes\n", BytesSent);
2087 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
2088 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
2089
2090 RTPrintf("Received: %lld Bytes\n", BytesReceived);
2091 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
2092 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
2093 }
2094
2095 if (Active)
2096 {
2097 if (details == VMINFO_MACHINEREADABLE)
2098 {
2099 RTPrintf("VRDEUserName=\"%lS\"\n", User.raw());
2100 RTPrintf("VRDEDomain=\"%lS\"\n", Domain.raw());
2101 RTPrintf("VRDEClientName=\"%lS\"\n", ClientName.raw());
2102 RTPrintf("VRDEClientIP=\"%lS\"\n", ClientIP.raw());
2103 RTPrintf("VRDEClientVersion=%d\n", ClientVersion);
2104 RTPrintf("VRDEEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2105 }
2106 else
2107 {
2108 RTPrintf("User name: %lS\n", User.raw());
2109 RTPrintf("Domain: %lS\n", Domain.raw());
2110 RTPrintf("Client name: %lS\n", ClientName.raw());
2111 RTPrintf("Client IP: %lS\n", ClientIP.raw());
2112 RTPrintf("Client version: %d\n", ClientVersion);
2113 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2114 }
2115 }
2116 }
2117
2118 if (details != VMINFO_MACHINEREADABLE)
2119 RTPrintf("\n");
2120 }
2121
2122 if ( details == VMINFO_STANDARD
2123 || details == VMINFO_FULL
2124 || details == VMINFO_MACHINEREADABLE)
2125 {
2126 Bstr description;
2127 machine->COMGETTER(Description)(description.asOutParam());
2128 if (!description.isEmpty())
2129 {
2130 if (details == VMINFO_MACHINEREADABLE)
2131 RTPrintf("description=\"%lS\"\n", description.raw());
2132 else
2133 RTPrintf("Description:\n%lS\n", description.raw());
2134 }
2135 }
2136
2137
2138 if (details != VMINFO_MACHINEREADABLE)
2139 RTPrintf("Guest:\n\n");
2140
2141 ULONG guestVal;
2142 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2143 if (SUCCEEDED(rc))
2144 {
2145 if (details == VMINFO_MACHINEREADABLE)
2146 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2147 else
2148 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2149 }
2150
2151 if (console)
2152 {
2153 ComPtr<IGuest> guest;
2154 rc = console->COMGETTER(Guest)(guest.asOutParam());
2155 if (SUCCEEDED(rc))
2156 {
2157 Bstr guestString;
2158 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
2159 if ( SUCCEEDED(rc)
2160 && !guestString.isEmpty())
2161 {
2162 if (details == VMINFO_MACHINEREADABLE)
2163 RTPrintf("GuestOSType=\"%lS\"\n", guestString.raw());
2164 else
2165 RTPrintf("OS type: %lS\n", guestString.raw());
2166 }
2167
2168 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2169 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2170 if (SUCCEEDED(rc))
2171 {
2172 if (details == VMINFO_MACHINEREADABLE)
2173 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
2174 else
2175 RTPrintf("Additions run level: %u\n", guestRunLevel);
2176 }
2177
2178 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2179 if ( SUCCEEDED(rc)
2180 && !guestString.isEmpty())
2181 {
2182 if (details == VMINFO_MACHINEREADABLE)
2183 RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw());
2184 else
2185 RTPrintf("Additions version: %lS\n\n", guestString.raw());
2186 }
2187
2188 if (details != VMINFO_MACHINEREADABLE)
2189 RTPrintf("\nGuest Facilities:\n\n");
2190
2191 /* Print information about known Guest Additions facilities: */
2192 SafeIfaceArray <IAdditionsFacility> collFac;
2193 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2194 LONG64 lLastUpdatedMS;
2195 char szLastUpdated[32];
2196 AdditionsFacilityStatus_T curStatus;
2197 for (size_t index = 0; index < collFac.size(); ++index)
2198 {
2199 ComPtr<IAdditionsFacility> fac = collFac[index];
2200 if (fac)
2201 {
2202 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2203 if (!guestString.isEmpty())
2204 {
2205 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2206 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2207 if (details == VMINFO_MACHINEREADABLE)
2208 RTPrintf("GuestAdditionsFacility_%lS=%u,%lld\n",
2209 guestString.raw(), curStatus, lLastUpdatedMS);
2210 else
2211 {
2212 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2213 RTPrintf("Facility \"%lS\": %s (last update: %s)\n",
2214 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2215 }
2216 }
2217 else
2218 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2219 }
2220 else
2221 AssertMsgFailed(("Invalid facility returned!\n"));
2222 }
2223 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2224 RTPrintf("No active facilities.\n");
2225 }
2226 }
2227
2228 if (details != VMINFO_MACHINEREADABLE)
2229 RTPrintf("\n");
2230
2231 /*
2232 * snapshots
2233 */
2234 ComPtr<ISnapshot> snapshot;
2235 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2236 if (SUCCEEDED(rc) && snapshot)
2237 {
2238 ComPtr<ISnapshot> currentSnapshot;
2239 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2240 if (SUCCEEDED(rc))
2241 {
2242 if (details != VMINFO_MACHINEREADABLE)
2243 RTPrintf("Snapshots:\n\n");
2244 showSnapshots(snapshot, currentSnapshot, details);
2245 }
2246 }
2247
2248 if (details != VMINFO_MACHINEREADABLE)
2249 RTPrintf("\n");
2250 return S_OK;
2251}
2252
2253#if defined(_MSC_VER)
2254# pragma optimize("", on)
2255#endif
2256
2257static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2258{
2259 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2260 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2261 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2262 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2263 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2264};
2265
2266int handleShowVMInfo(HandlerArg *a)
2267{
2268 HRESULT rc;
2269 const char *VMNameOrUuid = NULL;
2270 bool fLog = false;
2271 uint32_t uLogIdx = 0;
2272 bool fDetails = false;
2273 bool fMachinereadable = false;
2274
2275 int c;
2276 RTGETOPTUNION ValueUnion;
2277 RTGETOPTSTATE GetState;
2278 // start at 0 because main() has hacked both the argc and argv given to us
2279 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2280 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2281 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2282 {
2283 switch (c)
2284 {
2285 case 'D': // --details
2286 fDetails = true;
2287 break;
2288
2289 case 'M': // --machinereadable
2290 fMachinereadable = true;
2291 break;
2292
2293 case 'l': // --log
2294 fLog = true;
2295 uLogIdx = ValueUnion.u32;
2296 break;
2297
2298 case VINF_GETOPT_NOT_OPTION:
2299 if (!VMNameOrUuid)
2300 VMNameOrUuid = ValueUnion.psz;
2301 else
2302 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2303 break;
2304
2305 default:
2306 if (c > 0)
2307 {
2308 if (RT_C_IS_PRINT(c))
2309 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2310 else
2311 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2312 }
2313 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2314 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2315 else if (ValueUnion.pDef)
2316 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2317 else
2318 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2319 }
2320 }
2321
2322 /* check for required options */
2323 if (!VMNameOrUuid)
2324 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2325
2326 /* try to find the given machine */
2327 ComPtr <IMachine> machine;
2328 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2329 machine.asOutParam()));
2330 if (FAILED(rc))
2331 return 1;
2332
2333 /* Printing the log is exclusive. */
2334 if (fLog && (fMachinereadable || fDetails))
2335 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2336
2337 if (fLog)
2338 {
2339 ULONG64 uOffset = 0;
2340 SafeArray<BYTE> aLogData;
2341 ULONG cbLogData;
2342 while (true)
2343 {
2344 /* Reset the array */
2345 aLogData.setNull();
2346 /* Fetch a chunk of the log file */
2347 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2348 ComSafeArrayAsOutParam(aLogData)));
2349 cbLogData = aLogData.size();
2350 if (cbLogData == 0)
2351 break;
2352 /* aLogData has a platform dependent line ending, standardize on
2353 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2354 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2355 ULONG cbLogDataPrint = cbLogData;
2356 for (BYTE *s = aLogData.raw(), *d = s;
2357 s - aLogData.raw() < (ssize_t)cbLogData;
2358 s++, d++)
2359 {
2360 if (*s == '\r')
2361 {
2362 /* skip over CR, adjust destination */
2363 d--;
2364 cbLogDataPrint--;
2365 }
2366 else if (s != d)
2367 *d = *s;
2368 }
2369 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2370 uOffset += cbLogData;
2371 }
2372 }
2373 else
2374 {
2375 /* 2nd option can be -details or -argdump */
2376 VMINFO_DETAILS details = VMINFO_NONE;
2377 if (fMachinereadable)
2378 details = VMINFO_MACHINEREADABLE;
2379 else if (fDetails)
2380 details = VMINFO_FULL;
2381 else
2382 details = VMINFO_STANDARD;
2383
2384 ComPtr<IConsole> console;
2385
2386 /* open an existing session for the VM */
2387 rc = machine->LockMachine(a->session, LockType_Shared);
2388 if (SUCCEEDED(rc))
2389 /* get the session machine */
2390 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2391 if (SUCCEEDED(rc))
2392 /* get the session console */
2393 rc = a->session->COMGETTER(Console)(console.asOutParam());
2394
2395 rc = showVMInfo(a->virtualBox, machine, details, console);
2396
2397 if (console)
2398 a->session->UnlockMachine();
2399 }
2400
2401 return SUCCEEDED(rc) ? 0 : 1;
2402}
2403
2404#endif /* !VBOX_ONLY_DOCS */
2405/* 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