VirtualBox

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

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

Main/Frontends: Also use facilities for guest features (seamless, graphics), added facility-state-to-name to VBoxManage, some renaming.

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