VirtualBox

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

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

VRDE: use VRDE properties for video redirection settings.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use