VirtualBox

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

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

Main, FE/VBoxManage: Make it possible to mark specific controllers as bootable which means that the BIOS can access devices attached to the controller to boot from it

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