diff options
Diffstat (limited to 'src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp')
| -rw-r--r-- | src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp | 577 |
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) { |
