VirtualBox

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

Last change on this file since 33595 was 33386, checked in by vboxsync, 14 years ago

VRDE: API changes for the VRDP server separation.

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