VirtualBox

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

Last change on this file since 28888 was 28836, checked in by vboxsync, 15 years ago

VBoxManage: video channel options for modifyvm

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