Lines Matching refs:pImage
244 PVMDKIMAGE pImage;
327 * on a regular basis to avoid passing pImage references to functions
329 struct VMDKIMAGE *pImage;
480 PVMDKIMAGE pImage;
528 static int vmdkFreeExtentData(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
531 static int vmdkCreateExtents(PVMDKIMAGE pImage, unsigned cExtents);
532 static int vmdkFlushImage(PVMDKIMAGE pImage, PVDIOCTX pIoCtx);
533 static int vmdkSetImageComment(PVMDKIMAGE pImage, const char *pszComment);
534 static int vmdkFreeImage(PVMDKIMAGE pImage, bool fDelete);
543 static int vmdkFileOpen(PVMDKIMAGE pImage, PVMDKFILE *ppVmdkFile,
549 for (pVmdkFile = pImage->pFiles;
581 rc = vdIfIoIntFileOpen(pImage->pIfIo, pszFilename, fOpen,
586 pVmdkFile->pImage = pImage;
587 pVmdkFile->pNext = pImage->pFiles;
588 if (pImage->pFiles)
589 pImage->pFiles->pPrev = pVmdkFile;
590 pImage->pFiles = pVmdkFile;
606 static int vmdkFileClose(PVMDKIMAGE pImage, PVMDKFILE *ppVmdkFile, bool fDelete)
630 pImage->pFiles = pNext;
632 rc = vdIfIoIntFileClose(pImage->pIfIo, pVmdkFile->pStorage);
634 rc = vdIfIoIntFileDelete(pImage->pIfIo, pVmdkFile->pszFilename);
680 DECLINLINE(int) vmdkFileInflateSync(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
694 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
720 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
742 InflateState.pImage = pImage;
756 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: Compressed image is corrupted '%s'"), pExtent->pszFullname);
789 DECLINLINE(int) vmdkFileDeflateSync(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
798 DeflateState.pImage = pImage;
834 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
846 static int vmdkFileCheckAllClose(PVMDKIMAGE pImage)
851 Assert(pImage->pFiles == NULL);
852 for (pVmdkFile = pImage->pFiles;
858 pImage->pFiles = pVmdkFile->pNext;
860 rc2 = vmdkFileClose(pImage, &pVmdkFile, pVmdkFile->fDelete);
980 static int vmdkAllocStreamBuffers(PVMDKIMAGE pImage, PVMDKEXTENT pExtent)
984 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
1016 static int vmdkAllocGrainDirectory(PVMDKIMAGE pImage, PVMDKEXTENT pExtent)
1047 static int vmdkReadGrainDirectory(PVMDKIMAGE pImage, PVMDKEXTENT pExtent)
1064 rc = vmdkAllocGrainDirectory(pImage, pExtent);
1070 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
1076 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not read grain directory in '%s': %Rrc"), pExtent->pszFullname);
1083 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS))
1087 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
1093 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not read redundant grain directory in '%s'"), pExtent->pszFullname);
1134 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname);
1158 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname);
1207 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
1212 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
1218 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
1223 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
1229 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS,
1249 static int vmdkCreateGrainDirectory(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
1276 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
1286 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pExtent->pFile->pStorage, cbOverhead);
1293 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
1304 rc = vmdkAllocStreamBuffers(pImage, pExtent);
1308 rc = vmdkAllocGrainDirectory(pImage, pExtent);
1325 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
1330 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write new redundant grain directory entry in '%s'"), pExtent->pszFullname);
1343 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
1348 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write new grain directory entry in '%s'"), pExtent->pszFullname);
1361 static int vmdkStringUnquote(PVMDKIMAGE pImage, const char *pszStr,
1382 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrectly quoted value in descriptor in '%s'"), pImage->pszFilename);
1396 static int vmdkDescInitStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1404 return vdIfError(pImage->pIfError, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
1439 static int vmdkDescSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1478 return vdIfError(pImage->pIfError, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
1521 return vdIfError(pImage->pIfError, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
1564 static int vmdkDescBaseGetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1573 int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
1580 static int vmdkDescBaseSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1588 int rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDesc, pszKey,
1594 static void vmdkDescExtRemoveDummy(PVMDKIMAGE pImage,
1622 static int vmdkDescExtInsert(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1668 return vdIfError(pImage->pIfError, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
1697 static int vmdkDescDDBGetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1706 int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
1713 static int vmdkDescDDBGetU32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1722 int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
1730 static int vmdkDescDDBGetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1739 int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
1747 static int vmdkDescDDBSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1761 rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDDB, pszKey,
1768 static int vmdkDescDDBSetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1776 int rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDDB, pszKey,
1782 static int vmdkDescDDBSetU32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
1790 int rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDDB, pszKey,
1796 static int vmdkPreprocessDescriptor(PVMDKIMAGE pImage, char *pDescData,
1810 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
1820 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: unsupported end of line in descriptor in '%s'"), pImage->pszFilename);
1845 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: descriptor does not start as expected in '%s'"), pImage->pszFilename);
1865 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrect ordering of entries in descriptor in '%s'"), pImage->pszFilename);
1880 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrect ordering of entries in descriptor in '%s'"), pImage->pszFilename);
1895 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrect ordering of entries in descriptor in '%s'"), pImage->pszFilename);
1914 static int vmdkDescSetPCHSGeometry(PVMDKIMAGE pImage,
1917 int rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1922 rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1927 rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1933 static int vmdkDescSetLCHSGeometry(PVMDKIMAGE pImage,
1936 int rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1941 rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1947 rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor,
1953 static int vmdkCreateDescriptor(PVMDKIMAGE pImage, char *pDescData,
1967 rc = vmdkDescInitStr(pImage, pDescriptor, "# Disk DescriptorFile");
1970 rc = vmdkDescInitStr(pImage, pDescriptor, "version=1");
1974 rc = vmdkDescInitStr(pImage, pDescriptor, "");
1977 rc = vmdkDescInitStr(pImage, pDescriptor, "# Extent description");
1980 rc = vmdkDescInitStr(pImage, pDescriptor, "NOACCESS 0 ZERO ");
1984 rc = vmdkDescInitStr(pImage, pDescriptor, "");
1988 rc = vmdkDescInitStr(pImage, pDescriptor, "# The disk Data Base ");
1991 rc = vmdkDescInitStr(pImage, pDescriptor, "#DDB");
1994 rc = vmdkDescInitStr(pImage, pDescriptor, "");
1997 rc = vmdkDescInitStr(pImage, pDescriptor, "ddb.virtualHWVersion = \"4\"");
2006 rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDesc,
2010 rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDesc,
2015 rc = vmdkDescDDBSetStr(pImage, pDescriptor, "ddb.adapterType", "ide");
2023 static int vmdkParseDescriptor(PVMDKIMAGE pImage, char *pDescData,
2031 rc = vmdkPreprocessDescriptor(pImage, pDescData, cbDescData,
2032 &pImage->Descriptor);
2038 rc = vmdkDescBaseGetU32(&pImage->Descriptor, "version", &uVersion);
2040 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error finding key 'version' in descriptor in '%s'"), pImage->pszFilename);
2042 return vdIfError(pImage->pIfError, VERR_VD_VMDK_UNSUPPORTED_VERSION, RT_SRC_POS, N_("VMDK: unsupported format version in descriptor in '%s'"), pImage->pszFilename);
2046 rc = vmdkDescBaseGetStr(pImage, &pImage->Descriptor, "createType",
2049 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot get image type from descriptor in '%s'"), pImage->pszFilename);
2052 pImage->uImageFlags |= VD_VMDK_IMAGE_FLAGS_SPLIT_2G;
2055 pImage->uImageFlags |= VD_VMDK_IMAGE_FLAGS_RAWDISK;
2057 pImage->uImageFlags |= VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED;
2059 pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED | VD_VMDK_IMAGE_FLAGS_ESX;
2063 for (uLine = pImage->Descriptor.uFirstExtent, cExtents = 0;
2065 uLine = pImage->Descriptor.aNextLines[uLine], cExtents++)
2068 if (!pImage->pDescData && cExtents != 1)
2071 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: monolithic image may only have one extent in '%s'"), pImage->pszFilename);
2074 if (pImage->pDescData)
2077 rc = vmdkCreateExtents(pImage, cExtents);
2082 for (i = 0, uLine = pImage->Descriptor.uFirstExtent;
2083 i < cExtents; i++, uLine = pImage->Descriptor.aNextLines[uLine])
2085 char *pszLine = pImage->Descriptor.aLines[uLine];
2090 pImage->pExtents[i].enmAccess = VMDKACCESS_READWRITE;
2095 pImage->pExtents[i].enmAccess = VMDKACCESS_READONLY;
2100 pImage->pExtents[i].enmAccess = VMDKACCESS_NOACCESS;
2104 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2106 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2110 &pImage->pExtents[i].cNominalSectors);
2112 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2114 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2124 pImage->pExtents[i].enmType = VMDKETYPE_HOSTED_SPARSE;
2129 pImage->pExtents[i].enmType = VMDKETYPE_FLAT;
2134 pImage->pExtents[i].enmType = VMDKETYPE_ZERO;
2139 pImage->pExtents[i].enmType = VMDKETYPE_VMFS;
2143 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2145 if (pImage->pExtents[i].enmType == VMDKETYPE_ZERO)
2151 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2152 pImage->pExtents[i].pszBasename = NULL;
2158 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2162 rc = vmdkStringUnquote(pImage, pszLine, &pszBasename, &pszLine);
2165 pImage->pExtents[i].pszBasename = pszBasename;
2173 &pImage->pExtents[i].uSectorOffset);
2175 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2180 return vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename);
2185 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2187 &pImage->PCHSGeometry.cCylinders);
2189 pImage->PCHSGeometry.cCylinders = 0;
2191 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting PCHS geometry from extent description in '%s'"), pImage->pszFilename);
2192 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2194 &pImage->PCHSGeometry.cHeads);
2196 pImage->PCHSGeometry.cHeads = 0;
2198 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting PCHS geometry from extent description in '%s'"), pImage->pszFilename);
2199 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2201 &pImage->PCHSGeometry.cSectors);
2203 pImage->PCHSGeometry.cSectors = 0;
2205 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting PCHS geometry from extent description in '%s'"), pImage->pszFilename);
2206 if ( pImage->PCHSGeometry.cCylinders == 0
2207 || pImage->PCHSGeometry.cHeads == 0
2208 || pImage->PCHSGeometry.cHeads > 16
2209 || pImage->PCHSGeometry.cSectors == 0
2210 || pImage->PCHSGeometry.cSectors > 63)
2214 pImage->PCHSGeometry.cCylinders = 0;
2215 pImage->PCHSGeometry.cHeads = 16;
2216 pImage->PCHSGeometry.cSectors = 63;
2220 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2222 &pImage->LCHSGeometry.cCylinders);
2224 pImage->LCHSGeometry.cCylinders = 0;
2226 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting LCHS geometry from extent description in '%s'"), pImage->pszFilename);
2227 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2229 &pImage->LCHSGeometry.cHeads);
2231 pImage->LCHSGeometry.cHeads = 0;
2233 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting LCHS geometry from extent description in '%s'"), pImage->pszFilename);
2234 rc = vmdkDescDDBGetU32(pImage, &pImage->Descriptor,
2236 &pImage->LCHSGeometry.cSectors);
2238 pImage->LCHSGeometry.cSectors = 0;
2240 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting LCHS geometry from extent description in '%s'"), pImage->pszFilename);
2241 if ( pImage->LCHSGeometry.cCylinders == 0
2242 || pImage->LCHSGeometry.cHeads == 0
2243 || pImage->LCHSGeometry.cSectors == 0)
2245 pImage->LCHSGeometry.cCylinders = 0;
2246 pImage->LCHSGeometry.cHeads = 0;
2247 pImage->LCHSGeometry.cSectors = 0;
2251 rc = vmdkDescDDBGetUuid(pImage, &pImage->Descriptor, VMDK_DDB_IMAGE_UUID,
2252 &pImage->ImageUuid);
2258 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2259 RTUuidClear(&pImage->ImageUuid);
2262 rc = RTUuidCreate(&pImage->ImageUuid);
2265 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
2266 VMDK_DDB_IMAGE_UUID, &pImage->ImageUuid);
2268 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing image UUID in descriptor in '%s'"), pImage->pszFilename);
2275 rc = vmdkDescDDBGetUuid(pImage, &pImage->Descriptor,
2277 &pImage->ModificationUuid);
2283 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2284 RTUuidClear(&pImage->ModificationUuid);
2287 rc = RTUuidCreate(&pImage->ModificationUuid);
2290 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
2292 &pImage->ModificationUuid);
2294 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing image modification UUID in descriptor in '%s'"), pImage->pszFilename);
2301 rc = vmdkDescDDBGetUuid(pImage, &pImage->Descriptor, VMDK_DDB_PARENT_UUID,
2302 &pImage->ParentUuid);
2308 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2309 RTUuidClear(&pImage->ParentUuid);
2312 rc = RTUuidClear(&pImage->ParentUuid);
2315 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
2316 VMDK_DDB_PARENT_UUID, &pImage->ParentUuid);
2318 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent UUID in descriptor in '%s'"), pImage->pszFilename);
2325 rc = vmdkDescDDBGetUuid(pImage, &pImage->Descriptor,
2327 &pImage->ParentModificationUuid);
2333 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2334 RTUuidClear(&pImage->ParentModificationUuid);
2337 RTUuidClear(&pImage->ParentModificationUuid);
2338 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
2340 &pImage->ParentModificationUuid);
2342 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent modification UUID in descriptor in '%s'"), pImage->pszFilename);
2354 static int vmdkDescriptorPrepare(PVMDKIMAGE pImage, uint64_t cbLimit,
2371 for (unsigned i = 0; i < pImage->Descriptor.cLines; i++)
2373 const char *psz = pImage->Descriptor.aLines[i];
2384 rc = vdIfError(pImage->pIfError, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too long in '%s'"), pImage->pszFilename);
2427 static int vmdkWriteDescriptor(PVMDKIMAGE pImage, PVDIOCTX pIoCtx)
2436 if (pImage->pDescData)
2441 pDescFile = pImage->pFile;
2446 uOffset = VMDK_SECTOR2BYTE(pImage->pExtents[0].uDescriptorSector);
2447 cbLimit = VMDK_SECTOR2BYTE(pImage->pExtents[0].cDescriptorSectors);
2448 pDescFile = pImage->pExtents[0].pFile;
2454 rc = vmdkDescriptorPrepare(pImage, cbLimit, &pvDescriptor, &cbDescriptor);
2457 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pDescFile->pStorage,
2463 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename);
2468 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pDescFile->pStorage, cbDescriptor);
2470 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename);
2474 pImage->Descriptor.fDirty = false;
2485 static int vmdkValidateHeader(PVMDKIMAGE pImage, PVMDKEXTENT pExtent, const SparseExtentHeader *pHeader)
2490 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrect magic in sparse extent header in '%s'"), pExtent->pszFullname);
2495 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_UNSUPPORTED_VERSION, RT_SRC_POS, N_("VMDK: incorrect version in sparse extent header in '%s', not a VMDK 1.0/1.1 conforming file"), pExtent->pszFullname);
2504 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: corrupted by CR/LF translation in '%s'"), pExtent->pszFullname);
2514 static int vmdkReadBinaryMetaExtent(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
2523 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 0,
2528 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
2537 vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading extent header in '%s'"), pExtent->pszFullname);
2541 rc = vmdkValidateHeader(pImage, pExtent, &Header);
2549 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2551 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)))
2553 rc = vdIfIoIntFileGetSize(pImage->pIfIo, pExtent->pFile->pStorage, &cbFile);
2557 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot get size of '%s'"), pExtent->pszFullname);
2562 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
2566 && ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2567 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)))
2570 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
2576 vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading extent footer in '%s'"), pExtent->pszFullname);
2580 rc = vmdkValidateHeader(pImage, pExtent, &Header);
2595 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent embedded descriptor config in '%s'"), pExtent->pszFullname);
2611 && ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2612 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)))
2614 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: cannot resolve grain directory offset in '%s'"), pExtent->pszFullname);
2623 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: incorrect grain directory size in '%s'"), pExtent->pszFullname);
2643 vmdkFreeExtentData(pImage, pExtent, false);
2652 static int vmdkReadMetaExtent(PVMDKIMAGE pImage, PVMDKEXTENT pExtent)
2662 rc = vdIfIoIntFileGetSize(pImage->pIfIo, pExtent->pFile->pStorage, &cbExtentSize);
2665 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error getting size in '%s'"), pExtent->pszFullname);
2671 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: file size is not a multiple of 512 in '%s', file is truncated or otherwise garbled"), pExtent->pszFullname);
2683 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: invalid extent grain size %u in '%s'"), pExtent->cSectorsPerGrain, pExtent->pszFullname);
2692 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: grain table cache size problem in '%s'"), pExtent->pszFullname);
2696 rc = vmdkAllocStreamBuffers(pImage, pExtent);
2701 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
2704 if ( !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
2705 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
2706 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
2707 rc = vmdkReadGrainDirectory(pImage, pExtent);
2716 vmdkFreeExtentData(pImage, pExtent, false);
2724 static int vmdkWriteMetaSparseExtent(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
2735 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
2776 int rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
2780 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error writing extent header in '%s'"), pExtent->pszFullname);
2795 int rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 0,
2800 vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading ESX sparse extent header in '%s'"), pExtent->pszFullname);
2847 rc = vmdkReadGrainDirectory(pImage, pExtent);
2851 vmdkFreeExtentData(pImage, pExtent, false);
2879 * @param pImage Pointer to the image instance data.
2883 static int vmdkFreeExtentData(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
2897 rc =vmdkFileClose(pImage, &pExtent->pFile,
2920 static int vmdkAllocateGrainTableCache(PVMDKIMAGE pImage)
2925 for (unsigned i = 0; i < pImage->cExtents; i++)
2927 pExtent = &pImage->pExtents[i];
2935 pImage->pGTCache = (PVMDKGTCACHE)RTMemAllocZ(sizeof(VMDKGTCACHE));
2936 if (!pImage->pGTCache)
2940 PVMDKGTCACHEENTRY pGCE = &pImage->pGTCache->aGTCache[j];
2943 pImage->pGTCache->cEntries = VMDK_GT_CACHE_SIZE;
2954 static int vmdkCreateExtents(PVMDKIMAGE pImage, unsigned cExtents)
2971 pExtents[i].pImage = pImage;
2973 pImage->pExtents = pExtents;
2974 pImage->cExtents = cExtents;
2985 static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags)
2992 pImage->uOpenFlags = uOpenFlags;
2994 pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
2995 pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
2996 AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
3005 rc = vmdkFileOpen(pImage, &pFile, pImage->pszFilename,
3013 pImage->pFile = pFile;
3016 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pFile->pStorage, 0,
3020 vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading the magic number in '%s'"), pImage->pszFilename);
3029 rc = vmdkCreateExtents(pImage, 1);
3034 pExtent = &pImage->pExtents[0];
3036 pImage->pFile = NULL;
3037 pExtent->pszFullname = RTPathAbsDup(pImage->pszFilename);
3043 rc = vmdkReadBinaryMetaExtent(pImage, pExtent, true /* fMagicAlreadyRead */);
3051 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: monolithic image without descriptor in '%s'"), pImage->pszFilename);
3057 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
3072 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
3079 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: read error for descriptor in '%s'"), pExtent->pszFullname);
3083 rc = vmdkParseDescriptor(pImage, pExtent->pDescData,
3088 if ( pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED
3095 rc = vmdkReadMetaExtent(pImage, pExtent);
3101 && !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
3114 rc = vdIfIoIntFileGetSize(pImage->pIfIo, pFile->pStorage, &cbFileSize);
3121 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: descriptor in '%s' is too short"), pImage->pszFilename);
3131 pImage->cbDescAlloc = RT_MAX(VMDK_SECTOR2BYTE(20), cbSize);
3132 pImage->pDescData = (char *)RTMemAllocZ(pImage->cbDescAlloc);
3133 if (!pImage->pDescData)
3141 memcpy(pImage->pDescData, &u32Magic, sizeof(u32Magic));
3142 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pFile->pStorage, sizeof(u32Magic),
3143 pImage->pDescData + sizeof(u32Magic),
3144 RT_MIN(pImage->cbDescAlloc - sizeof(u32Magic),
3148 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: read error for descriptor in '%s'"), pImage->pszFilename);
3154 if (cbRead == pImage->cbDescAlloc)
3158 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: cannot read descriptor in '%s'"), pImage->pszFilename);
3163 rc = vmdkParseDescriptor(pImage, pImage->pDescData,
3164 pImage->cbDescAlloc);
3177 for (unsigned i = 0; i < pImage->cExtents; i++)
3179 pExtent = &pImage->pExtents[i];
3184 || ((pImage->pExtents[i].enmType == VMDKETYPE_FLAT) && (cFlatExtents > 0)))
3199 for (unsigned i = 0; i < pImage->cExtents; i++)
3201 pExtent = &pImage->pExtents[i];
3221 char *pszDirname = RTStrDup(pImage->pszFilename);
3244 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3254 rc = vmdkReadBinaryMetaExtent(pImage, pExtent,
3258 rc = vmdkReadMetaExtent(pImage, pExtent);
3271 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3295 if (pImage->PCHSGeometry.cCylinders == 0)
3297 uint64_t cCylinders = VMDK_BYTE2SECTOR(pImage->cbSize)
3298 / pImage->PCHSGeometry.cHeads
3299 / pImage->PCHSGeometry.cSectors;
3300 pImage->PCHSGeometry.cCylinders = (unsigned)RT_MIN(cCylinders, 16383);
3301 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
3302 && !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
3304 rc = vmdkDescSetPCHSGeometry(pImage, &pImage->PCHSGeometry);
3310 rc = vmdkFlushImage(pImage, NULL);
3315 pImage->cbSize = 0;
3316 for (unsigned i = 0; i < pImage->cExtents; i++)
3318 pExtent = &pImage->pExtents[i];
3330 pImage->cbSize += VMDK_SECTOR2BYTE(pExtent->cNominalSectors);
3333 for (unsigned i = 0; i < pImage->cExtents; i++)
3335 pExtent = &pImage->pExtents[i];
3336 if ( pImage->pExtents[i].enmType == VMDKETYPE_FLAT
3337 || pImage->pExtents[i].enmType == VMDKETYPE_ZERO)
3339 pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
3344 if ( !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
3345 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
3346 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
3347 rc = vmdkAllocateGrainTableCache(pImage);
3351 vmdkFreeImage(pImage, false);
3358 static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw,
3368 rc = vmdkCreateExtents(pImage, 1);
3370 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new extent list in '%s'"), pImage->pszFilename);
3371 pExtent = &pImage->pExtents[0];
3373 rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename,
3374 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3377 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pImage->pszFilename);
3397 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3398 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
3401 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not open raw disk file '%s'"), pExtent->pszFullname);
3418 return vdIfError(pImage->pIfError, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: incorrect partition data area ordering set up by the caller in '%s'"), pImage->pszFilename);
3429 rc = vmdkCreateExtents(pImage, cExtents);
3431 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new extent list in '%s'"), pImage->pszFilename);
3434 rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename,
3435 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3438 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pImage->pszFilename);
3443 const char *pszBase = RTPathFilename(pImage->pszFilename);
3446 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: invalid filename '%s'"), pImage->pszFilename);
3462 pExtent = &pImage->pExtents[cExtents++];
3474 pExtent = &pImage->pExtents[cExtents++];
3489 char *pszDirname = RTStrDup(pImage->pszFilename);
3505 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3506 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3509 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new partition data file '%s'"), pExtent->pszFullname);
3510 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
3515 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not write partition data to '%s'"), pExtent->pszFullname);
3540 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3541 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
3544 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not open raw partition file '%s'"), pExtent->pszFullname);
3561 pExtent = &pImage->pExtents[cExtents++];
3572 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType",
3576 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not set the image type in '%s'"), pImage->pszFilename);
3583 static int vmdkCreateRegularImage(PVMDKIMAGE pImage, uint64_t cbSize,
3601 rc = vmdkCreateExtents(pImage, cExtents);
3603 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new extent list in '%s'"), pImage->pszFilename);
3606 char *pszBasenameSubstr = RTPathFilename(pImage->pszFilename);
3613 rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename,
3614 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3617 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new sparse descriptor file '%s'"), pImage->pszFilename);
3620 pImage->pFile = NULL;
3625 PVMDKEXTENT pExtent = &pImage->pExtents[i];
3672 char *pszBasedirectory = RTStrDup(pImage->pszFilename);
3683 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3684 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3687 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pExtent->pszFullname);
3690 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pExtent->pFile->pStorage, cbExtent);
3692 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not set size of new file '%s'"), pExtent->pszFullname);
3713 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
3718 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: writing block failed for '%s'"), pImage->pszFilename);
3741 pExtent->cDescriptorSectors = VMDK_BYTE2SECTOR(pImage->cbDescAlloc);
3743 pExtent->pDescData = pImage->pDescData;
3744 pImage->pDescData = NULL;
3758 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
3784 rc = vmdkCreateGrainDirectory(pImage, pExtent,
3790 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new grain directory in '%s'"), pExtent->pszFullname);
3801 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_ESX)
3805 rc = vmdkDescDDBSetStr(pImage, &pImage->Descriptor, "ddb.adapterType", "lsilogic");
3807 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not set controller type to lsilogic in '%s'"), pImage->pszFilename);
3813 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_ESX)
3821 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
3829 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType",
3832 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not set the image type in '%s'"), pImage->pszFilename);
3839 static int vmdkCreateStreamImage(PVMDKIMAGE pImage, uint64_t cbSize,
3846 rc = vmdkCreateExtents(pImage, 1);
3848 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new extent list in '%s'"), pImage->pszFilename);
3851 const char *pszBasenameSubstr = RTPathFilename(pImage->pszFilename);
3856 pImage->pFile = NULL;
3859 PVMDKEXTENT pExtent = &pImage->pExtents[0];
3871 char *pszBasedirectory = RTStrDup(pImage->pszFilename);
3880 rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname,
3881 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags,
3885 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pExtent->pszFullname);
3889 pExtent->cDescriptorSectors = VMDK_BYTE2SECTOR(pImage->cbDescAlloc);
3891 pExtent->pDescData = pImage->pDescData;
3892 pImage->pDescData = NULL;
3921 rc = vmdkCreateGrainDirectory(pImage, pExtent, VMDK_GD_AT_END,
3924 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new grain directory in '%s'"), pExtent->pszFullname);
3926 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType",
3929 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not set the image type in '%s'"), pImage->pszFilename);
3938 static int vmdkCreateImage(PVMDKIMAGE pImage, uint64_t cbSize,
3947 pImage->uImageFlags = uImageFlags;
3949 pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
3950 pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
3951 AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
3953 rc = vmdkCreateDescriptor(pImage, pImage->pDescData, pImage->cbDescAlloc,
3954 &pImage->Descriptor);
3957 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not create new descriptor in '%s'"), pImage->pszFilename);
3969 rc = vmdkCreateRawImage(pImage, pRaw, cbSize);
3976 rc = vmdkCreateStreamImage(pImage, cbSize, uImageFlags,
3983 rc = vmdkCreateRegularImage(pImage, cbSize, uImageFlags,
3995 pImage->cbSize = cbSize;
3997 for (unsigned i = 0; i < pImage->cExtents; i++)
3999 PVMDKEXTENT pExtent = &pImage->pExtents[i];
4001 rc = vmdkDescExtInsert(pImage, &pImage->Descriptor, pExtent->enmAccess,
4006 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: could not insert the extent list into descriptor in '%s'"), pImage->pszFilename);
4010 vmdkDescExtRemoveDummy(pImage, &pImage->Descriptor);
4016 rc = vmdkDescSetPCHSGeometry(pImage, pPCHSGeometry);
4024 rc = vmdkDescSetLCHSGeometry(pImage, pLCHSGeometry);
4029 pImage->LCHSGeometry = *pLCHSGeometry;
4030 pImage->PCHSGeometry = *pPCHSGeometry;
4032 pImage->ImageUuid = *pUuid;
4033 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
4034 VMDK_DDB_IMAGE_UUID, &pImage->ImageUuid);
4037 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing image UUID in new descriptor in '%s'"), pImage->pszFilename);
4040 RTUuidClear(&pImage->ParentUuid);
4041 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
4042 VMDK_DDB_PARENT_UUID, &pImage->ParentUuid);
4045 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent image UUID in new descriptor in '%s'"), pImage->pszFilename);
4048 RTUuidClear(&pImage->ModificationUuid);
4049 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
4051 &pImage->ModificationUuid);
4054 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing modification UUID in new descriptor in '%s'"), pImage->pszFilename);
4057 RTUuidClear(&pImage->ParentModificationUuid);
4058 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
4060 &pImage->ParentModificationUuid);
4063 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent modification UUID in new descriptor in '%s'"), pImage->pszFilename);
4067 rc = vmdkAllocateGrainTableCache(pImage);
4071 rc = vmdkSetImageComment(pImage, pszComment);
4074 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot set image comment in '%s'"), pImage->pszFilename);
4081 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
4086 pImage->pExtents[0].cDescriptorSectors = VMDK_BYTE2SECTOR(RT_ALIGN_64( pImage->Descriptor.aLines[pImage->Descriptor.cLines]
4087 - pImage->Descriptor.aLines[0], 512));
4088 rc = vmdkWriteMetaSparseExtent(pImage, &pImage->pExtents[0], 0, NULL);
4091 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write VMDK header in '%s'"), pImage->pszFilename);
4095 rc = vmdkWriteDescriptor(pImage, NULL);
4098 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write VMDK descriptor in '%s'"), pImage->pszFilename);
4103 rc = vmdkFlushImage(pImage, NULL);
4110 vmdkFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
4117 static int vmdkSetImageComment(PVMDKIMAGE pImage, const char *pszComment)
4128 int rc = vmdkDescDDBSetStr(pImage, &pImage->Descriptor,
4133 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing image comment in descriptor in '%s'"), pImage->pszFilename);
4140 static void vmdkStreamClearGT(PVMDKIMAGE pImage, PVMDKEXTENT pExtent)
4144 memset(&pImage->pGTCache->aGTCache[i].aGTData[0], '\0',
4151 static int vmdkStreamFlushGT(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
4166 uint32_t *pGTTmp = &pImage->pGTCache->aGTCache[i].aGTData[0];
4191 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage, uFileOffset,
4205 uint32_t *pGTTmp = &pImage->pGTCache->aGTCache[i].aGTData[0];
4209 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage, uFileOffset,
4210 &pImage->pGTCache->aGTCache[i].aGTData[0],
4225 static int vmdkFreeImage(PVMDKIMAGE pImage, bool fDelete)
4231 if (pImage)
4233 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
4235 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
4238 for (unsigned i = 0; i < pImage->cExtents; i++)
4240 Assert(!pImage->pExtents[i].fUncleanShutdown);
4246 for (unsigned i = 0; i < pImage->cExtents; i++)
4248 if ( ( pImage->pExtents[i].enmType == VMDKETYPE_HOSTED_SPARSE
4250 || pImage->pExtents[i].enmType == VMDKETYPE_ESX_SPARSE
4253 && pImage->pExtents[i].fUncleanShutdown)
4255 pImage->pExtents[i].fUncleanShutdown = false;
4256 pImage->pExtents[i].fMetaDirty = true;
4260 pImage->pExtents[i].uAppendPosition = 0;
4265 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
4269 if ( !fDelete && pImage->pExtents
4270 && pImage->pExtents[0].cGTEntries
4271 && pImage->pExtents[0].uAppendPosition)
4273 PVMDKEXTENT pExtent = &pImage->pExtents[0];
4275 rc = vmdkStreamFlushGT(pImage, pExtent, uLastGDEntry);
4277 vmdkStreamClearGT(pImage, pExtent);
4280 rc = vmdkStreamFlushGT(pImage, pExtent, i);
4298 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage, uFileOffset,
4308 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
4323 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
4328 rc = vmdkWriteMetaSparseExtent(pImage, pExtent, uFileOffset, NULL);
4334 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pExtent->pFile->pStorage,
4340 vmdkFlushImage(pImage, NULL);
4342 if (pImage->pExtents != NULL)
4344 for (unsigned i = 0 ; i < pImage->cExtents; i++)
4346 int rc2 = vmdkFreeExtentData(pImage, &pImage->pExtents[i], fDelete);
4350 RTMemFree(pImage->pExtents);
4351 pImage->pExtents = NULL;
4353 pImage->cExtents = 0;
4354 if (pImage->pFile != NULL)
4356 int rc2 = vmdkFileClose(pImage, &pImage->pFile, fDelete);
4360 int rc2 = vmdkFileCheckAllClose(pImage);
4364 if (pImage->pGTCache)
4366 RTMemFree(pImage->pGTCache);
4367 pImage->pGTCache = NULL;
4369 if (pImage->pDescData)
4371 RTMemFree(pImage->pDescData);
4372 pImage->pDescData = NULL;
4383 static int vmdkFlushImage(PVMDKIMAGE pImage, PVDIOCTX pIoCtx)
4389 if (pImage->Descriptor.fDirty)
4391 rc = vmdkWriteDescriptor(pImage, pIoCtx);
4396 for (unsigned i = 0; i < pImage->cExtents; i++)
4398 pExtent = &pImage->pExtents[i];
4406 rc = vmdkWriteMetaSparseExtent(pImage, pExtent, 0, pIoCtx);
4418 rc = vmdkWriteMetaSparseExtent(pImage, pExtent,
4450 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
4452 rc = vdIfIoIntFileFlush(pImage->pIfIo, pExtent->pFile->pStorage, pIoCtx,
4471 static int vmdkFindExtent(PVMDKIMAGE pImage, uint64_t offSector,
4477 for (unsigned i = 0; i < pImage->cExtents; i++)
4479 if (offSector < pImage->pExtents[i].cNominalSectors)
4481 pExtent = &pImage->pExtents[i];
4482 *puSectorInExtent = offSector + pImage->pExtents[i].uSectorOffset;
4485 offSector -= pImage->pExtents[i].cNominalSectors;
4511 static int vmdkGetSector(PVMDKIMAGE pImage, PVDIOCTX pIoCtx,
4515 PVMDKGTCACHE pCache = pImage->pGTCache;
4524 if ( ( pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED
4526 || ( pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED
4527 && pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY
4528 && pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
4554 rc = vdIfIoIntFileReadMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4560 vdIfIoIntMetaXferRelease(pImage->pIfIo, pMetaXfer);
4579 static int vmdkStreamAllocGrain(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
4617 if ( !(pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_ZEROES)
4618 && vdIfIoIntIoCtxIsZero(pImage->pIfIo, pIoCtx, cbWrite, true /* fAdvance */))
4623 rc = vmdkStreamFlushGT(pImage, pExtent, uLastGDEntry);
4626 vmdkStreamClearGT(pImage, pExtent);
4629 rc = vmdkStreamFlushGT(pImage, pExtent, i);
4645 || !pImage->pGTCache
4647 || pImage->pGTCache->aGTCache[uCacheLine].aGTData[uCacheEntry])
4651 pImage->pGTCache->aGTCache[uCacheLine].aGTData[uCacheEntry] = VMDK_BYTE2SECTOR(uFileOffset);
4655 vdIfIoIntIoCtxCopyFrom(pImage->pIfIo, pIoCtx, pExtent->pvGrain, cbWrite);
4666 cbSeg = vdIfIoIntIoCtxSegArrayCreate(pImage->pIfIo, pIoCtx, &Segment,
4671 rc = vmdkFileDeflateSync(pImage, pExtent, uFileOffset, pData,
4678 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write compressed data block in '%s'"), pExtent->pszFullname);
4689 static int vmdkAllocGrainGTUpdate(PVMDKIMAGE pImage, PVMDKEXTENT pExtent, PVDIOCTX pIoCtx,
4693 PVMDKGTCACHE pCache = pImage->pGTCache;
4700 LogFlowFunc(("pImage=%#p pExtent=%#p pCache=%#p pIoCtx=%#p pGrainAlloc=%#p\n",
4701 pImage, pExtent, pCache, pIoCtx, pGrainAlloc));
4717 rc = vdIfIoIntFileReadMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4730 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot read allocated grain table entry in '%s'"), pExtent->pszFullname);
4731 vdIfIoIntMetaXferRelease(pImage->pIfIo, pMetaXfer);
4749 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4756 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write updated grain table in '%s'"), pExtent->pszFullname);
4760 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4767 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write updated backup grain table in '%s'"), pExtent->pszFullname);
4788 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
4797 rc = vmdkAllocGrainGTUpdate(pImage, pGrainAlloc->pExtent, pIoCtx, pGrainAlloc);
4812 static int vmdkAllocGrain(PVMDKIMAGE pImage, PVMDKEXTENT pExtent, PVDIOCTX pIoCtx,
4815 PVMDKGTCACHE pCache = pImage->pGTCache;
4873 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4882 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write grain table allocation in '%s'"), pExtent->pszFullname);
4908 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4917 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write backup grain table allocation in '%s'"), pExtent->pszFullname);
4930 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4937 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write grain directory entry in '%s'"), pExtent->pszFullname);
4941 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pExtent->pFile->pStorage,
4948 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write backup grain directory entry in '%s'"), pExtent->pszFullname);
4968 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
4970 AssertMsgReturn(vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx),
4975 return vdIfError(pImage->pIfError, VERR_INTERNAL_ERROR, RT_SRC_POS, N_("VMDK: not enough data for a compressed data block in '%s'"), pExtent->pszFullname);
4987 cbSeg = vdIfIoIntIoCtxSegArrayCreate(pImage->pIfIo, pIoCtx, &Segment,
4991 rc = vmdkFileDeflateSync(pImage, pExtent, uFileOffset,
4996 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write allocated compressed data block in '%s'"), pExtent->pszFullname);
5004 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pExtent->pFile->pStorage,
5010 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: cannot write allocated data block in '%s'"), pExtent->pszFullname);
5015 rc = vmdkAllocGrainGTUpdate(pImage, pExtent, pIoCtx, pGrainAlloc);
5032 static int vmdkStreamReadSequential(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
5038 LogFlowFunc(("pImage=%#p pExtent=%#p uSector=%llu pIoCtx=%#p cbRead=%llu\n",
5039 pImage, pExtent, uSector, pIoCtx, cbRead));
5041 AssertMsgReturn(vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx),
5070 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
5081 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
5097 vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
5135 rc = vmdkFileInflateSync(pImage, pExtent,
5177 vdIfIoIntIoCtxCopyTo(pImage->pIfIo, pIoCtx,
5223 PVMDKIMAGE pImage;
5233 pImage = (PVMDKIMAGE)RTMemAllocZ(sizeof(VMDKIMAGE));
5234 if (!pImage)
5239 pImage->pszFilename = pszFilename;
5240 pImage->pFile = NULL;
5241 pImage->pExtents = NULL;
5242 pImage->pFiles = NULL;
5243 pImage->pGTCache = NULL;
5244 pImage->pDescData = NULL;
5245 pImage->pVDIfsDisk = pVDIfsDisk;
5246 pImage->pVDIfsImage = pVDIfsImage;
5249 rc = vmdkOpenImage(pImage, VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_READONLY);
5250 vmdkFreeImage(pImage, false);
5251 RTMemFree(pImage);
5268 PVMDKIMAGE pImage;
5288 pImage = (PVMDKIMAGE)RTMemAllocZ(sizeof(VMDKIMAGE));
5289 if (!pImage)
5294 pImage->pszFilename = pszFilename;
5295 pImage->pFile = NULL;
5296 pImage->pExtents = NULL;
5297 pImage->pFiles = NULL;
5298 pImage->pGTCache = NULL;
5299 pImage->pDescData = NULL;
5300 pImage->pVDIfsDisk = pVDIfsDisk;
5301 pImage->pVDIfsImage = pVDIfsImage;
5303 rc = vmdkOpenImage(pImage, uOpenFlags);
5305 *ppBackendData = pImage;
5307 RTMemFree(pImage);
5327 PVMDKIMAGE pImage;
5384 pImage = (PVMDKIMAGE)RTMemAllocZ(sizeof(VMDKIMAGE));
5385 if (!pImage)
5390 pImage->pszFilename = pszFilename;
5391 pImage->pFile = NULL;
5392 pImage->pExtents = NULL;
5393 pImage->pFiles = NULL;
5394 pImage->pGTCache = NULL;
5395 pImage->pDescData = NULL;
5396 pImage->pVDIfsDisk = pVDIfsDisk;
5397 pImage->pVDIfsImage = pVDIfsImage;
5402 pImage->cbDescAlloc = VMDK_SECTOR2BYTE(200);
5404 pImage->cbDescAlloc = VMDK_SECTOR2BYTE(20);
5405 pImage->pDescData = (char *)RTMemAllocZ(pImage->cbDescAlloc);
5406 if (!pImage->pDescData)
5408 RTMemFree(pImage);
5413 rc = vmdkCreateImage(pImage, cbSize, uImageFlags, pszComment,
5422 vmdkFreeImage(pImage, false);
5423 rc = vmdkOpenImage(pImage, uOpenFlags);
5427 *ppBackendData = pImage;
5431 RTMemFree(pImage->pDescData);
5432 RTMemFree(pImage);
5445 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5466 if ( !pImage
5467 || (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_RAWDISK)
5475 cExtents = pImage->cExtents;
5492 if (pImage->pDescData)
5500 ExtentCopy = pImage->pExtents[0];
5504 DescriptorCopy.cLines = pImage->Descriptor.cLines;
5507 DescriptorCopy.aLines[i] = RTStrDup(pImage->Descriptor.aLines[i]);
5518 pszOldBaseName = RTStrDup(RTPathFilename(pImage->pszFilename));
5523 pszOldFullName = RTStrDup(pImage->pszFilename);
5529 pszOldDescName = RTStrDup(pImage->pszFilename);
5531 pszOldImageName = pImage->pszFilename;
5534 for (i = 0, line = pImage->Descriptor.uFirstExtent;
5536 i++, line = pImage->Descriptor.aNextLines[line])
5541 apszNewLines[i] = vmdkStrReplace(pImage->Descriptor.aLines[line],
5545 pImage->Descriptor.aLines[line] = apszNewLines[i];
5548 pImage->Descriptor.fDirty = true;
5550 vmdkFlushImage(pImage, NULL);
5555 PVMDKEXTENT pExtent = &pImage->pExtents[i];
5562 rc = vmdkFileClose(pImage, &pExtent->pFile, false);
5567 rc = vdIfIoIntFileMove(pImage->pIfIo, pExtent->pszFullname, apszNewName[i], 0);
5574 rc = vmdkFreeImage(pImage, false);
5587 rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, apszNewName[cExtents], 0);
5594 /* Update pImage with the new information. */
5595 pImage->pszFilename = pszFilename;
5598 rc = vmdkOpenImage(pImage, pImage->uOpenFlags);
5613 vmdkFreeImage(pImage, false);
5620 rrc = vdIfIoIntFileMove(pImage->pIfIo, apszNewName[i], apszOldName[i], 0);
5626 rrc = vmdkFileOpen(pImage, &pFile, pszOldDescName,
5633 pImage->pExtents = &ExtentCopy;
5640 pImage->pDescData = pszOldDescName;
5641 pImage->pFile = pFile;
5643 pImage->Descriptor = DescriptorCopy;
5644 vmdkWriteDescriptor(pImage, NULL);
5645 vmdkFileClose(pImage, &pFile, false);
5647 pImage->pExtents = NULL;
5648 pImage->pFile = NULL;
5649 pImage->pDescData = NULL;
5651 pImage->pszFilename = pszOldImageName;
5652 rrc = vmdkOpenImage(pImage, pImage->uOpenFlags);
5699 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5702 rc = vmdkFreeImage(pImage, fDelete);
5703 RTMemFree(pImage);
5715 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5721 AssertPtr(pImage);
5725 if ( uOffset + cbToRead > pImage->cbSize
5732 rc = vmdkFindExtent(pImage, VMDK_BYTE2SECTOR(uOffset),
5754 rc = vmdkGetSector(pImage, pIoCtx, pExtent, uSectorExtentRel, &uSectorExtentAbs);
5762 if ( !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
5763 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
5764 || !(pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL))
5767 rc = vmdkStreamReadSequential(pImage, pExtent,
5773 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
5775 AssertMsg(vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx),
5783 rc = vmdkFileInflateSync(pImage, pExtent,
5798 vdIfIoIntIoCtxCopyTo(pImage->pIfIo, pIoCtx,
5804 rc = vdIfIoIntFileReadUser(pImage->pIfIo, pExtent->pFile->pStorage,
5811 rc = vdIfIoIntFileReadUser(pImage->pIfIo, pExtent->pFile->pStorage,
5818 cbSet = vdIfIoIntIoCtxSet(pImage->pIfIo, pIoCtx, 0, cbToRead);
5839 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5845 AssertPtr(pImage);
5849 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
5868 rc = vmdkFindExtent(pImage, VMDK_BYTE2SECTOR(uOffset),
5875 && ( !(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
5876 && !pImage->pExtents[0].uAppendPosition
5890 rc = vmdkGetSector(pImage, pIoCtx, pExtent, uSectorExtentRel, &uSectorExtentAbs);
5895 if ( pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED
5903 if (!(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
5912 rc = vmdkAllocGrain(pImage, pExtent, pIoCtx,
5931 rc = vmdkStreamAllocGrain(pImage, pExtent,
5938 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
5949 Assert(!(pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED));
5950 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pExtent->pFile->pStorage,
5960 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pExtent->pFile->pStorage,
5981 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5983 return vmdkFlushImage(pImage, pIoCtx);
5990 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
5992 AssertPtr(pImage);
5994 if (pImage)
6004 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6006 AssertPtr(pImage);
6008 if (pImage)
6018 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6020 AssertPtr(pImage);
6022 if (pImage)
6023 return pImage->cbSize;
6032 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6035 AssertPtr(pImage);
6037 if (pImage)
6040 if (pImage->pFile != NULL)
6042 int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pFile->pStorage, &cbFile);
6046 for (unsigned i = 0; i < pImage->cExtents; i++)
6048 if (pImage->pExtents[i].pFile != NULL)
6050 int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pExtents[i].pFile->pStorage, &cbFile);
6065 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6068 AssertPtr(pImage);
6070 if (pImage)
6072 if (pImage->PCHSGeometry.cCylinders)
6074 *pPCHSGeometry = pImage->PCHSGeometry;
6091 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6094 AssertPtr(pImage);
6096 if (pImage)
6098 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
6103 if (pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
6108 rc = vmdkDescSetPCHSGeometry(pImage, pPCHSGeometry);
6112 pImage->PCHSGeometry = *pPCHSGeometry;
6127 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6130 AssertPtr(pImage);
6132 if (pImage)
6134 if (pImage->LCHSGeometry.cCylinders)
6136 *pLCHSGeometry = pImage->LCHSGeometry;
6153 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6156 AssertPtr(pImage);
6158 if (pImage)
6160 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
6165 if (pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
6170 rc = vmdkDescSetLCHSGeometry(pImage, pLCHSGeometry);
6174 pImage->LCHSGeometry = *pLCHSGeometry;
6189 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6192 AssertPtr(pImage);
6194 if (pImage)
6195 uImageFlags = pImage->uImageFlags;
6207 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6210 AssertPtr(pImage);
6212 if (pImage)
6213 uOpenFlags = pImage->uOpenFlags;
6225 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6229 if (!pImage || (uOpenFlags & ~( VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO
6238 if (pImage->uImageFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
6240 if (pImage->uOpenFlags == uOpenFlags)
6248 vmdkFreeImage(pImage, false);
6249 rc = vmdkOpenImage(pImage, uOpenFlags);
6262 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6265 AssertPtr(pImage);
6267 if (pImage)
6270 rc = vmdkDescDDBGetStr(pImage, &pImage->Descriptor,
6300 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6303 AssertPtr(pImage);
6305 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
6310 if (pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED)
6316 if (pImage)
6317 rc = vmdkSetImageComment(pImage, pszComment);
6330 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6333 AssertPtr(pImage);
6335 if (pImage)
6337 *pUuid = pImage->ImageUuid;
6351 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6355 AssertPtr(pImage);
6357 if (pImage)
6359 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
6361 if (!(pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
6363 pImage->ImageUuid = *pUuid;
6364 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
6367 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing image UUID in descriptor in '%s'"), pImage->pszFilename);
6387 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6390 AssertPtr(pImage);
6392 if (pImage)
6394 *pUuid = pImage->ModificationUuid;
6408 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6411 AssertPtr(pImage);
6413 if (pImage)
6415 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
6417 if (!(pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
6420 if (RTUuidCompare(&pImage->ModificationUuid, pUuid))
6422 pImage->ModificationUuid = *pUuid;
6423 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
6426 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing modification UUID in descriptor in '%s'"), pImage->pszFilename);
6447 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6450 AssertPtr(pImage);
6452 if (pImage)
6454 *pUuid = pImage->ParentUuid;
6468 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6471 AssertPtr(pImage);
6473 if (pImage)
6475 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
6477 if (!(pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
6479 pImage->ParentUuid = *pUuid;
6480 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
6483 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent image UUID in descriptor in '%s'"), pImage->pszFilename);
6503 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6506 AssertPtr(pImage);
6508 if (pImage)
6510 *pUuid = pImage->ParentModificationUuid;
6524 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6527 AssertPtr(pImage);
6529 if (pImage)
6531 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
6533 if (!(pImage->uOpenFlags & VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED))
6535 pImage->ParentModificationUuid = *pUuid;
6536 rc = vmdkDescDDBSetUuid(pImage, &pImage->Descriptor,
6539 return vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error storing parent image UUID in descriptor in '%s'"), pImage->pszFilename);
6558 PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
6560 AssertPtr(pImage);
6561 if (pImage)
6563 vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n",
6564 pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
6565 pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
6566 VMDK_BYTE2SECTOR(pImage->cbSize));
6567 vdIfErrorMessage(pImage->pIfError, "Header: uuidCreation={%RTuuid}\n", &pImage->ImageUuid);
6568 vdIfErrorMessage(pImage->pIfError, "Header: uuidModification={%RTuuid}\n", &pImage->ModificationUuid);
6569 vdIfErrorMessage(pImage->pIfError, "Header: uuidParent={%RTuuid}\n", &pImage->ParentUuid);
6570 vdIfErrorMessage(pImage->pIfError, "Header: uuidParentModification={%RTuuid}\n", &pImage->ParentModificationUuid);