VirtualBox

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

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

VBox/InterfaceVersion: Added IGuest methods.

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