151
HRESULT findMedium(HandlerArg *a, const char *pszFilenameOrUuid,
152
DeviceType_T enmDevType, bool fSilent,
153
ComPtr<IMedium> &pMedium)
156
Guid id(pszFilenameOrUuid);
157
char szFilenameAbs[RTPATH_MAX] = "";
159
/* If it is no UUID, convert the filename to an absolute one. */
162
int irc = RTPathAbs(pszFilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
166
RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilenameOrUuid);
169
pszFilenameOrUuid = szFilenameAbs;
173
CHECK_ERROR(a->virtualBox, FindMedium(Bstr(pszFilenameOrUuid).raw(),
174
enmDevType, pMedium.asOutParam()));
176
rc = a->virtualBox->FindMedium(Bstr(pszFilenameOrUuid).raw(),
177
enmDevType, pMedium.asOutParam());
181
HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
182
DeviceType_T enmDevType, ComPtr<IMedium> &pMedium,
186
bool fWasUnknown = false;
187
Guid id(pszFilenameOrUuid);
188
char szFilenameAbs[RTPATH_MAX] = "";
190
/* If it is no UUID, convert the filename to an absolute one. */
193
int irc = RTPathAbs(pszFilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
196
RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilenameOrUuid);
199
pszFilenameOrUuid = szFilenameAbs;
202
rc = a->virtualBox->FindMedium(Bstr(pszFilenameOrUuid).raw(), enmDevType,
203
pMedium.asOutParam());
204
/* If the medium is unknown try to open it. */
207
CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
208
enmDevType, AccessMode_ReadWrite,
209
pMedium.asOutParam()));
213
if (RT_VALID_PTR(pfWasUnknown))
214
*pfWasUnknown = fWasUnknown;
218
static HRESULT createHardDisk(HandlerArg *a, const char *pszFormat,
219
const char *pszFilename, ComPtr<IMedium> &pMedium)
222
char szFilenameAbs[RTPATH_MAX] = "";
224
/** @todo laziness shortcut. should really check the MediumFormatCapabilities */
225
if (RTStrICmp(pszFormat, "iSCSI"))
227
int irc = RTPathAbs(pszFilename, szFilenameAbs, sizeof(szFilenameAbs));
230
RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilename);
233
pszFilename = szFilenameAbs;
236
CHECK_ERROR(a->virtualBox, CreateHardDisk(Bstr(pszFormat).raw(),
237
Bstr(pszFilename).raw(),
238
pMedium.asOutParam()));
149
242
static const RTGETOPTDEF g_aCreateHardDiskOptions[] =
151
244
{ "--filename", 'f', RTGETOPT_REQ_STRING },
152
245
{ "-filename", 'f', RTGETOPT_REQ_STRING }, // deprecated
153
246
{ "--size", 's', RTGETOPT_REQ_UINT64 },
154
247
{ "-size", 's', RTGETOPT_REQ_UINT64 }, // deprecated
248
{ "--sizebyte", 'S', RTGETOPT_REQ_UINT64 },
155
249
{ "--format", 'o', RTGETOPT_REQ_STRING },
156
250
{ "-format", 'o', RTGETOPT_REQ_STRING }, // deprecated
157
251
{ "--static", 'F', RTGETOPT_REQ_NOTHING },
158
252
{ "-static", 'F', RTGETOPT_REQ_NOTHING }, // deprecated
159
253
{ "--variant", 'm', RTGETOPT_REQ_STRING },
160
254
{ "-variant", 'm', RTGETOPT_REQ_STRING }, // deprecated
161
{ "--type", 't', RTGETOPT_REQ_STRING },
162
{ "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
163
{ "--comment", 'c', RTGETOPT_REQ_STRING },
164
{ "-comment", 'c', RTGETOPT_REQ_STRING }, // deprecated
165
{ "--remember", 'r', RTGETOPT_REQ_NOTHING },
166
{ "-remember", 'r', RTGETOPT_REQ_NOTHING }, // deprecated
167
{ "--register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated (inofficial)
168
{ "-register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated
171
257
int handleCreateHardDisk(HandlerArg *a)
261
const char *filename = NULL;
263
const char *format = "VDI";
178
264
MediumVariant_T DiskVariant = MediumVariant_Standard;
180
bool fRemember = false;
181
MediumType_T DiskType = MediumType_Normal;
184
267
RTGETOPTUNION ValueUnion;
295
358
com::ProgressErrorInfo info(progress);
296
359
if (info.isBasicAvailable())
297
RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());
360
RTMsgError("Failed to create hard disk. Error message: %lS", info.getText().raw());
299
RTPrintf("Error: failed to create hard disk. No error message available!\n");
362
RTMsgError("Failed to create hard disk. No error message available!");
303
doClose = !fRemember;
306
367
CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
308
if ( DiskType == MediumType_Writethrough
309
|| DiskType == MediumType_Shareable)
311
CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));
314
RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).raw());
368
RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).c_str());
319
CHECK_ERROR(hardDisk, Close());
371
CHECK_ERROR(hardDisk, Close());
322
373
return SUCCEEDED(rc) ? 0 : 1;
325
#if 0 /* disabled until disk shrinking is implemented based on VBoxHDD */
326
static DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
328
unsigned *pPercent = (unsigned *)pvUser;
330
if (*pPercent != uPercent)
332
*pPercent = uPercent;
334
if ((uPercent % 10) == 0 && uPercent)
335
RTPrintf("%d%%", uPercent);
336
RTStrmFlush(g_pStdOut);
343
376
static const RTGETOPTDEF g_aModifyHardDiskOptions[] =
345
378
{ "--type", 't', RTGETOPT_REQ_STRING },
418
466
if (!FilenameOrUuid)
419
467
return errorSyntax(USAGE_MODIFYHD, "Disk name or UUID required");
421
if (!fModifyDiskType && !fModifyAutoReset && !fModifyCompact)
469
if (!fModifyDiskType && !fModifyAutoReset && !fModifyCompact && !fModifyResize)
422
470
return errorSyntax(USAGE_MODIFYHD, "No operation specified");
424
/* first guess is that it's a UUID */
425
Guid uuid(FilenameOrUuid);
426
rc = a->virtualBox->GetHardDisk(uuid.toUtf16(), hardDisk.asOutParam());
427
/* no? then it must be a filename */
472
/* Depending on the operation the medium must be in the registry or
473
* may be opened on demand. */
474
if (fModifyDiskType || fModifyAutoReset)
475
rc = findMedium(a, FilenameOrUuid, DeviceType_HardDisk, false /* fSilent */, hardDisk);
477
rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk,
481
if (hardDisk.isNull())
430
CHECK_ERROR(a->virtualBox, FindHardDisk(Bstr(FilenameOrUuid), hardDisk.asOutParam()));
483
RTMsgError("Invalid hard disk reference, avoiding crash");
435
487
if (fModifyDiskType)
437
/* hard disk must be registered */
438
if (SUCCEEDED(rc) && hardDisk)
440
MediumType_T hddType;
441
CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
489
MediumType_T hddType;
490
CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
443
if (hddType != DiskType)
444
CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));
447
return errorArgument("Hard disk image not registered");
492
if (hddType != DiskType)
493
CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));
450
496
if (fModifyAutoReset)
455
501
if (fModifyCompact)
457
bool unknown = false;
458
/* the hard disk image might not be registered */
462
rc = a->virtualBox->OpenHardDisk(Bstr(FilenameOrUuid), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam());
463
if (rc == VBOX_E_FILE_ERROR)
465
char szFilenameAbs[RTPATH_MAX] = "";
466
int irc = RTPathAbs(FilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
469
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", FilenameOrUuid);
472
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam()));
475
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(FilenameOrUuid), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam()));
477
if (SUCCEEDED(rc) && hardDisk)
479
ComPtr<IProgress> progress;
480
CHECK_ERROR(hardDisk, Compact(progress.asOutParam()));
482
rc = showProgress(progress);
487
RTPrintf("Error: Compact hard disk operation is not implemented!\n");
488
RTPrintf("The functionality will be restored later.\n");
490
else if (rc == VBOX_E_NOT_SUPPORTED)
492
RTPrintf("Error: Compact hard disk operation for this format is not implemented yet!\n");
495
com::GluePrintRCMessage(rc);
503
ComPtr<IProgress> progress;
504
CHECK_ERROR(hardDisk, Compact(progress.asOutParam()));
506
rc = showProgress(progress);
510
RTMsgError("Compact hard disk operation is not implemented!");
511
else if (rc == VBOX_E_NOT_SUPPORTED)
512
RTMsgError("Compact hard disk operation for this format is not implemented yet!");
514
com::GluePrintRCMessage(rc);
520
ComPtr<IProgress> progress;
521
CHECK_ERROR(hardDisk, Resize(cbResize, progress.asOutParam()));
523
rc = showProgress(progress);
527
RTMsgError("Resize hard disk operation is not implemented!");
528
else if (rc == VBOX_E_NOT_SUPPORTED)
529
RTMsgError("Resize hard disk operation for this format is not implemented yet!");
531
com::GluePrintRCMessage(rc);
502
538
return SUCCEEDED(rc) ? 0 : 1;
511
547
{ "--existing", 'E', RTGETOPT_REQ_NOTHING },
512
548
{ "--variant", 'm', RTGETOPT_REQ_STRING },
513
549
{ "-variant", 'm', RTGETOPT_REQ_STRING },
514
{ "--type", 't', RTGETOPT_REQ_STRING },
515
{ "-type", 't', RTGETOPT_REQ_STRING },
516
{ "--remember", 'r', RTGETOPT_REQ_NOTHING },
517
{ "-remember", 'r', RTGETOPT_REQ_NOTHING },
518
{ "--register", 'r', RTGETOPT_REQ_NOTHING },
519
{ "-register", 'r', RTGETOPT_REQ_NOTHING },
522
552
int handleCloneHardDisk(HandlerArg *a)
556
const char *pszSrc = NULL;
557
const char *pszDst = NULL;
528
559
MediumVariant_T DiskVariant = MediumVariant_Standard;
529
560
bool fExisting = false;
530
bool fRemember = false;
531
bool fSetDiskType = false;
532
MediumType_T DiskType = MediumType_Normal;
535
563
RTGETOPTUNION ValueUnion;
612
629
bool fSrcUnknown = false;
613
630
bool fDstUnknown = false;
615
/* first guess is that it's a UUID */
616
rc = a->virtualBox->GetHardDisk(src, srcDisk.asOutParam());
617
/* no? then it must be a filename */
619
rc = a->virtualBox->FindHardDisk(src, srcDisk.asOutParam());
620
/* no? well, then it's an unknown image */
623
rc = a->virtualBox->OpenHardDisk(src, AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), srcDisk.asOutParam());
624
if (rc == VBOX_E_FILE_ERROR)
626
char szFilenameAbs[RTPATH_MAX] = "";
627
int irc = RTPathAbs(Utf8Str(src).c_str(), szFilenameAbs, sizeof(szFilenameAbs));
630
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", Utf8Str(src).raw());
633
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), srcDisk.asOutParam()));
636
CHECK_ERROR(a->virtualBox, OpenHardDisk(src, AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), srcDisk.asOutParam()));
632
rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, srcDisk, &fSrcUnknown);
646
638
/* open/create destination hard disk */
649
/* first guess is that it's a UUID */
650
rc = a->virtualBox->GetHardDisk(dst, dstDisk.asOutParam());
651
/* no? then it must be a filename */
653
rc = a->virtualBox->FindHardDisk(dst, dstDisk.asOutParam());
654
/* no? well, then it's an unknown image */
657
rc = a->virtualBox->OpenHardDisk(dst, AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), dstDisk.asOutParam());
658
if (rc == VBOX_E_FILE_ERROR)
660
char szFilenameAbs[RTPATH_MAX] = "";
661
int irc = RTPathAbs(Utf8Str(dst).c_str(), szFilenameAbs, sizeof(szFilenameAbs));
664
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", Utf8Str(dst).raw());
667
CHECK_ERROR_BREAK(a->virtualBox, OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), dstDisk.asOutParam()));
670
CHECK_ERROR_BREAK(a->virtualBox, OpenHardDisk(dst, AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), dstDisk.asOutParam()));
678
/* Perform accessibility check now. */
680
CHECK_ERROR_BREAK(dstDisk, RefreshState(&state));
682
CHECK_ERROR_BREAK(dstDisk, COMGETTER(Format) (format.asOutParam()));
641
rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, dstDisk, &fDstUnknown);
645
/* Perform accessibility check now. */
647
CHECK_ERROR_BREAK(dstDisk, RefreshState(&state));
648
CHECK_ERROR_BREAK(dstDisk, COMGETTER(Format)(format.asOutParam()));
686
652
/* use the format of the source hard disk if unspecified */
687
653
if (format.isEmpty())
688
CHECK_ERROR_BREAK(srcDisk, COMGETTER(Format) (format.asOutParam()));
689
CHECK_ERROR_BREAK(a->virtualBox, CreateHardDisk(format, dst, dstDisk.asOutParam()));
654
CHECK_ERROR_BREAK(srcDisk, COMGETTER(Format)(format.asOutParam()));
655
rc = createHardDisk(a, Utf8Str(format).c_str(), pszDst, dstDisk);
692
660
ComPtr<IProgress> progress;
835
798
rc = RTFileGetSize(File, &cbFile);
836
799
if (RT_FAILURE(rc))
838
RTPrintf("Error getting image size for file \"%s\": %Rrc\n", srcfilename, rc);
801
RTMsgError("Cannot get image size for file \"%s\": %Rrc", srcfilename, rc);
842
RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (uImageFlags & VD_IMAGE_FLAGS_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
805
RTStrmPrintf(g_pStdErr, "Creating %s image with size %RU64 bytes (%RU64MB)...\n",
806
(uImageFlags & VD_IMAGE_FLAGS_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
843
807
char pszComment[256];
844
808
RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", srcfilename);
845
rc = VDCreate(pVDIfs, &pDisk);
809
rc = VDCreate(pVDIfs, VDTYPE_HDD, &pDisk);
846
810
if (RT_FAILURE(rc))
848
RTPrintf("Error while creating the virtual disk container: %Rrc\n", rc);
812
RTMsgError("Cannot create the virtual disk container: %Rrc", rc);
852
816
Assert(RT_MIN(cbFile / 512 / 16 / 63, 16383) -
853
817
(unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383) == 0);
854
PDMMEDIAGEOMETRY PCHS, LCHS;
818
VDGEOMETRY PCHS, LCHS;
855
819
PCHS.cCylinders = (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383);
856
820
PCHS.cHeads = 16;
857
821
PCHS.cSectors = 63;
906
870
if (File != NIL_RTFILE)
907
871
RTFileClose(File);
909
return RT_FAILURE(rc);
912
static const RTGETOPTDEF g_aAddiSCSIDiskOptions[] =
914
{ "--server", 's', RTGETOPT_REQ_STRING },
915
{ "-server", 's', RTGETOPT_REQ_STRING }, // deprecated
916
{ "--target", 'T', RTGETOPT_REQ_STRING },
917
{ "-target", 'T', RTGETOPT_REQ_STRING }, // deprecated
918
{ "--port", 'p', RTGETOPT_REQ_STRING },
919
{ "-port", 'p', RTGETOPT_REQ_STRING }, // deprecated
920
{ "--lun", 'l', RTGETOPT_REQ_STRING },
921
{ "-lun", 'l', RTGETOPT_REQ_STRING }, // deprecated
922
{ "--encodedlun", 'L', RTGETOPT_REQ_STRING },
923
{ "-encodedlun", 'L', RTGETOPT_REQ_STRING }, // deprecated
924
{ "--username", 'u', RTGETOPT_REQ_STRING },
925
{ "-username", 'u', RTGETOPT_REQ_STRING }, // deprecated
926
{ "--password", 'P', RTGETOPT_REQ_STRING },
927
{ "-password", 'P', RTGETOPT_REQ_STRING }, // deprecated
928
{ "--type", 't', RTGETOPT_REQ_STRING },
929
{ "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
930
{ "--intnet", 'I', RTGETOPT_REQ_NOTHING },
931
{ "-intnet", 'I', RTGETOPT_REQ_NOTHING }, // deprecated
934
int handleAddiSCSIDisk(HandlerArg *a)
945
bool fIntNet = false;
946
MediumType_T DiskType = MediumType_Normal;
949
RTGETOPTUNION ValueUnion;
950
RTGETOPTSTATE GetState;
951
// start at 0 because main() has hacked both the argc and argv given to us
952
RTGetOptInit(&GetState, a->argc, a->argv, g_aAddiSCSIDiskOptions, RT_ELEMENTS(g_aAddiSCSIDiskOptions),
953
0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
954
while ((c = RTGetOpt(&GetState, &ValueUnion)))
958
case 's': // --server
959
server = ValueUnion.psz;
962
case 'T': // --target
963
target = ValueUnion.psz;
967
port = ValueUnion.psz;
971
lun = ValueUnion.psz;
974
case 'L': // --encodedlun
975
lun = BstrFmt("enc%s", ValueUnion.psz);
978
case 'u': // --username
979
username = ValueUnion.psz;
982
case 'P': // --password
983
password = ValueUnion.psz;
987
vrc = parseDiskType(ValueUnion.psz, &DiskType);
989
return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);
992
case 'I': // --intnet
996
case VINF_GETOPT_NOT_OPTION:
997
return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", ValueUnion.psz);
1002
if (RT_C_IS_PRINT(c))
1003
return errorSyntax(USAGE_ADDISCSIDISK, "Invalid option -%c", c);
1005
return errorSyntax(USAGE_ADDISCSIDISK, "Invalid option case %i", c);
1007
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
1008
return errorSyntax(USAGE_ADDISCSIDISK, "unknown option: %s\n", ValueUnion.psz);
1009
else if (ValueUnion.pDef)
1010
return errorSyntax(USAGE_ADDISCSIDISK, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
1012
return errorSyntax(USAGE_ADDISCSIDISK, "error: %Rrs", c);
1016
/* check for required options */
1017
if (server.isEmpty() || target.isEmpty())
1018
return errorSyntax(USAGE_ADDISCSIDISK, "Parameters --server and --target are required");
1022
ComPtr<IMedium> hardDisk;
1023
/** @todo move the location stuff to Main, which can use pfnComposeName
1024
* from the disk backends to construct the location properly. Also do
1025
* not use slashes to separate the parts, as otherwise only the last
1026
* element comtaining information will be shown. */
1027
if (lun.isEmpty() || lun == "0" || lun == "enc0")
1029
CHECK_ERROR_BREAK (a->virtualBox,
1030
CreateHardDisk(Bstr ("iSCSI"),
1031
BstrFmt ("%ls|%ls", server.raw(), target.raw()),
1032
hardDisk.asOutParam()));
1036
CHECK_ERROR_BREAK (a->virtualBox,
1037
CreateHardDisk(Bstr ("iSCSI"),
1038
BstrFmt ("%ls|%ls|%ls", server.raw(), target.raw(), lun.raw()),
1039
hardDisk.asOutParam()));
1041
if (FAILED(rc)) break;
1043
if (!port.isEmpty())
1044
server = BstrFmt ("%ls:%ls", server.raw(), port.raw());
1046
com::SafeArray <BSTR> names;
1047
com::SafeArray <BSTR> values;
1049
Bstr ("TargetAddress").detachTo (names.appendedRaw());
1050
server.detachTo (values.appendedRaw());
1051
Bstr ("TargetName").detachTo (names.appendedRaw());
1052
target.detachTo (values.appendedRaw());
1056
Bstr ("LUN").detachTo (names.appendedRaw());
1057
lun.detachTo (values.appendedRaw());
1059
if (!username.isEmpty())
1061
Bstr ("InitiatorUsername").detachTo (names.appendedRaw());
1062
username.detachTo (values.appendedRaw());
1064
if (!password.isEmpty())
1066
Bstr ("InitiatorSecret").detachTo (names.appendedRaw());
1067
password.detachTo (values.appendedRaw());
1070
/// @todo add --initiator option - until that happens rely on the
1071
// defaults of the iSCSI initiator code. Setting it to a constant
1072
// value does more harm than good, as the initiator name is supposed
1073
// to identify a particular initiator uniquely.
1074
// Bstr ("InitiatorName").detachTo (names.appendedRaw());
1075
// Bstr ("iqn.2008-04.com.sun.virtualbox.initiator").detachTo (values.appendedRaw());
1077
/// @todo add --targetName and --targetPassword options
1081
Bstr ("HostIPStack").detachTo (names.appendedRaw());
1082
Bstr ("0").detachTo (values.appendedRaw());
1085
CHECK_ERROR_BREAK (hardDisk,
1086
SetProperties (ComSafeArrayAsInParam (names),
1087
ComSafeArrayAsInParam (values)));
1089
if (DiskType != MediumType_Normal)
1091
CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));
1095
CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
1096
RTPrintf("iSCSI disk created. UUID: %s\n", Utf8Str(guid).raw());
1100
return SUCCEEDED(rc) ? 0 : 1;
873
return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1103
876
static const RTGETOPTDEF g_aShowHardDiskInfoOptions[] =
1151
924
ComPtr<IMedium> hardDisk;
1152
925
bool unknown = false;
1153
/* first guess is that it's a UUID */
1154
Bstr uuid(FilenameOrUuid);
1155
rc = a->virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
1156
/* no? then it must be a filename */
1159
rc = a->virtualBox->FindHardDisk(Bstr(FilenameOrUuid), hardDisk.asOutParam());
1160
/* no? well, then it's an unkwnown image */
1163
rc = a->virtualBox->OpenHardDisk(Bstr(FilenameOrUuid), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam());
1164
if (rc == VBOX_E_FILE_ERROR)
1166
char szFilenameAbs[RTPATH_MAX] = "";
1167
int vrc = RTPathAbs(FilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
1168
if (RT_FAILURE(vrc))
1170
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", FilenameOrUuid);
1173
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam()));
1175
else if (FAILED(rc))
1176
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(FilenameOrUuid), AccessMode_ReadWrite, false, Bstr(""), false, Bstr(""), hardDisk.asOutParam()));
927
rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, hardDisk, &unknown);
1188
934
hardDisk->COMGETTER(Id)(uuid.asOutParam());
1189
RTPrintf("UUID: %s\n", Utf8Str(uuid).raw());
935
RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
1191
937
/* check for accessibility */
1192
938
/// @todo NEWMEDIA check accessibility of all parents
1193
939
/// @todo NEWMEDIA print the full state value
1194
940
MediumState_T state;
1195
CHECK_ERROR_BREAK (hardDisk, RefreshState(&state));
941
CHECK_ERROR_BREAK(hardDisk, RefreshState(&state));
1196
942
RTPrintf("Accessible: %s\n", state != MediumState_Inaccessible ? "yes" : "no");
1198
944
if (state == MediumState_Inaccessible)
1201
CHECK_ERROR_BREAK (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
947
CHECK_ERROR_BREAK(hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
1202
948
RTPrintf("Access Error: %lS\n", err.raw());
1289
1067
return SUCCEEDED(rc) ? 0 : 1;
1292
static const RTGETOPTDEF g_aOpenMediumOptions[] =
1294
{ "disk", 'd', RTGETOPT_REQ_NOTHING },
1295
{ "dvd", 'D', RTGETOPT_REQ_NOTHING },
1296
{ "floppy", 'f', RTGETOPT_REQ_NOTHING },
1297
{ "--type", 't', RTGETOPT_REQ_STRING },
1298
{ "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
1299
{ "--uuid", 'u', RTGETOPT_REQ_UUID },
1300
{ "--parentuuid", 'p', RTGETOPT_REQ_UUID },
1303
int handleOpenMedium(HandlerArg *a)
1313
const char *Filename = NULL;
1314
MediumType_T DiskType = MediumType_Normal;
1315
bool fDiskType = false;
1316
bool fSetImageId = false;
1317
bool fSetParentId = false;
1324
RTGETOPTUNION ValueUnion;
1325
RTGETOPTSTATE GetState;
1326
// start at 0 because main() has hacked both the argc and argv given to us
1327
RTGetOptInit(&GetState, a->argc, a->argv, g_aOpenMediumOptions, RT_ELEMENTS(g_aOpenMediumOptions),
1328
0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
1329
while ((c = RTGetOpt(&GetState, &ValueUnion)))
1334
if (cmd != CMD_NONE)
1335
return errorSyntax(USAGE_OPENMEDIUM, "Only one command can be specified: '%s'", ValueUnion.psz);
1340
if (cmd != CMD_NONE)
1341
return errorSyntax(USAGE_OPENMEDIUM, "Only one command can be specified: '%s'", ValueUnion.psz);
1346
if (cmd != CMD_NONE)
1347
return errorSyntax(USAGE_OPENMEDIUM, "Only one command can be specified: '%s'", ValueUnion.psz);
1352
vrc = parseDiskType(ValueUnion.psz, &DiskType);
1353
if (RT_FAILURE(vrc))
1354
return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);
1359
ImageId = ValueUnion.Uuid;
1363
case 'p': // --parentuuid
1364
ParentId = ValueUnion.Uuid;
1365
fSetParentId = true;
1368
case VINF_GETOPT_NOT_OPTION:
1370
Filename = ValueUnion.psz;
1372
return errorSyntax(USAGE_OPENMEDIUM, "Invalid parameter '%s'", ValueUnion.psz);
1378
if (RT_C_IS_PRINT(c))
1379
return errorSyntax(USAGE_OPENMEDIUM, "Invalid option -%c", c);
1381
return errorSyntax(USAGE_OPENMEDIUM, "Invalid option case %i", c);
1383
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
1384
return errorSyntax(USAGE_OPENMEDIUM, "unknown option: %s\n", ValueUnion.psz);
1385
else if (ValueUnion.pDef)
1386
return errorSyntax(USAGE_OPENMEDIUM, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
1388
return errorSyntax(USAGE_OPENMEDIUM, "error: %Rrs", c);
1392
/* check for required options */
1393
if (cmd == CMD_NONE)
1394
return errorSyntax(USAGE_OPENMEDIUM, "Command variant disk/dvd/floppy required");
1396
return errorSyntax(USAGE_OPENMEDIUM, "Disk name required");
1398
/** @todo remove this hack!
1399
* First try opening the image as is (using the regular API semantics for
1400
* images with relative path or without path), and if that fails with a
1401
* file related error then try it again with what the client thinks the
1402
* relative path would mean. Requires doing the command twice in certain
1403
* cases. This is an ugly hack and needs to be removed whevever we have a
1404
* chance to clean up the API semantics. */
1405
if (cmd == CMD_DISK)
1407
ComPtr<IMedium> hardDisk;
1408
Bstr ImageIdStr = BstrFmt("%RTuuid", &ImageId);
1409
Bstr ParentIdStr = BstrFmt("%RTuuid", &ParentId);
1410
rc = a->virtualBox->OpenHardDisk(Bstr(Filename), AccessMode_ReadWrite, fSetImageId, ImageIdStr, fSetParentId, ParentIdStr, hardDisk.asOutParam());
1411
if (rc == VBOX_E_FILE_ERROR)
1413
char szFilenameAbs[RTPATH_MAX] = "";
1414
int irc = RTPathAbs(Filename, szFilenameAbs, sizeof(szFilenameAbs));
1415
if (RT_FAILURE(irc))
1417
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", Filename);
1420
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, fSetImageId, ImageIdStr, fSetParentId, ParentIdStr, hardDisk.asOutParam()));
1422
else if (FAILED(rc))
1423
CHECK_ERROR(a->virtualBox, OpenHardDisk(Bstr(Filename), AccessMode_ReadWrite, fSetImageId, ImageIdStr, fSetParentId, ParentIdStr, hardDisk.asOutParam()));
1424
if (SUCCEEDED(rc) && hardDisk)
1426
/* change the type if requested */
1427
if (DiskType != MediumType_Normal)
1429
CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));
1433
else if (cmd == CMD_DVD)
1435
if (fDiskType || fSetParentId)
1436
return errorSyntax(USAGE_OPENMEDIUM, "Invalid option for DVD images");
1437
Bstr ImageIdStr = BstrFmt("%RTuuid", &ImageId);
1438
ComPtr<IMedium> dvdImage;
1439
rc = a->virtualBox->OpenDVDImage(Bstr(Filename), ImageIdStr, dvdImage.asOutParam());
1440
if (rc == VBOX_E_FILE_ERROR)
1442
char szFilenameAbs[RTPATH_MAX] = "";
1443
int irc = RTPathAbs(Filename, szFilenameAbs, sizeof(szFilenameAbs));
1444
if (RT_FAILURE(irc))
1446
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", Filename);
1449
CHECK_ERROR(a->virtualBox, OpenDVDImage(Bstr(szFilenameAbs), ImageIdStr, dvdImage.asOutParam()));
1451
else if (FAILED(rc))
1452
CHECK_ERROR(a->virtualBox, OpenDVDImage(Bstr(Filename), ImageIdStr, dvdImage.asOutParam()));
1454
else if (cmd == CMD_FLOPPY)
1456
if (fDiskType || fSetImageId || fSetParentId)
1457
return errorSyntax(USAGE_OPENMEDIUM, "Invalid option for floppy images");
1458
Bstr ImageIdStr = BstrFmt("%RTuuid", &ImageId);
1459
ComPtr<IMedium> floppyImage;
1460
rc = a->virtualBox->OpenFloppyImage(Bstr(Filename), ImageIdStr, floppyImage.asOutParam());
1461
if (rc == VBOX_E_FILE_ERROR)
1463
char szFilenameAbs[RTPATH_MAX] = "";
1464
int irc = RTPathAbs(Filename, szFilenameAbs, sizeof(szFilenameAbs));
1465
if (RT_FAILURE(irc))
1467
RTPrintf("Cannot convert filename \"%s\" to absolute path\n", Filename);
1470
CHECK_ERROR(a->virtualBox, OpenFloppyImage(Bstr(szFilenameAbs), ImageIdStr, floppyImage.asOutParam()));
1472
else if (FAILED(rc))
1473
CHECK_ERROR(a->virtualBox, OpenFloppyImage(Bstr(Filename), ImageIdStr, floppyImage.asOutParam()));
1476
return SUCCEEDED(rc) ? 0 : 1;
1479
1070
static const RTGETOPTDEF g_aCloseMediumOptions[] =
1481
1072
{ "disk", 'd', RTGETOPT_REQ_NOTHING },
1561
1152
ComPtr<IMedium> medium;
1563
/* first guess is that it's a UUID */
1564
Bstr uuid(FilenameOrUuid);
1566
1154
if (cmd == CMD_DISK)
1568
rc = a->virtualBox->GetHardDisk(uuid, medium.asOutParam());
1569
/* not a UUID or not registered? Then it must be a filename */
1572
CHECK_ERROR(a->virtualBox, FindHardDisk(Bstr(FilenameOrUuid), medium.asOutParam()));
1578
rc = a->virtualBox->GetDVDImage(uuid, medium.asOutParam());
1579
/* not a UUID or not registered? Then it must be a filename */
1582
CHECK_ERROR(a->virtualBox, FindDVDImage(Bstr(FilenameOrUuid), medium.asOutParam()));
1586
if (cmd == CMD_FLOPPY)
1588
rc = a->virtualBox->GetFloppyImage(uuid, medium.asOutParam());
1589
/* not a UUID or not registered? Then it must be a filename */
1592
CHECK_ERROR(a->virtualBox, FindFloppyImage(Bstr(FilenameOrUuid), medium.asOutParam()));
1155
rc = findMedium(a, FilenameOrUuid, DeviceType_HardDisk, false /* fSilent */, medium);
1156
else if (cmd == CMD_DVD)
1157
rc = findMedium(a, FilenameOrUuid, DeviceType_DVD, false /* fSilent */, medium);
1158
else if (cmd == CMD_FLOPPY)
1159
rc = findMedium(a, FilenameOrUuid, DeviceType_Floppy, false /* fSilent */, medium);
1596
1161
if (SUCCEEDED(rc) && medium)