VirtualBox

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

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

Added a promiscModePolicy attribute to INetworkAdapter, three values: deny (default), allow-network (i.e. VMs), allow-all (i.e. include unrelated host traffic).

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