VirtualBox

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

Last change on this file since 35740 was 35707, checked in by vboxsync, 13 years ago

VBoxManage: allow tot save the state of a VM which is already paused

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

© 2023 Oracle
ContactPrivacy policyTerms of Use