Changeset 14555 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Nov 25, 2008 9:08:06 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 39847
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
r13855 r14555 43 43 VBoxManage_SOURCES = \ 44 44 VBoxManage.cpp \ 45 VBoxManageInfo.cpp \ 45 46 VBoxInternalManage.cpp \ 46 47 $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \ -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r14371 r14555 765 765 } 766 766 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 else781 {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 else805 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. Any838 * other values printed are in CamelCase.839 * 2) strings (anything non-decimal) are printed surrounded by840 * double quotes '"'. If the strings themselves contain double841 * quotes, these characters are escaped by '\'. Any '\' character842 * 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 else857 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 else863 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 else884 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 else895 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 else902 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 else909 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 else916 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 else923 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 else940 pszBootMenu = "menu only";941 break;942 default:943 if (details == VMINFO_MACHINEREADABLE)944 pszBootMenu = "messageandmenu";945 else946 pszBootMenu = "message and menu";947 }948 if (details == VMINFO_MACHINEREADABLE)949 RTPrintf("bootmenu=\"%s\"\n", pszBootMenu);950 else951 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 else958 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 else965 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 else972 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 else979 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 else992 RTPrintf("Hardw. virt.ext: Default (%s)\n", fHWVirtExEnabled ? "on" : "off");993 }994 else995 {996 if (details == VMINFO_MACHINEREADABLE)997 RTPrintf("hwvirtex=\"%s\"\n", hwVirtExEnabled == TSBool_True ? "on" : "off");998 else999 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 else1006 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 else1013 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 else1024 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 else1066 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 else1073 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 else1080 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 else1111 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 else1127 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 else1140 {1141 pszFloppy = "disabled";1142 }1143 if (details == VMINFO_MACHINEREADABLE)1144 RTPrintf("floppy=\"%s\"\n", pszFloppy.raw());1145 else1146 RTPrintf("Floppy: %s\n", pszFloppy.raw());1147 }1148 1149 /*1150 * SATA.1151 *1152 * Contributed by: James Lucas1153 */1154 #ifdef VBOX_WITH_AHCI1155 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 else1166 RTPrintf("SATA: %s\n", fSataEnabled ? "enabled" : "disabled");1167 }1168 1169 /*1170 * SATA Hard disks1171 */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 else1192 RTPrintf("SATA %d: %lS (UUID: %s)\n", i, filePath.raw(), uuid.toString().raw());1193 }1194 else1195 {1196 if (details == VMINFO_MACHINEREADABLE)1197 RTPrintf("sata%d=\"none\"\n",i);1198 }1199 }1200 }1201 #endif1202 1203 /*1204 * IDE Hard disks1205 */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 else1223 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 else1238 RTPrintf("Primary master: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());1239 }1240 else1241 {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 else1256 RTPrintf("Primary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());1257 }1258 else1259 {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 else1274 RTPrintf("Secondary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());1275 }1276 else1277 {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 else1299 RTPrintf("DVD: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());1300 }1301 }1302 else1303 {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 else1313 RTPrintf("DVD: Host drive %lS", name.raw());1314 }1315 else1316 {1317 if (details == VMINFO_MACHINEREADABLE)1318 RTPrintf("dvd=\"none\"\n");1319 else1320 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 else1329 {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 else1355 RTPrintf("NIC %d: disabled\n", currentNIC + 1);1356 }1357 else1358 {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 else1370 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 else1384 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 else1397 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 else1410 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_E10001440 case NetworkAdapterType_I82540EM:1441 strNICType = "82540EM";1442 break;1443 case NetworkAdapterType_I82543GC:1444 strNICType = "82543GC";1445 break;1446 #endif1447 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 else1463 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 else1490 RTPrintf("UART %d: disabled\n", currentUART + 1);1491 }1492 else1493 {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 else1508 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 else1517 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 else1524 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 else1532 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 else1557 pszDrv = "Null";1558 break;1559 case AudioDriverType_WinMM:1560 if (details == VMINFO_MACHINEREADABLE)1561 pszDrv = "winmm";1562 else1563 pszDrv = "WINMM";1564 break;1565 case AudioDriverType_DirectSound:1566 if (details == VMINFO_MACHINEREADABLE)1567 pszDrv = "dsound";1568 else1569 pszDrv = "DSOUND";1570 break;1571 case AudioDriverType_OSS:1572 if (details == VMINFO_MACHINEREADABLE)1573 pszDrv = "oss";1574 else1575 pszDrv = "OSS";1576 break;1577 case AudioDriverType_ALSA:1578 if (details == VMINFO_MACHINEREADABLE)1579 pszDrv = "alsa";1580 else1581 pszDrv = "ALSA";1582 break;1583 case AudioDriverType_Pulse:1584 if (details == VMINFO_MACHINEREADABLE)1585 pszDrv = "pulse";1586 else1587 pszDrv = "PulseAudio";1588 break;1589 case AudioDriverType_CoreAudio:1590 if (details == VMINFO_MACHINEREADABLE)1591 pszDrv = "coreaudio";1592 else1593 pszDrv = "CoreAudio";1594 break;1595 case AudioDriverType_SolAudio:1596 if (details == VMINFO_MACHINEREADABLE)1597 pszDrv = "solaudio";1598 else1599 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 else1614 pszCtrl = "AC97";1615 break;1616 case AudioControllerType_SB16:1617 if (details == VMINFO_MACHINEREADABLE)1618 pszCtrl = "sb16";1619 else1620 pszCtrl = "SB16";1621 break;1622 }1623 }1624 else1625 fEnabled = FALSE;1626 if (details == VMINFO_MACHINEREADABLE)1627 {1628 if (fEnabled)1629 RTPrintf("audio=\"%s\"\n", pszDrv);1630 else1631 RTPrintf("audio=\"none\"\n");1632 }1633 else1634 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 else1649 psz = "disabled";1650 break;1651 case ClipboardMode_HostToGuest:1652 if (details == VMINFO_MACHINEREADABLE)1653 psz = "hosttoguest";1654 else1655 psz = "HostToGuest";1656 break;1657 case ClipboardMode_GuestToHost:1658 if (details == VMINFO_MACHINEREADABLE)1659 psz = "guesttohost";1660 else1661 psz = "GuestToHost";1662 break;1663 case ClipboardMode_Bidirectional:1664 if (details == VMINFO_MACHINEREADABLE)1665 psz = "bidirectional";1666 else1667 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 else1677 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 do1685 {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 else1717 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);1718 }1719 while (0);1720 }1721 1722 /*1723 * VRDP1724 */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 else1769 {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 else1776 {1777 if (details == VMINFO_MACHINEREADABLE)1778 RTPrintf("vrdp=\"off\"\n");1779 else1780 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 else1798 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 else1820 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 else1836 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 else1843 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 else1848 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 else1853 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 else1858 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 else1863 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 else1868 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 else1873 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 else1878 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 else1918 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 else1944 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 else1961 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 else1969 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 else1977 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 else1985 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 else2020 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 else2046 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 else2063 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 else2071 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 else2079 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 else2087 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 folders2104 */2105 if (details != VMINFO_MACHINEREADABLE)2106 RTPrintf("Shared folders: ");2107 uint32_t numSharedFolders = 0;2108 #if 0 // not yet implemented2109 /* 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 #endif2130 /* 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 else2158 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 else2191 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 else2241 RTPrintf("VRDP Connection: %s\n", Active? "active": "not active");2242 2243 if (details == VMINFO_MACHINEREADABLE)2244 RTPrintf("VRDPClients=%d\n", NumberOfClients);2245 else2246 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 else2258 RTPrintf("Start time: %s\n", timestr);2259 }2260 else2261 {2262 makeTimeStr (timestr, sizeof (timestr), BeginTime);2263 if (details == VMINFO_MACHINEREADABLE)2264 RTPrintf("VRDPLastStartTime=\"%s\"\n", timestr);2265 else2266 RTPrintf("Last started: %s\n", timestr);2267 makeTimeStr (timestr, sizeof (timestr), EndTime);2268 if (details == VMINFO_MACHINEREADABLE)2269 RTPrintf("VRDPLastEndTime=\"%s\"\n", timestr);2270 else2271 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 else2293 {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 else2315 {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_STANDARD2331 || details == VMINFO_FULL2332 || 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 else2341 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_BALLOONING2350 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);2351 if (SUCCEEDED(rc))2352 {2353 if (details == VMINFO_MACHINEREADABLE)2354 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);2355 else2356 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);2357 }2358 #endif2359 rc = machine->COMGETTER(StatisticsUpdateInterval)(&guestVal);2360 if (SUCCEEDED(rc))2361 {2362 if (details == VMINFO_MACHINEREADABLE)2363 RTPrintf("GuestStatisticsUpdateInterval=%d\n", guestVal);2364 else2365 {2366 if (guestVal == 0)2367 RTPrintf("Statistics update: disabled\n");2368 else2369 RTPrintf("Statistics update interval: %d seconds\n", guestVal);2370 }2371 }2372 if (details != VMINFO_MACHINEREADABLE)2373 RTPrintf("\n");2374 2375 if ( console2376 && ( details == VMINFO_STATISTICS2377 || details == VMINFO_FULL2378 || 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 else2391 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 else2399 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 else2408 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 else2417 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 else2426 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 else2435 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 else2444 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 else2453 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 else2462 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 else2471 RTPrintf("CPU%d: Free physical memory %-4d MB\n", 0, statVal);2472 }2473 2474 #ifdef VBOX_WITH_MEM_BALLOONING2475 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 else2481 RTPrintf("CPU%d: Memory balloon size %-4d MB\n", 0, statVal);2482 }2483 #endif2484 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 else2490 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 else2499 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 else2508 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 else2517 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 else2526 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 else2535 RTPrintf("CPU%d: Page file size %-4d MB\n", 0, statVal);2536 }2537 2538 RTPrintf("\n");2539 }2540 else2541 {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 * snapshots2552 */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 else2584 {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 else2602 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 else2610 if (fDetails && fStatistics)2611 details = VMINFO_FULL;2612 else2613 if (fDetails)2614 details = VMINFO_STANDARD;2615 else2616 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 VMs2653 */2654 com::SafeIfaceArray <IMachine> machines;2655 rc = virtualBox->COMGETTER(Machines2)(ComSafeArrayAsOutParam (machines));2656 if (SUCCEEDED(rc))2657 {2658 /*2659 * Iterate through the collection2660 */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 else2669 if (strcmp(argv[0], "runningvms") == 0)2670 {2671 /*2672 * Get the list of all _running_ VMs2673 */2674 com::SafeIfaceArray <IMachine> machines;2675 rc = virtualBox->COMGETTER(Machines2)(ComSafeArrayAsOutParam (machines));2676 if (SUCCEEDED(rc))2677 {2678 /*2679 * Iterate through the collection2680 */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 else2707 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 else2730 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 else2752 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 else2774 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 else2799 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 else2828 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 #endif2833 }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 #endif2852 }2853 else2854 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 else2930 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 parents2948 /// @todo NEWMEDIA print the full state value2949 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 too2966 /// @todo NEWMEDIA also list children and say 'differencing' for2967 /// hard disks with the parent or 'base' otherwise.2968 RTPrintf("\n");2969 }2970 }2971 else2972 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 else2993 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 else3014 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 else3036 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 else3105 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 else3128 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 else3213 return errorSyntax(USAGE_LIST, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());3214 3215 return SUCCEEDED(rc) ? 0 : 1;3216 }3217 3218 767 static int handleRegisterVM(int argc, char *argv[], 3219 768 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r14259 r14555 27 27 #include <VBox/com/VirtualBox.h> 28 28 #include <VBox/com/EventQueue.h> 29 #include <VBox/com/string.h> 29 30 #endif /* !VBOX_ONLY_DOCS */ 30 31 … … 112 113 * Prototypes 113 114 */ 115 /* VBoxManage.cpp */ 114 116 int errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...); 115 117 int errorArgument(const char *pszFormat, ...); … … 120 122 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession); 121 123 #endif /* !VBOX_ONLY_DOCS */ 124 125 /* VBoxManageGuestProp.cpp */ 122 126 extern void usageGuestProperty(void); 123 127 #ifndef VBOX_ONLY_DOCS 124 128 extern int handleGuestProperty(int argc, char *argv[], 125 129 ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession); 130 131 /* VBoxManageInfo.cpp */ 132 void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const com::Bstr &prefix = "", int level = 0); 133 int handleShowVMInfo(int argc, char *argv[], 134 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 135 HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine, 136 ComPtr <IConsole> console = ComPtr <IConsole> (), 137 VMINFO_DETAILS details = VMINFO_NONE); 138 int handleList(int argc, char *argv[], 139 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 140 141 /* VBoxManageVD.cpp */ 142 /* VBoxManageUSB.cpp */ 143 /* VBoxManageTODO.cpp */ 144 126 145 #endif /* !VBOX_ONLY_DOCS */ 127 146 unsigned long VBoxSVNRev(); -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
r14551 r14555 20 20 */ 21 21 22 #ifndef VBOX_ONLY_DOCS 22 23 23 24 /******************************************************************************* 24 25 * Header Files * 25 26 *******************************************************************************/ 26 #ifndef VBOX_ONLY_DOCS27 27 #include <VBox/com/com.h> 28 28 #include <VBox/com/string.h> … … 39 39 #include <vector> 40 40 #include <list> 41 #endif /* !VBOX_ONLY_DOCS */42 41 43 42 #include <iprt/runtime.h> … … 58 57 59 58 #include "VBoxManage.h" 60 61 #ifndef VBOX_ONLY_DOCS62 59 using namespace com; 63 60 64 /* missing XPCOM <-> COM wrappers */65 #ifndef STDMETHOD_66 # define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth67 #endif68 #ifndef NS_GET_IID69 # define NS_GET_IID(I) IID_##I70 #endif71 #ifndef RT_OS_WINDOWS72 #define IUnknown nsISupports73 #endif74 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_QUEUE80 /** A pointer to the event queue, set by main() before calling any handlers. */81 nsCOMPtr<nsIEventQueue> g_pEventQ;82 #endif83 84 /**85 * Quick IUSBDevice implementation for detaching / attaching86 * devices to the USB Controller.87 */88 class MyUSBDevice : public IUSBDevice89 {90 public:91 // public initializer/uninitializer for internal purposes only92 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 else119 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 // types152 ///////////////////////////////////////////////////////////////////////////////153 154 template <typename T>155 class Nullable156 {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 USBFilterCmd183 {184 struct USBFilter185 {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 */216 61 217 62 // funcs 218 63 /////////////////////////////////////////////////////////////////////////////// 219 64 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(¤tPercent)); 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 67 void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const Bstr &prefix /* = ""*/, int level /*= 0*/) 768 68 { 769 69 /* start with the root */ … … 826 126 } 827 127 828 staticHRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,829 ComPtr <IConsole> console = ComPtr <IConsole> (),830 VMINFO_DETAILS details = VMINFO_NONE)128 HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine, 129 ComPtr <IConsole> console /*= ComPtr <IConsole> ()*/, 130 VMINFO_DETAILS details /*= VMINFO_NONE*/) 831 131 { 832 132 HRESULT rc; … … 1167 467 } 1168 468 1169 /* 469 /* 1170 470 * SATA Hard disks 1171 471 */ … … 2565 1865 } 2566 1866 2567 staticint handleShowVMInfo(int argc, char *argv[],2568 1867 int handleShowVMInfo(int argc, char *argv[], 1868 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 2569 1869 { 2570 1870 HRESULT rc; … … 2636 1936 } 2637 1937 2638 2639 static int handleList(int argc, char *argv[], 2640 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 1938 int handleList(int argc, char *argv[], 1939 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 2641 1940 { 2642 1941 HRESULT rc = S_OK; … … 3216 2515 } 3217 2516 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.