VirtualBox

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

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

Main: fix snapshot folder and log folder regression (since 4.0 directory changes)

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