Changeset 15492 in vbox for trunk/src/VBox/Frontends/VBoxManage
- Timestamp:
- Dec 15, 2008 10:36:07 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 40959
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
r15235 r15492 47 47 VBoxManageMetrics.cpp \ 48 48 VBoxManageList.cpp \ 49 VBoxManageDisk.cpp \ 49 50 VBoxInternalManage.cpp \ 50 51 $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \ -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r15489 r15492 54 54 #include <iprt/uuid.h> 55 55 #include <VBox/version.h> 56 #include <VBox/VBoxHDD-new.h>57 56 #include <VBox/log.h> 58 57 … … 729 728 * Print out progress on the console 730 729 */ 731 staticvoid showProgress(ComPtr<IProgress> progress)730 void showProgress(ComPtr<IProgress> progress) 732 731 { 733 732 BOOL fCompleted; … … 825 824 } 826 825 } 827 return SUCCEEDED(rc) ? 0 : 1;828 }829 830 831 static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)832 {833 RTPrintf("ERROR: ");834 RTPrintfV(pszFormat, va);835 RTPrintf("\n");836 RTPrintf("Error code %Rrc at %s(%u) in function %s\n", rc, RT_SRC_POS_ARGS);837 }838 839 840 static int handleCreateHardDisk(int argc, char *argv[],841 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)842 {843 HRESULT rc;844 Bstr filename;845 uint64_t sizeMB = 0;846 Bstr format = "VDI";847 bool fStatic = false;848 Bstr comment;849 bool fRegister = false;850 const char *type = "normal";851 852 /* let's have a closer look at the arguments */853 for (int i = 0; i < argc; i++)854 {855 if (strcmp(argv[i], "-filename") == 0)856 {857 if (argc <= i + 1)858 return errorArgument("Missing argument to '%s'", argv[i]);859 i++;860 filename = argv[i];861 }862 else if (strcmp(argv[i], "-size") == 0)863 {864 if (argc <= i + 1)865 return errorArgument("Missing argument to '%s'", argv[i]);866 i++;867 sizeMB = RTStrToUInt64(argv[i]);868 }869 else if (strcmp(argv[i], "-format") == 0)870 {871 if (argc <= i + 1)872 return errorArgument("Missing argument to '%s'", argv[i]);873 i++;874 format = argv[i];875 }876 else if (strcmp(argv[i], "-static") == 0)877 {878 fStatic = true;879 }880 else if (strcmp(argv[i], "-comment") == 0)881 {882 if (argc <= i + 1)883 return errorArgument("Missing argument to '%s'", argv[i]);884 i++;885 comment = argv[i];886 }887 else if (strcmp(argv[i], "-register") == 0)888 {889 fRegister = true;890 }891 else if (strcmp(argv[i], "-type") == 0)892 {893 if (argc <= i + 1)894 return errorArgument("Missing argument to '%s'", argv[i]);895 i++;896 type = argv[i];897 }898 else899 return errorSyntax(USAGE_CREATEHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());900 }901 /* check the outcome */902 if (!filename || (sizeMB == 0))903 return errorSyntax(USAGE_CREATEHD, "Parameters -filename and -size are required");904 905 if (strcmp(type, "normal") && strcmp(type, "writethrough"))906 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());907 908 ComPtr<IHardDisk2> hardDisk;909 CHECK_ERROR(virtualBox, CreateHardDisk2(format, filename, hardDisk.asOutParam()));910 if (SUCCEEDED(rc) && hardDisk)911 {912 /* we will close the hard disk after the storage has been successfully913 * created unless fRegister is set */914 bool doClose = false;915 916 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));917 ComPtr<IProgress> progress;918 if (fStatic)919 {920 CHECK_ERROR(hardDisk, CreateFixedStorage(sizeMB, progress.asOutParam()));921 }922 else923 {924 CHECK_ERROR(hardDisk, CreateDynamicStorage(sizeMB, progress.asOutParam()));925 }926 if (SUCCEEDED(rc) && progress)927 {928 if (fStatic)929 showProgress(progress);930 else931 CHECK_ERROR(progress, WaitForCompletion(-1));932 if (SUCCEEDED(rc))933 {934 progress->COMGETTER(ResultCode)(&rc);935 if (FAILED(rc))936 {937 com::ProgressErrorInfo info(progress);938 if (info.isBasicAvailable())939 RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());940 else941 RTPrintf("Error: failed to create hard disk. No error message available!\n");942 }943 else944 {945 doClose = !fRegister;946 947 Guid uuid;948 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));949 950 if (strcmp(type, "normal") == 0)951 {952 /* nothing required, default */953 }954 else if (strcmp(type, "writethrough") == 0)955 {956 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));957 }958 959 RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());960 }961 }962 }963 if (doClose)964 {965 CHECK_ERROR(hardDisk, Close());966 }967 }968 return SUCCEEDED(rc) ? 0 : 1;969 }970 971 #if 0 /* disabled until disk shrinking is implemented based on VBoxHDD-new */972 static DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)973 {974 unsigned *pPercent = (unsigned *)pvUser;975 976 if (*pPercent != uPercent)977 {978 *pPercent = uPercent;979 RTPrintf(".");980 if ((uPercent % 10) == 0 && uPercent)981 RTPrintf("%d%%", uPercent);982 RTStrmFlush(g_pStdOut);983 }984 985 return VINF_SUCCESS;986 }987 #endif988 989 990 static int handleModifyHardDisk(int argc, char *argv[],991 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)992 {993 HRESULT rc;994 995 /* The uuid/filename and a command */996 if (argc < 2)997 return errorSyntax(USAGE_MODIFYHD, "Incorrect number of parameters");998 999 ComPtr<IHardDisk2> hardDisk;1000 Bstr filepath;1001 1002 /* first guess is that it's a UUID */1003 Guid uuid(argv[0]);1004 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());1005 /* no? then it must be a filename */1006 if (!hardDisk)1007 {1008 filepath = argv[0];1009 CHECK_ERROR(virtualBox, FindHardDisk2(filepath, hardDisk.asOutParam()));1010 }1011 1012 /* let's find out which command */1013 if (strcmp(argv[1], "settype") == 0)1014 {1015 /* hard disk must be registered */1016 if (SUCCEEDED(rc) && hardDisk)1017 {1018 char *type = NULL;1019 1020 if (argc <= 2)1021 return errorArgument("Missing argument to for settype");1022 1023 type = argv[2];1024 1025 HardDiskType_T hddType;1026 CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));1027 1028 if (strcmp(type, "normal") == 0)1029 {1030 if (hddType != HardDiskType_Normal)1031 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));1032 }1033 else if (strcmp(type, "writethrough") == 0)1034 {1035 if (hddType != HardDiskType_Writethrough)1036 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));1037 1038 }1039 else if (strcmp(type, "immutable") == 0)1040 {1041 if (hddType != HardDiskType_Immutable)1042 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));1043 }1044 else1045 {1046 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());1047 }1048 }1049 else1050 return errorArgument("Hard disk image not registered");1051 }1052 else if (strcmp(argv[1], "compact") == 0)1053 {1054 #if 11055 RTPrintf("Error: Shrink hard disk operation is temporarily unavailable!\n");1056 return 1;1057 #else1058 /* the hard disk image might not be registered */1059 if (!hardDisk)1060 {1061 virtualBox->OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam());1062 if (!hardDisk)1063 return errorArgument("Hard disk image not found");1064 }1065 1066 Bstr format;1067 hardDisk->COMGETTER(Format)(format.asOutParam());1068 if (format != "VDI")1069 return errorArgument("Invalid hard disk type. The command only works on VDI files\n");1070 1071 Bstr fileName;1072 hardDisk->COMGETTER(Location)(fileName.asOutParam());1073 1074 /* make sure the object reference is released */1075 hardDisk = NULL;1076 1077 unsigned uProcent;1078 1079 RTPrintf("Shrinking '%lS': 0%%", fileName.raw());1080 int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), hardDiskProgressCallback, &uProcent);1081 if (RT_FAILURE(vrc))1082 {1083 RTPrintf("Error while shrinking hard disk image: %Rrc\n", vrc);1084 rc = E_FAIL;1085 }1086 #endif1087 }1088 else1089 return errorSyntax(USAGE_MODIFYHD, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());1090 1091 return SUCCEEDED(rc) ? 0 : 1;1092 }1093 1094 static int handleCloneHardDisk(int argc, char *argv[],1095 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)1096 {1097 #if 11098 RTPrintf("Error: Clone hard disk operation is temporarily unavailable!\n");1099 return 1;1100 #else1101 /// @todo NEWMEDIA use IHardDisk2::cloneTo/flattenTo (not yet implemented)1102 HRESULT rc;1103 1104 /* source hard disk and target path */1105 if (argc != 2)1106 return errorSyntax(USAGE_CLONEHD, "Incorrect number of parameters");1107 1108 /* first guess is that it's a UUID */1109 Guid uuid(argv[0]);1110 ComPtr<IHardDisk2> hardDisk;1111 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());1112 if (!hardDisk)1113 {1114 /* not successful? Then it must be a filename */1115 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam()));1116 }1117 if (hardDisk)1118 {1119 ComPtr<IProgress> progress;1120 CHECK_ERROR(hardDisk, CloneToImage(Bstr(argv[1]), hardDisk.asOutParam(), progress.asOutParam()));1121 if (SUCCEEDED(rc))1122 {1123 showProgress(progress);1124 progress->COMGETTER(ResultCode)(&rc);1125 if (FAILED(rc))1126 {1127 com::ProgressErrorInfo info(progress);1128 if (info.isBasicAvailable())1129 {1130 RTPrintf("Error: failed to clone disk image. Error message: %lS\n", info.getText().raw());1131 }1132 else1133 {1134 RTPrintf("Error: failed to clone disk image. No error message available!\n");1135 }1136 }1137 }1138 }1139 return SUCCEEDED(rc) ? 0 : 1;1140 #endif1141 }1142 1143 static int handleConvertHardDisk(int argc, char **argv)1144 {1145 Bstr srcformat;1146 Bstr dstformat;1147 Bstr src;1148 Bstr dst;1149 int vrc;1150 PVBOXHDD pSrcDisk = NULL;1151 PVBOXHDD pDstDisk = NULL;1152 1153 /* Parse the arguments. */1154 for (int i = 0; i < argc; i++)1155 {1156 if (strcmp(argv[i], "-srcformat") == 0)1157 {1158 if (argc <= i + 1)1159 {1160 return errorArgument("Missing argument to '%s'", argv[i]);1161 }1162 i++;1163 srcformat = argv[i];1164 }1165 else if (strcmp(argv[i], "-dstformat") == 0)1166 {1167 if (argc <= i + 1)1168 {1169 return errorArgument("Missing argument to '%s'", argv[i]);1170 }1171 i++;1172 dstformat = argv[i];1173 }1174 else if (src.isEmpty())1175 {1176 src = argv[i];1177 }1178 else if (dst.isEmpty())1179 {1180 dst = argv[i];1181 }1182 else1183 {1184 return errorSyntax(USAGE_CONVERTHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());1185 }1186 }1187 1188 if (src.isEmpty())1189 return errorSyntax(USAGE_CONVERTHD, "Mandatory input image parameter missing");1190 if (dst.isEmpty())1191 return errorSyntax(USAGE_CONVERTHD, "Mandatory output image parameter missing");1192 1193 1194 PVDINTERFACE pVDIfs = NULL;1195 VDINTERFACE vdInterfaceError;1196 VDINTERFACEERROR vdInterfaceErrorCallbacks;1197 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);1198 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;1199 vdInterfaceErrorCallbacks.pfnError = handleVDError;1200 1201 vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,1202 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);1203 AssertRC(vrc);1204 1205 do1206 {1207 /* Try to determine input image format */1208 if (srcformat.isEmpty())1209 {1210 char *pszFormat = NULL;1211 vrc = VDGetFormat(Utf8Str(src).raw(), &pszFormat);1212 if (RT_FAILURE(vrc))1213 {1214 RTPrintf("No file format specified and autodetect failed - please specify format: %Rrc\n", vrc);1215 break;1216 }1217 srcformat = pszFormat;1218 RTStrFree(pszFormat);1219 }1220 1221 vrc = VDCreate(pVDIfs, &pSrcDisk);1222 if (RT_FAILURE(vrc))1223 {1224 RTPrintf("Error while creating the source virtual disk container: %Rrc\n", vrc);1225 break;1226 }1227 1228 /* Open the input image */1229 vrc = VDOpen(pSrcDisk, Utf8Str(srcformat).raw(), Utf8Str(src).raw(), VD_OPEN_FLAGS_READONLY, NULL);1230 if (RT_FAILURE(vrc))1231 {1232 RTPrintf("Error while opening the source image: %Rrc\n", vrc);1233 break;1234 }1235 1236 /* Output format defaults to VDI */1237 if (dstformat.isEmpty())1238 dstformat = "VDI";1239 1240 vrc = VDCreate(pVDIfs, &pDstDisk);1241 if (RT_FAILURE(vrc))1242 {1243 RTPrintf("Error while creating the destination virtual disk container: %Rrc\n", vrc);1244 break;1245 }1246 1247 uint64_t cbSize = VDGetSize(pSrcDisk, VD_LAST_IMAGE);1248 RTPrintf("Converting image \"%s\" with size %RU64 bytes (%RU64MB)...\n", Utf8Str(src).raw(), cbSize, (cbSize + _1M - 1) / _1M);1249 1250 /* Create the output image */1251 vrc = VDCopy(pSrcDisk, VD_LAST_IMAGE, pDstDisk, Utf8Str(dstformat).raw(),1252 Utf8Str(dst).raw(), false, 0, NULL, NULL, NULL);1253 if (RT_FAILURE(vrc))1254 {1255 RTPrintf("Error while copying the image: %Rrc\n", vrc);1256 break;1257 }1258 }1259 while (0);1260 if (pDstDisk)1261 VDCloseAll(pDstDisk);1262 if (pSrcDisk)1263 VDCloseAll(pSrcDisk);1264 1265 return RT_SUCCESS(vrc) ? 0 : 1;1266 }1267 1268 1269 static int handleConvertDDImage(int argc, char *argv[])1270 {1271 VDIMAGETYPE enmImgType = VD_IMAGE_TYPE_NORMAL;1272 bool fReadFromStdIn = false;1273 const char *format = NULL;1274 const char *srcfilename = NULL;1275 const char *dstfilename = NULL;1276 const char *filesize = NULL;1277 unsigned uImageFlags = 0; /**< @todo allow creation of non-default image variants */1278 void *pvBuf = NULL;1279 1280 for (int i = 0; i < argc; i++)1281 {1282 if (!strcmp(argv[i], "-static"))1283 {1284 enmImgType = VD_IMAGE_TYPE_FIXED;1285 }1286 else if (strcmp(argv[i], "-format") == 0)1287 {1288 if (argc <= i + 1)1289 {1290 return errorArgument("Missing argument to '%s'", argv[i]);1291 }1292 i++;1293 format = argv[i];1294 }1295 else1296 {1297 if (srcfilename)1298 {1299 if (dstfilename)1300 {1301 if (fReadFromStdIn && !filesize)1302 filesize = argv[i];1303 else1304 return errorSyntax(USAGE_CONVERTDD, "Incorrect number of parameters");1305 }1306 else1307 dstfilename = argv[i];1308 }1309 else1310 {1311 srcfilename = argv[i];1312 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)1313 fReadFromStdIn = !strcmp(srcfilename, "stdin");1314 #endif1315 }1316 }1317 }1318 1319 RTPrintf("Converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",1320 srcfilename, dstfilename);1321 1322 int rc = VINF_SUCCESS;1323 PVBOXHDD pDisk = NULL;1324 1325 PVDINTERFACE pVDIfs = NULL;1326 VDINTERFACE vdInterfaceError;1327 VDINTERFACEERROR vdInterfaceErrorCallbacks;1328 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);1329 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;1330 vdInterfaceErrorCallbacks.pfnError = handleVDError;1331 1332 rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,1333 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);1334 AssertRC(rc);1335 1336 /* open raw image file. */1337 RTFILE File;1338 if (fReadFromStdIn)1339 File = 0;1340 else1341 rc = RTFileOpen(&File, srcfilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);1342 if (RT_FAILURE(rc))1343 {1344 RTPrintf("File=\"%s\" open error: %Rrf\n", srcfilename, rc);1345 goto out;1346 }1347 1348 uint64_t cbFile;1349 /* get image size. */1350 if (fReadFromStdIn)1351 cbFile = RTStrToUInt64(filesize);1352 else1353 rc = RTFileGetSize(File, &cbFile);1354 if (RT_FAILURE(rc))1355 {1356 RTPrintf("Error getting image size for file \"%s\": %Rrc\n", srcfilename, rc);1357 goto out;1358 }1359 1360 RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (enmImgType == VD_IMAGE_TYPE_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);1361 char pszComment[256];1362 RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", srcfilename);1363 rc = VDCreate(pVDIfs, &pDisk);1364 if (RT_FAILURE(rc))1365 {1366 RTPrintf("Error while creating the virtual disk container: %Rrc\n", rc);1367 goto out;1368 }1369 1370 Assert(RT_MIN(cbFile / 512 / 16 / 63, 16383) -1371 (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383) == 0);1372 PDMMEDIAGEOMETRY PCHS, LCHS;1373 PCHS.cCylinders = (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383);1374 PCHS.cHeads = 16;1375 PCHS.cSectors = 63;1376 LCHS.cCylinders = 0;1377 LCHS.cHeads = 0;1378 LCHS.cSectors = 0;1379 rc = VDCreateBase(pDisk, format, dstfilename, enmImgType, cbFile,1380 uImageFlags, pszComment, &PCHS, &LCHS, NULL,1381 VD_OPEN_FLAGS_NORMAL, NULL, NULL);1382 if (RT_FAILURE(rc))1383 {1384 RTPrintf("Error while creating the disk image \"%s\": %Rrc\n", dstfilename, rc);1385 goto out;1386 }1387 1388 size_t cbBuffer;1389 cbBuffer = _1M;1390 pvBuf = RTMemAlloc(cbBuffer);1391 if (!pvBuf)1392 {1393 rc = VERR_NO_MEMORY;1394 RTPrintf("Not enough memory allocating buffers for image \"%s\": %Rrc\n", dstfilename, rc);1395 goto out;1396 }1397 1398 uint64_t offFile;1399 offFile = 0;1400 while (offFile < cbFile)1401 {1402 size_t cbRead;1403 size_t cbToRead;1404 cbRead = 0;1405 cbToRead = cbFile - offFile >= (uint64_t)cbBuffer ?1406 cbBuffer : (size_t) (cbFile - offFile);1407 rc = RTFileRead(File, pvBuf, cbToRead, &cbRead);1408 if (RT_FAILURE(rc) || !cbRead)1409 break;1410 rc = VDWrite(pDisk, offFile, pvBuf, cbRead);1411 if (RT_FAILURE(rc))1412 {1413 RTPrintf("Failed to write to disk image \"%s\": %Rrc\n", dstfilename, rc);1414 goto out;1415 }1416 offFile += cbRead;1417 }1418 1419 out:1420 if (pvBuf)1421 RTMemFree(pvBuf);1422 if (pDisk)1423 VDClose(pDisk, RT_FAILURE(rc));1424 if (File != NIL_RTFILE)1425 RTFileClose(File);1426 1427 return RT_FAILURE(rc);1428 }1429 1430 static int handleAddiSCSIDisk(int argc, char *argv[],1431 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)1432 {1433 HRESULT rc;1434 Bstr server;1435 Bstr target;1436 Bstr port;1437 Bstr lun;1438 Bstr username;1439 Bstr password;1440 Bstr comment;1441 bool fIntNet = false;1442 1443 /* at least server and target */1444 if (argc < 4)1445 return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");1446 1447 /* let's have a closer look at the arguments */1448 for (int i = 0; i < argc; i++)1449 {1450 if (strcmp(argv[i], "-server") == 0)1451 {1452 if (argc <= i + 1)1453 return errorArgument("Missing argument to '%s'", argv[i]);1454 i++;1455 server = argv[i];1456 }1457 else if (strcmp(argv[i], "-target") == 0)1458 {1459 if (argc <= i + 1)1460 return errorArgument("Missing argument to '%s'", argv[i]);1461 i++;1462 target = argv[i];1463 }1464 else if (strcmp(argv[i], "-port") == 0)1465 {1466 if (argc <= i + 1)1467 return errorArgument("Missing argument to '%s'", argv[i]);1468 i++;1469 port = argv[i];1470 }1471 else if (strcmp(argv[i], "-lun") == 0)1472 {1473 if (argc <= i + 1)1474 return errorArgument("Missing argument to '%s'", argv[i]);1475 i++;1476 lun = argv[i];1477 }1478 else if (strcmp(argv[i], "-encodedlun") == 0)1479 {1480 if (argc <= i + 1)1481 return errorArgument("Missing argument to '%s'", argv[i]);1482 i++;1483 lun = L"enc";1484 lun = lun + argv[i];1485 }1486 else if (strcmp(argv[i], "-username") == 0)1487 {1488 if (argc <= i + 1)1489 return errorArgument("Missing argument to '%s'", argv[i]);1490 i++;1491 username = argv[i];1492 }1493 else if (strcmp(argv[i], "-password") == 0)1494 {1495 if (argc <= i + 1)1496 return errorArgument("Missing argument to '%s'", argv[i]);1497 i++;1498 password = argv[i];1499 }1500 else if (strcmp(argv[i], "-comment") == 0)1501 {1502 if (argc <= i + 1)1503 return errorArgument("Missing argument to '%s'", argv[i]);1504 i++;1505 comment = argv[i];1506 }1507 else if (strcmp(argv[i], "-intnet") == 0)1508 {1509 i++;1510 fIntNet = true;1511 }1512 else1513 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());1514 }1515 1516 /* check for required options */1517 if (!server || !target)1518 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");1519 1520 do1521 {1522 ComPtr<IHardDisk2> hardDisk;1523 CHECK_ERROR_BREAK (aVirtualBox,1524 CreateHardDisk2(Bstr ("iSCSI"),1525 BstrFmt ("%ls/%ls", server.raw(), target.raw()),1526 hardDisk.asOutParam()));1527 CheckComRCBreakRC (rc);1528 1529 if (!comment.isNull())1530 CHECK_ERROR_BREAK(hardDisk, COMSETTER(Description)(comment));1531 1532 if (!port.isNull())1533 server = BstrFmt ("%ls:%ls", server.raw(), port.raw());1534 1535 com::SafeArray <BSTR> names;1536 com::SafeArray <BSTR> values;1537 1538 Bstr ("TargetAddress").detachTo (names.appendedRaw());1539 server.detachTo (values.appendedRaw());1540 Bstr ("TargetName").detachTo (names.appendedRaw());1541 target.detachTo (values.appendedRaw());1542 1543 if (!lun.isNull())1544 {1545 Bstr ("LUN").detachTo (names.appendedRaw());1546 lun.detachTo (values.appendedRaw());1547 }1548 if (!username.isNull())1549 {1550 Bstr ("InitiatorUsername").detachTo (names.appendedRaw());1551 username.detachTo (values.appendedRaw());1552 }1553 if (!password.isNull())1554 {1555 Bstr ("InitiatorSecret").detachTo (names.appendedRaw());1556 password.detachTo (values.appendedRaw());1557 }1558 1559 /// @todo add -initiator option1560 Bstr ("InitiatorName").detachTo (names.appendedRaw());1561 Bstr ("iqn.2008-04.com.sun.virtualbox.initiator").detachTo (values.appendedRaw());1562 1563 /// @todo add -targetName and -targetPassword options1564 1565 if (fIntNet)1566 {1567 Bstr ("HostIPStack").detachTo (names.appendedRaw());1568 Bstr ("0").detachTo (values.appendedRaw());1569 }1570 1571 CHECK_ERROR_BREAK (hardDisk,1572 SetProperties (ComSafeArrayAsInParam (names),1573 ComSafeArrayAsInParam (values)));1574 1575 Guid guid;1576 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));1577 RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());1578 }1579 while (0);1580 1581 826 return SUCCEEDED(rc) ? 0 : 1; 1582 827 } … … 4366 3611 } 4367 3612 4368 static int handleShowHardDiskInfo(int argc, char *argv[],4369 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4370 {4371 HRESULT rc;4372 4373 if (argc != 1)4374 return errorSyntax(USAGE_SHOWHDINFO, "Incorrect number of parameters");4375 4376 ComPtr<IHardDisk2> hardDisk;4377 Bstr filepath;4378 4379 bool unknown = false;4380 4381 /* first guess is that it's a UUID */4382 Guid uuid(argv[0]);4383 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());4384 /* no? then it must be a filename */4385 if (FAILED (rc))4386 {4387 filepath = argv[0];4388 rc = virtualBox->FindHardDisk2(filepath, hardDisk.asOutParam());4389 /* no? well, then it's an unkwnown image */4390 if (FAILED (rc))4391 {4392 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));4393 if (SUCCEEDED (rc))4394 {4395 unknown = true;4396 }4397 }4398 }4399 do4400 {4401 if (!SUCCEEDED(rc))4402 break;4403 4404 hardDisk->COMGETTER(Id)(uuid.asOutParam());4405 RTPrintf("UUID: %s\n", uuid.toString().raw());4406 4407 /* check for accessibility */4408 /// @todo NEWMEDIA check accessibility of all parents4409 /// @todo NEWMEDIA print the full state value4410 MediaState_T state;4411 CHECK_ERROR_BREAK (hardDisk, COMGETTER(State)(&state));4412 RTPrintf("Accessible: %s\n", state != MediaState_Inaccessible ? "yes" : "no");4413 4414 if (state == MediaState_Inaccessible)4415 {4416 Bstr err;4417 CHECK_ERROR_BREAK (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));4418 RTPrintf("Access Error: %lS\n", err.raw());4419 }4420 4421 Bstr description;4422 hardDisk->COMGETTER(Description)(description.asOutParam());4423 if (description)4424 {4425 RTPrintf("Description: %lS\n", description.raw());4426 }4427 4428 ULONG64 logicalSize;4429 hardDisk->COMGETTER(LogicalSize)(&logicalSize);4430 RTPrintf("Logical size: %llu MBytes\n", logicalSize);4431 ULONG64 actualSize;4432 hardDisk->COMGETTER(Size)(&actualSize);4433 RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);4434 4435 HardDiskType_T type;4436 hardDisk->COMGETTER(Type)(&type);4437 const char *typeStr = "unknown";4438 switch (type)4439 {4440 case HardDiskType_Normal:4441 typeStr = "normal";4442 break;4443 case HardDiskType_Immutable:4444 typeStr = "immutable";4445 break;4446 case HardDiskType_Writethrough:4447 typeStr = "writethrough";4448 break;4449 }4450 RTPrintf("Type: %s\n", typeStr);4451 4452 Bstr format;4453 hardDisk->COMGETTER(Format)(format.asOutParam());4454 RTPrintf("Storage format: %lS\n", format.raw());4455 4456 if (!unknown)4457 {4458 com::SafeGUIDArray machineIds;4459 hardDisk->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));4460 for (size_t j = 0; j < machineIds.size(); ++ j)4461 {4462 ComPtr<IMachine> machine;4463 CHECK_ERROR(virtualBox, GetMachine(machineIds[j], machine.asOutParam()));4464 ASSERT(machine);4465 Bstr name;4466 machine->COMGETTER(Name)(name.asOutParam());4467 machine->COMGETTER(Id)(uuid.asOutParam());4468 RTPrintf("%s%lS (UUID: %RTuuid)\n",4469 j == 0 ? "In use by VMs: " : " ",4470 name.raw(), &machineIds[j]);4471 }4472 /// @todo NEWMEDIA check usage in snapshots too4473 /// @todo NEWMEDIA also list children and say 'differencing' for4474 /// hard disks with the parent or 'base' otherwise.4475 }4476 4477 Bstr loc;4478 hardDisk->COMGETTER(Location)(loc.asOutParam());4479 RTPrintf("Location: %lS\n", loc.raw());4480 }4481 while (0);4482 4483 if (unknown)4484 {4485 /* close the unknown hard disk to forget it again */4486 hardDisk->Close();4487 }4488 4489 return SUCCEEDED(rc) ? 0 : 1;4490 }4491 4492 static int handleOpenMedium(int argc, char *argv[],4493 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4494 {4495 HRESULT rc;4496 4497 if (argc < 2)4498 return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");4499 4500 Bstr filepath(argv[1]);4501 4502 if (strcmp(argv[0], "disk") == 0)4503 {4504 const char *type = NULL;4505 /* there can be a type parameter */4506 if ((argc > 2) && (argc != 4))4507 return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");4508 if (argc == 4)4509 {4510 if (strcmp(argv[2], "-type") != 0)4511 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());4512 if ( (strcmp(argv[3], "normal") != 0)4513 && (strcmp(argv[3], "immutable") != 0)4514 && (strcmp(argv[3], "writethrough") != 0))4515 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(argv[3]).raw());4516 type = argv[3];4517 }4518 4519 ComPtr<IHardDisk2> hardDisk;4520 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));4521 if (SUCCEEDED(rc) && hardDisk)4522 {4523 /* change the type if requested */4524 if (type)4525 {4526 if (strcmp(type, "normal") == 0)4527 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));4528 else if (strcmp(type, "immutable") == 0)4529 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));4530 else if (strcmp(type, "writethrough") == 0)4531 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));4532 }4533 }4534 }4535 else if (strcmp(argv[0], "dvd") == 0)4536 {4537 ComPtr<IDVDImage2> dvdImage;4538 CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));4539 }4540 else if (strcmp(argv[0], "floppy") == 0)4541 {4542 ComPtr<IFloppyImage2> floppyImage;4543 CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));4544 }4545 else4546 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());4547 4548 return SUCCEEDED(rc) ? 0 : 1;4549 }4550 4551 static int handleCloseMedium(int argc, char *argv[],4552 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4553 {4554 HRESULT rc;4555 4556 if (argc != 2)4557 return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");4558 4559 /* first guess is that it's a UUID */4560 Guid uuid(argv[1]);4561 4562 if (strcmp(argv[0], "disk") == 0)4563 {4564 ComPtr<IHardDisk2> hardDisk;4565 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());4566 /* not a UUID or not registered? Then it must be a filename */4567 if (!hardDisk)4568 {4569 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(argv[1]), hardDisk.asOutParam()));4570 }4571 if (SUCCEEDED(rc) && hardDisk)4572 {4573 CHECK_ERROR(hardDisk, Close());4574 }4575 }4576 else4577 if (strcmp(argv[0], "dvd") == 0)4578 {4579 ComPtr<IDVDImage2> dvdImage;4580 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());4581 /* not a UUID or not registered? Then it must be a filename */4582 if (!dvdImage)4583 {4584 CHECK_ERROR(virtualBox, FindDVDImage(Bstr(argv[1]), dvdImage.asOutParam()));4585 }4586 if (SUCCEEDED(rc) && dvdImage)4587 {4588 CHECK_ERROR(dvdImage, Close());4589 }4590 }4591 else4592 if (strcmp(argv[0], "floppy") == 0)4593 {4594 ComPtr<IFloppyImage2> floppyImage;4595 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());4596 /* not a UUID or not registered? Then it must be a filename */4597 if (!floppyImage)4598 {4599 CHECK_ERROR(virtualBox, FindFloppyImage(Bstr(argv[1]), floppyImage.asOutParam()));4600 }4601 if (SUCCEEDED(rc) && floppyImage)4602 {4603 CHECK_ERROR(floppyImage, Close());4604 }4605 }4606 else4607 return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());4608 4609 return SUCCEEDED(rc) ? 0 : 1;4610 }4611 3613 4612 3614 #ifdef RT_OS_WINDOWS -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r15366 r15492 118 118 119 119 void printUsageInternal(USAGECATEGORY u64Cmd); 120 121 void showProgress(ComPtr<IProgress> progress); 122 120 123 #ifndef VBOX_ONLY_DOCS 121 124 int handleInternalCommands(int argc, char *argv[], … … 145 148 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 146 149 147 /* VBoxManageVD.cpp */ 150 /* VBoxManageDisk.cpp */ 151 int handleCreateHardDisk(int argc, char *argv[], 152 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 153 int handleModifyHardDisk(int argc, char *argv[], 154 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 155 int handleCloneHardDisk(int argc, char *argv[], 156 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 157 int handleConvertHardDisk(int argc, char **argv); 158 int handleConvertDDImage(int argc, char *argv[]); 159 int handleAddiSCSIDisk(int argc, char *argv[], 160 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession); 161 int handleShowHardDiskInfo(int argc, char *argv[], 162 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 163 int handleOpenMedium(int argc, char *argv[], 164 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 165 int handleCloseMedium(int argc, char *argv[], 166 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session); 167 148 168 /* VBoxManageUSB.cpp */ 149 169 /* VBoxManageTODO.cpp */ -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
r15489 r15492 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxManage - VirtualBox's command-line interface.3 * VBoxManage - The disk delated commands. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2006-200 7Sun Microsystems, Inc.7 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 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 #include <VBox/com/string.h>29 #include <VBox/com/Guid.h>30 28 #include <VBox/com/array.h> 31 29 #include <VBox/com/ErrorInfo.h> 32 #include <VBox/com/EventQueue.h>33 34 30 #include <VBox/com/VirtualBox.h> 35 31 36 #include <vector>37 #include <list>38 #endif /* !VBOX_ONLY_DOCS */39 40 32 #include <iprt/asm.h> 41 #include <iprt/cidr.h>42 #include <iprt/ctype.h>43 #include <iprt/dir.h>44 #include <iprt/env.h>45 #include <VBox/err.h>46 33 #include <iprt/file.h> 47 #include <iprt/initterm.h>48 #include <iprt/param.h>49 #include <iprt/path.h>50 34 #include <iprt/stream.h> 51 35 #include <iprt/string.h> 52 #include <iprt/stdarg.h> 53 #include <iprt/thread.h> 54 #include <iprt/uuid.h> 55 #include <VBox/version.h> 36 #include <VBox/log.h> 56 37 #include <VBox/VBoxHDD-new.h> 57 #include <VBox/log.h>58 38 59 39 #include "VBoxManage.h" 60 61 #ifndef VBOX_ONLY_DOCS62 40 using namespace com; 63 41 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 int (*PFNHANDLER)(int argc, char *argv[], ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);77 78 #ifdef USE_XPCOM_QUEUE79 /** A pointer to the event queue, set by main() before calling any handlers. */80 nsCOMPtr<nsIEventQueue> g_pEventQ;81 #endif82 83 /**84 * Quick IUSBDevice implementation for detaching / attaching85 * devices to the USB Controller.86 */87 class MyUSBDevice : public IUSBDevice88 {89 public:90 // public initializer/uninitializer for internal purposes only91 MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)92 : m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),93 m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),94 m_bstrComment(a_pszComment),95 m_cRefs(0)96 {97 }98 99 STDMETHOD_(ULONG, AddRef)(void)100 {101 return ASMAtomicIncU32(&m_cRefs);102 }103 STDMETHOD_(ULONG, Release)(void)104 {105 ULONG cRefs = ASMAtomicDecU32(&m_cRefs);106 if (!cRefs)107 delete this;108 return cRefs;109 }110 STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)111 {112 Guid guid(iid);113 if (guid == Guid(NS_GET_IID(IUnknown)))114 *ppvObject = (IUnknown *)this;115 else if (guid == Guid(NS_GET_IID(IUSBDevice)))116 *ppvObject = (IUSBDevice *)this;117 else118 return E_NOINTERFACE;119 AddRef();120 return S_OK;121 }122 123 STDMETHOD(COMGETTER(Id))(OUT_GUID a_pId) { return E_NOTIMPL; }124 STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId) { *a_pusVendorId = m_usVendorId; return S_OK; }125 STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId) { *a_pusProductId = m_usProductId; return S_OK; }126 STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision) { *a_pusRevision = m_bcdRevision; return S_OK; }127 STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash; return S_OK; }128 STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer) { return E_NOTIMPL; }129 STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct) { return E_NOTIMPL; }130 STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber) { return E_NOTIMPL; }131 STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress) { return E_NOTIMPL; }132 133 private:134 /** The vendor id of this USB device. */135 USHORT m_usVendorId;136 /** The product id of this USB device. */137 USHORT m_usProductId;138 /** The product revision number of this USB device.139 * (high byte = integer; low byte = decimal) */140 USHORT m_bcdRevision;141 /** The USB serial hash of the device. */142 uint64_t m_u64SerialHash;143 /** The user comment string. */144 Bstr m_bstrComment;145 /** Reference counter. */146 uint32_t volatile m_cRefs;147 };148 149 150 // types151 ///////////////////////////////////////////////////////////////////////////////152 153 template <typename T>154 class Nullable155 {156 public:157 158 Nullable() : mIsNull (true) {}159 Nullable (const T &aValue, bool aIsNull = false)160 : mIsNull (aIsNull), mValue (aValue) {}161 162 bool isNull() const { return mIsNull; };163 void setNull (bool aIsNull = true) { mIsNull = aIsNull; }164 165 operator const T&() const { return mValue; }166 167 Nullable &operator= (const T &aValue)168 {169 mValue = aValue;170 mIsNull = false;171 return *this;172 }173 174 private:175 176 bool mIsNull;177 T mValue;178 };179 180 /** helper structure to encapsulate USB filter manipulation commands */181 struct USBFilterCmd182 {183 struct USBFilter184 {185 USBFilter ()186 : mAction (USBDeviceFilterAction_Null)187 {}188 189 Bstr mName;190 Nullable <bool> mActive;191 Bstr mVendorId;192 Bstr mProductId;193 Bstr mRevision;194 Bstr mManufacturer;195 Bstr mProduct;196 Bstr mRemote;197 Bstr mSerialNumber;198 Nullable <ULONG> mMaskedInterfaces;199 USBDeviceFilterAction_T mAction;200 };201 202 enum Action { Invalid, Add, Modify, Remove };203 204 USBFilterCmd() : mAction (Invalid), mIndex (0), mGlobal (false) {}205 206 Action mAction;207 uint32_t mIndex;208 /** flag whether the command target is a global filter */209 bool mGlobal;210 /** machine this command is targeted at (null for global filters) */211 ComPtr<IMachine> mMachine;212 USBFilter mFilter;213 };214 #endif /* !VBOX_ONLY_DOCS */215 42 216 43 // funcs 217 44 /////////////////////////////////////////////////////////////////////////////// 218 219 static void showLogo(void)220 {221 static bool fShown; /* show only once */222 223 if (!fShown)224 {225 RTPrintf("VirtualBox Command Line Management Interface Version "226 VBOX_VERSION_STRING "\n"227 "(C) 2005-2008 Sun Microsystems, Inc.\n"228 "All rights reserved.\n"229 "\n");230 fShown = true;231 }232 }233 234 static void printUsage(USAGECATEGORY u64Cmd)235 {236 #ifdef RT_OS_LINUX237 bool fLinux = true;238 #else239 bool fLinux = false;240 #endif241 #ifdef RT_OS_WINDOWS242 bool fWin = true;243 #else244 bool fWin = false;245 #endif246 #ifdef RT_OS_SOLARIS247 bool fSolaris = true;248 #else249 bool fSolaris = false;250 #endif251 #ifdef RT_OS_DARWIN252 bool fDarwin = true;253 #else254 bool fDarwin = false;255 #endif256 #ifdef VBOX_WITH_VRDP257 bool fVRDP = true;258 #else259 bool fVRDP = false;260 #endif261 262 if (u64Cmd == USAGE_DUMPOPTS)263 {264 fLinux = true;265 fWin = true;266 fSolaris = true;267 fDarwin = true;268 fVRDP = true;269 u64Cmd = USAGE_ALL;270 }271 272 RTPrintf("Usage:\n"273 "\n");274 275 if (u64Cmd == USAGE_ALL)276 {277 RTPrintf("VBoxManage [-v|-version] print version number and exit\n"278 "VBoxManage -nologo ... suppress the logo\n"279 "\n"280 "VBoxManage -convertSettings ... allow to auto-convert settings files\n"281 "VBoxManage -convertSettingsBackup ... allow to auto-convert settings files\n"282 " but create backup copies before\n"283 "VBoxManage -convertSettingsIgnore ... allow to auto-convert settings files\n"284 " but don't explicitly save the results\n"285 "\n");286 }287 288 if (u64Cmd & USAGE_LIST)289 {290 RTPrintf("VBoxManage list vms|runningvms|ostypes|hostdvds|hostfloppies|\n"291 " hostifs|hostinfo|hddbackends|hdds|dvds|floppies|\n"292 " usbhost|usbfilters|systemproperties\n"293 "\n");294 }295 296 if (u64Cmd & USAGE_SHOWVMINFO)297 {298 RTPrintf("VBoxManage showvminfo <uuid>|<name>\n"299 " [-details]\n"300 " [-statistics]\n"301 " [-machinereadable]\n"302 "\n");303 }304 305 if (u64Cmd & USAGE_REGISTERVM)306 {307 RTPrintf("VBoxManage registervm <filename>\n"308 "\n");309 }310 311 if (u64Cmd & USAGE_UNREGISTERVM)312 {313 RTPrintf("VBoxManage unregistervm <uuid>|<name>\n"314 " [-delete]\n"315 "\n");316 }317 318 if (u64Cmd & USAGE_CREATEVM)319 {320 RTPrintf("VBoxManage createvm -name <name>\n"321 " [-ostype <ostype>]\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 in MB>]\n"335 " [-vram <vramsize in MB>]\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_AHCI355 " [-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 #endif360 " [-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_E1000367 "|82540EM|82543GC"368 #endif369 "]\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_BALLOONING384 " [-guestmemoryballoon <balloonsize in MB>]\n"385 #endif386 " [-gueststatisticsinterval <seconds>]\n"387 );388 RTPrintf(" [-audio none|null");389 if (fWin)390 {391 #ifdef VBOX_WITH_WINMM392 RTPrintf( "|winmm|dsound");393 #else394 RTPrintf( "|dsound");395 #endif396 }397 if (fSolaris)398 {399 RTPrintf( "|solaudio");400 }401 if (fLinux)402 {403 RTPrintf( "|oss"404 #ifdef VBOX_WITH_ALSA405 "|alsa"406 #endif407 #ifdef VBOX_WITH_PULSE408 "|pulse"409 #endif410 );411 }412 if (fDarwin)413 {414 RTPrintf( "|coreaudio");415 }416 RTPrintf( "]\n");417 RTPrintf(" [-audiocontroller ac97|sb16]\n"418 " [-clipboard disabled|hosttoguest|guesttohost|\n"419 " bidirectional]\n");420 if (fVRDP)421 {422 RTPrintf(" [-vrdp on|off]\n"423 " [-vrdpport default|<port>]\n"424 " [-vrdpaddress <host>]\n"425 " [-vrdpauthtype null|external|guest]\n"426 " [-vrdpmulticon on|off]\n"427 " [-vrdpreusecon on|off]\n");428 }429 RTPrintf(" [-usb on|off]\n"430 " [-usbehci on|off]\n"431 " [-snapshotfolder default|<path>]\n");432 RTPrintf("\n");433 }434 435 if (u64Cmd & USAGE_STARTVM)436 {437 RTPrintf("VBoxManage startvm <uuid>|<name>\n");438 if (fVRDP)439 RTPrintf(" [-type gui|vrdp]\n");440 RTPrintf("\n");441 }442 443 if (u64Cmd & USAGE_CONTROLVM)444 {445 RTPrintf("VBoxManage controlvm <uuid>|<name>\n"446 " pause|resume|reset|poweroff|savestate|\n"447 " acpipowerbutton|acpisleepbutton|\n"448 " keyboardputscancode <hex> [<hex> ...]|\n"449 " injectnmi|\n"450 " setlinkstate<1-4> on|off |\n"451 " usbattach <uuid>|<address> |\n"452 " usbdetach <uuid>|<address> |\n"453 " dvdattach none|<uuid>|<filename>|host:<drive> |\n"454 " floppyattach none|<uuid>|<filename>|host:<drive> |\n");455 if (fVRDP)456 {457 RTPrintf(" vrdp on|off] |\n");458 }459 RTPrintf(" setvideomodehint <xres> <yres> <bpp> [display]|\n"460 " setcredentials <username> <password> <domain>\n"461 " [-allowlocallogon <yes|no>]\n"462 "\n");463 }464 465 if (u64Cmd & USAGE_DISCARDSTATE)466 {467 RTPrintf("VBoxManage discardstate <uuid>|<name>\n"468 "\n");469 }470 471 if (u64Cmd & USAGE_ADOPTSTATE)472 {473 RTPrintf("VBoxManage adoptstate <uuid>|<name> <state_file>\n"474 "\n");475 }476 477 if (u64Cmd & USAGE_SNAPSHOT)478 {479 RTPrintf("VBoxManage snapshot <uuid>|<name>\n"480 " take <name> [-desc <desc>] |\n"481 " discard <uuid>|<name> |\n"482 " discardcurrent -state|-all |\n"483 " edit <uuid>|<name>|-current\n"484 " [-newname <name>]\n"485 " [-newdesc <desc>] |\n"486 " showvminfo <uuid>|<name>\n"487 "\n");488 }489 490 if (u64Cmd & USAGE_REGISTERIMAGE)491 {492 RTPrintf("VBoxManage openmedium disk|dvd|floppy <filename>\n"493 " [-type normal|immutable|writethrough] (disk only)\n"494 "\n");495 }496 497 if (u64Cmd & USAGE_UNREGISTERIMAGE)498 {499 RTPrintf("VBoxManage closemedium disk|dvd|floppy <uuid>|<filename>\n"500 "\n");501 }502 503 if (u64Cmd & USAGE_SHOWHDINFO)504 {505 RTPrintf("VBoxManage showhdinfo <uuid>|<filename>\n"506 "\n");507 }508 509 if (u64Cmd & USAGE_CREATEHD)510 {511 /// @todo NEWMEDIA add -format to specify the hard disk backend512 RTPrintf("VBoxManage createhd -filename <filename>\n"513 " -size <megabytes>\n"514 " [-format VDI|VMDK|VHD]\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_CONVERTHD)537 {538 RTPrintf("VBoxManage converthd [-srcformat VDI|VMDK|VHD|RAW]\n"539 " [-dstformat VDI|VMDK|VHD|RAW]\n"540 " <inputfile> <outputfile>\n"541 "\n");542 }543 544 if (u64Cmd & USAGE_CONVERTDD)545 {546 RTPrintf("VBoxManage convertdd [-static] [-format VDI|VMDK|VHD]"547 " <filename> <outputfile>\n"548 "VBoxManage convertdd [-static] [-format VDI|VMDK|VHD]"549 " stdin <outputfile> <bytes>\n"550 "\n");551 }552 553 if (u64Cmd & USAGE_ADDISCSIDISK)554 {555 RTPrintf("VBoxManage addiscsidisk -server <name>|<ip>\n"556 " -target <target>\n"557 " [-port <port>]\n"558 " [-lun <lun>]\n"559 " [-encodedlun <lun>]\n"560 " [-username <username>]\n"561 " [-password <password>]\n"562 " [-comment <comment>]\n"563 " [-intnet]\n"564 "\n");565 }566 567 if (u64Cmd & USAGE_CREATEHOSTIF && fWin)568 {569 RTPrintf("VBoxManage createhostif <name>\n"570 "\n");571 }572 573 if (u64Cmd & USAGE_REMOVEHOSTIF && fWin)574 {575 RTPrintf("VBoxManage removehostif <uuid>|<name>\n"576 "\n");577 }578 579 if (u64Cmd & USAGE_GETEXTRADATA)580 {581 RTPrintf("VBoxManage getextradata global|<uuid>|<name>\n"582 " <key>|enumerate\n"583 "\n");584 }585 586 if (u64Cmd & USAGE_SETEXTRADATA)587 {588 RTPrintf("VBoxManage setextradata global|<uuid>|<name>\n"589 " <key>\n"590 " [<value>] (no value deletes key)\n"591 "\n");592 }593 594 if (u64Cmd & USAGE_SETPROPERTY)595 {596 RTPrintf("VBoxManage setproperty hdfolder default|<folder> |\n"597 " machinefolder default|<folder> |\n"598 " vrdpauthlibrary default|<library> |\n"599 " websrvauthlibrary default|null|<library> |\n"600 " hwvirtexenabled yes|no\n"601 " loghistorycount <value>\n"602 "\n");603 }604 605 if (u64Cmd & USAGE_USBFILTER_ADD)606 {607 RTPrintf("VBoxManage usbfilter add <index,0-N>\n"608 " -target <uuid>|<name>|global\n"609 " -name <string>\n"610 " -action ignore|hold (global filters only)\n"611 " [-active yes|no] (yes)\n"612 " [-vendorid <XXXX>] (null)\n"613 " [-productid <XXXX>] (null)\n"614 " [-revision <IIFF>] (null)\n"615 " [-manufacturer <string>] (null)\n"616 " [-product <string>] (null)\n"617 " [-remote yes|no] (null, VM filters only)\n"618 " [-serialnumber <string>] (null)\n"619 " [-maskedinterfaces <XXXXXXXX>]\n"620 "\n");621 }622 623 if (u64Cmd & USAGE_USBFILTER_MODIFY)624 {625 RTPrintf("VBoxManage usbfilter modify <index,0-N>\n"626 " -target <uuid>|<name>|global\n"627 " [-name <string>]\n"628 " [-action ignore|hold] (global filters only)\n"629 " [-active yes|no]\n"630 " [-vendorid <XXXX>|\"\"]\n"631 " [-productid <XXXX>|\"\"]\n"632 " [-revision <IIFF>|\"\"]\n"633 " [-manufacturer <string>|\"\"]\n"634 " [-product <string>|\"\"]\n"635 " [-remote yes|no] (null, VM filters only)\n"636 " [-serialnumber <string>|\"\"]\n"637 " [-maskedinterfaces <XXXXXXXX>]\n"638 "\n");639 }640 641 if (u64Cmd & USAGE_USBFILTER_REMOVE)642 {643 RTPrintf("VBoxManage usbfilter remove <index,0-N>\n"644 " -target <uuid>|<name>|global\n"645 "\n");646 }647 648 if (u64Cmd & USAGE_SHAREDFOLDER_ADD)649 {650 RTPrintf("VBoxManage sharedfolder add <vmname>|<uuid>\n"651 " -name <name> -hostpath <hostpath>\n"652 " [-transient] [-readonly]\n"653 "\n");654 }655 656 if (u64Cmd & USAGE_SHAREDFOLDER_REMOVE)657 {658 RTPrintf("VBoxManage sharedfolder remove <vmname>|<uuid>\n"659 " -name <name> [-transient]\n"660 "\n");661 }662 663 if (u64Cmd & USAGE_VM_STATISTICS)664 {665 RTPrintf("VBoxManage vmstatistics <vmname>|<uuid> [-reset]\n"666 " [-pattern <pattern>] [-descriptions]\n"667 "\n");668 }669 670 #ifdef VBOX_WITH_GUEST_PROPS671 if (u64Cmd & USAGE_GUESTPROPERTY)672 usageGuestProperty();673 #endif /* VBOX_WITH_GUEST_PROPS defined */674 675 if (u64Cmd & USAGE_METRICS)676 {677 RTPrintf("VBoxManage metrics list [*|host|<vmname> [<metric_list>]] (comma-separated)\n\n"678 "VBoxManage metrics setup\n"679 " [-period <seconds>]\n"680 " [-samples <count>]\n"681 " [-list]\n"682 " [*|host|<vmname> [<metric_list>]]\n\n"683 "VBoxManage metrics query [*|host|<vmname> [<metric_list>]]\n\n"684 "VBoxManage metrics collect\n"685 " [-period <seconds>]\n"686 " [-samples <count>]\n"687 " [-list]\n"688 " [-detach]\n"689 " [*|host|<vmname> [<metric_list>]]\n"690 "\n");691 }692 693 }694 695 /**696 * Print a usage synopsis and the syntax error message.697 */698 int errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...)699 {700 va_list args;701 showLogo(); // show logo even if suppressed702 #ifndef VBOX_ONLY_DOCS703 if (g_fInternalMode)704 printUsageInternal(u64Cmd);705 else706 printUsage(u64Cmd);707 #endif /* !VBOX_ONLY_DOCS */708 va_start(args, pszFormat);709 RTPrintf("\n"710 "Syntax error: %N\n", pszFormat, &args);711 va_end(args);712 return 1;713 }714 715 /**716 * Print an error message without the syntax stuff.717 */718 int errorArgument(const char *pszFormat, ...)719 {720 va_list args;721 va_start(args, pszFormat);722 RTPrintf("error: %N\n", pszFormat, &args);723 va_end(args);724 return 1;725 }726 727 #ifndef VBOX_ONLY_DOCS728 /**729 * Print out progress on the console730 */731 static void showProgress(ComPtr<IProgress> progress)732 {733 BOOL fCompleted;734 LONG currentPercent;735 LONG lastPercent = 0;736 737 RTPrintf("0%%...");738 RTStrmFlush(g_pStdOut);739 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))740 {741 progress->COMGETTER(Percent(¤tPercent));742 743 /* did we cross a 10% mark? */744 if (((currentPercent / 10) > (lastPercent / 10)))745 {746 /* make sure to also print out missed steps */747 for (LONG curVal = (lastPercent / 10) * 10 + 10; curVal <= (currentPercent / 10) * 10; curVal += 10)748 {749 if (curVal < 100)750 {751 RTPrintf("%ld%%...", curVal);752 RTStrmFlush(g_pStdOut);753 }754 }755 lastPercent = (currentPercent / 10) * 10;756 }757 if (fCompleted)758 break;759 760 /* make sure the loop is not too tight */761 progress->WaitForCompletion(100);762 }763 764 /* complete the line. */765 HRESULT rc;766 if (SUCCEEDED(progress->COMGETTER(ResultCode)(&rc)))767 {768 if (SUCCEEDED(rc))769 RTPrintf("100%%\n");770 else771 RTPrintf("FAILED\n");772 }773 else774 RTPrintf("\n");775 RTStrmFlush(g_pStdOut);776 }777 778 static int handleRegisterVM(int argc, char *argv[],779 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)780 {781 HRESULT rc;782 783 if (argc != 1)784 return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");785 786 ComPtr<IMachine> machine;787 CHECK_ERROR(virtualBox, OpenMachine(Bstr(argv[0]), machine.asOutParam()));788 if (SUCCEEDED(rc))789 {790 ASSERT(machine);791 CHECK_ERROR(virtualBox, RegisterMachine(machine));792 }793 return SUCCEEDED(rc) ? 0 : 1;794 }795 796 static int handleUnregisterVM(int argc, char *argv[],797 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)798 {799 HRESULT rc;800 801 if ((argc != 1) && (argc != 2))802 return errorSyntax(USAGE_UNREGISTERVM, "Incorrect number of parameters");803 804 ComPtr<IMachine> machine;805 /* assume it's a UUID */806 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());807 if (FAILED(rc) || !machine)808 {809 /* must be a name */810 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));811 }812 if (machine)813 {814 Guid uuid;815 machine->COMGETTER(Id)(uuid.asOutParam());816 machine = NULL;817 CHECK_ERROR(virtualBox, UnregisterMachine(uuid, machine.asOutParam()));818 if (SUCCEEDED(rc) && machine)819 {820 /* are we supposed to delete the config file? */821 if ((argc == 2) && (strcmp(argv[1], "-delete") == 0))822 {823 CHECK_ERROR(machine, DeleteSettings());824 }825 }826 }827 return SUCCEEDED(rc) ? 0 : 1;828 }829 45 830 46 … … 838 54 839 55 840 staticint handleCreateHardDisk(int argc, char *argv[],841 56 int handleCreateHardDisk(int argc, char *argv[], 57 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 842 58 { 843 59 HRESULT rc; … … 988 204 989 205 990 staticint handleModifyHardDisk(int argc, char *argv[],991 206 int handleModifyHardDisk(int argc, char *argv[], 207 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 992 208 { 993 209 HRESULT rc; … … 1092 308 } 1093 309 1094 staticint handleCloneHardDisk(int argc, char *argv[],1095 310 int handleCloneHardDisk(int argc, char *argv[], 311 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 1096 312 { 1097 313 #if 1 … … 1141 357 } 1142 358 1143 staticint handleConvertHardDisk(int argc, char **argv)359 int handleConvertHardDisk(int argc, char **argv) 1144 360 { 1145 361 Bstr srcformat; … … 1267 483 1268 484 1269 staticint handleConvertDDImage(int argc, char *argv[])485 int handleConvertDDImage(int argc, char *argv[]) 1270 486 { 1271 487 VDIMAGETYPE enmImgType = VD_IMAGE_TYPE_NORMAL; … … 1428 644 } 1429 645 1430 staticint handleAddiSCSIDisk(int argc, char *argv[],1431 646 int handleAddiSCSIDisk(int argc, char *argv[], 647 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession) 1432 648 { 1433 649 HRESULT rc; … … 1582 798 } 1583 799 1584 static int handleCreateVM(int argc, char *argv[], 1585 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 1586 { 1587 HRESULT rc; 1588 Bstr baseFolder; 1589 Bstr settingsFile; 1590 Bstr name; 1591 Bstr osTypeId; 1592 RTUUID id; 1593 bool fRegister = false; 1594 1595 RTUuidClear(&id); 1596 for (int i = 0; i < argc; i++) 1597 { 1598 if (strcmp(argv[i], "-basefolder") == 0) 1599 { 1600 if (argc <= i + 1) 1601 return errorArgument("Missing argument to '%s'", argv[i]); 1602 i++; 1603 baseFolder = argv[i]; 1604 } 1605 else if (strcmp(argv[i], "-settingsfile") == 0) 1606 { 1607 if (argc <= i + 1) 1608 return errorArgument("Missing argument to '%s'", argv[i]); 1609 i++; 1610 settingsFile = argv[i]; 1611 } 1612 else if (strcmp(argv[i], "-name") == 0) 1613 { 1614 if (argc <= i + 1) 1615 return errorArgument("Missing argument to '%s'", argv[i]); 1616 i++; 1617 name = argv[i]; 1618 } 1619 else if (strcmp(argv[i], "-ostype") == 0) 1620 { 1621 if (argc <= i + 1) 1622 return errorArgument("Missing argument to '%s'", argv[i]); 1623 i++; 1624 osTypeId = argv[i]; 1625 } 1626 else if (strcmp(argv[i], "-uuid") == 0) 1627 { 1628 if (argc <= i + 1) 1629 return errorArgument("Missing argument to '%s'", argv[i]); 1630 i++; 1631 if (RT_FAILURE(RTUuidFromStr(&id, argv[i]))) 1632 return errorArgument("Invalid UUID format %s\n", argv[i]); 1633 } 1634 else if (strcmp(argv[i], "-register") == 0) 1635 { 1636 fRegister = true; 1637 } 1638 else 1639 return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw()); 1640 } 1641 if (!name) 1642 return errorSyntax(USAGE_CREATEVM, "Parameter -name is required"); 1643 1644 if (!!baseFolder && !!settingsFile) 1645 return errorSyntax(USAGE_CREATEVM, "Either -basefolder or -settingsfile must be specified"); 1646 1647 do 1648 { 1649 ComPtr<IMachine> machine; 1650 1651 if (!settingsFile) 1652 CHECK_ERROR_BREAK(virtualBox, 1653 CreateMachine(name, osTypeId, baseFolder, Guid(id), machine.asOutParam())); 1654 else 1655 CHECK_ERROR_BREAK(virtualBox, 1656 CreateLegacyMachine(name, osTypeId, settingsFile, Guid(id), machine.asOutParam())); 1657 1658 CHECK_ERROR_BREAK(machine, SaveSettings()); 1659 if (fRegister) 1660 { 1661 CHECK_ERROR_BREAK(virtualBox, RegisterMachine(machine)); 1662 } 1663 Guid uuid; 1664 CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam())); 1665 CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam())); 1666 RTPrintf("Virtual machine '%ls' is created%s.\n" 1667 "UUID: %s\n" 1668 "Settings file: '%ls'\n", 1669 name.raw(), fRegister ? " and registered" : "", 1670 uuid.toString().raw(), settingsFile.raw()); 1671 } 1672 while (0); 1673 1674 return SUCCEEDED(rc) ? 0 : 1; 1675 } 1676 1677 /** 1678 * Parses a number. 1679 * 1680 * @returns Valid number on success. 1681 * @returns 0 if invalid number. All necesary bitching has been done. 1682 * @param psz Pointer to the nic number. 1683 */ 1684 static unsigned parseNum(const char *psz, unsigned cMaxNum, const char *name) 1685 { 1686 uint32_t u32; 1687 char *pszNext; 1688 int rc = RTStrToUInt32Ex(psz, &pszNext, 10, &u32); 1689 if ( RT_SUCCESS(rc) 1690 && *pszNext == '\0' 1691 && u32 >= 1 1692 && u32 <= cMaxNum) 1693 return (unsigned)u32; 1694 errorArgument("Invalid %s number '%s'", name, psz); 1695 return 0; 1696 } 1697 1698 /** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */ 1699 #if defined(_MSC_VER) 1700 # pragma optimize("g", off) 1701 #endif 1702 1703 static int handleModifyVM(int argc, char *argv[], 1704 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 1705 { 1706 HRESULT rc; 1707 Bstr name; 1708 Bstr ostype; 1709 uint32_t memorySize = 0; 1710 uint32_t vramSize = 0; 1711 char *acpi = NULL; 1712 char *hwvirtex = NULL; 1713 char *nestedpaging = NULL; 1714 char *vtxvpid = NULL; 1715 char *pae = NULL; 1716 char *ioapic = NULL; 1717 uint32_t monitorcount = ~0; 1718 char *accelerate3d = NULL; 1719 char *bioslogofadein = NULL; 1720 char *bioslogofadeout = NULL; 1721 uint32_t bioslogodisplaytime = ~0; 1722 char *bioslogoimagepath = NULL; 1723 char *biosbootmenumode = NULL; 1724 char *biossystemtimeoffset = NULL; 1725 char *biospxedebug = NULL; 1726 DeviceType_T bootDevice[4]; 1727 int bootDeviceChanged[4] = { false }; 1728 char *hdds[34] = {0}; 1729 char *dvd = NULL; 1730 char *dvdpassthrough = NULL; 1731 char *idecontroller = NULL; 1732 char *floppy = NULL; 1733 char *audio = NULL; 1734 char *audiocontroller = NULL; 1735 char *clipboard = NULL; 1736 #ifdef VBOX_WITH_VRDP 1737 char *vrdp = NULL; 1738 uint16_t vrdpport = UINT16_MAX; 1739 char *vrdpaddress = NULL; 1740 char *vrdpauthtype = NULL; 1741 char *vrdpmulticon = NULL; 1742 char *vrdpreusecon = NULL; 1743 #endif 1744 int fUsbEnabled = -1; 1745 int fUsbEhciEnabled = -1; 1746 char *snapshotFolder = NULL; 1747 ULONG guestMemBalloonSize = (ULONG)-1; 1748 ULONG guestStatInterval = (ULONG)-1; 1749 int fSataEnabled = -1; 1750 int sataPortCount = -1; 1751 int sataBootDevices[4] = {-1,-1,-1,-1}; 1752 1753 /* VM ID + at least one parameter. Parameter arguments are checked 1754 * individually. */ 1755 if (argc < 2) 1756 return errorSyntax(USAGE_MODIFYVM, "Not enough parameters"); 1757 1758 /* Get the number of network adapters */ 1759 ULONG NetworkAdapterCount = 0; 1760 { 1761 ComPtr <ISystemProperties> info; 1762 CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1); 1763 CHECK_ERROR_RET (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount), 1); 1764 } 1765 ULONG SerialPortCount = 0; 1766 { 1767 ComPtr <ISystemProperties> info; 1768 CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1); 1769 CHECK_ERROR_RET (info, COMGETTER(SerialPortCount) (&SerialPortCount), 1); 1770 } 1771 1772 std::vector <char *> nics (NetworkAdapterCount, 0); 1773 std::vector <char *> nictype (NetworkAdapterCount, 0); 1774 std::vector <char *> cableconnected (NetworkAdapterCount, 0); 1775 std::vector <char *> nictrace (NetworkAdapterCount, 0); 1776 std::vector <char *> nictracefile (NetworkAdapterCount, 0); 1777 std::vector <char *> nicspeed (NetworkAdapterCount, 0); 1778 std::vector <char *> hostifdev (NetworkAdapterCount, 0); 1779 std::vector <const char *> intnet (NetworkAdapterCount, 0); 1780 std::vector <const char *> natnet (NetworkAdapterCount, 0); 1781 std::vector <char *> macs (NetworkAdapterCount, 0); 1782 std::vector <char *> uarts_mode (SerialPortCount, 0); 1783 std::vector <ULONG> uarts_base (SerialPortCount, 0); 1784 std::vector <ULONG> uarts_irq (SerialPortCount, 0); 1785 std::vector <char *> uarts_path (SerialPortCount, 0); 1786 1787 for (int i = 1; i < argc; i++) 1788 { 1789 if (strcmp(argv[i], "-name") == 0) 1790 { 1791 if (argc <= i + 1) 1792 return errorArgument("Missing argument to '%s'", argv[i]); 1793 i++; 1794 name = argv[i]; 1795 } 1796 else if (strcmp(argv[i], "-ostype") == 0) 1797 { 1798 if (argc <= i + 1) 1799 return errorArgument("Missing argument to '%s'", argv[i]); 1800 i++; 1801 ostype = argv[i]; 1802 } 1803 else if (strcmp(argv[i], "-memory") == 0) 1804 { 1805 if (argc <= i + 1) 1806 return errorArgument("Missing argument to '%s'", argv[i]); 1807 i++; 1808 memorySize = RTStrToUInt32(argv[i]); 1809 } 1810 else if (strcmp(argv[i], "-vram") == 0) 1811 { 1812 if (argc <= i + 1) 1813 return errorArgument("Missing argument to '%s'", argv[i]); 1814 i++; 1815 vramSize = RTStrToUInt32(argv[i]); 1816 } 1817 else if (strcmp(argv[i], "-acpi") == 0) 1818 { 1819 if (argc <= i + 1) 1820 return errorArgument("Missing argument to '%s'", argv[i]); 1821 i++; 1822 acpi = argv[i]; 1823 } 1824 else if (strcmp(argv[i], "-ioapic") == 0) 1825 { 1826 if (argc <= i + 1) 1827 return errorArgument("Missing argument to '%s'", argv[i]); 1828 i++; 1829 ioapic = argv[i]; 1830 } 1831 else if (strcmp(argv[i], "-hwvirtex") == 0) 1832 { 1833 if (argc <= i + 1) 1834 return errorArgument("Missing argument to '%s'", argv[i]); 1835 i++; 1836 hwvirtex = argv[i]; 1837 } 1838 else if (strcmp(argv[i], "-nestedpaging") == 0) 1839 { 1840 if (argc <= i + 1) 1841 return errorArgument("Missing argument to '%s'", argv[i]); 1842 i++; 1843 nestedpaging = argv[i]; 1844 } 1845 else if (strcmp(argv[i], "-vtxvpid") == 0) 1846 { 1847 if (argc <= i + 1) 1848 return errorArgument("Missing argument to '%s'", argv[i]); 1849 i++; 1850 vtxvpid = argv[i]; 1851 } 1852 else if (strcmp(argv[i], "-pae") == 0) 1853 { 1854 if (argc <= i + 1) 1855 return errorArgument("Missing argument to '%s'", argv[i]); 1856 i++; 1857 pae = argv[i]; 1858 } 1859 else if (strcmp(argv[i], "-monitorcount") == 0) 1860 { 1861 if (argc <= i + 1) 1862 return errorArgument("Missing argument to '%s'", argv[i]); 1863 i++; 1864 monitorcount = RTStrToUInt32(argv[i]); 1865 } 1866 else if (strcmp(argv[i], "-accelerate3d") == 0) 1867 { 1868 if (argc <= i + 1) 1869 return errorArgument("Missing argument to '%s'", argv[i]); 1870 i++; 1871 accelerate3d = argv[i]; 1872 } 1873 else if (strcmp(argv[i], "-bioslogofadein") == 0) 1874 { 1875 if (argc <= i + 1) 1876 return errorArgument("Missing argument to '%s'", argv[i]); 1877 i++; 1878 bioslogofadein = argv[i]; 1879 } 1880 else if (strcmp(argv[i], "-bioslogofadeout") == 0) 1881 { 1882 if (argc <= i + 1) 1883 return errorArgument("Missing argument to '%s'", argv[i]); 1884 i++; 1885 bioslogofadeout = argv[i]; 1886 } 1887 else if (strcmp(argv[i], "-bioslogodisplaytime") == 0) 1888 { 1889 if (argc <= i + 1) 1890 return errorArgument("Missing argument to '%s'", argv[i]); 1891 i++; 1892 bioslogodisplaytime = RTStrToUInt32(argv[i]); 1893 } 1894 else if (strcmp(argv[i], "-bioslogoimagepath") == 0) 1895 { 1896 if (argc <= i + 1) 1897 return errorArgument("Missing argument to '%s'", argv[i]); 1898 i++; 1899 bioslogoimagepath = argv[i]; 1900 } 1901 else if (strcmp(argv[i], "-biosbootmenu") == 0) 1902 { 1903 if (argc <= i + 1) 1904 return errorArgument("Missing argument to '%s'", argv[i]); 1905 i++; 1906 biosbootmenumode = argv[i]; 1907 } 1908 else if (strcmp(argv[i], "-biossystemtimeoffset") == 0) 1909 { 1910 if (argc <= i + 1) 1911 return errorArgument("Missing argument to '%s'", argv[i]); 1912 i++; 1913 biossystemtimeoffset = argv[i]; 1914 } 1915 else if (strcmp(argv[i], "-biospxedebug") == 0) 1916 { 1917 if (argc <= i + 1) 1918 return errorArgument("Missing argument to '%s'", argv[i]); 1919 i++; 1920 biospxedebug = argv[i]; 1921 } 1922 else if (strncmp(argv[i], "-boot", 5) == 0) 1923 { 1924 uint32_t n = 0; 1925 if (!argv[i][5]) 1926 return errorSyntax(USAGE_MODIFYVM, "Missing boot slot number in '%s'", argv[i]); 1927 if (VINF_SUCCESS != RTStrToUInt32Full(&argv[i][5], 10, &n)) 1928 return errorSyntax(USAGE_MODIFYVM, "Invalid boot slot number in '%s'", argv[i]); 1929 if (argc <= i + 1) 1930 return errorArgument("Missing argument to '%s'", argv[i]); 1931 i++; 1932 if (strcmp(argv[i], "none") == 0) 1933 { 1934 bootDevice[n - 1] = DeviceType_Null; 1935 } 1936 else if (strcmp(argv[i], "floppy") == 0) 1937 { 1938 bootDevice[n - 1] = DeviceType_Floppy; 1939 } 1940 else if (strcmp(argv[i], "dvd") == 0) 1941 { 1942 bootDevice[n - 1] = DeviceType_DVD; 1943 } 1944 else if (strcmp(argv[i], "disk") == 0) 1945 { 1946 bootDevice[n - 1] = DeviceType_HardDisk; 1947 } 1948 else if (strcmp(argv[i], "net") == 0) 1949 { 1950 bootDevice[n - 1] = DeviceType_Network; 1951 } 1952 else 1953 return errorArgument("Invalid boot device '%s'", argv[i]); 1954 1955 bootDeviceChanged[n - 1] = true; 1956 } 1957 else if (strcmp(argv[i], "-hda") == 0) 1958 { 1959 if (argc <= i + 1) 1960 return errorArgument("Missing argument to '%s'", argv[i]); 1961 i++; 1962 hdds[0] = argv[i]; 1963 } 1964 else if (strcmp(argv[i], "-hdb") == 0) 1965 { 1966 if (argc <= i + 1) 1967 return errorArgument("Missing argument to '%s'", argv[i]); 1968 i++; 1969 hdds[1] = argv[i]; 1970 } 1971 else if (strcmp(argv[i], "-hdd") == 0) 1972 { 1973 if (argc <= i + 1) 1974 return errorArgument("Missing argument to '%s'", argv[i]); 1975 i++; 1976 hdds[2] = argv[i]; 1977 } 1978 else if (strcmp(argv[i], "-dvd") == 0) 1979 { 1980 if (argc <= i + 1) 1981 return errorArgument("Missing argument to '%s'", argv[i]); 1982 i++; 1983 dvd = argv[i]; 1984 } 1985 else if (strcmp(argv[i], "-dvdpassthrough") == 0) 1986 { 1987 if (argc <= i + 1) 1988 return errorArgument("Missing argument to '%s'", argv[i]); 1989 i++; 1990 dvdpassthrough = argv[i]; 1991 } 1992 else if (strcmp(argv[i], "-idecontroller") == 0) 1993 { 1994 if (argc <= i + 1) 1995 return errorArgument("Missing argument to '%s'", argv[i]); 1996 i++; 1997 idecontroller = argv[i]; 1998 } 1999 else if (strcmp(argv[i], "-floppy") == 0) 2000 { 2001 if (argc <= i + 1) 2002 return errorArgument("Missing argument to '%s'", argv[i]); 2003 i++; 2004 floppy = argv[i]; 2005 } 2006 else if (strcmp(argv[i], "-audio") == 0) 2007 { 2008 if (argc <= i + 1) 2009 return errorArgument("Missing argument to '%s'", argv[i]); 2010 i++; 2011 audio = argv[i]; 2012 } 2013 else if (strcmp(argv[i], "-audiocontroller") == 0) 2014 { 2015 if (argc <= i + 1) 2016 return errorArgument("Missing argument to '%s'", argv[i]); 2017 i++; 2018 audiocontroller = argv[i]; 2019 } 2020 else if (strcmp(argv[i], "-clipboard") == 0) 2021 { 2022 if (argc <= i + 1) 2023 return errorArgument("Missing argument to '%s'", argv[i]); 2024 i++; 2025 clipboard = argv[i]; 2026 } 2027 else if (strncmp(argv[i], "-cableconnected", 15) == 0) 2028 { 2029 unsigned n = parseNum(&argv[i][15], NetworkAdapterCount, "NIC"); 2030 if (!n) 2031 return 1; 2032 2033 if (argc <= i + 1) 2034 return errorArgument("Missing argument to '%s'", argv[i]); 2035 2036 cableconnected[n - 1] = argv[i + 1]; 2037 i++; 2038 } 2039 /* watch for the right order of these -nic* comparisons! */ 2040 else if (strncmp(argv[i], "-nictracefile", 13) == 0) 2041 { 2042 unsigned n = parseNum(&argv[i][13], NetworkAdapterCount, "NIC"); 2043 if (!n) 2044 return 1; 2045 if (argc <= i + 1) 2046 { 2047 return errorArgument("Missing argument to '%s'", argv[i]); 2048 } 2049 nictracefile[n - 1] = argv[i + 1]; 2050 i++; 2051 } 2052 else if (strncmp(argv[i], "-nictrace", 9) == 0) 2053 { 2054 unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC"); 2055 if (!n) 2056 return 1; 2057 if (argc <= i + 1) 2058 return errorArgument("Missing argument to '%s'", argv[i]); 2059 nictrace[n - 1] = argv[i + 1]; 2060 i++; 2061 } 2062 else if (strncmp(argv[i], "-nictype", 8) == 0) 2063 { 2064 unsigned n = parseNum(&argv[i][8], NetworkAdapterCount, "NIC"); 2065 if (!n) 2066 return 1; 2067 if (argc <= i + 1) 2068 return errorArgument("Missing argument to '%s'", argv[i]); 2069 nictype[n - 1] = argv[i + 1]; 2070 i++; 2071 } 2072 else if (strncmp(argv[i], "-nicspeed", 9) == 0) 2073 { 2074 unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC"); 2075 if (!n) 2076 return 1; 2077 if (argc <= i + 1) 2078 return errorArgument("Missing argument to '%s'", argv[i]); 2079 nicspeed[n - 1] = argv[i + 1]; 2080 i++; 2081 } 2082 else if (strncmp(argv[i], "-nic", 4) == 0) 2083 { 2084 unsigned n = parseNum(&argv[i][4], NetworkAdapterCount, "NIC"); 2085 if (!n) 2086 return 1; 2087 if (argc <= i + 1) 2088 return errorArgument("Missing argument to '%s'", argv[i]); 2089 nics[n - 1] = argv[i + 1]; 2090 i++; 2091 } 2092 else if (strncmp(argv[i], "-hostifdev", 10) == 0) 2093 { 2094 unsigned n = parseNum(&argv[i][10], NetworkAdapterCount, "NIC"); 2095 if (!n) 2096 return 1; 2097 if (argc <= i + 1) 2098 return errorArgument("Missing argument to '%s'", argv[i]); 2099 hostifdev[n - 1] = argv[i + 1]; 2100 i++; 2101 } 2102 else if (strncmp(argv[i], "-intnet", 7) == 0) 2103 { 2104 unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC"); 2105 if (!n) 2106 return 1; 2107 if (argc <= i + 1) 2108 return errorArgument("Missing argument to '%s'", argv[i]); 2109 intnet[n - 1] = argv[i + 1]; 2110 i++; 2111 } 2112 else if (strncmp(argv[i], "-natnet", 7) == 0) 2113 { 2114 unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC"); 2115 if (!n) 2116 return 1; 2117 if (argc <= i + 1) 2118 return errorArgument("Missing argument to '%s'", argv[i]); 2119 2120 if (!strcmp(argv[i + 1], "default")) 2121 natnet[n - 1] = ""; 2122 else 2123 { 2124 RTIPV4ADDR Network; 2125 RTIPV4ADDR Netmask; 2126 int rc = RTCidrStrToIPv4(argv[i + 1], &Network, &Netmask); 2127 if (RT_FAILURE(rc)) 2128 return errorArgument("Invalid IPv4 network '%s' specified -- CIDR notation expected.\n", argv[i + 1]); 2129 if (Netmask & 0x1f) 2130 return errorArgument("Prefix length of the NAT network must be less than 28.\n"); 2131 natnet[n - 1] = argv[i + 1]; 2132 } 2133 i++; 2134 } 2135 else if (strncmp(argv[i], "-macaddress", 11) == 0) 2136 { 2137 unsigned n = parseNum(&argv[i][11], NetworkAdapterCount, "NIC"); 2138 if (!n) 2139 return 1; 2140 if (argc <= i + 1) 2141 return errorArgument("Missing argument to '%s'", argv[i]); 2142 macs[n - 1] = argv[i + 1]; 2143 i++; 2144 } 2145 #ifdef VBOX_WITH_VRDP 2146 else if (strcmp(argv[i], "-vrdp") == 0) 2147 { 2148 if (argc <= i + 1) 2149 return errorArgument("Missing argument to '%s'", argv[i]); 2150 i++; 2151 vrdp = argv[i]; 2152 } 2153 else if (strcmp(argv[i], "-vrdpport") == 0) 2154 { 2155 if (argc <= i + 1) 2156 return errorArgument("Missing argument to '%s'", argv[i]); 2157 i++; 2158 if (strcmp(argv[i], "default") == 0) 2159 vrdpport = 0; 2160 else 2161 vrdpport = RTStrToUInt16(argv[i]); 2162 } 2163 else if (strcmp(argv[i], "-vrdpaddress") == 0) 2164 { 2165 if (argc <= i + 1) 2166 return errorArgument("Missing argument to '%s'", argv[i]); 2167 i++; 2168 vrdpaddress = argv[i]; 2169 } 2170 else if (strcmp(argv[i], "-vrdpauthtype") == 0) 2171 { 2172 if (argc <= i + 1) 2173 return errorArgument("Missing argument to '%s'", argv[i]); 2174 i++; 2175 vrdpauthtype = argv[i]; 2176 } 2177 else if (strcmp(argv[i], "-vrdpmulticon") == 0) 2178 { 2179 if (argc <= i + 1) 2180 return errorArgument("Missing argument to '%s'", argv[i]); 2181 i++; 2182 vrdpmulticon = argv[i]; 2183 } 2184 else if (strcmp(argv[i], "-vrdpreusecon") == 0) 2185 { 2186 if (argc <= i + 1) 2187 return errorArgument("Missing argument to '%s'", argv[i]); 2188 i++; 2189 vrdpreusecon = argv[i]; 2190 } 2191 #endif /* VBOX_WITH_VRDP */ 2192 else if (strcmp(argv[i], "-usb") == 0) 2193 { 2194 if (argc <= i + 1) 2195 return errorArgument("Missing argument to '%s'", argv[i]); 2196 i++; 2197 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0) 2198 fUsbEnabled = 1; 2199 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0) 2200 fUsbEnabled = 0; 2201 else 2202 return errorArgument("Invalid -usb argument '%s'", argv[i]); 2203 } 2204 else if (strcmp(argv[i], "-usbehci") == 0) 2205 { 2206 if (argc <= i + 1) 2207 return errorArgument("Missing argument to '%s'", argv[i]); 2208 i++; 2209 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0) 2210 fUsbEhciEnabled = 1; 2211 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0) 2212 fUsbEhciEnabled = 0; 2213 else 2214 return errorArgument("Invalid -usbehci argument '%s'", argv[i]); 2215 } 2216 else if (strcmp(argv[i], "-snapshotfolder") == 0) 2217 { 2218 if (argc <= i + 1) 2219 return errorArgument("Missing argument to '%s'", argv[i]); 2220 i++; 2221 snapshotFolder = argv[i]; 2222 } 2223 else if (strncmp(argv[i], "-uartmode", 9) == 0) 2224 { 2225 unsigned n = parseNum(&argv[i][9], SerialPortCount, "UART"); 2226 if (!n) 2227 return 1; 2228 i++; 2229 if (strcmp(argv[i], "disconnected") == 0) 2230 { 2231 uarts_mode[n - 1] = argv[i]; 2232 } 2233 else 2234 { 2235 if (strcmp(argv[i], "server") == 0 || strcmp(argv[i], "client") == 0) 2236 { 2237 uarts_mode[n - 1] = argv[i]; 2238 i++; 2239 #ifdef RT_OS_WINDOWS 2240 if (strncmp(argv[i], "\\\\.\\pipe\\", 9)) 2241 return errorArgument("Uart pipe must start with \\\\.\\pipe\\"); 2242 #endif 2243 } 2244 else 2245 { 2246 uarts_mode[n - 1] = (char*)"device"; 2247 } 2248 if (argc <= i) 2249 return errorArgument("Missing argument to -uartmode"); 2250 uarts_path[n - 1] = argv[i]; 2251 } 2252 } 2253 else if (strncmp(argv[i], "-uart", 5) == 0) 2254 { 2255 unsigned n = parseNum(&argv[i][5], SerialPortCount, "UART"); 2256 if (!n) 2257 return 1; 2258 if (argc <= i + 1) 2259 return errorArgument("Missing argument to '%s'", argv[i]); 2260 i++; 2261 if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0) 2262 { 2263 uarts_base[n - 1] = (ULONG)-1; 2264 } 2265 else 2266 { 2267 if (argc <= i + 1) 2268 return errorArgument("Missing argument to '%s'", argv[i-1]); 2269 uint32_t uVal; 2270 int vrc; 2271 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal); 2272 if (vrc != VINF_SUCCESS || uVal == 0) 2273 return errorArgument("Error parsing UART I/O base '%s'", argv[i]); 2274 uarts_base[n - 1] = uVal; 2275 i++; 2276 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal); 2277 if (vrc != VINF_SUCCESS) 2278 return errorArgument("Error parsing UART IRQ '%s'", argv[i]); 2279 uarts_irq[n - 1] = uVal; 2280 } 2281 } 2282 #ifdef VBOX_WITH_MEM_BALLOONING 2283 else if (strncmp(argv[i], "-guestmemoryballoon", 19) == 0) 2284 { 2285 if (argc <= i + 1) 2286 return errorArgument("Missing argument to '%s'", argv[i]); 2287 i++; 2288 uint32_t uVal; 2289 int vrc; 2290 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal); 2291 if (vrc != VINF_SUCCESS) 2292 return errorArgument("Error parsing guest memory balloon size '%s'", argv[i]); 2293 guestMemBalloonSize = uVal; 2294 } 2295 #endif 2296 else if (strncmp(argv[i], "-gueststatisticsinterval", 24) == 0) 2297 { 2298 if (argc <= i + 1) 2299 return errorArgument("Missing argument to '%s'", argv[i]); 2300 i++; 2301 uint32_t uVal; 2302 int vrc; 2303 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal); 2304 if (vrc != VINF_SUCCESS) 2305 return errorArgument("Error parsing guest statistics interval '%s'", argv[i]); 2306 guestStatInterval = uVal; 2307 } 2308 else if (strcmp(argv[i], "-sata") == 0) 2309 { 2310 if (argc <= i + 1) 2311 return errorArgument("Missing argument to '%s'", argv[i]); 2312 i++; 2313 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0) 2314 fSataEnabled = 1; 2315 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0) 2316 fSataEnabled = 0; 2317 else 2318 return errorArgument("Invalid -usb argument '%s'", argv[i]); 2319 } 2320 else if (strcmp(argv[i], "-sataportcount") == 0) 2321 { 2322 unsigned n; 2323 2324 if (argc <= i + 1) 2325 return errorArgument("Missing arguments to '%s'", argv[i]); 2326 i++; 2327 2328 n = parseNum(argv[i], 30, "SATA"); 2329 if (!n) 2330 return 1; 2331 sataPortCount = n; 2332 } 2333 else if (strncmp(argv[i], "-sataport", 9) == 0) 2334 { 2335 unsigned n = parseNum(&argv[i][9], 30, "SATA"); 2336 if (!n) 2337 return 1; 2338 if (argc <= i + 1) 2339 return errorArgument("Missing argument to '%s'", argv[i]); 2340 i++; 2341 hdds[n-1+4] = argv[i]; 2342 } 2343 else if (strncmp(argv[i], "-sataideemulation", 17) == 0) 2344 { 2345 unsigned bootDevicePos = 0; 2346 unsigned n; 2347 2348 bootDevicePos = parseNum(&argv[i][17], 4, "SATA"); 2349 if (!bootDevicePos) 2350 return 1; 2351 bootDevicePos--; 2352 2353 if (argc <= i + 1) 2354 return errorArgument("Missing arguments to '%s'", argv[i]); 2355 i++; 2356 2357 n = parseNum(argv[i], 30, "SATA"); 2358 if (!n) 2359 return 1; 2360 2361 sataBootDevices[bootDevicePos] = n-1; 2362 } 2363 else 2364 return errorSyntax(USAGE_MODIFYVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw()); 2365 } 2366 2367 /* try to find the given machine */ 2368 ComPtr <IMachine> machine; 2369 Guid uuid (argv[0]); 2370 if (!uuid.isEmpty()) 2371 { 2372 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam())); 2373 } 2374 else 2375 { 2376 CHECK_ERROR (virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam())); 2377 if (SUCCEEDED (rc)) 2378 machine->COMGETTER(Id)(uuid.asOutParam()); 2379 } 2380 if (FAILED (rc)) 2381 return 1; 2382 2383 /* open a session for the VM */ 2384 CHECK_ERROR_RET (virtualBox, OpenSession(session, uuid), 1); 2385 2386 do 2387 { 2388 /* get the mutable session machine */ 2389 session->COMGETTER(Machine)(machine.asOutParam()); 2390 2391 ComPtr <IBIOSSettings> biosSettings; 2392 machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); 2393 2394 if (name) 2395 CHECK_ERROR(machine, COMSETTER(Name)(name)); 2396 if (ostype) 2397 { 2398 ComPtr<IGuestOSType> guestOSType; 2399 CHECK_ERROR(virtualBox, GetGuestOSType(ostype, guestOSType.asOutParam())); 2400 if (SUCCEEDED(rc) && guestOSType) 2401 { 2402 CHECK_ERROR(machine, COMSETTER(OSTypeId)(ostype)); 2403 } 2404 else 2405 { 2406 errorArgument("Invalid guest OS type '%s'", Utf8Str(ostype).raw()); 2407 rc = E_FAIL; 2408 break; 2409 } 2410 } 2411 if (memorySize > 0) 2412 CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySize)); 2413 if (vramSize > 0) 2414 CHECK_ERROR(machine, COMSETTER(VRAMSize)(vramSize)); 2415 if (acpi) 2416 { 2417 if (strcmp(acpi, "on") == 0) 2418 { 2419 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(true)); 2420 } 2421 else if (strcmp(acpi, "off") == 0) 2422 { 2423 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(false)); 2424 } 2425 else 2426 { 2427 errorArgument("Invalid -acpi argument '%s'", acpi); 2428 rc = E_FAIL; 2429 break; 2430 } 2431 } 2432 if (ioapic) 2433 { 2434 if (strcmp(ioapic, "on") == 0) 2435 { 2436 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(true)); 2437 } 2438 else if (strcmp(ioapic, "off") == 0) 2439 { 2440 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(false)); 2441 } 2442 else 2443 { 2444 errorArgument("Invalid -ioapic argument '%s'", ioapic); 2445 rc = E_FAIL; 2446 break; 2447 } 2448 } 2449 if (hwvirtex) 2450 { 2451 if (strcmp(hwvirtex, "on") == 0) 2452 { 2453 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_True)); 2454 } 2455 else if (strcmp(hwvirtex, "off") == 0) 2456 { 2457 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_False)); 2458 } 2459 else if (strcmp(hwvirtex, "default") == 0) 2460 { 2461 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_Default)); 2462 } 2463 else 2464 { 2465 errorArgument("Invalid -hwvirtex argument '%s'", hwvirtex); 2466 rc = E_FAIL; 2467 break; 2468 } 2469 } 2470 if (nestedpaging) 2471 { 2472 if (strcmp(nestedpaging, "on") == 0) 2473 { 2474 CHECK_ERROR(machine, COMSETTER(HWVirtExNestedPagingEnabled)(true)); 2475 } 2476 else if (strcmp(nestedpaging, "off") == 0) 2477 { 2478 CHECK_ERROR(machine, COMSETTER(HWVirtExNestedPagingEnabled)(false)); 2479 } 2480 else 2481 { 2482 errorArgument("Invalid -nestedpaging argument '%s'", ioapic); 2483 rc = E_FAIL; 2484 break; 2485 } 2486 } 2487 if (vtxvpid) 2488 { 2489 if (strcmp(vtxvpid, "on") == 0) 2490 { 2491 CHECK_ERROR(machine, COMSETTER(HWVirtExVPIDEnabled)(true)); 2492 } 2493 else if (strcmp(vtxvpid, "off") == 0) 2494 { 2495 CHECK_ERROR(machine, COMSETTER(HWVirtExVPIDEnabled)(false)); 2496 } 2497 else 2498 { 2499 errorArgument("Invalid -vtxvpid argument '%s'", ioapic); 2500 rc = E_FAIL; 2501 break; 2502 } 2503 } 2504 if (pae) 2505 { 2506 if (strcmp(pae, "on") == 0) 2507 { 2508 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(true)); 2509 } 2510 else if (strcmp(pae, "off") == 0) 2511 { 2512 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(false)); 2513 } 2514 else 2515 { 2516 errorArgument("Invalid -pae argument '%s'", ioapic); 2517 rc = E_FAIL; 2518 break; 2519 } 2520 } 2521 if (monitorcount != ~0U) 2522 { 2523 CHECK_ERROR(machine, COMSETTER(MonitorCount)(monitorcount)); 2524 } 2525 if (accelerate3d) 2526 { 2527 if (strcmp(accelerate3d, "on") == 0) 2528 { 2529 CHECK_ERROR(machine, COMSETTER(Accelerate3DEnabled)(true)); 2530 } 2531 else if (strcmp(accelerate3d, "off") == 0) 2532 { 2533 CHECK_ERROR(machine, COMSETTER(Accelerate3DEnabled)(false)); 2534 } 2535 else 2536 { 2537 errorArgument("Invalid -accelerate3d argument '%s'", ioapic); 2538 rc = E_FAIL; 2539 break; 2540 } 2541 } 2542 if (bioslogofadein) 2543 { 2544 if (strcmp(bioslogofadein, "on") == 0) 2545 { 2546 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(true)); 2547 } 2548 else if (strcmp(bioslogofadein, "off") == 0) 2549 { 2550 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(false)); 2551 } 2552 else 2553 { 2554 errorArgument("Invalid -bioslogofadein argument '%s'", bioslogofadein); 2555 rc = E_FAIL; 2556 break; 2557 } 2558 } 2559 if (bioslogofadeout) 2560 { 2561 if (strcmp(bioslogofadeout, "on") == 0) 2562 { 2563 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(true)); 2564 } 2565 else if (strcmp(bioslogofadeout, "off") == 0) 2566 { 2567 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(false)); 2568 } 2569 else 2570 { 2571 errorArgument("Invalid -bioslogofadeout argument '%s'", bioslogofadeout); 2572 rc = E_FAIL; 2573 break; 2574 } 2575 } 2576 if (bioslogodisplaytime != ~0U) 2577 { 2578 CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(bioslogodisplaytime)); 2579 } 2580 if (bioslogoimagepath) 2581 { 2582 CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(bioslogoimagepath))); 2583 } 2584 if (biosbootmenumode) 2585 { 2586 if (strcmp(biosbootmenumode, "disabled") == 0) 2587 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled)); 2588 else if (strcmp(biosbootmenumode, "menuonly") == 0) 2589 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly)); 2590 else if (strcmp(biosbootmenumode, "messageandmenu") == 0) 2591 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu)); 2592 else 2593 { 2594 errorArgument("Invalid -biosbootmenu argument '%s'", biosbootmenumode); 2595 rc = E_FAIL; 2596 break; 2597 } 2598 2599 } 2600 if (biossystemtimeoffset) 2601 { 2602 LONG64 timeOffset = RTStrToInt64(biossystemtimeoffset); 2603 CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(timeOffset)); 2604 } 2605 if (biospxedebug) 2606 { 2607 if (strcmp(biospxedebug, "on") == 0) 2608 { 2609 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(true)); 2610 } 2611 else if (strcmp(biospxedebug, "off") == 0) 2612 { 2613 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(false)); 2614 } 2615 else 2616 { 2617 errorArgument("Invalid -biospxedebug argument '%s'", biospxedebug); 2618 rc = E_FAIL; 2619 break; 2620 } 2621 } 2622 for (int curBootDev = 0; curBootDev < 4; curBootDev++) 2623 { 2624 if (bootDeviceChanged[curBootDev]) 2625 CHECK_ERROR(machine, SetBootOrder (curBootDev + 1, bootDevice[curBootDev])); 2626 } 2627 if (hdds[0]) 2628 { 2629 if (strcmp(hdds[0], "none") == 0) 2630 { 2631 machine->DetachHardDisk2(StorageBus_IDE, 0, 0); 2632 } 2633 else 2634 { 2635 /* first guess is that it's a UUID */ 2636 Guid uuid(hdds[0]); 2637 ComPtr<IHardDisk2> hardDisk; 2638 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam()); 2639 /* not successful? Then it must be a filename */ 2640 if (!hardDisk) 2641 { 2642 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[0]), hardDisk.asOutParam())); 2643 if (FAILED(rc)) 2644 { 2645 /* open the new hard disk object */ 2646 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[0]), hardDisk.asOutParam())); 2647 } 2648 } 2649 if (hardDisk) 2650 { 2651 hardDisk->COMGETTER(Id)(uuid.asOutParam()); 2652 CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 0, 0)); 2653 } 2654 else 2655 rc = E_FAIL; 2656 if (FAILED(rc)) 2657 break; 2658 } 2659 } 2660 if (hdds[1]) 2661 { 2662 if (strcmp(hdds[1], "none") == 0) 2663 { 2664 machine->DetachHardDisk2(StorageBus_IDE, 0, 1); 2665 } 2666 else 2667 { 2668 /* first guess is that it's a UUID */ 2669 Guid uuid(hdds[1]); 2670 ComPtr<IHardDisk2> hardDisk; 2671 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam()); 2672 /* not successful? Then it must be a filename */ 2673 if (!hardDisk) 2674 { 2675 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[1]), hardDisk.asOutParam())); 2676 if (FAILED(rc)) 2677 { 2678 /* open the new hard disk object */ 2679 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[1]), hardDisk.asOutParam())); 2680 } 2681 } 2682 if (hardDisk) 2683 { 2684 hardDisk->COMGETTER(Id)(uuid.asOutParam()); 2685 CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 0, 1)); 2686 } 2687 else 2688 rc = E_FAIL; 2689 if (FAILED(rc)) 2690 break; 2691 } 2692 } 2693 if (hdds[2]) 2694 { 2695 if (strcmp(hdds[2], "none") == 0) 2696 { 2697 machine->DetachHardDisk2(StorageBus_IDE, 1, 1); 2698 } 2699 else 2700 { 2701 /* first guess is that it's a UUID */ 2702 Guid uuid(hdds[2]); 2703 ComPtr<IHardDisk2> hardDisk; 2704 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam()); 2705 /* not successful? Then it must be a filename */ 2706 if (!hardDisk) 2707 { 2708 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[2]), hardDisk.asOutParam())); 2709 if (FAILED(rc)) 2710 { 2711 /* open the new hard disk object */ 2712 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[2]), hardDisk.asOutParam())); 2713 } 2714 } 2715 if (hardDisk) 2716 { 2717 hardDisk->COMGETTER(Id)(uuid.asOutParam()); 2718 CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_IDE, 1, 1)); 2719 } 2720 else 2721 rc = E_FAIL; 2722 if (FAILED(rc)) 2723 break; 2724 } 2725 } 2726 if (dvd) 2727 { 2728 ComPtr<IDVDDrive> dvdDrive; 2729 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam()); 2730 ASSERT(dvdDrive); 2731 2732 /* unmount? */ 2733 if (strcmp(dvd, "none") == 0) 2734 { 2735 CHECK_ERROR(dvdDrive, Unmount()); 2736 } 2737 /* host drive? */ 2738 else if (strncmp(dvd, "host:", 5) == 0) 2739 { 2740 ComPtr<IHost> host; 2741 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam())); 2742 ComPtr<IHostDVDDriveCollection> hostDVDs; 2743 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam())); 2744 ComPtr<IHostDVDDrive> hostDVDDrive; 2745 rc = hostDVDs->FindByName(Bstr(dvd + 5), hostDVDDrive.asOutParam()); 2746 if (!hostDVDDrive) 2747 { 2748 /* 2nd try: try with the real name, important on Linux+libhal */ 2749 char szPathReal[RTPATH_MAX]; 2750 if (RT_FAILURE(RTPathReal(dvd + 5, szPathReal, sizeof(szPathReal)))) 2751 { 2752 errorArgument("Invalid host DVD drive name"); 2753 rc = E_FAIL; 2754 break; 2755 } 2756 rc = hostDVDs->FindByName(Bstr(szPathReal), hostDVDDrive.asOutParam()); 2757 if (!hostDVDDrive) 2758 { 2759 errorArgument("Invalid host DVD drive name"); 2760 rc = E_FAIL; 2761 break; 2762 } 2763 } 2764 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive)); 2765 } 2766 else 2767 { 2768 /* first assume it's a UUID */ 2769 Guid uuid(dvd); 2770 ComPtr<IDVDImage2> dvdImage; 2771 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam()); 2772 if (FAILED(rc) || !dvdImage) 2773 { 2774 /* must be a filename, check if it's in the collection */ 2775 rc = virtualBox->FindDVDImage(Bstr(dvd), dvdImage.asOutParam()); 2776 /* not registered, do that on the fly */ 2777 if (!dvdImage) 2778 { 2779 Guid emptyUUID; 2780 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(dvd), emptyUUID, dvdImage.asOutParam())); 2781 } 2782 } 2783 if (!dvdImage) 2784 { 2785 rc = E_FAIL; 2786 break; 2787 } 2788 2789 dvdImage->COMGETTER(Id)(uuid.asOutParam()); 2790 CHECK_ERROR(dvdDrive, MountImage(uuid)); 2791 } 2792 } 2793 if (dvdpassthrough) 2794 { 2795 ComPtr<IDVDDrive> dvdDrive; 2796 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam()); 2797 ASSERT(dvdDrive); 2798 2799 CHECK_ERROR(dvdDrive, COMSETTER(Passthrough)(strcmp(dvdpassthrough, "on") == 0)); 2800 } 2801 if (idecontroller) 2802 { 2803 if (RTStrICmp(idecontroller, "PIIX3") == 0) 2804 { 2805 CHECK_ERROR(biosSettings, COMSETTER(IDEControllerType)(IDEControllerType_PIIX3)); 2806 } 2807 else if (RTStrICmp(idecontroller, "PIIX4") == 0) 2808 { 2809 CHECK_ERROR(biosSettings, COMSETTER(IDEControllerType)(IDEControllerType_PIIX4)); 2810 } 2811 else 2812 { 2813 errorArgument("Invalid -idecontroller argument '%s'", idecontroller); 2814 rc = E_FAIL; 2815 break; 2816 } 2817 } 2818 if (floppy) 2819 { 2820 ComPtr<IFloppyDrive> floppyDrive; 2821 machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam()); 2822 ASSERT(floppyDrive); 2823 2824 /* disable? */ 2825 if (strcmp(floppy, "disabled") == 0) 2826 { 2827 /* disable the controller */ 2828 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(false)); 2829 } 2830 else 2831 { 2832 /* enable the controller */ 2833 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(true)); 2834 2835 /* unmount? */ 2836 if (strcmp(floppy, "empty") == 0) 2837 { 2838 CHECK_ERROR(floppyDrive, Unmount()); 2839 } 2840 /* host drive? */ 2841 else if (strncmp(floppy, "host:", 5) == 0) 2842 { 2843 ComPtr<IHost> host; 2844 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam())); 2845 ComPtr<IHostFloppyDriveCollection> hostFloppies; 2846 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam())); 2847 ComPtr<IHostFloppyDrive> hostFloppyDrive; 2848 rc = hostFloppies->FindByName(Bstr(floppy + 5), hostFloppyDrive.asOutParam()); 2849 if (!hostFloppyDrive) 2850 { 2851 errorArgument("Invalid host floppy drive name"); 2852 rc = E_FAIL; 2853 break; 2854 } 2855 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive)); 2856 } 2857 else 2858 { 2859 /* first assume it's a UUID */ 2860 Guid uuid(floppy); 2861 ComPtr<IFloppyImage2> floppyImage; 2862 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam()); 2863 if (FAILED(rc) || !floppyImage) 2864 { 2865 /* must be a filename, check if it's in the collection */ 2866 rc = virtualBox->FindFloppyImage(Bstr(floppy), floppyImage.asOutParam()); 2867 /* not registered, do that on the fly */ 2868 if (!floppyImage) 2869 { 2870 Guid emptyUUID; 2871 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(floppy), emptyUUID, floppyImage.asOutParam())); 2872 } 2873 } 2874 if (!floppyImage) 2875 { 2876 rc = E_FAIL; 2877 break; 2878 } 2879 2880 floppyImage->COMGETTER(Id)(uuid.asOutParam()); 2881 CHECK_ERROR(floppyDrive, MountImage(uuid)); 2882 } 2883 } 2884 } 2885 if (audio || audiocontroller) 2886 { 2887 ComPtr<IAudioAdapter> audioAdapter; 2888 machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam()); 2889 ASSERT(audioAdapter); 2890 2891 if (audio) 2892 { 2893 /* disable? */ 2894 if (strcmp(audio, "none") == 0) 2895 { 2896 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(false)); 2897 } 2898 else if (strcmp(audio, "null") == 0) 2899 { 2900 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null)); 2901 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2902 } 2903 #ifdef RT_OS_WINDOWS 2904 #ifdef VBOX_WITH_WINMM 2905 else if (strcmp(audio, "winmm") == 0) 2906 { 2907 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM)); 2908 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2909 } 2910 #endif 2911 else if (strcmp(audio, "dsound") == 0) 2912 { 2913 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound)); 2914 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2915 } 2916 #endif /* RT_OS_WINDOWS */ 2917 #ifdef RT_OS_LINUX 2918 else if (strcmp(audio, "oss") == 0) 2919 { 2920 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS)); 2921 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2922 } 2923 # ifdef VBOX_WITH_ALSA 2924 else if (strcmp(audio, "alsa") == 0) 2925 { 2926 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA)); 2927 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2928 } 2929 # endif 2930 # ifdef VBOX_WITH_PULSE 2931 else if (strcmp(audio, "pulse") == 0) 2932 { 2933 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse)); 2934 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2935 } 2936 # endif 2937 #endif /* !RT_OS_LINUX */ 2938 #ifdef RT_OS_SOLARIS 2939 else if (strcmp(audio, "solaudio") == 0) 2940 { 2941 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_SolAudio)); 2942 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2943 } 2944 2945 #endif /* !RT_OS_SOLARIS */ 2946 #ifdef RT_OS_DARWIN 2947 else if (strcmp(audio, "coreaudio") == 0) 2948 { 2949 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio)); 2950 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true)); 2951 } 2952 2953 #endif /* !RT_OS_DARWIN */ 2954 else 2955 { 2956 errorArgument("Invalid -audio argument '%s'", audio); 2957 rc = E_FAIL; 2958 break; 2959 } 2960 } 2961 if (audiocontroller) 2962 { 2963 if (strcmp(audiocontroller, "sb16") == 0) 2964 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16)); 2965 else if (strcmp(audiocontroller, "ac97") == 0) 2966 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97)); 2967 else 2968 { 2969 errorArgument("Invalid -audiocontroller argument '%s'", audiocontroller); 2970 rc = E_FAIL; 2971 break; 2972 } 2973 } 2974 } 2975 /* Shared clipboard state */ 2976 if (clipboard) 2977 { 2978 /* ComPtr<IClipboardMode> clipboardMode; 2979 machine->COMGETTER(ClipboardMode)(clipboardMode.asOutParam()); 2980 ASSERT(clipboardMode); 2981 */ 2982 if (strcmp(clipboard, "disabled") == 0) 2983 { 2984 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Disabled)); 2985 } 2986 else if (strcmp(clipboard, "hosttoguest") == 0) 2987 { 2988 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_HostToGuest)); 2989 } 2990 else if (strcmp(clipboard, "guesttohost") == 0) 2991 { 2992 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_GuestToHost)); 2993 } 2994 else if (strcmp(clipboard, "bidirectional") == 0) 2995 { 2996 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Bidirectional)); 2997 } 2998 else 2999 { 3000 errorArgument("Invalid -clipboard argument '%s'", clipboard); 3001 rc = E_FAIL; 3002 break; 3003 } 3004 } 3005 /* iterate through all possible NICs */ 3006 for (ULONG n = 0; n < NetworkAdapterCount; n ++) 3007 { 3008 ComPtr<INetworkAdapter> nic; 3009 CHECK_ERROR_RET (machine, GetNetworkAdapter (n, nic.asOutParam()), 1); 3010 3011 ASSERT(nic); 3012 3013 /* something about the NIC? */ 3014 if (nics[n]) 3015 { 3016 if (strcmp(nics[n], "none") == 0) 3017 { 3018 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (FALSE), 1); 3019 } 3020 else if (strcmp(nics[n], "null") == 0) 3021 { 3022 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1); 3023 CHECK_ERROR_RET(nic, Detach(), 1); 3024 } 3025 else if (strcmp(nics[n], "nat") == 0) 3026 { 3027 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1); 3028 CHECK_ERROR_RET(nic, AttachToNAT(), 1); 3029 } 3030 else if (strcmp(nics[n], "hostif") == 0) 3031 { 3032 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1); 3033 CHECK_ERROR_RET(nic, AttachToHostInterface(), 1); 3034 } 3035 else if (strcmp(nics[n], "intnet") == 0) 3036 { 3037 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1); 3038 CHECK_ERROR_RET(nic, AttachToInternalNetwork(), 1); 3039 } 3040 else 3041 { 3042 errorArgument("Invalid type '%s' specfied for NIC %lu", nics[n], n + 1); 3043 rc = E_FAIL; 3044 break; 3045 } 3046 } 3047 3048 /* something about the NIC type? */ 3049 if (nictype[n]) 3050 { 3051 if (strcmp(nictype[n], "Am79C970A") == 0) 3052 { 3053 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A), 1); 3054 } 3055 else if (strcmp(nictype[n], "Am79C973") == 0) 3056 { 3057 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973), 1); 3058 } 3059 #ifdef VBOX_WITH_E1000 3060 else if (strcmp(nictype[n], "82540EM") == 0) 3061 { 3062 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM), 1); 3063 } 3064 else if (strcmp(nictype[n], "82543GC") == 0) 3065 { 3066 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC), 1); 3067 } 3068 #endif 3069 else 3070 { 3071 errorArgument("Invalid NIC type '%s' specified for NIC %lu", nictype[n], n + 1); 3072 rc = E_FAIL; 3073 break; 3074 } 3075 } 3076 3077 /* something about the MAC address? */ 3078 if (macs[n]) 3079 { 3080 /* generate one? */ 3081 if (strcmp(macs[n], "auto") == 0) 3082 { 3083 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(NULL), 1); 3084 } 3085 else 3086 { 3087 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(Bstr(macs[n])), 1); 3088 } 3089 } 3090 3091 /* something about the reported link speed? */ 3092 if (nicspeed[n]) 3093 { 3094 uint32_t u32LineSpeed; 3095 3096 u32LineSpeed = RTStrToUInt32(nicspeed[n]); 3097 3098 if (u32LineSpeed < 1000 || u32LineSpeed > 4000000) 3099 { 3100 errorArgument("Invalid -nicspeed%lu argument '%s'", n + 1, nicspeed[n]); 3101 rc = E_FAIL; 3102 break; 3103 } 3104 CHECK_ERROR_RET(nic, COMSETTER(LineSpeed)(u32LineSpeed), 1); 3105 } 3106 3107 /* the link status flag? */ 3108 if (cableconnected[n]) 3109 { 3110 if (strcmp(cableconnected[n], "on") == 0) 3111 { 3112 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(TRUE), 1); 3113 } 3114 else if (strcmp(cableconnected[n], "off") == 0) 3115 { 3116 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(FALSE), 1); 3117 } 3118 else 3119 { 3120 errorArgument("Invalid -cableconnected%lu argument '%s'", n + 1, cableconnected[n]); 3121 rc = E_FAIL; 3122 break; 3123 } 3124 } 3125 3126 /* the trace flag? */ 3127 if (nictrace[n]) 3128 { 3129 if (strcmp(nictrace[n], "on") == 0) 3130 { 3131 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(TRUE), 1); 3132 } 3133 else if (strcmp(nictrace[n], "off") == 0) 3134 { 3135 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(FALSE), 1); 3136 } 3137 else 3138 { 3139 errorArgument("Invalid -nictrace%lu argument '%s'", n + 1, nictrace[n]); 3140 rc = E_FAIL; 3141 break; 3142 } 3143 } 3144 3145 /* the tracefile flag? */ 3146 if (nictracefile[n]) 3147 { 3148 CHECK_ERROR_RET(nic, COMSETTER(TraceFile)(Bstr(nictracefile[n])), 1); 3149 } 3150 3151 /* the host interface device? */ 3152 if (hostifdev[n]) 3153 { 3154 /* remove it? */ 3155 if (strcmp(hostifdev[n], "none") == 0) 3156 { 3157 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(NULL), 1); 3158 } 3159 else 3160 { 3161 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(Bstr(hostifdev[n])), 1); 3162 } 3163 } 3164 3165 /* the internal network name? */ 3166 if (intnet[n]) 3167 { 3168 /* remove it? */ 3169 if (strcmp(intnet[n], "none") == 0) 3170 { 3171 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(NULL), 1); 3172 } 3173 else 3174 { 3175 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(Bstr(intnet[n])), 1); 3176 } 3177 } 3178 /* the network of the NAT */ 3179 if (natnet[n]) 3180 { 3181 CHECK_ERROR_RET(nic, COMSETTER(NATNetwork)(Bstr(natnet[n])), 1); 3182 } 3183 } 3184 if (FAILED(rc)) 3185 break; 3186 3187 /* iterate through all possible serial ports */ 3188 for (ULONG n = 0; n < SerialPortCount; n ++) 3189 { 3190 ComPtr<ISerialPort> uart; 3191 CHECK_ERROR_RET (machine, GetSerialPort (n, uart.asOutParam()), 1); 3192 3193 ASSERT(uart); 3194 3195 if (uarts_base[n]) 3196 { 3197 if (uarts_base[n] == (ULONG)-1) 3198 { 3199 CHECK_ERROR_RET(uart, COMSETTER(Enabled) (FALSE), 1); 3200 } 3201 else 3202 { 3203 CHECK_ERROR_RET(uart, COMSETTER(IOBase) (uarts_base[n]), 1); 3204 CHECK_ERROR_RET(uart, COMSETTER(IRQ) (uarts_irq[n]), 1); 3205 CHECK_ERROR_RET(uart, COMSETTER(Enabled) (TRUE), 1); 3206 } 3207 } 3208 if (uarts_mode[n]) 3209 { 3210 if (strcmp(uarts_mode[n], "disconnected") == 0) 3211 { 3212 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_Disconnected), 1); 3213 } 3214 else 3215 { 3216 CHECK_ERROR_RET(uart, COMSETTER(Path) (Bstr(uarts_path[n])), 1); 3217 if (strcmp(uarts_mode[n], "server") == 0) 3218 { 3219 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1); 3220 CHECK_ERROR_RET(uart, COMSETTER(Server) (TRUE), 1); 3221 } 3222 else if (strcmp(uarts_mode[n], "client") == 0) 3223 { 3224 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1); 3225 CHECK_ERROR_RET(uart, COMSETTER(Server) (FALSE), 1); 3226 } 3227 else 3228 { 3229 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostDevice), 1); 3230 } 3231 } 3232 } 3233 } 3234 if (FAILED(rc)) 3235 break; 3236 3237 #ifdef VBOX_WITH_VRDP 3238 if (vrdp || (vrdpport != UINT16_MAX) || vrdpaddress || vrdpauthtype || vrdpmulticon || vrdpreusecon) 3239 { 3240 ComPtr<IVRDPServer> vrdpServer; 3241 machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam()); 3242 ASSERT(vrdpServer); 3243 if (vrdpServer) 3244 { 3245 if (vrdp) 3246 { 3247 if (strcmp(vrdp, "on") == 0) 3248 { 3249 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(true)); 3250 } 3251 else if (strcmp(vrdp, "off") == 0) 3252 { 3253 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(false)); 3254 } 3255 else 3256 { 3257 errorArgument("Invalid -vrdp argument '%s'", vrdp); 3258 rc = E_FAIL; 3259 break; 3260 } 3261 } 3262 if (vrdpport != UINT16_MAX) 3263 { 3264 CHECK_ERROR(vrdpServer, COMSETTER(Port)(vrdpport)); 3265 } 3266 if (vrdpaddress) 3267 { 3268 CHECK_ERROR(vrdpServer, COMSETTER(NetAddress)(Bstr(vrdpaddress))); 3269 } 3270 if (vrdpauthtype) 3271 { 3272 if (strcmp(vrdpauthtype, "null") == 0) 3273 { 3274 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Null)); 3275 } 3276 else if (strcmp(vrdpauthtype, "external") == 0) 3277 { 3278 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_External)); 3279 } 3280 else if (strcmp(vrdpauthtype, "guest") == 0) 3281 { 3282 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Guest)); 3283 } 3284 else 3285 { 3286 errorArgument("Invalid -vrdpauthtype argument '%s'", vrdpauthtype); 3287 rc = E_FAIL; 3288 break; 3289 } 3290 } 3291 if (vrdpmulticon) 3292 { 3293 if (strcmp(vrdpmulticon, "on") == 0) 3294 { 3295 CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(true)); 3296 } 3297 else if (strcmp(vrdpmulticon, "off") == 0) 3298 { 3299 CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(false)); 3300 } 3301 else 3302 { 3303 errorArgument("Invalid -vrdpmulticon argument '%s'", vrdpmulticon); 3304 rc = E_FAIL; 3305 break; 3306 } 3307 } 3308 if (vrdpreusecon) 3309 { 3310 if (strcmp(vrdpreusecon, "on") == 0) 3311 { 3312 CHECK_ERROR(vrdpServer, COMSETTER(ReuseSingleConnection)(true)); 3313 } 3314 else if (strcmp(vrdpreusecon, "off") == 0) 3315 { 3316 CHECK_ERROR(vrdpServer, COMSETTER(ReuseSingleConnection)(false)); 3317 } 3318 else 3319 { 3320 errorArgument("Invalid -vrdpreusecon argument '%s'", vrdpreusecon); 3321 rc = E_FAIL; 3322 break; 3323 } 3324 } 3325 } 3326 } 3327 #endif /* VBOX_WITH_VRDP */ 3328 3329 /* 3330 * USB enable/disable 3331 */ 3332 if (fUsbEnabled != -1) 3333 { 3334 ComPtr<IUSBController> UsbCtl; 3335 CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam())); 3336 if (SUCCEEDED(rc)) 3337 { 3338 CHECK_ERROR(UsbCtl, COMSETTER(Enabled)(!!fUsbEnabled)); 3339 } 3340 } 3341 /* 3342 * USB EHCI enable/disable 3343 */ 3344 if (fUsbEhciEnabled != -1) 3345 { 3346 ComPtr<IUSBController> UsbCtl; 3347 CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam())); 3348 if (SUCCEEDED(rc)) 3349 { 3350 CHECK_ERROR(UsbCtl, COMSETTER(EnabledEhci)(!!fUsbEhciEnabled)); 3351 } 3352 } 3353 3354 if (snapshotFolder) 3355 { 3356 if (strcmp(snapshotFolder, "default") == 0) 3357 { 3358 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(NULL)); 3359 } 3360 else 3361 { 3362 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(snapshotFolder))); 3363 } 3364 } 3365 3366 if (guestMemBalloonSize != (ULONG)-1) 3367 CHECK_ERROR(machine, COMSETTER(MemoryBalloonSize)(guestMemBalloonSize)); 3368 3369 if (guestStatInterval != (ULONG)-1) 3370 CHECK_ERROR(machine, COMSETTER(StatisticsUpdateInterval)(guestStatInterval)); 3371 3372 /* 3373 * SATA controller enable/disable 3374 */ 3375 if (fSataEnabled != -1) 3376 { 3377 ComPtr<ISATAController> SataCtl; 3378 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam())); 3379 if (SUCCEEDED(rc)) 3380 { 3381 CHECK_ERROR(SataCtl, COMSETTER(Enabled)(!!fSataEnabled)); 3382 } 3383 } 3384 3385 for (uint32_t i = 4; i < 34; i++) 3386 { 3387 if (hdds[i]) 3388 { 3389 if (strcmp(hdds[i], "none") == 0) 3390 { 3391 machine->DetachHardDisk2(StorageBus_SATA, i-4, 0); 3392 } 3393 else 3394 { 3395 /* first guess is that it's a UUID */ 3396 Guid uuid(hdds[i]); 3397 ComPtr<IHardDisk2> hardDisk; 3398 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam()); 3399 /* not successful? Then it must be a filename */ 3400 if (!hardDisk) 3401 { 3402 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(hdds[i]), hardDisk.asOutParam())); 3403 if (FAILED(rc)) 3404 { 3405 /* open the new hard disk object */ 3406 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(hdds[i]), hardDisk.asOutParam())); 3407 } 3408 } 3409 if (hardDisk) 3410 { 3411 hardDisk->COMGETTER(Id)(uuid.asOutParam()); 3412 CHECK_ERROR(machine, AttachHardDisk2(uuid, StorageBus_SATA, i-4, 0)); 3413 } 3414 else 3415 rc = E_FAIL; 3416 if (FAILED(rc)) 3417 break; 3418 } 3419 } 3420 } 3421 3422 for (uint32_t i = 0; i < 4; i++) 3423 { 3424 if (sataBootDevices[i] != -1) 3425 { 3426 ComPtr<ISATAController> SataCtl; 3427 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam())); 3428 if (SUCCEEDED(rc)) 3429 { 3430 CHECK_ERROR(SataCtl, SetIDEEmulationPort(i, sataBootDevices[i])); 3431 } 3432 } 3433 } 3434 3435 if (sataPortCount != -1) 3436 { 3437 ComPtr<ISATAController> SataCtl; 3438 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam())); 3439 if (SUCCEEDED(rc)) 3440 { 3441 CHECK_ERROR(SataCtl, COMSETTER(PortCount)(sataPortCount)); 3442 } 3443 } 3444 3445 /* commit changes */ 3446 CHECK_ERROR(machine, SaveSettings()); 3447 } 3448 while (0); 3449 3450 /* it's important to always close sessions */ 3451 session->Close(); 3452 3453 return SUCCEEDED(rc) ? 0 : 1; 3454 } 3455 3456 /** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */ 3457 #if defined(_MSC_VER) 3458 # pragma optimize("", on) 3459 #endif 3460 3461 static int handleStartVM(int argc, char *argv[], 3462 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 3463 { 3464 HRESULT rc; 3465 3466 if (argc < 1) 3467 return errorSyntax(USAGE_STARTVM, "Not enough parameters"); 3468 3469 ComPtr<IMachine> machine; 3470 /* assume it's a UUID */ 3471 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam()); 3472 if (FAILED(rc) || !machine) 3473 { 3474 /* must be a name */ 3475 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam())); 3476 } 3477 if (machine) 3478 { 3479 Guid uuid; 3480 machine->COMGETTER(Id)(uuid.asOutParam()); 3481 3482 /* default to GUI session type */ 3483 Bstr sessionType = "gui"; 3484 /* has a session type been specified? */ 3485 if ((argc > 2) && (strcmp(argv[1], "-type") == 0)) 3486 { 3487 if (strcmp(argv[2], "gui") == 0) 3488 { 3489 sessionType = "gui"; 3490 } 3491 else if (strcmp(argv[2], "vrdp") == 0) 3492 { 3493 sessionType = "vrdp"; 3494 } 3495 else if (strcmp(argv[2], "capture") == 0) 3496 { 3497 sessionType = "capture"; 3498 } 3499 else 3500 return errorArgument("Invalid session type argument '%s'", argv[2]); 3501 } 3502 3503 Bstr env; 3504 #ifdef RT_OS_LINUX 3505 /* make sure the VM process will start on the same display as VBoxManage */ 3506 { 3507 const char *display = RTEnvGet ("DISPLAY"); 3508 if (display) 3509 env = Utf8StrFmt ("DISPLAY=%s", display); 3510 } 3511 #endif 3512 ComPtr<IProgress> progress; 3513 CHECK_ERROR_RET(virtualBox, OpenRemoteSession(session, uuid, sessionType, 3514 env, progress.asOutParam()), rc); 3515 RTPrintf("Waiting for the remote session to open...\n"); 3516 CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1); 3517 3518 BOOL completed; 3519 CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc); 3520 ASSERT(completed); 3521 3522 HRESULT resultCode; 3523 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&resultCode), rc); 3524 if (FAILED(resultCode)) 3525 { 3526 ComPtr <IVirtualBoxErrorInfo> errorInfo; 3527 CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1); 3528 ErrorInfo info (errorInfo); 3529 PRINT_ERROR_INFO(info); 3530 } 3531 else 3532 { 3533 RTPrintf("Remote session has been successfully opened.\n"); 3534 } 3535 } 3536 3537 /* it's important to always close sessions */ 3538 session->Close(); 3539 3540 return SUCCEEDED(rc) ? 0 : 1; 3541 } 3542 3543 static int handleControlVM(int argc, char *argv[], 800 801 int handleShowHardDiskInfo(int argc, char *argv[], 3544 802 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 3545 {3546 HRESULT rc;3547 3548 if (argc < 2)3549 return errorSyntax(USAGE_CONTROLVM, "Not enough parameters");3550 3551 /* try to find the given machine */3552 ComPtr <IMachine> machine;3553 Guid uuid (argv[0]);3554 if (!uuid.isEmpty())3555 {3556 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));3557 }3558 else3559 {3560 CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));3561 if (SUCCEEDED (rc))3562 machine->COMGETTER(Id) (uuid.asOutParam());3563 }3564 if (FAILED (rc))3565 return 1;3566 3567 /* open a session for the VM */3568 CHECK_ERROR_RET (virtualBox, OpenExistingSession (session, uuid), 1);3569 3570 do3571 {3572 /* get the associated console */3573 ComPtr<IConsole> console;3574 CHECK_ERROR_BREAK (session, COMGETTER(Console)(console.asOutParam()));3575 /* ... and session machine */3576 ComPtr<IMachine> sessionMachine;3577 CHECK_ERROR_BREAK (session, COMGETTER(Machine)(sessionMachine.asOutParam()));3578 3579 /* which command? */3580 if (strcmp(argv[1], "pause") == 0)3581 {3582 CHECK_ERROR_BREAK (console, Pause());3583 }3584 else if (strcmp(argv[1], "resume") == 0)3585 {3586 CHECK_ERROR_BREAK (console, Resume());3587 }3588 else if (strcmp(argv[1], "reset") == 0)3589 {3590 CHECK_ERROR_BREAK (console, Reset());3591 }3592 else if (strcmp(argv[1], "poweroff") == 0)3593 {3594 CHECK_ERROR_BREAK (console, PowerDown());3595 }3596 else if (strcmp(argv[1], "savestate") == 0)3597 {3598 ComPtr<IProgress> progress;3599 CHECK_ERROR_BREAK (console, SaveState(progress.asOutParam()));3600 3601 showProgress(progress);3602 3603 progress->COMGETTER(ResultCode)(&rc);3604 if (FAILED(rc))3605 {3606 com::ProgressErrorInfo info(progress);3607 if (info.isBasicAvailable())3608 {3609 RTPrintf("Error: failed to save machine state. Error message: %lS\n", info.getText().raw());3610 }3611 else3612 {3613 RTPrintf("Error: failed to save machine state. No error message available!\n");3614 }3615 }3616 }3617 else if (strcmp(argv[1], "acpipowerbutton") == 0)3618 {3619 CHECK_ERROR_BREAK (console, PowerButton());3620 }3621 else if (strcmp(argv[1], "acpisleepbutton") == 0)3622 {3623 CHECK_ERROR_BREAK (console, SleepButton());3624 }3625 else if (strcmp(argv[1], "injectnmi") == 0)3626 {3627 /* get the machine debugger. */3628 ComPtr <IMachineDebugger> debugger;3629 CHECK_ERROR_BREAK(console, COMGETTER(Debugger)(debugger.asOutParam()));3630 CHECK_ERROR_BREAK(debugger, InjectNMI());3631 }3632 else if (strcmp(argv[1], "keyboardputscancode") == 0)3633 {3634 ComPtr<IKeyboard> keyboard;3635 CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(keyboard.asOutParam()));3636 3637 if (argc <= 1 + 1)3638 {3639 errorArgument("Missing argument to '%s'. Expected IBM PC AT set 2 keyboard scancode(s) as hex byte(s).", argv[1]);3640 rc = E_FAIL;3641 break;3642 }3643 3644 /* Arbitrary restrict the length of a sequence of scancodes to 1024. */3645 LONG alScancodes[1024];3646 int cScancodes = 0;3647 3648 /* Process the command line. */3649 int i;3650 for (i = 1 + 1; i < argc && cScancodes < (int)RT_ELEMENTS(alScancodes); i++, cScancodes++)3651 {3652 if ( RT_C_IS_XDIGIT (argv[i][0])3653 && RT_C_IS_XDIGIT (argv[i][1])3654 && argv[i][2] == 0)3655 {3656 uint8_t u8Scancode;3657 int rc = RTStrToUInt8Ex(argv[i], NULL, 16, &u8Scancode);3658 if (RT_FAILURE (rc))3659 {3660 RTPrintf("Error: converting '%s' returned %Rrc!\n", argv[i], rc);3661 rc = E_FAIL;3662 break;3663 }3664 3665 alScancodes[cScancodes] = u8Scancode;3666 }3667 else3668 {3669 RTPrintf("Error: '%s' is not a hex byte!\n", argv[i]);3670 rc = E_FAIL;3671 break;3672 }3673 }3674 3675 if (FAILED(rc))3676 break;3677 3678 if ( cScancodes == RT_ELEMENTS(alScancodes)3679 && i < argc)3680 {3681 RTPrintf("Error: too many scancodes, maximum %d allowed!\n", RT_ELEMENTS(alScancodes));3682 rc = E_FAIL;3683 break;3684 }3685 3686 /* Send scancodes to the VM.3687 * Note: 'PutScancodes' did not work here. Only the first scancode was transmitted.3688 */3689 for (i = 0; i < cScancodes; i++)3690 {3691 CHECK_ERROR_BREAK(keyboard, PutScancode(alScancodes[i]));3692 RTPrintf("Scancode[%d]: 0x%02X\n", i, alScancodes[i]);3693 }3694 }3695 else if (strncmp(argv[1], "setlinkstate", 12) == 0)3696 {3697 /* Get the number of network adapters */3698 ULONG NetworkAdapterCount = 0;3699 ComPtr <ISystemProperties> info;3700 CHECK_ERROR_BREAK (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));3701 CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));3702 3703 unsigned n = parseNum(&argv[1][12], NetworkAdapterCount, "NIC");3704 if (!n)3705 {3706 rc = E_FAIL;3707 break;3708 }3709 if (argc <= 1 + 1)3710 {3711 errorArgument("Missing argument to '%s'", argv[1]);3712 rc = E_FAIL;3713 break;3714 }3715 /* get the corresponding network adapter */3716 ComPtr<INetworkAdapter> adapter;3717 CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));3718 if (adapter)3719 {3720 if (strcmp(argv[2], "on") == 0)3721 {3722 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(TRUE));3723 }3724 else if (strcmp(argv[2], "off") == 0)3725 {3726 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(FALSE));3727 }3728 else3729 {3730 errorArgument("Invalid link state '%s'", Utf8Str(argv[2]).raw());3731 rc = E_FAIL;3732 break;3733 }3734 }3735 }3736 #ifdef VBOX_WITH_VRDP3737 else if (strcmp(argv[1], "vrdp") == 0)3738 {3739 if (argc <= 1 + 1)3740 {3741 errorArgument("Missing argument to '%s'", argv[1]);3742 rc = E_FAIL;3743 break;3744 }3745 /* get the corresponding VRDP server */3746 ComPtr<IVRDPServer> vrdpServer;3747 sessionMachine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());3748 ASSERT(vrdpServer);3749 if (vrdpServer)3750 {3751 if (strcmp(argv[2], "on") == 0)3752 {3753 CHECK_ERROR_BREAK (vrdpServer, COMSETTER(Enabled)(TRUE));3754 }3755 else if (strcmp(argv[2], "off") == 0)3756 {3757 CHECK_ERROR_BREAK (vrdpServer, COMSETTER(Enabled)(FALSE));3758 }3759 else3760 {3761 errorArgument("Invalid vrdp server state '%s'", Utf8Str(argv[2]).raw());3762 rc = E_FAIL;3763 break;3764 }3765 }3766 }3767 #endif /* VBOX_WITH_VRDP */3768 else if (strcmp (argv[1], "usbattach") == 0 ||3769 strcmp (argv[1], "usbdetach") == 0)3770 {3771 if (argc < 3)3772 {3773 errorSyntax(USAGE_CONTROLVM, "Not enough parameters");3774 rc = E_FAIL;3775 break;3776 }3777 3778 bool attach = strcmp (argv[1], "usbattach") == 0;3779 3780 Guid usbId = argv [2];3781 if (usbId.isEmpty())3782 {3783 // assume address3784 if (attach)3785 {3786 ComPtr <IHost> host;3787 CHECK_ERROR_BREAK (virtualBox, COMGETTER(Host) (host.asOutParam()));3788 ComPtr <IHostUSBDeviceCollection> coll;3789 CHECK_ERROR_BREAK (host, COMGETTER(USBDevices) (coll.asOutParam()));3790 ComPtr <IHostUSBDevice> dev;3791 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));3792 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));3793 }3794 else3795 {3796 ComPtr <IUSBDeviceCollection> coll;3797 CHECK_ERROR_BREAK (console, COMGETTER(USBDevices)(coll.asOutParam()));3798 ComPtr <IUSBDevice> dev;3799 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));3800 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));3801 }3802 }3803 3804 if (attach)3805 CHECK_ERROR_BREAK (console, AttachUSBDevice (usbId));3806 else3807 {3808 ComPtr <IUSBDevice> dev;3809 CHECK_ERROR_BREAK (console, DetachUSBDevice (usbId, dev.asOutParam()));3810 }3811 }3812 else if (strcmp(argv[1], "setvideomodehint") == 0)3813 {3814 if (argc != 5 && argc != 6)3815 {3816 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");3817 rc = E_FAIL;3818 break;3819 }3820 uint32_t xres = RTStrToUInt32(argv[2]);3821 uint32_t yres = RTStrToUInt32(argv[3]);3822 uint32_t bpp = RTStrToUInt32(argv[4]);3823 uint32_t displayIdx = 0;3824 if (argc == 6)3825 displayIdx = RTStrToUInt32(argv[5]);3826 3827 ComPtr<IDisplay> display;3828 CHECK_ERROR_BREAK(console, COMGETTER(Display)(display.asOutParam()));3829 CHECK_ERROR_BREAK(display, SetVideoModeHint(xres, yres, bpp, displayIdx));3830 }3831 else if (strcmp(argv[1], "setcredentials") == 0)3832 {3833 bool fAllowLocalLogon = true;3834 if (argc == 7)3835 {3836 if (strcmp(argv[5], "-allowlocallogon") != 0)3837 {3838 errorArgument("Invalid parameter '%s'", argv[5]);3839 rc = E_FAIL;3840 break;3841 }3842 if (strcmp(argv[6], "no") == 0)3843 fAllowLocalLogon = false;3844 }3845 else if (argc != 5)3846 {3847 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");3848 rc = E_FAIL;3849 break;3850 }3851 3852 ComPtr<IGuest> guest;3853 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));3854 CHECK_ERROR_BREAK(guest, SetCredentials(Bstr(argv[2]), Bstr(argv[3]), Bstr(argv[4]), fAllowLocalLogon));3855 }3856 else if (strcmp(argv[1], "dvdattach") == 0)3857 {3858 if (argc != 3)3859 {3860 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");3861 rc = E_FAIL;3862 break;3863 }3864 ComPtr<IDVDDrive> dvdDrive;3865 sessionMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());3866 ASSERT(dvdDrive);3867 3868 /* unmount? */3869 if (strcmp(argv[2], "none") == 0)3870 {3871 CHECK_ERROR(dvdDrive, Unmount());3872 }3873 /* host drive? */3874 else if (strncmp(argv[2], "host:", 5) == 0)3875 {3876 ComPtr<IHost> host;3877 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));3878 ComPtr<IHostDVDDriveCollection> hostDVDs;3879 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));3880 ComPtr<IHostDVDDrive> hostDVDDrive;3881 rc = hostDVDs->FindByName(Bstr(argv[2] + 5), hostDVDDrive.asOutParam());3882 if (!hostDVDDrive)3883 {3884 errorArgument("Invalid host DVD drive name");3885 rc = E_FAIL;3886 break;3887 }3888 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));3889 }3890 else3891 {3892 /* first assume it's a UUID */3893 Guid uuid(argv[2]);3894 ComPtr<IDVDImage2> dvdImage;3895 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());3896 if (FAILED(rc) || !dvdImage)3897 {3898 /* must be a filename, check if it's in the collection */3899 rc = virtualBox->FindDVDImage(Bstr(argv[2]), dvdImage.asOutParam());3900 /* not registered, do that on the fly */3901 if (!dvdImage)3902 {3903 Guid emptyUUID;3904 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(argv[2]), emptyUUID, dvdImage.asOutParam()));3905 }3906 }3907 if (!dvdImage)3908 {3909 rc = E_FAIL;3910 break;3911 }3912 dvdImage->COMGETTER(Id)(uuid.asOutParam());3913 CHECK_ERROR(dvdDrive, MountImage(uuid));3914 }3915 }3916 else if (strcmp(argv[1], "floppyattach") == 0)3917 {3918 if (argc != 3)3919 {3920 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");3921 rc = E_FAIL;3922 break;3923 }3924 3925 ComPtr<IFloppyDrive> floppyDrive;3926 sessionMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());3927 ASSERT(floppyDrive);3928 3929 /* unmount? */3930 if (strcmp(argv[2], "none") == 0)3931 {3932 CHECK_ERROR(floppyDrive, Unmount());3933 }3934 /* host drive? */3935 else if (strncmp(argv[2], "host:", 5) == 0)3936 {3937 ComPtr<IHost> host;3938 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));3939 ComPtr<IHostFloppyDriveCollection> hostFloppies;3940 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));3941 ComPtr<IHostFloppyDrive> hostFloppyDrive;3942 rc = hostFloppies->FindByName(Bstr(argv[2] + 5), hostFloppyDrive.asOutParam());3943 if (!hostFloppyDrive)3944 {3945 errorArgument("Invalid host floppy drive name");3946 rc = E_FAIL;3947 break;3948 }3949 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));3950 }3951 else3952 {3953 /* first assume it's a UUID */3954 Guid uuid(argv[2]);3955 ComPtr<IFloppyImage2> floppyImage;3956 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());3957 if (FAILED(rc) || !floppyImage)3958 {3959 /* must be a filename, check if it's in the collection */3960 rc = virtualBox->FindFloppyImage(Bstr(argv[2]), floppyImage.asOutParam());3961 /* not registered, do that on the fly */3962 if (!floppyImage)3963 {3964 Guid emptyUUID;3965 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(argv[2]), emptyUUID, floppyImage.asOutParam()));3966 }3967 }3968 if (!floppyImage)3969 {3970 rc = E_FAIL;3971 break;3972 }3973 floppyImage->COMGETTER(Id)(uuid.asOutParam());3974 CHECK_ERROR(floppyDrive, MountImage(uuid));3975 }3976 }3977 #ifdef VBOX_WITH_MEM_BALLOONING3978 else if (strncmp(argv[1], "-guestmemoryballoon", 19) == 0)3979 {3980 if (argc != 3)3981 {3982 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");3983 rc = E_FAIL;3984 break;3985 }3986 uint32_t uVal;3987 int vrc;3988 vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);3989 if (vrc != VINF_SUCCESS)3990 {3991 errorArgument("Error parsing guest memory balloon size '%s'", argv[2]);3992 rc = E_FAIL;3993 break;3994 }3995 3996 /* guest is running; update IGuest */3997 ComPtr <IGuest> guest;3998 3999 rc = console->COMGETTER(Guest)(guest.asOutParam());4000 if (SUCCEEDED(rc))4001 CHECK_ERROR(guest, COMSETTER(MemoryBalloonSize)(uVal));4002 }4003 #endif4004 else if (strncmp(argv[1], "-gueststatisticsinterval", 24) == 0)4005 {4006 if (argc != 3)4007 {4008 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");4009 rc = E_FAIL;4010 break;4011 }4012 uint32_t uVal;4013 int vrc;4014 vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);4015 if (vrc != VINF_SUCCESS)4016 {4017 errorArgument("Error parsing guest statistics interval '%s'", argv[2]);4018 rc = E_FAIL;4019 break;4020 }4021 4022 /* guest is running; update IGuest */4023 ComPtr <IGuest> guest;4024 4025 rc = console->COMGETTER(Guest)(guest.asOutParam());4026 if (SUCCEEDED(rc))4027 CHECK_ERROR(guest, COMSETTER(StatisticsUpdateInterval)(uVal));4028 }4029 else4030 {4031 errorSyntax(USAGE_CONTROLVM, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());4032 rc = E_FAIL;4033 }4034 }4035 while (0);4036 4037 session->Close();4038 4039 return SUCCEEDED (rc) ? 0 : 1;4040 }4041 4042 static int handleDiscardState(int argc, char *argv[],4043 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4044 {4045 HRESULT rc;4046 4047 if (argc != 1)4048 return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");4049 4050 ComPtr<IMachine> machine;4051 /* assume it's a UUID */4052 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());4053 if (FAILED(rc) || !machine)4054 {4055 /* must be a name */4056 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));4057 }4058 if (machine)4059 {4060 do4061 {4062 /* we have to open a session for this task */4063 Guid guid;4064 machine->COMGETTER(Id)(guid.asOutParam());4065 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));4066 do4067 {4068 ComPtr<IConsole> console;4069 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));4070 CHECK_ERROR_BREAK(console, DiscardSavedState());4071 }4072 while (0);4073 CHECK_ERROR_BREAK(session, Close());4074 }4075 while (0);4076 }4077 4078 return SUCCEEDED(rc) ? 0 : 1;4079 }4080 4081 static int handleAdoptdState(int argc, char *argv[],4082 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4083 {4084 HRESULT rc;4085 4086 if (argc != 2)4087 return errorSyntax(USAGE_ADOPTSTATE, "Incorrect number of parameters");4088 4089 ComPtr<IMachine> machine;4090 /* assume it's a UUID */4091 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());4092 if (FAILED(rc) || !machine)4093 {4094 /* must be a name */4095 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));4096 }4097 if (machine)4098 {4099 do4100 {4101 /* we have to open a session for this task */4102 Guid guid;4103 machine->COMGETTER(Id)(guid.asOutParam());4104 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));4105 do4106 {4107 ComPtr<IConsole> console;4108 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));4109 CHECK_ERROR_BREAK(console, AdoptSavedState (Bstr (argv[1])));4110 }4111 while (0);4112 CHECK_ERROR_BREAK(session, Close());4113 }4114 while (0);4115 }4116 4117 return SUCCEEDED(rc) ? 0 : 1;4118 }4119 4120 static int handleSnapshot(int argc, char *argv[],4121 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4122 {4123 HRESULT rc;4124 4125 /* we need at least a VM and a command */4126 if (argc < 2)4127 return errorSyntax(USAGE_SNAPSHOT, "Not enough parameters");4128 4129 /* the first argument must be the VM */4130 ComPtr<IMachine> machine;4131 /* assume it's a UUID */4132 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());4133 if (FAILED(rc) || !machine)4134 {4135 /* must be a name */4136 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));4137 }4138 if (!machine)4139 return 1;4140 Guid guid;4141 machine->COMGETTER(Id)(guid.asOutParam());4142 4143 do4144 {4145 /* we have to open a session for this task. First try an existing session */4146 rc = virtualBox->OpenExistingSession(session, guid);4147 if (FAILED(rc))4148 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));4149 ComPtr<IConsole> console;4150 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));4151 4152 /* switch based on the command */4153 if (strcmp(argv[1], "take") == 0)4154 {4155 /* there must be a name */4156 if (argc < 3)4157 {4158 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");4159 rc = E_FAIL;4160 break;4161 }4162 Bstr name(argv[2]);4163 if ((argc > 3) && ((argc != 5) || (strcmp(argv[3], "-desc") != 0)))4164 {4165 errorSyntax(USAGE_SNAPSHOT, "Incorrect description format");4166 rc = E_FAIL;4167 break;4168 }4169 Bstr desc;4170 if (argc == 5)4171 desc = argv[4];4172 ComPtr<IProgress> progress;4173 CHECK_ERROR_BREAK(console, TakeSnapshot(name, desc, progress.asOutParam()));4174 4175 showProgress(progress);4176 progress->COMGETTER(ResultCode)(&rc);4177 if (FAILED(rc))4178 {4179 com::ProgressErrorInfo info(progress);4180 if (info.isBasicAvailable())4181 RTPrintf("Error: failed to take snapshot. Error message: %lS\n", info.getText().raw());4182 else4183 RTPrintf("Error: failed to take snapshot. No error message available!\n");4184 }4185 }4186 else if (strcmp(argv[1], "discard") == 0)4187 {4188 /* exactly one parameter: snapshot name */4189 if (argc != 3)4190 {4191 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");4192 rc = E_FAIL;4193 break;4194 }4195 4196 ComPtr<ISnapshot> snapshot;4197 4198 /* assume it's a UUID */4199 Guid guid(argv[2]);4200 if (!guid.isEmpty())4201 {4202 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));4203 }4204 else4205 {4206 /* then it must be a name */4207 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));4208 }4209 4210 snapshot->COMGETTER(Id)(guid.asOutParam());4211 4212 ComPtr<IProgress> progress;4213 CHECK_ERROR_BREAK(console, DiscardSnapshot(guid, progress.asOutParam()));4214 4215 showProgress(progress);4216 progress->COMGETTER(ResultCode)(&rc);4217 if (FAILED(rc))4218 {4219 com::ProgressErrorInfo info(progress);4220 if (info.isBasicAvailable())4221 RTPrintf("Error: failed to discard snapshot. Error message: %lS\n", info.getText().raw());4222 else4223 RTPrintf("Error: failed to discard snapshot. No error message available!\n");4224 }4225 }4226 else if (strcmp(argv[1], "discardcurrent") == 0)4227 {4228 if ( (argc != 3)4229 || ( (strcmp(argv[2], "-state") != 0)4230 && (strcmp(argv[2], "-all") != 0)))4231 {4232 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());4233 rc = E_FAIL;4234 break;4235 }4236 bool fAll = false;4237 if (strcmp(argv[2], "-all") == 0)4238 fAll = true;4239 4240 ComPtr<IProgress> progress;4241 4242 if (fAll)4243 {4244 CHECK_ERROR_BREAK(console, DiscardCurrentSnapshotAndState(progress.asOutParam()));4245 }4246 else4247 {4248 CHECK_ERROR_BREAK(console, DiscardCurrentState(progress.asOutParam()));4249 }4250 4251 showProgress(progress);4252 progress->COMGETTER(ResultCode)(&rc);4253 if (FAILED(rc))4254 {4255 com::ProgressErrorInfo info(progress);4256 if (info.isBasicAvailable())4257 RTPrintf("Error: failed to discard. Error message: %lS\n", info.getText().raw());4258 else4259 RTPrintf("Error: failed to discard. No error message available!\n");4260 }4261 4262 }4263 else if (strcmp(argv[1], "edit") == 0)4264 {4265 if (argc < 3)4266 {4267 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");4268 rc = E_FAIL;4269 break;4270 }4271 4272 ComPtr<ISnapshot> snapshot;4273 4274 if (strcmp(argv[2], "-current") == 0)4275 {4276 CHECK_ERROR_BREAK(machine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam()));4277 }4278 else4279 {4280 /* assume it's a UUID */4281 Guid guid(argv[2]);4282 if (!guid.isEmpty())4283 {4284 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));4285 }4286 else4287 {4288 /* then it must be a name */4289 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));4290 }4291 }4292 4293 /* parse options */4294 for (int i = 3; i < argc; i++)4295 {4296 if (strcmp(argv[i], "-newname") == 0)4297 {4298 if (argc <= i + 1)4299 {4300 errorArgument("Missing argument to '%s'", argv[i]);4301 rc = E_FAIL;4302 break;4303 }4304 i++;4305 snapshot->COMSETTER(Name)(Bstr(argv[i]));4306 }4307 else if (strcmp(argv[i], "-newdesc") == 0)4308 {4309 if (argc <= i + 1)4310 {4311 errorArgument("Missing argument to '%s'", argv[i]);4312 rc = E_FAIL;4313 break;4314 }4315 i++;4316 snapshot->COMSETTER(Description)(Bstr(argv[i]));4317 }4318 else4319 {4320 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());4321 rc = E_FAIL;4322 break;4323 }4324 }4325 4326 }4327 else if (strcmp(argv[1], "showvminfo") == 0)4328 {4329 /* exactly one parameter: snapshot name */4330 if (argc != 3)4331 {4332 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");4333 rc = E_FAIL;4334 break;4335 }4336 4337 ComPtr<ISnapshot> snapshot;4338 4339 /* assume it's a UUID */4340 Guid guid(argv[2]);4341 if (!guid.isEmpty())4342 {4343 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));4344 }4345 else4346 {4347 /* then it must be a name */4348 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));4349 }4350 4351 /* get the machine of the given snapshot */4352 ComPtr<IMachine> machine;4353 snapshot->COMGETTER(Machine)(machine.asOutParam());4354 showVMInfo(virtualBox, machine, console);4355 }4356 else4357 {4358 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());4359 rc = E_FAIL;4360 }4361 } while (0);4362 4363 session->Close();4364 4365 return SUCCEEDED(rc) ? 0 : 1;4366 }4367 4368 static int handleShowHardDiskInfo(int argc, char *argv[],4369 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4370 803 { 4371 804 HRESULT rc; … … 4490 923 } 4491 924 4492 staticint handleOpenMedium(int argc, char *argv[],4493 925 int handleOpenMedium(int argc, char *argv[], 926 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 4494 927 { 4495 928 HRESULT rc; … … 4549 982 } 4550 983 4551 staticint handleCloseMedium(int argc, char *argv[],4552 984 int handleCloseMedium(int argc, char *argv[], 985 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session) 4553 986 { 4554 987 HRESULT rc; … … 4609 1042 return SUCCEEDED(rc) ? 0 : 1; 4610 1043 } 4611 4612 #ifdef RT_OS_WINDOWS4613 static int handleCreateHostIF(int argc, char *argv[],4614 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4615 {4616 if (argc != 1)4617 return errorSyntax(USAGE_CREATEHOSTIF, "Incorrect number of parameters");4618 4619 HRESULT rc = S_OK;4620 4621 do4622 {4623 ComPtr<IHost> host;4624 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));4625 4626 ComPtr<IHostNetworkInterface> hostif;4627 ComPtr<IProgress> progress;4628 CHECK_ERROR_BREAK(host,4629 CreateHostNetworkInterface(Bstr(argv[0]),4630 hostif.asOutParam(),4631 progress.asOutParam()));4632 4633 showProgress(progress);4634 HRESULT result;4635 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));4636 if (FAILED(result))4637 {4638 com::ProgressErrorInfo info(progress);4639 PRINT_ERROR_INFO(info);4640 rc = result;4641 }4642 }4643 while (0);4644 4645 return SUCCEEDED(rc) ? 0 : 1;4646 }4647 4648 static int handleRemoveHostIF(int argc, char *argv[],4649 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4650 {4651 if (argc != 1)4652 return errorSyntax(USAGE_REMOVEHOSTIF, "Incorrect number of parameters");4653 4654 HRESULT rc = S_OK;4655 4656 do4657 {4658 ComPtr<IHost> host;4659 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));4660 4661 ComPtr<IHostNetworkInterface> hostif;4662 4663 /* first guess is that it's a UUID */4664 Guid uuid(argv[0]);4665 if (uuid.isEmpty())4666 {4667 /* not a valid UUID, search for it */4668 ComPtr<IHostNetworkInterfaceCollection> coll;4669 CHECK_ERROR_BREAK(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));4670 CHECK_ERROR_BREAK(coll, FindByName(Bstr(argv[0]), hostif.asOutParam()));4671 CHECK_ERROR_BREAK(hostif, COMGETTER(Id)(uuid.asOutParam()));4672 }4673 4674 ComPtr<IProgress> progress;4675 CHECK_ERROR_BREAK(host,4676 RemoveHostNetworkInterface(uuid,4677 hostif.asOutParam(),4678 progress.asOutParam()));4679 4680 showProgress(progress);4681 HRESULT result;4682 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));4683 if (FAILED(result))4684 {4685 com::ProgressErrorInfo info(progress);4686 PRINT_ERROR_INFO(info);4687 rc = result;4688 }4689 }4690 while (0);4691 4692 return SUCCEEDED(rc) ? 0 : 1;4693 }4694 #endif /* RT_OS_WINDOWS */4695 4696 static int handleGetExtraData(int argc, char *argv[],4697 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4698 {4699 HRESULT rc = S_OK;4700 4701 if (argc != 2)4702 return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");4703 4704 /* global data? */4705 if (strcmp(argv[0], "global") == 0)4706 {4707 /* enumeration? */4708 if (strcmp(argv[1], "enumerate") == 0)4709 {4710 Bstr extraDataKey;4711 4712 do4713 {4714 Bstr nextExtraDataKey;4715 Bstr nextExtraDataValue;4716 HRESULT rcEnum = virtualBox->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),4717 nextExtraDataValue.asOutParam());4718 extraDataKey = nextExtraDataKey;4719 4720 if (SUCCEEDED(rcEnum) && extraDataKey)4721 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());4722 } while (extraDataKey);4723 }4724 else4725 {4726 Bstr value;4727 CHECK_ERROR(virtualBox, GetExtraData(Bstr(argv[1]), value.asOutParam()));4728 if (value)4729 RTPrintf("Value: %lS\n", value.raw());4730 else4731 RTPrintf("No value set!\n");4732 }4733 }4734 else4735 {4736 ComPtr<IMachine> machine;4737 /* assume it's a UUID */4738 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());4739 if (FAILED(rc) || !machine)4740 {4741 /* must be a name */4742 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));4743 }4744 if (machine)4745 {4746 /* enumeration? */4747 if (strcmp(argv[1], "enumerate") == 0)4748 {4749 Bstr extraDataKey;4750 4751 do4752 {4753 Bstr nextExtraDataKey;4754 Bstr nextExtraDataValue;4755 HRESULT rcEnum = machine->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),4756 nextExtraDataValue.asOutParam());4757 extraDataKey = nextExtraDataKey;4758 4759 if (SUCCEEDED(rcEnum) && extraDataKey)4760 {4761 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());4762 }4763 } while (extraDataKey);4764 }4765 else4766 {4767 Bstr value;4768 CHECK_ERROR(machine, GetExtraData(Bstr(argv[1]), value.asOutParam()));4769 if (value)4770 RTPrintf("Value: %lS\n", value.raw());4771 else4772 RTPrintf("No value set!\n");4773 }4774 }4775 }4776 return SUCCEEDED(rc) ? 0 : 1;4777 }4778 4779 static int handleSetExtraData(int argc, char *argv[],4780 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4781 {4782 HRESULT rc = S_OK;4783 4784 if (argc < 2)4785 return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");4786 4787 /* global data? */4788 if (strcmp(argv[0], "global") == 0)4789 {4790 if (argc < 3)4791 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), NULL));4792 else if (argc == 3)4793 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));4794 else4795 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");4796 }4797 else4798 {4799 ComPtr<IMachine> machine;4800 /* assume it's a UUID */4801 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());4802 if (FAILED(rc) || !machine)4803 {4804 /* must be a name */4805 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));4806 }4807 if (machine)4808 {4809 if (argc < 3)4810 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), NULL));4811 else if (argc == 3)4812 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));4813 else4814 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");4815 }4816 }4817 return SUCCEEDED(rc) ? 0 : 1;4818 }4819 4820 static int handleSetProperty(int argc, char *argv[],4821 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)4822 {4823 HRESULT rc;4824 4825 /* there must be two arguments: property name and value */4826 if (argc != 2)4827 return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");4828 4829 ComPtr<ISystemProperties> systemProperties;4830 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());4831 4832 if (strcmp(argv[0], "hdfolder") == 0)4833 {4834 /* reset to default? */4835 if (strcmp(argv[1], "default") == 0)4836 CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(NULL));4837 else4838 CHECK_ERROR(systemProperties, COMSETTER(DefaultHardDiskFolder)(Bstr(argv[1])));4839 }4840 else if (strcmp(argv[0], "machinefolder") == 0)4841 {4842 /* reset to default? */4843 if (strcmp(argv[1], "default") == 0)4844 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));4845 else4846 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(argv[1])));4847 }4848 else if (strcmp(argv[0], "vrdpauthlibrary") == 0)4849 {4850 /* reset to default? */4851 if (strcmp(argv[1], "default") == 0)4852 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));4853 else4854 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(argv[1])));4855 }4856 else if (strcmp(argv[0], "websrvauthlibrary") == 0)4857 {4858 /* reset to default? */4859 if (strcmp(argv[1], "default") == 0)4860 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));4861 else4862 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(argv[1])));4863 }4864 else if (strcmp(argv[0], "hwvirtexenabled") == 0)4865 {4866 if (strcmp(argv[1], "yes") == 0)4867 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(TRUE));4868 else if (strcmp(argv[1], "no") == 0)4869 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(FALSE));4870 else4871 return errorArgument("Invalid value '%s' for hardware virtualization extension flag", argv[1]);4872 }4873 else if (strcmp(argv[0], "loghistorycount") == 0)4874 {4875 uint32_t uVal;4876 int vrc;4877 vrc = RTStrToUInt32Ex(argv[1], NULL, 0, &uVal);4878 if (vrc != VINF_SUCCESS)4879 return errorArgument("Error parsing Log history count '%s'", argv[1]);4880 CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));4881 }4882 else4883 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", argv[0]);4884 4885 return SUCCEEDED(rc) ? 0 : 1;4886 }4887 4888 static int handleUSBFilter (int argc, char *argv[],4889 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)4890 {4891 HRESULT rc = S_OK;4892 USBFilterCmd cmd;4893 4894 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */4895 if (argc < 4)4896 return errorSyntax(USAGE_USBFILTER, "Not enough parameters");4897 4898 /* which command? */4899 cmd.mAction = USBFilterCmd::Invalid;4900 if (strcmp (argv [0], "add") == 0) cmd.mAction = USBFilterCmd::Add;4901 else if (strcmp (argv [0], "modify") == 0) cmd.mAction = USBFilterCmd::Modify;4902 else if (strcmp (argv [0], "remove") == 0) cmd.mAction = USBFilterCmd::Remove;4903 4904 if (cmd.mAction == USBFilterCmd::Invalid)4905 return errorSyntax(USAGE_USBFILTER, "Invalid parameter '%s'", argv[0]);4906 4907 /* which index? */4908 if (VINF_SUCCESS != RTStrToUInt32Full (argv[1], 10, &cmd.mIndex))4909 return errorSyntax(USAGE_USBFILTER, "Invalid index '%s'", argv[1]);4910 4911 switch (cmd.mAction)4912 {4913 case USBFilterCmd::Add:4914 case USBFilterCmd::Modify:4915 {4916 /* at least: 0: command, 1: index, 2: -target, 3: <target value>, 4: -name, 5: <name value> */4917 if (argc < 6)4918 {4919 if (cmd.mAction == USBFilterCmd::Add)4920 return errorSyntax(USAGE_USBFILTER_ADD, "Not enough parameters");4921 4922 return errorSyntax(USAGE_USBFILTER_MODIFY, "Not enough parameters");4923 }4924 4925 // set Active to true by default4926 // (assuming that the user sets up all necessary attributes4927 // at once and wants the filter to be active immediately)4928 if (cmd.mAction == USBFilterCmd::Add)4929 cmd.mFilter.mActive = true;4930 4931 for (int i = 2; i < argc; i++)4932 {4933 if (strcmp(argv [i], "-target") == 0)4934 {4935 if (argc <= i + 1 || !*argv[i+1])4936 return errorArgument("Missing argument to '%s'", argv[i]);4937 i++;4938 if (strcmp (argv [i], "global") == 0)4939 cmd.mGlobal = true;4940 else4941 {4942 /* assume it's a UUID of a machine */4943 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());4944 if (FAILED(rc) || !cmd.mMachine)4945 {4946 /* must be a name */4947 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);4948 }4949 }4950 }4951 else if (strcmp(argv [i], "-name") == 0)4952 {4953 if (argc <= i + 1 || !*argv[i+1])4954 return errorArgument("Missing argument to '%s'", argv[i]);4955 i++;4956 cmd.mFilter.mName = argv [i];4957 }4958 else if (strcmp(argv [i], "-active") == 0)4959 {4960 if (argc <= i + 1)4961 return errorArgument("Missing argument to '%s'", argv[i]);4962 i++;4963 if (strcmp (argv [i], "yes") == 0)4964 cmd.mFilter.mActive = true;4965 else if (strcmp (argv [i], "no") == 0)4966 cmd.mFilter.mActive = false;4967 else4968 return errorArgument("Invalid -active argument '%s'", argv[i]);4969 }4970 else if (strcmp(argv [i], "-vendorid") == 0)4971 {4972 if (argc <= i + 1)4973 return errorArgument("Missing argument to '%s'", argv[i]);4974 i++;4975 cmd.mFilter.mVendorId = argv [i];4976 }4977 else if (strcmp(argv [i], "-productid") == 0)4978 {4979 if (argc <= i + 1)4980 return errorArgument("Missing argument to '%s'", argv[i]);4981 i++;4982 cmd.mFilter.mProductId = argv [i];4983 }4984 else if (strcmp(argv [i], "-revision") == 0)4985 {4986 if (argc <= i + 1)4987 return errorArgument("Missing argument to '%s'", argv[i]);4988 i++;4989 cmd.mFilter.mRevision = argv [i];4990 }4991 else if (strcmp(argv [i], "-manufacturer") == 0)4992 {4993 if (argc <= i + 1)4994 return errorArgument("Missing argument to '%s'", argv[i]);4995 i++;4996 cmd.mFilter.mManufacturer = argv [i];4997 }4998 else if (strcmp(argv [i], "-product") == 0)4999 {5000 if (argc <= i + 1)5001 return errorArgument("Missing argument to '%s'", argv[i]);5002 i++;5003 cmd.mFilter.mProduct = argv [i];5004 }5005 else if (strcmp(argv [i], "-remote") == 0)5006 {5007 if (argc <= i + 1)5008 return errorArgument("Missing argument to '%s'", argv[i]);5009 i++;5010 cmd.mFilter.mRemote = argv[i];5011 }5012 else if (strcmp(argv [i], "-serialnumber") == 0)5013 {5014 if (argc <= i + 1)5015 return errorArgument("Missing argument to '%s'", argv[i]);5016 i++;5017 cmd.mFilter.mSerialNumber = argv [i];5018 }5019 else if (strcmp(argv [i], "-maskedinterfaces") == 0)5020 {5021 if (argc <= i + 1)5022 return errorArgument("Missing argument to '%s'", argv[i]);5023 i++;5024 uint32_t u32;5025 rc = RTStrToUInt32Full(argv[i], 0, &u32);5026 if (RT_FAILURE(rc))5027 return errorArgument("Failed to convert the -maskedinterfaces value '%s' to a number, rc=%Rrc", argv[i], rc);5028 cmd.mFilter.mMaskedInterfaces = u32;5029 }5030 else if (strcmp(argv [i], "-action") == 0)5031 {5032 if (argc <= i + 1)5033 return errorArgument("Missing argument to '%s'", argv[i]);5034 i++;5035 if (strcmp (argv [i], "ignore") == 0)5036 cmd.mFilter.mAction = USBDeviceFilterAction_Ignore;5037 else if (strcmp (argv [i], "hold") == 0)5038 cmd.mFilter.mAction = USBDeviceFilterAction_Hold;5039 else5040 return errorArgument("Invalid USB filter action '%s'", argv[i]);5041 }5042 else5043 return errorSyntax(cmd.mAction == USBFilterCmd::Add ? USAGE_USBFILTER_ADD : USAGE_USBFILTER_MODIFY,5044 "Unknown option '%s'", argv[i]);5045 }5046 5047 if (cmd.mAction == USBFilterCmd::Add)5048 {5049 // mandatory/forbidden options5050 if ( cmd.mFilter.mName.isEmpty()5051 ||5052 ( cmd.mGlobal5053 && cmd.mFilter.mAction == USBDeviceFilterAction_Null5054 )5055 || ( !cmd.mGlobal5056 && !cmd.mMachine)5057 || ( cmd.mGlobal5058 && cmd.mFilter.mRemote)5059 )5060 {5061 return errorSyntax(USAGE_USBFILTER_ADD, "Mandatory options not supplied");5062 }5063 }5064 break;5065 }5066 5067 case USBFilterCmd::Remove:5068 {5069 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */5070 if (argc < 4)5071 return errorSyntax(USAGE_USBFILTER_REMOVE, "Not enough parameters");5072 5073 for (int i = 2; i < argc; i++)5074 {5075 if (strcmp(argv [i], "-target") == 0)5076 {5077 if (argc <= i + 1 || !*argv[i+1])5078 return errorArgument("Missing argument to '%s'", argv[i]);5079 i++;5080 if (strcmp (argv [i], "global") == 0)5081 cmd.mGlobal = true;5082 else5083 {5084 /* assume it's a UUID of a machine */5085 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());5086 if (FAILED(rc) || !cmd.mMachine)5087 {5088 /* must be a name */5089 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);5090 }5091 }5092 }5093 }5094 5095 // mandatory options5096 if (!cmd.mGlobal && !cmd.mMachine)5097 return errorSyntax(USAGE_USBFILTER_REMOVE, "Mandatory options not supplied");5098 5099 break;5100 }5101 5102 default: break;5103 }5104 5105 USBFilterCmd::USBFilter &f = cmd.mFilter;5106 5107 ComPtr <IHost> host;5108 ComPtr <IUSBController> ctl;5109 if (cmd.mGlobal)5110 CHECK_ERROR_RET (aVirtualBox, COMGETTER(Host) (host.asOutParam()), 1);5111 else5112 {5113 Guid uuid;5114 cmd.mMachine->COMGETTER(Id)(uuid.asOutParam());5115 /* open a session for the VM */5116 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);5117 /* get the mutable session machine */5118 aSession->COMGETTER(Machine)(cmd.mMachine.asOutParam());5119 /* and get the USB controller */5120 CHECK_ERROR_RET (cmd.mMachine, COMGETTER(USBController) (ctl.asOutParam()), 1);5121 }5122 5123 switch (cmd.mAction)5124 {5125 case USBFilterCmd::Add:5126 {5127 if (cmd.mGlobal)5128 {5129 ComPtr <IHostUSBDeviceFilter> flt;5130 CHECK_ERROR_BREAK (host, CreateUSBDeviceFilter (f.mName, flt.asOutParam()));5131 5132 if (!f.mActive.isNull())5133 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));5134 if (!f.mVendorId.isNull())5135 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));5136 if (!f.mProductId.isNull())5137 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));5138 if (!f.mRevision.isNull())5139 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));5140 if (!f.mManufacturer.isNull())5141 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));5142 if (!f.mSerialNumber.isNull())5143 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));5144 if (!f.mMaskedInterfaces.isNull())5145 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));5146 5147 if (f.mAction != USBDeviceFilterAction_Null)5148 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));5149 5150 CHECK_ERROR_BREAK (host, InsertUSBDeviceFilter (cmd.mIndex, flt));5151 }5152 else5153 {5154 ComPtr <IUSBDeviceFilter> flt;5155 CHECK_ERROR_BREAK (ctl, CreateDeviceFilter (f.mName, flt.asOutParam()));5156 5157 if (!f.mActive.isNull())5158 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));5159 if (!f.mVendorId.isNull())5160 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));5161 if (!f.mProductId.isNull())5162 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));5163 if (!f.mRevision.isNull())5164 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));5165 if (!f.mManufacturer.isNull())5166 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));5167 if (!f.mRemote.isNull())5168 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));5169 if (!f.mSerialNumber.isNull())5170 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));5171 if (!f.mMaskedInterfaces.isNull())5172 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));5173 5174 CHECK_ERROR_BREAK (ctl, InsertDeviceFilter (cmd.mIndex, flt));5175 }5176 break;5177 }5178 case USBFilterCmd::Modify:5179 {5180 if (cmd.mGlobal)5181 {5182 ComPtr <IHostUSBDeviceFilterCollection> coll;5183 CHECK_ERROR_BREAK (host, COMGETTER(USBDeviceFilters) (coll.asOutParam()));5184 ComPtr <IHostUSBDeviceFilter> flt;5185 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));5186 5187 if (!f.mName.isNull())5188 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));5189 if (!f.mActive.isNull())5190 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));5191 if (!f.mVendorId.isNull())5192 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));5193 if (!f.mProductId.isNull())5194 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));5195 if (!f.mRevision.isNull())5196 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));5197 if (!f.mManufacturer.isNull())5198 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));5199 if (!f.mSerialNumber.isNull())5200 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));5201 if (!f.mMaskedInterfaces.isNull())5202 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));5203 5204 if (f.mAction != USBDeviceFilterAction_Null)5205 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));5206 }5207 else5208 {5209 ComPtr <IUSBDeviceFilterCollection> coll;5210 CHECK_ERROR_BREAK (ctl, COMGETTER(DeviceFilters) (coll.asOutParam()));5211 5212 ComPtr <IUSBDeviceFilter> flt;5213 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));5214 5215 if (!f.mName.isNull())5216 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));5217 if (!f.mActive.isNull())5218 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));5219 if (!f.mVendorId.isNull())5220 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));5221 if (!f.mProductId.isNull())5222 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));5223 if (!f.mRevision.isNull())5224 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));5225 if (!f.mManufacturer.isNull())5226 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));5227 if (!f.mRemote.isNull())5228 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));5229 if (!f.mSerialNumber.isNull())5230 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));5231 if (!f.mMaskedInterfaces.isNull())5232 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));5233 }5234 break;5235 }5236 case USBFilterCmd::Remove:5237 {5238 if (cmd.mGlobal)5239 {5240 ComPtr <IHostUSBDeviceFilter> flt;5241 CHECK_ERROR_BREAK (host, RemoveUSBDeviceFilter (cmd.mIndex, flt.asOutParam()));5242 }5243 else5244 {5245 ComPtr <IUSBDeviceFilter> flt;5246 CHECK_ERROR_BREAK (ctl, RemoveDeviceFilter (cmd.mIndex, flt.asOutParam()));5247 }5248 break;5249 }5250 default:5251 break;5252 }5253 5254 if (cmd.mMachine)5255 {5256 /* commit and close the session */5257 CHECK_ERROR(cmd.mMachine, SaveSettings());5258 aSession->Close();5259 }5260 5261 return SUCCEEDED (rc) ? 0 : 1;5262 }5263 5264 static int handleSharedFolder (int argc, char *argv[],5265 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)5266 {5267 HRESULT rc;5268 5269 /* we need at least a command and target */5270 if (argc < 2)5271 return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");5272 5273 ComPtr<IMachine> machine;5274 /* assume it's a UUID */5275 rc = aVirtualBox->GetMachine(Guid(argv[1]), machine.asOutParam());5276 if (FAILED(rc) || !machine)5277 {5278 /* must be a name */5279 CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[1]), machine.asOutParam()));5280 }5281 if (!machine)5282 return 1;5283 Guid uuid;5284 machine->COMGETTER(Id)(uuid.asOutParam());5285 5286 if (strcmp(argv[0], "add") == 0)5287 {5288 /* we need at least four more parameters */5289 if (argc < 5)5290 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");5291 5292 char *name = NULL;5293 char *hostpath = NULL;5294 bool fTransient = false;5295 bool fWritable = true;5296 5297 for (int i = 2; i < argc; i++)5298 {5299 if (strcmp(argv[i], "-name") == 0)5300 {5301 if (argc <= i + 1 || !*argv[i+1])5302 return errorArgument("Missing argument to '%s'", argv[i]);5303 i++;5304 name = argv[i];5305 }5306 else if (strcmp(argv[i], "-hostpath") == 0)5307 {5308 if (argc <= i + 1 || !*argv[i+1])5309 return errorArgument("Missing argument to '%s'", argv[i]);5310 i++;5311 hostpath = argv[i];5312 }5313 else if (strcmp(argv[i], "-readonly") == 0)5314 {5315 fWritable = false;5316 }5317 else if (strcmp(argv[i], "-transient") == 0)5318 {5319 fTransient = true;5320 }5321 else5322 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());5323 }5324 5325 if (NULL != strstr(name, " "))5326 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");5327 5328 /* required arguments */5329 if (!name || !hostpath)5330 {5331 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters -name and -hostpath are required");5332 }5333 5334 if (fTransient)5335 {5336 ComPtr <IConsole> console;5337 5338 /* open an existing session for the VM */5339 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);5340 /* get the session machine */5341 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);5342 /* get the session console */5343 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);5344 5345 CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));5346 5347 if (console)5348 aSession->Close();5349 }5350 else5351 {5352 /* open a session for the VM */5353 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);5354 5355 /* get the mutable session machine */5356 aSession->COMGETTER(Machine)(machine.asOutParam());5357 5358 CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));5359 5360 if (SUCCEEDED(rc))5361 CHECK_ERROR(machine, SaveSettings());5362 5363 aSession->Close();5364 }5365 }5366 else if (strcmp(argv[0], "remove") == 0)5367 {5368 /* we need at least two more parameters */5369 if (argc < 3)5370 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");5371 5372 char *name = NULL;5373 bool fTransient = false;5374 5375 for (int i = 2; i < argc; i++)5376 {5377 if (strcmp(argv[i], "-name") == 0)5378 {5379 if (argc <= i + 1 || !*argv[i+1])5380 return errorArgument("Missing argument to '%s'", argv[i]);5381 i++;5382 name = argv[i];5383 }5384 else if (strcmp(argv[i], "-transient") == 0)5385 {5386 fTransient = true;5387 }5388 else5389 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());5390 }5391 5392 /* required arguments */5393 if (!name)5394 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter -name is required");5395 5396 if (fTransient)5397 {5398 ComPtr <IConsole> console;5399 5400 /* open an existing session for the VM */5401 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);5402 /* get the session machine */5403 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);5404 /* get the session console */5405 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);5406 5407 CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));5408 5409 if (console)5410 aSession->Close();5411 }5412 else5413 {5414 /* open a session for the VM */5415 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);5416 5417 /* get the mutable session machine */5418 aSession->COMGETTER(Machine)(machine.asOutParam());5419 5420 CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));5421 5422 /* commit and close the session */5423 CHECK_ERROR(machine, SaveSettings());5424 aSession->Close();5425 }5426 }5427 else5428 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());5429 5430 return 0;5431 }5432 5433 static int handleVMStatistics(int argc, char *argv[],5434 ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)5435 {5436 HRESULT rc;5437 5438 /* at least one option: the UUID or name of the VM */5439 if (argc < 1)5440 return errorSyntax(USAGE_VM_STATISTICS, "Incorrect number of parameters");5441 5442 /* try to find the given machine */5443 ComPtr <IMachine> machine;5444 Guid uuid (argv[0]);5445 if (!uuid.isEmpty())5446 CHECK_ERROR(aVirtualBox, GetMachine(uuid, machine.asOutParam()));5447 else5448 {5449 CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));5450 if (SUCCEEDED (rc))5451 machine->COMGETTER(Id)(uuid.asOutParam());5452 }5453 if (FAILED(rc))5454 return 1;5455 5456 /* parse arguments. */5457 bool fReset = false;5458 bool fWithDescriptions = false;5459 const char *pszPattern = NULL; /* all */5460 for (int i = 1; i < argc; i++)5461 {5462 if (!strcmp(argv[i], "-pattern"))5463 {5464 if (pszPattern)5465 return errorSyntax(USAGE_VM_STATISTICS, "Multiple -patterns options is not permitted");5466 if (i + 1 >= argc)5467 return errorArgument("Missing argument to '%s'", argv[i]);5468 pszPattern = argv[++i];5469 }5470 else if (!strcmp(argv[i], "-descriptions"))5471 fWithDescriptions = true;5472 /* add: -file <filename> and -formatted */5473 else if (!strcmp(argv[i], "-reset"))5474 fReset = true;5475 else5476 return errorSyntax(USAGE_VM_STATISTICS, "Unknown option '%s'", argv[i]);5477 }5478 if (fReset && fWithDescriptions)5479 return errorSyntax(USAGE_VM_STATISTICS, "The -reset and -descriptions options does not mix");5480 5481 5482 /* open an existing session for the VM. */5483 CHECK_ERROR(aVirtualBox, OpenExistingSession(aSession, uuid));5484 if (SUCCEEDED(rc))5485 {5486 /* get the session console. */5487 ComPtr <IConsole> console;5488 CHECK_ERROR(aSession, COMGETTER(Console)(console.asOutParam()));5489 if (SUCCEEDED(rc))5490 {5491 /* get the machine debugger. */5492 ComPtr <IMachineDebugger> debugger;5493 CHECK_ERROR(console, COMGETTER(Debugger)(debugger.asOutParam()));5494 if (SUCCEEDED(rc))5495 {5496 if (fReset)5497 CHECK_ERROR(debugger, ResetStats(Bstr(pszPattern)));5498 else5499 {5500 Bstr stats;5501 CHECK_ERROR(debugger, GetStats(Bstr(pszPattern), fWithDescriptions, stats.asOutParam()));5502 if (SUCCEEDED(rc))5503 {5504 /* if (fFormatted)5505 { big mess }5506 else5507 */5508 RTPrintf("%ls\n", stats.raw());5509 }5510 }5511 }5512 aSession->Close();5513 }5514 }5515 5516 return SUCCEEDED(rc) ? 0 : 1;5517 }5518 1044 #endif /* !VBOX_ONLY_DOCS */ 5519 5520 enum ConvertSettings5521 {5522 ConvertSettings_No = 0,5523 ConvertSettings_Yes = 1,5524 ConvertSettings_Backup = 2,5525 ConvertSettings_Ignore = 3,5526 };5527 5528 #ifndef VBOX_ONLY_DOCS5529 /**5530 * Checks if any of the settings files were auto-converted and informs the5531 * user if so.5532 *5533 * @return @false if the program should terminate and @true otherwise.5534 */5535 static bool checkForAutoConvertedSettings (ComPtr<IVirtualBox> virtualBox,5536 ComPtr<ISession> session,5537 ConvertSettings fConvertSettings)5538 {5539 /* return early if nothing to do */5540 if (fConvertSettings == ConvertSettings_Ignore)5541 return true;5542 5543 HRESULT rc;5544 5545 do5546 {5547 Bstr formatVersion;5548 CHECK_RC_BREAK (virtualBox->5549 COMGETTER(SettingsFormatVersion) (formatVersion.asOutParam()));5550 5551 bool isGlobalConverted = false;5552 std::list <ComPtr <IMachine> > cvtMachines;5553 std::list <Utf8Str> fileList;5554 Bstr version;5555 Bstr filePath;5556 5557 com::SafeIfaceArray <IMachine> machines;5558 CHECK_RC_BREAK (virtualBox->5559 COMGETTER(Machines2) (ComSafeArrayAsOutParam (machines)));5560 5561 for (size_t i = 0; i < machines.size(); ++ i)5562 {5563 BOOL accessible;5564 CHECK_RC_BREAK (machines [i]->5565 COMGETTER(Accessible) (&accessible));5566 if (!accessible)5567 continue;5568 5569 CHECK_RC_BREAK (machines [i]->5570 COMGETTER(SettingsFileVersion) (version.asOutParam()));5571 5572 if (version != formatVersion)5573 {5574 cvtMachines.push_back (machines [i]);5575 Bstr filePath;5576 CHECK_RC_BREAK (machines [i]->5577 COMGETTER(SettingsFilePath) (filePath.asOutParam()));5578 fileList.push_back (Utf8StrFmt ("%ls (%ls)", filePath.raw(),5579 version.raw()));5580 }5581 }5582 5583 CHECK_RC_BREAK (rc);5584 5585 CHECK_RC_BREAK (virtualBox->5586 COMGETTER(SettingsFileVersion) (version.asOutParam()));5587 if (version != formatVersion)5588 {5589 isGlobalConverted = true;5590 CHECK_RC_BREAK (virtualBox->5591 COMGETTER(SettingsFilePath) (filePath.asOutParam()));5592 fileList.push_back (Utf8StrFmt ("%ls (%ls)", filePath.raw(),5593 version.raw()));5594 }5595 5596 if (fileList.size() > 0)5597 {5598 switch (fConvertSettings)5599 {5600 case ConvertSettings_No:5601 {5602 RTPrintf (5603 "WARNING! The following VirtualBox settings files have been automatically\n"5604 "converted to the new settings file format version '%ls':\n"5605 "\n",5606 formatVersion.raw());5607 5608 for (std::list <Utf8Str>::const_iterator f = fileList.begin();5609 f != fileList.end(); ++ f)5610 RTPrintf (" %S\n", (*f).raw());5611 RTPrintf (5612 "\n"5613 "The current command was aborted to prevent overwriting the above settings\n"5614 "files with the results of the auto-conversion without your permission.\n"5615 "Please put one of the following command line switches to the beginning of\n"5616 "the VBoxManage command line and repeat the command:\n"5617 "\n"5618 " -convertSettings - to save all auto-converted files (it will not\n"5619 " be possible to use these settings files with an\n"5620 " older version of VirtualBox in the future);\n"5621 " -convertSettingsBackup - to create backup copies of the settings files in\n"5622 " the old format before saving them in the new format;\n"5623 " -convertSettingsIgnore - to not save the auto-converted settings files.\n"5624 "\n"5625 "Note that if you use -convertSettingsIgnore, the auto-converted settings files\n"5626 "will be implicitly saved in the new format anyway once you change a setting or\n"5627 "start a virtual machine, but NO backup copies will be created in this case.\n");5628 return false;5629 }5630 case ConvertSettings_Yes:5631 case ConvertSettings_Backup:5632 {5633 break;5634 }5635 default:5636 AssertFailedReturn (false);5637 }5638 5639 for (std::list <ComPtr <IMachine> >::const_iterator m = cvtMachines.begin();5640 m != cvtMachines.end(); ++ m)5641 {5642 Guid id;5643 CHECK_RC_BREAK ((*m)->COMGETTER(Id) (id.asOutParam()));5644 5645 /* open a session for the VM */5646 CHECK_ERROR_BREAK (virtualBox, OpenSession (session, id));5647 5648 ComPtr <IMachine> sm;5649 CHECK_RC_BREAK (session->COMGETTER(Machine) (sm.asOutParam()));5650 5651 Bstr bakFileName;5652 if (fConvertSettings == ConvertSettings_Backup)5653 CHECK_ERROR (sm, SaveSettingsWithBackup (bakFileName.asOutParam()));5654 else5655 CHECK_ERROR (sm, SaveSettings());5656 5657 session->Close();5658 5659 CHECK_RC_BREAK (rc);5660 }5661 5662 CHECK_RC_BREAK (rc);5663 5664 if (isGlobalConverted)5665 {5666 Bstr bakFileName;5667 if (fConvertSettings == ConvertSettings_Backup)5668 CHECK_ERROR (virtualBox, SaveSettingsWithBackup (bakFileName.asOutParam()));5669 else5670 CHECK_ERROR (virtualBox, SaveSettings());5671 }5672 5673 CHECK_RC_BREAK (rc);5674 }5675 }5676 while (0);5677 5678 return SUCCEEDED (rc);5679 }5680 #endif /* !VBOX_ONLY_DOCS */5681 5682 // main5683 ///////////////////////////////////////////////////////////////////////////////5684 5685 int main(int argc, char *argv[])5686 {5687 /*5688 * Before we do anything, init the runtime without loading5689 * the support driver.5690 */5691 RTR3Init();5692 5693 bool fShowLogo = true;5694 int iCmd = 1;5695 int iCmdArg;5696 5697 ConvertSettings fConvertSettings = ConvertSettings_No;5698 5699 /* global options */5700 for (int i = 1; i < argc || argc <= iCmd; i++)5701 {5702 if ( argc <= iCmd5703 || (strcmp(argv[i], "help") == 0)5704 || (strcmp(argv[i], "-?") == 0)5705 || (strcmp(argv[i], "-h") == 0)5706 || (strcmp(argv[i], "-help") == 0)5707 || (strcmp(argv[i], "--help") == 0))5708 {5709 showLogo();5710 printUsage(USAGE_ALL);5711 return 0;5712 }5713 else if ( strcmp(argv[i], "-v") == 05714 || strcmp(argv[i], "-version") == 05715 || strcmp(argv[i], "-Version") == 05716 || strcmp(argv[i], "--version") == 0)5717 {5718 /* Print version number, and do nothing else. */5719 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBoxSVNRev ());5720 return 0;5721 }5722 else if (strcmp(argv[i], "-dumpopts") == 0)5723 {5724 /* Special option to dump really all commands,5725 * even the ones not understood on this platform. */5726 printUsage(USAGE_DUMPOPTS);5727 return 0;5728 }5729 else if (strcmp(argv[i], "-nologo") == 0)5730 {5731 /* suppress the logo */5732 fShowLogo = false;5733 iCmd++;5734 }5735 else if (strcmp(argv[i], "-convertSettings") == 0)5736 {5737 fConvertSettings = ConvertSettings_Yes;5738 iCmd++;5739 }5740 else if (strcmp(argv[i], "-convertSettingsBackup") == 0)5741 {5742 fConvertSettings = ConvertSettings_Backup;5743 iCmd++;5744 }5745 else if (strcmp(argv[i], "-convertSettingsIgnore") == 0)5746 {5747 fConvertSettings = ConvertSettings_Ignore;5748 iCmd++;5749 }5750 else5751 {5752 break;5753 }5754 }5755 5756 iCmdArg = iCmd + 1;5757 5758 if (fShowLogo)5759 showLogo();5760 5761 5762 #ifdef VBOX_ONLY_DOCS5763 int rc = 0;5764 #else /* !VBOX_ONLY_DOCS */5765 HRESULT rc = 0;5766 5767 CHECK_RC_RET (com::Initialize());5768 5769 /*5770 * The input is in the host OS'es codepage (NT guarantees ACP).5771 * For VBox we use UTF-8 and convert to UCS-2 when calling (XP)COM APIs.5772 * For simplicity, just convert the argv[] array here.5773 */5774 for (int i = iCmdArg; i < argc; i++)5775 {5776 char *converted;5777 RTStrCurrentCPToUtf8(&converted, argv[i]);5778 argv[i] = converted;5779 }5780 5781 do5782 {5783 // scopes all the stuff till shutdown5784 ////////////////////////////////////////////////////////////////////////////5785 5786 /* converthd: does not need a VirtualBox instantiation. */5787 if (argc >= iCmdArg && (strcmp(argv[iCmd], "converthd") == 0))5788 {5789 rc = handleConvertHardDisk(argc - iCmdArg, argv + iCmdArg);5790 break;5791 }5792 5793 /* convertdd: does not need a VirtualBox instantiation. */5794 if (argc >= iCmdArg && (strcmp(argv[iCmd], "convertdd") == 0))5795 {5796 rc = handleConvertDDImage(argc - iCmdArg, argv + iCmdArg);5797 break;5798 }5799 5800 ComPtr <IVirtualBox> virtualBox;5801 ComPtr <ISession> session;5802 5803 rc = virtualBox.createLocalObject (CLSID_VirtualBox);5804 if (FAILED(rc))5805 {5806 RTPrintf ("[!] Failed to create the VirtualBox object!\n");5807 PRINT_RC_MESSAGE (rc);5808 5809 com::ErrorInfo info;5810 if (!info.isFullAvailable() && !info.isBasicAvailable())5811 RTPrintf ("[!] Most likely, the VirtualBox COM server is not running "5812 "or failed to start.\n");5813 else5814 PRINT_ERROR_INFO (info);5815 break;5816 }5817 5818 CHECK_RC_BREAK (session.createInprocObject (CLSID_Session));5819 5820 /* create the event queue5821 * (here it is necessary only to process remaining XPCOM/IPC events5822 * after the session is closed) */5823 5824 #ifdef USE_XPCOM_QUEUE5825 NS_GetMainEventQ(getter_AddRefs(g_pEventQ));5826 #endif5827 5828 if (!checkForAutoConvertedSettings (virtualBox, session, fConvertSettings))5829 break;5830 5831 /*5832 * All registered command handlers5833 */5834 struct5835 {5836 const char *command;5837 PFNHANDLER handler;5838 } commandHandlers[] =5839 {5840 { "internalcommands", handleInternalCommands },5841 { "list", handleList },5842 { "showvminfo", handleShowVMInfo },5843 { "registervm", handleRegisterVM },5844 { "unregistervm", handleUnregisterVM },5845 { "createhd", handleCreateHardDisk },5846 { "createvdi", handleCreateHardDisk }, /* backward compatiblity */5847 { "modifyhd", handleModifyHardDisk },5848 { "modifyvdi", handleModifyHardDisk }, /* backward compatiblity */5849 { "clonehd", handleCloneHardDisk },5850 { "clonevdi", handleCloneHardDisk }, /* backward compatiblity */5851 { "addiscsidisk", handleAddiSCSIDisk },5852 { "createvm", handleCreateVM },5853 { "modifyvm", handleModifyVM },5854 { "startvm", handleStartVM },5855 { "controlvm", handleControlVM },5856 { "discardstate", handleDiscardState },5857 { "adoptstate", handleAdoptdState },5858 { "snapshot", handleSnapshot },5859 { "openmedium", handleOpenMedium },5860 { "registerimage", handleOpenMedium }, /* backward compatiblity */5861 { "closemedium", handleCloseMedium },5862 { "unregisterimage", handleCloseMedium }, /* backward compatiblity */5863 { "showhdinfo", handleShowHardDiskInfo },5864 { "showvdiinfo", handleShowHardDiskInfo }, /* backward compatiblity */5865 #ifdef RT_OS_WINDOWS5866 { "createhostif", handleCreateHostIF },5867 { "removehostif", handleRemoveHostIF },5868 #endif5869 { "getextradata", handleGetExtraData },5870 { "setextradata", handleSetExtraData },5871 { "setproperty", handleSetProperty },5872 { "usbfilter", handleUSBFilter },5873 { "sharedfolder", handleSharedFolder },5874 { "vmstatistics", handleVMStatistics },5875 #ifdef VBOX_WITH_GUEST_PROPS5876 { "guestproperty", handleGuestProperty },5877 #endif /* VBOX_WITH_GUEST_PROPS defined */5878 { "metrics", handleMetrics },5879 { NULL, NULL }5880 };5881 5882 int commandIndex;5883 for (commandIndex = 0; commandHandlers[commandIndex].command != NULL; commandIndex++)5884 {5885 if (strcmp(commandHandlers[commandIndex].command, argv[iCmd]) == 0)5886 {5887 rc = commandHandlers[commandIndex].handler(argc - iCmdArg, &argv[iCmdArg], virtualBox, session);5888 break;5889 }5890 }5891 if (!commandHandlers[commandIndex].command)5892 {5893 rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).raw());5894 }5895 5896 /* Although all handlers should always close the session if they open it,5897 * we do it here just in case if some of the handlers contains a bug --5898 * leaving the direct session not closed will turn the machine state to5899 * Aborted which may have unwanted side effects like killing the saved5900 * state file (if the machine was in the Saved state before). */5901 session->Close();5902 5903 #ifdef USE_XPCOM_QUEUE5904 g_pEventQ->ProcessPendingEvents();5905 #endif5906 5907 // end "all-stuff" scope5908 ////////////////////////////////////////////////////////////////////////////5909 }5910 while (0);5911 5912 com::Shutdown();5913 #endif /* !VBOX_ONLY_DOCS */5914 5915 /*5916 * Free converted argument vector5917 */5918 for (int i = iCmdArg; i < argc; i++)5919 RTStrFree(argv[i]);5920 5921 return rc != 0;5922 }
Note:
See TracChangeset
for help on using the changeset viewer.