VirtualBox

Changeset 14555 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Nov 25, 2008 9:08:06 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
39847
Message:

VBoxManage: started splitting it up.

Location:
trunk/src/VBox/Frontends/VBoxManage
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk

    r13855 r14555  
    4343 VBoxManage_SOURCES = \
    4444        VBoxManage.cpp \
     45        VBoxManageInfo.cpp \
    4546        VBoxInternalManage.cpp \
    4647        $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r14371 r14555  
    765765}
    766766
    767 static void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const Bstr &prefix = "", int level = 0)
    768 {
    769     /* start with the root */
    770     Bstr name;
    771     Guid uuid;
    772     rootSnapshot->COMGETTER(Name)(name.asOutParam());
    773     rootSnapshot->COMGETTER(Id)(uuid.asOutParam());
    774     if (details == VMINFO_MACHINEREADABLE)
    775     {
    776         /* print with hierarchical numbering */
    777         RTPrintf("SnapshotName%lS=\"%lS\"\n", prefix.raw(), name.raw());
    778         RTPrintf("SnapshotUUID%lS=\"%s\"\n", prefix.raw(), uuid.toString().raw());
    779     }
    780     else
    781     {
    782         /* print with indentation */
    783         RTPrintf("   %lSName: %lS (UUID: %s)\n", prefix.raw(), name.raw(), uuid.toString().raw());
    784     }
    785 
    786     /* get the children */
    787     ComPtr<ISnapshotCollection> coll;
    788     rootSnapshot->COMGETTER(Children)(coll.asOutParam());
    789     if (coll)
    790     {
    791         ComPtr<ISnapshotEnumerator> enumerator;
    792         coll->Enumerate(enumerator.asOutParam());
    793         ULONG index = 0;
    794         BOOL hasMore = FALSE;
    795         while (enumerator->HasMore(&hasMore), hasMore)
    796         {
    797             ComPtr<ISnapshot> snapshot;
    798             enumerator->GetNext(snapshot.asOutParam());
    799             if (snapshot)
    800             {
    801                 Bstr newPrefix;
    802                 if (details == VMINFO_MACHINEREADABLE)
    803                     newPrefix = Utf8StrFmt("%lS-%d", prefix.raw(), index + 1);
    804                 else
    805                     newPrefix = Utf8StrFmt("%lS   ", prefix.raw());
    806                 /* recursive call */
    807                 showSnapshots(snapshot, details, newPrefix, level + 1);
    808             }
    809             index++;
    810         }
    811     }
    812 }
    813 
    814 static void makeTimeStr (char *s, int cb, int64_t millies)
    815 {
    816     RTTIME t;
    817     RTTIMESPEC ts;
    818 
    819     RTTimeSpecSetMilli(&ts, millies);
    820 
    821     RTTimeExplode (&t, &ts);
    822 
    823     RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
    824                         t.i32Year, t.u8Month, t.u8MonthDay,
    825                         t.u8Hour, t.u8Minute, t.u8Second);
    826 }
    827 
    828 static HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
    829                            ComPtr <IConsole> console = ComPtr <IConsole> (),
    830                            VMINFO_DETAILS details = VMINFO_NONE)
    831 {
    832     HRESULT rc;
    833 
    834     /*
    835      * The rules for output in -argdump format:
    836      * 1) the key part (the [0-9a-zA-Z_]+ string before the '=' delimiter)
    837      *    is all lowercase for "VBoxManage modifyvm" parameters. Any
    838      *    other values printed are in CamelCase.
    839      * 2) strings (anything non-decimal) are printed surrounded by
    840      *    double quotes '"'. If the strings themselves contain double
    841      *    quotes, these characters are escaped by '\'. Any '\' character
    842      *    in the original string is also escaped by '\'.
    843      * 3) numbers (containing just [0-9\-]) are written out unchanged.
    844      */
    845 
    846     /** @todo the quoting is not yet implemented! */
    847 
    848     BOOL accessible = FALSE;
    849     CHECK_ERROR (machine, COMGETTER(Accessible) (&accessible));
    850     CheckComRCReturnRC (rc);
    851 
    852     if (!accessible)
    853     {
    854         if (details == VMINFO_MACHINEREADABLE)
    855             RTPrintf("name=\"<inaccessible>\"\n");
    856         else
    857             RTPrintf ("Name:            <inaccessible!>\n");
    858         Guid uuid;
    859         rc = machine->COMGETTER(Id) (uuid.asOutParam());
    860         if (details == VMINFO_MACHINEREADABLE)
    861             RTPrintf ("UUID=\"%s\"\n", uuid.toString().raw());
    862         else
    863             RTPrintf ("UUID:            %s\n", uuid.toString().raw());
    864         if (details != VMINFO_MACHINEREADABLE)
    865         {
    866             Bstr settingsFilePath;
    867             rc = machine->COMGETTER(SettingsFilePath) (settingsFilePath.asOutParam());
    868             RTPrintf ("Config file:     %lS\n", settingsFilePath.raw());
    869             ComPtr<IVirtualBoxErrorInfo> accessError;
    870             rc = machine->COMGETTER(AccessError) (accessError.asOutParam());
    871             RTPrintf ("Access error details:\n");
    872             ErrorInfo ei (accessError);
    873             PRINT_ERROR_INFO (ei);
    874             RTPrintf ("\n");
    875         }
    876         return S_OK;
    877     }
    878 
    879     Bstr machineName;
    880     rc = machine->COMGETTER(Name)(machineName.asOutParam());
    881     if (details == VMINFO_MACHINEREADABLE)
    882         RTPrintf("name=\"%lS\"\n", machineName.raw());
    883     else
    884         RTPrintf("Name:            %lS\n", machineName.raw());
    885 
    886     Bstr osTypeId;
    887     rc = machine->COMGETTER(OSTypeId)(osTypeId.asOutParam());
    888     ComPtr<IGuestOSType> osType;
    889     rc = virtualBox->GetGuestOSType (osTypeId, osType.asOutParam());
    890     Bstr osName;
    891     rc = osType->COMGETTER(Description)(osName.asOutParam());
    892     if (details == VMINFO_MACHINEREADABLE)
    893         RTPrintf("ostype=\"%lS\"\n", osTypeId.raw());
    894     else
    895         RTPrintf("Guest OS:        %lS\n", osName.raw());
    896 
    897     Guid uuid;
    898     rc = machine->COMGETTER(Id)(uuid.asOutParam());
    899     if (details == VMINFO_MACHINEREADABLE)
    900         RTPrintf("UUID=\"%s\"\n", uuid.toString().raw());
    901     else
    902         RTPrintf("UUID:            %s\n", uuid.toString().raw());
    903 
    904     Bstr settingsFilePath;
    905     rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
    906     if (details == VMINFO_MACHINEREADABLE)
    907         RTPrintf("CfgFile=\"%lS\"\n", settingsFilePath.raw());
    908     else
    909         RTPrintf("Config file:     %lS\n", settingsFilePath.raw());
    910 
    911     ULONG memorySize;
    912     rc = machine->COMGETTER(MemorySize)(&memorySize);
    913     if (details == VMINFO_MACHINEREADABLE)
    914         RTPrintf("memory=%u\n", memorySize);
    915     else
    916         RTPrintf("Memory size:     %uMB\n", memorySize);
    917 
    918     ULONG vramSize;
    919     rc = machine->COMGETTER(VRAMSize)(&vramSize);
    920     if (details == VMINFO_MACHINEREADABLE)
    921         RTPrintf("vram=%u\n", vramSize);
    922     else
    923         RTPrintf("VRAM size:       %uMB\n", vramSize);
    924 
    925     ComPtr <IBIOSSettings> biosSettings;
    926     machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
    927 
    928     BIOSBootMenuMode_T bootMenuMode;
    929     biosSettings->COMGETTER(BootMenuMode)(&bootMenuMode);
    930     const char *pszBootMenu = NULL;
    931     switch (bootMenuMode)
    932     {
    933         case BIOSBootMenuMode_Disabled:
    934             pszBootMenu = "disabled";
    935             break;
    936         case BIOSBootMenuMode_MenuOnly:
    937             if (details == VMINFO_MACHINEREADABLE)
    938                 pszBootMenu = "menuonly";
    939             else
    940                 pszBootMenu = "menu only";
    941             break;
    942         default:
    943             if (details == VMINFO_MACHINEREADABLE)
    944                 pszBootMenu = "messageandmenu";
    945             else
    946                 pszBootMenu = "message and menu";
    947     }
    948     if (details == VMINFO_MACHINEREADABLE)
    949         RTPrintf("bootmenu=\"%s\"\n", pszBootMenu);
    950     else
    951         RTPrintf("Boot menu mode:  %s\n", pszBootMenu);
    952 
    953     BOOL acpiEnabled;
    954     biosSettings->COMGETTER(ACPIEnabled)(&acpiEnabled);
    955     if (details == VMINFO_MACHINEREADABLE)
    956         RTPrintf("acpi=\"%s\"\n", acpiEnabled ? "on" : "off");
    957     else
    958         RTPrintf("ACPI:            %s\n", acpiEnabled ? "on" : "off");
    959 
    960     BOOL ioapicEnabled;
    961     biosSettings->COMGETTER(IOAPICEnabled)(&ioapicEnabled);
    962     if (details == VMINFO_MACHINEREADABLE)
    963         RTPrintf("ioapic=\"%s\"\n", ioapicEnabled ? "on" : "off");
    964     else
    965         RTPrintf("IOAPIC:          %s\n", ioapicEnabled ? "on" : "off");
    966 
    967     BOOL PAEEnabled;
    968     machine->COMGETTER(PAEEnabled)(&PAEEnabled);
    969     if (details == VMINFO_MACHINEREADABLE)
    970         RTPrintf("pae=\"%s\"\n", PAEEnabled ? "on" : "off");
    971     else
    972         RTPrintf("PAE:             %s\n", PAEEnabled ? "on" : "off");
    973 
    974     LONG64 timeOffset;
    975     biosSettings->COMGETTER(TimeOffset)(&timeOffset);
    976     if (details == VMINFO_MACHINEREADABLE)
    977         RTPrintf("biossystemtimeoffset=%lld\n", timeOffset);
    978     else
    979         RTPrintf("Time offset:     %lld ms\n", timeOffset);
    980 
    981     TSBool_T hwVirtExEnabled;
    982     machine->COMGETTER(HWVirtExEnabled)(&hwVirtExEnabled);
    983     if (hwVirtExEnabled == TSBool_Default)
    984     {
    985         BOOL fHWVirtExEnabled;
    986         ComPtr<ISystemProperties> systemProperties;
    987         virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
    988         systemProperties->COMGETTER(HWVirtExEnabled)(&fHWVirtExEnabled);
    989         if (details == VMINFO_MACHINEREADABLE)
    990             RTPrintf("hwvirtex=\"default\"\n");
    991         else
    992             RTPrintf("Hardw. virt.ext: Default (%s)\n", fHWVirtExEnabled ? "on" : "off");
    993     }
    994     else
    995     {
    996         if (details == VMINFO_MACHINEREADABLE)
    997             RTPrintf("hwvirtex=\"%s\"\n", hwVirtExEnabled == TSBool_True ? "on" : "off");
    998         else
    999             RTPrintf("Hardw. virt.ext: %s\n", hwVirtExEnabled == TSBool_True ? "on" : "off");
    1000     }
    1001     BOOL HWVirtExNestedPagingEnabled;
    1002     machine->COMGETTER(HWVirtExNestedPagingEnabled)(&HWVirtExNestedPagingEnabled);
    1003     if (details == VMINFO_MACHINEREADABLE)
    1004         RTPrintf("nestedpaging=\"%s\"\n", HWVirtExNestedPagingEnabled ? "on" : "off");
    1005     else
    1006         RTPrintf("Nested Paging:   %s\n", HWVirtExNestedPagingEnabled ? "on" : "off");
    1007 
    1008     BOOL HWVirtExVPIDEnabled;
    1009     machine->COMGETTER(HWVirtExVPIDEnabled)(&HWVirtExVPIDEnabled);
    1010     if (details == VMINFO_MACHINEREADABLE)
    1011         RTPrintf("vtxvpid=\"%s\"\n", HWVirtExVPIDEnabled ? "on" : "off");
    1012     else
    1013         RTPrintf("VT-x VPID:       %s\n", HWVirtExVPIDEnabled ? "on" : "off");
    1014 
    1015     MachineState_T machineState;
    1016     const char *pszState = NULL;
    1017     rc = machine->COMGETTER(State)(&machineState);
    1018     switch (machineState)
    1019     {
    1020         case MachineState_PoweredOff:
    1021             if (details == VMINFO_MACHINEREADABLE)
    1022                 pszState = "poweroff";
    1023             else
    1024                 pszState = "powered off";
    1025             break;
    1026         case MachineState_Saved:
    1027             pszState = "saved";
    1028             break;
    1029         case MachineState_Aborted:
    1030             pszState = "aborted";
    1031             break;
    1032         case MachineState_Running:
    1033             pszState = "running";
    1034             break;
    1035         case MachineState_Paused:
    1036             pszState = "paused";
    1037             break;
    1038         case MachineState_Starting:
    1039             pszState = "starting";
    1040             break;
    1041         case MachineState_Stopping:
    1042             pszState = "stopping";
    1043             break;
    1044         case MachineState_Saving:
    1045             pszState = "saving";
    1046             break;
    1047         case MachineState_Restoring:
    1048             pszState = "restoring";
    1049             break;
    1050         default:
    1051             pszState = "unknown";
    1052             break;
    1053     }
    1054     LONG64 stateSince;
    1055     machine->COMGETTER(LastStateChange)(&stateSince);
    1056     RTTIMESPEC timeSpec;
    1057     RTTimeSpecSetMilli(&timeSpec, stateSince);
    1058     char pszTime[30] = {0};
    1059     RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
    1060     if (details == VMINFO_MACHINEREADABLE)
    1061     {
    1062         RTPrintf("VMState=\"%s\"\n", pszState);
    1063         RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
    1064     }
    1065     else
    1066         RTPrintf("State:           %s (since %s)\n", pszState, pszTime);
    1067 
    1068     ULONG numMonitors;
    1069     machine->COMGETTER(MonitorCount)(&numMonitors);
    1070     if (details == VMINFO_MACHINEREADABLE)
    1071         RTPrintf("monitorcount=%d\n", numMonitors);
    1072     else
    1073         RTPrintf("Monitor count:   %d\n", numMonitors);
    1074 
    1075     BOOL accelerate3d;
    1076     machine->COMGETTER(Accelerate3DEnabled)(&accelerate3d);
    1077     if (details == VMINFO_MACHINEREADABLE)
    1078         RTPrintf("accelerate3d=\"%s\"\n", accelerate3d ? "on" : "off");
    1079     else
    1080         RTPrintf("3D Acceleration:       %s\n", accelerate3d ? "on" : "off");
    1081 
    1082     ComPtr<IFloppyDrive> floppyDrive;
    1083     rc = machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
    1084     if (SUCCEEDED(rc) && floppyDrive)
    1085     {
    1086         BOOL fFloppyEnabled;
    1087         floppyDrive->COMGETTER(Enabled)(&fFloppyEnabled);
    1088         Utf8Str pszFloppy = "invalid";
    1089         if (fFloppyEnabled)
    1090         {
    1091             DriveState_T floppyState;
    1092             floppyDrive->COMGETTER(State)(&floppyState);
    1093             switch (floppyState)
    1094             {
    1095                 case DriveState_ImageMounted:
    1096                 {
    1097                     ComPtr<IFloppyImage2> floppyImage;
    1098                     rc = floppyDrive->GetImage(floppyImage.asOutParam());
    1099                     if (SUCCEEDED(rc) && floppyImage)
    1100                     {
    1101                         Bstr imagePath;
    1102                         floppyImage->COMGETTER(Location)(imagePath.asOutParam());
    1103                         Guid imageGuid;
    1104                         floppyImage->COMGETTER(Id)(imageGuid.asOutParam());
    1105                         if (details == VMINFO_MACHINEREADABLE)
    1106                         {
    1107                             RTPrintf("FloppyImageUUID=\"%s\"\n", imageGuid.toString().raw());
    1108                             pszFloppy = Utf8StrFmt("%lS", imagePath.raw());
    1109                         }
    1110                         else
    1111                             pszFloppy = Utf8StrFmt("%lS (UUID: %s)", imagePath.raw(), imageGuid.toString().raw());
    1112                     }
    1113                     break;
    1114                 }
    1115 
    1116                 case DriveState_HostDriveCaptured:
    1117                 {
    1118                     ComPtr<IHostFloppyDrive> hostFloppyDrive;
    1119                     rc = floppyDrive->GetHostDrive(hostFloppyDrive.asOutParam());
    1120                     if (SUCCEEDED(rc) && floppyDrive)
    1121                     {
    1122                         Bstr driveName;
    1123                         hostFloppyDrive->COMGETTER(Name)(driveName.asOutParam());
    1124                         if (details == VMINFO_MACHINEREADABLE)
    1125                             pszFloppy = Utf8StrFmt("host:%lS", driveName.raw());
    1126                         else
    1127                             pszFloppy = Utf8StrFmt("Host drive %lS", driveName.raw());
    1128                     }
    1129                     break;
    1130                 }
    1131 
    1132                 case DriveState_NotMounted:
    1133                 {
    1134                     pszFloppy = "empty";
    1135                     break;
    1136                 }
    1137             }
    1138         }
    1139         else
    1140         {
    1141             pszFloppy = "disabled";
    1142         }
    1143         if (details == VMINFO_MACHINEREADABLE)
    1144             RTPrintf("floppy=\"%s\"\n", pszFloppy.raw());
    1145         else
    1146             RTPrintf("Floppy:          %s\n", pszFloppy.raw());
    1147     }
    1148 
    1149     /*
    1150      * SATA.
    1151      *
    1152      * Contributed by: James Lucas
    1153      */
    1154 #ifdef VBOX_WITH_AHCI
    1155     ComPtr<ISATAController> SATACtl;
    1156     BOOL fSataEnabled;
    1157     rc = machine->COMGETTER(SATAController)(SATACtl.asOutParam());
    1158     if (SUCCEEDED(rc))
    1159     {
    1160         rc = SATACtl->COMGETTER(Enabled)(&fSataEnabled);
    1161         if (FAILED(rc))
    1162             fSataEnabled = false;
    1163         if (details == VMINFO_MACHINEREADABLE)
    1164             RTPrintf("sata=\"%s\"\n", fSataEnabled ? "on" : "off");
    1165         else
    1166             RTPrintf("SATA:            %s\n", fSataEnabled ? "enabled" : "disabled");
    1167     }
    1168 
    1169     /*
    1170      * SATA Hard disks
    1171      */
    1172     if (fSataEnabled)
    1173     {
    1174         ComPtr<IHardDisk2> hardDisk;
    1175         Bstr  filePath;
    1176         ULONG cSataPorts;
    1177 
    1178         SATACtl->COMGETTER(PortCount)(&cSataPorts);
    1179         for (ULONG i = 0; i < cSataPorts; ++ i)
    1180         {
    1181             rc = machine->GetHardDisk2(StorageBus_SATA, i, 0, hardDisk.asOutParam());
    1182             if (SUCCEEDED(rc) && hardDisk)
    1183             {
    1184                 hardDisk->COMGETTER(Location)(filePath.asOutParam());
    1185                 hardDisk->COMGETTER(Id)(uuid.asOutParam());
    1186                 if (details == VMINFO_MACHINEREADABLE)
    1187                 {
    1188                     RTPrintf("sata%d=\"%lS\"\n", i, filePath.raw());
    1189                     RTPrintf("sata%dImageUUID=\"%s\"\n", i, uuid.toString().raw());
    1190                 }
    1191                 else
    1192                     RTPrintf("SATA %d:          %lS (UUID: %s)\n", i, filePath.raw(), uuid.toString().raw());
    1193             }
    1194             else
    1195             {
    1196                 if (details == VMINFO_MACHINEREADABLE)
    1197                     RTPrintf("sata%d=\"none\"\n",i);
    1198             }
    1199         }
    1200     }
    1201 #endif
    1202 
    1203     /*
    1204      * IDE Hard disks
    1205      */
    1206     IDEControllerType_T ideController;
    1207     const char *pszIdeController = NULL;
    1208     biosSettings->COMGETTER(IDEControllerType)(&ideController);
    1209     switch (ideController)
    1210     {
    1211         case IDEControllerType_PIIX3:
    1212             pszIdeController = "PIIX3";
    1213             break;
    1214         case IDEControllerType_PIIX4:
    1215             pszIdeController = "PIIX4";
    1216             break;
    1217         default:
    1218             pszIdeController = "unknown";
    1219     }
    1220     if (details == VMINFO_MACHINEREADABLE)
    1221         RTPrintf("idecontroller=\"%s\"\n", pszIdeController);
    1222     else
    1223         RTPrintf("IDE Controller:  %s\n", pszIdeController);
    1224 
    1225     ComPtr<IHardDisk2> hardDisk;
    1226     Bstr filePath;
    1227     rc = machine->GetHardDisk2(StorageBus_IDE, 0, 0, hardDisk.asOutParam());
    1228     if (SUCCEEDED(rc) && hardDisk)
    1229     {
    1230         hardDisk->COMGETTER(Location)(filePath.asOutParam());
    1231         hardDisk->COMGETTER(Id)(uuid.asOutParam());
    1232         if (details == VMINFO_MACHINEREADABLE)
    1233         {
    1234             RTPrintf("hda=\"%lS\"\n", filePath.raw());
    1235             RTPrintf("HdaImageUUID=\"%s\"\n", uuid.toString().raw());
    1236         }
    1237         else
    1238             RTPrintf("Primary master:  %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
    1239     }
    1240     else
    1241     {
    1242         if (details == VMINFO_MACHINEREADABLE)
    1243             RTPrintf("hda=\"none\"\n");
    1244     }
    1245     rc = machine->GetHardDisk2(StorageBus_IDE, 0, 1, hardDisk.asOutParam());
    1246     if (SUCCEEDED(rc) && hardDisk)
    1247     {
    1248         hardDisk->COMGETTER(Location)(filePath.asOutParam());
    1249         hardDisk->COMGETTER(Id)(uuid.asOutParam());
    1250         if (details == VMINFO_MACHINEREADABLE)
    1251         {
    1252             RTPrintf("hdb=\"%lS\"\n", filePath.raw());
    1253             RTPrintf("HdbImageUUID=\"%s\"\n", uuid.toString().raw());
    1254         }
    1255         else
    1256             RTPrintf("Primary slave:   %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
    1257     }
    1258     else
    1259     {
    1260         if (details == VMINFO_MACHINEREADABLE)
    1261             RTPrintf("hdb=\"none\"\n");
    1262     }
    1263     rc = machine->GetHardDisk2(StorageBus_IDE, 1, 1, hardDisk.asOutParam());
    1264     if (SUCCEEDED(rc) && hardDisk)
    1265     {
    1266         hardDisk->COMGETTER(Location)(filePath.asOutParam());
    1267         hardDisk->COMGETTER(Id)(uuid.asOutParam());
    1268         if (details == VMINFO_MACHINEREADABLE)
    1269         {
    1270             RTPrintf("hdd=\"%lS\"\n", filePath.raw());
    1271             RTPrintf("HddImageUUID=\"%s\"\n", uuid.toString().raw());
    1272         }
    1273         else
    1274             RTPrintf("Secondary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
    1275     }
    1276     else
    1277     {
    1278         if (details == VMINFO_MACHINEREADABLE)
    1279             RTPrintf("hdd=\"none\"\n");
    1280     }
    1281     ComPtr<IDVDDrive> dvdDrive;
    1282     rc = machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
    1283     if (SUCCEEDED(rc) && dvdDrive)
    1284     {
    1285         ComPtr<IDVDImage2> dvdImage;
    1286         rc = dvdDrive->GetImage(dvdImage.asOutParam());
    1287         if (SUCCEEDED(rc) && dvdImage)
    1288         {
    1289             rc = dvdImage->COMGETTER(Location)(filePath.asOutParam());
    1290             if (SUCCEEDED(rc) && filePath)
    1291             {
    1292                 rc = dvdImage->COMGETTER(Id)(uuid.asOutParam());
    1293                 if (details == VMINFO_MACHINEREADABLE)
    1294                 {
    1295                     RTPrintf("dvd=\"%lS\"\n", filePath.raw());
    1296                     RTPrintf("DvdImageUUID=\"%s\"\n", uuid.toString().raw());
    1297                 }
    1298                 else
    1299                     RTPrintf("DVD:             %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
    1300             }
    1301         }
    1302         else
    1303         {
    1304             ComPtr<IHostDVDDrive> hostDVDDrive;
    1305             rc = dvdDrive->GetHostDrive(hostDVDDrive.asOutParam());
    1306             if (SUCCEEDED(rc) && hostDVDDrive)
    1307             {
    1308                 Bstr name;
    1309                 hostDVDDrive->COMGETTER(Name)(name.asOutParam());
    1310                 if (details == VMINFO_MACHINEREADABLE)
    1311                     RTPrintf("dvd=\"host:%lS\"\n", name.raw());
    1312                 else
    1313                     RTPrintf("DVD:             Host drive %lS", name.raw());
    1314             }
    1315             else
    1316             {
    1317                 if (details == VMINFO_MACHINEREADABLE)
    1318                     RTPrintf("dvd=\"none\"\n");
    1319                 else
    1320                     RTPrintf("DVD:             empty");
    1321             }
    1322             BOOL fPassthrough;
    1323             dvdDrive->COMGETTER(Passthrough)(&fPassthrough);
    1324             if (details == VMINFO_MACHINEREADABLE)
    1325             {
    1326                 RTPrintf("dvdpassthrough=\"%s\"\n", fPassthrough ? "on" : "off");
    1327             }
    1328             else
    1329             {
    1330                 if (fPassthrough)
    1331                     RTPrintf(" (passthrough enabled)");
    1332                 RTPrintf("\n");
    1333             }
    1334         }
    1335     }
    1336 
    1337     /* get the maximum amount of NICS */
    1338     ComPtr<ISystemProperties> sysProps;
    1339     virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
    1340     ULONG maxNICs = 0;
    1341     sysProps->COMGETTER(NetworkAdapterCount)(&maxNICs);
    1342     for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
    1343     {
    1344         ComPtr<INetworkAdapter> nic;
    1345         rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
    1346         if (SUCCEEDED(rc) && nic)
    1347         {
    1348             BOOL fEnabled;
    1349             nic->COMGETTER(Enabled)(&fEnabled);
    1350             if (!fEnabled)
    1351             {
    1352                 if (details == VMINFO_MACHINEREADABLE)
    1353                     RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
    1354                 else
    1355                     RTPrintf("NIC %d:           disabled\n", currentNIC + 1);
    1356             }
    1357             else
    1358             {
    1359                 Bstr strMACAddress;
    1360                 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
    1361                 Utf8Str strAttachment;
    1362                 NetworkAttachmentType_T attachment;
    1363                 nic->COMGETTER(AttachmentType)(&attachment);
    1364                 switch (attachment)
    1365                 {
    1366                     case NetworkAttachmentType_Null:
    1367                         if (details == VMINFO_MACHINEREADABLE)
    1368                             strAttachment = "null";
    1369                         else
    1370                             strAttachment = "none";
    1371                         break;
    1372                     case NetworkAttachmentType_NAT:
    1373                     {
    1374                         Bstr strNetwork;
    1375                         nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
    1376                         if (details == VMINFO_MACHINEREADABLE)
    1377                         {
    1378                             RTPrintf("natnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
    1379                             strAttachment = "nat";
    1380                         }
    1381                         else if (!strNetwork.isEmpty())
    1382                             strAttachment = Utf8StrFmt("NAT (%lS)", strNetwork.raw());
    1383                         else
    1384                             strAttachment = "NAT";
    1385                         break;
    1386                     }
    1387                     case NetworkAttachmentType_HostInterface:
    1388                     {
    1389                         Bstr strHostIfDev;
    1390                         nic->COMGETTER(HostInterface)(strHostIfDev.asOutParam());
    1391                         if (details == VMINFO_MACHINEREADABLE)
    1392                         {
    1393                             RTPrintf("hostifdev%d=\"%lS\"\n", currentNIC + 1, strHostIfDev.raw());
    1394                             strAttachment = "hostif";
    1395                         }
    1396                         else
    1397                             strAttachment = Utf8StrFmt("Host Interface '%lS'", strHostIfDev.raw());
    1398                         break;
    1399                     }
    1400                     case NetworkAttachmentType_Internal:
    1401                     {
    1402                         Bstr strNetwork;
    1403                         nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
    1404                         if (details == VMINFO_MACHINEREADABLE)
    1405                         {
    1406                             RTPrintf("intnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
    1407                             strAttachment = "intnet";
    1408                         }
    1409                         else
    1410                             strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).raw());
    1411                         break;
    1412                     }
    1413                     default:
    1414                         strAttachment = "unknown";
    1415                         break;
    1416                 }
    1417 
    1418                 /* cable connected */
    1419                 BOOL fConnected;
    1420                 nic->COMGETTER(CableConnected)(&fConnected);
    1421 
    1422                 /* trace stuff */
    1423                 BOOL fTraceEnabled;
    1424                 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
    1425                 Bstr traceFile;
    1426                 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
    1427 
    1428                 /* NIC type */
    1429                 Utf8Str strNICType;
    1430                 NetworkAdapterType_T NICType;
    1431                 nic->COMGETTER(AdapterType)(&NICType);
    1432                 switch (NICType) {
    1433                 case NetworkAdapterType_Am79C970A:
    1434                     strNICType = "Am79C970A";
    1435                     break;
    1436                 case NetworkAdapterType_Am79C973:
    1437                     strNICType = "Am79C973";
    1438                     break;
    1439 #ifdef VBOX_WITH_E1000
    1440                 case NetworkAdapterType_I82540EM:
    1441                     strNICType = "82540EM";
    1442                     break;
    1443                 case NetworkAdapterType_I82543GC:
    1444                     strNICType = "82543GC";
    1445                     break;
    1446 #endif
    1447                 default:
    1448                     strNICType = "unknown";
    1449                     break;
    1450                 }
    1451 
    1452                 /* reported line speed */
    1453                 ULONG ulLineSpeed;
    1454                 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
    1455 
    1456                 if (details == VMINFO_MACHINEREADABLE)
    1457                 {
    1458                     RTPrintf("macaddress%d=\"%lS\"\n", currentNIC + 1, strMACAddress.raw());
    1459                     RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
    1460                     RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.raw());
    1461                 }
    1462                 else
    1463                     RTPrintf("NIC %d:           MAC: %lS, Attachment: %s, Cable connected: %s, Trace: %s (file: %lS), Type: %s, Reported speed: %d Mbps\n",
    1464                              currentNIC + 1, strMACAddress.raw(), strAttachment.raw(),
    1465                              fConnected ? "on" : "off",
    1466                              fTraceEnabled ? "on" : "off",
    1467                              traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
    1468                              strNICType.raw(),
    1469                              ulLineSpeed / 1000);
    1470             }
    1471         }
    1472     }
    1473 
    1474     /* get the maximum amount of UARTs */
    1475     ULONG maxUARTs = 0;
    1476     sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
    1477     for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
    1478     {
    1479         ComPtr<ISerialPort> uart;
    1480         rc = machine->GetSerialPort(currentUART, uart.asOutParam());
    1481         if (SUCCEEDED(rc) && uart)
    1482         {
    1483             BOOL fEnabled;
    1484             uart->COMGETTER(Enabled)(&fEnabled);
    1485             if (!fEnabled)
    1486             {
    1487                 if (details == VMINFO_MACHINEREADABLE)
    1488                     RTPrintf("uart%d=\"off\"\n", currentUART + 1);
    1489                 else
    1490                     RTPrintf("UART %d:          disabled\n", currentUART + 1);
    1491             }
    1492             else
    1493             {
    1494                 ULONG ulIRQ, ulIOBase;
    1495                 PortMode_T HostMode;
    1496                 Bstr path;
    1497                 BOOL fServer;
    1498                 uart->COMGETTER(IRQ)(&ulIRQ);
    1499                 uart->COMGETTER(IOBase)(&ulIOBase);
    1500                 uart->COMGETTER(Path)(path.asOutParam());
    1501                 uart->COMGETTER(Server)(&fServer);
    1502                 uart->COMGETTER(HostMode)(&HostMode);
    1503 
    1504                 if (details == VMINFO_MACHINEREADABLE)
    1505                     RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
    1506                              ulIOBase, ulIRQ);
    1507                 else
    1508                     RTPrintf("UART %d:          I/O base: 0x%04x, IRQ: %d",
    1509                              currentUART + 1, ulIOBase, ulIRQ);
    1510                 switch (HostMode)
    1511                 {
    1512                     default:
    1513                     case PortMode_Disconnected:
    1514                         if (details == VMINFO_MACHINEREADABLE)
    1515                             RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
    1516                         else
    1517                             RTPrintf(", disconnected\n");
    1518                         break;
    1519                     case PortMode_HostPipe:
    1520                         if (details == VMINFO_MACHINEREADABLE)
    1521                             RTPrintf("uartmode%d=\"%s,%lS\"\n", currentUART + 1,
    1522                                      fServer ? "server" : "client", path.raw());
    1523                         else
    1524                             RTPrintf(", attached to pipe (%s) '%lS'\n",
    1525                                      fServer ? "server" : "client", path.raw());
    1526                         break;
    1527                     case PortMode_HostDevice:
    1528                         if (details == VMINFO_MACHINEREADABLE)
    1529                             RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
    1530                                      path.raw());
    1531                         else
    1532                             RTPrintf(", attached to device '%lS'\n", path.raw());
    1533                         break;
    1534                 }
    1535             }
    1536         }
    1537     }
    1538 
    1539     ComPtr<IAudioAdapter> AudioAdapter;
    1540     rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
    1541     if (SUCCEEDED(rc))
    1542     {
    1543         const char *pszDrv  = "Unknown";
    1544         const char *pszCtrl = "Unknown";
    1545         BOOL fEnabled;
    1546         rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
    1547         if (SUCCEEDED(rc) && fEnabled)
    1548         {
    1549             AudioDriverType_T enmDrvType;
    1550             rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
    1551             switch (enmDrvType)
    1552             {
    1553                 case AudioDriverType_Null:
    1554                     if (details == VMINFO_MACHINEREADABLE)
    1555                         pszDrv = "null";
    1556                     else
    1557                         pszDrv = "Null";
    1558                     break;
    1559                 case AudioDriverType_WinMM:
    1560                     if (details == VMINFO_MACHINEREADABLE)
    1561                         pszDrv = "winmm";
    1562                     else
    1563                         pszDrv = "WINMM";
    1564                     break;
    1565                 case AudioDriverType_DirectSound:
    1566                     if (details == VMINFO_MACHINEREADABLE)
    1567                         pszDrv = "dsound";
    1568                     else
    1569                         pszDrv = "DSOUND";
    1570                     break;
    1571                 case AudioDriverType_OSS:
    1572                     if (details == VMINFO_MACHINEREADABLE)
    1573                         pszDrv = "oss";
    1574                     else
    1575                         pszDrv = "OSS";
    1576                     break;
    1577                 case AudioDriverType_ALSA:
    1578                     if (details == VMINFO_MACHINEREADABLE)
    1579                         pszDrv = "alsa";
    1580                     else
    1581                         pszDrv = "ALSA";
    1582                     break;
    1583                 case AudioDriverType_Pulse:
    1584                     if (details == VMINFO_MACHINEREADABLE)
    1585                         pszDrv = "pulse";
    1586                     else
    1587                         pszDrv = "PulseAudio";
    1588                     break;
    1589                 case AudioDriverType_CoreAudio:
    1590                     if (details == VMINFO_MACHINEREADABLE)
    1591                         pszDrv = "coreaudio";
    1592                     else
    1593                         pszDrv = "CoreAudio";
    1594                     break;
    1595                 case AudioDriverType_SolAudio:
    1596                     if (details == VMINFO_MACHINEREADABLE)
    1597                         pszDrv = "solaudio";
    1598                     else
    1599                         pszDrv = "SolAudio";
    1600                     break;
    1601                 default:
    1602                     if (details == VMINFO_MACHINEREADABLE)
    1603                         pszDrv = "unknown";
    1604                     break;
    1605             }
    1606             AudioControllerType_T enmCtrlType;
    1607             rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
    1608             switch (enmCtrlType)
    1609             {
    1610                 case AudioControllerType_AC97:
    1611                     if (details == VMINFO_MACHINEREADABLE)
    1612                         pszCtrl = "ac97";
    1613                     else
    1614                         pszCtrl = "AC97";
    1615                     break;
    1616                 case AudioControllerType_SB16:
    1617                     if (details == VMINFO_MACHINEREADABLE)
    1618                         pszCtrl = "sb16";
    1619                     else
    1620                         pszCtrl = "SB16";
    1621                     break;
    1622             }
    1623         }
    1624         else
    1625             fEnabled = FALSE;
    1626         if (details == VMINFO_MACHINEREADABLE)
    1627         {
    1628             if (fEnabled)
    1629                 RTPrintf("audio=\"%s\"\n", pszDrv);
    1630             else
    1631                 RTPrintf("audio=\"none\"\n");
    1632         }
    1633         else
    1634             RTPrintf("Audio:           %s (Driver: %s, Controller: %s)\n",
    1635                     fEnabled ? "enabled" : "disabled", pszDrv, pszCtrl);
    1636     }
    1637 
    1638     /* Shared clipboard */
    1639     {
    1640         const char *psz = "Unknown";
    1641         ClipboardMode_T enmMode;
    1642         rc = machine->COMGETTER(ClipboardMode)(&enmMode);
    1643         switch (enmMode)
    1644         {
    1645             case ClipboardMode_Disabled:
    1646                 if (details == VMINFO_MACHINEREADABLE)
    1647                     psz = "disabled";
    1648                 else
    1649                     psz = "disabled";
    1650                 break;
    1651             case ClipboardMode_HostToGuest:
    1652                 if (details == VMINFO_MACHINEREADABLE)
    1653                     psz = "hosttoguest";
    1654                 else
    1655                     psz = "HostToGuest";
    1656                 break;
    1657             case ClipboardMode_GuestToHost:
    1658                 if (details == VMINFO_MACHINEREADABLE)
    1659                     psz = "guesttohost";
    1660                 else
    1661                     psz = "GuestToHost";
    1662                 break;
    1663             case ClipboardMode_Bidirectional:
    1664                 if (details == VMINFO_MACHINEREADABLE)
    1665                     psz = "bidirectional";
    1666                 else
    1667                     psz = "Bidirectional";
    1668                 break;
    1669             default:
    1670                 if (details == VMINFO_MACHINEREADABLE)
    1671                     psz = "unknown";
    1672                 break;
    1673         }
    1674         if (details == VMINFO_MACHINEREADABLE)
    1675             RTPrintf("clipboard=\"%s\"\n", psz);
    1676         else
    1677             RTPrintf("Clipboard Mode:  %s\n", psz);
    1678     }
    1679 
    1680     if (console)
    1681     {
    1682         ComPtr<IDisplay> display;
    1683         CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
    1684         do
    1685         {
    1686             ULONG xRes, yRes, bpp;
    1687             rc = display->COMGETTER(Width)(&xRes);
    1688             if (rc == E_ACCESSDENIED)
    1689                 break; /* VM not powered up */
    1690             if (FAILED(rc))
    1691             {
    1692                 com::ErrorInfo info (display);
    1693                 PRINT_ERROR_INFO (info);
    1694                 return rc;
    1695             }
    1696             rc = display->COMGETTER(Height)(&yRes);
    1697             if (rc == E_ACCESSDENIED)
    1698                 break; /* VM not powered up */
    1699             if (FAILED(rc))
    1700             {
    1701                 com::ErrorInfo info (display);
    1702                 PRINT_ERROR_INFO (info);
    1703                 return rc;
    1704             }
    1705             rc = display->COMGETTER(BitsPerPixel)(&bpp);
    1706             if (rc == E_ACCESSDENIED)
    1707                 break; /* VM not powered up */
    1708             if (FAILED(rc))
    1709             {
    1710                 com::ErrorInfo info (display);
    1711                 PRINT_ERROR_INFO (info);
    1712                 return rc;
    1713             }
    1714             if (details == VMINFO_MACHINEREADABLE)
    1715                 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
    1716             else
    1717                 RTPrintf("Video mode:      %dx%dx%d\n", xRes, yRes, bpp);
    1718         }
    1719         while (0);
    1720     }
    1721 
    1722     /*
    1723      * VRDP
    1724      */
    1725     ComPtr<IVRDPServer> vrdpServer;
    1726     rc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
    1727     if (SUCCEEDED(rc) && vrdpServer)
    1728     {
    1729         BOOL fEnabled = false;
    1730         vrdpServer->COMGETTER(Enabled)(&fEnabled);
    1731         if (fEnabled)
    1732         {
    1733             ULONG port;
    1734             vrdpServer->COMGETTER(Port)(&port);
    1735             Bstr address;
    1736             vrdpServer->COMGETTER(NetAddress)(address.asOutParam());
    1737             BOOL fMultiCon;
    1738             vrdpServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
    1739             BOOL fReuseCon;
    1740             vrdpServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
    1741             VRDPAuthType_T vrdpAuthType;
    1742             const char *strAuthType;
    1743             vrdpServer->COMGETTER(AuthType)(&vrdpAuthType);
    1744             switch (vrdpAuthType)
    1745             {
    1746                 case VRDPAuthType_Null:
    1747                     strAuthType = "null";
    1748                     break;
    1749                 case VRDPAuthType_External:
    1750                     strAuthType = "external";
    1751                     break;
    1752                 case VRDPAuthType_Guest:
    1753                     strAuthType = "guest";
    1754                     break;
    1755                 default:
    1756                     strAuthType = "unknown";
    1757                     break;
    1758             }
    1759             if (details == VMINFO_MACHINEREADABLE)
    1760             {
    1761                 RTPrintf("vrdp=\"on\"\n");
    1762                 RTPrintf("vrdpport=%d\n", port);
    1763                 RTPrintf("vrdpaddress=\"%lS\"\n", address.raw());
    1764                 RTPrintf("vrdpauthtype=\"%s\"\n", strAuthType);
    1765                 RTPrintf("vrdpmulticon=\"%s\"\n", fMultiCon ? "on" : "off");
    1766                 RTPrintf("vrdpreusecon=\"%s\"\n", fReuseCon ? "on" : "off");
    1767             }
    1768             else
    1769             {
    1770                 if (address.isEmpty())
    1771                     address = "0.0.0.0";
    1772                 RTPrintf("VRDP:            enabled (Address %lS, Port %d, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)\n", address.raw(), port, fMultiCon ? "on" : "off", fReuseCon ? "on" : "off", strAuthType);
    1773             }
    1774         }
    1775         else
    1776         {
    1777             if (details == VMINFO_MACHINEREADABLE)
    1778                 RTPrintf("vrdp=\"off\"\n");
    1779             else
    1780                 RTPrintf("VRDP:            disabled\n");
    1781         }
    1782     }
    1783 
    1784     /*
    1785      * USB.
    1786      */
    1787     ComPtr<IUSBController> USBCtl;
    1788     rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
    1789     if (SUCCEEDED(rc))
    1790     {
    1791         BOOL fEnabled;
    1792         rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
    1793         if (FAILED(rc))
    1794             fEnabled = false;
    1795         if (details == VMINFO_MACHINEREADABLE)
    1796             RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
    1797         else
    1798             RTPrintf("USB:             %s\n", fEnabled ? "enabled" : "disabled");
    1799 
    1800         if (details != VMINFO_MACHINEREADABLE)
    1801             RTPrintf("\nUSB Device Filters:\n\n");
    1802 
    1803         ComPtr<IUSBDeviceFilterCollection> Coll;
    1804         CHECK_ERROR_RET (USBCtl, COMGETTER(DeviceFilters)(Coll.asOutParam()), rc);
    1805 
    1806         ComPtr<IUSBDeviceFilterEnumerator> Enum;
    1807         CHECK_ERROR_RET (Coll, Enumerate(Enum.asOutParam()), rc);
    1808 
    1809         ULONG index = 0;
    1810         BOOL fMore = FALSE;
    1811         rc = Enum->HasMore (&fMore);
    1812         ASSERT_RET (SUCCEEDED (rc), rc);
    1813 
    1814         if (!fMore)
    1815         {
    1816             if (details != VMINFO_MACHINEREADABLE)
    1817                 RTPrintf("<none>\n\n");
    1818         }
    1819         else
    1820         while (fMore)
    1821         {
    1822             ComPtr<IUSBDeviceFilter> DevPtr;
    1823             rc = Enum->GetNext(DevPtr.asOutParam());
    1824             ASSERT_RET (SUCCEEDED (rc), rc);
    1825 
    1826             /* Query info. */
    1827 
    1828             if (details != VMINFO_MACHINEREADABLE)
    1829                 RTPrintf("Index:            %lu\n", index);
    1830 
    1831             BOOL bActive = FALSE;
    1832             CHECK_ERROR_RET (DevPtr, COMGETTER (Active) (&bActive), rc);
    1833             if (details == VMINFO_MACHINEREADABLE)
    1834                 RTPrintf("USBFilterActive%d=\"%s\"\n", index + 1, bActive ? "on" : "off");
    1835             else
    1836                 RTPrintf("Active:           %s\n", bActive ? "yes" : "no");
    1837 
    1838             Bstr bstr;
    1839             CHECK_ERROR_RET (DevPtr, COMGETTER (Name) (bstr.asOutParam()), rc);
    1840             if (details == VMINFO_MACHINEREADABLE)
    1841                 RTPrintf("USBFilterName%d=\"%lS\"\n", index + 1, bstr.raw());
    1842             else
    1843                 RTPrintf("Name:             %lS\n", bstr.raw());
    1844             CHECK_ERROR_RET (DevPtr, COMGETTER (VendorId) (bstr.asOutParam()), rc);
    1845             if (details == VMINFO_MACHINEREADABLE)
    1846                 RTPrintf("USBFilterVendorId%d=\"%lS\"\n", index + 1, bstr.raw());
    1847             else
    1848                 RTPrintf("VendorId:         %lS\n", bstr.raw());
    1849             CHECK_ERROR_RET (DevPtr, COMGETTER (ProductId) (bstr.asOutParam()), rc);
    1850             if (details == VMINFO_MACHINEREADABLE)
    1851                 RTPrintf("USBFilterProductId%d=\"%lS\"\n", index + 1, bstr.raw());
    1852             else
    1853                 RTPrintf("ProductId:        %lS\n", bstr.raw());
    1854             CHECK_ERROR_RET (DevPtr, COMGETTER (Revision) (bstr.asOutParam()), rc);
    1855             if (details == VMINFO_MACHINEREADABLE)
    1856                 RTPrintf("USBFilterRevision%d=\"%lS\"\n", index + 1, bstr.raw());
    1857             else
    1858                 RTPrintf("Revision:         %lS\n", bstr.raw());
    1859             CHECK_ERROR_RET (DevPtr, COMGETTER (Manufacturer) (bstr.asOutParam()), rc);
    1860             if (details == VMINFO_MACHINEREADABLE)
    1861                 RTPrintf("USBFilterManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
    1862             else
    1863                 RTPrintf("Manufacturer:     %lS\n", bstr.raw());
    1864             CHECK_ERROR_RET (DevPtr, COMGETTER (Product) (bstr.asOutParam()), rc);
    1865             if (details == VMINFO_MACHINEREADABLE)
    1866                 RTPrintf("USBFilterProduct%d=\"%lS\"\n", index + 1, bstr.raw());
    1867             else
    1868                 RTPrintf("Product:          %lS\n", bstr.raw());
    1869             CHECK_ERROR_RET (DevPtr, COMGETTER (Remote) (bstr.asOutParam()), rc);
    1870             if (details == VMINFO_MACHINEREADABLE)
    1871                 RTPrintf("USBFilterRemote%d=\"%lS\"\n", index + 1, bstr.raw());
    1872             else
    1873                 RTPrintf("Remote:           %lS\n", bstr.raw());
    1874             CHECK_ERROR_RET (DevPtr, COMGETTER (SerialNumber) (bstr.asOutParam()), rc);
    1875             if (details == VMINFO_MACHINEREADABLE)
    1876                 RTPrintf("USBFilterSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
    1877             else
    1878                 RTPrintf("Serial Number:    %lS\n", bstr.raw());
    1879             if (details != VMINFO_MACHINEREADABLE)
    1880             {
    1881                 ULONG fMaskedIfs;
    1882                 CHECK_ERROR_RET (DevPtr, COMGETTER (MaskedInterfaces) (&fMaskedIfs), rc);
    1883                 if (fMaskedIfs)
    1884                     RTPrintf("Masked Interfaces: 0x%08x\n", fMaskedIfs);
    1885                 RTPrintf("\n");
    1886             }
    1887 
    1888             rc = Enum->HasMore (&fMore);
    1889             ASSERT_RET (SUCCEEDED (rc), rc);
    1890 
    1891             index ++;
    1892         }
    1893 
    1894         if (console)
    1895         {
    1896             index = 0;
    1897             /* scope */
    1898             {
    1899                 if (details != VMINFO_MACHINEREADABLE)
    1900                     RTPrintf("Available remote USB devices:\n\n");
    1901 
    1902                 ComPtr<IHostUSBDeviceCollection> coll;
    1903                 CHECK_ERROR_RET (console, COMGETTER(RemoteUSBDevices) (coll.asOutParam()), rc);
    1904 
    1905                 ComPtr <IHostUSBDeviceEnumerator> en;
    1906                 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
    1907 
    1908                 BOOL more = FALSE;
    1909                 rc = en->HasMore (&more);
    1910                 ASSERT_RET (SUCCEEDED (rc), rc);
    1911 
    1912                 if (!more)
    1913                 {
    1914                     if (details != VMINFO_MACHINEREADABLE)
    1915                         RTPrintf("<none>\n\n");
    1916                 }
    1917                 else
    1918                 while (more)
    1919                 {
    1920                     ComPtr <IHostUSBDevice> dev;
    1921                     rc = en->GetNext (dev.asOutParam());
    1922                     ASSERT_RET (SUCCEEDED (rc), rc);
    1923 
    1924                     /* Query info. */
    1925                     Guid id;
    1926                     CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
    1927                     USHORT usVendorId;
    1928                     CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
    1929                     USHORT usProductId;
    1930                     CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
    1931                     USHORT bcdRevision;
    1932                     CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
    1933 
    1934                     if (details == VMINFO_MACHINEREADABLE)
    1935                         RTPrintf("USBRemoteUUID%d=\"%S\"\n"
    1936                                  "USBRemoteVendorId%d=\"%#06x\"\n"
    1937                                  "USBRemoteProductId%d=\"%#06x\"\n"
    1938                                  "USBRemoteRevision%d=\"%#04x%02x\"\n",
    1939                                  index + 1, id.toString().raw(),
    1940                                  index + 1, usVendorId,
    1941                                  index + 1, usProductId,
    1942                                  index + 1, bcdRevision >> 8, bcdRevision & 0xff);
    1943                     else
    1944                         RTPrintf("UUID:               %S\n"
    1945                                  "VendorId:           0x%04x (%04X)\n"
    1946                                  "ProductId:          0x%04x (%04X)\n"
    1947                                  "Revision:           %u.%u (%02u%02u)\n",
    1948                                  id.toString().raw(),
    1949                                  usVendorId, usVendorId, usProductId, usProductId,
    1950                                  bcdRevision >> 8, bcdRevision & 0xff,
    1951                                  bcdRevision >> 8, bcdRevision & 0xff);
    1952 
    1953                     /* optional stuff. */
    1954                     Bstr bstr;
    1955                     CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
    1956                     if (!bstr.isEmpty())
    1957                     {
    1958                         if (details == VMINFO_MACHINEREADABLE)
    1959                             RTPrintf("USBRemoteManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
    1960                         else
    1961                             RTPrintf("Manufacturer:       %lS\n", bstr.raw());
    1962                     }
    1963                     CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
    1964                     if (!bstr.isEmpty())
    1965                     {
    1966                         if (details == VMINFO_MACHINEREADABLE)
    1967                             RTPrintf("USBRemoteProduct%d=\"%lS\"\n", index + 1, bstr.raw());
    1968                         else
    1969                             RTPrintf("Product:            %lS\n", bstr.raw());
    1970                     }
    1971                     CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
    1972                     if (!bstr.isEmpty())
    1973                     {
    1974                         if (details == VMINFO_MACHINEREADABLE)
    1975                             RTPrintf("USBRemoteSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
    1976                         else
    1977                             RTPrintf("SerialNumber:       %lS\n", bstr.raw());
    1978                     }
    1979                     CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
    1980                     if (!bstr.isEmpty())
    1981                     {
    1982                         if (details == VMINFO_MACHINEREADABLE)
    1983                             RTPrintf("USBRemoteAddress%d=\"%lS\"\n", index + 1, bstr.raw());
    1984                         else
    1985                             RTPrintf("Address:            %lS\n", bstr.raw());
    1986                     }
    1987 
    1988                     if (details != VMINFO_MACHINEREADABLE)
    1989                         RTPrintf("\n");
    1990 
    1991                     rc = en->HasMore (&more);
    1992                     ASSERT_RET (SUCCEEDED (rc), rc);
    1993 
    1994                     index ++;
    1995                 }
    1996             }
    1997 
    1998             index = 0;
    1999             /* scope */
    2000             {
    2001                 if (details != VMINFO_MACHINEREADABLE)
    2002                     RTPrintf ("Currently Attached USB Devices:\n\n");
    2003 
    2004                 ComPtr <IUSBDeviceCollection> coll;
    2005                 CHECK_ERROR_RET (console, COMGETTER(USBDevices) (coll.asOutParam()), rc);
    2006 
    2007                 ComPtr <IUSBDeviceEnumerator> en;
    2008                 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
    2009 
    2010                 BOOL more = FALSE;
    2011                 rc = en->HasMore (&more);
    2012                 ASSERT_RET (SUCCEEDED (rc), rc);
    2013 
    2014                 if (!more)
    2015                 {
    2016                     if (details != VMINFO_MACHINEREADABLE)
    2017                         RTPrintf("<none>\n\n");
    2018                 }
    2019                 else
    2020                 while (more)
    2021                 {
    2022                     ComPtr <IUSBDevice> dev;
    2023                     rc = en->GetNext (dev.asOutParam());
    2024                     ASSERT_RET (SUCCEEDED (rc), rc);
    2025 
    2026                     /* Query info. */
    2027                     Guid id;
    2028                     CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
    2029                     USHORT usVendorId;
    2030                     CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
    2031                     USHORT usProductId;
    2032                     CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
    2033                     USHORT bcdRevision;
    2034                     CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
    2035 
    2036                     if (details == VMINFO_MACHINEREADABLE)
    2037                         RTPrintf("USBAttachedUUID%d=\"%S\"\n"
    2038                                  "USBAttachedVendorId%d=\"%#06x\"\n"
    2039                                  "USBAttachedProductId%d=\"%#06x\"\n"
    2040                                  "USBAttachedRevision%d=\"%#04x%02x\"\n",
    2041                                  index + 1, id.toString().raw(),
    2042                                  index + 1, usVendorId,
    2043                                  index + 1, usProductId,
    2044                                  index + 1, bcdRevision >> 8, bcdRevision & 0xff);
    2045                     else
    2046                         RTPrintf("UUID:               %S\n"
    2047                                  "VendorId:           0x%04x (%04X)\n"
    2048                                  "ProductId:          0x%04x (%04X)\n"
    2049                                  "Revision:           %u.%u (%02u%02u)\n",
    2050                                  id.toString().raw(),
    2051                                  usVendorId, usVendorId, usProductId, usProductId,
    2052                                  bcdRevision >> 8, bcdRevision & 0xff,
    2053                                  bcdRevision >> 8, bcdRevision & 0xff);
    2054 
    2055                     /* optional stuff. */
    2056                     Bstr bstr;
    2057                     CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
    2058                     if (!bstr.isEmpty())
    2059                     {
    2060                         if (details == VMINFO_MACHINEREADABLE)
    2061                             RTPrintf("USBAttachedManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
    2062                         else
    2063                             RTPrintf("Manufacturer:       %lS\n", bstr.raw());
    2064                     }
    2065                     CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
    2066                     if (!bstr.isEmpty())
    2067                     {
    2068                         if (details == VMINFO_MACHINEREADABLE)
    2069                             RTPrintf("USBAttachedProduct%d=\"%lS\"\n", index + 1, bstr.raw());
    2070                         else
    2071                             RTPrintf("Product:            %lS\n", bstr.raw());
    2072                     }
    2073                     CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
    2074                     if (!bstr.isEmpty())
    2075                     {
    2076                         if (details == VMINFO_MACHINEREADABLE)
    2077                             RTPrintf("USBAttachedSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
    2078                         else
    2079                             RTPrintf("SerialNumber:       %lS\n", bstr.raw());
    2080                     }
    2081                     CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
    2082                     if (!bstr.isEmpty())
    2083                     {
    2084                         if (details == VMINFO_MACHINEREADABLE)
    2085                             RTPrintf("USBAttachedAddress%d=\"%lS\"\n", index + 1, bstr.raw());
    2086                         else
    2087                             RTPrintf("Address:            %lS\n", bstr.raw());
    2088                     }
    2089 
    2090                     if (details != VMINFO_MACHINEREADABLE)
    2091                         RTPrintf("\n");
    2092 
    2093                     rc = en->HasMore (&more);
    2094                     ASSERT_RET (SUCCEEDED (rc), rc);
    2095 
    2096                     index ++;
    2097                 }
    2098             }
    2099         }
    2100     } /* USB */
    2101 
    2102     /*
    2103      * Shared folders
    2104      */
    2105     if (details != VMINFO_MACHINEREADABLE)
    2106         RTPrintf("Shared folders:  ");
    2107     uint32_t numSharedFolders = 0;
    2108 #if 0 // not yet implemented
    2109     /* globally shared folders first */
    2110     {
    2111         ComPtr<ISharedFolderCollection> sfColl;
    2112         ComPtr<ISharedFolderEnumerator> sfEnum;
    2113         CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
    2114         CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
    2115         BOOL fMore;
    2116         sfEnum->HasMore(&fMore);
    2117         while (fMore)
    2118         {
    2119             ComPtr<ISharedFolder> sf;
    2120             CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
    2121             Bstr name, hostPath;
    2122             sf->COMGETTER(Name)(name.asOutParam());
    2123             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2124             RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
    2125             ++numSharedFolders;
    2126             CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
    2127         }
    2128     }
    2129 #endif
    2130     /* now VM mappings */
    2131     {
    2132         ComPtr<ISharedFolderCollection> sfColl;
    2133         ComPtr<ISharedFolderEnumerator> sfEnum;
    2134         CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
    2135         CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
    2136         ULONG index = 0;
    2137         BOOL fMore;
    2138         sfEnum->HasMore(&fMore);
    2139         while (fMore)
    2140         {
    2141             ComPtr<ISharedFolder> sf;
    2142             CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
    2143             Bstr name, hostPath;
    2144             BOOL writable;
    2145             sf->COMGETTER(Name)(name.asOutParam());
    2146             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2147             sf->COMGETTER(Writable)(&writable);
    2148             if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
    2149                 RTPrintf("\n\n");
    2150             if (details == VMINFO_MACHINEREADABLE)
    2151             {
    2152                 RTPrintf("SharedFolderNameMachineMapping%d=\"%lS\"\n", index + 1,
    2153                          name.raw());
    2154                 RTPrintf("SharedFolderPathMachineMapping%d=\"%lS\"\n", index + 1,
    2155                          hostPath.raw());
    2156             }
    2157             else
    2158                 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
    2159                          name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
    2160             ++numSharedFolders;
    2161             CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
    2162         }
    2163     }
    2164     /* transient mappings */
    2165     if (console)
    2166     {
    2167         ComPtr<ISharedFolderCollection> sfColl;
    2168         ComPtr<ISharedFolderEnumerator> sfEnum;
    2169         CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
    2170         CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
    2171         ULONG index = 0;
    2172         BOOL fMore;
    2173         sfEnum->HasMore(&fMore);
    2174         while (fMore)
    2175         {
    2176             ComPtr<ISharedFolder> sf;
    2177             CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
    2178             Bstr name, hostPath;
    2179             sf->COMGETTER(Name)(name.asOutParam());
    2180             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2181             if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
    2182                 RTPrintf("\n\n");
    2183             if (details == VMINFO_MACHINEREADABLE)
    2184             {
    2185                 RTPrintf("SharedFolderNameTransientMapping%d=\"%lS\"\n", index + 1,
    2186                          name.raw());
    2187                 RTPrintf("SharedFolderPathTransientMapping%d=\"%lS\"\n", index + 1,
    2188                          hostPath.raw());
    2189             }
    2190             else
    2191                 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
    2192             ++numSharedFolders;
    2193             CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
    2194         }
    2195     }
    2196     if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
    2197         RTPrintf("<none>\n");
    2198     if (details != VMINFO_MACHINEREADABLE)
    2199         RTPrintf("\n");
    2200 
    2201     if (console)
    2202     {
    2203         /*
    2204          * Live VRDP info.
    2205          */
    2206         ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
    2207         CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
    2208         BOOL    Active;
    2209         ULONG   NumberOfClients;
    2210         LONG64  BeginTime;
    2211         LONG64  EndTime;
    2212         ULONG64 BytesSent;
    2213         ULONG64 BytesSentTotal;
    2214         ULONG64 BytesReceived;
    2215         ULONG64 BytesReceivedTotal;
    2216         Bstr    User;
    2217         Bstr    Domain;
    2218         Bstr    ClientName;
    2219         Bstr    ClientIP;
    2220         ULONG   ClientVersion;
    2221         ULONG   EncryptionStyle;
    2222 
    2223         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Active)             (&Active), rc);
    2224         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(NumberOfClients)    (&NumberOfClients), rc);
    2225         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BeginTime)          (&BeginTime), rc);
    2226         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EndTime)            (&EndTime), rc);
    2227         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSent)          (&BytesSent), rc);
    2228         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSentTotal)     (&BytesSentTotal), rc);
    2229         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceived)      (&BytesReceived), rc);
    2230         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceivedTotal) (&BytesReceivedTotal), rc);
    2231         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(User)               (User.asOutParam ()), rc);
    2232         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Domain)             (Domain.asOutParam ()), rc);
    2233         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientName)         (ClientName.asOutParam ()), rc);
    2234         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientIP)           (ClientIP.asOutParam ()), rc);
    2235         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientVersion)      (&ClientVersion), rc);
    2236         CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EncryptionStyle)    (&EncryptionStyle), rc);
    2237 
    2238         if (details == VMINFO_MACHINEREADABLE)
    2239             RTPrintf("VRDPActiveConnection=\"%s\"\n", Active ? "on": "off");
    2240         else
    2241             RTPrintf("VRDP Connection:    %s\n", Active? "active": "not active");
    2242 
    2243         if (details == VMINFO_MACHINEREADABLE)
    2244             RTPrintf("VRDPClients=%d\n", NumberOfClients);
    2245         else
    2246             RTPrintf("Clients so far:     %d\n", NumberOfClients);
    2247 
    2248         if (NumberOfClients > 0)
    2249         {
    2250             char timestr[128];
    2251 
    2252             if (Active)
    2253             {
    2254                 makeTimeStr (timestr, sizeof (timestr), BeginTime);
    2255                 if (details == VMINFO_MACHINEREADABLE)
    2256                     RTPrintf("VRDPStartTime=\"%s\"\n", timestr);
    2257                 else
    2258                     RTPrintf("Start time:         %s\n", timestr);
    2259             }
    2260             else
    2261             {
    2262                 makeTimeStr (timestr, sizeof (timestr), BeginTime);
    2263                 if (details == VMINFO_MACHINEREADABLE)
    2264                     RTPrintf("VRDPLastStartTime=\"%s\"\n", timestr);
    2265                 else
    2266                     RTPrintf("Last started:       %s\n", timestr);
    2267                 makeTimeStr (timestr, sizeof (timestr), EndTime);
    2268                 if (details == VMINFO_MACHINEREADABLE)
    2269                     RTPrintf("VRDPLastEndTime=\"%s\"\n", timestr);
    2270                 else
    2271                     RTPrintf("Last ended:         %s\n", timestr);
    2272             }
    2273 
    2274             uint64_t ThroughputSend = 0;
    2275             uint64_t ThroughputReceive = 0;
    2276             if (EndTime != BeginTime)
    2277             {
    2278                 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
    2279                 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
    2280             }
    2281 
    2282             if (details == VMINFO_MACHINEREADABLE)
    2283             {
    2284                 RTPrintf("VRDPBytesSent=%llu\n", BytesSent);
    2285                 RTPrintf("VRDPThroughputSend=%llu\n", ThroughputSend);
    2286                 RTPrintf("VRDPBytesSentTotal=%llu\n", BytesSentTotal);
    2287 
    2288                 RTPrintf("VRDPBytesReceived=%llu\n", BytesReceived);
    2289                 RTPrintf("VRDPThroughputReceive=%llu\n", ThroughputReceive);
    2290                 RTPrintf("VRDPBytesReceivedTotal=%llu\n", BytesReceivedTotal);
    2291             }
    2292             else
    2293             {
    2294                 RTPrintf("Sent:               %llu Bytes\n", BytesSent);
    2295                 RTPrintf("Average speed:      %llu B/s\n", ThroughputSend);
    2296                 RTPrintf("Sent total:         %llu Bytes\n", BytesSentTotal);
    2297 
    2298                 RTPrintf("Received:           %llu Bytes\n", BytesReceived);
    2299                 RTPrintf("Speed:              %llu B/s\n", ThroughputReceive);
    2300                 RTPrintf("Received total:     %llu Bytes\n", BytesReceivedTotal);
    2301             }
    2302 
    2303             if (Active)
    2304             {
    2305                 if (details == VMINFO_MACHINEREADABLE)
    2306                 {
    2307                     RTPrintf("VRDPUserName=\"%lS\"\n", User.raw());
    2308                     RTPrintf("VRDPDomain=\"%lS\"\n", Domain.raw());
    2309                     RTPrintf("VRDPClientName=\"%lS\"\n", ClientName.raw());
    2310                     RTPrintf("VRDPClientIP=\"%lS\"\n", ClientIP.raw());
    2311                     RTPrintf("VRDPClientVersion=%d\n",  ClientVersion);
    2312                     RTPrintf("VRDPEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
    2313                 }
    2314                 else
    2315                 {
    2316                     RTPrintf("User name:          %lS\n", User.raw());
    2317                     RTPrintf("Domain:             %lS\n", Domain.raw());
    2318                     RTPrintf("Client name:        %lS\n", ClientName.raw());
    2319                     RTPrintf("Client IP:          %lS\n", ClientIP.raw());
    2320                     RTPrintf("Client version:     %d\n",  ClientVersion);
    2321                     RTPrintf("Encryption:         %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
    2322                 }
    2323             }
    2324         }
    2325 
    2326         if (details != VMINFO_MACHINEREADABLE)
    2327             RTPrintf("\n");
    2328     }
    2329 
    2330     if (    details == VMINFO_STANDARD
    2331         ||  details == VMINFO_FULL
    2332         ||  details == VMINFO_MACHINEREADABLE)
    2333     {
    2334         Bstr description;
    2335         machine->COMGETTER(Description)(description.asOutParam());
    2336         if (!description.isEmpty())
    2337         {
    2338             if (details == VMINFO_MACHINEREADABLE)
    2339                 RTPrintf("description=\"%lS\"\n", description.raw());
    2340             else
    2341                 RTPrintf("Description:\n%lS\n", description.raw());
    2342         }
    2343     }
    2344 
    2345     ULONG guestVal;
    2346     if (details != VMINFO_MACHINEREADABLE)
    2347         RTPrintf("Guest:\n\n");
    2348 
    2349 #ifdef VBOX_WITH_MEM_BALLOONING
    2350     rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
    2351     if (SUCCEEDED(rc))
    2352     {
    2353         if (details == VMINFO_MACHINEREADABLE)
    2354             RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
    2355         else
    2356             RTPrintf("Configured memory balloon size:      %d MB\n", guestVal);
    2357     }
    2358 #endif
    2359     rc = machine->COMGETTER(StatisticsUpdateInterval)(&guestVal);
    2360     if (SUCCEEDED(rc))
    2361     {
    2362         if (details == VMINFO_MACHINEREADABLE)
    2363             RTPrintf("GuestStatisticsUpdateInterval=%d\n", guestVal);
    2364         else
    2365         {
    2366             if (guestVal == 0)
    2367                 RTPrintf("Statistics update:                   disabled\n");
    2368             else
    2369                 RTPrintf("Statistics update interval:          %d seconds\n", guestVal);
    2370         }
    2371     }
    2372     if (details != VMINFO_MACHINEREADABLE)
    2373         RTPrintf("\n");
    2374 
    2375     if (    console
    2376         &&  (   details == VMINFO_STATISTICS
    2377              || details == VMINFO_FULL
    2378              || details == VMINFO_MACHINEREADABLE))
    2379     {
    2380         ComPtr <IGuest> guest;
    2381 
    2382         rc = console->COMGETTER(Guest)(guest.asOutParam());
    2383         if (SUCCEEDED(rc))
    2384         {
    2385             ULONG statVal;
    2386 
    2387             rc = guest->GetStatistic(0, GuestStatisticType_SampleNumber, &statVal);
    2388             if (details == VMINFO_MACHINEREADABLE)
    2389                 RTPrintf("StatGuestSample=%d\n", statVal);
    2390             else
    2391                 RTPrintf("Guest statistics for sample %d:\n\n", statVal);
    2392 
    2393             rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_Idle, &statVal);
    2394             if (SUCCEEDED(rc))
    2395             {
    2396                 if (details == VMINFO_MACHINEREADABLE)
    2397                     RTPrintf("StatGuestLoadIdleCPU%d=%d\n", 0, statVal);
    2398                 else
    2399                     RTPrintf("CPU%d: CPU Load Idle          %-3d%%\n", 0, statVal);
    2400             }
    2401 
    2402             rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_Kernel, &statVal);
    2403             if (SUCCEEDED(rc))
    2404             {
    2405                 if (details == VMINFO_MACHINEREADABLE)
    2406                     RTPrintf("StatGuestLoadKernelCPU%d=%d\n", 0, statVal);
    2407                 else
    2408                     RTPrintf("CPU%d: CPU Load Kernel        %-3d%%\n", 0, statVal);
    2409             }
    2410 
    2411             rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_User, &statVal);
    2412             if (SUCCEEDED(rc))
    2413             {
    2414                 if (details == VMINFO_MACHINEREADABLE)
    2415                     RTPrintf("StatGuestLoadUserCPU%d=%d\n", 0, statVal);
    2416                 else
    2417                     RTPrintf("CPU%d: CPU Load User          %-3d%%\n", 0, statVal);
    2418             }
    2419 
    2420             rc = guest->GetStatistic(0, GuestStatisticType_Threads, &statVal);
    2421             if (SUCCEEDED(rc))
    2422             {
    2423                 if (details == VMINFO_MACHINEREADABLE)
    2424                     RTPrintf("StatGuestThreadsCPU%d=%d\n", 0, statVal);
    2425                 else
    2426                     RTPrintf("CPU%d: Threads                %d\n", 0, statVal);
    2427             }
    2428 
    2429             rc = guest->GetStatistic(0, GuestStatisticType_Processes, &statVal);
    2430             if (SUCCEEDED(rc))
    2431             {
    2432                 if (details == VMINFO_MACHINEREADABLE)
    2433                     RTPrintf("StatGuestProcessesCPU%d=%d\n", 0, statVal);
    2434                 else
    2435                     RTPrintf("CPU%d: Processes              %d\n", 0, statVal);
    2436             }
    2437 
    2438             rc = guest->GetStatistic(0, GuestStatisticType_Handles, &statVal);
    2439             if (SUCCEEDED(rc))
    2440             {
    2441                 if (details == VMINFO_MACHINEREADABLE)
    2442                     RTPrintf("StatGuestHandlesCPU%d=%d\n", 0, statVal);
    2443                 else
    2444                     RTPrintf("CPU%d: Handles                %d\n", 0, statVal);
    2445             }
    2446 
    2447             rc = guest->GetStatistic(0, GuestStatisticType_MemoryLoad, &statVal);
    2448             if (SUCCEEDED(rc))
    2449             {
    2450                 if (details == VMINFO_MACHINEREADABLE)
    2451                     RTPrintf("StatGuestMemoryLoadCPU%d=%d\n", 0, statVal);
    2452                 else
    2453                     RTPrintf("CPU%d: Memory Load            %d%%\n", 0, statVal);
    2454             }
    2455 
    2456             rc = guest->GetStatistic(0, GuestStatisticType_PhysMemTotal, &statVal);
    2457             if (SUCCEEDED(rc))
    2458             {
    2459                 if (details == VMINFO_MACHINEREADABLE)
    2460                     RTPrintf("StatGuestMemoryTotalPhysCPU%d=%d\n", 0, statVal);
    2461                 else
    2462                     RTPrintf("CPU%d: Total physical memory  %-4d MB\n", 0, statVal);
    2463             }
    2464 
    2465             rc = guest->GetStatistic(0, GuestStatisticType_PhysMemAvailable, &statVal);
    2466             if (SUCCEEDED(rc))
    2467             {
    2468                 if (details == VMINFO_MACHINEREADABLE)
    2469                     RTPrintf("StatGuestMemoryFreePhysCPU%d=%d\n", 0, statVal);
    2470                 else
    2471                     RTPrintf("CPU%d: Free physical memory   %-4d MB\n", 0, statVal);
    2472             }
    2473 
    2474 #ifdef VBOX_WITH_MEM_BALLOONING
    2475             rc = guest->GetStatistic(0, GuestStatisticType_PhysMemBalloon, &statVal);
    2476             if (SUCCEEDED(rc))
    2477             {
    2478                 if (details == VMINFO_MACHINEREADABLE)
    2479                     RTPrintf("StatGuestMemoryBalloonCPU%d=%d\n", 0, statVal);
    2480                 else
    2481                     RTPrintf("CPU%d: Memory balloon size    %-4d MB\n", 0, statVal);
    2482             }
    2483 #endif
    2484             rc = guest->GetStatistic(0, GuestStatisticType_MemCommitTotal, &statVal);
    2485             if (SUCCEEDED(rc))
    2486             {
    2487                 if (details == VMINFO_MACHINEREADABLE)
    2488                     RTPrintf("StatGuestMemoryCommittedCPU%d=%d\n", 0, statVal);
    2489                 else
    2490                     RTPrintf("CPU%d: Committed memory       %-4d MB\n", 0, statVal);
    2491             }
    2492 
    2493             rc = guest->GetStatistic(0, GuestStatisticType_MemKernelTotal, &statVal);
    2494             if (SUCCEEDED(rc))
    2495             {
    2496                 if (details == VMINFO_MACHINEREADABLE)
    2497                     RTPrintf("StatGuestMemoryTotalKernelCPU%d=%d\n", 0, statVal);
    2498                 else
    2499                     RTPrintf("CPU%d: Total kernel memory    %-4d MB\n", 0, statVal);
    2500             }
    2501 
    2502             rc = guest->GetStatistic(0, GuestStatisticType_MemKernelPaged, &statVal);
    2503             if (SUCCEEDED(rc))
    2504             {
    2505                 if (details == VMINFO_MACHINEREADABLE)
    2506                     RTPrintf("StatGuestMemoryPagedKernelCPU%d=%d\n", 0, statVal);
    2507                 else
    2508                     RTPrintf("CPU%d: Paged kernel memory    %-4d MB\n", 0, statVal);
    2509             }
    2510 
    2511             rc = guest->GetStatistic(0, GuestStatisticType_MemKernelNonpaged, &statVal);
    2512             if (SUCCEEDED(rc))
    2513             {
    2514                 if (details == VMINFO_MACHINEREADABLE)
    2515                     RTPrintf("StatGuestMemoryNonpagedKernelCPU%d=%d\n", 0, statVal);
    2516                 else
    2517                     RTPrintf("CPU%d: Nonpaged kernel memory %-4d MB\n", 0, statVal);
    2518             }
    2519 
    2520             rc = guest->GetStatistic(0, GuestStatisticType_MemSystemCache, &statVal);
    2521             if (SUCCEEDED(rc))
    2522             {
    2523                 if (details == VMINFO_MACHINEREADABLE)
    2524                     RTPrintf("StatGuestSystemCacheSizeCPU%d=%d\n", 0, statVal);
    2525                 else
    2526                     RTPrintf("CPU%d: System cache size      %-4d MB\n", 0, statVal);
    2527             }
    2528 
    2529             rc = guest->GetStatistic(0, GuestStatisticType_PageFileSize, &statVal);
    2530             if (SUCCEEDED(rc))
    2531             {
    2532                 if (details == VMINFO_MACHINEREADABLE)
    2533                     RTPrintf("StatGuestPageFileSizeCPU%d=%d\n", 0, statVal);
    2534                 else
    2535                     RTPrintf("CPU%d: Page file size         %-4d MB\n", 0, statVal);
    2536             }
    2537 
    2538             RTPrintf("\n");
    2539         }
    2540         else
    2541         {
    2542             if (details != VMINFO_MACHINEREADABLE)
    2543             {
    2544                 RTPrintf("[!] FAILED calling console->getGuest at line %d!\n", __LINE__);
    2545                 PRINT_RC_MESSAGE(rc);
    2546             }
    2547         }
    2548     }
    2549 
    2550     /*
    2551      * snapshots
    2552      */
    2553     ComPtr<ISnapshot> snapshot;
    2554     rc = machine->GetSnapshot(Guid(), snapshot.asOutParam());
    2555     if (SUCCEEDED(rc) && snapshot)
    2556     {
    2557         if (details != VMINFO_MACHINEREADABLE)
    2558             RTPrintf("Snapshots:\n\n");
    2559         showSnapshots(snapshot, details);
    2560     }
    2561 
    2562     if (details != VMINFO_MACHINEREADABLE)
    2563         RTPrintf("\n");
    2564     return S_OK;
    2565 }
    2566 
    2567 static int handleShowVMInfo(int argc, char *argv[],
    2568                             ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    2569 {
    2570     HRESULT rc;
    2571 
    2572     /* at least one option: the UUID or name of the VM */
    2573     if (argc < 1)
    2574         return errorSyntax(USAGE_SHOWVMINFO, "Incorrect number of parameters");
    2575 
    2576     /* try to find the given machine */
    2577     ComPtr <IMachine> machine;
    2578     Guid uuid (argv[0]);
    2579     if (!uuid.isEmpty())
    2580     {
    2581         CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
    2582     }
    2583     else
    2584     {
    2585         CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
    2586         if (SUCCEEDED (rc))
    2587             machine->COMGETTER(Id) (uuid.asOutParam());
    2588     }
    2589     if (FAILED (rc))
    2590         return 1;
    2591 
    2592     /* 2nd option can be -details, -statistics or -argdump */
    2593     VMINFO_DETAILS details = VMINFO_NONE;
    2594     bool fDetails = false;
    2595     bool fStatistics = false;
    2596     bool fMachinereadable = false;
    2597     for (int i=1;i<argc;i++)
    2598     {
    2599         if (!strcmp(argv[i], "-details"))
    2600             fDetails = true;
    2601         else
    2602         if (!strcmp(argv[i], "-statistics"))
    2603             fStatistics = true;
    2604         if (!strcmp(argv[1], "-machinereadable"))
    2605             fMachinereadable = true;
    2606     }
    2607     if (fMachinereadable)
    2608         details = VMINFO_MACHINEREADABLE;
    2609     else
    2610     if (fDetails && fStatistics)
    2611         details = VMINFO_FULL;
    2612     else
    2613     if (fDetails)
    2614         details = VMINFO_STANDARD;
    2615     else
    2616     if (fStatistics)
    2617         details = VMINFO_STATISTICS;
    2618 
    2619     ComPtr <IConsole> console;
    2620 
    2621     /* open an existing session for the VM */
    2622     rc = virtualBox->OpenExistingSession (session, uuid);
    2623     if (SUCCEEDED(rc))
    2624         /* get the session machine */
    2625         rc = session->COMGETTER(Machine)(machine.asOutParam());
    2626     if (SUCCEEDED(rc))
    2627         /* get the session console */
    2628         rc = session->COMGETTER(Console)(console.asOutParam());
    2629 
    2630     rc = showVMInfo (virtualBox, machine, console, details);
    2631 
    2632     if (console)
    2633         session->Close();
    2634 
    2635     return SUCCEEDED (rc) ? 0 : 1;
    2636 }
    2637 
    2638 
    2639 static int handleList(int argc, char *argv[],
    2640                       ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    2641 {
    2642     HRESULT rc = S_OK;
    2643 
    2644     /* exactly one option: the object */
    2645     if (argc != 1)
    2646         return errorSyntax(USAGE_LIST, "Incorrect number of parameters");
    2647 
    2648     /* which object? */
    2649     if (strcmp(argv[0], "vms") == 0)
    2650     {
    2651         /*
    2652          * Get the list of all registered VMs
    2653          */
    2654         com::SafeIfaceArray <IMachine> machines;
    2655         rc = virtualBox->COMGETTER(Machines2)(ComSafeArrayAsOutParam (machines));
    2656         if (SUCCEEDED(rc))
    2657         {
    2658             /*
    2659              * Iterate through the collection
    2660              */
    2661             for (size_t i = 0; i < machines.size(); ++ i)
    2662             {
    2663                 if (machines [i])
    2664                     rc = showVMInfo(virtualBox, machines [i]);
    2665             }
    2666         }
    2667     }
    2668     else
    2669     if (strcmp(argv[0], "runningvms") == 0)
    2670     {
    2671         /*
    2672          * Get the list of all _running_ VMs
    2673          */
    2674         com::SafeIfaceArray <IMachine> machines;
    2675         rc = virtualBox->COMGETTER(Machines2)(ComSafeArrayAsOutParam (machines));
    2676         if (SUCCEEDED(rc))
    2677         {
    2678             /*
    2679              * Iterate through the collection
    2680              */
    2681             for (size_t i = 0; i < machines.size(); ++ i)
    2682             {
    2683                 if (machines [i])
    2684                 {
    2685                     MachineState_T machineState;
    2686                     rc = machines [i]->COMGETTER(State)(&machineState);
    2687                     if (SUCCEEDED(rc))
    2688                     {
    2689                         switch (machineState)
    2690                         {
    2691                             case MachineState_Running:
    2692                             case MachineState_Paused:
    2693                                 {
    2694                                     Guid uuid;
    2695                                     rc = machines [i]->COMGETTER(Id) (uuid.asOutParam());
    2696                                     if (SUCCEEDED(rc))
    2697                                         RTPrintf ("%s\n", uuid.toString().raw());
    2698                                     break;
    2699                                 }
    2700                         }
    2701                     }
    2702                 }
    2703             }
    2704         }
    2705     }
    2706     else
    2707     if (strcmp(argv[0], "ostypes") == 0)
    2708     {
    2709         ComPtr<IGuestOSTypeCollection> coll;
    2710         ComPtr<IGuestOSTypeEnumerator> enumerator;
    2711         CHECK_ERROR(virtualBox, COMGETTER(GuestOSTypes)(coll.asOutParam()));
    2712         if (SUCCEEDED(rc) && coll)
    2713         {
    2714             CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
    2715             BOOL hasMore;
    2716             while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
    2717             {
    2718                 ComPtr<IGuestOSType> guestOS;
    2719                 CHECK_RC_BREAK(enumerator->GetNext(guestOS.asOutParam()));
    2720                 Bstr guestId;
    2721                 guestOS->COMGETTER(Id)(guestId.asOutParam());
    2722                 RTPrintf("ID:          %lS\n", guestId.raw());
    2723                 Bstr guestDescription;
    2724                 guestOS->COMGETTER(Description)(guestDescription.asOutParam());
    2725                 RTPrintf("Description: %lS\n\n", guestDescription.raw());
    2726             }
    2727         }
    2728     }
    2729     else
    2730     if (strcmp(argv[0], "hostdvds") == 0)
    2731     {
    2732         ComPtr<IHost> host;
    2733         CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    2734         ComPtr<IHostDVDDriveCollection> coll;
    2735         ComPtr<IHostDVDDriveEnumerator> enumerator;
    2736         CHECK_ERROR(host, COMGETTER(DVDDrives)(coll.asOutParam()));
    2737         if (SUCCEEDED(rc) && coll)
    2738         {
    2739             CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
    2740             BOOL hasMore;
    2741             while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
    2742             {
    2743                 ComPtr<IHostDVDDrive> dvdDrive;
    2744                 CHECK_RC_BREAK(enumerator->GetNext(dvdDrive.asOutParam()));
    2745                 Bstr name;
    2746                 dvdDrive->COMGETTER(Name)(name.asOutParam());
    2747                 RTPrintf("Name:        %lS\n\n", name.raw());
    2748             }
    2749         }
    2750     }
    2751     else
    2752     if (strcmp(argv[0], "hostfloppies") == 0)
    2753     {
    2754         ComPtr<IHost> host;
    2755         CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    2756         ComPtr<IHostFloppyDriveCollection> coll;
    2757         ComPtr<IHostFloppyDriveEnumerator> enumerator;
    2758         CHECK_ERROR(host, COMGETTER(FloppyDrives)(coll.asOutParam()));
    2759         if (SUCCEEDED(rc) && coll)
    2760         {
    2761             CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
    2762             BOOL hasMore;
    2763             while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
    2764             {
    2765                 ComPtr<IHostFloppyDrive> floppyDrive;
    2766                 CHECK_RC_BREAK(enumerator->GetNext(floppyDrive.asOutParam()));
    2767                 Bstr name;
    2768                 floppyDrive->COMGETTER(Name)(name.asOutParam());
    2769                 RTPrintf("Name:        %lS\n\n", name.raw());
    2770             }
    2771         }
    2772     }
    2773     else
    2774     if (strcmp(argv[0], "hostifs") == 0)
    2775     {
    2776         ComPtr<IHost> host;
    2777         CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    2778         ComPtr<IHostNetworkInterfaceCollection> coll;
    2779         ComPtr<IHostNetworkInterfaceEnumerator> enumerator;
    2780         CHECK_ERROR(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
    2781         if (SUCCEEDED(rc) && coll)
    2782         {
    2783             CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
    2784             BOOL hasMore;
    2785             while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
    2786             {
    2787                 ComPtr<IHostNetworkInterface> networkInterface;
    2788                 CHECK_RC_BREAK(enumerator->GetNext(networkInterface.asOutParam()));
    2789                 Bstr interfaceName;
    2790                 networkInterface->COMGETTER(Name)(interfaceName.asOutParam());
    2791                 RTPrintf("Name:        %lS\n", interfaceName.raw());
    2792                 Guid interfaceGuid;
    2793                 networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam());
    2794                 RTPrintf("GUID:        %lS\n\n", Bstr(interfaceGuid.toString()).raw());
    2795             }
    2796         }
    2797     }
    2798     else
    2799     if (strcmp(argv[0], "hostinfo") == 0)
    2800     {
    2801         ComPtr<IHost> Host;
    2802         CHECK_ERROR (virtualBox, COMGETTER(Host)(Host.asOutParam()));
    2803 
    2804         RTPrintf("Host Information:\n\n");
    2805 
    2806         LONG64 uTCTime = 0;
    2807         CHECK_ERROR (Host, COMGETTER(UTCTime)(&uTCTime));
    2808         RTTIMESPEC timeSpec;
    2809         RTTimeSpecSetMilli(&timeSpec, uTCTime);
    2810         char pszTime[30] = {0};
    2811         RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
    2812         RTPrintf("Host time: %s\n", pszTime);
    2813 
    2814         ULONG processorOnlineCount = 0;
    2815         CHECK_ERROR (Host, COMGETTER(ProcessorOnlineCount)(&processorOnlineCount));
    2816         RTPrintf("Processor online count: %lu\n", processorOnlineCount);
    2817         ULONG processorCount = 0;
    2818         CHECK_ERROR (Host, COMGETTER(ProcessorCount)(&processorCount));
    2819         RTPrintf("Processor count: %lu\n", processorCount);
    2820         ULONG processorSpeed = 0;
    2821         Bstr processorDescription;
    2822         for (ULONG i = 0; i < processorCount; i++)
    2823         {
    2824             CHECK_ERROR (Host, GetProcessorSpeed(i, &processorSpeed));
    2825             if (processorSpeed)
    2826                 RTPrintf("Processor#%u speed: %lu MHz\n", i, processorSpeed);
    2827             else
    2828                 RTPrintf("Processor#%u speed: unknown\n", i, processorSpeed);
    2829     #if 0 /* not yet implemented in Main */
    2830             CHECK_ERROR (Host, GetProcessorDescription(i, processorDescription.asOutParam()));
    2831             RTPrintf("Processor#%u description: %lS\n", i, processorDescription.raw());
    2832     #endif
    2833         }
    2834 
    2835     #if 0 /* not yet implemented in Main */
    2836         ULONG memorySize = 0;
    2837         CHECK_ERROR (Host, COMGETTER(MemorySize)(&memorySize));
    2838         RTPrintf("Memory size: %lu MByte\n", memorySize);
    2839 
    2840         ULONG memoryAvailable = 0;
    2841         CHECK_ERROR (Host, COMGETTER(MemoryAvailable)(&memoryAvailable));
    2842         RTPrintf("Memory available: %lu MByte\n", memoryAvailable);
    2843 
    2844         Bstr operatingSystem;
    2845         CHECK_ERROR (Host, COMGETTER(OperatingSystem)(operatingSystem.asOutParam()));
    2846         RTPrintf("Operating system: %lS\n", operatingSystem.raw());
    2847 
    2848         Bstr oSVersion;
    2849         CHECK_ERROR (Host, COMGETTER(OSVersion)(oSVersion.asOutParam()));
    2850         RTPrintf("Operating system version: %lS\n", oSVersion.raw());
    2851     #endif
    2852     }
    2853     else
    2854     if (strcmp(argv[0], "hddbackends") == 0)
    2855     {
    2856         ComPtr<ISystemProperties> systemProperties;
    2857         CHECK_ERROR(virtualBox,
    2858                     COMGETTER(SystemProperties) (systemProperties.asOutParam()));
    2859         com::SafeIfaceArray <IHardDiskFormat> hardDiskFormats;
    2860         CHECK_ERROR(systemProperties,
    2861                     COMGETTER(HardDiskFormats) (ComSafeArrayAsOutParam (hardDiskFormats)));
    2862 
    2863         RTPrintf("Supported hard disk backends:\n\n");
    2864         for (size_t i = 0; i < hardDiskFormats.size(); ++ i)
    2865         {
    2866             /* General information */
    2867             Bstr id;
    2868             CHECK_ERROR(hardDiskFormats [i],
    2869                         COMGETTER(Id) (id.asOutParam()));
    2870 
    2871             Bstr description;
    2872             CHECK_ERROR(hardDiskFormats [i],
    2873                         COMGETTER(Id) (description.asOutParam()));
    2874 
    2875             ULONG caps;
    2876             CHECK_ERROR(hardDiskFormats [i],
    2877                         COMGETTER(Capabilities) (&caps));
    2878 
    2879             RTPrintf("Backend %u: id='%ls' description='%ls' capabilities=%#06x extensions='",
    2880                      i, id.raw(), description.raw(), caps);
    2881 
    2882             /* File extensions */
    2883             com::SafeArray <BSTR> fileExtensions;
    2884             CHECK_ERROR(hardDiskFormats [i],
    2885                         COMGETTER(FileExtensions) (ComSafeArrayAsOutParam (fileExtensions)));
    2886             for (size_t a = 0; a < fileExtensions.size(); ++ a)
    2887             {
    2888                 RTPrintf ("%ls", Bstr (fileExtensions [a]).raw());
    2889                 if (a != fileExtensions.size()-1)
    2890                     RTPrintf (",");
    2891             }
    2892             RTPrintf ("'");
    2893 
    2894             /* Configuration keys */
    2895             com::SafeArray <BSTR> propertyNames;
    2896             com::SafeArray <BSTR> propertyDescriptions;
    2897             com::SafeArray <DataType_T> propertyTypes;
    2898             com::SafeArray <ULONG> propertyFlags;
    2899             com::SafeArray <BSTR> propertyDefaults;
    2900             CHECK_ERROR(hardDiskFormats [i],
    2901                         DescribeProperties (ComSafeArrayAsOutParam (propertyNames),
    2902                                             ComSafeArrayAsOutParam (propertyDescriptions),
    2903                                             ComSafeArrayAsOutParam (propertyTypes),
    2904                                             ComSafeArrayAsOutParam (propertyFlags),
    2905                                             ComSafeArrayAsOutParam (propertyDefaults)));
    2906 
    2907             RTPrintf (" properties=(");
    2908             if (propertyNames.size() > 0)
    2909             {
    2910                 for (size_t a = 0; a < propertyNames.size(); ++ a)
    2911                 {
    2912                     RTPrintf ("\n  name='%ls' desc='%ls' type=",
    2913                               Bstr (propertyNames [a]).raw(), Bstr (propertyDescriptions [a]).raw());
    2914                     switch (propertyTypes [a])
    2915                     {
    2916                         case DataType_Int32: RTPrintf ("int"); break;
    2917                         case DataType_Int8: RTPrintf ("byte"); break;
    2918                         case DataType_String: RTPrintf ("string"); break;
    2919                     }
    2920                     RTPrintf (" flags=%#04x", propertyFlags [a]);
    2921                     RTPrintf (" default='%ls'", Bstr (propertyDefaults [a]).raw());
    2922                     if (a != propertyNames.size()-1)
    2923                         RTPrintf (", ");
    2924                 }
    2925             }
    2926             RTPrintf (")\n");
    2927         }
    2928     }
    2929     else
    2930     if (strcmp(argv[0], "hdds") == 0)
    2931     {
    2932         com::SafeIfaceArray <IHardDisk2> hdds;
    2933         CHECK_ERROR(virtualBox, COMGETTER(HardDisks2)(ComSafeArrayAsOutParam (hdds)));
    2934         for (size_t i = 0; i < hdds.size(); ++ i)
    2935         {
    2936             ComPtr<IHardDisk2> hdd = hdds[i];
    2937             Guid uuid;
    2938             hdd->COMGETTER(Id)(uuid.asOutParam());
    2939             RTPrintf("UUID:         %s\n", uuid.toString().raw());
    2940             Bstr format;
    2941             hdd->COMGETTER(Format)(format.asOutParam());
    2942             RTPrintf("Format:       %lS\n", format.raw());
    2943             Bstr filepath;
    2944             hdd->COMGETTER(Location)(filepath.asOutParam());
    2945             RTPrintf("Location:     %lS\n", filepath.raw());
    2946             MediaState_T enmState;
    2947             /// @todo NEWMEDIA check accessibility of all parents
    2948             /// @todo NEWMEDIA print the full state value
    2949             hdd->COMGETTER(State)(&enmState);
    2950             RTPrintf("Accessible:   %s\n", enmState != MediaState_Inaccessible ? "yes" : "no");
    2951             com::SafeGUIDArray machineIds;
    2952             hdd->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
    2953             for (size_t j = 0; j < machineIds.size(); ++ j)
    2954             {
    2955                 ComPtr<IMachine> machine;
    2956                 CHECK_ERROR(virtualBox, GetMachine(machineIds[j], machine.asOutParam()));
    2957                 ASSERT(machine);
    2958                 Bstr name;
    2959                 machine->COMGETTER(Name)(name.asOutParam());
    2960                 machine->COMGETTER(Id)(uuid.asOutParam());
    2961                 RTPrintf("%s%lS (UUID: %RTuuid)\n",
    2962                          j == 0 ? "Usage:        " : "              ",
    2963                          name.raw(), &machineIds[j]);
    2964             }
    2965             /// @todo NEWMEDIA check usage in snapshots too
    2966             /// @todo NEWMEDIA also list children and say 'differencing' for
    2967             /// hard disks with the parent or 'base' otherwise.
    2968             RTPrintf("\n");
    2969         }
    2970     }
    2971     else
    2972     if (strcmp(argv[0], "dvds") == 0)
    2973     {
    2974         com::SafeIfaceArray<IDVDImage2> dvds;
    2975         CHECK_ERROR(virtualBox, COMGETTER(DVDImages)(ComSafeArrayAsOutParam(dvds)));
    2976         for (size_t i = 0; i < dvds.size(); ++ i)
    2977         {
    2978             ComPtr<IDVDImage2> dvdImage = dvds[i];
    2979             Guid uuid;
    2980             dvdImage->COMGETTER(Id)(uuid.asOutParam());
    2981             RTPrintf("UUID:       %s\n", uuid.toString().raw());
    2982             Bstr filePath;
    2983             dvdImage->COMGETTER(Location)(filePath.asOutParam());
    2984             RTPrintf("Path:       %lS\n", filePath.raw());
    2985             MediaState_T enmState;
    2986             dvdImage->COMGETTER(State)(&enmState);
    2987             RTPrintf("Accessible: %s\n", enmState != MediaState_Inaccessible ? "yes" : "no");
    2988             /** @todo usage */
    2989             RTPrintf("\n");
    2990         }
    2991     }
    2992     else
    2993     if (strcmp(argv[0], "floppies") == 0)
    2994     {
    2995         com::SafeIfaceArray<IFloppyImage2> floppies;
    2996         CHECK_ERROR(virtualBox, COMGETTER(FloppyImages)(ComSafeArrayAsOutParam(floppies)));
    2997         for (size_t i = 0; i < floppies.size(); ++ i)
    2998         {
    2999             ComPtr<IFloppyImage2> floppyImage = floppies[i];
    3000             Guid uuid;
    3001             floppyImage->COMGETTER(Id)(uuid.asOutParam());
    3002             RTPrintf("UUID:       %s\n", uuid.toString().raw());
    3003             Bstr filePath;
    3004             floppyImage->COMGETTER(Location)(filePath.asOutParam());
    3005             RTPrintf("Path:       %lS\n", filePath.raw());
    3006             MediaState_T enmState;
    3007             floppyImage->COMGETTER(State)(&enmState);
    3008             RTPrintf("Accessible: %s\n", enmState != MediaState_Inaccessible ? "yes" : "no");
    3009             /** @todo usage */
    3010             RTPrintf("\n");
    3011         }
    3012     }
    3013     else
    3014     if (strcmp(argv[0], "usbhost") == 0)
    3015     {
    3016         ComPtr<IHost> Host;
    3017         CHECK_ERROR_RET (virtualBox, COMGETTER(Host)(Host.asOutParam()), 1);
    3018 
    3019         ComPtr<IHostUSBDeviceCollection> CollPtr;
    3020         CHECK_ERROR_RET (Host, COMGETTER(USBDevices)(CollPtr.asOutParam()), 1);
    3021 
    3022         ComPtr<IHostUSBDeviceEnumerator> EnumPtr;
    3023         CHECK_ERROR_RET (CollPtr, Enumerate(EnumPtr.asOutParam()), 1);
    3024 
    3025         RTPrintf("Host USB Devices:\n\n");
    3026 
    3027         BOOL fMore = FALSE;
    3028         rc = EnumPtr->HasMore (&fMore);
    3029         ASSERT_RET (SUCCEEDED (rc), 1);
    3030 
    3031         if (!fMore)
    3032         {
    3033             RTPrintf("<none>\n\n");
    3034         }
    3035         else
    3036         while (fMore)
    3037         {
    3038             ComPtr <IHostUSBDevice> dev;
    3039             rc = EnumPtr->GetNext (dev.asOutParam());
    3040             ASSERT_RET (SUCCEEDED (rc), 1);
    3041 
    3042             /* Query info. */
    3043             Guid id;
    3044             CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), 1);
    3045             USHORT usVendorId;
    3046             CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), 1);
    3047             USHORT usProductId;
    3048             CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), 1);
    3049             USHORT bcdRevision;
    3050             CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), 1);
    3051 
    3052             RTPrintf("UUID:               %S\n"
    3053                      "VendorId:           0x%04x (%04X)\n"
    3054                      "ProductId:          0x%04x (%04X)\n"
    3055                      "Revision:           %u.%u (%02u%02u)\n",
    3056                      id.toString().raw(),
    3057                      usVendorId, usVendorId, usProductId, usProductId,
    3058                      bcdRevision >> 8, bcdRevision & 0xff,
    3059                      bcdRevision >> 8, bcdRevision & 0xff);
    3060 
    3061             /* optional stuff. */
    3062             Bstr bstr;
    3063             CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), 1);
    3064             if (!bstr.isEmpty())
    3065                 RTPrintf("Manufacturer:       %lS\n", bstr.raw());
    3066             CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), 1);
    3067             if (!bstr.isEmpty())
    3068                 RTPrintf("Product:            %lS\n", bstr.raw());
    3069             CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), 1);
    3070             if (!bstr.isEmpty())
    3071                 RTPrintf("SerialNumber:       %lS\n", bstr.raw());
    3072             CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), 1);
    3073             if (!bstr.isEmpty())
    3074                 RTPrintf("Address:            %lS\n", bstr.raw());
    3075 
    3076             /* current state  */
    3077             USBDeviceState_T state;
    3078             CHECK_ERROR_RET (dev, COMGETTER(State)(&state), 1);
    3079             const char *pszState = "?";
    3080             switch (state)
    3081             {
    3082                 case USBDeviceState_NotSupported:
    3083                     pszState = "Not supported"; break;
    3084                 case USBDeviceState_Unavailable:
    3085                     pszState = "Unavailable"; break;
    3086                 case USBDeviceState_Busy:
    3087                     pszState = "Busy"; break;
    3088                 case USBDeviceState_Available:
    3089                     pszState = "Available"; break;
    3090                 case USBDeviceState_Held:
    3091                     pszState = "Held"; break;
    3092                 case USBDeviceState_Captured:
    3093                     pszState = "Captured"; break;
    3094                 default:
    3095                     ASSERT (false);
    3096                     break;
    3097             }
    3098             RTPrintf("Current State:      %s\n\n", pszState);
    3099 
    3100             rc = EnumPtr->HasMore (&fMore);
    3101             ASSERT_RET (SUCCEEDED (rc), rc);
    3102         }
    3103     }
    3104     else
    3105     if (strcmp(argv[0], "usbfilters") == 0)
    3106     {
    3107         RTPrintf("Global USB Device Filters:\n\n");
    3108 
    3109         ComPtr <IHost> host;
    3110         CHECK_ERROR_RET (virtualBox, COMGETTER(Host) (host.asOutParam()), 1);
    3111 
    3112         ComPtr<IHostUSBDeviceFilterCollection> coll;
    3113         CHECK_ERROR_RET (host, COMGETTER (USBDeviceFilters)(coll.asOutParam()), 1);
    3114 
    3115         ComPtr<IHostUSBDeviceFilterEnumerator> en;
    3116         CHECK_ERROR_RET (coll, Enumerate(en.asOutParam()), 1);
    3117 
    3118         ULONG index = 0;
    3119         BOOL more = FALSE;
    3120         rc = en->HasMore (&more);
    3121         ASSERT_RET (SUCCEEDED (rc), 1);
    3122 
    3123         if (!more)
    3124         {
    3125             RTPrintf("<none>\n\n");
    3126         }
    3127         else
    3128         while (more)
    3129         {
    3130             ComPtr<IHostUSBDeviceFilter> flt;
    3131             rc = en->GetNext (flt.asOutParam());
    3132             ASSERT_RET (SUCCEEDED (rc), 1);
    3133 
    3134             /* Query info. */
    3135 
    3136             RTPrintf("Index:            %lu\n", index);
    3137 
    3138             BOOL active = FALSE;
    3139             CHECK_ERROR_RET (flt, COMGETTER (Active) (&active), 1);
    3140             RTPrintf("Active:           %s\n", active ? "yes" : "no");
    3141 
    3142             USBDeviceFilterAction_T action;
    3143             CHECK_ERROR_RET (flt, COMGETTER (Action) (&action), 1);
    3144             const char *pszAction = "<invalid>";
    3145             switch (action)
    3146             {
    3147                 case USBDeviceFilterAction_Ignore:
    3148                     pszAction = "Ignore";
    3149                     break;
    3150                 case USBDeviceFilterAction_Hold:
    3151                     pszAction = "Hold";
    3152                     break;
    3153                 default:
    3154                     break;
    3155             }
    3156             RTPrintf("Action:           %s\n", pszAction);
    3157 
    3158             Bstr bstr;
    3159             CHECK_ERROR_RET (flt, COMGETTER (Name) (bstr.asOutParam()), 1);
    3160             RTPrintf("Name:             %lS\n", bstr.raw());
    3161             CHECK_ERROR_RET (flt, COMGETTER (VendorId) (bstr.asOutParam()), 1);
    3162             RTPrintf("VendorId:         %lS\n", bstr.raw());
    3163             CHECK_ERROR_RET (flt, COMGETTER (ProductId) (bstr.asOutParam()), 1);
    3164             RTPrintf("ProductId:        %lS\n", bstr.raw());
    3165             CHECK_ERROR_RET (flt, COMGETTER (Revision) (bstr.asOutParam()), 1);
    3166             RTPrintf("Revision:         %lS\n", bstr.raw());
    3167             CHECK_ERROR_RET (flt, COMGETTER (Manufacturer) (bstr.asOutParam()), 1);
    3168             RTPrintf("Manufacturer:     %lS\n", bstr.raw());
    3169             CHECK_ERROR_RET (flt, COMGETTER (Product) (bstr.asOutParam()), 1);
    3170             RTPrintf("Product:          %lS\n", bstr.raw());
    3171             CHECK_ERROR_RET (flt, COMGETTER (SerialNumber) (bstr.asOutParam()), 1);
    3172             RTPrintf("Serial Number:    %lS\n\n", bstr.raw());
    3173 
    3174             rc = en->HasMore (&more);
    3175             ASSERT_RET (SUCCEEDED (rc), 1);
    3176 
    3177             index ++;
    3178         }
    3179     }
    3180     else if (strcmp(argv[0], "systemproperties") == 0)
    3181     {
    3182         ComPtr<ISystemProperties> systemProperties;
    3183         virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
    3184 
    3185         Bstr str;
    3186         ULONG ulValue;
    3187         ULONG64 ul64Value;
    3188         BOOL flag;
    3189 
    3190         systemProperties->COMGETTER(MinGuestRAM)(&ulValue);
    3191         RTPrintf("Minimum guest RAM size:      %u Megabytes\n", ulValue);
    3192         systemProperties->COMGETTER(MaxGuestRAM)(&ulValue);
    3193         RTPrintf("Maximum guest RAM size:      %u Megabytes\n", ulValue);
    3194         systemProperties->COMGETTER(MaxGuestVRAM)(&ulValue);
    3195         RTPrintf("Maximum video RAM size:      %u Megabytes\n", ulValue);
    3196         systemProperties->COMGETTER(MaxVDISize)(&ul64Value);
    3197         RTPrintf("Maximum VDI size:            %lu Megabytes\n", ul64Value);
    3198         systemProperties->COMGETTER(DefaultHardDiskFolder)(str.asOutParam());
    3199         RTPrintf("Default hard disk filder:    %lS\n", str.raw());
    3200         systemProperties->COMGETTER(DefaultMachineFolder)(str.asOutParam());
    3201         RTPrintf("Default machine folder:      %lS\n", str.raw());
    3202         systemProperties->COMGETTER(RemoteDisplayAuthLibrary)(str.asOutParam());
    3203         RTPrintf("VRDP authentication library: %lS\n", str.raw());
    3204         systemProperties->COMGETTER(WebServiceAuthLibrary)(str.asOutParam());
    3205         RTPrintf("Webservice auth. library:    %lS\n", str.raw());
    3206         systemProperties->COMGETTER(HWVirtExEnabled)(&flag);
    3207         RTPrintf("Hardware virt. extensions:   %s\n", flag ? "yes" : "no");
    3208         systemProperties->COMGETTER(LogHistoryCount)(&ulValue);
    3209         RTPrintf("Log history count:           %u\n", ulValue);
    3210 
    3211     }
    3212     else
    3213         return errorSyntax(USAGE_LIST, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
    3214 
    3215     return SUCCEEDED(rc) ? 0 : 1;
    3216 }
    3217 
    3218767static int handleRegisterVM(int argc, char *argv[],
    3219768                            ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r14259 r14555  
    2727#include <VBox/com/VirtualBox.h>
    2828#include <VBox/com/EventQueue.h>
     29#include <VBox/com/string.h>
    2930#endif /* !VBOX_ONLY_DOCS */
    3031
     
    112113 * Prototypes
    113114 */
     115/* VBoxManage.cpp */
    114116int errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...);
    115117int errorArgument(const char *pszFormat, ...);
     
    120122                           ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
    121123#endif /* !VBOX_ONLY_DOCS */
     124
     125/* VBoxManageGuestProp.cpp */
    122126extern void usageGuestProperty(void);
    123127#ifndef VBOX_ONLY_DOCS
    124128extern int handleGuestProperty(int argc, char *argv[],
    125129                               ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
     130
     131/* VBoxManageInfo.cpp */
     132void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const com::Bstr &prefix = "", int level = 0);
     133int handleShowVMInfo(int argc, char *argv[],
     134                     ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     135HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
     136                    ComPtr <IConsole> console = ComPtr <IConsole> (),
     137                    VMINFO_DETAILS details = VMINFO_NONE);
     138int handleList(int argc, char *argv[],
     139               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     140
     141/* VBoxManageVD.cpp */
     142/* VBoxManageUSB.cpp */
     143/* VBoxManageTODO.cpp */
     144
    126145#endif /* !VBOX_ONLY_DOCS */
    127146unsigned long VBoxSVNRev();
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r14551 r14555  
    2020 */
    2121
     22#ifndef VBOX_ONLY_DOCS
    2223
    2324/*******************************************************************************
    2425*   Header Files                                                               *
    2526*******************************************************************************/
    26 #ifndef VBOX_ONLY_DOCS
    2727#include <VBox/com/com.h>
    2828#include <VBox/com/string.h>
     
    3939#include <vector>
    4040#include <list>
    41 #endif /* !VBOX_ONLY_DOCS */
    4241
    4342#include <iprt/runtime.h>
     
    5857
    5958#include "VBoxManage.h"
    60 
    61 #ifndef VBOX_ONLY_DOCS
    6259using namespace com;
    6360
    64 /* missing XPCOM <-> COM wrappers */
    65 #ifndef STDMETHOD_
    66 # define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth
    67 #endif
    68 #ifndef NS_GET_IID
    69 # define NS_GET_IID(I) IID_##I
    70 #endif
    71 #ifndef RT_OS_WINDOWS
    72 #define IUnknown nsISupports
    73 #endif
    74 
    75 /** command handler type */
    76 typedef DECLCALLBACK(int) FNHANDLER(int argc, char *argv[], ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
    77 typedef FNHANDLER *PFNHANDLER;
    78 
    79 #ifdef USE_XPCOM_QUEUE
    80 /** A pointer to the event queue, set by main() before calling any handlers. */
    81 nsCOMPtr<nsIEventQueue> g_pEventQ;
    82 #endif
    83 
    84 /**
    85  * Quick IUSBDevice implementation for detaching / attaching
    86  * devices to the USB Controller.
    87  */
    88 class MyUSBDevice : public IUSBDevice
    89 {
    90 public:
    91     // public initializer/uninitializer for internal purposes only
    92     MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)
    93         :  m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),
    94            m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),
    95            m_bstrComment(a_pszComment),
    96            m_cRefs(0)
    97     {
    98     }
    99 
    100     STDMETHOD_(ULONG, AddRef)(void)
    101     {
    102         return ASMAtomicIncU32(&m_cRefs);
    103     }
    104     STDMETHOD_(ULONG, Release)(void)
    105     {
    106         ULONG cRefs = ASMAtomicDecU32(&m_cRefs);
    107         if (!cRefs)
    108             delete this;
    109         return cRefs;
    110     }
    111     STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)
    112     {
    113         Guid guid(iid);
    114         if (guid == Guid(NS_GET_IID(IUnknown)))
    115             *ppvObject = (IUnknown *)this;
    116         else if (guid == Guid(NS_GET_IID(IUSBDevice)))
    117             *ppvObject = (IUSBDevice *)this;
    118         else
    119             return E_NOINTERFACE;
    120         AddRef();
    121         return S_OK;
    122     }
    123 
    124     STDMETHOD(COMGETTER(Id))(GUIDPARAMOUT a_pId)                { return E_NOTIMPL; }
    125     STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId)       { *a_pusVendorId    = m_usVendorId;     return S_OK; }
    126     STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId)     { *a_pusProductId   = m_usProductId;    return S_OK; }
    127     STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision)       { *a_pusRevision    = m_bcdRevision;    return S_OK; }
    128     STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash;  return S_OK; }
    129     STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer)   { return E_NOTIMPL; }
    130     STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct)             { return E_NOTIMPL; }
    131     STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber)   { return E_NOTIMPL; }
    132     STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress)             { return E_NOTIMPL; }
    133 
    134 private:
    135     /** The vendor id of this USB device. */
    136     USHORT m_usVendorId;
    137     /** The product id of this USB device. */
    138     USHORT m_usProductId;
    139     /** The product revision number of this USB device.
    140      * (high byte = integer; low byte = decimal) */
    141     USHORT m_bcdRevision;
    142     /** The USB serial hash of the device. */
    143     uint64_t m_u64SerialHash;
    144     /** The user comment string. */
    145     Bstr     m_bstrComment;
    146     /** Reference counter. */
    147     uint32_t volatile m_cRefs;
    148 };
    149 
    150 
    151 // types
    152 ///////////////////////////////////////////////////////////////////////////////
    153 
    154 template <typename T>
    155 class Nullable
    156 {
    157 public:
    158 
    159     Nullable() : mIsNull (true) {}
    160     Nullable (const T &aValue, bool aIsNull = false)
    161         : mIsNull (aIsNull), mValue (aValue) {}
    162 
    163     bool isNull() const { return mIsNull; };
    164     void setNull (bool aIsNull = true) { mIsNull = aIsNull; }
    165 
    166     operator const T&() const { return mValue; }
    167 
    168     Nullable &operator= (const T &aValue)
    169     {
    170         mValue = aValue;
    171         mIsNull = false;
    172         return *this;
    173     }
    174 
    175 private:
    176 
    177     bool mIsNull;
    178     T mValue;
    179 };
    180 
    181 /** helper structure to encapsulate USB filter manipulation commands */
    182 struct USBFilterCmd
    183 {
    184     struct USBFilter
    185     {
    186         USBFilter ()
    187             : mAction (USBDeviceFilterAction_Null)
    188             {}
    189 
    190         Bstr mName;
    191         Nullable <bool> mActive;
    192         Bstr mVendorId;
    193         Bstr mProductId;
    194         Bstr mRevision;
    195         Bstr mManufacturer;
    196         Bstr mProduct;
    197         Bstr mRemote;
    198         Bstr mSerialNumber;
    199         Nullable <ULONG> mMaskedInterfaces;
    200         USBDeviceFilterAction_T mAction;
    201     };
    202 
    203     enum Action { Invalid, Add, Modify, Remove };
    204 
    205     USBFilterCmd() : mAction (Invalid), mIndex (0), mGlobal (false) {}
    206 
    207     Action mAction;
    208     ULONG mIndex;
    209     /** flag whether the command target is a global filter */
    210     bool mGlobal;
    211     /** machine this command is targeted at (null for global filters) */
    212     ComPtr<IMachine> mMachine;
    213     USBFilter mFilter;
    214 };
    215 #endif /* !VBOX_ONLY_DOCS */
    21661
    21762// funcs
    21863///////////////////////////////////////////////////////////////////////////////
    21964
    220 static void showLogo(void)
    221 {
    222     static bool fShown; /* show only once */
    223 
    224     if (!fShown)
    225     {
    226         RTPrintf("VirtualBox Command Line Management Interface Version "
    227                  VBOX_VERSION_STRING  "\n"
    228                  "(C) 2005-2008 Sun Microsystems, Inc.\n"
    229                  "All rights reserved.\n"
    230                  "\n");
    231         fShown = true;
    232     }
    233 }
    234 
    235 static void printUsage(USAGECATEGORY u64Cmd)
    236 {
    237 #ifdef RT_OS_LINUX
    238     bool fLinux = true;
    239 #else
    240     bool fLinux = false;
    241 #endif
    242 #ifdef RT_OS_WINDOWS
    243     bool fWin = true;
    244 #else
    245     bool fWin = false;
    246 #endif
    247 #ifdef RT_OS_SOLARIS
    248     bool fSolaris = true;
    249 #else
    250     bool fSolaris = false;
    251 #endif
    252 #ifdef RT_OS_DARWIN
    253     bool fDarwin = true;
    254 #else
    255     bool fDarwin = false;
    256 #endif
    257 #ifdef VBOX_WITH_VRDP
    258     bool fVRDP = true;
    259 #else
    260     bool fVRDP = false;
    261 #endif
    262 
    263     if (u64Cmd == USAGE_DUMPOPTS)
    264     {
    265         fLinux = true;
    266         fWin = true;
    267         fSolaris = true;
    268         fDarwin = true;
    269         fVRDP = true;
    270         u64Cmd = USAGE_ALL;
    271     }
    272 
    273     RTPrintf("Usage:\n"
    274              "\n");
    275 
    276     if (u64Cmd == USAGE_ALL)
    277     {
    278         RTPrintf("VBoxManage [-v|-version]    print version number and exit\n"
    279                  "VBoxManage -nologo ...      suppress the logo\n"
    280                  "\n"
    281                  "VBoxManage -convertSettings ...        allow to auto-convert settings files\n"
    282                  "VBoxManage -convertSettingsBackup ...  allow to auto-convert settings files\n"
    283                  "                                       but create backup copies before\n"
    284                  "VBoxManage -convertSettingsIgnore ...  allow to auto-convert settings files\n"
    285                  "                                       but don't explicitly save the results\n"
    286                  "\n");
    287     }
    288 
    289     if (u64Cmd & USAGE_LIST)
    290     {
    291         RTPrintf("VBoxManage list             vms|runningvms|ostypes|hostdvds|hostfloppies|\n"
    292                  "                            hostifs|hostinfo|hddbackends|hdds|dvds|floppies|\n"
    293                  "                            usbhost|usbfilters|systemproperties\n"
    294                  "\n");
    295     }
    296 
    297     if (u64Cmd & USAGE_SHOWVMINFO)
    298     {
    299         RTPrintf("VBoxManage showvminfo       <uuid>|<name>\n"
    300                  "                            [-details]\n"
    301                  "                            [-statistics]\n"
    302                  "                            [-machinereadable]\n"
    303                  "\n");
    304     }
    305 
    306     if (u64Cmd & USAGE_REGISTERVM)
    307     {
    308         RTPrintf("VBoxManage registervm       <filename>\n"
    309                  "\n");
    310     }
    311 
    312     if (u64Cmd & USAGE_UNREGISTERVM)
    313     {
    314         RTPrintf("VBoxManage unregistervm     <uuid>|<name>\n"
    315                  "                            [-delete]\n"
    316                  "\n");
    317     }
    318 
    319     if (u64Cmd & USAGE_CREATEVM)
    320     {
    321         RTPrintf("VBoxManage createvm         -name <name>\n"
    322                  "                            [-register]\n"
    323                  "                            [-basefolder <path> | -settingsfile <path>]\n"
    324                  "                            [-uuid <uuid>]\n"
    325                  "                            \n"
    326                  "\n");
    327     }
    328 
    329     if (u64Cmd & USAGE_MODIFYVM)
    330     {
    331         RTPrintf("VBoxManage modifyvm         <uuid|name>\n"
    332                  "                            [-name <name>]\n"
    333                  "                            [-ostype <ostype>]\n"
    334                  "                            [-memory <memorysize>]\n"
    335                  "                            [-vram <vramsize>]\n"
    336                  "                            [-acpi on|off]\n"
    337                  "                            [-ioapic on|off]\n"
    338                  "                            [-pae on|off]\n"
    339                  "                            [-hwvirtex on|off|default]\n"
    340                  "                            [-nestedpaging on|off]\n"
    341                  "                            [-vtxvpid on|off]\n"
    342                  "                            [-monitorcount <number>]\n"
    343                  "                            [-accelerate3d <on|off>]\n"
    344                  "                            [-bioslogofadein on|off]\n"
    345                  "                            [-bioslogofadeout on|off]\n"
    346                  "                            [-bioslogodisplaytime <msec>]\n"
    347                  "                            [-bioslogoimagepath <imagepath>]\n"
    348                  "                            [-biosbootmenu disabled|menuonly|messageandmenu]\n"
    349                  "                            [-biossystemtimeoffset <msec>]\n"
    350                  "                            [-biospxedebug on|off]\n"
    351                  "                            [-boot<1-4> none|floppy|dvd|disk|net>]\n"
    352                  "                            [-hd<a|b|d> none|<uuid>|<filename>]\n"
    353                  "                            [-idecontroller PIIX3|PIIX4]\n"
    354 #ifdef VBOX_WITH_AHCI
    355                  "                            [-sata on|off]\n"
    356                  "                            [-sataportcount <1-30>]\n"
    357                  "                            [-sataport<1-30> none|<uuid>|<filename>]\n"
    358                  "                            [-sataideemulation<1-4> <1-30>]\n"
    359 #endif
    360                  "                            [-dvd none|<uuid>|<filename>|host:<drive>]\n"
    361                  "                            [-dvdpassthrough on|off]\n"
    362                  "                            [-floppy disabled|empty|<uuid>|\n"
    363                  "                                     <filename>|host:<drive>]\n"
    364                  "                            [-nic<1-N> none|null|nat|hostif|intnet]\n"
    365                  "                            [-nictype<1-N> Am79C970A|Am79C973"
    366 #ifdef VBOX_WITH_E1000
    367                                                                               "|82540EM|82543GC"
    368 #endif
    369                  "]\n"
    370                  "                            [-cableconnected<1-N> on|off]\n"
    371                  "                            [-nictrace<1-N> on|off]\n"
    372                  "                            [-nictracefile<1-N> <filename>]\n"
    373                  "                            [-nicspeed<1-N> <kbps>]\n"
    374                  "                            [-hostifdev<1-N> none|<devicename>]\n"
    375                  "                            [-intnet<1-N> <network name>]\n"
    376                  "                            [-natnet<1-N> <network>|default]\n"
    377                  "                            [-macaddress<1-N> auto|<mac>]\n"
    378                  "                            [-uart<1-N> off|<I/O base> <IRQ>]\n"
    379                  "                            [-uartmode<1-N> disconnected|\n"
    380                  "                                            server <pipe>|\n"
    381                  "                                            client <pipe>|\n"
    382                  "                                            <devicename>]\n"
    383 #ifdef VBOX_WITH_MEM_BALLOONING
    384                  "                            [-guestmemoryballoon <balloonsize>]\n"
    385 #endif
    386                  "                            [-gueststatisticsinterval <seconds>]\n"
    387                  );
    388         if (fLinux)
    389         {
    390             RTPrintf("                            [-tapsetup<1-N> none|<application>]\n"
    391                      "                            [-tapterminate<1-N> none|<application>]\n");
    392         }
    393         RTPrintf("                            [-audio none|null");
    394         if (fWin)
    395         {
    396 #ifdef VBOX_WITH_WINMM
    397             RTPrintf(                        "|winmm|dsound");
    398 #else
    399             RTPrintf(                        "|dsound");
    400 #endif
    401         }
    402         if (fSolaris)
    403         {
    404             RTPrintf(                        "|solaudio");
    405         }
    406         if (fLinux)
    407         {
    408             RTPrintf(                        "|oss"
    409 #ifdef VBOX_WITH_ALSA
    410                                              "|alsa"
    411 #endif
    412 #ifdef VBOX_WITH_PULSE
    413                                              "|pulse"
    414 #endif
    415                                              );
    416         }
    417         if (fDarwin)
    418         {
    419             RTPrintf(                        "|coreaudio");
    420         }
    421         RTPrintf(                            "]\n");
    422         RTPrintf("                            [-audiocontroller ac97|sb16]\n"
    423                  "                            [-clipboard disabled|hosttoguest|guesttohost|\n"
    424                  "                                        bidirectional]\n");
    425         if (fVRDP)
    426         {
    427             RTPrintf("                            [-vrdp on|off]\n"
    428                      "                            [-vrdpport default|<port>]\n"
    429                      "                            [-vrdpaddress <host>]\n"
    430                      "                            [-vrdpauthtype null|external|guest]\n"
    431                      "                            [-vrdpmulticon on|off]\n"
    432                      "                            [-vrdpreusecon on|off]\n");
    433         }
    434         RTPrintf("                            [-usb on|off]\n"
    435                  "                            [-usbehci on|off]\n"
    436                  "                            [-snapshotfolder default|<path>]\n");
    437         RTPrintf("\n");
    438     }
    439 
    440     if (u64Cmd & USAGE_STARTVM)
    441     {
    442         RTPrintf("VBoxManage startvm          <uuid>|<name>\n");
    443         if (fVRDP)
    444             RTPrintf("                            [-type gui|vrdp]\n");
    445         RTPrintf("\n");
    446     }
    447 
    448     if (u64Cmd & USAGE_CONTROLVM)
    449     {
    450         RTPrintf("VBoxManage controlvm        <uuid>|<name>\n"
    451                  "                            pause|resume|reset|poweroff|savestate|\n"
    452                  "                            acpipowerbutton|acpisleepbutton|\n"
    453                  "                            keyboardputscancode <hex> [<hex> ...]|\n"
    454                  "                            injectnmi|\n"
    455                  "                            setlinkstate<1-4> on|off |\n"
    456                  "                            usbattach <uuid>|<address> |\n"
    457                  "                            usbdetach <uuid>|<address> |\n"
    458                  "                            dvdattach none|<uuid>|<filename>|host:<drive> |\n"
    459                  "                            floppyattach none|<uuid>|<filename>|host:<drive> |\n"
    460                  "                            setvideomodehint <xres> <yres> <bpp> [display]|\n"
    461                  "                            setcredentials <username> <password> <domain>\n"
    462                  "                                           [-allowlocallogon <yes|no>]\n"
    463                  "\n");
    464     }
    465 
    466     if (u64Cmd & USAGE_DISCARDSTATE)
    467     {
    468         RTPrintf("VBoxManage discardstate     <uuid>|<name>\n"
    469                  "\n");
    470     }
    471 
    472     if (u64Cmd & USAGE_ADOPTSTATE)
    473     {
    474         RTPrintf("VBoxManage adoptstate       <uuid>|<name> <state_file>\n"
    475                  "\n");
    476     }
    477 
    478     if (u64Cmd & USAGE_SNAPSHOT)
    479     {
    480         RTPrintf("VBoxManage snapshot         <uuid>|<name>\n"
    481                  "                            take <name> [-desc <desc>] |\n"
    482                  "                            discard <uuid>|<name> |\n"
    483                  "                            discardcurrent -state|-all |\n"
    484                  "                            edit <uuid>|<name>|-current\n"
    485                  "                                 [-newname <name>]\n"
    486                  "                                 [-newdesc <desc>] |\n"
    487                  "                            showvminfo <uuid>|<name>\n"
    488                  "\n");
    489     }
    490 
    491     if (u64Cmd & USAGE_REGISTERIMAGE)
    492     {
    493         RTPrintf("VBoxManage openmedium       disk|dvd|floppy <filename>\n"
    494                  "                            [-type normal|immutable|writethrough] (disk only)\n"
    495                  "\n");
    496     }
    497 
    498     if (u64Cmd & USAGE_UNREGISTERIMAGE)
    499     {
    500         RTPrintf("VBoxManage closemedium      disk|dvd|floppy <uuid>|<filename>\n"
    501                  "\n");
    502     }
    503 
    504     if (u64Cmd & USAGE_SHOWHDINFO)
    505     {
    506         RTPrintf("VBoxManage showhdinfo       <uuid>|<filename>\n"
    507                  "\n");
    508     }
    509 
    510     if (u64Cmd & USAGE_CREATEHD)
    511     {
    512         /// @todo NEWMEDIA add -format to specify the hard disk backend
    513         RTPrintf("VBoxManage createhd         -filename <filename>\n"
    514                  "                            -size <megabytes>\n"
    515                  "                            [-static]\n"
    516                  "                            [-comment <comment>]\n"
    517                  "                            [-register]\n"
    518                  "                            [-type normal|writethrough] (default: normal)\n"
    519                  "\n");
    520     }
    521 
    522     if (u64Cmd & USAGE_MODIFYHD)
    523     {
    524         RTPrintf("VBoxManage modifyhd         <uuid>|<filename>\n"
    525                  "                            settype normal|writethrough|immutable |\n"
    526                  "                            compact\n"
    527                  "\n");
    528     }
    529 
    530     if (u64Cmd & USAGE_CLONEHD)
    531     {
    532         RTPrintf("VBoxManage clonehd          <uuid>|<filename> <outputfile>\n"
    533                  "\n");
    534     }
    535 
    536     if (u64Cmd & USAGE_CONVERTDD)
    537     {
    538         RTPrintf("VBoxManage convertdd        [-static] <filename> <outputfile>\n"
    539                  "VBoxManage convertdd        [-static] stdin <outputfile> <bytes>\n"
    540                  "\n");
    541     }
    542 
    543     if (u64Cmd & USAGE_ADDISCSIDISK)
    544     {
    545         RTPrintf("VBoxManage addiscsidisk     -server <name>|<ip>\n"
    546                  "                            -target <target>\n"
    547                  "                            [-port <port>]\n"
    548                  "                            [-lun <lun>]\n"
    549                  "                            [-encodedlun <lun>]\n"
    550                  "                            [-username <username>]\n"
    551                  "                            [-password <password>]\n"
    552                  "                            [-comment <comment>]\n"
    553                  "\n");
    554     }
    555 
    556     if (u64Cmd & USAGE_CREATEHOSTIF && fWin)
    557     {
    558         RTPrintf("VBoxManage createhostif     <name>\n"
    559                  "\n");
    560     }
    561 
    562     if (u64Cmd & USAGE_REMOVEHOSTIF && fWin)
    563     {
    564         RTPrintf("VBoxManage removehostif     <uuid>|<name>\n"
    565                  "\n");
    566     }
    567 
    568     if (u64Cmd & USAGE_GETEXTRADATA)
    569     {
    570         RTPrintf("VBoxManage getextradata     global|<uuid>|<name>\n"
    571                  "                            <key>|enumerate\n"
    572                  "\n");
    573     }
    574 
    575     if (u64Cmd & USAGE_SETEXTRADATA)
    576     {
    577         RTPrintf("VBoxManage setextradata     global|<uuid>|<name>\n"
    578                  "                            <key>\n"
    579                  "                            [<value>] (no value deletes key)\n"
    580                  "\n");
    581     }
    582 
    583     if (u64Cmd & USAGE_SETPROPERTY)
    584     {
    585         RTPrintf("VBoxManage setproperty      hdfolder default|<folder> |\n"
    586                  "                            machinefolder default|<folder> |\n"
    587                  "                            vrdpauthlibrary default|<library> |\n"
    588                  "                            websrvauthlibrary default|null|<library> |\n"
    589                  "                            hwvirtexenabled yes|no\n"
    590                  "                            loghistorycount <value>\n"
    591                  "\n");
    592     }
    593 
    594     if (u64Cmd & USAGE_USBFILTER_ADD)
    595     {
    596         RTPrintf("VBoxManage usbfilter        add <index,0-N>\n"
    597                  "                            -target <uuid>|<name>|global\n"
    598                  "                            -name <string>\n"
    599                  "                            -action ignore|hold (global filters only)\n"
    600                  "                            [-active yes|no] (yes)\n"
    601                  "                            [-vendorid <XXXX>] (null)\n"
    602                  "                            [-productid <XXXX>] (null)\n"
    603                  "                            [-revision <IIFF>] (null)\n"
    604                  "                            [-manufacturer <string>] (null)\n"
    605                  "                            [-product <string>] (null)\n"
    606                  "                            [-remote yes|no] (null, VM filters only)\n"
    607                  "                            [-serialnumber <string>] (null)\n"
    608                  "                            [-maskedinterfaces <XXXXXXXX>]\n"
    609                  "\n");
    610     }
    611 
    612     if (u64Cmd & USAGE_USBFILTER_MODIFY)
    613     {
    614         RTPrintf("VBoxManage usbfilter        modify <index,0-N>\n"
    615                  "                            -target <uuid>|<name>|global\n"
    616                  "                            [-name <string>]\n"
    617                  "                            [-action ignore|hold] (global filters only)\n"
    618                  "                            [-active yes|no]\n"
    619                  "                            [-vendorid <XXXX>|\"\"]\n"
    620                  "                            [-productid <XXXX>|\"\"]\n"
    621                  "                            [-revision <IIFF>|\"\"]\n"
    622                  "                            [-manufacturer <string>|\"\"]\n"
    623                  "                            [-product <string>|\"\"]\n"
    624                  "                            [-remote yes|no] (null, VM filters only)\n"
    625                  "                            [-serialnumber <string>|\"\"]\n"
    626                  "                            [-maskedinterfaces <XXXXXXXX>]\n"
    627                  "\n");
    628     }
    629 
    630     if (u64Cmd & USAGE_USBFILTER_REMOVE)
    631     {
    632         RTPrintf("VBoxManage usbfilter        remove <index,0-N>\n"
    633                  "                            -target <uuid>|<name>|global\n"
    634                  "\n");
    635     }
    636 
    637     if (u64Cmd & USAGE_SHAREDFOLDER_ADD)
    638     {
    639         RTPrintf("VBoxManage sharedfolder     add <vmname>|<uuid>\n"
    640                  "                            -name <name> -hostpath <hostpath>\n"
    641                  "                            [-transient] [-readonly]\n"
    642                  "\n");
    643     }
    644 
    645     if (u64Cmd & USAGE_SHAREDFOLDER_REMOVE)
    646     {
    647         RTPrintf("VBoxManage sharedfolder     remove <vmname>|<uuid>\n"
    648                  "                            -name <name> [-transient]\n"
    649                  "\n");
    650     }
    651 
    652     if (u64Cmd & USAGE_VM_STATISTICS)
    653     {
    654         RTPrintf("VBoxManage vmstatistics     <vmname>|<uuid> [-reset]\n"
    655                  "                            [-pattern <pattern>] [-descriptions]\n"
    656                  "\n");
    657     }
    658 
    659 #ifdef VBOX_WITH_GUEST_PROPS
    660     if (u64Cmd & USAGE_GUESTPROPERTY)
    661         usageGuestProperty();
    662 #endif /* VBOX_WITH_GUEST_PROPS defined */
    663 
    664     if (u64Cmd & USAGE_METRICS)
    665     {
    666         RTPrintf("VBoxManage metrics          list [*|host|<vmname> [<metric_list>]] (comma-separated)\n\n"
    667                  "VBoxManage metrics          setup\n"
    668                  "                            [-period <seconds>]\n"
    669                  "                            [-samples <count>]\n"
    670                  "                            [-list]\n"
    671                  "                            [*|host|<vmname> [<metric_list>]]\n\n"
    672                  "VBoxManage metrics          query [*|host|<vmname> [<metric_list>]]\n\n"
    673                  "VBoxManage metrics          collect\n"
    674                  "                            [-period <seconds>]\n"
    675                  "                            [-samples <count>]\n"
    676                  "                            [-list]\n"
    677                  "                            [-detach]\n"
    678                  "                            [*|host|<vmname> [<metric_list>]]\n"
    679                  "\n");
    680     }
    681 
    682 }
    683 
    684 /**
    685  * Print a usage synopsis and the syntax error message.
    686  */
    687 int errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...)
    688 {
    689     va_list args;
    690     showLogo(); // show logo even if suppressed
    691 #ifndef VBOX_ONLY_DOCS
    692     if (g_fInternalMode)
    693         printUsageInternal(u64Cmd);
    694     else
    695         printUsage(u64Cmd);
    696 #endif /* !VBOX_ONLY_DOCS */
    697     va_start(args, pszFormat);
    698     RTPrintf("\n"
    699              "Syntax error: %N\n", pszFormat, &args);
    700     va_end(args);
    701     return 1;
    702 }
    703 
    704 /**
    705  * Print an error message without the syntax stuff.
    706  */
    707 int errorArgument(const char *pszFormat, ...)
    708 {
    709     va_list args;
    710     va_start(args, pszFormat);
    711     RTPrintf("error: %N\n", pszFormat, &args);
    712     va_end(args);
    713     return 1;
    714 }
    715 
    716 #ifndef VBOX_ONLY_DOCS
    717 /**
    718  * Print out progress on the console
    719  */
    720 static void showProgress(ComPtr<IProgress> progress)
    721 {
    722     BOOL fCompleted;
    723     LONG currentPercent;
    724     LONG lastPercent = 0;
    725 
    726     RTPrintf("0%%...");
    727     RTStrmFlush(g_pStdOut);
    728     while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
    729     {
    730         progress->COMGETTER(Percent(&currentPercent));
    731 
    732         /* did we cross a 10% mark? */
    733         if (((currentPercent / 10) > (lastPercent / 10)))
    734         {
    735             /* make sure to also print out missed steps */
    736             for (LONG curVal = (lastPercent / 10) * 10 + 10; curVal <= (currentPercent / 10) * 10; curVal += 10)
    737             {
    738                 if (curVal < 100)
    739                 {
    740                     RTPrintf("%ld%%...", curVal);
    741                     RTStrmFlush(g_pStdOut);
    742                 }
    743             }
    744             lastPercent = (currentPercent / 10) * 10;
    745         }
    746         if (fCompleted)
    747             break;
    748 
    749         /* make sure the loop is not too tight */
    750         progress->WaitForCompletion(100);
    751     }
    752 
    753     /* complete the line. */
    754     HRESULT rc;
    755     if (SUCCEEDED(progress->COMGETTER(ResultCode)(&rc)))
    756     {
    757         if (SUCCEEDED(rc))
    758             RTPrintf("100%%\n");
    759         else
    760             RTPrintf("FAILED\n");
    761     }
    762     else
    763         RTPrintf("\n");
    764     RTStrmFlush(g_pStdOut);
    765 }
    766 
    767 static void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const Bstr &prefix = "", int level = 0)
     65
     66
     67void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const Bstr &prefix /* = ""*/, int level /*= 0*/)
    76868{
    76969    /* start with the root */
     
    826126}
    827127
    828 static HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
    829                            ComPtr <IConsole> console = ComPtr <IConsole> (),
    830                            VMINFO_DETAILS details = VMINFO_NONE)
     128HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
     129                    ComPtr <IConsole> console /*= ComPtr <IConsole> ()*/,
     130                    VMINFO_DETAILS details /*= VMINFO_NONE*/)
    831131{
    832132    HRESULT rc;
     
    1167467    }
    1168468
    1169     /* 
     469    /*
    1170470     * SATA Hard disks
    1171471     */
     
    25651865}
    25661866
    2567 static int handleShowVMInfo(int argc, char *argv[],
    2568                             ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     1867int handleShowVMInfo(int argc, char *argv[],
     1868                     ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    25691869{
    25701870    HRESULT rc;
     
    26361936}
    26371937
    2638 
    2639 static int handleList(int argc, char *argv[],
    2640                       ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     1938int handleList(int argc, char *argv[],
     1939               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    26411940{
    26421941    HRESULT rc = S_OK;
     
    32162515}
    32172516
    3218 static int handleRegisterVM(int argc, char *argv[],
    3219                             ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3220 {
    3221     HRESULT rc;
    3222 
    3223     if (argc != 1)
    3224         return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");
    3225 
    3226     ComPtr<IMachine> machine;
    3227     CHECK_ERROR(virtualBox, OpenMachine(Bstr(argv[0]), machine.asOutParam()));
    3228     if (SUCCEEDED(rc))
    3229     {
    3230         ASSERT(machine);
    3231         CHECK_ERROR(virtualBox, RegisterMachine(machine));
    3232     }
    3233     return SUCCEEDED(rc) ? 0 : 1;
    3234 }
    3235 
    3236 static int handleUnregisterVM(int argc, char *argv[],
    3237                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3238 {
    3239     HRESULT rc;
    3240 
    3241     if ((argc != 1) && (argc != 2))
    3242         return errorSyntax(USAGE_UNREGISTERVM, "Incorrect number of parameters");
    3243 
    3244     ComPtr<IMachine> machine;
    3245     /* assume it's a UUID */
    3246     rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    3247     if (FAILED(rc) || !machine)
    3248     {
    3249         /* must be a name */
    3250         CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    3251     }
    3252     if (machine)
    3253     {
    3254         Guid uuid;
    3255         machine->COMGETTER(Id)(uuid.asOutParam());
    3256         machine = NULL;
    3257         CHECK_ERROR(virtualBox, UnregisterMachine(uuid, machine.asOutParam()));
    3258         if (SUCCEEDED(rc) && machine)
    3259         {
    3260             /* are we supposed to delete the config file? */
    3261             if ((argc == 2) && (strcmp(argv[1], "-delete") == 0))
    3262             {
    3263                 CHECK_ERROR(machine, DeleteSettings());
    3264             }
    3265         }
    3266     }
    3267     return SUCCEEDED(rc) ? 0 : 1;
    3268 }
    3269 
    3270 static int handleCreateHardDisk(int argc, char *argv[],
    3271                                 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3272 {
    3273     HRESULT rc;
    3274     Bstr filename;
    3275     uint64_t sizeMB = 0;
    3276     bool fStatic = false;
    3277     Bstr comment;
    3278     bool fRegister = false;
    3279     const char *type = "normal";
    3280 
    3281     /* let's have a closer look at the arguments */
    3282     for (int i = 0; i < argc; i++)
    3283     {
    3284         if (strcmp(argv[i], "-filename") == 0)
    3285         {
    3286             if (argc <= i + 1)
    3287                 return errorArgument("Missing argument to '%s'", argv[i]);
    3288             i++;
    3289             filename = argv[i];
    3290         }
    3291         else if (strcmp(argv[i], "-size") == 0)
    3292         {
    3293             if (argc <= i + 1)
    3294                 return errorArgument("Missing argument to '%s'", argv[i]);
    3295             i++;
    3296             sizeMB = RTStrToUInt64(argv[i]);
    3297         }
    3298         else if (strcmp(argv[i], "-static") == 0)
    3299         {
    3300             fStatic = true;
    3301         }
    3302         else if (strcmp(argv[i], "-comment") == 0)
    3303         {
    3304             if (argc <= i + 1)
    3305                 return errorArgument("Missing argument to '%s'", argv[i]);
    3306             i++;
    3307             comment = argv[i];
    3308         }
    3309         else if (strcmp(argv[i], "-register") == 0)
    3310         {
    3311             fRegister = true;
    3312         }
    3313         else if (strcmp(argv[i], "-type") == 0)
    3314         {
    3315             if (argc <= i + 1)
    3316                 return errorArgument("Missing argument to '%s'", argv[i]);
    3317             i++;
    3318             type = argv[i];
    3319         }
    3320         else
    3321             return errorSyntax(USAGE_CREATEHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    3322     }
    3323     /* check the outcome */
    3324     if (!filename || (sizeMB == 0))
    3325         return errorSyntax(USAGE_CREATEHD, "Parameters -filename and -size are required");
    3326 
    3327     if (strcmp(type, "normal") && strcmp(type, "writethrough"))
    3328         return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
    3329 
    3330     ComPtr<IHardDisk2> hardDisk;
    3331     CHECK_ERROR(virtualBox, CreateHardDisk2(Bstr("VDI"), filename, hardDisk.asOutParam()));
    3332     if (SUCCEEDED(rc) && hardDisk)
    3333     {
    3334         /* we will close the hard disk after the storage has been successfully
    3335          * created unless fRegister is set */
    3336         bool doClose = false;
    3337 
    3338         CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
    3339         ComPtr<IProgress> progress;
    3340         if (fStatic)
    3341         {
    3342             CHECK_ERROR(hardDisk, CreateFixedStorage(sizeMB, progress.asOutParam()));
    3343         }
    3344         else
    3345         {
    3346             CHECK_ERROR(hardDisk, CreateDynamicStorage(sizeMB, progress.asOutParam()));
    3347         }
    3348         if (SUCCEEDED(rc) && progress)
    3349         {
    3350             if (fStatic)
    3351                 showProgress(progress);
    3352             else
    3353                 CHECK_ERROR(progress, WaitForCompletion(-1));
    3354             if (SUCCEEDED(rc))
    3355             {
    3356                 progress->COMGETTER(ResultCode)(&rc);
    3357                 if (FAILED(rc))
    3358                 {
    3359                     com::ProgressErrorInfo info(progress);
    3360                     if (info.isBasicAvailable())
    3361                         RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());
    3362                     else
    3363                         RTPrintf("Error: failed to create hard disk. No error message available!\n");
    3364                 }
    3365                 else
    3366                 {
    3367                     doClose = !fRegister;
    3368 
    3369                     Guid uuid;
    3370                     CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
    3371 
    3372                     if (strcmp(type, "normal") == 0)
    3373                     {
    3374                         /* nothing required, default */
    3375                     }
    3376                     else if (strcmp(type, "writethrough") == 0)
    3377                     {
    3378                         CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
    3379                     }
    3380 
    3381                     RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
    3382                 }
    3383             }
    3384         }
    3385         if (doClose)
    3386         {
    3387             CHECK_ERROR(hardDisk, Close());
    3388         }
    3389     }
    3390     return SUCCEEDED(rc) ? 0 : 1;
    3391 }
    3392 
    3393 static DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
    3394 {
    3395     unsigned *pPercent = (unsigned *)pvUser;
    3396 
    3397     if (*pPercent != uPercent)
    3398     {
    3399         *pPercent = uPercent;
    3400         RTPrintf(".");
    3401         if ((uPercent % 10) == 0 && uPercent)
    3402             RTPrintf("%d%%", uPercent);
    3403         RTStrmFlush(g_pStdOut);
    3404     }
    3405 
    3406     return VINF_SUCCESS;
    3407 }
    3408 
    3409 
    3410 static int handleModifyHardDisk(int argc, char *argv[],
    3411                                 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3412 {
    3413     HRESULT rc;
    3414 
    3415     /* The uuid/filename and a command */
    3416     if (argc < 2)
    3417         return errorSyntax(USAGE_MODIFYHD, "Incorrect number of parameters");
    3418 
    3419     ComPtr<IHardDisk2> hardDisk;
    3420     Bstr filepath;
    3421 
    3422     /* first guess is that it's a UUID */
    3423     Guid uuid(argv[0]);
    3424     rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    3425     /* no? then it must be a filename */
    3426     if (!hardDisk)
    3427     {
    3428         filepath = argv[0];
    3429         CHECK_ERROR(virtualBox, FindHardDisk2(filepath, hardDisk.asOutParam()));
    3430     }
    3431 
    3432     /* let's find out which command */
    3433     if (strcmp(argv[1], "settype") == 0)
    3434     {
    3435         /* hard disk must be registered */
    3436         if (SUCCEEDED(rc) && hardDisk)
    3437         {
    3438             char *type = NULL;
    3439 
    3440             if (argc <= 2)
    3441                 return errorArgument("Missing argument to for settype");
    3442 
    3443             type = argv[2];
    3444 
    3445             HardDiskType_T hddType;
    3446             CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
    3447 
    3448             if (strcmp(type, "normal") == 0)
    3449             {
    3450                 if (hddType != HardDiskType_Normal)
    3451                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
    3452             }
    3453             else if (strcmp(type, "writethrough") == 0)
    3454             {
    3455                 if (hddType != HardDiskType_Writethrough)
    3456                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
    3457 
    3458             }
    3459             else if (strcmp(type, "immutable") == 0)
    3460             {
    3461                 if (hddType != HardDiskType_Immutable)
    3462                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
    3463             }
    3464             else
    3465             {
    3466                 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
    3467             }
    3468         }
    3469         else
    3470             return errorArgument("Hard disk image not registered");
    3471     }
    3472     else if (strcmp(argv[1], "compact") == 0)
    3473     {
    3474         /* the hard disk image might not be registered */
    3475         if (!hardDisk)
    3476         {
    3477             virtualBox->OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam());
    3478             if (!hardDisk)
    3479                 return errorArgument("Hard disk image not found");
    3480         }
    3481 
    3482         Bstr format;
    3483         hardDisk->COMGETTER(Format)(format.asOutParam());
    3484         if (format != "VDI")
    3485             return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
    3486 
    3487         Bstr fileName;
    3488         hardDisk->COMGETTER(Location)(fileName.asOutParam());
    3489 
    3490         /* make sure the object reference is released */
    3491         hardDisk = NULL;
    3492 
    3493         unsigned uProcent;
    3494 
    3495         RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
    3496         int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), hardDiskProgressCallback, &uProcent);
    3497         if (RT_FAILURE(vrc))
    3498         {
    3499             RTPrintf("Error while shrinking hard disk image: %Rrc\n", vrc);
    3500             rc = E_FAIL;
    3501         }
    3502     }
    3503     else
    3504         return errorSyntax(USAGE_MODIFYHD, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    3505 
    3506     return SUCCEEDED(rc) ? 0 : 1;
    3507 }
    3508 
    3509 static int handleCloneHardDisk(int argc, char *argv[],
    3510                                ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3511 {
    3512 #if 1
    3513     RTPrintf("Error: Clone hard disk operation is temporarily unavailable!\n");
    3514     return 1;
    3515 #else
    3516     /// @todo NEWMEDIA use IHardDisk2::cloneTo/flattenTo (not yet implemented)
    3517     HRESULT rc;
    3518 
    3519     /* source hard disk and target path */
    3520     if (argc != 2)
    3521         return errorSyntax(USAGE_CLONEHD, "Incorrect number of parameters");
    3522 
    3523     /* first guess is that it's a UUID */
    3524     Guid uuid(argv[0]);
    3525     ComPtr<IHardDisk2> hardDisk;
    3526     rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    3527     if (!hardDisk)
    3528     {
    3529         /* not successful? Then it must be a filename */
    3530         CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam()));
    3531     }
    3532     if (hardDisk)
    3533     {
    3534         ComPtr<IProgress> progress;
    3535         CHECK_ERROR(hardDisk, CloneToImage(Bstr(argv[1]), hardDisk.asOutParam(), progress.asOutParam()));
    3536         if (SUCCEEDED(rc))
    3537         {
    3538             showProgress(progress);
    3539             progress->COMGETTER(ResultCode)(&rc);
    3540             if (FAILED(rc))
    3541             {
    3542                 com::ProgressErrorInfo info(progress);
    3543                 if (info.isBasicAvailable())
    3544                 {
    3545                     RTPrintf("Error: failed to clone disk image. Error message: %lS\n", info.getText().raw());
    3546                 }
    3547                 else
    3548                 {
    3549                     RTPrintf("Error: failed to clone disk image. No error message available!\n");
    3550                 }
    3551             }
    3552         }
    3553     }
    3554     return SUCCEEDED(rc) ? 0 : 1;
    3555 #endif
    3556 }
    3557 
    3558 static int handleConvertDDImage(int argc, char *argv[])
    3559 {
    3560     int arg = 0;
    3561     VDIIMAGETYPE enmImgType = VDI_IMAGE_TYPE_NORMAL;
    3562     if (argc >= 1 && !strcmp(argv[arg], "-static"))
    3563     {
    3564         arg++;
    3565         enmImgType = VDI_IMAGE_TYPE_FIXED;
    3566     }
    3567 
    3568 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
    3569     const bool fReadFromStdIn = (argc >= arg + 1) && !strcmp(argv[arg], "stdin");
    3570 #else
    3571     const bool fReadFromStdIn = false;
    3572 #endif
    3573 
    3574     if ((!fReadFromStdIn && argc != arg + 2) || (fReadFromStdIn && argc != arg + 3))
    3575         return errorSyntax(USAGE_CONVERTDD, "Incorrect number of parameters");
    3576 
    3577     RTPrintf("Converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",
    3578              argv[arg], argv[arg + 1]);
    3579 
    3580     /* open raw image file. */
    3581     RTFILE File;
    3582     int rc = VINF_SUCCESS;
    3583     if (fReadFromStdIn)
    3584         File = 0;
    3585     else
    3586         rc = RTFileOpen(&File, argv[arg], RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    3587     if (RT_FAILURE(rc))
    3588     {
    3589         RTPrintf("File=\"%s\" open error: %Rrf\n", argv[arg], rc);
    3590         return rc;
    3591     }
    3592 
    3593     uint64_t cbFile;
    3594     /* get image size. */
    3595     if (fReadFromStdIn)
    3596         cbFile = RTStrToUInt64(argv[arg + 2]);
    3597     else
    3598         rc = RTFileGetSize(File, &cbFile);
    3599     if (RT_SUCCESS(rc))
    3600     {
    3601         RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (enmImgType == VDI_IMAGE_TYPE_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
    3602         char pszComment[256];
    3603         RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", argv[arg]);
    3604         rc = VDICreateBaseImage(argv[arg + 1],
    3605                                 enmImgType,
    3606                                 cbFile,
    3607                                 pszComment, NULL, NULL);
    3608         if (RT_SUCCESS(rc))
    3609         {
    3610             PVDIDISK pVdi = VDIDiskCreate();
    3611             rc = VDIDiskOpenImage(pVdi, argv[arg + 1], VDI_OPEN_FLAGS_NORMAL);
    3612             if (RT_SUCCESS(rc))
    3613             {
    3614                 /* alloc work buffer. */
    3615                 size_t cbBuffer = VDIDiskGetBufferSize(pVdi);
    3616                 void   *pvBuf = RTMemAlloc(cbBuffer);
    3617                 if (pvBuf)
    3618                 {
    3619                     uint64_t offFile = 0;
    3620                     while (offFile < cbFile)
    3621                     {
    3622                         size_t cbRead = 0;
    3623                         size_t cbToRead = cbFile - offFile >= (uint64_t) cbBuffer ?
    3624                             cbBuffer : (size_t) (cbFile - offFile);
    3625                         rc = RTFileRead(File, pvBuf, cbToRead, &cbRead);
    3626                         if (RT_FAILURE(rc) || !cbRead)
    3627                             break;
    3628                         rc = VDIDiskWrite(pVdi, offFile, pvBuf, cbRead);
    3629                         if (RT_FAILURE(rc))
    3630                             break;
    3631                         offFile += cbRead;
    3632                     }
    3633 
    3634                     RTMemFree(pvBuf);
    3635                 }
    3636                 else
    3637                     rc = VERR_NO_MEMORY;
    3638 
    3639                 VDIDiskCloseImage(pVdi);
    3640             }
    3641 
    3642             if (RT_FAILURE(rc))
    3643             {
    3644                 /* delete image on error */
    3645                 RTPrintf("Failed (%Rrc)!\n", rc);
    3646                 VDIDeleteImage(argv[arg + 1]);
    3647             }
    3648         }
    3649         else
    3650             RTPrintf("Failed to create output file (%Rrc)!\n", rc);
    3651     }
    3652     RTFileClose(File);
    3653 
    3654     return rc;
    3655 }
    3656 
    3657 static int handleAddiSCSIDisk(int argc, char *argv[],
    3658                               ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    3659 {
    3660 #if 1
    3661     RTPrintf("Error: Create iSCSI hard disk operation is temporarily unavailable!\n");
    3662     return 1;
    3663 #else
    3664     HRESULT rc;
    3665     Bstr server;
    3666     Bstr target;
    3667     uint16_t port = UINT16_MAX;
    3668     uint64_t lun = UINT64_MAX;
    3669     Bstr username;
    3670     Bstr password;
    3671     Bstr comment;
    3672 
    3673     /* at least server and target */
    3674     if (argc < 4)
    3675         return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");
    3676 
    3677     /* let's have a closer look at the arguments */
    3678     for (int i = 0; i < argc; i++)
    3679     {
    3680         if (strcmp(argv[i], "-server") == 0)
    3681         {
    3682             if (argc <= i + 1)
    3683                 return errorArgument("Missing argument to '%s'", argv[i]);
    3684             i++;
    3685             server = argv[i];
    3686         }
    3687         else if (strcmp(argv[i], "-target") == 0)
    3688         {
    3689             if (argc <= i + 1)
    3690                 return errorArgument("Missing argument to '%s'", argv[i]);
    3691             i++;
    3692             target = argv[i];
    3693         }
    3694         else if (strcmp(argv[i], "-port") == 0)
    3695         {
    3696             if (argc <= i + 1)
    3697                 return errorArgument("Missing argument to '%s'", argv[i]);
    3698             i++;
    3699             port = atoi(argv[i]);
    3700         }
    3701         else if (strcmp(argv[i], "-lun") == 0)
    3702         {
    3703             /** @todo move the LUN encoding algorithm into IISCSIHardDisk, add decoding */
    3704             if (argc <= i + 1)
    3705                 return errorArgument("Missing argument to '%s'", argv[i]);
    3706             i++;
    3707             char *pszNext;
    3708             int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
    3709             if (RT_FAILURE(rc) || *pszNext != '\0' || lun >= 16384)
    3710                 return errorArgument("Invalid LUN number '%s'", argv[i]);
    3711             if (lun <= 255)
    3712             {
    3713                 /* Assume bus identifier = 0. */
    3714                 lun = (lun << 48); /* uses peripheral device addressing method */
    3715             }
    3716             else
    3717             {
    3718                 /* Check above already limited the LUN to 14 bits. */
    3719                 lun = (lun << 48) | RT_BIT_64(62); /* uses flat space addressing method */
    3720             }
    3721         }
    3722         else if (strcmp(argv[i], "-encodedlun") == 0)
    3723         {
    3724             if (argc <= i + 1)
    3725                 return errorArgument("Missing argument to '%s'", argv[i]);
    3726             i++;
    3727             char *pszNext;
    3728             int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
    3729             if (RT_FAILURE(rc) || *pszNext != '\0')
    3730                 return errorArgument("Invalid encoded LUN number '%s'", argv[i]);
    3731         }
    3732         else if (strcmp(argv[i], "-username") == 0)
    3733         {
    3734             if (argc <= i + 1)
    3735                 return errorArgument("Missing argument to '%s'", argv[i]);
    3736             i++;
    3737             username = argv[i];
    3738         }
    3739         else if (strcmp(argv[i], "-password") == 0)
    3740         {
    3741             if (argc <= i + 1)
    3742                 return errorArgument("Missing argument to '%s'", argv[i]);
    3743             i++;
    3744             password = argv[i];
    3745         }
    3746         else if (strcmp(argv[i], "-comment") == 0)
    3747         {
    3748             if (argc <= i + 1)
    3749                 return errorArgument("Missing argument to '%s'", argv[i]);
    3750             i++;
    3751             comment = argv[i];
    3752         }
    3753         else
    3754             return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    3755     }
    3756 
    3757     /* check for required options */
    3758     if (!server || !target)
    3759         return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");
    3760 
    3761     ComPtr<IHardDisk> hardDisk;
    3762     CHECK_ERROR(aVirtualBox, CreateHardDisk(HardDiskStorageType_ISCSIHardDisk, hardDisk.asOutParam()));
    3763     if (SUCCEEDED(rc) && hardDisk)
    3764     {
    3765         CHECK_ERROR(hardDisk, COMSETTER(Description)(comment));
    3766         ComPtr<IISCSIHardDisk> iSCSIDisk = hardDisk;
    3767         CHECK_ERROR(iSCSIDisk, COMSETTER(Server)(server));
    3768         if (port != UINT16_MAX)
    3769             CHECK_ERROR(iSCSIDisk, COMSETTER(Port)(port));
    3770         CHECK_ERROR(iSCSIDisk, COMSETTER(Target)(target));
    3771         if (lun != UINT64_MAX)
    3772             CHECK_ERROR(iSCSIDisk, COMSETTER(Lun)(lun));
    3773         CHECK_ERROR(iSCSIDisk, COMSETTER(UserName)(username));
    3774         CHECK_ERROR(iSCSIDisk, COMSETTER(Password)(password));
    3775 
    3776         if (SUCCEEDED(rc))
    3777         {
    3778             CHECK_ERROR(aVirtualBox, RegisterHardDisk(hardDisk));
    3779         }
    3780 
    3781         if (SUCCEEDED(rc))
    3782         {
    3783             Guid guid;
    3784             CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
    3785             RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());
    3786         }
    3787     }
    3788 
    3789     return SUCCEEDED(rc) ? 0 : 1;
    3790 #endif
    3791 }
    3792 
    3793 static int handleCreateVM(int argc, char *argv[],
    3794                           ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3795 {
    3796     HRESULT rc;
    3797     Bstr baseFolder;
    3798     Bstr settingsFile;
    3799     Bstr name;
    3800     RTUUID id;
    3801     bool fRegister = false;
    3802 
    3803     RTUuidClear(&id);
    3804     for (int i = 0; i < argc; i++)
    3805     {
    3806         if (strcmp(argv[i], "-basefolder") == 0)
    3807         {
    3808             if (argc <= i + 1)
    3809                 return errorArgument("Missing argument to '%s'", argv[i]);
    3810             i++;
    3811             baseFolder = argv[i];
    3812         }
    3813         else if (strcmp(argv[i], "-settingsfile") == 0)
    3814         {
    3815             if (argc <= i + 1)
    3816                 return errorArgument("Missing argument to '%s'", argv[i]);
    3817             i++;
    3818             settingsFile = argv[i];
    3819         }
    3820         else if (strcmp(argv[i], "-name") == 0)
    3821         {
    3822             if (argc <= i + 1)
    3823                 return errorArgument("Missing argument to '%s'", argv[i]);
    3824             i++;
    3825             name = argv[i];
    3826         }
    3827         else if (strcmp(argv[i], "-uuid") == 0)
    3828         {
    3829             if (argc <= i + 1)
    3830                 return errorArgument("Missing argument to '%s'", argv[i]);
    3831             i++;
    3832             if (RT_FAILURE(RTUuidFromStr(&id, argv[i])))
    3833                 return errorArgument("Invalid UUID format %s\n", argv[i]);
    3834         }
    3835         else if (strcmp(argv[i], "-register") == 0)
    3836         {
    3837             fRegister = true;
    3838         }
    3839         else
    3840             return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    3841     }
    3842     if (!name)
    3843         return errorSyntax(USAGE_CREATEVM, "Parameter -name is required");
    3844 
    3845     if (!!baseFolder && !!settingsFile)
    3846         return errorSyntax(USAGE_CREATEVM, "Either -basefolder or -settingsfile must be specified");
    3847 
    3848     do
    3849     {
    3850         ComPtr<IMachine> machine;
    3851 
    3852         if (!settingsFile)
    3853             CHECK_ERROR_BREAK(virtualBox,
    3854                 CreateMachine(baseFolder, name, Guid(id), machine.asOutParam()));
    3855         else
    3856             CHECK_ERROR_BREAK(virtualBox,
    3857                 CreateLegacyMachine(settingsFile, name, Guid(id), machine.asOutParam()));
    3858 
    3859         CHECK_ERROR_BREAK(machine, SaveSettings());
    3860         if (fRegister)
    3861         {
    3862             CHECK_ERROR_BREAK(virtualBox, RegisterMachine(machine));
    3863         }
    3864         Guid uuid;
    3865         CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam()));
    3866         CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam()));
    3867         RTPrintf("Virtual machine '%ls' is created%s.\n"
    3868                  "UUID: %s\n"
    3869                  "Settings file: '%ls'\n",
    3870                  name.raw(), fRegister ? " and registered" : "",
    3871                  uuid.toString().raw(), settingsFile.raw());
    3872     }
    3873     while (0);
    3874 
    3875     return SUCCEEDED(rc) ? 0 : 1;
    3876 }
    3877 
    3878 /**
    3879  * Parses a number.
    3880  *
    3881  * @returns Valid number on success.
    3882  * @returns 0 if invalid number. All necesary bitching has been done.
    3883  * @param   psz     Pointer to the nic number.
    3884  */
    3885 static unsigned parseNum(const char *psz, unsigned cMaxNum, const char *name)
    3886 {
    3887     uint32_t u32;
    3888     char *pszNext;
    3889     int rc = RTStrToUInt32Ex(psz, &pszNext, 10, &u32);
    3890     if (    RT_SUCCESS(rc)
    3891         &&  *pszNext == '\0'
    3892         &&  u32 >= 1
    3893         &&  u32 <= cMaxNum)
    3894         return (unsigned)u32;
    3895     errorArgument("Invalid %s number '%s'", name, psz);
    3896     return 0;
    3897 }
    3898 
    3899 static int handleModifyVM(int argc, char *argv[],
    3900                           ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    3901 {
    3902     HRESULT rc;
    3903     Bstr name;
    3904     Bstr ostype;
    3905     ULONG memorySize = 0;
    3906     ULONG vramSize = 0;
    3907     char *acpi = NULL;
    3908     char *hwvirtex = NULL;
    3909     char *nestedpaging = NULL;
    3910     char *vtxvpid = NULL;
    3911     char *pae = NULL;
    3912     char *ioapic = NULL;
    3913     int monitorcount = -1;
    3914     char *accelerate3d = NULL;
    3915     char *bioslogofadein = NULL;
    3916     char *bioslogofadeout = NULL;
    3917     uint32_t bioslogodisplaytime = ~0;
    3918     char *bioslogoimagepath = NULL;
    3919     char *biosbootmenumode = NULL;
    3920     char *biossystemtimeoffset = NULL;
    3921     char *biospxedebug = NULL;
    3922     DeviceType_T bootDevice[4];
    3923     int bootDeviceChanged[4] = { false };
    3924     char *hdds[34] = {0};
    3925     char *dvd = NULL;
    3926     char *dvdpassthrough = NULL;
    3927     char *idecontroller = NULL;
    3928     char *floppy = NULL;
    3929     char *audio = NULL;
    3930     char *audiocontroller = NULL;
    3931     char *clipboard = NULL;
    3932 #ifdef VBOX_WITH_VRDP
    3933     char *vrdp = NULL;
    3934     uint16_t vrdpport = UINT16_MAX;
    3935     char *vrdpaddress = NULL;
    3936     char *vrdpauthtype = NULL;
    3937     char *vrdpmulticon = NULL;
    3938     char *vrdpreusecon = NULL;
    3939 #endif
    3940     int   fUsbEnabled = -1;
    3941     int   fUsbEhciEnabled = -1;
    3942     char *snapshotFolder = NULL;
    3943     ULONG guestMemBalloonSize = (ULONG)-1;
    3944     ULONG guestStatInterval = (ULONG)-1;
    3945     int   fSataEnabled = -1;
    3946     int   sataPortCount = -1;
    3947     int   sataBootDevices[4] = {-1,-1,-1,-1};
    3948 
    3949     /* VM ID + at least one parameter. Parameter arguments are checked
    3950      * individually. */
    3951     if (argc < 2)
    3952         return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
    3953 
    3954     /* Get the number of network adapters */
    3955     ULONG NetworkAdapterCount = 0;
    3956     {
    3957         ComPtr <ISystemProperties> info;
    3958         CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1);
    3959         CHECK_ERROR_RET (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount), 1);
    3960     }
    3961     ULONG SerialPortCount = 0;
    3962     {
    3963         ComPtr <ISystemProperties> info;
    3964         CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1);
    3965         CHECK_ERROR_RET (info, COMGETTER(SerialPortCount) (&SerialPortCount), 1);
    3966     }
    3967 
    3968     std::vector <char *> nics (NetworkAdapterCount, 0);
    3969     std::vector <char *> nictype (NetworkAdapterCount, 0);
    3970     std::vector <char *> cableconnected (NetworkAdapterCount, 0);
    3971     std::vector <char *> nictrace (NetworkAdapterCount, 0);
    3972     std::vector <char *> nictracefile (NetworkAdapterCount, 0);
    3973     std::vector <char *> nicspeed (NetworkAdapterCount, 0);
    3974     std::vector <char *> hostifdev (NetworkAdapterCount, 0);
    3975     std::vector <const char *> intnet (NetworkAdapterCount, 0);
    3976     std::vector <const char *> natnet (NetworkAdapterCount, 0);
    3977 #ifdef RT_OS_LINUX
    3978     std::vector <char *> tapsetup (NetworkAdapterCount, 0);
    3979     std::vector <char *> tapterm (NetworkAdapterCount, 0);
    3980 #endif
    3981     std::vector <char *> macs (NetworkAdapterCount, 0);
    3982     std::vector <char *> uarts_mode (SerialPortCount, 0);
    3983     std::vector <ULONG>  uarts_base (SerialPortCount, 0);
    3984     std::vector <ULONG>  uarts_irq (SerialPortCount, 0);
    3985     std::vector <char *> uarts_path (SerialPortCount, 0);
    3986 
    3987     for (int i = 1; i < argc; i++)
    3988     {
    3989         if (strcmp(argv[i], "-name") == 0)
    3990         {
    3991             if (argc <= i + 1)
    3992                 return errorArgument("Missing argument to '%s'", argv[i]);
    3993             i++;
    3994             name = argv[i];
    3995         }
    3996         else if (strcmp(argv[i], "-ostype") == 0)
    3997         {
    3998             if (argc <= i + 1)
    3999                 return errorArgument("Missing argument to '%s'", argv[i]);
    4000             i++;
    4001             ostype = argv[i];
    4002         }
    4003         else if (strcmp(argv[i], "-memory") == 0)
    4004         {
    4005             if (argc <= i + 1)
    4006                 return errorArgument("Missing argument to '%s'", argv[i]);
    4007             i++;
    4008             memorySize = atoi(argv[i]);
    4009         }
    4010         else if (strcmp(argv[i], "-vram") == 0)
    4011         {
    4012             if (argc <= i + 1)
    4013                 return errorArgument("Missing argument to '%s'", argv[i]);
    4014             i++;
    4015             vramSize = atoi(argv[i]);
    4016         }
    4017         else if (strcmp(argv[i], "-acpi") == 0)
    4018         {
    4019             if (argc <= i + 1)
    4020                 return errorArgument("Missing argument to '%s'", argv[i]);
    4021             i++;
    4022             acpi = argv[i];
    4023         }
    4024         else if (strcmp(argv[i], "-ioapic") == 0)
    4025         {
    4026             if (argc <= i + 1)
    4027                 return errorArgument("Missing argument to '%s'", argv[i]);
    4028             i++;
    4029             ioapic = argv[i];
    4030         }
    4031         else if (strcmp(argv[i], "-hwvirtex") == 0)
    4032         {
    4033             if (argc <= i + 1)
    4034                 return errorArgument("Missing argument to '%s'", argv[i]);
    4035             i++;
    4036             hwvirtex = argv[i];
    4037         }
    4038         else if (strcmp(argv[i], "-nestedpaging") == 0)
    4039         {
    4040             if (argc <= i + 1)
    4041                 return errorArgument("Missing argument to '%s'", argv[i]);
    4042             i++;
    4043             nestedpaging = argv[i];
    4044         }
    4045         else if (strcmp(argv[i], "-vtxvpid") == 0)
    4046         {
    4047             if (argc <= i + 1)
    4048                 return errorArgument("Missing argument to '%s'", argv[i]);
    4049             i++;
    4050             vtxvpid = argv[i];
    4051         }
    4052         else if (strcmp(argv[i], "-pae") == 0)
    4053         {
    4054             if (argc <= i + 1)
    4055                 return errorArgument("Missing argument to '%s'", argv[i]);
    4056             i++;
    4057             pae = argv[i];
    4058         }
    4059         else if (strcmp(argv[i], "-monitorcount") == 0)
    4060         {
    4061             if (argc <= i + 1)
    4062                 return errorArgument("Missing argument to '%s'", argv[i]);
    4063             i++;
    4064             monitorcount = atoi(argv[i]);
    4065         }
    4066         else if (strcmp(argv[i], "-accelerate3d") == 0)
    4067         {
    4068             if (argc <= i + 1)
    4069                 return errorArgument("Missing argument to '%s'", argv[i]);
    4070             i++;
    4071             accelerate3d = argv[i];
    4072         }
    4073         else if (strcmp(argv[i], "-bioslogofadein") == 0)
    4074         {
    4075             if (argc <= i + 1)
    4076                 return errorArgument("Missing argument to '%s'", argv[i]);
    4077             i++;
    4078             bioslogofadein = argv[i];
    4079         }
    4080         else if (strcmp(argv[i], "-bioslogofadeout") == 0)
    4081         {
    4082             if (argc <= i + 1)
    4083                 return errorArgument("Missing argument to '%s'", argv[i]);
    4084             i++;
    4085             bioslogofadeout = argv[i];
    4086         }
    4087         else if (strcmp(argv[i], "-bioslogodisplaytime") == 0)
    4088         {
    4089             if (argc <= i + 1)
    4090                 return errorArgument("Missing argument to '%s'", argv[i]);
    4091             i++;
    4092             bioslogodisplaytime = atoi(argv[i]);
    4093         }
    4094         else if (strcmp(argv[i], "-bioslogoimagepath") == 0)
    4095         {
    4096             if (argc <= i + 1)
    4097                 return errorArgument("Missing argument to '%s'", argv[i]);
    4098             i++;
    4099             bioslogoimagepath = argv[i];
    4100         }
    4101         else if (strcmp(argv[i], "-biosbootmenu") == 0)
    4102         {
    4103             if (argc <= i + 1)
    4104                 return errorArgument("Missing argument to '%s'", argv[i]);
    4105             i++;
    4106             biosbootmenumode = argv[i];
    4107         }
    4108         else if (strcmp(argv[i], "-biossystemtimeoffset") == 0)
    4109         {
    4110             if (argc <= i + 1)
    4111                 return errorArgument("Missing argument to '%s'", argv[i]);
    4112             i++;
    4113             biossystemtimeoffset = argv[i];
    4114         }
    4115         else if (strcmp(argv[i], "-biospxedebug") == 0)
    4116         {
    4117             if (argc <= i + 1)
    4118                 return errorArgument("Missing argument to '%s'", argv[i]);
    4119             i++;
    4120             biospxedebug = argv[i];
    4121         }
    4122         else if (strncmp(argv[i], "-boot", 5) == 0)
    4123         {
    4124             ULONG n = 0;
    4125             if (!argv[i][5])
    4126                 return errorSyntax(USAGE_MODIFYVM, "Missing boot slot number in '%s'", argv[i]);
    4127             if ((n = strtoul(&argv[i][5], NULL, 10)) < 1)
    4128                 return errorSyntax(USAGE_MODIFYVM, "Invalid boot slot number in '%s'", argv[i]);
    4129             if (argc <= i + 1)
    4130                 return errorArgument("Missing argument to '%s'", argv[i]);
    4131             i++;
    4132             if (strcmp(argv[i], "none") == 0)
    4133             {
    4134                 bootDevice[n - 1] = DeviceType_Null;
    4135             }
    4136             else if (strcmp(argv[i], "floppy") == 0)
    4137             {
    4138                 bootDevice[n - 1] = DeviceType_Floppy;
    4139             }
    4140             else if (strcmp(argv[i], "dvd") == 0)
    4141             {
    4142                 bootDevice[n - 1] = DeviceType_DVD;
    4143             }
    4144             else if (strcmp(argv[i], "disk") == 0)
    4145             {
    4146                 bootDevice[n - 1] = DeviceType_HardDisk;
    4147             }
    4148             else if (strcmp(argv[i], "net") == 0)
    4149             {
    4150                 bootDevice[n - 1] = DeviceType_Network;
    4151             }
    4152             else
    4153                 return errorArgument("Invalid boot device '%s'", argv[i]);
    4154 
    4155             bootDeviceChanged[n - 1] = true;
    4156         }
    4157         else if (strcmp(argv[i], "-hda") == 0)
    4158         {
    4159             if (argc <= i + 1)
    4160                 return errorArgument("Missing argument to '%s'", argv[i]);
    4161             i++;
    4162             hdds[0] = argv[i];
    4163         }
    4164         else if (strcmp(argv[i], "-hdb") == 0)
    4165         {
    4166             if (argc <= i + 1)
    4167                 return errorArgument("Missing argument to '%s'", argv[i]);
    4168             i++;
    4169             hdds[1] = argv[i];
    4170         }
    4171         else if (strcmp(argv[i], "-hdd") == 0)
    4172         {
    4173             if (argc <= i + 1)
    4174                 return errorArgument("Missing argument to '%s'", argv[i]);
    4175             i++;
    4176             hdds[2] = argv[i];
    4177         }
    4178         else if (strcmp(argv[i], "-dvd") == 0)
    4179         {
    4180             if (argc <= i + 1)
    4181                 return errorArgument("Missing argument to '%s'", argv[i]);
    4182             i++;
    4183             dvd = argv[i];
    4184         }
    4185         else if (strcmp(argv[i], "-dvdpassthrough") == 0)
    4186         {
    4187             if (argc <= i + 1)
    4188                 return errorArgument("Missing argument to '%s'", argv[i]);
    4189             i++;
    4190             dvdpassthrough = argv[i];
    4191         }
    4192         else if (strcmp(argv[i], "-idecontroller") == 0)
    4193         {
    4194             if (argc <= i + 1)
    4195                 return errorArgument("Missing argument to '%s'", argv[i]);
    4196             i++;
    4197             idecontroller = argv[i];
    4198         }
    4199         else if (strcmp(argv[i], "-floppy") == 0)
    4200         {
    4201             if (argc <= i + 1)
    4202                 return errorArgument("Missing argument to '%s'", argv[i]);
    4203             i++;
    4204             floppy = argv[i];
    4205         }
    4206         else if (strcmp(argv[i], "-audio") == 0)
    4207         {
    4208             if (argc <= i + 1)
    4209                 return errorArgument("Missing argument to '%s'", argv[i]);
    4210             i++;
    4211             audio = argv[i];
    4212         }
    4213         else if (strcmp(argv[i], "-audiocontroller") == 0)
    4214         {
    4215             if (argc <= i + 1)
    4216                 return errorArgument("Missing argument to '%s'", argv[i]);
    4217             i++;
    4218             audiocontroller = argv[i];
    4219         }
    4220         else if (strcmp(argv[i], "-clipboard") == 0)
    4221         {
    4222             if (argc <= i + 1)
    4223                 return errorArgument("Missing argument to '%s'", argv[i]);
    4224             i++;
    4225             clipboard = argv[i];
    4226         }
    4227         else if (strncmp(argv[i], "-cableconnected", 15) == 0)
    4228         {
    4229             unsigned n = parseNum(&argv[i][15], NetworkAdapterCount, "NIC");
    4230             if (!n)
    4231                 return 1;
    4232 
    4233             if (argc <= i + 1)
    4234                 return errorArgument("Missing argument to '%s'", argv[i]);
    4235 
    4236             cableconnected[n - 1] = argv[i + 1];
    4237             i++;
    4238         }
    4239         /* watch for the right order of these -nic* comparisons! */
    4240         else if (strncmp(argv[i], "-nictracefile", 13) == 0)
    4241         {
    4242             unsigned n = parseNum(&argv[i][13], NetworkAdapterCount, "NIC");
    4243             if (!n)
    4244                 return 1;
    4245             if (argc <= i + 1)
    4246             {
    4247                 return errorArgument("Missing argument to '%s'", argv[i]);
    4248             }
    4249             nictracefile[n - 1] = argv[i + 1];
    4250             i++;
    4251         }
    4252         else if (strncmp(argv[i], "-nictrace", 9) == 0)
    4253         {
    4254             unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
    4255             if (!n)
    4256                 return 1;
    4257             if (argc <= i + 1)
    4258                 return errorArgument("Missing argument to '%s'", argv[i]);
    4259             nictrace[n - 1] = argv[i + 1];
    4260             i++;
    4261         }
    4262         else if (strncmp(argv[i], "-nictype", 8) == 0)
    4263         {
    4264             unsigned n = parseNum(&argv[i][8], NetworkAdapterCount, "NIC");
    4265             if (!n)
    4266                 return 1;
    4267             if (argc <= i + 1)
    4268                 return errorArgument("Missing argument to '%s'", argv[i]);
    4269             nictype[n - 1] = argv[i + 1];
    4270             i++;
    4271         }
    4272         else if (strncmp(argv[i], "-nicspeed", 9) == 0)
    4273         {
    4274             unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
    4275             if (!n)
    4276                 return 1;
    4277             if (argc <= i + 1)
    4278                 return errorArgument("Missing argument to '%s'", argv[i]);
    4279             nicspeed[n - 1] = argv[i + 1];
    4280             i++;
    4281         }
    4282         else if (strncmp(argv[i], "-nic", 4) == 0)
    4283         {
    4284             unsigned n = parseNum(&argv[i][4], NetworkAdapterCount, "NIC");
    4285             if (!n)
    4286                 return 1;
    4287             if (argc <= i + 1)
    4288                 return errorArgument("Missing argument to '%s'", argv[i]);
    4289             nics[n - 1] = argv[i + 1];
    4290             i++;
    4291         }
    4292         else if (strncmp(argv[i], "-hostifdev", 10) == 0)
    4293         {
    4294             unsigned n = parseNum(&argv[i][10], NetworkAdapterCount, "NIC");
    4295             if (!n)
    4296                 return 1;
    4297             if (argc <= i + 1)
    4298                 return errorArgument("Missing argument to '%s'", argv[i]);
    4299             hostifdev[n - 1] = argv[i + 1];
    4300             i++;
    4301         }
    4302         else if (strncmp(argv[i], "-intnet", 7) == 0)
    4303         {
    4304             unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC");
    4305             if (!n)
    4306                 return 1;
    4307             if (argc <= i + 1)
    4308                 return errorArgument("Missing argument to '%s'", argv[i]);
    4309             intnet[n - 1] = argv[i + 1];
    4310             i++;
    4311         }
    4312         else if (strncmp(argv[i], "-natnet", 7) == 0)
    4313         {
    4314             unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC");
    4315             if (!n)
    4316                 return 1;
    4317             if (argc <= i + 1)
    4318                 return errorArgument("Missing argument to '%s'", argv[i]);
    4319 
    4320             if (!strcmp(argv[i + 1], "default"))
    4321                 natnet[n - 1] = "";
    4322             else
    4323             {
    4324                 RTIPV4ADDR Network;
    4325                 RTIPV4ADDR Netmask;
    4326                 int rc = RTCidrStrToIPv4(argv[i + 1], &Network, &Netmask);
    4327                 if (RT_FAILURE(rc))
    4328                     return errorArgument("Invalid IPv4 network '%s' specified -- CIDR notation expected.\n", argv[i + 1]);
    4329                 if (Netmask & 0x1f)
    4330                     return errorArgument("Prefix length of the NAT network must be less than 28.\n");
    4331                 natnet[n - 1] = argv[i + 1];
    4332             }
    4333             i++;
    4334         }
    4335 #ifdef RT_OS_LINUX
    4336         else if (strncmp(argv[i], "-tapsetup", 9) == 0)
    4337         {
    4338             unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
    4339             if (!n)
    4340                 return 1;
    4341             if (argc <= i + 1)
    4342                 return errorArgument("Missing argument to '%s'", argv[i]);
    4343             tapsetup[n - 1] = argv[i + 1];
    4344             i++;
    4345         }
    4346         else if (strncmp(argv[i], "-tapterminate", 13) == 0)
    4347         {
    4348             unsigned n = parseNum(&argv[i][13], NetworkAdapterCount, "NIC");
    4349             if (!n)
    4350                 return 1;
    4351             if (argc <= i + 1)
    4352                 return errorArgument("Missing argument to '%s'", argv[i]);
    4353             tapterm[n - 1] = argv[i + 1];
    4354             i++;
    4355         }
    4356 #endif /* RT_OS_LINUX */
    4357         else if (strncmp(argv[i], "-macaddress", 11) == 0)
    4358         {
    4359             unsigned n = parseNum(&argv[i][11], NetworkAdapterCount, "NIC");
    4360             if (!n)
    4361                 return 1;
    4362             if (argc <= i + 1)
    4363                 return errorArgument("Missing argument to '%s'", argv[i]);
    4364             macs[n - 1] = argv[i + 1];
    4365             i++;
    4366         }
    4367 #ifdef VBOX_WITH_VRDP
    4368         else if (strcmp(argv[i], "-vrdp") == 0)
    4369         {
    4370             if (argc <= i + 1)
    4371                 return errorArgument("Missing argument to '%s'", argv[i]);
    4372             i++;
    4373             vrdp = argv[i];
    4374         }
    4375         else if (strcmp(argv[i], "-vrdpport") == 0)
    4376         {
    4377             if (argc <= i + 1)
    4378                 return errorArgument("Missing argument to '%s'", argv[i]);
    4379             i++;
    4380             if (strcmp(argv[i], "default") == 0)
    4381                 vrdpport = 0;
    4382             else
    4383                 vrdpport = atoi(argv[i]);
    4384         }
    4385         else if (strcmp(argv[i], "-vrdpaddress") == 0)
    4386         {
    4387             if (argc <= i + 1)
    4388                 return errorArgument("Missing argument to '%s'", argv[i]);
    4389             i++;
    4390             vrdpaddress = argv[i];
    4391         }
    4392         else if (strcmp(argv[i], "-vrdpauthtype") == 0)
    4393         {
    4394             if (argc <= i + 1)
    4395                 return errorArgument("Missing argument to '%s'", argv[i]);
    4396             i++;
    4397             vrdpauthtype = argv[i];
    4398         }
    4399         else if (strcmp(argv[i], "-vrdpmulticon") == 0)
    4400         {
    4401             if (argc <= i + 1)
    4402                 return errorArgument("Missing argument to '%s'", argv[i]);
    4403             i++;
    4404             vrdpmulticon = argv[i];
    4405         }
    4406         else if (strcmp(argv[i], "-vrdpreusecon") == 0)
    4407         {
    4408             if (argc <= i + 1)
    4409                 return errorArgument("Missing argument to '%s'", argv[i]);
    4410             i++;
    4411             vrdpreusecon = argv[i];
    4412         }
    4413 #endif /* VBOX_WITH_VRDP */
    4414         else if (strcmp(argv[i], "-usb") == 0)
    4415         {
    4416             if (argc <= i + 1)
    4417                 return errorArgument("Missing argument to '%s'", argv[i]);
    4418             i++;
    4419             if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
    4420                 fUsbEnabled = 1;
    4421             else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
    4422                 fUsbEnabled = 0;
    4423             else
    4424                 return errorArgument("Invalid -usb argument '%s'", argv[i]);
    4425         }
    4426         else if (strcmp(argv[i], "-usbehci") == 0)
    4427         {
    4428             if (argc <= i + 1)
    4429                 return errorArgument("Missing argument to '%s'", argv[i]);
    4430             i++;
    4431             if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
    4432                 fUsbEhciEnabled = 1;
    4433             else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
    4434                 fUsbEhciEnabled = 0;
    4435             else
    4436                 return errorArgument("Invalid -usbehci argument '%s'", argv[i]);
    4437         }
    4438         else if (strcmp(argv[i], "-snapshotfolder") == 0)
    4439         {
    4440             if (argc <= i + 1)
    4441                 return errorArgument("Missing argument to '%s'", argv[i]);
    4442             i++;
    4443             snapshotFolder = argv[i];
    4444         }
    4445         else if (strncmp(argv[i], "-uartmode", 9) == 0)
    4446         {
    4447             unsigned n = parseNum(&argv[i][9], SerialPortCount, "UART");
    4448             if (!n)
    4449                 return 1;
    4450             i++;
    4451             if (strcmp(argv[i], "disconnected") == 0)
    4452             {
    4453                 uarts_mode[n - 1] = argv[i];
    4454             }
    4455             else
    4456             {
    4457                 if (strcmp(argv[i], "server") == 0 || strcmp(argv[i], "client") == 0)
    4458                 {
    4459                     uarts_mode[n - 1] = argv[i];
    4460                     i++;
    4461 #ifdef RT_OS_WINDOWS
    4462                     if (strncmp(argv[i], "\\\\.\\pipe\\", 9))
    4463                         return errorArgument("Uart pipe must start with \\\\.\\pipe\\");
    4464 #endif
    4465                 }
    4466                 else
    4467                 {
    4468                     uarts_mode[n - 1] = (char*)"device";
    4469                 }
    4470                 if (argc <= i)
    4471                     return errorArgument("Missing argument to -uartmode");
    4472                 uarts_path[n - 1] = argv[i];
    4473             }
    4474         }
    4475         else if (strncmp(argv[i], "-uart", 5) == 0)
    4476         {
    4477             unsigned n = parseNum(&argv[i][5], SerialPortCount, "UART");
    4478             if (!n)
    4479                 return 1;
    4480             if (argc <= i + 1)
    4481                 return errorArgument("Missing argument to '%s'", argv[i]);
    4482             i++;
    4483             if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
    4484             {
    4485                 uarts_base[n - 1] = (ULONG)-1;
    4486             }
    4487             else
    4488             {
    4489                 if (argc <= i + 1)
    4490                     return errorArgument("Missing argument to '%s'", argv[i-1]);
    4491                 uint32_t uVal;
    4492                 int vrc;
    4493                 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
    4494                 if (vrc != VINF_SUCCESS || uVal == 0)
    4495                     return errorArgument("Error parsing UART I/O base '%s'", argv[i]);
    4496                 uarts_base[n - 1] = uVal;
    4497                 i++;
    4498                 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
    4499                 if (vrc != VINF_SUCCESS)
    4500                     return errorArgument("Error parsing UART IRQ '%s'", argv[i]);
    4501                 uarts_irq[n - 1]  = uVal;
    4502             }
    4503         }
    4504 #ifdef VBOX_WITH_MEM_BALLOONING
    4505         else if (strncmp(argv[i], "-guestmemoryballoon", 19) == 0)
    4506         {
    4507             if (argc <= i + 1)
    4508                 return errorArgument("Missing argument to '%s'", argv[i]);
    4509             i++;
    4510             uint32_t uVal;
    4511             int vrc;
    4512             vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
    4513             if (vrc != VINF_SUCCESS)
    4514                 return errorArgument("Error parsing guest memory balloon size '%s'", argv[i]);
    4515             guestMemBalloonSize = uVal;
    4516         }
    4517 #endif
    4518         else if (strncmp(argv[i], "-gueststatisticsinterval", 24) == 0)
    4519         {
    4520             if (argc <= i + 1)
    4521                 return errorArgument("Missing argument to '%s'", argv[i]);
    4522             i++;
    4523             uint32_t uVal;
    4524             int vrc;
    4525             vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
    4526             if (vrc != VINF_SUCCESS)
    4527                 return errorArgument("Error parsing guest statistics interval '%s'", argv[i]);
    4528             guestStatInterval = uVal;
    4529         }
    4530         else if (strcmp(argv[i], "-sata") == 0)
    4531         {
    4532             if (argc <= i + 1)
    4533                 return errorArgument("Missing argument to '%s'", argv[i]);
    4534             i++;
    4535             if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
    4536                 fSataEnabled = 1;
    4537             else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
    4538                 fSataEnabled = 0;
    4539             else
    4540                 return errorArgument("Invalid -usb argument '%s'", argv[i]);
    4541         }
    4542         else if (strcmp(argv[i], "-sataportcount") == 0)
    4543         {
    4544             unsigned n;
    4545 
    4546             if (argc <= i + 1)
    4547                 return errorArgument("Missing arguments to '%s'", argv[i]);
    4548             i++;
    4549 
    4550             n = parseNum(argv[i], 30, "SATA");
    4551             if (!n)
    4552                 return 1;
    4553             sataPortCount = n;
    4554         }
    4555         else if (strncmp(argv[i], "-sataport", 9) == 0)
    4556         {
    4557             unsigned n = parseNum(&argv[i][9], 30, "SATA");
    4558             if (!n)
    4559                 return 1;
    4560             if (argc <= i + 1)
    4561                 return errorArgument("Missing argument to '%s'", argv[i]);
    4562             i++;
    4563             hdds[n-1+4] = argv[i];
    4564         }
    4565         else if (strncmp(argv[i], "-sataideemulation", 17) == 0)
    4566         {
    4567             unsigned bootDevicePos = 0;
    4568             unsigned n;
    4569 
    4570             bootDevicePos = parseNum(&argv[i][17], 4, "SATA");
    4571             if (!bootDevicePos)
    4572                 return 1;
    4573             bootDevicePos--;
    4574 
    4575             if (argc <= i + 1)
    4576                 return errorArgument("Missing arguments to '%s'", argv[i]);
    4577             i++;
    4578 
    4579             n = parseNum(argv[i], 30, "SATA");
    4580             if (!n)
    4581                 return 1;
    4582 
    4583             sataBootDevices[bootDevicePos] = n-1;
    4584         }
    4585         else
    4586             return errorSyntax(USAGE_MODIFYVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    4587     }
    4588 
    4589     /* try to find the given machine */
    4590     ComPtr <IMachine> machine;
    4591     Guid uuid (argv[0]);
    4592     if (!uuid.isEmpty())
    4593     {
    4594         CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
    4595     }
    4596     else
    4597     {
    4598         CHECK_ERROR (virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    4599         if (SUCCEEDED (rc))
    4600             machine->COMGETTER(Id)(uuid.asOutParam());
    4601     }
    4602     if (FAILED (rc))
    4603         return 1;
    4604 
    4605     /* open a session for the VM */
    4606     CHECK_ERROR_RET (virtualBox, OpenSession(session, uuid), 1);
    4607 
    4608     do
    4609     {
    4610         /* get the mutable session machine */
    4611         session->COMGETTER(Machine)(machine.asOutParam());
    4612 
    4613         ComPtr <IBIOSSettings> biosSettings;
    4614         machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
    4615 
    4616         if (name)
    4617             CHECK_ERROR(machine, COMSETTER(Name)(name));
    4618         if (ostype)
    4619         {
    4620             ComPtr<IGuestOSType> guestOSType;
    4621             CHECK_ERROR(virtualBox, GetGuestOSType(ostype, guestOSType.asOutParam()));
    4622             if (SUCCEEDED(rc) && guestOSType)
    4623             {
    4624                 CHECK_ERROR(machine, COMSETTER(OSTypeId)(ostype));
    4625             }
    4626             else
    4627             {
    4628                 errorArgument("Invalid guest OS type '%s'", Utf8Str(ostype).raw());
    4629                 rc = E_FAIL;
    4630                 break;
    4631             }
    4632         }
    4633         if (memorySize > 0)
    4634             CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySize));
    4635         if (vramSize > 0)
    4636             CHECK_ERROR(machine, COMSETTER(VRAMSize)(vramSize));
    4637         if (acpi)
    4638         {
    4639             if (strcmp(acpi, "on") == 0)
    4640             {
    4641                 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(true));
    4642             }
    4643             else if (strcmp(acpi, "off") == 0)
    4644             {
    4645                 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(false));
    4646             }
    4647             else
    4648             {
    4649                 errorArgument("Invalid -acpi argument '%s'", acpi);
    4650                 rc = E_FAIL;
    4651                 break;
    4652             }
    4653         }
    4654         if (ioapic)
    4655         {
    4656             if (strcmp(ioapic, "on") == 0)
    4657             {
    4658                 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(true));
    4659             }
    4660             else if (strcmp(ioapic, "off") == 0)
    4661             {
    4662                 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(false));
    4663             }
    4664             else
    4665             {
    4666                 errorArgument("Invalid -ioapic argument '%s'", ioapic);
    4667                 rc = E_FAIL;
    4668                 break;
    4669             }
    4670         }
    4671         if (hwvirtex)
    4672         {
    4673             if (strcmp(hwvirtex, "on") == 0)
    4674             {
    4675                 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_True));
    4676             }
    4677             else if (strcmp(hwvirtex, "off") == 0)
    4678             {
    4679                 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_False));
    4680             }
    4681             else if (strcmp(hwvirtex, "default") == 0)
    4682             {
    4683                 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_Default));
    4684             }
    4685             else
    4686             {
    4687                 errorArgument("Invalid -hwvirtex argument '%s'", hwvirtex);
    4688                 rc = E_FAIL;
    4689                 break;
    4690             }
    4691         }
    4692         if (nestedpaging)
    4693         {
    4694             if (strcmp(nestedpaging, "on") == 0)
    4695             {
    4696                 CHECK_ERROR(machine, COMSETTER(HWVirtExNestedPagingEnabled)(true));
    4697             }
    4698             else if (strcmp(nestedpaging, "off") == 0)
    4699             {
    4700                 CHECK_ERROR(machine, COMSETTER(HWVirtExNestedPagingEnabled)(false));
    4701             }
    4702             else
    4703             {
    4704                 errorArgument("Invalid -nestedpaging argument '%s'", ioapic);
    4705                 rc = E_FAIL;
    4706                 break;
    4707             }
    4708         }
    4709         if (vtxvpid)
    4710         {
    4711             if (strcmp(vtxvpid, "on") == 0)
    4712             {
    4713                 CHECK_ERROR(machine, COMSETTER(HWVirtExVPIDEnabled)(true));
    4714             }
    4715             else if (strcmp(vtxvpid, "off") == 0)
    4716             {
    4717                 CHECK_ERROR(machine, COMSETTER(HWVirtExVPIDEnabled)(false));
    4718             }
    4719             else
    4720             {
    4721                 errorArgument("Invalid -vtxvpid argument '%s'", ioapic);
    4722                 rc = E_FAIL;
    4723                 break;
    4724             }
    4725         }
    4726         if (pae)
    4727         {
    4728             if (strcmp(pae, "on") == 0)
    4729             {
    4730                 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(true));
    4731             }
    4732             else if (strcmp(pae, "off") == 0)
    4733             {
    4734                 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(false));
    4735             }
    4736             else
    4737             {
    4738                 errorArgument("Invalid -pae argument '%s'", ioapic);
    4739                 rc = E_FAIL;
    4740                 break;
    4741             }
    4742         }
    4743         if (monitorcount != -1)
    4744         {
    4745             CHECK_ERROR(machine, COMSETTER(MonitorCount)(monitorcount));
    4746         }
    4747         if (accelerate3d)
    4748         {
    4749             if (strcmp(accelerate3d, "on") == 0)
    4750             {
    4751                 CHECK_ERROR(machine, COMSETTER(Accelerate3DEnabled)(true));
    4752             }
    4753             else if (strcmp(accelerate3d, "off") == 0)
    4754             {
    4755                 CHECK_ERROR(machine, COMSETTER(Accelerate3DEnabled)(false));
    4756             }
    4757             else
    4758             {
    4759                 errorArgument("Invalid -accelerate3d argument '%s'", ioapic);
    4760                 rc = E_FAIL;
    4761                 break;
    4762             }
    4763         }
    4764         if (bioslogofadein)
    4765         {
    4766             if (strcmp(bioslogofadein, "on") == 0)
    4767             {
    4768                 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(true));
    4769             }
    4770             else if (strcmp(bioslogofadein, "off") == 0)
    4771             {
    4772                 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(false));
    4773             }
    4774             else
    4775             {
    4776                 errorArgument("Invalid -bioslogofadein argument '%s'", bioslogofadein);
    4777                 rc = E_FAIL;
    4778                 break;
    4779             }
    4780         }
    4781         if (bioslogofadeout)
    4782         {
    4783             if (strcmp(bioslogofadeout, "on") == 0)
    4784             {
    4785                 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(true));
    4786             }
    4787             else if (strcmp(bioslogofadeout, "off") == 0)
    4788             {
    4789                 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(false));
    4790             }
    4791             else
    4792             {
    4793                 errorArgument("Invalid -bioslogofadeout argument '%s'", bioslogofadeout);
    4794                 rc = E_FAIL;
    4795                 break;
    4796             }
    4797         }
    4798         if (bioslogodisplaytime != ~0U)
    4799         {
    4800             CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(bioslogodisplaytime));
    4801         }
    4802         if (bioslogoimagepath)
    4803         {
    4804             CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(bioslogoimagepath)));
    4805         }
    4806         if (biosbootmenumode)
    4807         {
    4808             if (strcmp(biosbootmenumode, "disabled") == 0)
    4809                 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
    4810             else if (strcmp(biosbootmenumode, "menuonly") == 0)
    4811                 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
    4812             else if (strcmp(biosbootmenumode, "messageandmenu") == 0)
    4813                 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
    4814             else
    4815             {
    4816                 errorArgument("Invalid -biosbootmenu argument '%s'", biosbootmenumode);
    4817                 rc = E_FAIL;
    4818                 break;
    4819             }
    4820 
    4821         }
    4822         if (biossystemtimeoffset)
    4823         {
    4824             LONG64 timeOffset = RTStrToInt64(biossystemtimeoffset);
    4825             CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(timeOffset));
    4826         }
    4827         if (biospxedebug)
    4828         {
    4829             if (strcmp(biospxedebug, "on") == 0)
    4830             {
    4831                 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(true));
    4832             }
    4833             else if (strcmp(biospxedebug, "off") == 0)
    4834             {
    4835                 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(false));
    4836             }
    4837             else
    4838             {
    4839                 errorArgument("Invalid -biospxedebug argument '%s'", biospxedebug);
    4840                 rc = E_FAIL;
    4841                 break;
    4842             }
    4843         }
    4844         for (int curBootDev = 0; curBootDev < 4; curBootDev++)
    4845         {
    4846             if (bootDeviceChanged[curBootDev])
    4847                 CHECK_ERROR(machine, SetBootOrder (curBootDev + 1, bootDevice[curBootDev]));
    4848         }
    4849         if (hdds[0])
    4850         {
    4851             if (strcmp(hdds[0], "none") == 0)
    4852             {
    4853                 machine->DetachHardDisk2(StorageBus_IDE, 0, 0);
    4854             }
    4855             else
    4856             {
    4857                 /* first guess is that it's a UUID */
    4858                 Guid uuid(hdds[0]);
    4859                 ComPtr<IHardDisk2> hardDisk;
    4860                 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    4861                 /* not successful? Then it must be a filename */
    4862                 if (!hardDisk)
    4863                 {
    4864                     CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[0]), hardDisk.asOutParam()));
    4865                     if (FAILED(rc))
    4866                     {
    4867                         /* open the new hard disk object */
    4868                         CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[0]), hardDisk.asOutParam()));
    4869                     }
    4870                 }
    4871                 if (hardDisk)
    4872                 {
    4873                     hardDisk->COMGETTER(Id)(uuid.asOutParam());
    4874                     CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 0, 0));
    4875                 }
    4876                 else
    4877                     rc = E_FAIL;
    4878                 if (FAILED(rc))
    4879                     break;
    4880             }
    4881         }
    4882         if (hdds[1])
    4883         {
    4884             if (strcmp(hdds[1], "none") == 0)
    4885             {
    4886                 machine->DetachHardDisk2(StorageBus_IDE, 0, 1);
    4887             }
    4888             else
    4889             {
    4890                 /* first guess is that it's a UUID */
    4891                 Guid uuid(hdds[1]);
    4892                 ComPtr<IHardDisk2> hardDisk;
    4893                 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    4894                 /* not successful? Then it must be a filename */
    4895                 if (!hardDisk)
    4896                 {
    4897                     CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[1]), hardDisk.asOutParam()));
    4898                     if (FAILED(rc))
    4899                     {
    4900                         /* open the new hard disk object */
    4901                         CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[1]), hardDisk.asOutParam()));
    4902                     }
    4903                 }
    4904                 if (hardDisk)
    4905                 {
    4906                     hardDisk->COMGETTER(Id)(uuid.asOutParam());
    4907                     CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 0, 1));
    4908                 }
    4909                 else
    4910                     rc = E_FAIL;
    4911                 if (FAILED(rc))
    4912                     break;
    4913             }
    4914         }
    4915         if (hdds[2])
    4916         {
    4917             if (strcmp(hdds[2], "none") == 0)
    4918             {
    4919                 machine->DetachHardDisk2(StorageBus_IDE, 1, 1);
    4920             }
    4921             else
    4922             {
    4923                 /* first guess is that it's a UUID */
    4924                 Guid uuid(hdds[2]);
    4925                 ComPtr<IHardDisk2> hardDisk;
    4926                 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    4927                 /* not successful? Then it must be a filename */
    4928                 if (!hardDisk)
    4929                 {
    4930                     CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[2]), hardDisk.asOutParam()));
    4931                     if (FAILED(rc))
    4932                     {
    4933                         /* open the new hard disk object */
    4934                         CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[2]), hardDisk.asOutParam()));
    4935                     }
    4936                 }
    4937                 if (hardDisk)
    4938                 {
    4939                     hardDisk->COMGETTER(Id)(uuid.asOutParam());
    4940                     CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 1, 1));
    4941                 }
    4942                 else
    4943                     rc = E_FAIL;
    4944                 if (FAILED(rc))
    4945                     break;
    4946             }
    4947         }
    4948         if (dvd)
    4949         {
    4950             ComPtr<IDVDDrive> dvdDrive;
    4951             machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
    4952             ASSERT(dvdDrive);
    4953 
    4954             /* unmount? */
    4955             if (strcmp(dvd, "none") == 0)
    4956             {
    4957                 CHECK_ERROR(dvdDrive, Unmount());
    4958             }
    4959             /* host drive? */
    4960             else if (strncmp(dvd, "host:", 5) == 0)
    4961             {
    4962                 ComPtr<IHost> host;
    4963                 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    4964                 ComPtr<IHostDVDDriveCollection> hostDVDs;
    4965                 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
    4966                 ComPtr<IHostDVDDrive> hostDVDDrive;
    4967                 rc = hostDVDs->FindByName(Bstr(dvd + 5), hostDVDDrive.asOutParam());
    4968                 if (!hostDVDDrive)
    4969                 {
    4970                     /* 2nd try: try with the real name, important on Linux+libhal */
    4971                     char szPathReal[RTPATH_MAX];
    4972                     if (RT_FAILURE(RTPathReal(dvd + 5, szPathReal, sizeof(szPathReal))))
    4973                     {
    4974                         errorArgument("Invalid host DVD drive name");
    4975                         rc = E_FAIL;
    4976                         break;
    4977                     }
    4978                     rc = hostDVDs->FindByName(Bstr(szPathReal), hostDVDDrive.asOutParam());
    4979                     if (!hostDVDDrive)
    4980                     {
    4981                         errorArgument("Invalid host DVD drive name");
    4982                         rc = E_FAIL;
    4983                         break;
    4984                     }
    4985                 }
    4986                 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
    4987             }
    4988             else
    4989             {
    4990                 /* first assume it's a UUID */
    4991                 Guid uuid(dvd);
    4992                 ComPtr<IDVDImage2> dvdImage;
    4993                 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
    4994                 if (FAILED(rc) || !dvdImage)
    4995                 {
    4996                     /* must be a filename, check if it's in the collection */
    4997                     rc = virtualBox->FindDVDImage(Bstr(dvd), dvdImage.asOutParam());
    4998                     /* not registered, do that on the fly */
    4999                     if (!dvdImage)
    5000                     {
    5001                         Guid emptyUUID;
    5002                         CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(dvd), emptyUUID, dvdImage.asOutParam()));
    5003                     }
    5004                 }
    5005                 if (!dvdImage)
    5006                 {
    5007                     rc = E_FAIL;
    5008                     break;
    5009                 }
    5010 
    5011                 dvdImage->COMGETTER(Id)(uuid.asOutParam());
    5012                 CHECK_ERROR(dvdDrive, MountImage(uuid));
    5013             }
    5014         }
    5015         if (dvdpassthrough)
    5016         {
    5017             ComPtr<IDVDDrive> dvdDrive;
    5018             machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
    5019             ASSERT(dvdDrive);
    5020 
    5021             CHECK_ERROR(dvdDrive, COMSETTER(Passthrough)(strcmp(dvdpassthrough, "on") == 0));
    5022         }
    5023         if (idecontroller)
    5024         {
    5025             if (RTStrICmp(idecontroller, "PIIX3") == 0)
    5026             {
    5027                 CHECK_ERROR(biosSettings, COMSETTER(IDEControllerType)(IDEControllerType_PIIX3));
    5028             }
    5029             else if (RTStrICmp(idecontroller, "PIIX4") == 0)
    5030             {
    5031                 CHECK_ERROR(biosSettings, COMSETTER(IDEControllerType)(IDEControllerType_PIIX4));
    5032             }
    5033             else
    5034             {
    5035                 errorArgument("Invalid -idecontroller argument '%s'", idecontroller);
    5036                 rc = E_FAIL;
    5037                 break;
    5038             }
    5039         }
    5040         if (floppy)
    5041         {
    5042             ComPtr<IFloppyDrive> floppyDrive;
    5043             machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
    5044             ASSERT(floppyDrive);
    5045 
    5046             /* disable? */
    5047             if (strcmp(floppy, "disabled") == 0)
    5048             {
    5049                 /* disable the controller */
    5050                 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(false));
    5051             }
    5052             else
    5053             {
    5054                 /* enable the controller */
    5055                 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(true));
    5056 
    5057                 /* unmount? */
    5058                 if (strcmp(floppy, "empty") == 0)
    5059                 {
    5060                     CHECK_ERROR(floppyDrive, Unmount());
    5061                 }
    5062                 /* host drive? */
    5063                 else if (strncmp(floppy, "host:", 5) == 0)
    5064                 {
    5065                     ComPtr<IHost> host;
    5066                     CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    5067                     ComPtr<IHostFloppyDriveCollection> hostFloppies;
    5068                     CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
    5069                     ComPtr<IHostFloppyDrive> hostFloppyDrive;
    5070                     rc = hostFloppies->FindByName(Bstr(floppy + 5), hostFloppyDrive.asOutParam());
    5071                     if (!hostFloppyDrive)
    5072                     {
    5073                         errorArgument("Invalid host floppy drive name");
    5074                         rc = E_FAIL;
    5075                         break;
    5076                     }
    5077                     CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
    5078                 }
    5079                 else
    5080                 {
    5081                     /* first assume it's a UUID */
    5082                     Guid uuid(floppy);
    5083                     ComPtr<IFloppyImage2> floppyImage;
    5084                     rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
    5085                     if (FAILED(rc) || !floppyImage)
    5086                     {
    5087                         /* must be a filename, check if it's in the collection */
    5088                         rc = virtualBox->FindFloppyImage(Bstr(floppy), floppyImage.asOutParam());
    5089                         /* not registered, do that on the fly */
    5090                         if (!floppyImage)
    5091                         {
    5092                             Guid emptyUUID;
    5093                             CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(floppy), emptyUUID, floppyImage.asOutParam()));
    5094                         }
    5095                     }
    5096                     if (!floppyImage)
    5097                     {
    5098                         rc = E_FAIL;
    5099                         break;
    5100                     }
    5101 
    5102                     floppyImage->COMGETTER(Id)(uuid.asOutParam());
    5103                     CHECK_ERROR(floppyDrive, MountImage(uuid));
    5104                 }
    5105             }
    5106         }
    5107         if (audio || audiocontroller)
    5108         {
    5109             ComPtr<IAudioAdapter> audioAdapter;
    5110             machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
    5111             ASSERT(audioAdapter);
    5112 
    5113             if (audio)
    5114             {
    5115                 /* disable? */
    5116                 if (strcmp(audio, "none") == 0)
    5117                 {
    5118                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(false));
    5119                 }
    5120                 else if (strcmp(audio, "null") == 0)
    5121                 {
    5122                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null));
    5123                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5124                 }
    5125 #ifdef RT_OS_WINDOWS
    5126 #ifdef VBOX_WITH_WINMM
    5127                 else if (strcmp(audio, "winmm") == 0)
    5128                 {
    5129                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM));
    5130                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5131                 }
    5132 #endif
    5133                 else if (strcmp(audio, "dsound") == 0)
    5134                 {
    5135                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound));
    5136                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5137                 }
    5138 #endif /* RT_OS_WINDOWS */
    5139 #ifdef RT_OS_LINUX
    5140                 else if (strcmp(audio, "oss") == 0)
    5141                 {
    5142                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS));
    5143                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5144                 }
    5145 # ifdef VBOX_WITH_ALSA
    5146                 else if (strcmp(audio, "alsa") == 0)
    5147                 {
    5148                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA));
    5149                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5150                 }
    5151 # endif
    5152 # ifdef VBOX_WITH_PULSE
    5153                 else if (strcmp(audio, "pulse") == 0)
    5154                 {
    5155                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse));
    5156                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5157                 }
    5158 # endif
    5159 #endif /* !RT_OS_LINUX */
    5160 #ifdef RT_OS_SOLARIS
    5161                 else if (strcmp(audio, "solaudio") == 0)
    5162                 {
    5163                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_SolAudio));
    5164                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5165                 }
    5166 
    5167 #endif /* !RT_OS_SOLARIS */
    5168 #ifdef RT_OS_DARWIN
    5169                 else if (strcmp(audio, "coreaudio") == 0)
    5170                 {
    5171                     CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio));
    5172                     CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
    5173                 }
    5174 
    5175 #endif /* !RT_OS_DARWIN */
    5176                 else
    5177                 {
    5178                     errorArgument("Invalid -audio argument '%s'", audio);
    5179                     rc = E_FAIL;
    5180                     break;
    5181                 }
    5182             }
    5183             if (audiocontroller)
    5184             {
    5185                 if (strcmp(audiocontroller, "sb16") == 0)
    5186                     CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16));
    5187                 else if (strcmp(audiocontroller, "ac97") == 0)
    5188                     CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97));
    5189                 else
    5190                 {
    5191                     errorArgument("Invalid -audiocontroller argument '%s'", audiocontroller);
    5192                     rc = E_FAIL;
    5193                     break;
    5194                 }
    5195             }
    5196         }
    5197         /* Shared clipboard state */
    5198         if (clipboard)
    5199         {
    5200 /*            ComPtr<IClipboardMode> clipboardMode;
    5201             machine->COMGETTER(ClipboardMode)(clipboardMode.asOutParam());
    5202             ASSERT(clipboardMode);
    5203 */
    5204             if (strcmp(clipboard, "disabled") == 0)
    5205             {
    5206                 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Disabled));
    5207             }
    5208             else if (strcmp(clipboard, "hosttoguest") == 0)
    5209             {
    5210                 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_HostToGuest));
    5211             }
    5212             else if (strcmp(clipboard, "guesttohost") == 0)
    5213             {
    5214                 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_GuestToHost));
    5215             }
    5216             else if (strcmp(clipboard, "bidirectional") == 0)
    5217             {
    5218                 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Bidirectional));
    5219             }
    5220             else
    5221             {
    5222                 errorArgument("Invalid -clipboard argument '%s'", clipboard);
    5223                 rc = E_FAIL;
    5224                 break;
    5225             }
    5226         }
    5227         /* iterate through all possible NICs */
    5228         for (ULONG n = 0; n < NetworkAdapterCount; n ++)
    5229         {
    5230             ComPtr<INetworkAdapter> nic;
    5231             CHECK_ERROR_RET (machine, GetNetworkAdapter (n, nic.asOutParam()), 1);
    5232 
    5233             ASSERT(nic);
    5234 
    5235             /* something about the NIC? */
    5236             if (nics[n])
    5237             {
    5238                 if (strcmp(nics[n], "none") == 0)
    5239                 {
    5240                     CHECK_ERROR_RET(nic, COMSETTER(Enabled) (FALSE), 1);
    5241                 }
    5242                 else if (strcmp(nics[n], "null") == 0)
    5243                 {
    5244                     CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
    5245                     CHECK_ERROR_RET(nic, Detach(), 1);
    5246                 }
    5247                 else if (strcmp(nics[n], "nat") == 0)
    5248                 {
    5249                     CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
    5250                     CHECK_ERROR_RET(nic, AttachToNAT(), 1);
    5251                 }
    5252                 else if (strcmp(nics[n], "hostif") == 0)
    5253                 {
    5254                     CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
    5255                     CHECK_ERROR_RET(nic, AttachToHostInterface(), 1);
    5256                 }
    5257                 else if (strcmp(nics[n], "intnet") == 0)
    5258                 {
    5259                     CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
    5260                     CHECK_ERROR_RET(nic, AttachToInternalNetwork(), 1);
    5261                 }
    5262                 else
    5263                 {
    5264                     errorArgument("Invalid type '%s' specfied for NIC %lu", nics[n], n + 1);
    5265                     rc = E_FAIL;
    5266                     break;
    5267                 }
    5268             }
    5269 
    5270             /* something about the NIC type? */
    5271             if (nictype[n])
    5272             {
    5273                 if (strcmp(nictype[n], "Am79C970A") == 0)
    5274                 {
    5275                     CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A), 1);
    5276                 }
    5277                 else if (strcmp(nictype[n], "Am79C973") == 0)
    5278                 {
    5279                     CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973), 1);
    5280                 }
    5281 #ifdef VBOX_WITH_E1000
    5282                 else if (strcmp(nictype[n], "82540EM") == 0)
    5283                 {
    5284                     CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM), 1);
    5285                 }
    5286                 else if (strcmp(nictype[n], "82543GC") == 0)
    5287                 {
    5288                     CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC), 1);
    5289                 }
    5290 #endif
    5291                 else
    5292                 {
    5293                     errorArgument("Invalid NIC type '%s' specified for NIC %lu", nictype[n], n + 1);
    5294                     rc = E_FAIL;
    5295                     break;
    5296                 }
    5297             }
    5298 
    5299             /* something about the MAC address? */
    5300             if (macs[n])
    5301             {
    5302                 /* generate one? */
    5303                 if (strcmp(macs[n], "auto") == 0)
    5304                 {
    5305                     CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(NULL), 1);
    5306                 }
    5307                 else
    5308                 {
    5309                     CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(Bstr(macs[n])), 1);
    5310                 }
    5311             }
    5312 
    5313             /* something about the reported link speed? */
    5314             if (nicspeed[n])
    5315             {
    5316                 uint32_t    u32LineSpeed;
    5317 
    5318                 u32LineSpeed = atoi(nicspeed[n]);
    5319 
    5320                 if (u32LineSpeed < 1000 || u32LineSpeed > 4000000)
    5321                 {
    5322                     errorArgument("Invalid -nicspeed%lu argument '%s'", n + 1, nicspeed[n]);
    5323                     rc = E_FAIL;
    5324                     break;
    5325                 }
    5326                 CHECK_ERROR_RET(nic, COMSETTER(LineSpeed)(u32LineSpeed), 1);
    5327             }
    5328 
    5329             /* the link status flag? */
    5330             if (cableconnected[n])
    5331             {
    5332                 if (strcmp(cableconnected[n], "on") == 0)
    5333                 {
    5334                     CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(TRUE), 1);
    5335                 }
    5336                 else if (strcmp(cableconnected[n], "off") == 0)
    5337                 {
    5338                     CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(FALSE), 1);
    5339                 }
    5340                 else
    5341                 {
    5342                     errorArgument("Invalid -cableconnected%lu argument '%s'", n + 1, cableconnected[n]);
    5343                     rc = E_FAIL;
    5344                     break;
    5345                 }
    5346             }
    5347 
    5348             /* the trace flag? */
    5349             if (nictrace[n])
    5350             {
    5351                 if (strcmp(nictrace[n], "on") == 0)
    5352                 {
    5353                     CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(TRUE), 1);
    5354                 }
    5355                 else if (strcmp(nictrace[n], "off") == 0)
    5356                 {
    5357                     CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(FALSE), 1);
    5358                 }
    5359                 else
    5360                 {
    5361                     errorArgument("Invalid -nictrace%lu argument '%s'", n + 1, nictrace[n]);
    5362                     rc = E_FAIL;
    5363                     break;
    5364                 }
    5365             }
    5366 
    5367             /* the tracefile flag? */
    5368             if (nictracefile[n])
    5369             {
    5370                 CHECK_ERROR_RET(nic, COMSETTER(TraceFile)(Bstr(nictracefile[n])), 1);
    5371             }
    5372 
    5373             /* the host interface device? */
    5374             if (hostifdev[n])
    5375             {
    5376                 /* remove it? */
    5377                 if (strcmp(hostifdev[n], "none") == 0)
    5378                 {
    5379                     CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(NULL), 1);
    5380                 }
    5381                 else
    5382                 {
    5383                     CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(Bstr(hostifdev[n])), 1);
    5384                 }
    5385             }
    5386 
    5387             /* the internal network name? */
    5388             if (intnet[n])
    5389             {
    5390                 /* remove it? */
    5391                 if (strcmp(intnet[n], "none") == 0)
    5392                 {
    5393                     CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(NULL), 1);
    5394                 }
    5395                 else
    5396                 {
    5397                     CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(Bstr(intnet[n])), 1);
    5398                 }
    5399             }
    5400             /* the network of the NAT */
    5401             if (natnet[n])
    5402             {
    5403                 CHECK_ERROR_RET(nic, COMSETTER(NATNetwork)(Bstr(natnet[n])), 1);
    5404             }
    5405 #ifdef RT_OS_LINUX
    5406             /* the TAP setup application? */
    5407             if (tapsetup[n])
    5408             {
    5409                 /* remove it? */
    5410                 if (strcmp(tapsetup[n], "none") == 0)
    5411                 {
    5412                     CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(NULL), 1);
    5413                 }
    5414                 else
    5415                 {
    5416                     CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(Bstr(tapsetup[n])), 1);
    5417                 }
    5418             }
    5419 
    5420             /* the TAP terminate application? */
    5421             if (tapterm[n])
    5422             {
    5423                 /* remove it? */
    5424                 if (strcmp(tapterm[n], "none") == 0)
    5425                 {
    5426                     CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(NULL), 1);
    5427                 }
    5428                 else
    5429                 {
    5430                     CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(Bstr(tapterm[n])), 1);
    5431                 }
    5432             }
    5433 #endif /* RT_OS_LINUX */
    5434 
    5435         }
    5436         if (FAILED(rc))
    5437             break;
    5438 
    5439         /* iterate through all possible serial ports */
    5440         for (ULONG n = 0; n < SerialPortCount; n ++)
    5441         {
    5442             ComPtr<ISerialPort> uart;
    5443             CHECK_ERROR_RET (machine, GetSerialPort (n, uart.asOutParam()), 1);
    5444 
    5445             ASSERT(uart);
    5446 
    5447             if (uarts_base[n])
    5448             {
    5449                 if (uarts_base[n] == (ULONG)-1)
    5450                 {
    5451                     CHECK_ERROR_RET(uart, COMSETTER(Enabled) (FALSE), 1);
    5452                 }
    5453                 else
    5454                 {
    5455                     CHECK_ERROR_RET(uart, COMSETTER(IOBase) (uarts_base[n]), 1);
    5456                     CHECK_ERROR_RET(uart, COMSETTER(IRQ) (uarts_irq[n]), 1);
    5457                     CHECK_ERROR_RET(uart, COMSETTER(Enabled) (TRUE), 1);
    5458                 }
    5459             }
    5460             if (uarts_mode[n])
    5461             {
    5462                 if (strcmp(uarts_mode[n], "disconnected") == 0)
    5463                 {
    5464                     CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_Disconnected), 1);
    5465                 }
    5466                 else
    5467                 {
    5468                     if (strcmp(uarts_mode[n], "server") == 0)
    5469                     {
    5470                         CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1);
    5471                         CHECK_ERROR_RET(uart, COMSETTER(Server) (TRUE), 1);
    5472                     }
    5473                     else if (strcmp(uarts_mode[n], "client") == 0)
    5474                     {
    5475                         CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1);
    5476                         CHECK_ERROR_RET(uart, COMSETTER(Server) (FALSE), 1);
    5477                     }
    5478                     else
    5479                     {
    5480                         CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostDevice), 1);
    5481                     }
    5482                     CHECK_ERROR_RET(uart, COMSETTER(Path) (Bstr(uarts_path[n])), 1);
    5483                 }
    5484             }
    5485         }
    5486         if (FAILED(rc))
    5487             break;
    5488 
    5489 #ifdef VBOX_WITH_VRDP
    5490         if (vrdp || (vrdpport != UINT16_MAX) || vrdpaddress || vrdpauthtype || vrdpmulticon || vrdpreusecon)
    5491         {
    5492             ComPtr<IVRDPServer> vrdpServer;
    5493             machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
    5494             ASSERT(vrdpServer);
    5495             if (vrdpServer)
    5496             {
    5497                 if (vrdp)
    5498                 {
    5499                     if (strcmp(vrdp, "on") == 0)
    5500                     {
    5501                         CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(true));
    5502                     }
    5503                     else if (strcmp(vrdp, "off") == 0)
    5504                     {
    5505                         CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(false));
    5506                     }
    5507                     else
    5508                     {
    5509                         errorArgument("Invalid -vrdp argument '%s'", vrdp);
    5510                         rc = E_FAIL;
    5511                         break;
    5512                     }
    5513                 }
    5514                 if (vrdpport != UINT16_MAX)
    5515                 {
    5516                     CHECK_ERROR(vrdpServer, COMSETTER(Port)(vrdpport));
    5517                 }
    5518                 if (vrdpaddress)
    5519                 {
    5520                     CHECK_ERROR(vrdpServer, COMSETTER(NetAddress)(Bstr(vrdpaddress)));
    5521                 }
    5522                 if (vrdpauthtype)
    5523                 {
    5524                     if (strcmp(vrdpauthtype, "null") == 0)
    5525                     {
    5526                         CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Null));
    5527                     }
    5528                     else if (strcmp(vrdpauthtype, "external") == 0)
    5529                     {
    5530                         CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_External));
    5531                     }
    5532                     else if (strcmp(vrdpauthtype, "guest") == 0)
    5533                     {
    5534                         CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Guest));
    5535                     }
    5536                     else
    5537                     {
    5538                         errorArgument("Invalid -vrdpauthtype argument '%s'", vrdpauthtype);
    5539                         rc = E_FAIL;
    5540                         break;
    5541                     }
    5542                 }
    5543                 if (vrdpmulticon)
    5544                 {
    5545                     if (strcmp(vrdpmulticon, "on") == 0)
    5546                     {
    5547                         CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(true));
    5548                     }
    5549                     else if (strcmp(vrdpmulticon, "off") == 0)
    5550                     {
    5551                         CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(false));
    5552                     }
    5553                     else
    5554                     {
    5555                         errorArgument("Invalid -vrdpmulticon argument '%s'", vrdpmulticon);
    5556                         rc = E_FAIL;
    5557                         break;
    5558                     }
    5559                 }
    5560                 if (vrdpreusecon)
    5561                 {
    5562                     if (strcmp(vrdpreusecon, "on") == 0)
    5563                     {
    5564                         CHECK_ERROR(vrdpServer, COMSETTER(ReuseSingleConnection)(true));
    5565                     }
    5566                     else if (strcmp(vrdpreusecon, "off") == 0)
    5567                     {
    5568                         CHECK_ERROR(vrdpServer, COMSETTER(ReuseSingleConnection)(false));
    5569                     }
    5570                     else
    5571                     {
    5572                         errorArgument("Invalid -vrdpreusecon argument '%s'", vrdpreusecon);
    5573                         rc = E_FAIL;
    5574                         break;
    5575                     }
    5576                 }
    5577             }
    5578         }
    5579 #endif /* VBOX_WITH_VRDP */
    5580 
    5581         /*
    5582          * USB enable/disable
    5583          */
    5584         if (fUsbEnabled != -1)
    5585         {
    5586             ComPtr<IUSBController> UsbCtl;
    5587             CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam()));
    5588             if (SUCCEEDED(rc))
    5589             {
    5590                 CHECK_ERROR(UsbCtl, COMSETTER(Enabled)(!!fUsbEnabled));
    5591             }
    5592         }
    5593         /*
    5594          * USB EHCI enable/disable
    5595          */
    5596         if (fUsbEhciEnabled != -1)
    5597         {
    5598             ComPtr<IUSBController> UsbCtl;
    5599             CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam()));
    5600             if (SUCCEEDED(rc))
    5601             {
    5602                 CHECK_ERROR(UsbCtl, COMSETTER(EnabledEhci)(!!fUsbEhciEnabled));
    5603             }
    5604         }
    5605 
    5606         if (snapshotFolder)
    5607         {
    5608             if (strcmp(snapshotFolder, "default") == 0)
    5609             {
    5610                 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(NULL));
    5611             }
    5612             else
    5613             {
    5614                 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(snapshotFolder)));
    5615             }
    5616         }
    5617 
    5618         if (guestMemBalloonSize != (ULONG)-1)
    5619             CHECK_ERROR(machine, COMSETTER(MemoryBalloonSize)(guestMemBalloonSize));
    5620 
    5621         if (guestStatInterval != (ULONG)-1)
    5622             CHECK_ERROR(machine, COMSETTER(StatisticsUpdateInterval)(guestStatInterval));
    5623 
    5624         /*
    5625          * SATA controller enable/disable
    5626          */
    5627         if (fSataEnabled != -1)
    5628         {
    5629             ComPtr<ISATAController> SataCtl;
    5630             CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
    5631             if (SUCCEEDED(rc))
    5632             {
    5633                 CHECK_ERROR(SataCtl, COMSETTER(Enabled)(!!fSataEnabled));
    5634             }
    5635         }
    5636 
    5637         for (uint32_t i = 4; i < 34; i++)
    5638         {
    5639             if (hdds[i])
    5640             {
    5641                 if (strcmp(hdds[i], "none") == 0)
    5642                 {
    5643                     machine->DetachHardDisk2(StorageBus_SATA, i-4, 0);
    5644                 }
    5645                 else
    5646                 {
    5647                     /* first guess is that it's a UUID */
    5648                     Guid uuid(hdds[i]);
    5649                     ComPtr<IHardDisk2> hardDisk;
    5650                     rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    5651                     /* not successful? Then it must be a filename */
    5652                     if (!hardDisk)
    5653                     {
    5654                         CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[i]), hardDisk.asOutParam()));
    5655                         if (FAILED(rc))
    5656                         {
    5657                             /* open the new hard disk object */
    5658                             CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[i]), hardDisk.asOutParam()));
    5659                         }
    5660                     }
    5661                     if (hardDisk)
    5662                     {
    5663                         hardDisk->COMGETTER(Id)(uuid.asOutParam());
    5664                         CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_SATA, i-4, 0));
    5665                     }
    5666                     else
    5667                         rc = E_FAIL;
    5668                     if (FAILED(rc))
    5669                         break;
    5670                 }
    5671             }
    5672         }
    5673 
    5674         for (uint32_t i = 0; i < 4; i++)
    5675         {
    5676             if (sataBootDevices[i] != -1)
    5677             {
    5678                 ComPtr<ISATAController> SataCtl;
    5679                 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
    5680                 if (SUCCEEDED(rc))
    5681                 {
    5682                     CHECK_ERROR(SataCtl, SetIDEEmulationPort(i, sataBootDevices[i]));
    5683                 }
    5684             }
    5685         }
    5686 
    5687         if (sataPortCount != -1)
    5688         {
    5689             ComPtr<ISATAController> SataCtl;
    5690             CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
    5691             if (SUCCEEDED(rc))
    5692             {
    5693                 CHECK_ERROR(SataCtl, COMSETTER(PortCount)(sataPortCount));
    5694             }
    5695         }
    5696 
    5697         /* commit changes */
    5698         CHECK_ERROR(machine, SaveSettings());
    5699     }
    5700     while (0);
    5701 
    5702     /* it's important to always close sessions */
    5703     session->Close();
    5704 
    5705     return SUCCEEDED(rc) ? 0 : 1;
    5706 }
    5707 
    5708 static int handleStartVM(int argc, char *argv[],
    5709                          ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    5710 {
    5711     HRESULT rc;
    5712 
    5713     if (argc < 1)
    5714         return errorSyntax(USAGE_STARTVM, "Not enough parameters");
    5715 
    5716     ComPtr<IMachine> machine;
    5717     /* assume it's a UUID */
    5718     rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    5719     if (FAILED(rc) || !machine)
    5720     {
    5721         /* must be a name */
    5722         CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    5723     }
    5724     if (machine)
    5725     {
    5726         Guid uuid;
    5727         machine->COMGETTER(Id)(uuid.asOutParam());
    5728 
    5729         /* default to GUI session type */
    5730         Bstr sessionType = "gui";
    5731         /* has a session type been specified? */
    5732         if ((argc > 2) && (strcmp(argv[1], "-type") == 0))
    5733         {
    5734             if (strcmp(argv[2], "gui") == 0)
    5735             {
    5736                 sessionType = "gui";
    5737             }
    5738             else if (strcmp(argv[2], "vrdp") == 0)
    5739             {
    5740                 sessionType = "vrdp";
    5741             }
    5742             else if (strcmp(argv[2], "capture") == 0)
    5743             {
    5744                 sessionType = "capture";
    5745             }
    5746             else
    5747                 return errorArgument("Invalid session type argument '%s'", argv[2]);
    5748         }
    5749 
    5750         Bstr env;
    5751 #ifdef RT_OS_LINUX
    5752         /* make sure the VM process will start on the same display as VBoxManage */
    5753         {
    5754             const char *display = RTEnvGet ("DISPLAY");
    5755             if (display)
    5756                 env = Utf8StrFmt ("DISPLAY=%s", display);
    5757         }
    5758 #endif
    5759         ComPtr<IProgress> progress;
    5760         CHECK_ERROR_RET(virtualBox, OpenRemoteSession(session, uuid, sessionType,
    5761                                                       env, progress.asOutParam()), rc);
    5762         RTPrintf("Waiting for the remote session to open...\n");
    5763         CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1);
    5764 
    5765         BOOL completed;
    5766         CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc);
    5767         ASSERT(completed);
    5768 
    5769         HRESULT resultCode;
    5770         CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&resultCode), rc);
    5771         if (FAILED(resultCode))
    5772         {
    5773             ComPtr <IVirtualBoxErrorInfo> errorInfo;
    5774             CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1);
    5775             ErrorInfo info (errorInfo);
    5776             PRINT_ERROR_INFO(info);
    5777         }
    5778         else
    5779         {
    5780             RTPrintf("Remote session has been successfully opened.\n");
    5781         }
    5782     }
    5783 
    5784     /* it's important to always close sessions */
    5785     session->Close();
    5786 
    5787     return SUCCEEDED(rc) ? 0 : 1;
    5788 }
    5789 
    5790 static int handleControlVM(int argc, char *argv[],
    5791                            ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    5792 {
    5793     HRESULT rc;
    5794 
    5795     if (argc < 2)
    5796         return errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
    5797 
    5798     /* try to find the given machine */
    5799     ComPtr <IMachine> machine;
    5800     Guid uuid (argv[0]);
    5801     if (!uuid.isEmpty())
    5802     {
    5803         CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
    5804     }
    5805     else
    5806     {
    5807         CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
    5808         if (SUCCEEDED (rc))
    5809             machine->COMGETTER(Id) (uuid.asOutParam());
    5810     }
    5811     if (FAILED (rc))
    5812         return 1;
    5813 
    5814     /* open a session for the VM */
    5815     CHECK_ERROR_RET (virtualBox, OpenExistingSession (session, uuid), 1);
    5816 
    5817     do
    5818     {
    5819         /* get the associated console */
    5820         ComPtr<IConsole> console;
    5821         CHECK_ERROR_BREAK (session, COMGETTER(Console)(console.asOutParam()));
    5822         /* ... and session machine */
    5823         ComPtr<IMachine> sessionMachine;
    5824         CHECK_ERROR_BREAK (session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    5825 
    5826         /* which command? */
    5827         if (strcmp(argv[1], "pause") == 0)
    5828         {
    5829             CHECK_ERROR_BREAK (console, Pause());
    5830         }
    5831         else if (strcmp(argv[1], "resume") == 0)
    5832         {
    5833             CHECK_ERROR_BREAK (console, Resume());
    5834         }
    5835         else if (strcmp(argv[1], "reset") == 0)
    5836         {
    5837             CHECK_ERROR_BREAK (console, Reset());
    5838         }
    5839         else if (strcmp(argv[1], "poweroff") == 0)
    5840         {
    5841             CHECK_ERROR_BREAK (console, PowerDown());
    5842         }
    5843         else if (strcmp(argv[1], "savestate") == 0)
    5844         {
    5845             ComPtr<IProgress> progress;
    5846             CHECK_ERROR_BREAK (console, SaveState(progress.asOutParam()));
    5847 
    5848             showProgress(progress);
    5849 
    5850             progress->COMGETTER(ResultCode)(&rc);
    5851             if (FAILED(rc))
    5852             {
    5853                 com::ProgressErrorInfo info(progress);
    5854                 if (info.isBasicAvailable())
    5855                 {
    5856                     RTPrintf("Error: failed to save machine state. Error message: %lS\n", info.getText().raw());
    5857                 }
    5858                 else
    5859                 {
    5860                     RTPrintf("Error: failed to save machine state. No error message available!\n");
    5861                 }
    5862             }
    5863         }
    5864         else if (strcmp(argv[1], "acpipowerbutton") == 0)
    5865         {
    5866             CHECK_ERROR_BREAK (console, PowerButton());
    5867         }
    5868         else if (strcmp(argv[1], "acpisleepbutton") == 0)
    5869         {
    5870             CHECK_ERROR_BREAK (console, SleepButton());
    5871         }
    5872         else if (strcmp(argv[1], "injectnmi") == 0)
    5873         {
    5874             /* get the machine debugger. */
    5875             ComPtr <IMachineDebugger> debugger;
    5876             CHECK_ERROR_BREAK(console, COMGETTER(Debugger)(debugger.asOutParam()));
    5877             CHECK_ERROR_BREAK(debugger, InjectNMI());
    5878         }
    5879         else if (strcmp(argv[1], "keyboardputscancode") == 0)
    5880         {
    5881             ComPtr<IKeyboard> keyboard;
    5882             CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(keyboard.asOutParam()));
    5883 
    5884             if (argc <= 1 + 1)
    5885             {
    5886                 errorArgument("Missing argument to '%s'. Expected IBM PC AT set 2 keyboard scancode(s) as hex byte(s).", argv[1]);
    5887                 rc = E_FAIL;
    5888                 break;
    5889             }
    5890 
    5891             /* Arbitrary restrict the length of a sequence of scancodes to 1024. */
    5892             LONG alScancodes[1024];
    5893             int cScancodes = 0;
    5894 
    5895             /* Process the command line. */
    5896             int i;
    5897             for (i = 1 + 1; i < argc && cScancodes < (int)RT_ELEMENTS(alScancodes); i++, cScancodes++)
    5898             {
    5899                 if (   isxdigit (argv[i][0])
    5900                     && isxdigit (argv[i][1])
    5901                     && argv[i][2] == 0)
    5902                 {
    5903                     uint8_t u8Scancode;
    5904                     int rc = RTStrToUInt8Ex(argv[i], NULL, 16, &u8Scancode);
    5905                     if (RT_FAILURE (rc))
    5906                     {
    5907                         RTPrintf("Error: converting '%s' returned %Rrc!\n", argv[i], rc);
    5908                         rc = E_FAIL;
    5909                         break;
    5910                     }
    5911 
    5912                     alScancodes[cScancodes] = u8Scancode;
    5913                 }
    5914                 else
    5915                 {
    5916                     RTPrintf("Error: '%s' is not a hex byte!\n", argv[i]);
    5917                     rc = E_FAIL;
    5918                     break;
    5919                 }
    5920             }
    5921 
    5922             if (FAILED(rc))
    5923                 break;
    5924 
    5925             if (   cScancodes == RT_ELEMENTS(alScancodes)
    5926                 && i < argc)
    5927             {
    5928                 RTPrintf("Error: too many scancodes, maximum %d allowed!\n", RT_ELEMENTS(alScancodes));
    5929                 rc = E_FAIL;
    5930                 break;
    5931             }
    5932 
    5933             /* Send scancodes to the VM.
    5934              * Note: 'PutScancodes' did not work here. Only the first scancode was transmitted.
    5935              */
    5936             for (i = 0; i < cScancodes; i++)
    5937             {
    5938                 CHECK_ERROR_BREAK(keyboard, PutScancode(alScancodes[i]));
    5939                 RTPrintf("Scancode[%d]: 0x%02X\n", i, alScancodes[i]);
    5940             }
    5941         }
    5942         else if (strncmp(argv[1], "setlinkstate", 12) == 0)
    5943         {
    5944             /* Get the number of network adapters */
    5945             ULONG NetworkAdapterCount = 0;
    5946             ComPtr <ISystemProperties> info;
    5947             CHECK_ERROR_BREAK (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));
    5948             CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));
    5949 
    5950             unsigned n = parseNum(&argv[1][12], NetworkAdapterCount, "NIC");
    5951             if (!n)
    5952             {
    5953                 rc = E_FAIL;
    5954                 break;
    5955             }
    5956             if (argc <= 1 + 1)
    5957             {
    5958                 errorArgument("Missing argument to '%s'", argv[1]);
    5959                 rc = E_FAIL;
    5960                 break;
    5961             }
    5962             /* get the corresponding network adapter */
    5963             ComPtr<INetworkAdapter> adapter;
    5964             CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
    5965             if (adapter)
    5966             {
    5967                 if (strcmp(argv[2], "on") == 0)
    5968                 {
    5969                     CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(TRUE));
    5970                 }
    5971                 else if (strcmp(argv[2], "off") == 0)
    5972                 {
    5973                     CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(FALSE));
    5974                 }
    5975                 else
    5976                 {
    5977                     errorArgument("Invalid link state '%s'", Utf8Str(argv[2]).raw());
    5978                     rc = E_FAIL;
    5979                     break;
    5980                 }
    5981             }
    5982         }
    5983         else if (strcmp (argv[1], "usbattach") == 0 ||
    5984                  strcmp (argv[1], "usbdetach") == 0)
    5985         {
    5986             if (argc < 3)
    5987             {
    5988                 errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
    5989                 rc = E_FAIL;
    5990                 break;
    5991             }
    5992 
    5993             bool attach = strcmp (argv[1], "usbattach") == 0;
    5994 
    5995             Guid usbId = argv [2];
    5996             if (usbId.isEmpty())
    5997             {
    5998                 // assume address
    5999                 if (attach)
    6000                 {
    6001                     ComPtr <IHost> host;
    6002                     CHECK_ERROR_BREAK (virtualBox, COMGETTER(Host) (host.asOutParam()));
    6003                     ComPtr <IHostUSBDeviceCollection> coll;
    6004                     CHECK_ERROR_BREAK (host, COMGETTER(USBDevices) (coll.asOutParam()));
    6005                     ComPtr <IHostUSBDevice> dev;
    6006                     CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
    6007                     CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
    6008                 }
    6009                 else
    6010                 {
    6011                     ComPtr <IUSBDeviceCollection> coll;
    6012                     CHECK_ERROR_BREAK (console, COMGETTER(USBDevices)(coll.asOutParam()));
    6013                     ComPtr <IUSBDevice> dev;
    6014                     CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
    6015                     CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
    6016                 }
    6017             }
    6018 
    6019             if (attach)
    6020                 CHECK_ERROR_BREAK (console, AttachUSBDevice (usbId));
    6021             else
    6022             {
    6023                 ComPtr <IUSBDevice> dev;
    6024                 CHECK_ERROR_BREAK (console, DetachUSBDevice (usbId, dev.asOutParam()));
    6025             }
    6026         }
    6027         else if (strcmp(argv[1], "setvideomodehint") == 0)
    6028         {
    6029             if (argc != 5 && argc != 6)
    6030             {
    6031                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6032                 rc = E_FAIL;
    6033                 break;
    6034             }
    6035             uint32_t xres = atoi(argv[2]);
    6036             uint32_t yres = atoi(argv[3]);
    6037             uint32_t bpp  = atoi(argv[4]);
    6038             uint32_t displayIdx = 0;
    6039             if (argc == 6)
    6040                 displayIdx = atoi(argv[5]);
    6041 
    6042             ComPtr<IDisplay> display;
    6043             CHECK_ERROR_BREAK(console, COMGETTER(Display)(display.asOutParam()));
    6044             CHECK_ERROR_BREAK(display, SetVideoModeHint(xres, yres, bpp, displayIdx));
    6045         }
    6046         else if (strcmp(argv[1], "setcredentials") == 0)
    6047         {
    6048             bool fAllowLocalLogon = true;
    6049             if (argc == 7)
    6050             {
    6051                 if (strcmp(argv[5], "-allowlocallogon") != 0)
    6052                 {
    6053                     errorArgument("Invalid parameter '%s'", argv[5]);
    6054                     rc = E_FAIL;
    6055                     break;
    6056                 }
    6057                 if (strcmp(argv[6], "no") == 0)
    6058                     fAllowLocalLogon = false;
    6059             }
    6060             else if (argc != 5)
    6061             {
    6062                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6063                 rc = E_FAIL;
    6064                 break;
    6065             }
    6066 
    6067             ComPtr<IGuest> guest;
    6068             CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
    6069             CHECK_ERROR_BREAK(guest, SetCredentials(Bstr(argv[2]), Bstr(argv[3]), Bstr(argv[4]), fAllowLocalLogon));
    6070         }
    6071         else if (strcmp(argv[1], "dvdattach") == 0)
    6072         {
    6073             if (argc != 3)
    6074             {
    6075                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6076                 rc = E_FAIL;
    6077                 break;
    6078             }
    6079             ComPtr<IDVDDrive> dvdDrive;
    6080             sessionMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
    6081             ASSERT(dvdDrive);
    6082 
    6083             /* unmount? */
    6084             if (strcmp(argv[2], "none") == 0)
    6085             {
    6086                 CHECK_ERROR(dvdDrive, Unmount());
    6087             }
    6088             /* host drive? */
    6089             else if (strncmp(argv[2], "host:", 5) == 0)
    6090             {
    6091                 ComPtr<IHost> host;
    6092                 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    6093                 ComPtr<IHostDVDDriveCollection> hostDVDs;
    6094                 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
    6095                 ComPtr<IHostDVDDrive> hostDVDDrive;
    6096                 rc = hostDVDs->FindByName(Bstr(argv[2] + 5), hostDVDDrive.asOutParam());
    6097                 if (!hostDVDDrive)
    6098                 {
    6099                     errorArgument("Invalid host DVD drive name");
    6100                     rc = E_FAIL;
    6101                     break;
    6102                 }
    6103                 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
    6104             }
    6105             else
    6106             {
    6107                 /* first assume it's a UUID */
    6108                 Guid uuid(argv[2]);
    6109                 ComPtr<IDVDImage2> dvdImage;
    6110                 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
    6111                 if (FAILED(rc) || !dvdImage)
    6112                 {
    6113                     /* must be a filename, check if it's in the collection */
    6114                     rc = virtualBox->FindDVDImage(Bstr(argv[2]), dvdImage.asOutParam());
    6115                     /* not registered, do that on the fly */
    6116                     if (!dvdImage)
    6117                     {
    6118                         Guid emptyUUID;
    6119                         CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(argv[2]), emptyUUID, dvdImage.asOutParam()));
    6120                     }
    6121                 }
    6122                 if (!dvdImage)
    6123                 {
    6124                     rc = E_FAIL;
    6125                     break;
    6126                 }
    6127                 dvdImage->COMGETTER(Id)(uuid.asOutParam());
    6128                 CHECK_ERROR(dvdDrive, MountImage(uuid));
    6129             }
    6130         }
    6131         else if (strcmp(argv[1], "floppyattach") == 0)
    6132         {
    6133             if (argc != 3)
    6134             {
    6135                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6136                 rc = E_FAIL;
    6137                 break;
    6138             }
    6139 
    6140             ComPtr<IFloppyDrive> floppyDrive;
    6141             sessionMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
    6142             ASSERT(floppyDrive);
    6143 
    6144             /* unmount? */
    6145             if (strcmp(argv[2], "none") == 0)
    6146             {
    6147                 CHECK_ERROR(floppyDrive, Unmount());
    6148             }
    6149             /* host drive? */
    6150             else if (strncmp(argv[2], "host:", 5) == 0)
    6151             {
    6152                 ComPtr<IHost> host;
    6153                 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
    6154                 ComPtr<IHostFloppyDriveCollection> hostFloppies;
    6155                 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
    6156                 ComPtr<IHostFloppyDrive> hostFloppyDrive;
    6157                 rc = hostFloppies->FindByName(Bstr(argv[2] + 5), hostFloppyDrive.asOutParam());
    6158                 if (!hostFloppyDrive)
    6159                 {
    6160                     errorArgument("Invalid host floppy drive name");
    6161                     rc = E_FAIL;
    6162                     break;
    6163                 }
    6164                 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
    6165             }
    6166             else
    6167             {
    6168                 /* first assume it's a UUID */
    6169                 Guid uuid(argv[2]);
    6170                 ComPtr<IFloppyImage2> floppyImage;
    6171                 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
    6172                 if (FAILED(rc) || !floppyImage)
    6173                 {
    6174                     /* must be a filename, check if it's in the collection */
    6175                     rc = virtualBox->FindFloppyImage(Bstr(argv[2]), floppyImage.asOutParam());
    6176                     /* not registered, do that on the fly */
    6177                     if (!floppyImage)
    6178                     {
    6179                         Guid emptyUUID;
    6180                         CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(argv[2]), emptyUUID, floppyImage.asOutParam()));
    6181                     }
    6182                 }
    6183                 if (!floppyImage)
    6184                 {
    6185                     rc = E_FAIL;
    6186                     break;
    6187                 }
    6188                 floppyImage->COMGETTER(Id)(uuid.asOutParam());
    6189                 CHECK_ERROR(floppyDrive, MountImage(uuid));
    6190             }
    6191         }
    6192 #ifdef VBOX_WITH_MEM_BALLOONING
    6193         else if (strncmp(argv[1], "-guestmemoryballoon", 19) == 0)
    6194         {
    6195             if (argc != 3)
    6196             {
    6197                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6198                 rc = E_FAIL;
    6199                 break;
    6200             }
    6201             uint32_t uVal;
    6202             int vrc;
    6203             vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);
    6204             if (vrc != VINF_SUCCESS)
    6205             {
    6206                 errorArgument("Error parsing guest memory balloon size '%s'", argv[2]);
    6207                 rc = E_FAIL;
    6208                 break;
    6209             }
    6210 
    6211             /* guest is running; update IGuest */
    6212             ComPtr <IGuest> guest;
    6213 
    6214             rc = console->COMGETTER(Guest)(guest.asOutParam());
    6215             if (SUCCEEDED(rc))
    6216                 CHECK_ERROR(guest, COMSETTER(MemoryBalloonSize)(uVal));
    6217         }
    6218 #endif
    6219         else if (strncmp(argv[1], "-gueststatisticsinterval", 24) == 0)
    6220         {
    6221             if (argc != 3)
    6222             {
    6223                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    6224                 rc = E_FAIL;
    6225                 break;
    6226             }
    6227             uint32_t uVal;
    6228             int vrc;
    6229             vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);
    6230             if (vrc != VINF_SUCCESS)
    6231             {
    6232                 errorArgument("Error parsing guest statistics interval '%s'", argv[2]);
    6233                 rc = E_FAIL;
    6234                 break;
    6235             }
    6236 
    6237             /* guest is running; update IGuest */
    6238             ComPtr <IGuest> guest;
    6239 
    6240             rc = console->COMGETTER(Guest)(guest.asOutParam());
    6241             if (SUCCEEDED(rc))
    6242                 CHECK_ERROR(guest, COMSETTER(StatisticsUpdateInterval)(uVal));
    6243         }
    6244         else
    6245         {
    6246             errorSyntax(USAGE_CONTROLVM, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    6247             rc = E_FAIL;
    6248         }
    6249     }
    6250     while (0);
    6251 
    6252     session->Close();
    6253 
    6254     return SUCCEEDED (rc) ? 0 : 1;
    6255 }
    6256 
    6257 static int handleDiscardState(int argc, char *argv[],
    6258                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6259 {
    6260     HRESULT rc;
    6261 
    6262     if (argc != 1)
    6263         return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");
    6264 
    6265     ComPtr<IMachine> machine;
    6266     /* assume it's a UUID */
    6267     rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    6268     if (FAILED(rc) || !machine)
    6269     {
    6270         /* must be a name */
    6271         CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    6272     }
    6273     if (machine)
    6274     {
    6275         do
    6276         {
    6277             /* we have to open a session for this task */
    6278             Guid guid;
    6279             machine->COMGETTER(Id)(guid.asOutParam());
    6280             CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
    6281             do
    6282             {
    6283                 ComPtr<IConsole> console;
    6284                 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
    6285                 CHECK_ERROR_BREAK(console, DiscardSavedState());
    6286             }
    6287             while (0);
    6288             CHECK_ERROR_BREAK(session, Close());
    6289         }
    6290         while (0);
    6291     }
    6292 
    6293     return SUCCEEDED(rc) ? 0 : 1;
    6294 }
    6295 
    6296 static int handleAdoptdState(int argc, char *argv[],
    6297                              ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6298 {
    6299     HRESULT rc;
    6300 
    6301     if (argc != 2)
    6302         return errorSyntax(USAGE_ADOPTSTATE, "Incorrect number of parameters");
    6303 
    6304     ComPtr<IMachine> machine;
    6305     /* assume it's a UUID */
    6306     rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    6307     if (FAILED(rc) || !machine)
    6308     {
    6309         /* must be a name */
    6310         CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    6311     }
    6312     if (machine)
    6313     {
    6314         do
    6315         {
    6316             /* we have to open a session for this task */
    6317             Guid guid;
    6318             machine->COMGETTER(Id)(guid.asOutParam());
    6319             CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
    6320             do
    6321             {
    6322                 ComPtr<IConsole> console;
    6323                 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
    6324                 CHECK_ERROR_BREAK(console, AdoptSavedState (Bstr (argv[1])));
    6325             }
    6326             while (0);
    6327             CHECK_ERROR_BREAK(session, Close());
    6328         }
    6329         while (0);
    6330     }
    6331 
    6332     return SUCCEEDED(rc) ? 0 : 1;
    6333 }
    6334 
    6335 static int handleSnapshot(int argc, char *argv[],
    6336                           ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6337 {
    6338     HRESULT rc;
    6339 
    6340     /* we need at least a VM and a command */
    6341     if (argc < 2)
    6342         return errorSyntax(USAGE_SNAPSHOT, "Not enough parameters");
    6343 
    6344     /* the first argument must be the VM */
    6345     ComPtr<IMachine> machine;
    6346     /* assume it's a UUID */
    6347     rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    6348     if (FAILED(rc) || !machine)
    6349     {
    6350         /* must be a name */
    6351         CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    6352     }
    6353     if (!machine)
    6354         return 1;
    6355     Guid guid;
    6356     machine->COMGETTER(Id)(guid.asOutParam());
    6357 
    6358     do
    6359     {
    6360         /* we have to open a session for this task. First try an existing session */
    6361         rc = virtualBox->OpenExistingSession(session, guid);
    6362         if (FAILED(rc))
    6363             CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
    6364         ComPtr<IConsole> console;
    6365         CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
    6366 
    6367         /* switch based on the command */
    6368         if (strcmp(argv[1], "take") == 0)
    6369         {
    6370             /* there must be a name */
    6371             if (argc < 3)
    6372             {
    6373                 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
    6374                 rc = E_FAIL;
    6375                 break;
    6376             }
    6377             Bstr name(argv[2]);
    6378             if ((argc > 3) && ((argc != 5) || (strcmp(argv[3], "-desc") != 0)))
    6379             {
    6380                 errorSyntax(USAGE_SNAPSHOT, "Incorrect description format");
    6381                 rc = E_FAIL;
    6382                 break;
    6383             }
    6384             Bstr desc;
    6385             if (argc == 5)
    6386                 desc = argv[4];
    6387             ComPtr<IProgress> progress;
    6388             CHECK_ERROR_BREAK(console, TakeSnapshot(name, desc, progress.asOutParam()));
    6389 
    6390             showProgress(progress);
    6391             progress->COMGETTER(ResultCode)(&rc);
    6392             if (FAILED(rc))
    6393             {
    6394                 com::ProgressErrorInfo info(progress);
    6395                 if (info.isBasicAvailable())
    6396                     RTPrintf("Error: failed to take snapshot. Error message: %lS\n", info.getText().raw());
    6397                 else
    6398                     RTPrintf("Error: failed to take snapshot. No error message available!\n");
    6399             }
    6400         }
    6401         else if (strcmp(argv[1], "discard") == 0)
    6402         {
    6403             /* exactly one parameter: snapshot name */
    6404             if (argc != 3)
    6405             {
    6406                 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
    6407                 rc = E_FAIL;
    6408                 break;
    6409             }
    6410 
    6411             ComPtr<ISnapshot> snapshot;
    6412 
    6413             /* assume it's a UUID */
    6414             Guid guid(argv[2]);
    6415             if (!guid.isEmpty())
    6416             {
    6417                 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
    6418             }
    6419             else
    6420             {
    6421                 /* then it must be a name */
    6422                 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
    6423             }
    6424 
    6425             snapshot->COMGETTER(Id)(guid.asOutParam());
    6426 
    6427             ComPtr<IProgress> progress;
    6428             CHECK_ERROR_BREAK(console, DiscardSnapshot(guid, progress.asOutParam()));
    6429 
    6430             showProgress(progress);
    6431             progress->COMGETTER(ResultCode)(&rc);
    6432             if (FAILED(rc))
    6433             {
    6434                 com::ProgressErrorInfo info(progress);
    6435                 if (info.isBasicAvailable())
    6436                     RTPrintf("Error: failed to discard snapshot. Error message: %lS\n", info.getText().raw());
    6437                 else
    6438                     RTPrintf("Error: failed to discard snapshot. No error message available!\n");
    6439             }
    6440         }
    6441         else if (strcmp(argv[1], "discardcurrent") == 0)
    6442         {
    6443             if (   (argc != 3)
    6444                 || (   (strcmp(argv[2], "-state") != 0)
    6445                     && (strcmp(argv[2], "-all") != 0)))
    6446             {
    6447                 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
    6448                 rc = E_FAIL;
    6449                 break;
    6450             }
    6451             bool fAll = false;
    6452             if (strcmp(argv[2], "-all") == 0)
    6453                 fAll = true;
    6454 
    6455             ComPtr<IProgress> progress;
    6456 
    6457             if (fAll)
    6458             {
    6459                 CHECK_ERROR_BREAK(console, DiscardCurrentSnapshotAndState(progress.asOutParam()));
    6460             }
    6461             else
    6462             {
    6463                 CHECK_ERROR_BREAK(console, DiscardCurrentState(progress.asOutParam()));
    6464             }
    6465 
    6466             showProgress(progress);
    6467             progress->COMGETTER(ResultCode)(&rc);
    6468             if (FAILED(rc))
    6469             {
    6470                 com::ProgressErrorInfo info(progress);
    6471                 if (info.isBasicAvailable())
    6472                     RTPrintf("Error: failed to discard. Error message: %lS\n", info.getText().raw());
    6473                 else
    6474                     RTPrintf("Error: failed to discard. No error message available!\n");
    6475             }
    6476 
    6477         }
    6478         else if (strcmp(argv[1], "edit") == 0)
    6479         {
    6480             if (argc < 3)
    6481             {
    6482                 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
    6483                 rc = E_FAIL;
    6484                 break;
    6485             }
    6486 
    6487             ComPtr<ISnapshot> snapshot;
    6488 
    6489             if (strcmp(argv[2], "-current") == 0)
    6490             {
    6491                 CHECK_ERROR_BREAK(machine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam()));
    6492             }
    6493             else
    6494             {
    6495                 /* assume it's a UUID */
    6496                 Guid guid(argv[2]);
    6497                 if (!guid.isEmpty())
    6498                 {
    6499                     CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
    6500                 }
    6501                 else
    6502                 {
    6503                     /* then it must be a name */
    6504                     CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
    6505                 }
    6506             }
    6507 
    6508             /* parse options */
    6509             for (int i = 3; i < argc; i++)
    6510             {
    6511                 if (strcmp(argv[i], "-newname") == 0)
    6512                 {
    6513                     if (argc <= i + 1)
    6514                     {
    6515                         errorArgument("Missing argument to '%s'", argv[i]);
    6516                         rc = E_FAIL;
    6517                         break;
    6518                     }
    6519                     i++;
    6520                     snapshot->COMSETTER(Name)(Bstr(argv[i]));
    6521                 }
    6522                 else if (strcmp(argv[i], "-newdesc") == 0)
    6523                 {
    6524                     if (argc <= i + 1)
    6525                     {
    6526                         errorArgument("Missing argument to '%s'", argv[i]);
    6527                         rc = E_FAIL;
    6528                         break;
    6529                     }
    6530                     i++;
    6531                     snapshot->COMSETTER(Description)(Bstr(argv[i]));
    6532                 }
    6533                 else
    6534                 {
    6535                     errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    6536                     rc = E_FAIL;
    6537                     break;
    6538                 }
    6539             }
    6540 
    6541         }
    6542         else if (strcmp(argv[1], "showvminfo") == 0)
    6543         {
    6544             /* exactly one parameter: snapshot name */
    6545             if (argc != 3)
    6546             {
    6547                 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
    6548                 rc = E_FAIL;
    6549                 break;
    6550             }
    6551 
    6552             ComPtr<ISnapshot> snapshot;
    6553 
    6554             /* assume it's a UUID */
    6555             Guid guid(argv[2]);
    6556             if (!guid.isEmpty())
    6557             {
    6558                 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
    6559             }
    6560             else
    6561             {
    6562                 /* then it must be a name */
    6563                 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
    6564             }
    6565 
    6566             /* get the machine of the given snapshot */
    6567             ComPtr<IMachine> machine;
    6568             snapshot->COMGETTER(Machine)(machine.asOutParam());
    6569             showVMInfo(virtualBox, machine, console);
    6570         }
    6571         else
    6572         {
    6573             errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    6574             rc = E_FAIL;
    6575         }
    6576     } while (0);
    6577 
    6578     session->Close();
    6579 
    6580     return SUCCEEDED(rc) ? 0 : 1;
    6581 }
    6582 
    6583 static int handleShowHardDiskInfo(int argc, char *argv[],
    6584                                   ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6585 {
    6586     HRESULT rc;
    6587 
    6588     if (argc != 1)
    6589         return errorSyntax(USAGE_SHOWHDINFO, "Incorrect number of parameters");
    6590 
    6591     ComPtr<IHardDisk2> hardDisk;
    6592     Bstr filepath;
    6593 
    6594     bool unknown = false;
    6595 
    6596     /* first guess is that it's a UUID */
    6597     Guid uuid(argv[0]);
    6598     rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    6599     /* no? then it must be a filename */
    6600     if (FAILED (rc))
    6601     {
    6602         filepath = argv[0];
    6603         rc = virtualBox->FindHardDisk2(filepath, hardDisk.asOutParam());
    6604         /* no? well, then it's an unkwnown image */
    6605         if (FAILED (rc))
    6606         {
    6607             CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
    6608             if (SUCCEEDED (rc))
    6609             {
    6610                 unknown = true;
    6611             }
    6612         }
    6613     }
    6614     do
    6615     {
    6616         if (!SUCCEEDED(rc))
    6617             break;
    6618 
    6619         hardDisk->COMGETTER(Id)(uuid.asOutParam());
    6620         RTPrintf("UUID:                 %s\n", uuid.toString().raw());
    6621 
    6622         /* check for accessibility */
    6623         /// @todo NEWMEDIA check accessibility of all parents
    6624         /// @todo NEWMEDIA print the full state value
    6625         MediaState_T state;
    6626         CHECK_ERROR_BREAK (hardDisk, COMGETTER(State)(&state));
    6627         RTPrintf("Accessible:           %s\n", state != MediaState_Inaccessible ? "yes" : "no");
    6628 
    6629         if (state == MediaState_Inaccessible)
    6630         {
    6631             Bstr err;
    6632             CHECK_ERROR_BREAK (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
    6633             RTPrintf("Access Error:         %lS\n", err.raw());
    6634         }
    6635 
    6636         Bstr description;
    6637         hardDisk->COMGETTER(Description)(description.asOutParam());
    6638         if (description)
    6639         {
    6640             RTPrintf("Description:          %lS\n", description.raw());
    6641         }
    6642 
    6643         ULONG64 logicalSize;
    6644         hardDisk->COMGETTER(LogicalSize)(&logicalSize);
    6645         RTPrintf("Logical size:         %llu MBytes\n", logicalSize);
    6646         ULONG64 actualSize;
    6647         hardDisk->COMGETTER(Size)(&actualSize);
    6648         RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);
    6649 
    6650         HardDiskType_T type;
    6651         hardDisk->COMGETTER(Type)(&type);
    6652         const char *typeStr = "unknown";
    6653         switch (type)
    6654         {
    6655             case HardDiskType_Normal:
    6656                 typeStr = "normal";
    6657                 break;
    6658             case HardDiskType_Immutable:
    6659                 typeStr = "immutable";
    6660                 break;
    6661             case HardDiskType_Writethrough:
    6662                 typeStr = "writethrough";
    6663                 break;
    6664         }
    6665         RTPrintf("Type:                 %s\n", typeStr);
    6666 
    6667         Bstr format;
    6668         hardDisk->COMGETTER(Format)(format.asOutParam());
    6669         RTPrintf("Storage format:       %lS\n", format.raw());
    6670 
    6671         if (!unknown)
    6672         {
    6673             com::SafeGUIDArray machineIds;
    6674             hardDisk->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
    6675             for (size_t j = 0; j < machineIds.size(); ++ j)
    6676             {
    6677                 ComPtr<IMachine> machine;
    6678                 CHECK_ERROR(virtualBox, GetMachine(machineIds[j], machine.asOutParam()));
    6679                 ASSERT(machine);
    6680                 Bstr name;
    6681                 machine->COMGETTER(Name)(name.asOutParam());
    6682                 machine->COMGETTER(Id)(uuid.asOutParam());
    6683                 RTPrintf("%s%lS (UUID: %RTuuid)\n",
    6684                          j == 0 ? "In use by VMs:        " : "                      ",
    6685                          name.raw(), &machineIds[j]);
    6686             }
    6687             /// @todo NEWMEDIA check usage in snapshots too
    6688             /// @todo NEWMEDIA also list children and say 'differencing' for
    6689             /// hard disks with the parent or 'base' otherwise.
    6690         }
    6691 
    6692         Bstr loc;
    6693         hardDisk->COMGETTER(Location)(loc.asOutParam());
    6694         RTPrintf("Location:             %lS\n", loc.raw());
    6695     }
    6696     while (0);
    6697 
    6698     if (unknown)
    6699     {
    6700         /* close the unknown hard disk to forget it again */
    6701         hardDisk->Close();
    6702     }
    6703 
    6704     return SUCCEEDED(rc) ? 0 : 1;
    6705 }
    6706 
    6707 static int handleOpenMedium(int argc, char *argv[],
    6708                             ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6709 {
    6710     HRESULT rc;
    6711 
    6712     if (argc < 2)
    6713         return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");
    6714 
    6715     Bstr filepath(argv[1]);
    6716 
    6717     if (strcmp(argv[0], "disk") == 0)
    6718     {
    6719         const char *type = NULL;
    6720         /* there can be a type parameter */
    6721         if ((argc > 2) && (argc != 4))
    6722             return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");
    6723         if (argc == 4)
    6724         {
    6725             if (strcmp(argv[2], "-type") != 0)
    6726                 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
    6727             if (   (strcmp(argv[3], "normal") != 0)
    6728                 && (strcmp(argv[3], "immutable") != 0)
    6729                 && (strcmp(argv[3], "writethrough") != 0))
    6730                 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(argv[3]).raw());
    6731             type = argv[3];
    6732         }
    6733 
    6734         ComPtr<IHardDisk2> hardDisk;
    6735         CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
    6736         if (SUCCEEDED(rc) && hardDisk)
    6737         {
    6738             /* change the type if requested */
    6739             if (type)
    6740             {
    6741                 if (strcmp(type, "normal") == 0)
    6742                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
    6743                 else if (strcmp(type, "immutable") == 0)
    6744                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
    6745                 else if (strcmp(type, "writethrough") == 0)
    6746                     CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
    6747             }
    6748         }
    6749     }
    6750     else if (strcmp(argv[0], "dvd") == 0)
    6751     {
    6752         ComPtr<IDVDImage2> dvdImage;
    6753         CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));
    6754     }
    6755     else if (strcmp(argv[0], "floppy") == 0)
    6756     {
    6757         ComPtr<IFloppyImage2> floppyImage;
    6758         CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));
    6759     }
    6760     else
    6761         return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    6762 
    6763     return SUCCEEDED(rc) ? 0 : 1;
    6764 }
    6765 
    6766 static int handleCloseMedium(int argc, char *argv[],
    6767                              ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6768 {
    6769     HRESULT rc;
    6770 
    6771     if (argc != 2)
    6772         return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");
    6773 
    6774     /* first guess is that it's a UUID */
    6775     Guid uuid(argv[1]);
    6776 
    6777     if (strcmp(argv[0], "disk") == 0)
    6778     {
    6779         ComPtr<IHardDisk2> hardDisk;
    6780         rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
    6781         /* not a UUID or not registered? Then it must be a filename */
    6782         if (!hardDisk)
    6783         {
    6784             CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(argv[1]), hardDisk.asOutParam()));
    6785         }
    6786         if (SUCCEEDED(rc) && hardDisk)
    6787         {
    6788             CHECK_ERROR(hardDisk, Close());
    6789         }
    6790     }
    6791     else
    6792     if (strcmp(argv[0], "dvd") == 0)
    6793     {
    6794         ComPtr<IDVDImage2> dvdImage;
    6795         rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
    6796         /* not a UUID or not registered? Then it must be a filename */
    6797         if (!dvdImage)
    6798         {
    6799             CHECK_ERROR(virtualBox, FindDVDImage(Bstr(argv[1]), dvdImage.asOutParam()));
    6800         }
    6801         if (SUCCEEDED(rc) && dvdImage)
    6802         {
    6803             CHECK_ERROR(dvdImage, Close());
    6804         }
    6805     }
    6806     else
    6807     if (strcmp(argv[0], "floppy") == 0)
    6808     {
    6809         ComPtr<IFloppyImage2> floppyImage;
    6810         rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
    6811         /* not a UUID or not registered? Then it must be a filename */
    6812         if (!floppyImage)
    6813         {
    6814             CHECK_ERROR(virtualBox, FindFloppyImage(Bstr(argv[1]), floppyImage.asOutParam()));
    6815         }
    6816         if (SUCCEEDED(rc) && floppyImage)
    6817         {
    6818             CHECK_ERROR(floppyImage, Close());
    6819         }
    6820     }
    6821     else
    6822         return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    6823 
    6824     return SUCCEEDED(rc) ? 0 : 1;
    6825 }
    6826 
    6827 #ifdef RT_OS_WINDOWS
    6828 static int handleCreateHostIF(int argc, char *argv[],
    6829                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6830 {
    6831     if (argc != 1)
    6832         return errorSyntax(USAGE_CREATEHOSTIF, "Incorrect number of parameters");
    6833 
    6834     HRESULT rc = S_OK;
    6835 
    6836     do
    6837     {
    6838         ComPtr<IHost> host;
    6839         CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
    6840 
    6841         ComPtr<IHostNetworkInterface> hostif;
    6842         ComPtr<IProgress> progress;
    6843         CHECK_ERROR_BREAK(host,
    6844             CreateHostNetworkInterface(Bstr(argv[0]),
    6845                                        hostif.asOutParam(),
    6846                                        progress.asOutParam()));
    6847 
    6848         showProgress(progress);
    6849         HRESULT result;
    6850         CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
    6851         if (FAILED(result))
    6852         {
    6853             com::ProgressErrorInfo info(progress);
    6854             PRINT_ERROR_INFO(info);
    6855             rc = result;
    6856         }
    6857     }
    6858     while (0);
    6859 
    6860     return SUCCEEDED(rc) ? 0 : 1;
    6861 }
    6862 
    6863 static int handleRemoveHostIF(int argc, char *argv[],
    6864                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6865 {
    6866     if (argc != 1)
    6867         return errorSyntax(USAGE_REMOVEHOSTIF, "Incorrect number of parameters");
    6868 
    6869     HRESULT rc = S_OK;
    6870 
    6871     do
    6872     {
    6873         ComPtr<IHost> host;
    6874         CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
    6875 
    6876         ComPtr<IHostNetworkInterface> hostif;
    6877 
    6878         /* first guess is that it's a UUID */
    6879         Guid uuid(argv[0]);
    6880         if (uuid.isEmpty())
    6881         {
    6882             /* not a valid UUID, search for it */
    6883             ComPtr<IHostNetworkInterfaceCollection> coll;
    6884             CHECK_ERROR_BREAK(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
    6885             CHECK_ERROR_BREAK(coll, FindByName(Bstr(argv[0]), hostif.asOutParam()));
    6886             CHECK_ERROR_BREAK(hostif, COMGETTER(Id)(uuid.asOutParam()));
    6887         }
    6888 
    6889         ComPtr<IProgress> progress;
    6890         CHECK_ERROR_BREAK(host,
    6891             RemoveHostNetworkInterface(uuid,
    6892                                        hostif.asOutParam(),
    6893                                        progress.asOutParam()));
    6894 
    6895         showProgress(progress);
    6896         HRESULT result;
    6897         CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
    6898         if (FAILED(result))
    6899         {
    6900             com::ProgressErrorInfo info(progress);
    6901             PRINT_ERROR_INFO(info);
    6902             rc = result;
    6903         }
    6904     }
    6905     while (0);
    6906 
    6907     return SUCCEEDED(rc) ? 0 : 1;
    6908 }
    6909 #endif /* RT_OS_WINDOWS */
    6910 
    6911 static int handleGetExtraData(int argc, char *argv[],
    6912                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6913 {
    6914     HRESULT rc = S_OK;
    6915 
    6916     if (argc != 2)
    6917         return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");
    6918 
    6919     /* global data? */
    6920     if (strcmp(argv[0], "global") == 0)
    6921     {
    6922         /* enumeration? */
    6923         if (strcmp(argv[1], "enumerate") == 0)
    6924         {
    6925             Bstr extraDataKey;
    6926 
    6927             do
    6928             {
    6929                 Bstr nextExtraDataKey;
    6930                 Bstr nextExtraDataValue;
    6931                 HRESULT rcEnum = virtualBox->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
    6932                                                                  nextExtraDataValue.asOutParam());
    6933                 extraDataKey = nextExtraDataKey;
    6934 
    6935                 if (SUCCEEDED(rcEnum) && extraDataKey)
    6936                     RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
    6937             } while (extraDataKey);
    6938         }
    6939         else
    6940         {
    6941             Bstr value;
    6942             CHECK_ERROR(virtualBox, GetExtraData(Bstr(argv[1]), value.asOutParam()));
    6943             if (value)
    6944                 RTPrintf("Value: %lS\n", value.raw());
    6945             else
    6946                 RTPrintf("No value set!\n");
    6947         }
    6948     }
    6949     else
    6950     {
    6951         ComPtr<IMachine> machine;
    6952         /* assume it's a UUID */
    6953         rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    6954         if (FAILED(rc) || !machine)
    6955         {
    6956             /* must be a name */
    6957             CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    6958         }
    6959         if (machine)
    6960         {
    6961             /* enumeration? */
    6962             if (strcmp(argv[1], "enumerate") == 0)
    6963             {
    6964                 Bstr extraDataKey;
    6965 
    6966                 do
    6967                 {
    6968                     Bstr nextExtraDataKey;
    6969                     Bstr nextExtraDataValue;
    6970                     HRESULT rcEnum = machine->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
    6971                                                                   nextExtraDataValue.asOutParam());
    6972                     extraDataKey = nextExtraDataKey;
    6973 
    6974                     if (SUCCEEDED(rcEnum) && extraDataKey)
    6975                     {
    6976                         RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
    6977                     }
    6978                 } while (extraDataKey);
    6979             }
    6980             else
    6981             {
    6982                 Bstr value;
    6983                 CHECK_ERROR(machine, GetExtraData(Bstr(argv[1]), value.asOutParam()));
    6984                 if (value)
    6985                     RTPrintf("Value: %lS\n", value.raw());
    6986                 else
    6987                     RTPrintf("No value set!\n");
    6988             }
    6989         }
    6990     }
    6991     return SUCCEEDED(rc) ? 0 : 1;
    6992 }
    6993 
    6994 static int handleSetExtraData(int argc, char *argv[],
    6995                               ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    6996 {
    6997     HRESULT rc = S_OK;
    6998 
    6999     if (argc < 2)
    7000         return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");
    7001 
    7002     /* global data? */
    7003     if (strcmp(argv[0], "global") == 0)
    7004     {
    7005         if (argc < 3)
    7006             CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), NULL));
    7007         else if (argc == 3)
    7008             CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
    7009         else
    7010             return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
    7011     }
    7012     else
    7013     {
    7014         ComPtr<IMachine> machine;
    7015         /* assume it's a UUID */
    7016         rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
    7017         if (FAILED(rc) || !machine)
    7018         {
    7019             /* must be a name */
    7020             CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    7021         }
    7022         if (machine)
    7023         {
    7024             if (argc < 3)
    7025                 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), NULL));
    7026             else if (argc == 3)
    7027                 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
    7028             else
    7029                 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
    7030         }
    7031     }
    7032     return SUCCEEDED(rc) ? 0 : 1;
    7033 }
    7034 
    7035 static int handleSetProperty(int argc, char *argv[],
    7036                              ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    7037 {
    7038     HRESULT rc;
    7039 
    7040     /* there must be two arguments: property name and value */
    7041     if (argc != 2)
    7042         return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");
    7043 
    7044     ComPtr<ISystemProperties> systemProperties;
    7045     virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
    7046 
    7047     if (strcmp(argv[0], "hdfolder") == 0)
    7048     {
    7049         /* reset to default? */
    7050         if (strcmp(argv[1], "default") == 0)
    7051             CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(NULL));
    7052         else
    7053             CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(Bstr(argv[1])));
    7054     }
    7055     else if (strcmp(argv[0], "machinefolder") == 0)
    7056     {
    7057         /* reset to default? */
    7058         if (strcmp(argv[1], "default") == 0)
    7059             CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
    7060         else
    7061             CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(argv[1])));
    7062     }
    7063     else if (strcmp(argv[0], "vrdpauthlibrary") == 0)
    7064     {
    7065         /* reset to default? */
    7066         if (strcmp(argv[1], "default") == 0)
    7067             CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));
    7068         else
    7069             CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(argv[1])));
    7070     }
    7071     else if (strcmp(argv[0], "websrvauthlibrary") == 0)
    7072     {
    7073         /* reset to default? */
    7074         if (strcmp(argv[1], "default") == 0)
    7075             CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));
    7076         else
    7077             CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(argv[1])));
    7078     }
    7079     else if (strcmp(argv[0], "hwvirtexenabled") == 0)
    7080     {
    7081         if (strcmp(argv[1], "yes") == 0)
    7082             CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(TRUE));
    7083         else if (strcmp(argv[1], "no") == 0)
    7084             CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(FALSE));
    7085         else
    7086             return errorArgument("Invalid value '%s' for hardware virtualization extension flag", argv[1]);
    7087     }
    7088     else if (strcmp(argv[0], "loghistorycount") == 0)
    7089     {
    7090         uint32_t uVal;
    7091         int vrc;
    7092         vrc = RTStrToUInt32Ex(argv[1], NULL, 0, &uVal);
    7093         if (vrc != VINF_SUCCESS)
    7094             return errorArgument("Error parsing Log history count '%s'", argv[1]);
    7095         CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));
    7096     }
    7097     else
    7098         return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", argv[0]);
    7099 
    7100     return SUCCEEDED(rc) ? 0 : 1;
    7101 }
    7102 
    7103 static int handleUSBFilter (int argc, char *argv[],
    7104                             ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    7105 {
    7106     HRESULT rc = S_OK;
    7107     USBFilterCmd cmd;
    7108 
    7109     /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
    7110     if (argc < 4)
    7111         return errorSyntax(USAGE_USBFILTER, "Not enough parameters");
    7112 
    7113     /* which command? */
    7114     cmd.mAction = USBFilterCmd::Invalid;
    7115     if      (strcmp (argv [0], "add") == 0)     cmd.mAction = USBFilterCmd::Add;
    7116     else if (strcmp (argv [0], "modify") == 0)  cmd.mAction = USBFilterCmd::Modify;
    7117     else if (strcmp (argv [0], "remove") == 0)  cmd.mAction = USBFilterCmd::Remove;
    7118 
    7119     if (cmd.mAction == USBFilterCmd::Invalid)
    7120         return errorSyntax(USAGE_USBFILTER, "Invalid parameter '%s'", argv[0]);
    7121 
    7122     /* which index? */
    7123     char *endptr = NULL;
    7124     cmd.mIndex = strtoul (argv[1], &endptr, 10);
    7125     if (!endptr || *endptr)
    7126         return errorSyntax(USAGE_USBFILTER, "Invalid index '%s'", argv[1]);
    7127 
    7128     switch (cmd.mAction)
    7129     {
    7130         case USBFilterCmd::Add:
    7131         case USBFilterCmd::Modify:
    7132         {
    7133             /* at least: 0: command, 1: index, 2: -target, 3: <target value>, 4: -name, 5: <name value> */
    7134             if (argc < 6)
    7135             {
    7136                 if (cmd.mAction == USBFilterCmd::Add)
    7137                     return errorSyntax(USAGE_USBFILTER_ADD, "Not enough parameters");
    7138 
    7139                 return errorSyntax(USAGE_USBFILTER_MODIFY, "Not enough parameters");
    7140             }
    7141 
    7142             // set Active to true by default
    7143             // (assuming that the user sets up all necessary attributes
    7144             // at once and wants the filter to be active immediately)
    7145             if (cmd.mAction == USBFilterCmd::Add)
    7146                 cmd.mFilter.mActive = true;
    7147 
    7148             for (int i = 2; i < argc; i++)
    7149             {
    7150                 if  (strcmp(argv [i], "-target") == 0)
    7151                 {
    7152                     if (argc <= i + 1 || !*argv[i+1])
    7153                         return errorArgument("Missing argument to '%s'", argv[i]);
    7154                     i++;
    7155                     if (strcmp (argv [i], "global") == 0)
    7156                         cmd.mGlobal = true;
    7157                     else
    7158                     {
    7159                         /* assume it's a UUID of a machine */
    7160                         rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
    7161                         if (FAILED(rc) || !cmd.mMachine)
    7162                         {
    7163                             /* must be a name */
    7164                             CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
    7165                         }
    7166                     }
    7167                 }
    7168                 else if (strcmp(argv [i], "-name") == 0)
    7169                 {
    7170                     if (argc <= i + 1 || !*argv[i+1])
    7171                         return errorArgument("Missing argument to '%s'", argv[i]);
    7172                     i++;
    7173                     cmd.mFilter.mName = argv [i];
    7174                 }
    7175                 else if (strcmp(argv [i], "-active") == 0)
    7176                 {
    7177                     if (argc <= i + 1)
    7178                         return errorArgument("Missing argument to '%s'", argv[i]);
    7179                     i++;
    7180                     if (strcmp (argv [i], "yes") == 0)
    7181                         cmd.mFilter.mActive = true;
    7182                     else if (strcmp (argv [i], "no") == 0)
    7183                         cmd.mFilter.mActive = false;
    7184                     else
    7185                         return errorArgument("Invalid -active argument '%s'", argv[i]);
    7186                 }
    7187                 else if (strcmp(argv [i], "-vendorid") == 0)
    7188                 {
    7189                     if (argc <= i + 1)
    7190                         return errorArgument("Missing argument to '%s'", argv[i]);
    7191                     i++;
    7192                     cmd.mFilter.mVendorId = argv [i];
    7193                 }
    7194                 else if (strcmp(argv [i], "-productid") == 0)
    7195                 {
    7196                     if (argc <= i + 1)
    7197                         return errorArgument("Missing argument to '%s'", argv[i]);
    7198                     i++;
    7199                     cmd.mFilter.mProductId = argv [i];
    7200                 }
    7201                 else if (strcmp(argv [i], "-revision") == 0)
    7202                 {
    7203                     if (argc <= i + 1)
    7204                         return errorArgument("Missing argument to '%s'", argv[i]);
    7205                     i++;
    7206                     cmd.mFilter.mRevision = argv [i];
    7207                 }
    7208                 else if (strcmp(argv [i], "-manufacturer") == 0)
    7209                 {
    7210                     if (argc <= i + 1)
    7211                         return errorArgument("Missing argument to '%s'", argv[i]);
    7212                     i++;
    7213                     cmd.mFilter.mManufacturer = argv [i];
    7214                 }
    7215                 else if (strcmp(argv [i], "-product") == 0)
    7216                 {
    7217                     if (argc <= i + 1)
    7218                         return errorArgument("Missing argument to '%s'", argv[i]);
    7219                     i++;
    7220                     cmd.mFilter.mProduct = argv [i];
    7221                 }
    7222                 else if (strcmp(argv [i], "-remote") == 0)
    7223                 {
    7224                     if (argc <= i + 1)
    7225                         return errorArgument("Missing argument to '%s'", argv[i]);
    7226                     i++;
    7227                     cmd.mFilter.mRemote = argv[i];
    7228                 }
    7229                 else if (strcmp(argv [i], "-serialnumber") == 0)
    7230                 {
    7231                     if (argc <= i + 1)
    7232                         return errorArgument("Missing argument to '%s'", argv[i]);
    7233                     i++;
    7234                     cmd.mFilter.mSerialNumber = argv [i];
    7235                 }
    7236                 else if (strcmp(argv [i], "-maskedinterfaces") == 0)
    7237                 {
    7238                     if (argc <= i + 1)
    7239                         return errorArgument("Missing argument to '%s'", argv[i]);
    7240                     i++;
    7241                     uint32_t u32;
    7242                     rc = RTStrToUInt32Full(argv[i], 0, &u32);
    7243                     if (RT_FAILURE(rc))
    7244                         return errorArgument("Failed to convert the -maskedinterfaces value '%s' to a number, rc=%Rrc", argv[i], rc);
    7245                     cmd.mFilter.mMaskedInterfaces = u32;
    7246                 }
    7247                 else if (strcmp(argv [i], "-action") == 0)
    7248                 {
    7249                     if (argc <= i + 1)
    7250                         return errorArgument("Missing argument to '%s'", argv[i]);
    7251                     i++;
    7252                     if (strcmp (argv [i], "ignore") == 0)
    7253                         cmd.mFilter.mAction = USBDeviceFilterAction_Ignore;
    7254                     else if (strcmp (argv [i], "hold") == 0)
    7255                         cmd.mFilter.mAction = USBDeviceFilterAction_Hold;
    7256                     else
    7257                         return errorArgument("Invalid USB filter action '%s'", argv[i]);
    7258                 }
    7259                 else
    7260                     return errorSyntax(cmd.mAction == USBFilterCmd::Add ? USAGE_USBFILTER_ADD : USAGE_USBFILTER_MODIFY,
    7261                                        "Unknown option '%s'", argv[i]);
    7262             }
    7263 
    7264             if (cmd.mAction == USBFilterCmd::Add)
    7265             {
    7266                 // mandatory/forbidden options
    7267                 if (   cmd.mFilter.mName.isEmpty()
    7268                     ||
    7269                        (   cmd.mGlobal
    7270                         && cmd.mFilter.mAction == USBDeviceFilterAction_Null
    7271                        )
    7272                     || (   !cmd.mGlobal
    7273                         && !cmd.mMachine)
    7274                     || (   cmd.mGlobal
    7275                         && cmd.mFilter.mRemote)
    7276                    )
    7277                 {
    7278                     return errorSyntax(USAGE_USBFILTER_ADD, "Mandatory options not supplied");
    7279                 }
    7280             }
    7281             break;
    7282         }
    7283 
    7284         case USBFilterCmd::Remove:
    7285         {
    7286             /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
    7287             if (argc < 4)
    7288                 return errorSyntax(USAGE_USBFILTER_REMOVE, "Not enough parameters");
    7289 
    7290             for (int i = 2; i < argc; i++)
    7291             {
    7292                 if  (strcmp(argv [i], "-target") == 0)
    7293                 {
    7294                     if (argc <= i + 1 || !*argv[i+1])
    7295                         return errorArgument("Missing argument to '%s'", argv[i]);
    7296                     i++;
    7297                     if (strcmp (argv [i], "global") == 0)
    7298                         cmd.mGlobal = true;
    7299                     else
    7300                     {
    7301                         /* assume it's a UUID of a machine */
    7302                         rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
    7303                         if (FAILED(rc) || !cmd.mMachine)
    7304                         {
    7305                             /* must be a name */
    7306                             CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
    7307                         }
    7308                     }
    7309                 }
    7310             }
    7311 
    7312             // mandatory options
    7313             if (!cmd.mGlobal && !cmd.mMachine)
    7314                 return errorSyntax(USAGE_USBFILTER_REMOVE, "Mandatory options not supplied");
    7315 
    7316             break;
    7317         }
    7318 
    7319         default: break;
    7320     }
    7321 
    7322     USBFilterCmd::USBFilter &f = cmd.mFilter;
    7323 
    7324     ComPtr <IHost> host;
    7325     ComPtr <IUSBController> ctl;
    7326     if (cmd.mGlobal)
    7327         CHECK_ERROR_RET (aVirtualBox, COMGETTER(Host) (host.asOutParam()), 1);
    7328     else
    7329     {
    7330         Guid uuid;
    7331         cmd.mMachine->COMGETTER(Id)(uuid.asOutParam());
    7332         /* open a session for the VM */
    7333         CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
    7334         /* get the mutable session machine */
    7335         aSession->COMGETTER(Machine)(cmd.mMachine.asOutParam());
    7336         /* and get the USB controller */
    7337         CHECK_ERROR_RET (cmd.mMachine, COMGETTER(USBController) (ctl.asOutParam()), 1);
    7338     }
    7339 
    7340     switch (cmd.mAction)
    7341     {
    7342         case USBFilterCmd::Add:
    7343         {
    7344             if (cmd.mGlobal)
    7345             {
    7346                 ComPtr <IHostUSBDeviceFilter> flt;
    7347                 CHECK_ERROR_BREAK (host, CreateUSBDeviceFilter (f.mName, flt.asOutParam()));
    7348 
    7349                 if (!f.mActive.isNull())
    7350                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
    7351                 if (!f.mVendorId.isNull())
    7352                     CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
    7353                 if (!f.mProductId.isNull())
    7354                     CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
    7355                 if (!f.mRevision.isNull())
    7356                     CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
    7357                 if (!f.mManufacturer.isNull())
    7358                     CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
    7359                 if (!f.mSerialNumber.isNull())
    7360                     CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
    7361                 if (!f.mMaskedInterfaces.isNull())
    7362                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
    7363 
    7364                 if (f.mAction != USBDeviceFilterAction_Null)
    7365                     CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
    7366 
    7367                 CHECK_ERROR_BREAK (host, InsertUSBDeviceFilter (cmd.mIndex, flt));
    7368             }
    7369             else
    7370             {
    7371                 ComPtr <IUSBDeviceFilter> flt;
    7372                 CHECK_ERROR_BREAK (ctl, CreateDeviceFilter (f.mName, flt.asOutParam()));
    7373 
    7374                 if (!f.mActive.isNull())
    7375                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
    7376                 if (!f.mVendorId.isNull())
    7377                     CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
    7378                 if (!f.mProductId.isNull())
    7379                     CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
    7380                 if (!f.mRevision.isNull())
    7381                     CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
    7382                 if (!f.mManufacturer.isNull())
    7383                     CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
    7384                 if (!f.mRemote.isNull())
    7385                     CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
    7386                 if (!f.mSerialNumber.isNull())
    7387                     CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
    7388                 if (!f.mMaskedInterfaces.isNull())
    7389                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
    7390 
    7391                 CHECK_ERROR_BREAK (ctl, InsertDeviceFilter (cmd.mIndex, flt));
    7392             }
    7393             break;
    7394         }
    7395         case USBFilterCmd::Modify:
    7396         {
    7397             if (cmd.mGlobal)
    7398             {
    7399                 ComPtr <IHostUSBDeviceFilterCollection> coll;
    7400                 CHECK_ERROR_BREAK (host, COMGETTER(USBDeviceFilters) (coll.asOutParam()));
    7401                 ComPtr <IHostUSBDeviceFilter> flt;
    7402                 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
    7403 
    7404                 if (!f.mName.isNull())
    7405                     CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
    7406                 if (!f.mActive.isNull())
    7407                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
    7408                 if (!f.mVendorId.isNull())
    7409                     CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
    7410                 if (!f.mProductId.isNull())
    7411                     CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
    7412                 if (!f.mRevision.isNull())
    7413                     CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
    7414                 if (!f.mManufacturer.isNull())
    7415                     CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
    7416                 if (!f.mSerialNumber.isNull())
    7417                     CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
    7418                 if (!f.mMaskedInterfaces.isNull())
    7419                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
    7420 
    7421                 if (f.mAction != USBDeviceFilterAction_Null)
    7422                     CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
    7423             }
    7424             else
    7425             {
    7426                 ComPtr <IUSBDeviceFilterCollection> coll;
    7427                 CHECK_ERROR_BREAK (ctl, COMGETTER(DeviceFilters) (coll.asOutParam()));
    7428 
    7429                 ComPtr <IUSBDeviceFilter> flt;
    7430                 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
    7431 
    7432                 if (!f.mName.isNull())
    7433                     CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
    7434                 if (!f.mActive.isNull())
    7435                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
    7436                 if (!f.mVendorId.isNull())
    7437                     CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
    7438                 if (!f.mProductId.isNull())
    7439                     CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
    7440                 if (!f.mRevision.isNull())
    7441                     CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
    7442                 if (!f.mManufacturer.isNull())
    7443                     CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
    7444                 if (!f.mRemote.isNull())
    7445                     CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
    7446                 if (!f.mSerialNumber.isNull())
    7447                     CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
    7448                 if (!f.mMaskedInterfaces.isNull())
    7449                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
    7450             }
    7451             break;
    7452         }
    7453         case USBFilterCmd::Remove:
    7454         {
    7455             if (cmd.mGlobal)
    7456             {
    7457                 ComPtr <IHostUSBDeviceFilter> flt;
    7458                 CHECK_ERROR_BREAK (host, RemoveUSBDeviceFilter (cmd.mIndex, flt.asOutParam()));
    7459             }
    7460             else
    7461             {
    7462                 ComPtr <IUSBDeviceFilter> flt;
    7463                 CHECK_ERROR_BREAK (ctl, RemoveDeviceFilter (cmd.mIndex, flt.asOutParam()));
    7464             }
    7465             break;
    7466         }
    7467         default:
    7468             break;
    7469     }
    7470 
    7471     if (cmd.mMachine)
    7472     {
    7473         /* commit and close the session */
    7474         CHECK_ERROR(cmd.mMachine, SaveSettings());
    7475         aSession->Close();
    7476     }
    7477 
    7478     return SUCCEEDED (rc) ? 0 : 1;
    7479 }
    7480 
    7481 static int handleSharedFolder (int argc, char *argv[],
    7482                                ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    7483 {
    7484     HRESULT rc;
    7485 
    7486     /* we need at least a command and target */
    7487     if (argc < 2)
    7488         return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
    7489 
    7490     ComPtr<IMachine> machine;
    7491     /* assume it's a UUID */
    7492     rc = aVirtualBox->GetMachine(Guid(argv[1]), machine.asOutParam());
    7493     if (FAILED(rc) || !machine)
    7494     {
    7495         /* must be a name */
    7496         CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[1]), machine.asOutParam()));
    7497     }
    7498     if (!machine)
    7499         return 1;
    7500     Guid uuid;
    7501     machine->COMGETTER(Id)(uuid.asOutParam());
    7502 
    7503     if (strcmp(argv[0], "add") == 0)
    7504     {
    7505         /* we need at least four more parameters */
    7506         if (argc < 5)
    7507             return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");
    7508 
    7509         char *name = NULL;
    7510         char *hostpath = NULL;
    7511         bool fTransient = false;
    7512         bool fWritable = true;
    7513 
    7514         for (int i = 2; i < argc; i++)
    7515         {
    7516             if (strcmp(argv[i], "-name") == 0)
    7517             {
    7518                 if (argc <= i + 1 || !*argv[i+1])
    7519                     return errorArgument("Missing argument to '%s'", argv[i]);
    7520                 i++;
    7521                 name = argv[i];
    7522             }
    7523             else if (strcmp(argv[i], "-hostpath") == 0)
    7524             {
    7525                 if (argc <= i + 1 || !*argv[i+1])
    7526                     return errorArgument("Missing argument to '%s'", argv[i]);
    7527                 i++;
    7528                 hostpath = argv[i];
    7529             }
    7530             else if (strcmp(argv[i], "-readonly") == 0)
    7531             {
    7532                 fWritable = false;
    7533             }
    7534             else if (strcmp(argv[i], "-transient") == 0)
    7535             {
    7536                 fTransient = true;
    7537             }
    7538             else
    7539                 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    7540         }
    7541 
    7542         if (NULL != strstr(name, " "))
    7543             return errorSyntax(USAGE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");
    7544 
    7545         /* required arguments */
    7546         if (!name || !hostpath)
    7547         {
    7548             return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters -name and -hostpath are required");
    7549         }
    7550 
    7551         if (fTransient)
    7552         {
    7553             ComPtr <IConsole> console;
    7554 
    7555             /* open an existing session for the VM */
    7556             CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
    7557             /* get the session machine */
    7558             CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
    7559             /* get the session console */
    7560             CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
    7561 
    7562             CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
    7563 
    7564             if (console)
    7565                 aSession->Close();
    7566         }
    7567         else
    7568         {
    7569             /* open a session for the VM */
    7570             CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
    7571 
    7572             /* get the mutable session machine */
    7573             aSession->COMGETTER(Machine)(machine.asOutParam());
    7574 
    7575             CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
    7576 
    7577             if (SUCCEEDED(rc))
    7578                 CHECK_ERROR(machine, SaveSettings());
    7579 
    7580             aSession->Close();
    7581         }
    7582     }
    7583     else if (strcmp(argv[0], "remove") == 0)
    7584     {
    7585         /* we need at least two more parameters */
    7586         if (argc < 3)
    7587             return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");
    7588 
    7589         char *name = NULL;
    7590         bool fTransient = false;
    7591 
    7592         for (int i = 2; i < argc; i++)
    7593         {
    7594             if (strcmp(argv[i], "-name") == 0)
    7595             {
    7596                 if (argc <= i + 1 || !*argv[i+1])
    7597                     return errorArgument("Missing argument to '%s'", argv[i]);
    7598                 i++;
    7599                 name = argv[i];
    7600             }
    7601             else if (strcmp(argv[i], "-transient") == 0)
    7602             {
    7603                 fTransient = true;
    7604             }
    7605             else
    7606                 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
    7607         }
    7608 
    7609         /* required arguments */
    7610         if (!name)
    7611             return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter -name is required");
    7612 
    7613         if (fTransient)
    7614         {
    7615             ComPtr <IConsole> console;
    7616 
    7617             /* open an existing session for the VM */
    7618             CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
    7619             /* get the session machine */
    7620             CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
    7621             /* get the session console */
    7622             CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
    7623 
    7624             CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));
    7625 
    7626             if (console)
    7627                 aSession->Close();
    7628         }
    7629         else
    7630         {
    7631             /* open a session for the VM */
    7632             CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
    7633 
    7634             /* get the mutable session machine */
    7635             aSession->COMGETTER(Machine)(machine.asOutParam());
    7636 
    7637             CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));
    7638 
    7639             /* commit and close the session */
    7640             CHECK_ERROR(machine, SaveSettings());
    7641             aSession->Close();
    7642         }
    7643     }
    7644     else
    7645         return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
    7646 
    7647     return 0;
    7648 }
    7649 
    7650 static int handleVMStatistics(int argc, char *argv[],
    7651                               ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    7652 {
    7653     HRESULT rc;
    7654 
    7655     /* at least one option: the UUID or name of the VM */
    7656     if (argc < 1)
    7657         return errorSyntax(USAGE_VM_STATISTICS, "Incorrect number of parameters");
    7658 
    7659     /* try to find the given machine */
    7660     ComPtr <IMachine> machine;
    7661     Guid uuid (argv[0]);
    7662     if (!uuid.isEmpty())
    7663         CHECK_ERROR(aVirtualBox, GetMachine(uuid, machine.asOutParam()));
    7664     else
    7665     {
    7666         CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
    7667         if (SUCCEEDED (rc))
    7668             machine->COMGETTER(Id)(uuid.asOutParam());
    7669     }
    7670     if (FAILED(rc))
    7671         return 1;
    7672 
    7673     /* parse arguments. */
    7674     bool fReset = false;
    7675     bool fWithDescriptions = false;
    7676     const char *pszPattern = NULL; /* all */
    7677     for (int i = 1; i < argc; i++)
    7678     {
    7679         if (!strcmp(argv[i], "-pattern"))
    7680         {
    7681             if (pszPattern)
    7682                 return errorSyntax(USAGE_VM_STATISTICS, "Multiple -patterns options is not permitted");
    7683             if (i + 1 >= argc)
    7684                 return errorArgument("Missing argument to '%s'", argv[i]);
    7685             pszPattern = argv[++i];
    7686         }
    7687         else if (!strcmp(argv[i], "-descriptions"))
    7688             fWithDescriptions = true;
    7689         /* add: -file <filename> and -formatted */
    7690         else if (!strcmp(argv[i], "-reset"))
    7691             fReset = true;
    7692         else
    7693             return errorSyntax(USAGE_VM_STATISTICS, "Unknown option '%s'", argv[i]);
    7694     }
    7695     if (fReset && fWithDescriptions)
    7696         return errorSyntax(USAGE_VM_STATISTICS, "The -reset and -descriptions options does not mix");
    7697 
    7698 
    7699     /* open an existing session for the VM. */
    7700     CHECK_ERROR(aVirtualBox, OpenExistingSession(aSession, uuid));
    7701     if (SUCCEEDED(rc))
    7702     {
    7703         /* get the session console. */
    7704         ComPtr <IConsole> console;
    7705         CHECK_ERROR(aSession, COMGETTER(Console)(console.asOutParam()));
    7706         if (SUCCEEDED(rc))
    7707         {
    7708             /* get the machine debugger. */
    7709             ComPtr <IMachineDebugger> debugger;
    7710             CHECK_ERROR(console, COMGETTER(Debugger)(debugger.asOutParam()));
    7711             if (SUCCEEDED(rc))
    7712             {
    7713                 if (fReset)
    7714                     CHECK_ERROR(debugger, ResetStats(Bstr(pszPattern).raw()));
    7715                 else
    7716                 {
    7717                     Bstr stats;
    7718                     CHECK_ERROR(debugger, GetStats(Bstr(pszPattern).raw(), fWithDescriptions, stats.asOutParam()));
    7719                     if (SUCCEEDED(rc))
    7720                     {
    7721                         /* if (fFormatted)
    7722                          { big mess }
    7723                          else
    7724                          */
    7725                         RTPrintf("%ls\n", stats.raw());
    7726                     }
    7727                 }
    7728             }
    7729             aSession->Close();
    7730         }
    7731     }
    7732 
    7733     return SUCCEEDED(rc) ? 0 : 1;
    7734 }
    7735 
    7736 static char *toBaseMetricNames(const char *metricList)
    7737 {
    7738     char *newList = (char*)RTMemAlloc(strlen(metricList) + 1);
    7739     int cSlashes = 0;
    7740     bool fSkip = false;
    7741     const char *src = metricList;
    7742     char c, *dst = newList;
    7743     while ((c = *src++))
    7744         if (c == ':')
    7745             fSkip = true;
    7746         else if (c == '/' && ++cSlashes == 2)
    7747             fSkip = true;
    7748         else if (c == ',')
    7749         {
    7750             fSkip = false;
    7751             cSlashes = 0;
    7752             *dst++ = c;
    7753         }
    7754         else
    7755             if (!fSkip)
    7756                 *dst++ = c;
    7757     *dst = 0;
    7758     return newList;
    7759 }
    7760 
    7761 static int parseFilterParameters(int argc, char *argv[],
    7762                                  ComPtr<IVirtualBox> aVirtualBox,
    7763                                  ComSafeArrayOut(BSTR, outMetrics),
    7764                                  ComSafeArrayOut(BSTR, outBaseMetrics),
    7765                                  ComSafeArrayOut(IUnknown *, outObjects))
    7766 {
    7767     HRESULT rc = S_OK;
    7768     com::SafeArray<BSTR> retMetrics(1);
    7769     com::SafeArray<BSTR> retBaseMetrics(1);
    7770     com::SafeIfaceArray <IUnknown> retObjects;
    7771 
    7772     Bstr metricNames, baseNames;
    7773 
    7774     /* Metric list */
    7775     if (argc > 1)
    7776     {
    7777         metricNames = argv[1];
    7778         char *tmp   = toBaseMetricNames(argv[1]);
    7779         if (!tmp)
    7780             return VERR_NO_MEMORY;
    7781         baseNames   = tmp;
    7782         RTMemFree(tmp);
    7783     }
    7784     else
    7785     {
    7786         metricNames = L"*";
    7787         baseNames = L"*";
    7788     }
    7789     metricNames.cloneTo(&retMetrics[0]);
    7790     baseNames.cloneTo(&retBaseMetrics[0]);
    7791 
    7792     /* Object name */
    7793     if (argc > 0 && strcmp(argv[0], "*"))
    7794     {
    7795         if (!strcmp(argv[0], "host"))
    7796         {
    7797             ComPtr<IHost> host;
    7798             CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam()));
    7799             retObjects.reset(1);
    7800             host.queryInterfaceTo(&retObjects[0]);
    7801         }
    7802         else
    7803         {
    7804             ComPtr <IMachine> machine;
    7805             rc = aVirtualBox->FindMachine(Bstr(argv[0]), machine.asOutParam());
    7806             if (SUCCEEDED (rc))
    7807             {
    7808                 retObjects.reset(1);
    7809                 machine.queryInterfaceTo(&retObjects[0]);
    7810             }
    7811             else
    7812             {
    7813                 errorArgument("Invalid machine name: '%s'", argv[0]);
    7814                 return rc;
    7815             }
    7816         }
    7817 
    7818     }
    7819 
    7820     retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
    7821     retBaseMetrics.detachTo(ComSafeArrayOutArg(outBaseMetrics));
    7822     retObjects.detachTo(ComSafeArrayOutArg(outObjects));
    7823 
    7824     return rc;
    7825 }
    7826 
    7827 static Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
    7828                                   ComPtr<IUnknown> aObject)
    7829 {
    7830     HRESULT rc;
    7831 
    7832     ComPtr<IHost> host = aObject;
    7833     if (!host.isNull())
    7834         return Bstr("host");
    7835 
    7836     ComPtr<IMachine> machine = aObject;
    7837     if (!machine.isNull())
    7838     {
    7839         Bstr name;
    7840         CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
    7841         if (SUCCEEDED(rc))
    7842             return name;
    7843     }
    7844     return Bstr("unknown");
    7845 }
    7846 
    7847 static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
    7848                                 ComSafeArrayIn(IPerformanceMetric*, aMetrics))
    7849 {
    7850     HRESULT rc;
    7851     com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
    7852     if (metrics.size())
    7853     {
    7854         ComPtr<IUnknown> object;
    7855         Bstr metricName;
    7856         RTPrintf("The following metrics were modified:\n\n"
    7857                  "Object     Metric\n"
    7858                  "---------- --------------------\n");
    7859         for (size_t i = 0; i < metrics.size(); i++)
    7860         {
    7861             CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
    7862             CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
    7863             RTPrintf("%-10ls %-20ls\n",
    7864                 getObjectName(aVirtualBox, object).raw(), metricName.raw());
    7865         }
    7866         RTPrintf("\n");
    7867     }
    7868     else
    7869     {
    7870         RTPrintf("No metrics match the specified filter!\n");
    7871     }
    7872 }
    7873 
    7874 /**
    7875  * list                                                               *
    7876  */
    7877 static int handleMetricsList(int argc, char *argv[],
    7878                              ComPtr<IVirtualBox> aVirtualBox,
    7879                              ComPtr<IPerformanceCollector> performanceCollector)
    7880 {
    7881     HRESULT rc;
    7882     com::SafeArray<BSTR>          metrics;
    7883     com::SafeArray<BSTR>          baseMetrics;
    7884     com::SafeIfaceArray<IUnknown> objects;
    7885 
    7886     rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
    7887                                ComSafeArrayAsOutParam(metrics),
    7888                                ComSafeArrayAsOutParam(baseMetrics),
    7889                                ComSafeArrayAsOutParam(objects));
    7890     if (FAILED(rc))
    7891         return 1;
    7892 
    7893     com::SafeIfaceArray<IPerformanceMetric> metricInfo;
    7894 
    7895     CHECK_ERROR(performanceCollector,
    7896         GetMetrics(ComSafeArrayAsInParam(metrics),
    7897                    ComSafeArrayAsInParam(objects),
    7898                    ComSafeArrayAsOutParam(metricInfo)));
    7899 
    7900     ComPtr<IUnknown> object;
    7901     Bstr metricName, unit, description;
    7902     ULONG period, count;
    7903     LONG minimum, maximum;
    7904     RTPrintf(
    7905 "Object     Metric               Unit Minimum    Maximum    Period     Count      Description\n"
    7906 "---------- -------------------- ---- ---------- ---------- ---------- ---------- -----------\n");
    7907     for (size_t i = 0; i < metricInfo.size(); i++)
    7908     {
    7909         CHECK_ERROR(metricInfo[i], COMGETTER(Object)(object.asOutParam()));
    7910         CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricName.asOutParam()));
    7911         CHECK_ERROR(metricInfo[i], COMGETTER(Period)(&period));
    7912         CHECK_ERROR(metricInfo[i], COMGETTER(Count)(&count));
    7913         CHECK_ERROR(metricInfo[i], COMGETTER(MinimumValue)(&minimum));
    7914         CHECK_ERROR(metricInfo[i], COMGETTER(MaximumValue)(&maximum));
    7915         CHECK_ERROR(metricInfo[i], COMGETTER(Unit)(unit.asOutParam()));
    7916         CHECK_ERROR(metricInfo[i], COMGETTER(Description)(description.asOutParam()));
    7917         RTPrintf("%-10ls %-20ls %-4ls %10d %10d %10u %10u %ls\n",
    7918             getObjectName(aVirtualBox, object).raw(), metricName.raw(), unit.raw(),
    7919             minimum, maximum, period, count, description.raw());
    7920     }
    7921 
    7922     return 0;
    7923 }
    7924 
    7925 /**
    7926  * Metics setup
    7927  */
    7928 static int handleMetricsSetup(int argc, char *argv[],
    7929                               ComPtr<IVirtualBox> aVirtualBox,
    7930                               ComPtr<IPerformanceCollector> performanceCollector)
    7931 {
    7932     HRESULT rc;
    7933     com::SafeArray<BSTR>          metrics;
    7934     com::SafeArray<BSTR>          baseMetrics;
    7935     com::SafeIfaceArray<IUnknown> objects;
    7936     ULONG period = 1, samples = 1;
    7937     bool listMatches = false;
    7938     int i;
    7939 
    7940     for (i = 1; i < argc; i++)
    7941     {
    7942         if (strcmp(argv[i], "-period") == 0)
    7943         {
    7944             if (argc <= i + 1)
    7945                 return errorArgument("Missing argument to '%s'", argv[i]);
    7946             char *endptr = NULL;
    7947             period = strtoul (argv[++i], &endptr, 10);
    7948             if (!endptr || *endptr || !period)
    7949                 return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
    7950         }
    7951         else if (strcmp(argv[i], "-samples") == 0)
    7952         {
    7953             if (argc <= i + 1)
    7954                 return errorArgument("Missing argument to '%s'", argv[i]);
    7955             char *endptr = NULL;
    7956             samples = strtoul (argv[++i], &endptr, 10);
    7957             if (!endptr || *endptr)
    7958                 return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
    7959         }
    7960         else if (strcmp(argv[i], "-list") == 0)
    7961             listMatches = true;
    7962         else
    7963             break; /* The rest of params should define the filter */
    7964     }
    7965 
    7966     rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
    7967                                ComSafeArrayAsOutParam(metrics),
    7968                                ComSafeArrayAsOutParam(baseMetrics),
    7969                                ComSafeArrayAsOutParam(objects));
    7970     if (FAILED(rc))
    7971         return 1;
    7972 
    7973     com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
    7974     CHECK_ERROR(performanceCollector,
    7975         SetupMetrics(ComSafeArrayAsInParam(metrics),
    7976                      ComSafeArrayAsInParam(objects), period, samples,
    7977                      ComSafeArrayAsOutParam(affectedMetrics)));
    7978     if (listMatches)
    7979         listAffectedMetrics(aVirtualBox,
    7980                             ComSafeArrayAsInParam(affectedMetrics));
    7981 
    7982     return 0;
    7983 }
    7984 
    7985 /**
    7986  * metrics query
    7987  */
    7988 static int handleMetricsQuery(int argc, char *argv[],
    7989                               ComPtr<IVirtualBox> aVirtualBox,
    7990                               ComPtr<IPerformanceCollector> performanceCollector)
    7991 {
    7992     HRESULT rc;
    7993     com::SafeArray<BSTR>          metrics;
    7994     com::SafeArray<BSTR>          baseMetrics;
    7995     com::SafeIfaceArray<IUnknown> objects;
    7996 
    7997     rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
    7998                                ComSafeArrayAsOutParam(metrics),
    7999                                ComSafeArrayAsOutParam(baseMetrics),
    8000                                ComSafeArrayAsOutParam(objects));
    8001     if (FAILED(rc))
    8002         return 1;
    8003 
    8004     com::SafeArray<BSTR>          retNames;
    8005     com::SafeIfaceArray<IUnknown> retObjects;
    8006     com::SafeArray<BSTR>          retUnits;
    8007     com::SafeArray<ULONG>         retScales;
    8008     com::SafeArray<ULONG>         retSequenceNumbers;
    8009     com::SafeArray<ULONG>         retIndices;
    8010     com::SafeArray<ULONG>         retLengths;
    8011     com::SafeArray<LONG>          retData;
    8012     CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
    8013                                              ComSafeArrayAsInParam(objects),
    8014                                              ComSafeArrayAsOutParam(retNames),
    8015                                              ComSafeArrayAsOutParam(retObjects),
    8016                                              ComSafeArrayAsOutParam(retUnits),
    8017                                              ComSafeArrayAsOutParam(retScales),
    8018                                              ComSafeArrayAsOutParam(retSequenceNumbers),
    8019                                              ComSafeArrayAsOutParam(retIndices),
    8020                                              ComSafeArrayAsOutParam(retLengths),
    8021                                              ComSafeArrayAsOutParam(retData)) );
    8022 
    8023     RTPrintf("Object     Metric               Values\n"
    8024              "---------- -------------------- --------------------------------------------\n");
    8025     for (unsigned i = 0; i < retNames.size(); i++)
    8026     {
    8027         Bstr metricUnit(retUnits[i]);
    8028         Bstr metricName(retNames[i]);
    8029         RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
    8030         const char *separator = "";
    8031         for (unsigned j = 0; j < retLengths[i]; j++)
    8032         {
    8033             if (retScales[i] == 1)
    8034                 RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
    8035             else
    8036                 RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
    8037                          (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
    8038             separator = ", ";
    8039         }
    8040         RTPrintf("\n");
    8041     }
    8042 
    8043     return 0;
    8044 }
    8045 
    8046 static void getTimestamp(char *pts, size_t tsSize)
    8047 {
    8048     *pts = 0;
    8049     AssertReturnVoid(tsSize >= 13); /* 3+3+3+3+1 */
    8050     RTTIMESPEC TimeSpec;
    8051     RTTIME Time;
    8052     RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
    8053     pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
    8054     *pts++ = ':';
    8055     pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
    8056     *pts++ = ':';
    8057     pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
    8058     *pts++ = '.';
    8059     pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
    8060     *pts = 0;
    8061 }
    8062 
    8063 /** Used by the handleMetricsCollect loop. */
    8064 static bool volatile g_fKeepGoing = true;
    8065 
    8066 #ifdef RT_OS_WINDOWS
    8067 /**
    8068  * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
    8069  * the console.
    8070  *
    8071  * @returns true if handled, false if not handled.
    8072  * @param   dwCtrlType      The type of control signal.
    8073  *
    8074  * @remarks This is called on a new thread.
    8075  */
    8076 static BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
    8077 {
    8078     switch (dwCtrlType)
    8079     {
    8080         /* Ctrl-C or Ctrl-Break or Close */
    8081         case CTRL_C_EVENT:
    8082         case CTRL_BREAK_EVENT:
    8083         case CTRL_CLOSE_EVENT:
    8084             /* Let's shut down gracefully. */
    8085             ASMAtomicWriteBool(&g_fKeepGoing, false);
    8086             return TRUE;
    8087     }
    8088     /* Don't care about the rest -- let it die a horrible death. */
    8089     return FALSE;
    8090 }
    8091 #endif /* RT_OS_WINDOWS */
    8092 
    8093 /**
    8094  * collect
    8095  */
    8096 static int handleMetricsCollect(int argc, char *argv[],
    8097                                 ComPtr<IVirtualBox> aVirtualBox,
    8098                                 ComPtr<IPerformanceCollector> performanceCollector)
    8099 {
    8100     HRESULT rc;
    8101     com::SafeArray<BSTR>          metrics;
    8102     com::SafeArray<BSTR>          baseMetrics;
    8103     com::SafeIfaceArray<IUnknown> objects;
    8104     ULONG period = 1, samples = 1;
    8105     bool isDetached = false, listMatches = false;
    8106     int i;
    8107     for (i = 1; i < argc; i++)
    8108     {
    8109         if (strcmp(argv[i], "-period") == 0)
    8110         {
    8111             if (argc <= i + 1)
    8112                 return errorArgument("Missing argument to '%s'", argv[i]);
    8113             char *endptr = NULL;
    8114             period = strtoul (argv[++i], &endptr, 10);
    8115             if (!endptr || *endptr || !period)
    8116                 return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
    8117         }
    8118         else if (strcmp(argv[i], "-samples") == 0)
    8119         {
    8120             if (argc <= i + 1)
    8121                 return errorArgument("Missing argument to '%s'", argv[i]);
    8122             char *endptr = NULL;
    8123             samples = strtoul (argv[++i], &endptr, 10);
    8124             if (!endptr || *endptr || !samples)
    8125                 return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
    8126         }
    8127         else if (strcmp(argv[i], "-list") == 0)
    8128             listMatches = true;
    8129         else if (strcmp(argv[i], "-detach") == 0)
    8130             isDetached = true;
    8131         else
    8132             break; /* The rest of params should define the filter */
    8133     }
    8134 
    8135     rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
    8136                                ComSafeArrayAsOutParam(metrics),
    8137                                ComSafeArrayAsOutParam(baseMetrics),
    8138                                ComSafeArrayAsOutParam(objects));
    8139     if (FAILED(rc))
    8140         return 1;
    8141 
    8142 
    8143     com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
    8144     CHECK_ERROR(performanceCollector,
    8145         SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
    8146                      ComSafeArrayAsInParam(objects), period, samples,
    8147                      ComSafeArrayAsOutParam(affectedMetrics)));
    8148     if (listMatches)
    8149         listAffectedMetrics(aVirtualBox,
    8150                             ComSafeArrayAsInParam(affectedMetrics));
    8151     if (!affectedMetrics.size())
    8152         return 1;
    8153 
    8154     if (isDetached)
    8155     {
    8156         RTPrintf("Warning! The background process holding collected metrics will shutdown\n"
    8157                  "in few seconds, discarding all collected data and parameters.\n");
    8158         return 0;
    8159     }
    8160 
    8161 #ifdef RT_OS_WINDOWS
    8162     SetConsoleCtrlHandler(ctrlHandler, true);
    8163 #endif /* RT_OS_WINDOWS */
    8164 
    8165     RTPrintf("Time stamp   Object     Metric               Value\n");
    8166 
    8167     while (g_fKeepGoing)
    8168     {
    8169         RTPrintf("------------ ---------- -------------------- --------------------\n");
    8170         RTThreadSleep(period * 1000); // Sleep for 'period' seconds
    8171         char ts[15];
    8172 
    8173         getTimestamp(ts, sizeof(ts));
    8174         com::SafeArray<BSTR>          retNames;
    8175         com::SafeIfaceArray<IUnknown> retObjects;
    8176         com::SafeArray<BSTR>          retUnits;
    8177         com::SafeArray<ULONG>         retScales;
    8178         com::SafeArray<ULONG>         retSequenceNumbers;
    8179         com::SafeArray<ULONG>         retIndices;
    8180         com::SafeArray<ULONG>         retLengths;
    8181         com::SafeArray<LONG>          retData;
    8182         CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
    8183                                                  ComSafeArrayAsInParam(objects),
    8184                                                  ComSafeArrayAsOutParam(retNames),
    8185                                                  ComSafeArrayAsOutParam(retObjects),
    8186                                                  ComSafeArrayAsOutParam(retUnits),
    8187                                                  ComSafeArrayAsOutParam(retScales),
    8188                                                  ComSafeArrayAsOutParam(retSequenceNumbers),
    8189                                                  ComSafeArrayAsOutParam(retIndices),
    8190                                                  ComSafeArrayAsOutParam(retLengths),
    8191                                                  ComSafeArrayAsOutParam(retData)) );
    8192         for (unsigned i = 0; i < retNames.size(); i++)
    8193         {
    8194             Bstr metricUnit(retUnits[i]);
    8195             Bstr metricName(retNames[i]);
    8196             RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
    8197             const char *separator = "";
    8198             for (unsigned j = 0; j < retLengths[i]; j++)
    8199             {
    8200                 if (retScales[i] == 1)
    8201                     RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
    8202                 else
    8203                     RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
    8204                              (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
    8205                 separator = ", ";
    8206             }
    8207             RTPrintf("\n");
    8208         }
    8209     }
    8210 
    8211 #ifdef RT_OS_WINDOWS
    8212     SetConsoleCtrlHandler(ctrlHandler, false);
    8213 #endif /* RT_OS_WINDOWS */
    8214 
    8215     return 0;
    8216 }
    8217 
    8218 static int handleMetrics(int argc, char *argv[],
    8219                          ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    8220 {
    8221     int rc;
    8222 
    8223     /* at least one option: subcommand name */
    8224     if (argc < 1)
    8225         return errorSyntax(USAGE_METRICS, "Subcommand missing");
    8226 
    8227     ComPtr<IPerformanceCollector> performanceCollector;
    8228     CHECK_ERROR(aVirtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()));
    8229 
    8230     if (!strcmp(argv[0], "list"))
    8231         rc = handleMetricsList(argc, argv, aVirtualBox, performanceCollector);
    8232     else if (!strcmp(argv[0], "setup"))
    8233         rc = handleMetricsSetup(argc, argv, aVirtualBox, performanceCollector);
    8234     else if (!strcmp(argv[0], "query"))
    8235         rc = handleMetricsQuery(argc, argv, aVirtualBox, performanceCollector);
    8236     else if (!strcmp(argv[0], "collect"))
    8237         rc = handleMetricsCollect(argc, argv, aVirtualBox, performanceCollector);
    8238     else
    8239         return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", argv[0]);
    8240 
    8241     return rc;
    8242 }
    8243 #endif /* !VBOX_ONLY_DOCS */
    8244 
    8245 enum ConvertSettings
    8246 {
    8247     ConvertSettings_No      = 0,
    8248     ConvertSettings_Yes     = 1,
    8249     ConvertSettings_Backup  = 2,
    8250     ConvertSettings_Ignore  = 3,
    8251 };
    8252 
    8253 #ifndef VBOX_ONLY_DOCS
    8254 /**
    8255  * Checks if any of the settings files were auto-converted and informs the
    8256  * user if so.
    8257  *
    8258  * @return @false if the program should terminate and @true otherwise.
    8259  */
    8260 static bool checkForAutoConvertedSettings (ComPtr<IVirtualBox> virtualBox,
    8261                                            ComPtr<ISession> session,
    8262                                            ConvertSettings fConvertSettings)
    8263 {
    8264     /* return early if nothing to do */
    8265     if (fConvertSettings == ConvertSettings_Ignore)
    8266         return true;
    8267 
    8268     HRESULT rc;
    8269 
    8270     do
    8271     {
    8272         Bstr formatVersion;
    8273         CHECK_RC_BREAK (virtualBox->
    8274                         COMGETTER(SettingsFormatVersion) (formatVersion.asOutParam()));
    8275 
    8276         bool isGlobalConverted = false;
    8277         std::list <ComPtr <IMachine> > cvtMachines;
    8278         std::list <Utf8Str> fileList;
    8279         Bstr version;
    8280         Bstr filePath;
    8281 
    8282         com::SafeIfaceArray <IMachine> machines;
    8283         CHECK_RC_BREAK (virtualBox->
    8284                         COMGETTER(Machines2) (ComSafeArrayAsOutParam (machines)));
    8285 
    8286         for (size_t i = 0; i < machines.size(); ++ i)
    8287         {
    8288             BOOL accessible;
    8289             CHECK_RC_BREAK (machines [i]->
    8290                             COMGETTER(Accessible) (&accessible));
    8291             if (!accessible)
    8292                 continue;
    8293 
    8294             CHECK_RC_BREAK (machines [i]->
    8295                             COMGETTER(SettingsFileVersion) (version.asOutParam()));
    8296 
    8297             if (version != formatVersion)
    8298             {
    8299                 cvtMachines.push_back (machines [i]);
    8300                 Bstr filePath;
    8301                 CHECK_RC_BREAK (machines [i]->
    8302                                 COMGETTER(SettingsFilePath) (filePath.asOutParam()));
    8303                 fileList.push_back (Utf8StrFmt ("%ls  (%ls)", filePath.raw(),
    8304                                                 version.raw()));
    8305             }
    8306         }
    8307 
    8308         CHECK_RC_BREAK (rc);
    8309 
    8310         CHECK_RC_BREAK (virtualBox->
    8311                         COMGETTER(SettingsFileVersion) (version.asOutParam()));
    8312         if (version != formatVersion)
    8313         {
    8314             isGlobalConverted = true;
    8315             CHECK_RC_BREAK (virtualBox->
    8316                             COMGETTER(SettingsFilePath) (filePath.asOutParam()));
    8317             fileList.push_back (Utf8StrFmt ("%ls  (%ls)", filePath.raw(),
    8318                                             version.raw()));
    8319         }
    8320 
    8321         if (fileList.size() > 0)
    8322         {
    8323             switch (fConvertSettings)
    8324             {
    8325                 case ConvertSettings_No:
    8326                 {
    8327                     RTPrintf (
    8328 "WARNING! The following VirtualBox settings files have been automatically\n"
    8329 "converted to the new settings file format version '%ls':\n"
    8330 "\n",
    8331                               formatVersion.raw());
    8332 
    8333                     for (std::list <Utf8Str>::const_iterator f = fileList.begin();
    8334                          f != fileList.end(); ++ f)
    8335                         RTPrintf ("  %S\n", (*f).raw());
    8336                     RTPrintf (
    8337 "\n"
    8338 "The current command was aborted to prevent overwriting the above settings\n"
    8339 "files with the results of the auto-conversion without your permission.\n"
    8340 "Please put one of the following command line switches to the beginning of\n"
    8341 "the VBoxManage command line and repeat the command:\n"
    8342 "\n"
    8343 "  -convertSettings       - to save all auto-converted files (it will not\n"
    8344 "                           be possible to use these settings files with an\n"
    8345 "                           older version of VirtualBox in the future);\n"
    8346 "  -convertSettingsBackup - to create backup copies of the settings files in\n"
    8347 "                           the old format before saving them in the new format;\n"
    8348 "  -convertSettingsIgnore - to not save the auto-converted settings files.\n"
    8349 "\n"
    8350 "Note that if you use -convertSettingsIgnore, the auto-converted settings files\n"
    8351 "will be implicitly saved in the new format anyway once you change a setting or\n"
    8352 "start a virtual machine, but NO backup copies will be created in this case.\n");
    8353                     return false;
    8354                 }
    8355                 case ConvertSettings_Yes:
    8356                 case ConvertSettings_Backup:
    8357                 {
    8358                     break;
    8359                 }
    8360                 default:
    8361                     AssertFailedReturn (false);
    8362             }
    8363 
    8364             for (std::list <ComPtr <IMachine> >::const_iterator m = cvtMachines.begin();
    8365                  m != cvtMachines.end(); ++ m)
    8366             {
    8367                 Guid id;
    8368                 CHECK_RC_BREAK ((*m)->COMGETTER(Id) (id.asOutParam()));
    8369 
    8370                 /* open a session for the VM */
    8371                 CHECK_ERROR_BREAK (virtualBox, OpenSession (session, id));
    8372 
    8373                 ComPtr <IMachine> sm;
    8374                 CHECK_RC_BREAK (session->COMGETTER(Machine) (sm.asOutParam()));
    8375 
    8376                 Bstr bakFileName;
    8377                 if (fConvertSettings == ConvertSettings_Backup)
    8378                     CHECK_ERROR (sm, SaveSettingsWithBackup (bakFileName.asOutParam()));
    8379                 else
    8380                     CHECK_ERROR (sm, SaveSettings());
    8381 
    8382                 session->Close();
    8383 
    8384                 CHECK_RC_BREAK (rc);
    8385             }
    8386 
    8387             CHECK_RC_BREAK (rc);
    8388 
    8389             if (isGlobalConverted)
    8390             {
    8391                 Bstr bakFileName;
    8392                 if (fConvertSettings == ConvertSettings_Backup)
    8393                     CHECK_ERROR (virtualBox, SaveSettingsWithBackup (bakFileName.asOutParam()));
    8394                 else
    8395                     CHECK_ERROR (virtualBox, SaveSettings());
    8396             }
    8397 
    8398             CHECK_RC_BREAK (rc);
    8399         }
    8400     }
    8401     while (0);
    8402 
    8403     return SUCCEEDED (rc);
    8404 }
    8405 #endif /* !VBOX_ONLY_DOCS */
    8406 
    8407 // main
    8408 ///////////////////////////////////////////////////////////////////////////////
    8409 
    8410 int main(int argc, char *argv[])
    8411 {
    8412     /*
    8413      * Before we do anything, init the runtime without loading
    8414      * the support driver.
    8415      */
    8416     RTR3Init();
    8417 
    8418     bool fShowLogo = true;
    8419     int  iCmd      = 1;
    8420     int  iCmdArg;
    8421 
    8422     ConvertSettings fConvertSettings = ConvertSettings_No;
    8423 
    8424     /* global options */
    8425     for (int i = 1; i < argc || argc <= iCmd; i++)
    8426     {
    8427         if (    argc <= iCmd
    8428             ||  (strcmp(argv[i], "help")   == 0)
    8429             ||  (strcmp(argv[i], "-?")     == 0)
    8430             ||  (strcmp(argv[i], "-h")     == 0)
    8431             ||  (strcmp(argv[i], "-help")  == 0)
    8432             ||  (strcmp(argv[i], "--help") == 0))
    8433         {
    8434             showLogo();
    8435             printUsage(USAGE_ALL);
    8436             return 0;
    8437         }
    8438         else if (   strcmp(argv[i], "-v") == 0
    8439                  || strcmp(argv[i], "-version") == 0
    8440                  || strcmp(argv[i], "-Version") == 0
    8441                  || strcmp(argv[i], "--version") == 0)
    8442         {
    8443             /* Print version number, and do nothing else. */
    8444             RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBoxSVNRev ());
    8445             exit(0);
    8446         }
    8447         else if (strcmp(argv[i], "-dumpopts") == 0)
    8448         {
    8449             /* Special option to dump really all commands,
    8450              * even the ones not understood on this platform. */
    8451             printUsage(USAGE_DUMPOPTS);
    8452             return 0;
    8453         }
    8454         else if (strcmp(argv[i], "-nologo") == 0)
    8455         {
    8456             /* suppress the logo */
    8457             fShowLogo = false;
    8458             iCmd++;
    8459         }
    8460         else if (strcmp(argv[i], "-convertSettings") == 0)
    8461         {
    8462             fConvertSettings = ConvertSettings_Yes;
    8463             iCmd++;
    8464         }
    8465         else if (strcmp(argv[i], "-convertSettingsBackup") == 0)
    8466         {
    8467             fConvertSettings = ConvertSettings_Backup;
    8468             iCmd++;
    8469         }
    8470         else if (strcmp(argv[i], "-convertSettingsIgnore") == 0)
    8471         {
    8472             fConvertSettings = ConvertSettings_Ignore;
    8473             iCmd++;
    8474         }
    8475         else
    8476         {
    8477             break;
    8478         }
    8479     }
    8480 
    8481     iCmdArg = iCmd + 1;
    8482 
    8483     if (fShowLogo)
    8484         showLogo();
    8485 
    8486 
    8487 #ifdef VBOX_ONLY_DOCS
    8488     int rc = 0;
    8489 #else /* !VBOX_ONLY_DOCS */
    8490     HRESULT rc = 0;
    8491 
    8492     CHECK_RC_RET (com::Initialize());
    8493 
    8494     /*
    8495      * The input is in the host OS'es codepage (NT guarantees ACP).
    8496      * For VBox we use UTF-8 and convert to UCS-2 when calling (XP)COM APIs.
    8497      * For simplicity, just convert the argv[] array here.
    8498      */
    8499     for (int i = iCmdArg; i < argc; i++)
    8500     {
    8501         char *converted;
    8502         RTStrCurrentCPToUtf8(&converted, argv[i]);
    8503         argv[i] = converted;
    8504     }
    8505 
    8506     do
    8507     {
    8508     // scopes all the stuff till shutdown
    8509     ////////////////////////////////////////////////////////////////////////////
    8510 
    8511     /* convertdd: does not need a VirtualBox instantiation) */
    8512     if (argc >= iCmdArg && (strcmp(argv[iCmd], "convertdd") == 0))
    8513     {
    8514         rc = handleConvertDDImage(argc - iCmdArg, argv + iCmdArg);
    8515         break;
    8516     }
    8517 
    8518     ComPtr <IVirtualBox> virtualBox;
    8519     ComPtr <ISession> session;
    8520 
    8521     rc = virtualBox.createLocalObject (CLSID_VirtualBox);
    8522     if (FAILED(rc))
    8523     {
    8524         RTPrintf ("[!] Failed to create the VirtualBox object!\n");
    8525         PRINT_RC_MESSAGE (rc);
    8526 
    8527         com::ErrorInfo info;
    8528         if (!info.isFullAvailable() && !info.isBasicAvailable())
    8529             RTPrintf ("[!] Most likely, the VirtualBox COM server is not running "
    8530                       "or failed to start.\n");
    8531         else
    8532             PRINT_ERROR_INFO (info);
    8533         break;
    8534     }
    8535 
    8536     CHECK_RC_BREAK (session.createInprocObject (CLSID_Session));
    8537 
    8538     /* create the event queue
    8539      * (here it is necessary only to process remaining XPCOM/IPC events
    8540      * after the session is closed) */
    8541 
    8542 #ifdef USE_XPCOM_QUEUE
    8543     NS_GetMainEventQ(getter_AddRefs(g_pEventQ));
    8544 #endif
    8545 
    8546     if (!checkForAutoConvertedSettings (virtualBox, session, fConvertSettings))
    8547         break;
    8548 
    8549     /*
    8550      * All registered command handlers
    8551      */
    8552     struct
    8553     {
    8554         const char *command;
    8555         PFNHANDLER handler;
    8556     } commandHandlers[] =
    8557     {
    8558         { "internalcommands", handleInternalCommands },
    8559         { "list",             handleList },
    8560         { "showvminfo",       handleShowVMInfo },
    8561         { "registervm",       handleRegisterVM },
    8562         { "unregistervm",     handleUnregisterVM },
    8563         { "createhd",         handleCreateHardDisk },
    8564         { "createvdi",        handleCreateHardDisk }, /* backward compatiblity */
    8565         { "modifyhd",         handleModifyHardDisk },
    8566         { "modifyvdi",        handleModifyHardDisk }, /* backward compatiblity */
    8567         { "addiscsidisk",     handleAddiSCSIDisk },
    8568         { "createvm",         handleCreateVM },
    8569         { "modifyvm",         handleModifyVM },
    8570         { "clonehd",          handleCloneHardDisk },
    8571         { "clonevdi",         handleCloneHardDisk }, /* backward compatiblity */
    8572         { "startvm",          handleStartVM },
    8573         { "controlvm",        handleControlVM },
    8574         { "discardstate",     handleDiscardState },
    8575         { "adoptstate",       handleAdoptdState },
    8576         { "snapshot",         handleSnapshot },
    8577         { "openmedium",       handleOpenMedium },
    8578         { "registerimage",    handleOpenMedium }, /* backward compatiblity */
    8579         { "closemedium",      handleCloseMedium },
    8580         { "unregisterimage",  handleCloseMedium }, /* backward compatiblity */
    8581         { "showhdinfo",       handleShowHardDiskInfo },
    8582         { "showvdiinfo",      handleShowHardDiskInfo }, /* backward compatiblity */
    8583 #ifdef RT_OS_WINDOWS
    8584         { "createhostif",     handleCreateHostIF },
    8585         { "removehostif",     handleRemoveHostIF },
    8586 #endif
    8587         { "getextradata",     handleGetExtraData },
    8588         { "setextradata",     handleSetExtraData },
    8589         { "setproperty",      handleSetProperty },
    8590         { "usbfilter",        handleUSBFilter },
    8591         { "sharedfolder",     handleSharedFolder },
    8592         { "vmstatistics",     handleVMStatistics },
    8593 #ifdef VBOX_WITH_GUEST_PROPS
    8594         { "guestproperty",    handleGuestProperty },
    8595 #endif /* VBOX_WITH_GUEST_PROPS defined */
    8596         { "metrics",          handleMetrics },
    8597         { NULL,               NULL }
    8598     };
    8599 
    8600     int commandIndex;
    8601     for (commandIndex = 0; commandHandlers[commandIndex].command != NULL; commandIndex++)
    8602     {
    8603         if (strcmp(commandHandlers[commandIndex].command, argv[iCmd]) == 0)
    8604         {
    8605             rc = commandHandlers[commandIndex].handler(argc - iCmdArg, &argv[iCmdArg], virtualBox, session);
    8606             break;
    8607         }
    8608     }
    8609     if (!commandHandlers[commandIndex].command)
    8610     {
    8611         rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).raw());
    8612     }
    8613 
    8614     /* Although all handlers should always close the session if they open it,
    8615      * we do it here just in case if some of the handlers contains a bug --
    8616      * leaving the direct session not closed will turn the machine state to
    8617      * Aborted which may have unwanted side effects like killing the saved
    8618      * state file (if the machine was in the Saved state before). */
    8619     session->Close();
    8620 
    8621 #ifdef USE_XPCOM_QUEUE
    8622     g_pEventQ->ProcessPendingEvents();
    8623 #endif
    8624 
    8625     // end "all-stuff" scope
    8626     ////////////////////////////////////////////////////////////////////////////
    8627     }
    8628     while (0);
    8629 
    8630     com::Shutdown();
    8631 #endif /* !VBOX_ONLY_DOCS */
    8632 
    8633     /*
    8634      * Free converted argument vector
    8635      */
    8636     for (int i = iCmdArg; i < argc; i++)
    8637         RTStrFree(argv[i]);
    8638 
    8639     return rc != 0;
    8640 }
     2517#endif /* VBOX_ONLY_DOCS */
     2518
Note: See TracChangeset for help on using the changeset viewer.

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