VirtualBox

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

Last change on this file since 32962 was 32718, checked in by vboxsync, 14 years ago

com/string: Remove bool conversion operator and other convenience error operators. They are hiding programming errors (like incorrect empty string checks, and in one case a free of the wrong pointer).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 86.1 KB
Line 
1/* $Id: VBoxManageInfo.cpp 32718 2010-09-23 12:57:52Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'showvminfo' command and helper routines.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_ONLY_DOCS
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <VBox/com/com.h>
24#include <VBox/com/string.h>
25#include <VBox/com/Guid.h>
26#include <VBox/com/array.h>
27#include <VBox/com/ErrorInfo.h>
28#include <VBox/com/errorprint.h>
29
30#include <VBox/com/VirtualBox.h>
31
32#include <VBox/log.h>
33#include <iprt/stream.h>
34#include <iprt/time.h>
35#include <iprt/string.h>
36#include <iprt/getopt.h>
37#include <iprt/ctype.h>
38
39#include "VBoxManage.h"
40using namespace com;
41
42
43// funcs
44///////////////////////////////////////////////////////////////////////////////
45
46void showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
47 ComPtr<ISnapshot> &currentSnapshot,
48 VMINFO_DETAILS details,
49 const Bstr &prefix /* = ""*/,
50 int level /*= 0*/)
51{
52 /* start with the root */
53 Bstr name;
54 Bstr uuid;
55 rootSnapshot->COMGETTER(Name)(name.asOutParam());
56 rootSnapshot->COMGETTER(Id)(uuid.asOutParam());
57 if (details == VMINFO_MACHINEREADABLE)
58 {
59 /* print with hierarchical numbering */
60 RTPrintf("SnapshotName%lS=\"%lS\"\n", prefix.raw(), name.raw());
61 RTPrintf("SnapshotUUID%lS=\"%s\"\n", prefix.raw(), Utf8Str(uuid).c_str());
62 }
63 else
64 {
65 /* print with indentation */
66 bool fCurrent = (rootSnapshot == currentSnapshot);
67 RTPrintf(" %lSName: %lS (UUID: %s)%s\n",
68 prefix.raw(),
69 name.raw(),
70 Utf8Str(uuid).c_str(),
71 (fCurrent) ? " *" : "");
72 }
73
74 /* get the children */
75 SafeIfaceArray <ISnapshot> coll;
76 rootSnapshot->COMGETTER(Children)(ComSafeArrayAsOutParam(coll));
77 if (!coll.isNull())
78 {
79 for (size_t index = 0; index < coll.size(); ++index)
80 {
81 ComPtr<ISnapshot> snapshot = coll[index];
82 if (snapshot)
83 {
84 Bstr newPrefix;
85 if (details == VMINFO_MACHINEREADABLE)
86 newPrefix = Utf8StrFmt("%lS-%d", prefix.raw(), index + 1);
87 else
88 {
89 newPrefix = Utf8StrFmt("%lS ", prefix.raw());
90 }
91
92 /* recursive call */
93 showSnapshots(snapshot, currentSnapshot, details, newPrefix, level + 1);
94 }
95 }
96 }
97}
98
99static void makeTimeStr(char *s, int cb, int64_t millies)
100{
101 RTTIME t;
102 RTTIMESPEC ts;
103
104 RTTimeSpecSetMilli(&ts, millies);
105
106 RTTimeExplode(&t, &ts);
107
108 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
109 t.i32Year, t.u8Month, t.u8MonthDay,
110 t.u8Hour, t.u8Minute, t.u8Second);
111}
112
113/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
114 time. MSC 7.1/32 doesn't have quite as much trouble with it, but still
115 sufficient to qualify for this hack as well since this code isn't performance
116 critical and probably won't gain much from the extra optimizing in real life. */
117#if defined(_MSC_VER)
118# pragma optimize("g", off)
119#endif
120
121HRESULT showVMInfo(ComPtr<IVirtualBox> virtualBox,
122 ComPtr<IMachine> machine,
123 VMINFO_DETAILS details /*= VMINFO_NONE*/,
124 ComPtr<IConsole> console /*= ComPtr <IConsole> ()*/)
125{
126 HRESULT rc;
127
128 /*
129 * The rules for output in -argdump format:
130 * 1) the key part (the [0-9a-zA-Z_]+ string before the '=' delimiter)
131 * is all lowercase for "VBoxManage modifyvm" parameters. Any
132 * other values printed are in CamelCase.
133 * 2) strings (anything non-decimal) are printed surrounded by
134 * double quotes '"'. If the strings themselves contain double
135 * quotes, these characters are escaped by '\'. Any '\' character
136 * in the original string is also escaped by '\'.
137 * 3) numbers (containing just [0-9\-]) are written out unchanged.
138 */
139
140 /** @todo the quoting is not yet implemented! */
141 /** @todo error checking! */
142
143 BOOL accessible = FALSE;
144 CHECK_ERROR(machine, COMGETTER(Accessible)(&accessible));
145 if (FAILED(rc)) return rc;
146
147 Bstr uuid;
148 rc = machine->COMGETTER(Id)(uuid.asOutParam());
149
150 if (!accessible)
151 {
152 if (details == VMINFO_COMPACT)
153 RTPrintf("\"<inaccessible>\" {%s}\n", Utf8Str(uuid).c_str());
154 else
155 {
156 if (details == VMINFO_MACHINEREADABLE)
157 RTPrintf("name=\"<inaccessible>\"\n");
158 else
159 RTPrintf("Name: <inaccessible!>\n");
160 if (details == VMINFO_MACHINEREADABLE)
161 RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
162 else
163 RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
164 if (details != VMINFO_MACHINEREADABLE)
165 {
166 Bstr settingsFilePath;
167 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
168 RTPrintf("Config file: %lS\n", settingsFilePath.raw());
169 ComPtr<IVirtualBoxErrorInfo> accessError;
170 rc = machine->COMGETTER(AccessError)(accessError.asOutParam());
171 RTPrintf("Access error details:\n");
172 ErrorInfo ei(accessError, COM_IIDOF(IVirtualBoxErrorInfo));
173 GluePrintErrorInfo(ei);
174 RTPrintf("\n");
175 }
176 }
177 return S_OK;
178 }
179
180 Bstr machineName;
181 rc = machine->COMGETTER(Name)(machineName.asOutParam());
182
183 if (details == VMINFO_COMPACT)
184 {
185 RTPrintf("\"%lS\" {%s}\n", machineName.raw(), Utf8Str(uuid).c_str());
186 return S_OK;
187 }
188
189 if (details == VMINFO_MACHINEREADABLE)
190 RTPrintf("name=\"%lS\"\n", machineName.raw());
191 else
192 RTPrintf("Name: %lS\n", machineName.raw());
193
194 Bstr osTypeId;
195 rc = machine->COMGETTER(OSTypeId)(osTypeId.asOutParam());
196 ComPtr<IGuestOSType> osType;
197 rc = virtualBox->GetGuestOSType(osTypeId.raw(), osType.asOutParam());
198 Bstr osName;
199 rc = osType->COMGETTER(Description)(osName.asOutParam());
200 if (details == VMINFO_MACHINEREADABLE)
201 RTPrintf("ostype=\"%lS\"\n", osTypeId.raw());
202 else
203 RTPrintf("Guest OS: %lS\n", osName.raw());
204
205 if (details == VMINFO_MACHINEREADABLE)
206 RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
207 else
208 RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
209
210 Bstr settingsFilePath;
211 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
212 if (details == VMINFO_MACHINEREADABLE)
213 RTPrintf("CfgFile=\"%lS\"\n", settingsFilePath.raw());
214 else
215 RTPrintf("Config file: %lS\n", settingsFilePath.raw());
216
217 Bstr 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.raw(), i, k,
679 medium.asOutParam());
680 if (SUCCEEDED(rc) && medium)
681 {
682 BOOL fPassthrough;
683 ComPtr<IMediumAttachment> mediumAttach;
684
685 rc = machine->GetMediumAttachment(storageCtlName.raw(),
686 i, k,
687 mediumAttach.asOutParam());
688 if (SUCCEEDED(rc) && mediumAttach)
689 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
690
691 medium->COMGETTER(Location)(filePath.asOutParam());
692 medium->COMGETTER(Id)(uuid.asOutParam());
693
694 if (details == VMINFO_MACHINEREADABLE)
695 {
696 RTPrintf("\"%lS-%d-%d\"=\"%lS\"\n", storageCtlName.raw(),
697 i, k, filePath.raw());
698 RTPrintf("\"%lS-ImageUUID-%d-%d\"=\"%s\"\n",
699 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
700 if (fPassthrough)
701 RTPrintf("\"%lS-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
702 fPassthrough ? "on" : "off");
703 }
704 else
705 {
706 RTPrintf("%lS (%d, %d): %lS (UUID: %s)",
707 storageCtlName.raw(), i, k, filePath.raw(),
708 Utf8Str(uuid).c_str());
709 if (fPassthrough)
710 RTPrintf(" (passthrough enabled)");
711 RTPrintf("\n");
712 }
713 }
714 else if (SUCCEEDED(rc))
715 {
716 if (details == VMINFO_MACHINEREADABLE)
717 RTPrintf("\"%lS-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
718 else
719 RTPrintf("%lS (%d, %d): Empty\n", storageCtlName.raw(), i, k);
720 }
721 else
722 {
723 if (details == VMINFO_MACHINEREADABLE)
724 RTPrintf("\"%lS-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
725 }
726 }
727 }
728 }
729
730 /* get the maximum amount of NICS */
731 ComPtr<ISystemProperties> sysProps;
732 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
733 ULONG maxNICs = 0;
734 sysProps->COMGETTER(NetworkAdapterCount)(&maxNICs);
735 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
736 {
737 ComPtr<INetworkAdapter> nic;
738 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
739 if (SUCCEEDED(rc) && nic)
740 {
741 BOOL fEnabled;
742 nic->COMGETTER(Enabled)(&fEnabled);
743 if (!fEnabled)
744 {
745 if (details == VMINFO_MACHINEREADABLE)
746 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
747 else
748 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
749 }
750 else
751 {
752 Bstr strMACAddress;
753 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
754 Utf8Str strAttachment;
755 Utf8Str strNatSettings = "";
756 Utf8Str strNatForwardings = "";
757 NetworkAttachmentType_T attachment;
758 nic->COMGETTER(AttachmentType)(&attachment);
759 switch (attachment)
760 {
761 case NetworkAttachmentType_Null:
762 if (details == VMINFO_MACHINEREADABLE)
763 strAttachment = "null";
764 else
765 strAttachment = "none";
766 break;
767 case NetworkAttachmentType_NAT:
768 {
769 Bstr strNetwork;
770 ComPtr<INATEngine> driver;
771 nic->COMGETTER(NatDriver)(driver.asOutParam());
772 driver->COMGETTER(Network)(strNetwork.asOutParam());
773 com::SafeArray<BSTR> forwardings;
774 driver->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
775 strNatForwardings = "";
776 for (size_t i = 0; i < forwardings.size(); ++i)
777 {
778 bool fSkip = false;
779 uint16_t port = 0;
780 BSTR r = forwardings[i];
781 Utf8Str utf = Utf8Str(r);
782 Utf8Str strName;
783 Utf8Str strProto;
784 Utf8Str strHostPort;
785 Utf8Str strHostIP;
786 Utf8Str strGuestPort;
787 Utf8Str strGuestIP;
788 size_t pos, ppos;
789 pos = ppos = 0;
790 #define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
791 do { \
792 pos = str.find(",", ppos); \
793 if (pos == Utf8Str::npos) \
794 { \
795 Log(( #res " extracting from %s is failed\n", str.c_str())); \
796 fSkip = true; \
797 } \
798 res = str.substr(ppos, pos - ppos); \
799 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
800 ppos = pos + 1; \
801 } while (0)
802 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
803 if (fSkip) continue;
804 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
805 if (fSkip) continue;
806 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
807 if (fSkip) continue;
808 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
809 if (fSkip) continue;
810 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
811 if (fSkip) continue;
812 strGuestPort = utf.substr(ppos, utf.length() - ppos);
813 #undef ITERATE_TO_NEXT_TERM
814 switch (strProto.toUInt32())
815 {
816 case NATProtocol_TCP:
817 strProto = "tcp";
818 break;
819 case NATProtocol_UDP:
820 strProto = "udp";
821 break;
822 default:
823 strProto = "unk";
824 break;
825 }
826 if (details == VMINFO_MACHINEREADABLE)
827 {
828 strNatForwardings = Utf8StrFmt("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
829 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
830 strHostIP.c_str(), strHostPort.c_str(),
831 strGuestIP.c_str(), strGuestPort.c_str());
832 }
833 else
834 {
835 strNatForwardings = Utf8StrFmt("%sNIC %d Rule(%d): name = %s, protocol = %s,"
836 " host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
837 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(), strProto.c_str(),
838 strHostIP.c_str(), strHostPort.c_str(),
839 strGuestIP.c_str(), strGuestPort.c_str());
840 }
841 }
842 ULONG mtu = 0;
843 ULONG sockSnd = 0;
844 ULONG sockRcv = 0;
845 ULONG tcpSnd = 0;
846 ULONG tcpRcv = 0;
847 driver->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
848
849 if (details == VMINFO_MACHINEREADABLE)
850 {
851 RTPrintf("natnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
852 strAttachment = "nat";
853 strNatSettings = Utf8StrFmt("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
854 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
855 }
856 else
857 {
858 strAttachment = "NAT";
859 strNatSettings = Utf8StrFmt("NIC %d Settings: MTU: %d, Socket( send: %d, receive: %d), TCP Window( send:%d, receive: %d)\n",
860 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64 , tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
861 }
862 break;
863 }
864 case NetworkAttachmentType_Bridged:
865 {
866 Bstr strBridgeAdp;
867 nic->COMGETTER(HostInterface)(strBridgeAdp.asOutParam());
868 if (details == VMINFO_MACHINEREADABLE)
869 {
870 RTPrintf("bridgeadapter%d=\"%lS\"\n", currentNIC + 1, strBridgeAdp.raw());
871 strAttachment = "bridged";
872 }
873 else
874 strAttachment = Utf8StrFmt("Bridged Interface '%lS'", strBridgeAdp.raw());
875 break;
876 }
877 case NetworkAttachmentType_Internal:
878 {
879 Bstr strNetwork;
880 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
881 if (details == VMINFO_MACHINEREADABLE)
882 {
883 RTPrintf("intnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
884 strAttachment = "intnet";
885 }
886 else
887 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).c_str());
888 break;
889 }
890#if defined(VBOX_WITH_NETFLT)
891 case NetworkAttachmentType_HostOnly:
892 {
893 Bstr strHostonlyAdp;
894 nic->COMGETTER(HostInterface)(strHostonlyAdp.asOutParam());
895 if (details == VMINFO_MACHINEREADABLE)
896 {
897 RTPrintf("hostonlyadapter%d=\"%lS\"\n", currentNIC + 1, strHostonlyAdp.raw());
898 strAttachment = "hostonly";
899 }
900 else
901 strAttachment = Utf8StrFmt("Host-only Interface '%lS'", strHostonlyAdp.raw());
902 break;
903 }
904#endif
905#ifdef VBOX_WITH_VDE
906 case NetworkAttachmentType_VDE:
907 {
908 Bstr strVDEAdp;
909 nic->COMGETTER(VDENetwork)(strVDEAdp.asOutParam());
910 if (details == VMINFO_MACHINEREADABLE)
911 {
912 RTPrintf("vdenet%d=\"%lS\"\n", currentNIC + 1, strVDEAdp.raw());
913 strAttachment = "VDE";
914 }
915 else
916 strAttachment = Utf8StrFmt("VDE Network '%lS'", strVDEAdp.raw());
917 break;
918 }
919#endif
920 default:
921 strAttachment = "unknown";
922 break;
923 }
924
925 /* cable connected */
926 BOOL fConnected;
927 nic->COMGETTER(CableConnected)(&fConnected);
928
929 /* trace stuff */
930 BOOL fTraceEnabled;
931 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
932 Bstr traceFile;
933 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
934
935 /* NIC type */
936 Utf8Str strNICType;
937 NetworkAdapterType_T NICType;
938 nic->COMGETTER(AdapterType)(&NICType);
939 switch (NICType) {
940 case NetworkAdapterType_Am79C970A:
941 strNICType = "Am79C970A";
942 break;
943 case NetworkAdapterType_Am79C973:
944 strNICType = "Am79C973";
945 break;
946#ifdef VBOX_WITH_E1000
947 case NetworkAdapterType_I82540EM:
948 strNICType = "82540EM";
949 break;
950 case NetworkAdapterType_I82543GC:
951 strNICType = "82543GC";
952 break;
953 case NetworkAdapterType_I82545EM:
954 strNICType = "82545EM";
955 break;
956#endif
957#ifdef VBOX_WITH_VIRTIO
958 case NetworkAdapterType_Virtio:
959 strNICType = "virtio";
960 break;
961#endif /* VBOX_WITH_VIRTIO */
962 default:
963 strNICType = "unknown";
964 break;
965 }
966
967 /* reported line speed */
968 ULONG ulLineSpeed;
969 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
970
971 /* boot priority of the adapter */
972 ULONG ulBootPriority;
973 nic->COMGETTER(BootPriority)(&ulBootPriority);
974
975 if (details == VMINFO_MACHINEREADABLE)
976 {
977 RTPrintf("macaddress%d=\"%lS\"\n", currentNIC + 1, strMACAddress.raw());
978 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
979 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
980 }
981 else
982 RTPrintf("NIC %d: MAC: %lS, Attachment: %s, Cable connected: %s, Trace: %s (file: %lS), Type: %s, Reported speed: %d Mbps, Boot priority: %d\n",
983 currentNIC + 1, strMACAddress.raw(), strAttachment.c_str(),
984 fConnected ? "on" : "off",
985 fTraceEnabled ? "on" : "off",
986 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
987 strNICType.c_str(),
988 ulLineSpeed / 1000,
989 (int)ulBootPriority);
990 if (strNatSettings.length())
991 RTPrintf(strNatSettings.c_str());
992 if (strNatForwardings.length())
993 RTPrintf(strNatForwardings.c_str());
994 }
995 }
996 }
997
998 /* Pointing device information */
999 PointingHidType_T aPointingHid;
1000 const char *pszHid = "Unknown";
1001 const char *pszMrHid = "unknown";
1002 machine->COMGETTER(PointingHidType)(&aPointingHid);
1003 switch (aPointingHid)
1004 {
1005 case PointingHidType_None:
1006 pszHid = "None";
1007 pszMrHid = "none";
1008 break;
1009 case PointingHidType_PS2Mouse:
1010 pszHid = "PS/2 Mouse";
1011 pszMrHid = "ps2mouse";
1012 break;
1013 case PointingHidType_USBMouse:
1014 pszHid = "USB Mouse";
1015 pszMrHid = "usbmouse";
1016 break;
1017 case PointingHidType_USBTablet:
1018 pszHid = "USB Tablet";
1019 pszMrHid = "usbtablet";
1020 break;
1021 case PointingHidType_ComboMouse:
1022 pszHid = "USB Tablet and PS/2 Mouse";
1023 pszMrHid = "combomouse";
1024 break;
1025 default:
1026 break;
1027 }
1028 if (details == VMINFO_MACHINEREADABLE)
1029 RTPrintf("hidpointing=\"%s\"\n", pszMrHid);
1030 else
1031 RTPrintf("Pointing Device: %s\n", pszHid);
1032
1033 /* Keyboard device information */
1034 KeyboardHidType_T aKeyboardHid;
1035 machine->COMGETTER(KeyboardHidType)(&aKeyboardHid);
1036 pszHid = "Unknown";
1037 pszMrHid = "unknown";
1038 switch (aKeyboardHid)
1039 {
1040 case KeyboardHidType_None:
1041 pszHid = "None";
1042 pszMrHid = "none";
1043 break;
1044 case KeyboardHidType_PS2Keyboard:
1045 pszHid = "PS/2 Keyboard";
1046 pszMrHid = "ps2kbd";
1047 break;
1048 case KeyboardHidType_USBKeyboard:
1049 pszHid = "USB Keyboard";
1050 pszMrHid = "usbkbd";
1051 break;
1052 case KeyboardHidType_ComboKeyboard:
1053 pszHid = "USB and PS/2 Keyboard";
1054 pszMrHid = "combokbd";
1055 break;
1056 default:
1057 break;
1058 }
1059 if (details == VMINFO_MACHINEREADABLE)
1060 RTPrintf("hidkeyboard=\"%s\"\n", pszMrHid);
1061 else
1062 RTPrintf("Keyboard Device: %s\n", pszHid);
1063
1064 /* get the maximum amount of UARTs */
1065 ULONG maxUARTs = 0;
1066 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1067 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1068 {
1069 ComPtr<ISerialPort> uart;
1070 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1071 if (SUCCEEDED(rc) && uart)
1072 {
1073 BOOL fEnabled;
1074 uart->COMGETTER(Enabled)(&fEnabled);
1075 if (!fEnabled)
1076 {
1077 if (details == VMINFO_MACHINEREADABLE)
1078 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1079 else
1080 RTPrintf("UART %d: disabled\n", currentUART + 1);
1081 }
1082 else
1083 {
1084 ULONG ulIRQ, ulIOBase;
1085 PortMode_T HostMode;
1086 Bstr path;
1087 BOOL fServer;
1088 uart->COMGETTER(IRQ)(&ulIRQ);
1089 uart->COMGETTER(IOBase)(&ulIOBase);
1090 uart->COMGETTER(Path)(path.asOutParam());
1091 uart->COMGETTER(Server)(&fServer);
1092 uart->COMGETTER(HostMode)(&HostMode);
1093
1094 if (details == VMINFO_MACHINEREADABLE)
1095 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1096 ulIOBase, ulIRQ);
1097 else
1098 RTPrintf("UART %d: I/O base: %#06x, IRQ: %d",
1099 currentUART + 1, ulIOBase, ulIRQ);
1100 switch (HostMode)
1101 {
1102 default:
1103 case PortMode_Disconnected:
1104 if (details == VMINFO_MACHINEREADABLE)
1105 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1106 else
1107 RTPrintf(", disconnected\n");
1108 break;
1109 case PortMode_RawFile:
1110 if (details == VMINFO_MACHINEREADABLE)
1111 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
1112 path.raw());
1113 else
1114 RTPrintf(", attached to raw file '%lS'\n",
1115 path.raw());
1116 break;
1117 case PortMode_HostPipe:
1118 if (details == VMINFO_MACHINEREADABLE)
1119 RTPrintf("uartmode%d=\"%s,%lS\"\n", currentUART + 1,
1120 fServer ? "server" : "client", path.raw());
1121 else
1122 RTPrintf(", attached to pipe (%s) '%lS'\n",
1123 fServer ? "server" : "client", path.raw());
1124 break;
1125 case PortMode_HostDevice:
1126 if (details == VMINFO_MACHINEREADABLE)
1127 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
1128 path.raw());
1129 else
1130 RTPrintf(", attached to device '%lS'\n", path.raw());
1131 break;
1132 }
1133 }
1134 }
1135 }
1136
1137 ComPtr<IAudioAdapter> AudioAdapter;
1138 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1139 if (SUCCEEDED(rc))
1140 {
1141 const char *pszDrv = "Unknown";
1142 const char *pszCtrl = "Unknown";
1143 BOOL fEnabled;
1144 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1145 if (SUCCEEDED(rc) && fEnabled)
1146 {
1147 AudioDriverType_T enmDrvType;
1148 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1149 switch (enmDrvType)
1150 {
1151 case AudioDriverType_Null:
1152 if (details == VMINFO_MACHINEREADABLE)
1153 pszDrv = "null";
1154 else
1155 pszDrv = "Null";
1156 break;
1157 case AudioDriverType_WinMM:
1158 if (details == VMINFO_MACHINEREADABLE)
1159 pszDrv = "winmm";
1160 else
1161 pszDrv = "WINMM";
1162 break;
1163 case AudioDriverType_DirectSound:
1164 if (details == VMINFO_MACHINEREADABLE)
1165 pszDrv = "dsound";
1166 else
1167 pszDrv = "DSOUND";
1168 break;
1169 case AudioDriverType_OSS:
1170 if (details == VMINFO_MACHINEREADABLE)
1171 pszDrv = "oss";
1172 else
1173 pszDrv = "OSS";
1174 break;
1175 case AudioDriverType_ALSA:
1176 if (details == VMINFO_MACHINEREADABLE)
1177 pszDrv = "alsa";
1178 else
1179 pszDrv = "ALSA";
1180 break;
1181 case AudioDriverType_Pulse:
1182 if (details == VMINFO_MACHINEREADABLE)
1183 pszDrv = "pulse";
1184 else
1185 pszDrv = "PulseAudio";
1186 break;
1187 case AudioDriverType_CoreAudio:
1188 if (details == VMINFO_MACHINEREADABLE)
1189 pszDrv = "coreaudio";
1190 else
1191 pszDrv = "CoreAudio";
1192 break;
1193 case AudioDriverType_SolAudio:
1194 if (details == VMINFO_MACHINEREADABLE)
1195 pszDrv = "solaudio";
1196 else
1197 pszDrv = "SolAudio";
1198 break;
1199 default:
1200 if (details == VMINFO_MACHINEREADABLE)
1201 pszDrv = "unknown";
1202 break;
1203 }
1204 AudioControllerType_T enmCtrlType;
1205 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1206 switch (enmCtrlType)
1207 {
1208 case AudioControllerType_AC97:
1209 if (details == VMINFO_MACHINEREADABLE)
1210 pszCtrl = "ac97";
1211 else
1212 pszCtrl = "AC97";
1213 break;
1214 case AudioControllerType_SB16:
1215 if (details == VMINFO_MACHINEREADABLE)
1216 pszCtrl = "sb16";
1217 else
1218 pszCtrl = "SB16";
1219 break;
1220 case AudioControllerType_HDA:
1221 if (details == VMINFO_MACHINEREADABLE)
1222 pszCtrl = "hda";
1223 else
1224 pszCtrl = "HDA";
1225 break;
1226 }
1227 }
1228 else
1229 fEnabled = FALSE;
1230 if (details == VMINFO_MACHINEREADABLE)
1231 {
1232 if (fEnabled)
1233 RTPrintf("audio=\"%s\"\n", pszDrv);
1234 else
1235 RTPrintf("audio=\"none\"\n");
1236 }
1237 else
1238 {
1239 RTPrintf("Audio: %s",
1240 fEnabled ? "enabled" : "disabled");
1241 if (fEnabled)
1242 RTPrintf(" (Driver: %s, Controller: %s)",
1243 pszDrv, pszCtrl);
1244 RTPrintf("\n");
1245 }
1246 }
1247
1248 /* Shared clipboard */
1249 {
1250 const char *psz = "Unknown";
1251 ClipboardMode_T enmMode;
1252 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1253 switch (enmMode)
1254 {
1255 case ClipboardMode_Disabled:
1256 if (details == VMINFO_MACHINEREADABLE)
1257 psz = "disabled";
1258 else
1259 psz = "disabled";
1260 break;
1261 case ClipboardMode_HostToGuest:
1262 if (details == VMINFO_MACHINEREADABLE)
1263 psz = "hosttoguest";
1264 else
1265 psz = "HostToGuest";
1266 break;
1267 case ClipboardMode_GuestToHost:
1268 if (details == VMINFO_MACHINEREADABLE)
1269 psz = "guesttohost";
1270 else
1271 psz = "GuestToHost";
1272 break;
1273 case ClipboardMode_Bidirectional:
1274 if (details == VMINFO_MACHINEREADABLE)
1275 psz = "bidirectional";
1276 else
1277 psz = "Bidirectional";
1278 break;
1279 default:
1280 if (details == VMINFO_MACHINEREADABLE)
1281 psz = "unknown";
1282 break;
1283 }
1284 if (details == VMINFO_MACHINEREADABLE)
1285 RTPrintf("clipboard=\"%s\"\n", psz);
1286 else
1287 RTPrintf("Clipboard Mode: %s\n", psz);
1288 }
1289
1290 if (console)
1291 {
1292 ComPtr<IDisplay> display;
1293 CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
1294 do
1295 {
1296 ULONG xRes, yRes, bpp;
1297 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp);
1298 if (rc == E_ACCESSDENIED)
1299 break; /* VM not powered up */
1300 if (FAILED(rc))
1301 {
1302 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1303 GluePrintErrorInfo(info);
1304 return rc;
1305 }
1306 if (details == VMINFO_MACHINEREADABLE)
1307 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1308 else
1309 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1310 }
1311 while (0);
1312 }
1313
1314 /*
1315 * VRDP
1316 */
1317 ComPtr<IVRDPServer> vrdpServer;
1318 rc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
1319 if (SUCCEEDED(rc) && vrdpServer)
1320 {
1321 BOOL fEnabled = false;
1322 vrdpServer->COMGETTER(Enabled)(&fEnabled);
1323 if (fEnabled)
1324 {
1325 LONG vrdpPort = -1;
1326 Bstr ports;
1327 vrdpServer->COMGETTER(Ports)(ports.asOutParam());
1328 Bstr address;
1329 vrdpServer->COMGETTER(NetAddress)(address.asOutParam());
1330 BOOL fMultiCon;
1331 vrdpServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1332 BOOL fReuseCon;
1333 vrdpServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
1334 BOOL fVideoChannel;
1335 vrdpServer->COMGETTER(VideoChannel)(&fVideoChannel);
1336 ULONG ulVideoChannelQuality;
1337 vrdpServer->COMGETTER(VideoChannelQuality)(&ulVideoChannelQuality);
1338 VRDPAuthType_T vrdpAuthType;
1339 const char *strAuthType;
1340 vrdpServer->COMGETTER(AuthType)(&vrdpAuthType);
1341 switch (vrdpAuthType)
1342 {
1343 case VRDPAuthType_Null:
1344 strAuthType = "null";
1345 break;
1346 case VRDPAuthType_External:
1347 strAuthType = "external";
1348 break;
1349 case VRDPAuthType_Guest:
1350 strAuthType = "guest";
1351 break;
1352 default:
1353 strAuthType = "unknown";
1354 break;
1355 }
1356 if (console)
1357 {
1358 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
1359 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
1360 rc = remoteDisplayInfo->COMGETTER(Port)(&vrdpPort);
1361 if (rc == E_ACCESSDENIED)
1362 {
1363 vrdpPort = -1; /* VM not powered up */
1364 }
1365 if (FAILED(rc))
1366 {
1367 com::ErrorInfo info(remoteDisplayInfo, COM_IIDOF(IRemoteDisplayInfo));
1368 GluePrintErrorInfo(info);
1369 return rc;
1370 }
1371 }
1372 if (details == VMINFO_MACHINEREADABLE)
1373 {
1374 RTPrintf("vrdp=\"on\"\n");
1375 RTPrintf("vrdpport=%d\n", vrdpPort);
1376 RTPrintf("vrdpports=\"%lS\"\n", ports.raw());
1377 RTPrintf("vrdpaddress=\"%lS\"\n", address.raw());
1378 RTPrintf("vrdpauthtype=\"%s\"\n", strAuthType);
1379 RTPrintf("vrdpmulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1380 RTPrintf("vrdpreusecon=\"%s\"\n", fReuseCon ? "on" : "off");
1381 RTPrintf("vrdpvideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
1382 if (fVideoChannel)
1383 RTPrintf("vrdpvideochannelquality=\"%d\"\n", ulVideoChannelQuality);
1384 }
1385 else
1386 {
1387 if (address.isEmpty())
1388 address = "0.0.0.0";
1389 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);
1390 if (console && vrdpPort != -1 && vrdpPort != 0)
1391 RTPrintf("VRDP port: %d\n", vrdpPort);
1392 if (fVideoChannel)
1393 RTPrintf("Video redirection: enabled (Quality %d)\n", ulVideoChannelQuality);
1394 else
1395 RTPrintf("Video redirection: disabled\n");
1396 }
1397 }
1398 else
1399 {
1400 if (details == VMINFO_MACHINEREADABLE)
1401 RTPrintf("vrdp=\"off\"\n");
1402 else
1403 RTPrintf("VRDP: disabled\n");
1404 }
1405 }
1406
1407 /*
1408 * USB.
1409 */
1410 ComPtr<IUSBController> USBCtl;
1411 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1412 if (SUCCEEDED(rc))
1413 {
1414 BOOL fEnabled;
1415 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1416 if (FAILED(rc))
1417 fEnabled = false;
1418 if (details == VMINFO_MACHINEREADABLE)
1419 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1420 else
1421 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1422
1423 SafeIfaceArray <IUSBDeviceFilter> Coll;
1424 rc = USBCtl->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
1425 if (SUCCEEDED(rc))
1426 {
1427 if (details != VMINFO_MACHINEREADABLE)
1428 RTPrintf("\nUSB Device Filters:\n\n");
1429
1430 if (Coll.size() == 0)
1431 {
1432 if (details != VMINFO_MACHINEREADABLE)
1433 RTPrintf("<none>\n\n");
1434 }
1435 else
1436 {
1437 for (size_t index = 0; index < Coll.size(); ++index)
1438 {
1439 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
1440
1441 /* Query info. */
1442
1443 if (details != VMINFO_MACHINEREADABLE)
1444 RTPrintf("Index: %zu\n", index);
1445
1446 BOOL bActive = FALSE;
1447 CHECK_ERROR_RET(DevPtr, COMGETTER(Active)(&bActive), rc);
1448 if (details == VMINFO_MACHINEREADABLE)
1449 RTPrintf("USBFilterActive%zu=\"%s\"\n", index + 1, bActive ? "on" : "off");
1450 else
1451 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1452
1453 Bstr bstr;
1454 CHECK_ERROR_RET(DevPtr, COMGETTER(Name)(bstr.asOutParam()), rc);
1455 if (details == VMINFO_MACHINEREADABLE)
1456 RTPrintf("USBFilterName%zu=\"%lS\"\n", index + 1, bstr.raw());
1457 else
1458 RTPrintf("Name: %lS\n", bstr.raw());
1459 CHECK_ERROR_RET(DevPtr, COMGETTER(VendorId)(bstr.asOutParam()), rc);
1460 if (details == VMINFO_MACHINEREADABLE)
1461 RTPrintf("USBFilterVendorId%zu=\"%lS\"\n", index + 1, bstr.raw());
1462 else
1463 RTPrintf("VendorId: %lS\n", bstr.raw());
1464 CHECK_ERROR_RET(DevPtr, COMGETTER(ProductId)(bstr.asOutParam()), rc);
1465 if (details == VMINFO_MACHINEREADABLE)
1466 RTPrintf("USBFilterProductId%zu=\"%lS\"\n", index + 1, bstr.raw());
1467 else
1468 RTPrintf("ProductId: %lS\n", bstr.raw());
1469 CHECK_ERROR_RET(DevPtr, COMGETTER(Revision)(bstr.asOutParam()), rc);
1470 if (details == VMINFO_MACHINEREADABLE)
1471 RTPrintf("USBFilterRevision%zu=\"%lS\"\n", index + 1, bstr.raw());
1472 else
1473 RTPrintf("Revision: %lS\n", bstr.raw());
1474 CHECK_ERROR_RET(DevPtr, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1475 if (details == VMINFO_MACHINEREADABLE)
1476 RTPrintf("USBFilterManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1477 else
1478 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1479 CHECK_ERROR_RET(DevPtr, COMGETTER(Product)(bstr.asOutParam()), rc);
1480 if (details == VMINFO_MACHINEREADABLE)
1481 RTPrintf("USBFilterProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1482 else
1483 RTPrintf("Product: %lS\n", bstr.raw());
1484 CHECK_ERROR_RET(DevPtr, COMGETTER(Remote)(bstr.asOutParam()), rc);
1485 if (details == VMINFO_MACHINEREADABLE)
1486 RTPrintf("USBFilterRemote%zu=\"%lS\"\n", index + 1, bstr.raw());
1487 else
1488 RTPrintf("Remote: %lS\n", bstr.raw());
1489 CHECK_ERROR_RET(DevPtr, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1490 if (details == VMINFO_MACHINEREADABLE)
1491 RTPrintf("USBFilterSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1492 else
1493 RTPrintf("Serial Number: %lS\n", bstr.raw());
1494 if (details != VMINFO_MACHINEREADABLE)
1495 {
1496 ULONG fMaskedIfs;
1497 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
1498 if (fMaskedIfs)
1499 RTPrintf("Masked Interfaces: %#010x\n", fMaskedIfs);
1500 RTPrintf("\n");
1501 }
1502 }
1503 }
1504 }
1505
1506 if (console)
1507 {
1508 /* scope */
1509 {
1510 if (details != VMINFO_MACHINEREADABLE)
1511 RTPrintf("Available remote USB devices:\n\n");
1512
1513 SafeIfaceArray <IHostUSBDevice> coll;
1514 CHECK_ERROR_RET(console, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1515
1516 if (coll.size() == 0)
1517 {
1518 if (details != VMINFO_MACHINEREADABLE)
1519 RTPrintf("<none>\n\n");
1520 }
1521 else
1522 {
1523 for (size_t index = 0; index < coll.size(); ++index)
1524 {
1525 ComPtr <IHostUSBDevice> dev = coll[index];
1526
1527 /* Query info. */
1528 Bstr id;
1529 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1530 USHORT usVendorId;
1531 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1532 USHORT usProductId;
1533 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1534 USHORT bcdRevision;
1535 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1536
1537 if (details == VMINFO_MACHINEREADABLE)
1538 RTPrintf("USBRemoteUUID%zu=\"%S\"\n"
1539 "USBRemoteVendorId%zu=\"%#06x\"\n"
1540 "USBRemoteProductId%zu=\"%#06x\"\n"
1541 "USBRemoteRevision%zu=\"%#04x%02x\"\n",
1542 index + 1, Utf8Str(id).c_str(),
1543 index + 1, usVendorId,
1544 index + 1, usProductId,
1545 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1546 else
1547 RTPrintf("UUID: %S\n"
1548 "VendorId: %#06x (%04X)\n"
1549 "ProductId: %#06x (%04X)\n"
1550 "Revision: %u.%u (%02u%02u)\n",
1551 Utf8Str(id).c_str(),
1552 usVendorId, usVendorId, usProductId, usProductId,
1553 bcdRevision >> 8, bcdRevision & 0xff,
1554 bcdRevision >> 8, bcdRevision & 0xff);
1555
1556 /* optional stuff. */
1557 Bstr bstr;
1558 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1559 if (!bstr.isEmpty())
1560 {
1561 if (details == VMINFO_MACHINEREADABLE)
1562 RTPrintf("USBRemoteManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1563 else
1564 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1565 }
1566 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1567 if (!bstr.isEmpty())
1568 {
1569 if (details == VMINFO_MACHINEREADABLE)
1570 RTPrintf("USBRemoteProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1571 else
1572 RTPrintf("Product: %lS\n", bstr.raw());
1573 }
1574 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1575 if (!bstr.isEmpty())
1576 {
1577 if (details == VMINFO_MACHINEREADABLE)
1578 RTPrintf("USBRemoteSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1579 else
1580 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1581 }
1582 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1583 if (!bstr.isEmpty())
1584 {
1585 if (details == VMINFO_MACHINEREADABLE)
1586 RTPrintf("USBRemoteAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1587 else
1588 RTPrintf("Address: %lS\n", bstr.raw());
1589 }
1590
1591 if (details != VMINFO_MACHINEREADABLE)
1592 RTPrintf("\n");
1593 }
1594 }
1595 }
1596
1597 /* scope */
1598 {
1599 if (details != VMINFO_MACHINEREADABLE)
1600 RTPrintf("Currently Attached USB Devices:\n\n");
1601
1602 SafeIfaceArray <IUSBDevice> coll;
1603 CHECK_ERROR_RET(console, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
1604
1605 if (coll.size() == 0)
1606 {
1607 if (details != VMINFO_MACHINEREADABLE)
1608 RTPrintf("<none>\n\n");
1609 }
1610 else
1611 {
1612 for (size_t index = 0; index < coll.size(); ++index)
1613 {
1614 ComPtr <IUSBDevice> dev = coll[index];
1615
1616 /* Query info. */
1617 Bstr id;
1618 CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), rc);
1619 USHORT usVendorId;
1620 CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), rc);
1621 USHORT usProductId;
1622 CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), rc);
1623 USHORT bcdRevision;
1624 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
1625
1626 if (details == VMINFO_MACHINEREADABLE)
1627 RTPrintf("USBAttachedUUID%zu=\"%S\"\n"
1628 "USBAttachedVendorId%zu=\"%#06x\"\n"
1629 "USBAttachedProductId%zu=\"%#06x\"\n"
1630 "USBAttachedRevision%zu=\"%#04x%02x\"\n",
1631 index + 1, Utf8Str(id).c_str(),
1632 index + 1, usVendorId,
1633 index + 1, usProductId,
1634 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1635 else
1636 RTPrintf("UUID: %S\n"
1637 "VendorId: %#06x (%04X)\n"
1638 "ProductId: %#06x (%04X)\n"
1639 "Revision: %u.%u (%02u%02u)\n",
1640 Utf8Str(id).c_str(),
1641 usVendorId, usVendorId, usProductId, usProductId,
1642 bcdRevision >> 8, bcdRevision & 0xff,
1643 bcdRevision >> 8, bcdRevision & 0xff);
1644
1645 /* optional stuff. */
1646 Bstr bstr;
1647 CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1648 if (!bstr.isEmpty())
1649 {
1650 if (details == VMINFO_MACHINEREADABLE)
1651 RTPrintf("USBAttachedManufacturer%zu=\"%lS\"\n", index + 1, bstr.raw());
1652 else
1653 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1654 }
1655 CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1656 if (!bstr.isEmpty())
1657 {
1658 if (details == VMINFO_MACHINEREADABLE)
1659 RTPrintf("USBAttachedProduct%zu=\"%lS\"\n", index + 1, bstr.raw());
1660 else
1661 RTPrintf("Product: %lS\n", bstr.raw());
1662 }
1663 CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1664 if (!bstr.isEmpty())
1665 {
1666 if (details == VMINFO_MACHINEREADABLE)
1667 RTPrintf("USBAttachedSerialNumber%zu=\"%lS\"\n", index + 1, bstr.raw());
1668 else
1669 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1670 }
1671 CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1672 if (!bstr.isEmpty())
1673 {
1674 if (details == VMINFO_MACHINEREADABLE)
1675 RTPrintf("USBAttachedAddress%zu=\"%lS\"\n", index + 1, bstr.raw());
1676 else
1677 RTPrintf("Address: %lS\n", bstr.raw());
1678 }
1679
1680 if (details != VMINFO_MACHINEREADABLE)
1681 RTPrintf("\n");
1682 }
1683 }
1684 }
1685 }
1686 } /* USB */
1687
1688 /*
1689 * Shared folders
1690 */
1691 if (details != VMINFO_MACHINEREADABLE)
1692 RTPrintf("Shared folders: ");
1693 uint32_t numSharedFolders = 0;
1694#if 0 // not yet implemented
1695 /* globally shared folders first */
1696 {
1697 SafeIfaceArray <ISharedFolder> sfColl;
1698 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
1699 for (size_t i = 0; i < sfColl.size(); ++i)
1700 {
1701 ComPtr<ISharedFolder> sf = sfColl[i];
1702 Bstr name, hostPath;
1703 sf->COMGETTER(Name)(name.asOutParam());
1704 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1705 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
1706 ++numSharedFolders;
1707 }
1708 }
1709#endif
1710 /* now VM mappings */
1711 {
1712 com::SafeIfaceArray <ISharedFolder> folders;
1713
1714 CHECK_ERROR_RET(machine, 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 BOOL writable;
1722 sf->COMGETTER(Name)(name.asOutParam());
1723 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1724 sf->COMGETTER(Writable)(&writable);
1725 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1726 RTPrintf("\n\n");
1727 if (details == VMINFO_MACHINEREADABLE)
1728 {
1729 RTPrintf("SharedFolderNameMachineMapping%zu=\"%lS\"\n", i + 1,
1730 name.raw());
1731 RTPrintf("SharedFolderPathMachineMapping%zu=\"%lS\"\n", i + 1,
1732 hostPath.raw());
1733 }
1734 else
1735 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
1736 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
1737 ++numSharedFolders;
1738 }
1739 }
1740 /* transient mappings */
1741 if (console)
1742 {
1743 com::SafeIfaceArray <ISharedFolder> folders;
1744
1745 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
1746
1747 for (size_t i = 0; i < folders.size(); ++i)
1748 {
1749 ComPtr <ISharedFolder> sf = folders[i];
1750
1751 Bstr name, hostPath;
1752 sf->COMGETTER(Name)(name.asOutParam());
1753 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1754 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1755 RTPrintf("\n\n");
1756 if (details == VMINFO_MACHINEREADABLE)
1757 {
1758 RTPrintf("SharedFolderNameTransientMapping%zu=\"%lS\"\n", i + 1,
1759 name.raw());
1760 RTPrintf("SharedFolderPathTransientMapping%zu=\"%lS\"\n", i + 1,
1761 hostPath.raw());
1762 }
1763 else
1764 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
1765 ++numSharedFolders;
1766 }
1767 }
1768 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
1769 RTPrintf("<none>\n");
1770 if (details != VMINFO_MACHINEREADABLE)
1771 RTPrintf("\n");
1772
1773 if (console)
1774 {
1775 /*
1776 * Live VRDP info.
1777 */
1778 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
1779 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
1780 BOOL Active;
1781 ULONG NumberOfClients;
1782 LONG64 BeginTime;
1783 LONG64 EndTime;
1784 LONG64 BytesSent;
1785 LONG64 BytesSentTotal;
1786 LONG64 BytesReceived;
1787 LONG64 BytesReceivedTotal;
1788 Bstr User;
1789 Bstr Domain;
1790 Bstr ClientName;
1791 Bstr ClientIP;
1792 ULONG ClientVersion;
1793 ULONG EncryptionStyle;
1794
1795 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Active)(&Active), rc);
1796 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(NumberOfClients)(&NumberOfClients), rc);
1797 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BeginTime)(&BeginTime), rc);
1798 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EndTime)(&EndTime), rc);
1799 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSent)(&BytesSent), rc);
1800 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
1801 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
1802 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
1803 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(User)(User.asOutParam()), rc);
1804 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
1805 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
1806 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
1807 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
1808 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
1809
1810 if (details == VMINFO_MACHINEREADABLE)
1811 RTPrintf("VRDPActiveConnection=\"%s\"\n", Active ? "on": "off");
1812 else
1813 RTPrintf("VRDP Connection: %s\n", Active? "active": "not active");
1814
1815 if (details == VMINFO_MACHINEREADABLE)
1816 RTPrintf("VRDPClients=%d\n", NumberOfClients);
1817 else
1818 RTPrintf("Clients so far: %d\n", NumberOfClients);
1819
1820 if (NumberOfClients > 0)
1821 {
1822 char timestr[128];
1823
1824 if (Active)
1825 {
1826 makeTimeStr(timestr, sizeof(timestr), BeginTime);
1827 if (details == VMINFO_MACHINEREADABLE)
1828 RTPrintf("VRDPStartTime=\"%s\"\n", timestr);
1829 else
1830 RTPrintf("Start time: %s\n", timestr);
1831 }
1832 else
1833 {
1834 makeTimeStr(timestr, sizeof(timestr), BeginTime);
1835 if (details == VMINFO_MACHINEREADABLE)
1836 RTPrintf("VRDPLastStartTime=\"%s\"\n", timestr);
1837 else
1838 RTPrintf("Last started: %s\n", timestr);
1839 makeTimeStr(timestr, sizeof(timestr), EndTime);
1840 if (details == VMINFO_MACHINEREADABLE)
1841 RTPrintf("VRDPLastEndTime=\"%s\"\n", timestr);
1842 else
1843 RTPrintf("Last ended: %s\n", timestr);
1844 }
1845
1846 int64_t ThroughputSend = 0;
1847 int64_t ThroughputReceive = 0;
1848 if (EndTime != BeginTime)
1849 {
1850 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
1851 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
1852 }
1853
1854 if (details == VMINFO_MACHINEREADABLE)
1855 {
1856 RTPrintf("VRDPBytesSent=%lld\n", BytesSent);
1857 RTPrintf("VRDPThroughputSend=%lld\n", ThroughputSend);
1858 RTPrintf("VRDPBytesSentTotal=%lld\n", BytesSentTotal);
1859
1860 RTPrintf("VRDPBytesReceived=%lld\n", BytesReceived);
1861 RTPrintf("VRDPThroughputReceive=%lld\n", ThroughputReceive);
1862 RTPrintf("VRDPBytesReceivedTotal=%lld\n", BytesReceivedTotal);
1863 }
1864 else
1865 {
1866 RTPrintf("Sent: %lld Bytes\n", BytesSent);
1867 RTPrintf("Average speed: %lld B/s\n", ThroughputSend);
1868 RTPrintf("Sent total: %lld Bytes\n", BytesSentTotal);
1869
1870 RTPrintf("Received: %lld Bytes\n", BytesReceived);
1871 RTPrintf("Speed: %lld B/s\n", ThroughputReceive);
1872 RTPrintf("Received total: %lld Bytes\n", BytesReceivedTotal);
1873 }
1874
1875 if (Active)
1876 {
1877 if (details == VMINFO_MACHINEREADABLE)
1878 {
1879 RTPrintf("VRDPUserName=\"%lS\"\n", User.raw());
1880 RTPrintf("VRDPDomain=\"%lS\"\n", Domain.raw());
1881 RTPrintf("VRDPClientName=\"%lS\"\n", ClientName.raw());
1882 RTPrintf("VRDPClientIP=\"%lS\"\n", ClientIP.raw());
1883 RTPrintf("VRDPClientVersion=%d\n", ClientVersion);
1884 RTPrintf("VRDPEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
1885 }
1886 else
1887 {
1888 RTPrintf("User name: %lS\n", User.raw());
1889 RTPrintf("Domain: %lS\n", Domain.raw());
1890 RTPrintf("Client name: %lS\n", ClientName.raw());
1891 RTPrintf("Client IP: %lS\n", ClientIP.raw());
1892 RTPrintf("Client version: %d\n", ClientVersion);
1893 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
1894 }
1895 }
1896 }
1897
1898 if (details != VMINFO_MACHINEREADABLE)
1899 RTPrintf("\n");
1900 }
1901
1902 if ( details == VMINFO_STANDARD
1903 || details == VMINFO_FULL
1904 || details == VMINFO_MACHINEREADABLE)
1905 {
1906 Bstr description;
1907 machine->COMGETTER(Description)(description.asOutParam());
1908 if (!description.isEmpty())
1909 {
1910 if (details == VMINFO_MACHINEREADABLE)
1911 RTPrintf("description=\"%lS\"\n", description.raw());
1912 else
1913 RTPrintf("Description:\n%lS\n", description.raw());
1914 }
1915 }
1916
1917
1918 if (details != VMINFO_MACHINEREADABLE)
1919 RTPrintf("Guest:\n\n");
1920
1921 if (console)
1922 {
1923 ComPtr<IGuest> guest;
1924 rc = console->COMGETTER(Guest)(guest.asOutParam());
1925 if (SUCCEEDED(rc))
1926 {
1927 Bstr guestString;
1928 rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam());
1929 if ( SUCCEEDED(rc)
1930 && !guestString.isEmpty())
1931 {
1932 if (details == VMINFO_MACHINEREADABLE)
1933 RTPrintf("GuestOSType=\"%lS\"\n", guestString.raw());
1934 else
1935 RTPrintf("OS type: %lS\n", guestString.raw());
1936 }
1937
1938 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
1939 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
1940 if (SUCCEEDED(rc))
1941 {
1942 if (details == VMINFO_MACHINEREADABLE)
1943 RTPrintf("GuestAdditionsRunLevel=%u\n", guestRunLevel);
1944 else
1945 RTPrintf("Additions run level: %u\n", guestRunLevel);
1946 }
1947
1948 if (details == VMINFO_FULL)
1949 {
1950 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
1951 if ( SUCCEEDED(rc)
1952 && !guestString.isEmpty())
1953 {
1954 if (details == VMINFO_MACHINEREADABLE)
1955 RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw());
1956 else
1957 RTPrintf("Additions version: %lS\n\n", guestString.raw());
1958 }
1959 }
1960 }
1961 }
1962
1963 ULONG guestVal;
1964 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
1965 if (SUCCEEDED(rc))
1966 {
1967 if (details == VMINFO_MACHINEREADABLE)
1968 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
1969 else
1970 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
1971 }
1972 if (details != VMINFO_MACHINEREADABLE)
1973 RTPrintf("\n");
1974
1975 /*
1976 * snapshots
1977 */
1978 ComPtr<ISnapshot> snapshot;
1979 rc = machine->GetSnapshot(Bstr().raw(), snapshot.asOutParam());
1980 if (SUCCEEDED(rc) && snapshot)
1981 {
1982 ComPtr<ISnapshot> currentSnapshot;
1983 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
1984 if (SUCCEEDED(rc))
1985 {
1986 if (details != VMINFO_MACHINEREADABLE)
1987 RTPrintf("Snapshots:\n\n");
1988 showSnapshots(snapshot, currentSnapshot, details);
1989 }
1990 }
1991
1992 if (details != VMINFO_MACHINEREADABLE)
1993 RTPrintf("\n");
1994 return S_OK;
1995}
1996
1997#if defined(_MSC_VER)
1998# pragma optimize("", on)
1999#endif
2000
2001static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2002{
2003 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2004 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2005 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2006 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2007 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2008};
2009
2010int handleShowVMInfo(HandlerArg *a)
2011{
2012 HRESULT rc;
2013 const char *VMNameOrUuid = NULL;
2014 bool fLog = false;
2015 uint32_t uLogIdx = 0;
2016 bool fDetails = false;
2017 bool fMachinereadable = false;
2018
2019 int c;
2020 RTGETOPTUNION ValueUnion;
2021 RTGETOPTSTATE GetState;
2022 // start at 0 because main() has hacked both the argc and argv given to us
2023 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2024 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2025 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2026 {
2027 switch (c)
2028 {
2029 case 'D': // --details
2030 fDetails = true;
2031 break;
2032
2033 case 'M': // --machinereadable
2034 fMachinereadable = true;
2035 break;
2036
2037 case 'l': // --log
2038 fLog = true;
2039 uLogIdx = ValueUnion.u32;
2040 break;
2041
2042 case VINF_GETOPT_NOT_OPTION:
2043 if (!VMNameOrUuid)
2044 VMNameOrUuid = ValueUnion.psz;
2045 else
2046 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2047 break;
2048
2049 default:
2050 if (c > 0)
2051 {
2052 if (RT_C_IS_PRINT(c))
2053 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option -%c", c);
2054 else
2055 return errorSyntax(USAGE_SHOWVMINFO, "Invalid option case %i", c);
2056 }
2057 else if (c == VERR_GETOPT_UNKNOWN_OPTION)
2058 return errorSyntax(USAGE_SHOWVMINFO, "unknown option: %s\n", ValueUnion.psz);
2059 else if (ValueUnion.pDef)
2060 return errorSyntax(USAGE_SHOWVMINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
2061 else
2062 return errorSyntax(USAGE_SHOWVMINFO, "error: %Rrs", c);
2063 }
2064 }
2065
2066 /* check for required options */
2067 if (!VMNameOrUuid)
2068 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2069
2070 /* try to find the given machine */
2071 ComPtr <IMachine> machine;
2072 Bstr uuid(VMNameOrUuid);
2073 if (!Guid(VMNameOrUuid).isEmpty())
2074 {
2075 CHECK_ERROR(a->virtualBox, GetMachine(uuid.raw(),
2076 machine.asOutParam()));
2077 }
2078 else
2079 {
2080 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2081 machine.asOutParam()));
2082 if (SUCCEEDED(rc))
2083 machine->COMGETTER(Id)(uuid.asOutParam());
2084 }
2085 if (FAILED(rc))
2086 return 1;
2087
2088 /* Printing the log is exclusive. */
2089 if (fLog && (fMachinereadable || fDetails))
2090 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2091
2092 if (fLog)
2093 {
2094 ULONG64 uOffset = 0;
2095 SafeArray<BYTE> aLogData;
2096 ULONG cbLogData;
2097 while (true)
2098 {
2099 /* Reset the array */
2100 aLogData.setNull();
2101 /* Fetch a chunk of the log file */
2102 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2103 ComSafeArrayAsOutParam(aLogData)));
2104 cbLogData = aLogData.size();
2105 if (cbLogData == 0)
2106 break;
2107 /* aLogData has a platform dependent line ending, standardize on
2108 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2109 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2110 ULONG cbLogDataPrint = cbLogData;
2111 for (BYTE *s = aLogData.raw(), *d = s;
2112 s - aLogData.raw() < (ssize_t)cbLogData;
2113 s++, d++)
2114 {
2115 if (*s == '\r')
2116 {
2117 /* skip over CR, adjust destination */
2118 d--;
2119 cbLogDataPrint--;
2120 }
2121 else if (s != d)
2122 *d = *s;
2123 }
2124 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2125 uOffset += cbLogData;
2126 }
2127 }
2128 else
2129 {
2130 /* 2nd option can be -details or -argdump */
2131 VMINFO_DETAILS details = VMINFO_NONE;
2132 if (fMachinereadable)
2133 details = VMINFO_MACHINEREADABLE;
2134 else if (fDetails)
2135 details = VMINFO_FULL;
2136 else
2137 details = VMINFO_STANDARD;
2138
2139 ComPtr<IConsole> console;
2140
2141 /* open an existing session for the VM */
2142 rc = machine->LockMachine(a->session, LockType_Shared);
2143 if (SUCCEEDED(rc))
2144 /* get the session machine */
2145 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2146 if (SUCCEEDED(rc))
2147 /* get the session console */
2148 rc = a->session->COMGETTER(Console)(console.asOutParam());
2149
2150 rc = showVMInfo(a->virtualBox, machine, details, console);
2151
2152 if (console)
2153 a->session->UnlockMachine();
2154 }
2155
2156 return SUCCEEDED(rc) ? 0 : 1;
2157}
2158
2159#endif /* !VBOX_ONLY_DOCS */
2160/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette