VirtualBox

Ignore:
Timestamp:
Dec 15, 2008 10:36:07 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
40959
Message:

VBoxManage: split off various disk handling commands.

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

Legend:

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

    r15235 r15492  
    4747        VBoxManageMetrics.cpp \
    4848        VBoxManageList.cpp \
     49        VBoxManageDisk.cpp \
    4950        VBoxInternalManage.cpp \
    5051        $(if $(VBOX_WITH_GUEST_PROPS),VBoxManageGuestProp.cpp) \
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r15489 r15492  
    5454#include <iprt/uuid.h>
    5555#include <VBox/version.h>
    56 #include <VBox/VBoxHDD-new.h>
    5756#include <VBox/log.h>
    5857
     
    729728 * Print out progress on the console
    730729 */
    731 static void showProgress(ComPtr<IProgress> progress)
     730void showProgress(ComPtr<IProgress> progress)
    732731{
    733732    BOOL fCompleted;
     
    825824        }
    826825    }
    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         else
    899             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 successfully
    913          * 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         else
    923         {
    924             CHECK_ERROR(hardDisk, CreateDynamicStorage(sizeMB, progress.asOutParam()));
    925         }
    926         if (SUCCEEDED(rc) && progress)
    927         {
    928             if (fStatic)
    929                 showProgress(progress);
    930             else
    931                 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                     else
    941                         RTPrintf("Error: failed to create hard disk. No error message available!\n");
    942                 }
    943                 else
    944                 {
    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 #endif
    988 
    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             else
    1045             {
    1046                 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
    1047             }
    1048         }
    1049         else
    1050             return errorArgument("Hard disk image not registered");
    1051     }
    1052     else if (strcmp(argv[1], "compact") == 0)
    1053     {
    1054 #if 1
    1055         RTPrintf("Error: Shrink hard disk operation is temporarily unavailable!\n");
    1056         return 1;
    1057 #else
    1058         /* 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 #endif
    1087     }
    1088     else
    1089         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 1
    1098     RTPrintf("Error: Clone hard disk operation is temporarily unavailable!\n");
    1099     return 1;
    1100 #else
    1101     /// @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                 else
    1133                 {
    1134                     RTPrintf("Error: failed to clone disk image. No error message available!\n");
    1135                 }
    1136             }
    1137         }
    1138     }
    1139     return SUCCEEDED(rc) ? 0 : 1;
    1140 #endif
    1141 }
    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         else
    1183         {
    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     do
    1206     {
    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         else
    1296         {
    1297             if (srcfilename)
    1298             {
    1299                 if (dstfilename)
    1300                 {
    1301                     if (fReadFromStdIn && !filesize)
    1302                         filesize = argv[i];
    1303                     else
    1304                         return errorSyntax(USAGE_CONVERTDD, "Incorrect number of parameters");
    1305                 }
    1306                 else
    1307                     dstfilename = argv[i];
    1308             }
    1309             else
    1310             {
    1311                 srcfilename = argv[i];
    1312 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
    1313                 fReadFromStdIn = !strcmp(srcfilename, "stdin");
    1314 #endif
    1315             }
    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     else
    1341         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     else
    1353         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         else
    1513             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     do
    1521     {
    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 option
    1560         Bstr ("InitiatorName").detachTo (names.appendedRaw());
    1561         Bstr ("iqn.2008-04.com.sun.virtualbox.initiator").detachTo (values.appendedRaw());
    1562 
    1563         /// @todo add -targetName and -targetPassword options
    1564 
    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 
    1581826    return SUCCEEDED(rc) ? 0 : 1;
    1582827}
     
    43663611}
    43673612
    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     do
    4400     {
    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 parents
    4409         /// @todo NEWMEDIA print the full state value
    4410         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 too
    4473             /// @todo NEWMEDIA also list children and say 'differencing' for
    4474             /// 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     else
    4546         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     else
    4577     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     else
    4592     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     else
    4607         return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
    4608 
    4609     return SUCCEEDED(rc) ? 0 : 1;
    4610 }
    46113613
    46123614#ifdef RT_OS_WINDOWS
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r15366 r15492  
    118118
    119119void printUsageInternal(USAGECATEGORY u64Cmd);
     120
     121void showProgress(ComPtr<IProgress> progress);
     122
    120123#ifndef VBOX_ONLY_DOCS
    121124int handleInternalCommands(int argc, char *argv[],
     
    145148                  ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
    146149
    147 /* VBoxManageVD.cpp */
     150/* VBoxManageDisk.cpp */
     151int handleCreateHardDisk(int argc, char *argv[],
     152                         ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     153int handleModifyHardDisk(int argc, char *argv[],
     154                         ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     155int handleCloneHardDisk(int argc, char *argv[],
     156                        ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     157int handleConvertHardDisk(int argc, char **argv);
     158int handleConvertDDImage(int argc, char *argv[]);
     159int handleAddiSCSIDisk(int argc, char *argv[],
     160                       ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
     161int handleShowHardDiskInfo(int argc, char *argv[],
     162                           ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     163int handleOpenMedium(int argc, char *argv[],
     164                     ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     165int handleCloseMedium(int argc, char *argv[],
     166                      ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session);
     167
    148168/* VBoxManageUSB.cpp */
    149169/* VBoxManageTODO.cpp */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp

    r15489 r15492  
    11/* $Id$ */
    22/** @file
    3  * VBoxManage - VirtualBox's command-line interface.
     3 * VBoxManage - The disk delated commands.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2020 */
    2121
     22#ifndef VBOX_ONLY_DOCS
    2223
    2324/*******************************************************************************
    2425*   Header Files                                                               *
    2526*******************************************************************************/
    26 #ifndef VBOX_ONLY_DOCS
    2727#include <VBox/com/com.h>
    28 #include <VBox/com/string.h>
    29 #include <VBox/com/Guid.h>
    3028#include <VBox/com/array.h>
    3129#include <VBox/com/ErrorInfo.h>
    32 #include <VBox/com/EventQueue.h>
    33 
    3430#include <VBox/com/VirtualBox.h>
    3531
    36 #include <vector>
    37 #include <list>
    38 #endif /* !VBOX_ONLY_DOCS */
    39 
    4032#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>
    4633#include <iprt/file.h>
    47 #include <iprt/initterm.h>
    48 #include <iprt/param.h>
    49 #include <iprt/path.h>
    5034#include <iprt/stream.h>
    5135#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>
    5637#include <VBox/VBoxHDD-new.h>
    57 #include <VBox/log.h>
    5838
    5939#include "VBoxManage.h"
    60 
    61 #ifndef VBOX_ONLY_DOCS
    6240using namespace com;
    6341
    64 /* missing XPCOM <-> COM wrappers */
    65 #ifndef STDMETHOD_
    66 # define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth
    67 #endif
    68 #ifndef NS_GET_IID
    69 # define NS_GET_IID(I) IID_##I
    70 #endif
    71 #ifndef RT_OS_WINDOWS
    72 #define IUnknown nsISupports
    73 #endif
    74 
    75 /** command handler type */
    76 typedef int (*PFNHANDLER)(int argc, char *argv[], ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
    77 
    78 #ifdef USE_XPCOM_QUEUE
    79 /** A pointer to the event queue, set by main() before calling any handlers. */
    80 nsCOMPtr<nsIEventQueue> g_pEventQ;
    81 #endif
    82 
    83 /**
    84  * Quick IUSBDevice implementation for detaching / attaching
    85  * devices to the USB Controller.
    86  */
    87 class MyUSBDevice : public IUSBDevice
    88 {
    89 public:
    90     // public initializer/uninitializer for internal purposes only
    91     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         else
    118             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 // types
    151 ///////////////////////////////////////////////////////////////////////////////
    152 
    153 template <typename T>
    154 class Nullable
    155 {
    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 USBFilterCmd
    182 {
    183     struct USBFilter
    184     {
    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 */
    21542
    21643// funcs
    21744///////////////////////////////////////////////////////////////////////////////
    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_LINUX
    237     bool fLinux = true;
    238 #else
    239     bool fLinux = false;
    240 #endif
    241 #ifdef RT_OS_WINDOWS
    242     bool fWin = true;
    243 #else
    244     bool fWin = false;
    245 #endif
    246 #ifdef RT_OS_SOLARIS
    247     bool fSolaris = true;
    248 #else
    249     bool fSolaris = false;
    250 #endif
    251 #ifdef RT_OS_DARWIN
    252     bool fDarwin = true;
    253 #else
    254     bool fDarwin = false;
    255 #endif
    256 #ifdef VBOX_WITH_VRDP
    257     bool fVRDP = true;
    258 #else
    259     bool fVRDP = false;
    260 #endif
    261 
    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_AHCI
    355                  "                            [-sata on|off]\n"
    356                  "                            [-sataportcount <1-30>]\n"
    357                  "                            [-sataport<1-30> none|<uuid>|<filename>]\n"
    358                  "                            [-sataideemulation<1-4> <1-30>]\n"
    359 #endif
    360                  "                            [-dvd none|<uuid>|<filename>|host:<drive>]\n"
    361                  "                            [-dvdpassthrough on|off]\n"
    362                  "                            [-floppy disabled|empty|<uuid>|\n"
    363                  "                                     <filename>|host:<drive>]\n"
    364                  "                            [-nic<1-N> none|null|nat|hostif|intnet]\n"
    365                  "                            [-nictype<1-N> Am79C970A|Am79C973"
    366 #ifdef VBOX_WITH_E1000
    367                                                                               "|82540EM|82543GC"
    368 #endif
    369                  "]\n"
    370                  "                            [-cableconnected<1-N> on|off]\n"
    371                  "                            [-nictrace<1-N> on|off]\n"
    372                  "                            [-nictracefile<1-N> <filename>]\n"
    373                  "                            [-nicspeed<1-N> <kbps>]\n"
    374                  "                            [-hostifdev<1-N> none|<devicename>]\n"
    375                  "                            [-intnet<1-N> <network name>]\n"
    376                  "                            [-natnet<1-N> <network>|default]\n"
    377                  "                            [-macaddress<1-N> auto|<mac>]\n"
    378                  "                            [-uart<1-N> off|<I/O base> <IRQ>]\n"
    379                  "                            [-uartmode<1-N> disconnected|\n"
    380                  "                                            server <pipe>|\n"
    381                  "                                            client <pipe>|\n"
    382                  "                                            <devicename>]\n"
    383 #ifdef VBOX_WITH_MEM_BALLOONING
    384                  "                            [-guestmemoryballoon <balloonsize in MB>]\n"
    385 #endif
    386                  "                            [-gueststatisticsinterval <seconds>]\n"
    387                  );
    388         RTPrintf("                            [-audio none|null");
    389         if (fWin)
    390         {
    391 #ifdef VBOX_WITH_WINMM
    392             RTPrintf(                        "|winmm|dsound");
    393 #else
    394             RTPrintf(                        "|dsound");
    395 #endif
    396         }
    397         if (fSolaris)
    398         {
    399             RTPrintf(                        "|solaudio");
    400         }
    401         if (fLinux)
    402         {
    403             RTPrintf(                        "|oss"
    404 #ifdef VBOX_WITH_ALSA
    405                                              "|alsa"
    406 #endif
    407 #ifdef VBOX_WITH_PULSE
    408                                              "|pulse"
    409 #endif
    410                                              );
    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 backend
    512         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_PROPS
    671     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 suppressed
    702 #ifndef VBOX_ONLY_DOCS
    703     if (g_fInternalMode)
    704         printUsageInternal(u64Cmd);
    705     else
    706         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_DOCS
    728 /**
    729  * Print out progress on the console
    730  */
    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(&currentPercent));
    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         else
    771             RTPrintf("FAILED\n");
    772     }
    773     else
    774         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 }
    82945
    83046
     
    83854
    83955
    840 static int handleCreateHardDisk(int argc, char *argv[],
    841                                 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     56int handleCreateHardDisk(int argc, char *argv[],
     57                         ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    84258{
    84359    HRESULT rc;
     
    988204
    989205
    990 static int handleModifyHardDisk(int argc, char *argv[],
    991                                 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     206int handleModifyHardDisk(int argc, char *argv[],
     207                         ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    992208{
    993209    HRESULT rc;
     
    1092308}
    1093309
    1094 static int handleCloneHardDisk(int argc, char *argv[],
    1095                                ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     310int handleCloneHardDisk(int argc, char *argv[],
     311                        ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    1096312{
    1097313#if 1
     
    1141357}
    1142358
    1143 static int handleConvertHardDisk(int argc, char **argv)
     359int handleConvertHardDisk(int argc, char **argv)
    1144360{
    1145361    Bstr srcformat;
     
    1267483
    1268484
    1269 static int handleConvertDDImage(int argc, char *argv[])
     485int handleConvertDDImage(int argc, char *argv[])
    1270486{
    1271487    VDIMAGETYPE enmImgType = VD_IMAGE_TYPE_NORMAL;
     
    1428644}
    1429645
    1430 static int handleAddiSCSIDisk(int argc, char *argv[],
    1431                               ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
     646int handleAddiSCSIDisk(int argc, char *argv[],
     647                       ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
    1432648{
    1433649    HRESULT rc;
     
    1582798}
    1583799
    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
     801int handleShowHardDiskInfo(int argc, char *argv[],
    3544802                           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     else
    3559     {
    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     do
    3571     {
    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                 else
    3612                 {
    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                 else
    3668                 {
    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                 else
    3729                 {
    3730                     errorArgument("Invalid link state '%s'", Utf8Str(argv[2]).raw());
    3731                     rc = E_FAIL;
    3732                     break;
    3733                 }
    3734             }
    3735         }
    3736 #ifdef VBOX_WITH_VRDP
    3737         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                 else
    3760                 {
    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 address
    3784                 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                 else
    3795                 {
    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             else
    3807             {
    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             else
    3891             {
    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             else
    3952             {
    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_BALLOONING
    3978         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 #endif
    4004         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         else
    4030         {
    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         do
    4061         {
    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             do
    4067             {
    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         do
    4100         {
    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             do
    4106             {
    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     do
    4144     {
    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                 else
    4183                     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             else
    4205             {
    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                 else
    4223                     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             else
    4247             {
    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                 else
    4259                     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             else
    4279             {
    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                 else
    4287                 {
    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                 else
    4319                 {
    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             else
    4346             {
    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         else
    4357         {
    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)
    4370803{
    4371804    HRESULT rc;
     
    4490923}
    4491924
    4492 static int handleOpenMedium(int argc, char *argv[],
    4493                             ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     925int handleOpenMedium(int argc, char *argv[],
     926                     ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    4494927{
    4495928    HRESULT rc;
     
    4549982}
    4550983
    4551 static int handleCloseMedium(int argc, char *argv[],
    4552                              ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
     984int handleCloseMedium(int argc, char *argv[],
     985                      ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
    4553986{
    4554987    HRESULT rc;
     
    46091042    return SUCCEEDED(rc) ? 0 : 1;
    46101043}
    4611 
    4612 #ifdef RT_OS_WINDOWS
    4613 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     do
    4622     {
    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     do
    4657     {
    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             do
    4713             {
    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         else
    4725         {
    4726             Bstr value;
    4727             CHECK_ERROR(virtualBox, GetExtraData(Bstr(argv[1]), value.asOutParam()));
    4728             if (value)
    4729                 RTPrintf("Value: %lS\n", value.raw());
    4730             else
    4731                 RTPrintf("No value set!\n");
    4732         }
    4733     }
    4734     else
    4735     {
    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                 do
    4752                 {
    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             else
    4766             {
    4767                 Bstr value;
    4768                 CHECK_ERROR(machine, GetExtraData(Bstr(argv[1]), value.asOutParam()));
    4769                 if (value)
    4770                     RTPrintf("Value: %lS\n", value.raw());
    4771                 else
    4772                     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         else
    4795             return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
    4796     }
    4797     else
    4798     {
    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             else
    4814                 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         else
    4838             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         else
    4846             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         else
    4854             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         else
    4862             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         else
    4871             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     else
    4883         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 default
    4926             // (assuming that the user sets up all necessary attributes
    4927             // 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                     else
    4941                     {
    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                     else
    4968                         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                     else
    5040                         return errorArgument("Invalid USB filter action '%s'", argv[i]);
    5041                 }
    5042                 else
    5043                     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 options
    5050                 if (   cmd.mFilter.mName.isEmpty()
    5051                     ||
    5052                        (   cmd.mGlobal
    5053                         && cmd.mFilter.mAction == USBDeviceFilterAction_Null
    5054                        )
    5055                     || (   !cmd.mGlobal
    5056                         && !cmd.mMachine)
    5057                     || (   cmd.mGlobal
    5058                         && 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                     else
    5083                     {
    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 options
    5096             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     else
    5112     {
    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             else
    5153             {
    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             else
    5208             {
    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             else
    5244             {
    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             else
    5322                 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         else
    5351         {
    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             else
    5389                 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         else
    5413         {
    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     else
    5428         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     else
    5448     {
    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         else
    5476             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                 else
    5499                 {
    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                          else
    5507                          */
    5508                         RTPrintf("%ls\n", stats.raw());
    5509                     }
    5510                 }
    5511             }
    5512             aSession->Close();
    5513         }
    5514     }
    5515 
    5516     return SUCCEEDED(rc) ? 0 : 1;
    5517 }
    55181044#endif /* !VBOX_ONLY_DOCS */
    5519 
    5520 enum ConvertSettings
    5521 {
    5522     ConvertSettings_No      = 0,
    5523     ConvertSettings_Yes     = 1,
    5524     ConvertSettings_Backup  = 2,
    5525     ConvertSettings_Ignore  = 3,
    5526 };
    5527 
    5528 #ifndef VBOX_ONLY_DOCS
    5529 /**
    5530  * Checks if any of the settings files were auto-converted and informs the
    5531  * 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     do
    5546     {
    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                 else
    5655                     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                 else
    5670                     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 // main
    5683 ///////////////////////////////////////////////////////////////////////////////
    5684 
    5685 int main(int argc, char *argv[])
    5686 {
    5687     /*
    5688      * Before we do anything, init the runtime without loading
    5689      * 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 <= iCmd
    5703             ||  (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") == 0
    5714                  || strcmp(argv[i], "-version") == 0
    5715                  || strcmp(argv[i], "-Version") == 0
    5716                  || 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         else
    5751         {
    5752             break;
    5753         }
    5754     }
    5755 
    5756     iCmdArg = iCmd + 1;
    5757 
    5758     if (fShowLogo)
    5759         showLogo();
    5760 
    5761 
    5762 #ifdef VBOX_ONLY_DOCS
    5763     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     do
    5782     {
    5783     // scopes all the stuff till shutdown
    5784     ////////////////////////////////////////////////////////////////////////////
    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         else
    5814             PRINT_ERROR_INFO (info);
    5815         break;
    5816     }
    5817 
    5818     CHECK_RC_BREAK (session.createInprocObject (CLSID_Session));
    5819 
    5820     /* create the event queue
    5821      * (here it is necessary only to process remaining XPCOM/IPC events
    5822      * after the session is closed) */
    5823 
    5824 #ifdef USE_XPCOM_QUEUE
    5825     NS_GetMainEventQ(getter_AddRefs(g_pEventQ));
    5826 #endif
    5827 
    5828     if (!checkForAutoConvertedSettings (virtualBox, session, fConvertSettings))
    5829         break;
    5830 
    5831     /*
    5832      * All registered command handlers
    5833      */
    5834     struct
    5835     {
    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_WINDOWS
    5866         { "createhostif",     handleCreateHostIF },
    5867         { "removehostif",     handleRemoveHostIF },
    5868 #endif
    5869         { "getextradata",     handleGetExtraData },
    5870         { "setextradata",     handleSetExtraData },
    5871         { "setproperty",      handleSetProperty },
    5872         { "usbfilter",        handleUSBFilter },
    5873         { "sharedfolder",     handleSharedFolder },
    5874         { "vmstatistics",     handleVMStatistics },
    5875 #ifdef VBOX_WITH_GUEST_PROPS
    5876         { "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 to
    5899      * Aborted which may have unwanted side effects like killing the saved
    5900      * state file (if the machine was in the Saved state before). */
    5901     session->Close();
    5902 
    5903 #ifdef USE_XPCOM_QUEUE
    5904     g_pEventQ->ProcessPendingEvents();
    5905 #endif
    5906 
    5907     // end "all-stuff" scope
    5908     ////////////////////////////////////////////////////////////////////////////
    5909     }
    5910     while (0);
    5911 
    5912     com::Shutdown();
    5913 #endif /* !VBOX_ONLY_DOCS */
    5914 
    5915     /*
    5916      * Free converted argument vector
    5917      */
    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.

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