summaryrefslogtreecommitdiff
path: root/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp')
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp577
1 files changed, 344 insertions, 233 deletions
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
index e960c26e..d6b1f201 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -47,7 +47,7 @@ using namespace com;
static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
{
- RTMsgError(pszFormat, va);
+ RTMsgErrorV(pszFormat, va);
RTMsgError("Error code %Rrc at %s(%u) in function %s", rc, RT_SRC_POS_ARGS);
}
@@ -148,16 +148,17 @@ int parseBool(const char *psz, bool *pb)
return rc;
}
-HRESULT findMedium(HandlerArg *a, const char *pszFilenameOrUuid,
- DeviceType_T enmDevType, bool fSilent,
- ComPtr<IMedium> &pMedium)
+HRESULT openMedium(HandlerArg *a, const char *pszFilenameOrUuid,
+ DeviceType_T enmDevType, AccessMode_T enmAccessMode,
+ ComPtr<IMedium> &pMedium, bool fForceNewUuidOnOpen,
+ bool fSilent)
{
HRESULT rc;
Guid id(pszFilenameOrUuid);
char szFilenameAbs[RTPATH_MAX] = "";
/* If it is no UUID, convert the filename to an absolute one. */
- if (id.isEmpty())
+ if (!id.isValid())
{
int irc = RTPathAbs(pszFilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
if (RT_FAILURE(irc))
@@ -170,59 +171,18 @@ HRESULT findMedium(HandlerArg *a, const char *pszFilenameOrUuid,
}
if (!fSilent)
- CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
- enmDevType,
- AccessMode_ReadWrite,
- /*fForceNewUidOnOpen */ false,
- pMedium.asOutParam()));
- else
- rc = a->virtualBox->OpenMedium(Bstr(pszFilenameOrUuid).raw(),
- enmDevType,
- AccessMode_ReadWrite,
- /*fForceNewUidOnOpen */ false,
- pMedium.asOutParam());
- return rc;
-}
-
-HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
- DeviceType_T enmDevType, AccessMode_T enmAccessMode,
- ComPtr<IMedium> &pMedium, bool fForceNewUuidOnOpen,
- bool *pfWasUnknown)
-{
- HRESULT rc;
- bool fWasUnknown = false;
- Guid id(pszFilenameOrUuid);
- char szFilenameAbs[RTPATH_MAX] = "";
-
- /* If it is no UUID, convert the filename to an absolute one. */
- if (id.isEmpty())
- {
- int irc = RTPathAbs(pszFilenameOrUuid, szFilenameAbs, sizeof(szFilenameAbs));
- if (RT_FAILURE(irc))
- {
- RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilenameOrUuid);
- return E_FAIL;
- }
- pszFilenameOrUuid = szFilenameAbs;
- }
-
- rc = a->virtualBox->OpenMedium(Bstr(pszFilenameOrUuid).raw(),
- enmDevType,
- enmAccessMode,
- /*fForceNewUidOnOpen */ false,
- pMedium.asOutParam());
- /* If the medium is unknown try to open it. */
- if (!pMedium)
- {
CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
- enmDevType, enmAccessMode,
+ enmDevType,
+ enmAccessMode,
fForceNewUuidOnOpen,
pMedium.asOutParam()));
- if (SUCCEEDED(rc))
- fWasUnknown = true;
- }
- if (RT_VALID_PTR(pfWasUnknown))
- *pfWasUnknown = fWasUnknown;
+ else
+ rc = a->virtualBox->OpenMedium(Bstr(pszFilenameOrUuid).raw(),
+ enmDevType,
+ enmAccessMode,
+ fForceNewUuidOnOpen,
+ pMedium.asOutParam());
+
return rc;
}
@@ -343,7 +303,6 @@ int handleCreateHardDisk(HandlerArg *a)
}
/* check the outcome */
- bool fUnknownParent = false;
ComPtr<IMedium> parentHardDisk;
if (fBase)
{
@@ -372,9 +331,9 @@ int handleCreateHardDisk(HandlerArg *a)
else
format = pszExt;
}
- rc = findOrOpenMedium(a, diffparent, DeviceType_HardDisk, AccessMode_ReadWrite,
- parentHardDisk, false /* fForceNewUuidOnOpen */,
- &fUnknownParent);
+ rc = openMedium(a, diffparent, DeviceType_HardDisk,
+ AccessMode_ReadWrite, parentHardDisk,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
if (FAILED(rc))
return 1;
if (parentHardDisk.isNull())
@@ -413,10 +372,19 @@ int handleCreateHardDisk(HandlerArg *a)
if (SUCCEEDED(rc) && hardDisk)
{
ComPtr<IProgress> progress;
+ com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+ for (ULONG i = 0; i < l_variants.size(); ++i)
+ {
+ ULONG temp = DiskVariant;
+ temp &= 1<<i;
+ l_variants [i] = (MediumVariant_T)temp;
+ }
+
if (fBase)
- CHECK_ERROR(hardDisk, CreateBaseStorage(size, DiskVariant, progress.asOutParam()));
+ CHECK_ERROR(hardDisk, CreateBaseStorage(size, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
else
- CHECK_ERROR(parentHardDisk, CreateDiffStorage(hardDisk, DiskVariant, progress.asOutParam()));
+ CHECK_ERROR(parentHardDisk, CreateDiffStorage(hardDisk, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
if (SUCCEEDED(rc) && progress)
{
rc = showProgress(progress);
@@ -430,8 +398,6 @@ int handleCreateHardDisk(HandlerArg *a)
}
CHECK_ERROR(hardDisk, Close());
- if (!fBase && fUnknownParent)
- CHECK_ERROR(parentHardDisk, Close());
}
return SUCCEEDED(rc) ? 0 : 1;
}
@@ -444,6 +410,7 @@ static const RTGETOPTDEF g_aModifyHardDiskOptions[] =
{ "--autoreset", 'z', RTGETOPT_REQ_STRING },
{ "-autoreset", 'z', RTGETOPT_REQ_STRING }, // deprecated
{ "autoreset", 'z', RTGETOPT_REQ_STRING }, // deprecated
+ { "--property", 'p', RTGETOPT_REQ_STRING },
{ "--compact", 'c', RTGETOPT_REQ_NOTHING },
{ "-compact", 'c', RTGETOPT_REQ_NOTHING }, // deprecated
{ "compact", 'c', RTGETOPT_REQ_NOTHING }, // deprecated
@@ -458,11 +425,15 @@ int handleModifyHardDisk(HandlerArg *a)
ComPtr<IMedium> hardDisk;
MediumType_T DiskType;
bool AutoReset = false;
- bool fModifyDiskType = false, fModifyAutoReset = false, fModifyCompact = false;
+ SafeArray<BSTR> mediumPropNames;
+ SafeArray<BSTR> mediumPropValues;
+ bool fModifyDiskType = false;
+ bool fModifyAutoReset = false;
+ bool fModifyProperties = false;
+ bool fModifyCompact = false;
bool fModifyResize = false;
uint64_t cbResize = 0;
const char *FilenameOrUuid = NULL;
- bool unknown = false;
int c;
RTGETOPTUNION ValueUnion;
@@ -488,6 +459,38 @@ int handleModifyHardDisk(HandlerArg *a)
fModifyAutoReset = true;
break;
+ case 'p': // --property
+ {
+ /* Parse 'name=value' */
+ char *pszProperty = RTStrDup(ValueUnion.psz);
+ if (pszProperty)
+ {
+ char *pDelimiter = strchr(pszProperty, '=');
+ if (pDelimiter)
+ {
+ *pDelimiter = '\0';
+
+ Bstr bstrName(pszProperty);
+ Bstr bstrValue(&pDelimiter[1]);
+ bstrName.detachTo(mediumPropNames.appendedRaw());
+ bstrValue.detachTo(mediumPropValues.appendedRaw());
+ fModifyProperties = true;
+ }
+ else
+ {
+ errorArgument("Invalid --property argument '%s'", ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ RTStrFree(pszProperty);
+ }
+ else
+ {
+ RTStrmPrintf(g_pStdErr, "Error: Failed to allocate memory for medium property '%s'\n", ValueUnion.psz);
+ rc = E_FAIL;
+ }
+ break;
+ }
+
case 'c': // --compact
fModifyCompact = true;
break;
@@ -529,16 +532,13 @@ int handleModifyHardDisk(HandlerArg *a)
if (!FilenameOrUuid)
return errorSyntax(USAGE_MODIFYHD, "Disk name or UUID required");
- if (!fModifyDiskType && !fModifyAutoReset && !fModifyCompact && !fModifyResize)
+ if (!fModifyDiskType && !fModifyAutoReset && !fModifyProperties && !fModifyCompact && !fModifyResize)
return errorSyntax(USAGE_MODIFYHD, "No operation specified");
- /* Depending on the operation the medium must be in the registry or
- * may be opened on demand. */
- if (fModifyDiskType || fModifyAutoReset)
- rc = findMedium(a, FilenameOrUuid, DeviceType_HardDisk, false /* fSilent */, hardDisk);
- else
- rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, AccessMode_ReadWrite,
- hardDisk, false /* fForceNewUuidOnOpen */, &unknown);
+ /* Always open the medium if necessary, there is no other way. */
+ rc = openMedium(a, FilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, hardDisk,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
if (FAILED(rc))
return 1;
if (hardDisk.isNull())
@@ -561,6 +561,11 @@ int handleModifyHardDisk(HandlerArg *a)
CHECK_ERROR(hardDisk, COMSETTER(AutoReset)(AutoReset));
}
+ if (fModifyProperties)
+ {
+ CHECK_ERROR(hardDisk, SetProperties(ComSafeArrayAsInParam(mediumPropNames), ComSafeArrayAsInParam(mediumPropValues)));
+ }
+
if (fModifyCompact)
{
ComPtr<IProgress> progress;
@@ -597,9 +602,6 @@ int handleModifyHardDisk(HandlerArg *a)
}
}
- if (unknown)
- hardDisk->Close();
-
return SUCCEEDED(rc) ? 0 : 1;
}
@@ -691,11 +693,10 @@ int handleCloneHardDisk(HandlerArg *a)
ComPtr<IMedium> srcDisk;
ComPtr<IMedium> dstDisk;
- bool fSrcUnknown = false;
- bool fDstUnknown = false;
- rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, AccessMode_ReadOnly,
- srcDisk, false /* fForceNewUuidOnOpen */, &fSrcUnknown);
+ rc = openMedium(a, pszSrc, DeviceType_HardDisk, AccessMode_ReadOnly,
+ srcDisk, false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
if (FAILED(rc))
return 1;
@@ -704,8 +705,10 @@ int handleCloneHardDisk(HandlerArg *a)
/* open/create destination hard disk */
if (fExisting)
{
- rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, AccessMode_ReadWrite,
- dstDisk, false /* fForceNewUuidOnOpen */, &fDstUnknown);
+ rc = openMedium(a, pszDst, DeviceType_HardDisk,
+ AccessMode_ReadWrite, dstDisk,
+ false /* fForceNewUuidOnOpen */,
+ false /* fSilent */);
if (FAILED(rc))
break;
@@ -722,11 +725,19 @@ int handleCloneHardDisk(HandlerArg *a)
rc = createHardDisk(a, Utf8Str(format).c_str(), pszDst, dstDisk);
if (FAILED(rc))
break;
- fDstUnknown = true;
}
ComPtr<IProgress> progress;
- CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, DiskVariant, NULL, progress.asOutParam()));
+ com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+ for (ULONG i = 0; i < l_variants.size(); ++i)
+ {
+ ULONG temp = DiskVariant;
+ temp &= 1<<i;
+ l_variants [i] = (MediumVariant_T)temp;
+ }
+
+ CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, ComSafeArrayAsInParam(l_variants), NULL, progress.asOutParam()));
rc = showProgress(progress);
CHECK_PROGRESS_ERROR_BREAK(progress, ("Failed to clone hard disk"));
@@ -739,17 +750,6 @@ int handleCloneHardDisk(HandlerArg *a)
}
while (0);
- if (fDstUnknown && !dstDisk.isNull())
- {
- /* forget the created clone */
- dstDisk->Close();
- }
- if (fSrcUnknown)
- {
- /* close the unknown hard disk to forget it again */
- srcDisk->Close();
- }
-
return SUCCEEDED(rc) ? 0 : 1;
}
@@ -797,14 +797,15 @@ RTEXITCODE handleConvertFromRaw(int argc, char *argv[])
break;
case 'm': // --variant
- MediumVariant_T DiskVariant;
+ {
+ MediumVariant_T DiskVariant = MediumVariant_Standard;
rc = parseDiskVariant(ValueUnion.psz, &DiskVariant);
if (RT_FAILURE(rc))
return errorArgument("Invalid hard disk variant '%s'", ValueUnion.psz);
/// @todo cleaner solution than assuming 1:1 mapping?
uImageFlags = (unsigned)DiskVariant;
break;
-
+ }
case VINF_GETOPT_NOT_OPTION:
if (!srcfilename)
{
@@ -935,106 +936,73 @@ out:
return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
-static const RTGETOPTDEF g_aShowHardDiskInfoOptions[] =
-{
- { "--dummy", 256, RTGETOPT_REQ_NOTHING }, // placeholder for C++
-};
-
-int handleShowHardDiskInfo(HandlerArg *a)
+HRESULT showMediumInfo(const ComPtr<IVirtualBox> &pVirtualBox,
+ const ComPtr<IMedium> &pMedium,
+ const char *pszParentUUID,
+ bool fOptLong)
{
- HRESULT rc;
- const char *FilenameOrUuid = NULL;
-
- int c;
- RTGETOPTUNION ValueUnion;
- RTGETOPTSTATE GetState;
- // start at 0 because main() has hacked both the argc and argv given to us
- RTGetOptInit(&GetState, a->argc, a->argv, g_aShowHardDiskInfoOptions, RT_ELEMENTS(g_aShowHardDiskInfoOptions),
- 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
- while ((c = RTGetOpt(&GetState, &ValueUnion)))
- {
- switch (c)
- {
- case VINF_GETOPT_NOT_OPTION:
- if (!FilenameOrUuid)
- FilenameOrUuid = ValueUnion.psz;
- else
- return errorSyntax(USAGE_SHOWHDINFO, "Invalid parameter '%s'", ValueUnion.psz);
- break;
-
- default:
- if (c > 0)
- {
- if (RT_C_IS_PRINT(c))
- return errorSyntax(USAGE_SHOWHDINFO, "Invalid option -%c", c);
- else
- return errorSyntax(USAGE_SHOWHDINFO, "Invalid option case %i", c);
- }
- else if (c == VERR_GETOPT_UNKNOWN_OPTION)
- return errorSyntax(USAGE_SHOWHDINFO, "unknown option: %s\n", ValueUnion.psz);
- else if (ValueUnion.pDef)
- return errorSyntax(USAGE_SHOWHDINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
- else
- return errorSyntax(USAGE_SHOWHDINFO, "error: %Rrs", c);
- }
- }
-
- /* check for required options */
- if (!FilenameOrUuid)
- return errorSyntax(USAGE_SHOWHDINFO, "Disk name or UUID required");
-
- ComPtr<IMedium> hardDisk;
- bool unknown = false;
-
- rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, AccessMode_ReadOnly,
- hardDisk, false /* fForceNewUuidOnOpen */, &unknown);
- if (FAILED(rc))
- return 1;
-
+ HRESULT rc = S_OK;
do
{
Bstr uuid;
- hardDisk->COMGETTER(Id)(uuid.asOutParam());
- RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
+ pMedium->COMGETTER(Id)(uuid.asOutParam());
+ RTPrintf("UUID: %ls\n", uuid.raw());
+ if (pszParentUUID)
+ RTPrintf("Parent UUID: %s\n", pszParentUUID);
/* check for accessibility */
- /// @todo NEWMEDIA check accessibility of all parents
- /// @todo NEWMEDIA print the full state value
- MediumState_T state;
- CHECK_ERROR_BREAK(hardDisk, RefreshState(&state));
- RTPrintf("Accessible: %s\n", state != MediumState_Inaccessible ? "yes" : "no");
+ MediumState_T enmState;
+ CHECK_ERROR_BREAK(pMedium, RefreshState(&enmState));
+ pMedium->RefreshState(&enmState);
+ const char *pszState = "unknown";
+ switch (enmState)
+ {
+ case MediumState_NotCreated:
+ pszState = "not created";
+ break;
+ case MediumState_Created:
+ pszState = "created";
+ break;
+ case MediumState_LockedRead:
+ pszState = "locked read";
+ break;
+ case MediumState_LockedWrite:
+ pszState = "locked write";
+ break;
+ case MediumState_Inaccessible:
+ pszState = "inaccessible";
+ break;
+ case MediumState_Creating:
+ pszState = "creating";
+ break;
+ case MediumState_Deleting:
+ pszState = "deleting";
+ break;
+ }
+ RTPrintf("State: %s\n", pszState);
- if (state == MediumState_Inaccessible)
+ if (fOptLong && enmState == MediumState_Inaccessible)
{
Bstr err;
- CHECK_ERROR_BREAK(hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
- RTPrintf("Access Error: %ls\n", err.raw());
+ CHECK_ERROR_BREAK(pMedium, COMGETTER(LastAccessError)(err.asOutParam()));
+ RTPrintf("Access Error: %ls\n", err.raw());
}
- Bstr description;
- hardDisk->COMGETTER(Description)(description.asOutParam());
- if (!description.isEmpty())
+ if (fOptLong)
{
- RTPrintf("Description: %ls\n", description.raw());
+ Bstr description;
+ pMedium->COMGETTER(Description)(description.asOutParam());
+ if (!description.isEmpty())
+ RTPrintf("Description: %ls\n", description.raw());
}
- LONG64 logicalSize;
- hardDisk->COMGETTER(LogicalSize)(&logicalSize);
- RTPrintf("Logical size: %lld MBytes\n", logicalSize >> 20);
- LONG64 actualSize;
- hardDisk->COMGETTER(Size)(&actualSize);
- RTPrintf("Current size on disk: %lld MBytes\n", actualSize >> 20);
-
- ComPtr <IMedium> parent;
- hardDisk->COMGETTER(Parent)(parent.asOutParam());
-
MediumType_T type;
- hardDisk->COMGETTER(Type)(&type);
+ pMedium->COMGETTER(Type)(&type);
const char *typeStr = "unknown";
switch (type)
{
case MediumType_Normal:
- if (!parent.isNull())
+ if (pszParentUUID && Guid(pszParentUUID).isValid())
typeStr = "normal (differencing)";
else
typeStr = "normal (base)";
@@ -1055,78 +1023,215 @@ int handleShowHardDiskInfo(HandlerArg *a)
typeStr = "multiattach";
break;
}
- RTPrintf("Type: %s\n", typeStr);
+ RTPrintf("Type: %s\n", typeStr);
+
+ /* print out information specific for differencing hard disks */
+ if (fOptLong && pszParentUUID && Guid(pszParentUUID).isValid())
+ {
+ BOOL autoReset = FALSE;
+ pMedium->COMGETTER(AutoReset)(&autoReset);
+ RTPrintf("Auto-Reset: %s\n", autoReset ? "on" : "off");
+ }
+
+ Bstr loc;
+ pMedium->COMGETTER(Location)(loc.asOutParam());
+ RTPrintf("Location: %ls\n", loc.raw());
Bstr format;
- hardDisk->COMGETTER(Format)(format.asOutParam());
- RTPrintf("Storage format: %ls\n", format.raw());
- ULONG variant;
- hardDisk->COMGETTER(Variant)(&variant);
- const char *variantStr = "unknown";
- switch (variant & ~(MediumVariant_Fixed | MediumVariant_Diff))
+ pMedium->COMGETTER(Format)(format.asOutParam());
+ RTPrintf("Storage format: %ls\n", format.raw());
+
+ if (fOptLong)
{
- case MediumVariant_VmdkSplit2G:
- variantStr = "split2G";
- break;
- case MediumVariant_VmdkStreamOptimized:
- variantStr = "streamOptimized";
- break;
- case MediumVariant_VmdkESX:
- variantStr = "ESX";
- break;
- case MediumVariant_Standard:
- variantStr = "default";
- break;
+ com::SafeArray<MediumVariant_T> safeArray_variant;
+
+ pMedium->COMGETTER(Variant)(ComSafeArrayAsOutParam(safeArray_variant));
+ ULONG variant=0;
+ for (size_t i = 0; i < safeArray_variant.size(); i++)
+ variant |= safeArray_variant[i];
+
+ const char *variantStr = "unknown";
+ switch (variant & ~(MediumVariant_Fixed | MediumVariant_Diff))
+ {
+ case MediumVariant_VmdkSplit2G:
+ variantStr = "split2G";
+ break;
+ case MediumVariant_VmdkStreamOptimized:
+ variantStr = "streamOptimized";
+ break;
+ case MediumVariant_VmdkESX:
+ variantStr = "ESX";
+ break;
+ case MediumVariant_Standard:
+ variantStr = "default";
+ break;
+ }
+ const char *variantTypeStr = "dynamic";
+ if (variant & MediumVariant_Fixed)
+ variantTypeStr = "fixed";
+ else if (variant & MediumVariant_Diff)
+ variantTypeStr = "differencing";
+ RTPrintf("Format variant: %s %s\n", variantTypeStr, variantStr);
+ }
+
+ LONG64 logicalSize;
+ pMedium->COMGETTER(LogicalSize)(&logicalSize);
+ RTPrintf("Capacity: %lld MBytes\n", logicalSize >> 20);
+ if (fOptLong)
+ {
+ LONG64 actualSize;
+ pMedium->COMGETTER(Size)(&actualSize);
+ RTPrintf("Size on disk: %lld MBytes\n", actualSize >> 20);
}
- const char *variantTypeStr = "dynamic";
- if (variant & MediumVariant_Fixed)
- variantTypeStr = "fixed";
- else if (variant & MediumVariant_Diff)
- variantTypeStr = "differencing";
- RTPrintf("Format variant: %s %s\n", variantTypeStr, variantStr);
- /// @todo also dump config parameters (iSCSI)
+ if (fOptLong)
+ {
+ com::SafeArray<BSTR> names;
+ com::SafeArray<BSTR> values;
+ pMedium->GetProperties(Bstr().raw(), ComSafeArrayAsOutParam(names), ComSafeArrayAsOutParam(values));
+ size_t cNames = names.size();
+ size_t cValues = values.size();
+ bool fFirst = true;
+ for (size_t i = 0; i < cNames; i++)
+ {
+ Bstr value;
+ if (i < cValues)
+ value = values[i];
+ RTPrintf("%s%ls=%ls\n",
+ fFirst ? "Property: " : " ",
+ names[i], value.raw());
+ }
+ }
- if (!unknown)
+ if (fOptLong)
{
+ bool fFirst = true;
com::SafeArray<BSTR> machineIds;
- hardDisk->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
- for (size_t j = 0; j < machineIds.size(); ++ j)
+ pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
+ for (size_t i = 0; i < machineIds.size(); i++)
{
ComPtr<IMachine> machine;
- CHECK_ERROR(a->virtualBox, FindMachine(machineIds[j], machine.asOutParam()));
- ASSERT(machine);
- Bstr name;
- machine->COMGETTER(Name)(name.asOutParam());
- machine->COMGETTER(Id)(uuid.asOutParam());
- RTPrintf("%s%ls (UUID: %ls)\n",
- j == 0 ? "In use by VMs: " : " ",
- name.raw(), machineIds[j]);
+ CHECK_ERROR(pVirtualBox, FindMachine(machineIds[i], machine.asOutParam()));
+ if (machine)
+ {
+ Bstr name;
+ machine->COMGETTER(Name)(name.asOutParam());
+ machine->COMGETTER(Id)(uuid.asOutParam());
+ RTPrintf("%s%ls (UUID: %ls)",
+ fFirst ? "In use by VMs: " : " ",
+ name.raw(), machineIds[i]);
+ fFirst = false;
+ com::SafeArray<BSTR> snapshotIds;
+ pMedium->GetSnapshotIds(machineIds[i],
+ ComSafeArrayAsOutParam(snapshotIds));
+ for (size_t j = 0; j < snapshotIds.size(); j++)
+ {
+ ComPtr<ISnapshot> snapshot;
+ machine->FindSnapshot(snapshotIds[j], snapshot.asOutParam());
+ if (snapshot)
+ {
+ Bstr snapshotName;
+ snapshot->COMGETTER(Name)(snapshotName.asOutParam());
+ RTPrintf(" [%ls (UUID: %ls)]", snapshotName.raw(), snapshotIds[j]);
+ }
+ }
+ RTPrintf("\n");
+ }
}
- /// @todo NEWMEDIA check usage in snapshots too
- /// @todo NEWMEDIA also list children
}
- Bstr loc;
- hardDisk->COMGETTER(Location)(loc.asOutParam());
- RTPrintf("Location: %ls\n", loc.raw());
-
- /* print out information specific for differencing hard disks */
- if (!parent.isNull())
+ if (fOptLong)
{
- BOOL autoReset = FALSE;
- hardDisk->COMGETTER(AutoReset)(&autoReset);
- RTPrintf("Auto-Reset: %s\n", autoReset ? "on" : "off");
+ com::SafeIfaceArray<IMedium> children;
+ pMedium->COMGETTER(Children)(ComSafeArrayAsOutParam(children));
+ bool fFirst = true;
+ for (size_t i = 0; i < children.size(); i++)
+ {
+ ComPtr<IMedium> pChild(children[i]);
+ if (pChild)
+ {
+ Bstr childUUID;
+ pChild->COMGETTER(Id)(childUUID.asOutParam());
+ RTPrintf("%s%ls\n",
+ fFirst ? "Child UUIDs: " : " ",
+ childUUID.raw());
+ fFirst = false;
+ }
+ }
}
}
while (0);
- if (unknown)
+ return rc;
+}
+
+static const RTGETOPTDEF g_aShowHardDiskInfoOptions[] =
+{
+ { "--dummy", 256, RTGETOPT_REQ_NOTHING }, // placeholder for C++
+};
+
+int handleShowHardDiskInfo(HandlerArg *a)
+{
+ HRESULT rc;
+ const char *FilenameOrUuid = NULL;
+
+ int c;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ // start at 0 because main() has hacked both the argc and argv given to us
+ RTGetOptInit(&GetState, a->argc, a->argv, g_aShowHardDiskInfoOptions, RT_ELEMENTS(g_aShowHardDiskInfoOptions),
+ 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+ while ((c = RTGetOpt(&GetState, &ValueUnion)))
{
- /* close the unknown hard disk to forget it again */
- hardDisk->Close();
+ switch (c)
+ {
+ case VINF_GETOPT_NOT_OPTION:
+ if (!FilenameOrUuid)
+ FilenameOrUuid = ValueUnion.psz;
+ else
+ return errorSyntax(USAGE_SHOWHDINFO, "Invalid parameter '%s'", ValueUnion.psz);
+ break;
+
+ default:
+ if (c > 0)
+ {
+ if (RT_C_IS_PRINT(c))
+ return errorSyntax(USAGE_SHOWHDINFO, "Invalid option -%c", c);
+ else
+ return errorSyntax(USAGE_SHOWHDINFO, "Invalid option case %i", c);
+ }
+ else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+ return errorSyntax(USAGE_SHOWHDINFO, "unknown option: %s\n", ValueUnion.psz);
+ else if (ValueUnion.pDef)
+ return errorSyntax(USAGE_SHOWHDINFO, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
+ else
+ return errorSyntax(USAGE_SHOWHDINFO, "error: %Rrs", c);
+ }
}
+ /* check for required options */
+ if (!FilenameOrUuid)
+ return errorSyntax(USAGE_SHOWHDINFO, "Disk name or UUID required");
+
+ ComPtr<IMedium> hardDisk;
+ rc = openMedium(a, FilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadOnly, hardDisk,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
+ if (FAILED(rc))
+ return 1;
+
+ Utf8Str strParentUUID("base");
+ ComPtr<IMedium> parent;
+ hardDisk->COMGETTER(Parent)(parent.asOutParam());
+ if (!parent.isNull())
+ {
+ Bstr bstrParentUUID;
+ parent->COMGETTER(Id)(bstrParentUUID.asOutParam());
+ strParentUUID = bstrParentUUID;
+ }
+
+ rc = showMediumInfo(a->virtualBox, hardDisk, strParentUUID.c_str(), true);
+
return SUCCEEDED(rc) ? 0 : 1;
}
@@ -1215,11 +1320,17 @@ int handleCloseMedium(HandlerArg *a)
ComPtr<IMedium> medium;
if (cmd == CMD_DISK)
- rc = findMedium(a, FilenameOrUuid, DeviceType_HardDisk, false /* fSilent */, medium);
+ rc = openMedium(a, FilenameOrUuid, DeviceType_HardDisk,
+ AccessMode_ReadWrite, medium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
else if (cmd == CMD_DVD)
- rc = findMedium(a, FilenameOrUuid, DeviceType_DVD, false /* fSilent */, medium);
+ rc = openMedium(a, FilenameOrUuid, DeviceType_DVD,
+ AccessMode_ReadOnly, medium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
else if (cmd == CMD_FLOPPY)
- rc = findMedium(a, FilenameOrUuid, DeviceType_Floppy, false /* fSilent */, medium);
+ rc = openMedium(a, FilenameOrUuid, DeviceType_Floppy,
+ AccessMode_ReadWrite, medium,
+ false /* fForceNewUuidOnOpen */, false /* fSilent */);
if (SUCCEEDED(rc) && medium)
{