VirtualBox

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

Last change on this file since 30013 was 29465, checked in by vboxsync, 15 years ago

Page fusion enabling

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 84.1 KB
Line 
1/* $Id: VBoxManageInfo.cpp 29465 2010-05-14 11:59:31Z 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);
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 }
1218 }
1219 else
1220 fEnabled = FALSE;
1221 if (details == VMINFO_MACHINEREADABLE)
1222 {
1223 if (fEnabled)
1224 RTPrintf("audio=\"%s\"\n", pszDrv);
1225 else
1226 RTPrintf("audio=\"none\"\n");
1227 }
1228 else
1229 {
1230 RTPrintf("Audio: %s",
1231 fEnabled ? "enabled" : "disabled");
1232 if (fEnabled)
1233 RTPrintf(" (Driver: %s, Controller: %s)",
1234 pszDrv, pszCtrl);
1235 RTPrintf("\n");
1236 }
1237 }
1238
1239 /* Shared clipboard */
1240 {
1241 const char *psz = "Unknown";
1242 ClipboardMode_T enmMode;
1243 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1244 switch (enmMode)
1245 {
1246 case ClipboardMode_Disabled:
1247 if (details == VMINFO_MACHINEREADABLE)
1248 psz = "disabled";
1249 else
1250 psz = "disabled";
1251 break;
1252 case ClipboardMode_HostToGuest:
1253 if (details == VMINFO_MACHINEREADABLE)
1254 psz = "hosttoguest";
1255 else
1256 psz = "HostToGuest";
1257 break;
1258 case ClipboardMode_GuestToHost:
1259 if (details == VMINFO_MACHINEREADABLE)
1260 psz = "guesttohost";
1261 else
1262 psz = "GuestToHost";
1263 break;
1264 case ClipboardMode_Bidirectional:
1265 if (details == VMINFO_MACHINEREADABLE)
1266 psz = "bidirectional";
1267 else
1268 psz = "Bidirectional";
1269 break;
1270 default:
1271 if (details == VMINFO_MACHINEREADABLE)
1272 psz = "unknown";
1273 break;
1274 }
1275 if (details == VMINFO_MACHINEREADABLE)
1276 RTPrintf("clipboard=\"%s\"\n", psz);
1277 else
1278 RTPrintf("Clipboard Mode: %s\n", psz);
1279 }
1280
1281 if (console)
1282 {
1283 ComPtr<IDisplay> display;
1284 CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
1285 do
1286 {
1287 ULONG xRes, yRes, bpp;
1288 rc = display->GetScreenResolution (0, &xRes, &yRes, &bpp);
1289 if (rc == E_ACCESSDENIED)
1290 break; /* VM not powered up */
1291 if (FAILED(rc))
1292 {
1293 com::ErrorInfo info (display);
1294 GluePrintErrorInfo(info);
1295 return rc;
1296 }
1297 if (details == VMINFO_MACHINEREADABLE)
1298 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1299 else
1300 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1301 }
1302 while (0);
1303 }
1304
1305 /*
1306 * VRDP
1307 */
1308 ComPtr<IVRDPServer> vrdpServer;
1309 rc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
1310 if (SUCCEEDED(rc) && vrdpServer)
1311 {
1312 BOOL fEnabled = false;
1313 vrdpServer->COMGETTER(Enabled)(&fEnabled);
1314 if (fEnabled)
1315 {
1316 LONG vrdpPort = -1;
1317 Bstr ports;
1318 vrdpServer->COMGETTER(Ports)(ports.asOutParam());
1319 Bstr address;
1320 vrdpServer->COMGETTER(NetAddress)(address.asOutParam());
1321 BOOL fMultiCon;
1322 vrdpServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1323 BOOL fReuseCon;
1324 vrdpServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1325 BOOL fVideoChannel;
1326 vrdpServer->COMGETTER(VideoChannel)(&fVideoChannel);
1327 ULONG ulVideoChannelQuality;
1328 vrdpServer->COMGETTER(VideoChannelQuality)(&ulVideoChannelQuality);
1329 VRDPAuthType_T vrdpAuthType;
1330 const char *strAuthType;
1331 vrdpServer->COMGETTER(AuthType)(&vrdpAuthType);
1332 switch (vrdpAuthType)
1333 {
1334 case VRDPAuthType_Null:
1335 strAuthType = "null";
1336 break;
1337 case VRDPAuthType_External:
1338 strAuthType = "external";
1339 break;
1340 case VRDPAuthType_Guest:
1341 strAuthType = "guest";
1342 break;
1343 default:
1344 strAuthType = "unknown";
1345 break;
1346 }
1347 if (console)
1348 {
1349 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
1350 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
1351 rc = remoteDisplayInfo->COMGETTER(Port)(&vrdpPort);
1352 if (rc == E_ACCESSDENIED)
1353 {
1354 vrdpPort = -1; /* VM not powered up */
1355 }
1356 if (FAILED(rc))
1357 {
1358 com::ErrorInfo info (remoteDisplayInfo);
1359 GluePrintErrorInfo(info);
1360 return rc;
1361 }
1362 }
1363 if (details == VMINFO_MACHINEREADABLE)
1364 {
1365 RTPrintf("vrdp=\"on\"\n");
1366 RTPrintf("vrdpport=%d\n", vrdpPort);
1367 RTPrintf("vrdpports=\"%lS\"\n", ports.raw());
1368 RTPrintf("vrdpaddress=\"%lS\"\n", address.raw());
1369 RTPrintf("vrdpauthtype=\"%s\"\n", strAuthType);
1370 RTPrintf("vrdpmulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1371 RTPrintf("vrdpreusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1372 RTPrintf("vrdpvideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1373 if (fVideoChannel)
1374 RTPrintf("vrdpvideochannelquality=\"%d\"\n", ulVideoChannelQuality);
1375 }
1376 else
1377 {
1378 if (address.isEmpty())
1379 address = "0.0.0.0";
1380 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);
1381 if (console && vrdpPort != -1 && vrdpPort != 0)
1382 RTPrintf("VRDP port: %d\n", vrdpPort);
1383 if (fVideoChannel)
1384 RTPrintf("Video redirection: enabled (Quality %d)\n", ulVideoChannelQuality);
1385 else
1386 RTPrintf("Video redirection: disabled\n");
1387 }
1388 }
1389 else
1390 {
1391 if (details == VMINFO_MACHINEREADABLE)
1392 RTPrintf("vrdp=\"off\"\n");
1393 else
1394 RTPrintf("VRDP: disabled\n");
1395 }
1396 }
1397
1398 /*
1399 * USB.
1400 */
1401 ComPtr<IUSBController> USBCtl;
1402 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1403 if (SUCCEEDED(rc))
1404 {
1405 BOOL fEnabled;
1406 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1407 if (FAILED(rc))
1408 fEnabled = false;
1409 if (details == VMINFO_MACHINEREADABLE)
1410 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1411 else
1412 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1413
1414 SafeIfaceArray <IUSBDeviceFilter> Coll;
1415 rc = USBCtl->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1416 if (SUCCEEDED(rc))
1417 {
1418 if (details != VMINFO_MACHINEREADABLE)
1419 RTPrintf("\nUSB Device Filters:\n\n");
1420
1421 if (Coll.size() == 0)
1422 {
1423 if (details != VMINFO_MACHINEREADABLE)
1424 RTPrintf("<none>\n\n");
1425 }
1426 else
1427 {
1428 for (size_t index = 0; index < Coll.size(); ++index)
1429 {
1430 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1431
1432 /* Query info. */
1433
1434 if (details != VMINFO_MACHINEREADABLE)
1435 RTPrintf("Index: %zu\n", index);
1436
1437 BOOL bActive = FALSE;
1438 CHECK_ERROR_RET (DevPtr, COMGETTER (Active) (&bActive), rc);
1439 if (details == VMINFO_MACHINEREADABLE)
1440 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1441 else
1442 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1443
1444 Bstr bstr;
1445 CHECK_ERROR_RET (DevPtr, COMGETTER (Name) (bstr.asOutParam()), rc);
1446 if (details == VMINFO_MACHINEREADABLE)
1447 RTPrintf("USBFilterName%zu=\"%lS\"\n", index + 1, bstr.raw());
1448 else
1449 RTPrintf("Name: %lS\n", bstr.raw());
1450 CHECK_ERROR_RET (DevPtr, COMGETTER (VendorId) (bstr.asOutParam()), rc);
1451 if (details == VMINFO_MACHINEREADABLE)
1452 RTPrintf("USBFilterVendorId%zu=\"%lS\"\n", index + 1, bstr.raw());
1453 else
1454 RTPrintf("VendorId: %lS\n", bstr.raw());
1455 CHECK_ERROR_RET (DevPtr, COMGETTER (ProductId) (bstr.asOutParam()), rc);
1456 if (details == VMINFO_MACHINEREADABLE)
1457 RTPrintf("USBFilterProductId%zu=\"%lS\"\n", index + 1, bstr.raw());
1458 else
1459 RTPrintf("ProductId: %lS\n", bstr.raw());
1460 CHECK_ERROR_RET (DevPtr, COMGETTER (Revision) (bstr.asOutParam()), rc);
1461 if (details == VMINFO_MACHINEREADABLE)
1462 RTPrintf("USBFilterRevision%zu=\"%lS\"\n", index + 1, bstr.raw());
1463 else
1464 RTPrintf("Revision: %lS\n", bstr.raw());
1465 CHECK_ERROR_RET (DevPtr, COMGETTER (Manufacturer) (bstr.asOutParam()), rc);
1466 if (details == VMINFO_MACHINEREADABLE)
1467 RTPrintf("USBFilterManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1468 else
1469 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1470 CHECK_ERROR_RET (DevPtr, COMGETTER (Product) (bstr.asOutParam()), rc);
1471 if (details == VMINFO_MACHINEREADABLE)
1472 RTPrintf("USBFilterProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1473 else
1474 RTPrintf("Product: %lS\n", bstr.raw());
1475 CHECK_ERROR_RET (DevPtr, COMGETTER (Remote) (bstr.asOutParam()), rc);
1476 if (details == VMINFO_MACHINEREADABLE)
1477 RTPrintf("USBFilterRemote%zu=\"%lS\"\n", index + 1, bstr.raw());
1478 else
1479 RTPrintf("Remote: %lS\n", bstr.raw());
1480 CHECK_ERROR_RET (DevPtr, COMGETTER (SerialNumber) (bstr.asOutParam()), rc);
1481 if (details == VMINFO_MACHINEREADABLE)
1482 RTPrintf("USBFilterSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1483 else
1484 RTPrintf("Serial Number: %lS\n", bstr.raw());
1485 if (details != VMINFO_MACHINEREADABLE)
1486 {
1487 ULONG fMaskedIfs;
1488 CHECK_ERROR_RET (DevPtr, COMGETTER (MaskedInterfaces) (&fMaskedIfs), rc);
1489 if (fMaskedIfs)
1490 RTPrintf("Masked Interfaces: 0x%08x\n", fMaskedIfs);
1491 RTPrintf("\n");
1492 }
1493 }
1494 }
1495 }
1496
1497 if (console)
1498 {
1499 /* scope */
1500 {
1501 if (details != VMINFO_MACHINEREADABLE)
1502 RTPrintf("Available remote USB devices:\n\n");
1503
1504 SafeIfaceArray <IHostUSBDevice> coll;
1505 CHECK_ERROR_RET (console, COMGETTER(RemoteUSBDevices) (ComSafeArrayAsOutParam(coll)), rc);
1506
1507 if (coll.size() == 0)
1508 {
1509 if (details != VMINFO_MACHINEREADABLE)
1510 RTPrintf("<none>\n\n");
1511 }
1512 else
1513 {
1514 for (size_t index = 0; index < coll.size(); ++index)
1515 {
1516 ComPtr <IHostUSBDevice> dev = coll[index];
1517
1518 /* Query info. */
1519 Bstr id;
1520 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1521 USHORT usVendorId;
1522 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1523 USHORT usProductId;
1524 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1525 USHORT bcdRevision;
1526 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1527
1528 if (details == VMINFO_MACHINEREADABLE)
1529 RTPrintf("USBRemoteUUID%zu=\"%S\"\n"
1530 "USBRemoteVendorId%zu=\"%#06x\"\n"
1531 "USBRemoteProductId%zu=\"%#06x\"\n"
1532 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1533 index + 1, Utf8Str(id).raw(),
1534 index + 1, usVendorId,
1535 index + 1, usProductId,
1536 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1537 else
1538 RTPrintf("UUID: %S\n"
1539 "VendorId: 0x%04x (%04X)\n"
1540 "ProductId: 0x%04x (%04X)\n"
1541 "Revision: %u.%u (%02u%02u)\n",
1542 Utf8Str(id).raw(),
1543 usVendorId, usVendorId, usProductId, usProductId,
1544 bcdRevision >> 8, bcdRevision & 0xff,
1545 bcdRevision >> 8, bcdRevision & 0xff);
1546
1547 /* optional stuff. */
1548 Bstr bstr;
1549 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1550 if (!bstr.isEmpty())
1551 {
1552 if (details == VMINFO_MACHINEREADABLE)
1553 RTPrintf("USBRemoteManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1554 else
1555 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1556 }
1557 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1558 if (!bstr.isEmpty())
1559 {
1560 if (details == VMINFO_MACHINEREADABLE)
1561 RTPrintf("USBRemoteProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1562 else
1563 RTPrintf("Product: %lS\n", bstr.raw());
1564 }
1565 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1566 if (!bstr.isEmpty())
1567 {
1568 if (details == VMINFO_MACHINEREADABLE)
1569 RTPrintf("USBRemoteSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1570 else
1571 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1572 }
1573 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1574 if (!bstr.isEmpty())
1575 {
1576 if (details == VMINFO_MACHINEREADABLE)
1577 RTPrintf("USBRemoteAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1578 else
1579 RTPrintf("Address: %lS\n", bstr.raw());
1580 }
1581
1582 if (details != VMINFO_MACHINEREADABLE)
1583 RTPrintf("\n");
1584 }
1585 }
1586 }
1587
1588 /* scope */
1589 {
1590 if (details != VMINFO_MACHINEREADABLE)
1591 RTPrintf ("Currently Attached USB Devices:\n\n");
1592
1593 SafeIfaceArray <IUSBDevice> coll;
1594 CHECK_ERROR_RET (console, COMGETTER(USBDevices) (ComSafeArrayAsOutParam(coll)), rc);
1595
1596 if (coll.size() == 0)
1597 {
1598 if (details != VMINFO_MACHINEREADABLE)
1599 RTPrintf("<none>\n\n");
1600 }
1601 else
1602 {
1603 for (size_t index = 0; index < coll.size(); ++index)
1604 {
1605 ComPtr <IUSBDevice> dev = coll[index];
1606
1607 /* Query info. */
1608 Bstr id;
1609 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1610 USHORT usVendorId;
1611 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1612 USHORT usProductId;
1613 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1614 USHORT bcdRevision;
1615 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1616
1617 if (details == VMINFO_MACHINEREADABLE)
1618 RTPrintf("USBAttachedUUID%zu=\"%S\"\n"
1619 "USBAttachedVendorId%zu=\"%#06x\"\n"
1620 "USBAttachedProductId%zu=\"%#06x\"\n"
1621 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
1622 index + 1, Utf8Str(id).raw(),
1623 index + 1, usVendorId,
1624 index + 1, usProductId,
1625 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1626 else
1627 RTPrintf("UUID: %S\n"
1628 "VendorId: 0x%04x (%04X)\n"
1629 "ProductId: 0x%04x (%04X)\n"
1630 "Revision: %u.%u (%02u%02u)\n",
1631 Utf8Str(id).raw(),
1632 usVendorId, usVendorId, usProductId, usProductId,
1633 bcdRevision >> 8, bcdRevision & 0xff,
1634 bcdRevision >> 8, bcdRevision & 0xff);
1635
1636 /* optional stuff. */
1637 Bstr bstr;
1638 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1639 if (!bstr.isEmpty())
1640 {
1641 if (details == VMINFO_MACHINEREADABLE)
1642 RTPrintf("USBAttachedManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1643 else
1644 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1645 }
1646 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1647 if (!bstr.isEmpty())
1648 {
1649 if (details == VMINFO_MACHINEREADABLE)
1650 RTPrintf("USBAttachedProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1651 else
1652 RTPrintf("Product: %lS\n", bstr.raw());
1653 }
1654 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1655 if (!bstr.isEmpty())
1656 {
1657 if (details == VMINFO_MACHINEREADABLE)
1658 RTPrintf("USBAttachedSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1659 else
1660 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1661 }
1662 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1663 if (!bstr.isEmpty())
1664 {
1665 if (details == VMINFO_MACHINEREADABLE)
1666 RTPrintf("USBAttachedAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1667 else
1668 RTPrintf("Address: %lS\n", bstr.raw());
1669 }
1670
1671 if (details != VMINFO_MACHINEREADABLE)
1672 RTPrintf("\n");
1673 }
1674 }
1675 }
1676 }
1677 } /* USB */
1678
1679 /*
1680 * Shared folders
1681 */
1682 if (details != VMINFO_MACHINEREADABLE)
1683 RTPrintf("Shared folders: ");
1684 uint32_t numSharedFolders = 0;
1685#if 0 // not yet implemented
1686 /* globally shared folders first */
1687 {
1688 SafeIfaceArray <ISharedFolder> sfColl;
1689 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
1690 for (size_t i = 0; i < sfColl.size(); ++i)
1691 {
1692 ComPtr<ISharedFolder> sf = sfColl[i];
1693 Bstr name, hostPath;
1694 sf->COMGETTER(Name)(name.asOutParam());
1695 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1696 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
1697 ++numSharedFolders;
1698 }
1699 }
1700#endif
1701 /* now VM mappings */
1702 {
1703 com::SafeIfaceArray <ISharedFolder> folders;
1704
1705 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1706
1707 for (size_t i = 0; i < folders.size(); ++i)
1708 {
1709 ComPtr <ISharedFolder> sf = folders[i];
1710
1711 Bstr name, hostPath;
1712 BOOL writable;
1713 sf->COMGETTER(Name)(name.asOutParam());
1714 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1715 sf->COMGETTER(Writable)(&writable);
1716 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1717 RTPrintf("\n\n");
1718 if (details == VMINFO_MACHINEREADABLE)
1719 {
1720 RTPrintf("SharedFolderNameMachineMapping%zu=\"%lS\"\n", i + 1,
1721 name.raw());
1722 RTPrintf("SharedFolderPathMachineMapping%zu=\"%lS\"\n", i + 1,
1723 hostPath.raw());
1724 }
1725 else
1726 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
1727 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
1728 ++numSharedFolders;
1729 }
1730 }
1731 /* transient mappings */
1732 if (console)
1733 {
1734 com::SafeIfaceArray <ISharedFolder> folders;
1735
1736 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1737
1738 for (size_t i = 0; i < folders.size(); ++i)
1739 {
1740 ComPtr <ISharedFolder> sf = folders[i];
1741
1742 Bstr name, hostPath;
1743 sf->COMGETTER(Name)(name.asOutParam());
1744 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1745 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1746 RTPrintf("\n\n");
1747 if (details == VMINFO_MACHINEREADABLE)
1748 {
1749 RTPrintf("SharedFolderNameTransientMapping%zu=\"%lS\"\n", i + 1,
1750 name.raw());
1751 RTPrintf("SharedFolderPathTransientMapping%zu=\"%lS\"\n", i + 1,
1752 hostPath.raw());
1753 }
1754 else
1755 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
1756 ++numSharedFolders;
1757 }
1758 }
1759 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1760 RTPrintf("<none>\n");
1761 if (details != VMINFO_MACHINEREADABLE)
1762 RTPrintf("\n");
1763
1764 if (console)
1765 {
1766 /*
1767 * Live VRDP info.
1768 */
1769 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
1770 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
1771 BOOL Active;
1772 ULONG NumberOfClients;
1773 LONG64 BeginTime;
1774 LONG64 EndTime;
1775 ULONG64 BytesSent;
1776 ULONG64 BytesSentTotal;
1777 ULONG64 BytesReceived;
1778 ULONG64 BytesReceivedTotal;
1779 Bstr User;
1780 Bstr Domain;
1781 Bstr ClientName;
1782 Bstr ClientIP;
1783 ULONG ClientVersion;
1784 ULONG EncryptionStyle;
1785
1786 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Active) (&Active), rc);
1787 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(NumberOfClients) (&NumberOfClients), rc);
1788 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BeginTime) (&BeginTime), rc);
1789 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EndTime) (&EndTime), rc);
1790 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSent) (&BytesSent), rc);
1791 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSentTotal) (&BytesSentTotal), rc);
1792 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceived) (&BytesReceived), rc);
1793 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceivedTotal) (&BytesReceivedTotal), rc);
1794 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(User) (User.asOutParam ()), rc);
1795 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Domain) (Domain.asOutParam ()), rc);
1796 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientName) (ClientName.asOutParam ()), rc);
1797 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientIP) (ClientIP.asOutParam ()), rc);
1798 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientVersion) (&ClientVersion), rc);
1799 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EncryptionStyle) (&EncryptionStyle), rc);
1800
1801 if (details == VMINFO_MACHINEREADABLE)
1802 RTPrintf("VRDPActiveConnection=\"%s\"\n", Active ? "on": "off");
1803 else
1804 RTPrintf("VRDP Connection: %s\n", Active? "active": "not active");
1805
1806 if (details == VMINFO_MACHINEREADABLE)
1807 RTPrintf("VRDPClients=%d\n", NumberOfClients);
1808 else
1809 RTPrintf("Clients so far: %d\n", NumberOfClients);
1810
1811 if (NumberOfClients > 0)
1812 {
1813 char timestr[128];
1814
1815 if (Active)
1816 {
1817 makeTimeStr (timestr, sizeof (timestr), BeginTime);
1818 if (details == VMINFO_MACHINEREADABLE)
1819 RTPrintf("VRDPStartTime=\"%s\"\n", timestr);
1820 else
1821 RTPrintf("Start time: %s\n", timestr);
1822 }
1823 else
1824 {
1825 makeTimeStr (timestr, sizeof (timestr), BeginTime);
1826 if (details == VMINFO_MACHINEREADABLE)
1827 RTPrintf("VRDPLastStartTime=\"%s\"\n", timestr);
1828 else
1829 RTPrintf("Last started: %s\n", timestr);
1830 makeTimeStr (timestr, sizeof (timestr), EndTime);
1831 if (details == VMINFO_MACHINEREADABLE)
1832 RTPrintf("VRDPLastEndTime=\"%s\"\n", timestr);
1833 else
1834 RTPrintf("Last ended: %s\n", timestr);
1835 }
1836
1837 uint64_t ThroughputSend = 0;
1838 uint64_t ThroughputReceive = 0;
1839 if (EndTime != BeginTime)
1840 {
1841 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
1842 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
1843 }
1844
1845 if (details == VMINFO_MACHINEREADABLE)
1846 {
1847 RTPrintf("VRDPBytesSent=%llu\n", BytesSent);
1848 RTPrintf("VRDPThroughputSend=%llu\n", ThroughputSend);
1849 RTPrintf("VRDPBytesSentTotal=%llu\n", BytesSentTotal);
1850
1851 RTPrintf("VRDPBytesReceived=%llu\n", BytesReceived);
1852 RTPrintf("VRDPThroughputReceive=%llu\n", ThroughputReceive);
1853 RTPrintf("VRDPBytesReceivedTotal=%llu\n", BytesReceivedTotal);
1854 }
1855 else
1856 {
1857 RTPrintf("Sent: %llu Bytes\n", BytesSent);
1858 RTPrintf("Average speed: %llu B/s\n", ThroughputSend);
1859 RTPrintf("Sent total: %llu Bytes\n", BytesSentTotal);
1860
1861 RTPrintf("Received: %llu Bytes\n", BytesReceived);
1862 RTPrintf("Speed: %llu B/s\n", ThroughputReceive);
1863 RTPrintf("Received total: %llu Bytes\n", BytesReceivedTotal);
1864 }
1865
1866 if (Active)
1867 {
1868 if (details == VMINFO_MACHINEREADABLE)
1869 {
1870 RTPrintf("VRDPUserName=\"%lS\"\n", User.raw());
1871 RTPrintf("VRDPDomain=\"%lS\"\n", Domain.raw());
1872 RTPrintf("VRDPClientName=\"%lS\"\n", ClientName.raw());
1873 RTPrintf("VRDPClientIP=\"%lS\"\n", ClientIP.raw());
1874 RTPrintf("VRDPClientVersion=%d\n", ClientVersion);
1875 RTPrintf("VRDPEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
1876 }
1877 else
1878 {
1879 RTPrintf("User name: %lS\n", User.raw());
1880 RTPrintf("Domain: %lS\n", Domain.raw());
1881 RTPrintf("Client name: %lS\n", ClientName.raw());
1882 RTPrintf("Client IP: %lS\n", ClientIP.raw());
1883 RTPrintf("Client version: %d\n", ClientVersion);
1884 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
1885 }
1886 }
1887 }
1888
1889 if (details != VMINFO_MACHINEREADABLE)
1890 RTPrintf("\n");
1891 }
1892
1893 if ( details == VMINFO_STANDARD
1894 || details == VMINFO_FULL
1895 || details == VMINFO_MACHINEREADABLE)
1896 {
1897 Bstr description;
1898 machine->COMGETTER(Description)(description.asOutParam());
1899 if (!description.isEmpty())
1900 {
1901 if (details == VMINFO_MACHINEREADABLE)
1902 RTPrintf("description=\"%lS\"\n", description.raw());
1903 else
1904 RTPrintf("Description:\n%lS\n", description.raw());
1905 }
1906 }
1907
1908 ULONG guestVal;
1909 if (details != VMINFO_MACHINEREADABLE)
1910 RTPrintf("Guest:\n\n");
1911
1912 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
1913 if (SUCCEEDED(rc))
1914 {
1915 if (details == VMINFO_MACHINEREADABLE)
1916 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
1917 else
1918 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
1919 }
1920 if (details != VMINFO_MACHINEREADABLE)
1921 RTPrintf("\n");
1922
1923 /*
1924 * snapshots
1925 */
1926 ComPtr<ISnapshot> snapshot;
1927 rc = machine->GetSnapshot(Bstr(), snapshot.asOutParam());
1928 if (SUCCEEDED(rc) && snapshot)
1929 {
1930 ComPtr<ISnapshot> currentSnapshot;
1931 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
1932 if (SUCCEEDED(rc))
1933 {
1934 if (details != VMINFO_MACHINEREADABLE)
1935 RTPrintf("Snapshots:\n\n");
1936 showSnapshots(snapshot, currentSnapshot, details);
1937 }
1938 }
1939
1940 if (details != VMINFO_MACHINEREADABLE)
1941 RTPrintf("\n");
1942 return S_OK;
1943}
1944
1945#if defined(_MSC_VER)
1946# pragma optimize("", on)
1947#endif
1948
1949static const RTGETOPTDEF g_aShowVMInfoOptions[] =
1950{
1951 { "--details", 'D', RTGETOPT_REQ_NOTHING },
1952 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
1953 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
1954 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
1955 { "--log", 'l', RTGETOPT_REQ_UINT32 },
1956};
1957
1958int handleShowVMInfo(HandlerArg *a)
1959{
1960 HRESULT rc;
1961 const char *VMNameOrUuid = NULL;
1962 bool fLog = false;
1963 uint32_t uLogIdx = 0;
1964 bool fDetails = false;
1965 bool fMachinereadable = false;
1966
1967 int c;
1968 RTGETOPTUNION ValueUnion;
1969 RTGETOPTSTATE GetState;
1970 // start at 0 because main() has hacked both the argc and argv given to us
1971 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
1972 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
1973 while ((c = RTGetOpt(&GetState, &ValueUnion)))
1974 {
1975 switch (c)
1976 {
1977 case 'D': // --details
1978 fDetails = true;
1979 break;
1980
1981 case 'M': // --machinereadable
1982 fMachinereadable = true;
1983 break;
1984
1985 case 'l': // --log
1986 fLog = true;
1987 uLogIdx = ValueUnion.u32;
1988 break;
1989
1990 case VINF_GETOPT_NOT_OPTION:
1991 if (!VMNameOrUuid)
1992 VMNameOrUuid = ValueUnion.psz;
1993 else
1994 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
1995 break;
1996
1997 default:
1998 if (c > 0)
1999 {
2000 if (RT_C_IS_PRINT(c))
2001 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2002 else
2003 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2004 }
2005 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2006 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2007 else if (ValueUnion.pDef)
2008 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2009 else
2010 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2011 }
2012 }
2013
2014 /* check for required options */
2015 if (!VMNameOrUuid)
2016 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2017
2018 /* try to find the given machine */
2019 ComPtr <IMachine> machine;
2020 Bstr uuid(VMNameOrUuid);
2021 if (!Guid(VMNameOrUuid).isEmpty())
2022 {
2023 CHECK_ERROR(a->virtualBox, GetMachine(uuid, machine.asOutParam()));
2024 }
2025 else
2026 {
2027 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid), machine.asOutParam()));
2028 if (SUCCEEDED(rc))
2029 machine->COMGETTER(Id)(uuid.asOutParam());
2030 }
2031 if (FAILED(rc))
2032 return 1;
2033
2034 /* Printing the log is exclusive. */
2035 if (fLog && (fMachinereadable || fDetails))
2036 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2037
2038 if (fLog)
2039 {
2040 ULONG64 uOffset = 0;
2041 SafeArray<BYTE> aLogData;
2042 ULONG cbLogData;
2043 while (true)
2044 {
2045 /* Reset the array */
2046 aLogData.setNull();
2047 /* Fetch a chunk of the log file */
2048 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2049 ComSafeArrayAsOutParam(aLogData)));
2050 cbLogData = aLogData.size();
2051 if (cbLogData == 0)
2052 break;
2053 /* aLogData has a platform dependent line ending, standardize on
2054 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2055 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2056 ULONG cbLogDataPrint = cbLogData;
2057 for (BYTE *s = aLogData.raw(), *d = s;
2058 s - aLogData.raw() < (ssize_t)cbLogData;
2059 s++, d++)
2060 {
2061 if (*s == '\r')
2062 {
2063 /* skip over CR, adjust destination */
2064 d--;
2065 cbLogDataPrint--;
2066 }
2067 else if (s != d)
2068 *d = *s;
2069 }
2070 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2071 uOffset += cbLogData;
2072 }
2073 }
2074 else
2075 {
2076 /* 2nd option can be -details or -argdump */
2077 VMINFO_DETAILS details = VMINFO_NONE;
2078 if (fMachinereadable)
2079 details = VMINFO_MACHINEREADABLE;
2080 else if (fDetails)
2081 details = VMINFO_FULL;
2082 else
2083 details = VMINFO_STANDARD;
2084
2085 ComPtr <IConsole> console;
2086
2087 /* open an existing session for the VM */
2088 rc = a->virtualBox->OpenExistingSession(a->session, uuid);
2089 if (SUCCEEDED(rc))
2090 /* get the session machine */
2091 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2092 if (SUCCEEDED(rc))
2093 /* get the session console */
2094 rc = a->session->COMGETTER(Console)(console.asOutParam());
2095
2096 rc = showVMInfo(a->virtualBox, machine, details, console);
2097
2098 if (console)
2099 a->session->Close();
2100 }
2101
2102 return SUCCEEDED(rc) ? 0 : 1;
2103}
2104
2105#endif /* !VBOX_ONLY_DOCS */
2106/* 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