Changeset 29649 in vbox
- Timestamp:
- May 18, 2010 4:29:31 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
include/VBox/VBoxHDD.h (modified) (2 diffs)
-
src/VBox/Devices/Storage/VmdkHDDCore.cpp (modified) (6 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxHDD.h
r28800 r29649 103 103 104 104 /** 105 * Auxiliary type for describing partitions on raw disks. 106 */ 107 typedef struct VBOXHDDRAWPART 108 { 109 /** Device to use for this partition. Can be the disk device if the offset 110 * field is set appropriately. If this is NULL, then this partition will 111 * not be accessible to the guest. The size of the partition must still 112 * be set correctly. */ 105 * Auxiliary type for describing partitions on raw disks. The entries must be 106 * in ascending order (as far as uStart is concerned), and must not overlap. 107 * Note that this does not correspond 1:1 to partitions, it is describing the 108 * general meaning of contiguous areas on the disk. 109 */ 110 typedef struct VBOXHDDRAWPARTDESC 111 { 112 /** Device to use for this partition/data area. Can be the disk device if 113 * the offset field is set appropriately. If this is NULL, then this 114 * partition will not be accessible to the guest. The size of the data area 115 * must still be set correctly. */ 113 116 const char *pszRawDevice; 114 /** Offset where the partition data starts in this device. */ 115 uint64_t uPartitionStartOffset; 116 /** Offset where the partition data starts in the disk. */ 117 uint64_t uPartitionStart; 118 /** Size of the partition. */ 119 uint64_t cbPartition; 120 /** Size of the partitioning info to prepend. */ 121 uint64_t cbPartitionData; 122 /** Offset where the partitioning info starts in the disk. */ 123 uint64_t uPartitionDataStart; 124 /** Pointer to the partitioning info to prepend. */ 117 /** Pointer to the partitioning info. NULL means this is a regular data 118 * area on disk, non-NULL denotes data which should be copied to the 119 * partition data overlay. */ 125 120 const void *pvPartitionData; 126 } VBOXHDDRAWPART, *PVBOXHDDRAWPART; 121 /** Offset where the data starts in this device. */ 122 uint64_t uStartOffset; 123 /** Offset where the data starts in the disk. */ 124 uint64_t uStart; 125 /** Size of the data area. */ 126 uint64_t cbData; 127 } VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC; 127 128 128 129 /** … … 140 141 * For Linux e.g. /dev/sda, and for Windows e.g. \\\\.\\PhysicalDisk0. */ 141 142 const char *pszRawDisk; 142 /** Number of entries in the partition sarray. */143 unsigned cPart itions;144 /** Pointer to the partition sarray. */145 PVBOXHDDRAWPART pPartitions;143 /** Number of entries in the partition descriptor array. */ 144 unsigned cPartDescs; 145 /** Pointer to the partition descriptor array. */ 146 PVBOXHDDRAWPARTDESC pPartDescs; 146 147 } VBOXHDDRAW, *PVBOXHDDRAW; 147 148 -
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r29035 r29649 3481 3481 * open all the (flat) raw disk partitions. */ 3482 3482 3483 /* First pass over the partitions to determine how many 3484 * extents we need. One partition can require up to 4 extents. 3485 * One to skip over unpartitioned space, one for the 3486 * partitioning data, one to skip over unpartitioned space 3487 * and one for the partition data. */ 3483 /* First pass over the partition data areas to determine how many 3484 * extents we need. One data area can require up to 2 extents, as 3485 * it might be necessary to skip over unpartitioned space. */ 3488 3486 unsigned cExtents = 0; 3489 3487 uint64_t uStart = 0; 3490 for (unsigned i = 0; i < pRaw->cPartitions; i++) 3491 { 3492 PVBOXHDDRAWPART pPart = &pRaw->pPartitions[i]; 3493 if (pPart->cbPartitionData) 3494 { 3495 if (uStart > pPart->uPartitionDataStart) 3496 return vmdkError(pImage, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: cannot go backwards for partitioning information in '%s'"), pImage->pszFilename); 3497 else if (uStart != pPart->uPartitionDataStart) 3498 cExtents++; 3499 uStart = pPart->uPartitionDataStart + pPart->cbPartitionData; 3488 for (unsigned i = 0; i < pRaw->cPartDescs; i++) 3489 { 3490 PVBOXHDDRAWPARTDESC pPart = &pRaw->pPartDescs[i]; 3491 if (uStart > pPart->uStart) 3492 return vmdkError(pImage, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: incorrect partition data area ordering set up by the caller in '%s'"), pImage->pszFilename); 3493 3494 if (uStart < pPart->uStart) 3500 3495 cExtents++; 3501 } 3502 if (pPart->cbPartition) 3503 { 3504 if (uStart > pPart->uPartitionStart) 3505 return vmdkError(pImage, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("VMDK: cannot go backwards for partition data in '%s'"), pImage->pszFilename); 3506 else if (uStart != pPart->uPartitionStart) 3507 cExtents++; 3508 uStart = pPart->uPartitionStart + pPart->cbPartition; 3509 cExtents++; 3510 } 3496 uStart = pPart->uStart + pPart->cbData; 3497 cExtents++; 3511 3498 } 3512 3499 /* Another extent for filling up the rest of the image. */ … … 3544 3531 cExtents = 0; 3545 3532 uStart = 0; 3546 for (unsigned i = 0; i < pRaw->cPartitions; i++) 3547 { 3548 PVBOXHDDRAWPART pPart = &pRaw->pPartitions[i]; 3549 if (pPart->cbPartitionData) 3533 for (unsigned i = 0; i < pRaw->cPartDescs; i++) 3534 { 3535 PVBOXHDDRAWPARTDESC pPart = &pRaw->pPartDescs[i]; 3536 pExtent = &pImage->pExtents[cExtents++]; 3537 3538 if (uStart < pPart->uStart) 3550 3539 { 3551 if (uStart != pPart->uPartitionDataStart) 3552 { 3553 pExtent = &pImage->pExtents[cExtents++]; 3554 pExtent->pszBasename = NULL; 3555 pExtent->pszFullname = NULL; 3556 pExtent->enmType = VMDKETYPE_ZERO; 3557 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->uPartitionDataStart - uStart); 3558 pExtent->uSectorOffset = 0; 3559 pExtent->enmAccess = VMDKACCESS_READWRITE; 3560 pExtent->fMetaDirty = false; 3561 } 3562 uStart = pPart->uPartitionDataStart + pPart->cbPartitionData; 3540 pExtent->pszBasename = NULL; 3541 pExtent->pszFullname = NULL; 3542 pExtent->enmType = VMDKETYPE_ZERO; 3543 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->uStart - uStart); 3544 pExtent->uSectorOffset = 0; 3545 pExtent->enmAccess = VMDKACCESS_READWRITE; 3546 pExtent->fMetaDirty = false; 3547 /* go to next extent */ 3563 3548 pExtent = &pImage->pExtents[cExtents++]; 3549 } 3550 uStart = pPart->uStart + pPart->cbData; 3551 3552 if (pPart->pvPartitionData) 3553 { 3564 3554 /* Set up basename for extent description. Can't use StrDup. */ 3565 3555 size_t cbBasename = strlen(pszPartition) + 1; … … 3585 3575 pExtent->pszFullname = pszFullname; 3586 3576 pExtent->enmType = VMDKETYPE_FLAT; 3587 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cb PartitionData);3577 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbData); 3588 3578 pExtent->uSectorOffset = uPartOffset; 3589 3579 pExtent->enmAccess = VMDKACCESS_READWRITE; … … 3599 3589 VMDK_SECTOR2BYTE(uPartOffset), 3600 3590 pPart->pvPartitionData, 3601 pPart->cb PartitionData, NULL);3591 pPart->cbData, NULL); 3602 3592 if (RT_FAILURE(rc)) 3603 3593 return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not write partition data to '%s'"), pExtent->pszFullname); 3604 uPartOffset += VMDK_BYTE2SECTOR(pPart->cb PartitionData);3594 uPartOffset += VMDK_BYTE2SECTOR(pPart->cbData); 3605 3595 } 3606 if (pPart->cbPartition)3596 else 3607 3597 { 3608 if (uStart != pPart->uPartitionStart)3609 {3610 pExtent = &pImage->pExtents[cExtents++];3611 pExtent->pszBasename = NULL;3612 pExtent->pszFullname = NULL;3613 pExtent->enmType = VMDKETYPE_ZERO;3614 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->uPartitionStart - uStart);3615 pExtent->uSectorOffset = 0;3616 pExtent->enmAccess = VMDKACCESS_READWRITE;3617 pExtent->fMetaDirty = false;3618 }3619 uStart = pPart->uPartitionStart + pPart->cbPartition;3620 pExtent = &pImage->pExtents[cExtents++];3621 3598 if (pPart->pszRawDevice) 3622 3599 { … … 3633 3610 return VERR_NO_MEMORY; 3634 3611 pExtent->enmType = VMDKETYPE_FLAT; 3635 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cb Partition);3636 pExtent->uSectorOffset = VMDK_BYTE2SECTOR(pPart->u PartitionStartOffset);3612 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbData); 3613 pExtent->uSectorOffset = VMDK_BYTE2SECTOR(pPart->uStartOffset); 3637 3614 pExtent->enmAccess = VMDKACCESS_READWRITE; 3638 3615 pExtent->fMetaDirty = false; … … 3650 3627 pExtent->pszFullname = NULL; 3651 3628 pExtent->enmType = VMDKETYPE_ZERO; 3652 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cb Partition);3629 pExtent->cNominalSectors = VMDK_BYTE2SECTOR(pPart->cbData); 3653 3630 pExtent->uSectorOffset = 0; 3654 3631 pExtent->enmAccess = VMDKACCESS_READWRITE; -
trunk/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
r28800 r29649 496 496 } 497 497 498 static int handleVDMessage(void *pvUser, const char *pszFormat, ...) 499 { 500 NOREF(pvUser); 501 va_list args; 502 va_start(args, pszFormat); 503 int rc = RTPrintfV(pszFormat, args); 504 va_end(args); 505 return rc; 506 } 507 498 508 static int CmdSetHDUUID(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession) 499 509 { … … 525 535 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR; 526 536 vdInterfaceErrorCallbacks.pfnError = handleVDError; 527 vdInterfaceErrorCallbacks.pfnMessage = NULL;537 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage; 528 538 529 539 rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR, … … 557 567 } 558 568 559 560 static int handleVDMessage(void *pvUser, const char *pszFormat, ...)561 {562 NOREF(pvUser);563 va_list args;564 va_start(args, pszFormat);565 int rc = RTPrintfV(pszFormat, args);566 va_end(args);567 return rc;568 }569 569 570 570 static int CmdDumpHDInfo(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession) … … 769 769 } 770 770 771 /* Now do a lot of consistency checking. */772 uint64_t uPrevEnd = 0;773 for (unsigned i = 0; i < pPart->cPartitions-1; i++)774 {775 if (pPart->aPartitions[i].cPartDataSectors)776 {777 if (pPart->aPartitions[i].uPartDataStart < uPrevEnd)778 {779 RTPrintf("Overlapping partition description areas. Aborting\n");780 return VERR_INVALID_PARAMETER;781 }782 uPrevEnd = pPart->aPartitions[i].uPartDataStart + pPart->aPartitions[i].cPartDataSectors;783 }784 if (pPart->aPartitions[i].uStart < uPrevEnd)785 {786 RTPrintf("Overlapping partitions. Aborting\n");787 return VERR_INVALID_PARAMETER;788 }789 if (!PARTTYPE_IS_EXTENDED(pPart->aPartitions[i].uType))790 uPrevEnd = pPart->aPartitions[i].uStart + pPart->aPartitions[i].uSize;791 }792 793 771 /* Fill out partitioning location info for MBR. */ 794 772 pPart->aPartitions[0].uPartDataStart = 0; 795 773 pPart->aPartitions[0].cPartDataSectors = pPart->aPartitions[0].uStart; 796 774 775 /* Now do a some partition table consistency checking, to reject the most 776 * obvious garbage which can lead to trouble later. */ 777 uint64_t uPrevEnd = 0; 778 for (unsigned i = 0; i < pPart->cPartitions-1; i++) 779 { 780 if (pPart->aPartitions[i].cPartDataSectors) 781 uPrevEnd = pPart->aPartitions[i].uPartDataStart + pPart->aPartitions[i].cPartDataSectors; 782 if (pPart->aPartitions[i].uStart < uPrevEnd) 783 { 784 RTPrintf("Overlapping partitions. Aborting\n"); 785 return VERR_INVALID_PARAMETER; 786 } 787 if (!PARTTYPE_IS_EXTENDED(pPart->aPartitions[i].uType)) 788 uPrevEnd = pPart->aPartitions[i].uStart + pPart->aPartitions[i].uSize; 789 } 790 797 791 return VINF_SUCCESS; 798 792 } … … 833 827 HOSTPARTITIONS partitions; 834 828 vrc = partRead(RawFile, &partitions); 835 if (RT_FAILURE(vrc)) 836 return vrc; 829 /* Don't bail out on errors, print the table and return the result code. */ 837 830 838 831 RTPrintf("Number Type StartCHS EndCHS Size (MiB) Start (Sect)\n"); 839 832 for (unsigned i = 0; i < partitions.cPartitions; i++) 840 833 { 841 /* Suppress printing the extended partition. Otherwise people 842 * might add it to the list of partitions for raw partition 843 * access (which is not good). */ 834 /* Don't show the extended partition, otherwise users might think they 835 * can add it to the list of partitions for raw partition access. */ 844 836 if (PARTTYPE_IS_EXTENDED(partitions.aPartitions[i].uType)) 845 837 continue; … … 858 850 } 859 851 860 return 0; 852 return vrc; 853 } 854 855 static PVBOXHDDRAWPARTDESC appendPartDesc(uint32_t *pcPartDescs, PVBOXHDDRAWPARTDESC *ppPartDescs) 856 { 857 (*pcPartDescs)++; 858 PVBOXHDDRAWPARTDESC p; 859 p = (PVBOXHDDRAWPARTDESC)RTMemRealloc(*ppPartDescs, 860 *pcPartDescs * sizeof(VBOXHDDRAWPARTDESC)); 861 *ppPartDescs = p; 862 if (p) 863 { 864 p = p + *pcPartDescs - 1; 865 memset(p, '\0', sizeof(VBOXHDDRAWPARTDESC)); 866 } 867 868 return p; 861 869 } 862 870 … … 874 882 PVBOXHDD pDisk = NULL; 875 883 VBOXHDDRAW RawDescriptor; 876 HOSTPARTITIONS partitions;877 uint32_t uPartitions = 0;878 884 PVDINTERFACE pVDIfs = NULL; 879 885 … … 1138 1144 RawDescriptor.fRawDisk = false; 1139 1145 RawDescriptor.pszRawDisk = NULL; 1140 RawDescriptor.cPartitions = 0; 1146 RawDescriptor.cPartDescs = 0; 1147 RawDescriptor.pPartDescs = NULL; 1148 1149 uint32_t uPartitions = 0; 1141 1150 1142 1151 const char *p = pszPartitions; … … 1163 1172 } 1164 1173 1174 HOSTPARTITIONS partitions; 1165 1175 vrc = partRead(RawFile, &partitions); 1166 1176 if (RT_FAILURE(vrc)) … … 1186 1196 } 1187 1197 1188 RawDescriptor.cPartitions = partitions.cPartitions;1189 RawDescriptor.pPartitions = (PVBOXHDDRAWPART)RTMemAllocZ(partitions.cPartitions * sizeof(VBOXHDDRAWPART));1190 if (!RawDescriptor.pPartitions)1191 {1192 RTPrintf("Out of memory allocating the partition list for '%s'\n", rawdisk.raw());1193 vrc = VERR_NO_MEMORY;1194 goto out;1195 }1196 1198 for (unsigned i = 0; i < partitions.cPartitions; i++) 1197 1199 { 1198 if (uPartitions & RT_BIT(partitions.aPartitions[i].uIndex)) 1199 { 1200 if (fRelative) 1200 PVBOXHDDRAWPARTDESC pPartDesc = NULL; 1201 1202 /* first dump the MBR/EPT data area */ 1203 if (partitions.aPartitions[i].cPartDataSectors) 1204 { 1205 pPartDesc = appendPartDesc(&RawDescriptor.cPartDescs, 1206 &RawDescriptor.pPartDescs); 1207 if (!pPartDesc) 1201 1208 { 1202 #ifdef RT_OS_LINUX 1203 /* Refer to the correct partition and use offset 0. */ 1204 char *pszRawName; 1205 vrc = RTStrAPrintf(&pszRawName, "%s%u", rawdisk.raw(), 1206 partitions.aPartitions[i].uIndex); 1207 if (RT_FAILURE(vrc)) 1208 { 1209 RTPrintf("Error creating reference to individual partition %u, rc=%Rrc\n", 1210 partitions.aPartitions[i].uIndex, vrc); 1211 goto out; 1212 } 1213 RawDescriptor.pPartitions[i].pszRawDevice = pszRawName; 1214 RawDescriptor.pPartitions[i].uPartitionStartOffset = 0; 1215 RawDescriptor.pPartitions[i].uPartitionStart = partitions.aPartitions[i].uStart * 512; 1216 #elif defined(RT_OS_DARWIN) 1217 /* Refer to the correct partition and use offset 0. */ 1218 char *pszRawName; 1219 vrc = RTStrAPrintf(&pszRawName, "%ss%u", rawdisk.raw(), 1220 partitions.aPartitions[i].uIndex); 1221 if (RT_FAILURE(vrc)) 1222 { 1223 RTPrintf("Error creating reference to individual partition %u, rc=%Rrc\n", 1224 partitions.aPartitions[i].uIndex, vrc); 1225 goto out; 1226 } 1227 RawDescriptor.pPartitions[i].pszRawDevice = pszRawName; 1228 RawDescriptor.pPartitions[i].uPartitionStartOffset = 0; 1229 RawDescriptor.pPartitions[i].uPartitionStart = partitions.aPartitions[i].uStart * 512; 1230 #else 1231 /** @todo not implemented yet for Windows host. Treat just 1232 * like not specified (this code is actually never reached). */ 1233 RawDescriptor.pPartitions[i].pszRawDevice = rawdisk.raw(); 1234 RawDescriptor.pPartitions[i].uPartitionStartOffset = partitions.aPartitions[i].uStart * 512; 1235 RawDescriptor.pPartitions[i].uPartitionStart = partitions.aPartitions[i].uStart * 512; 1236 #endif 1209 RTPrintf("Out of memory allocating the partition list for '%s'\n", rawdisk.raw()); 1210 vrc = VERR_NO_MEMORY; 1211 goto out; 1237 1212 } 1238 else 1239 { 1240 /* This is the "everything refers to the base raw device" 1241 * variant. This requires opening the base device in RW 1242 * mode even for creation. */ 1243 RawDescriptor.pPartitions[i].pszRawDevice = rawdisk.raw(); 1244 RawDescriptor.pPartitions[i].uPartitionStartOffset = partitions.aPartitions[i].uStart * 512; 1245 RawDescriptor.pPartitions[i].uPartitionStart = partitions.aPartitions[i].uStart * 512; 1246 } 1247 } 1248 else 1249 { 1250 /* Suppress access to this partition. */ 1251 RawDescriptor.pPartitions[i].pszRawDevice = NULL; 1252 RawDescriptor.pPartitions[i].uPartitionStartOffset = 0; 1253 /* This is used in the plausibility check in the creation 1254 * code. In theory it's a dummy, but I don't want to make 1255 * the VMDK creatiion any more complicated than what it needs 1256 * to be. */ 1257 RawDescriptor.pPartitions[i].uPartitionStart = partitions.aPartitions[i].uStart * 512; 1258 } 1259 if (PARTTYPE_IS_EXTENDED(partitions.aPartitions[i].uType)) 1260 { 1261 /* Suppress exporting the actual extended partition. Only 1262 * logical partitions should be processed. However completely 1263 * ignoring it leads to leaving out the MBR data. */ 1264 RawDescriptor.pPartitions[i].cbPartition = 0; 1265 } 1266 else 1267 RawDescriptor.pPartitions[i].cbPartition = partitions.aPartitions[i].uSize * 512; 1268 RawDescriptor.pPartitions[i].uPartitionDataStart = partitions.aPartitions[i].uPartDataStart * 512; 1269 /** @todo the clipping below isn't 100% accurate, as it should 1270 * actually clip to the track size. However that's easier said 1271 * than done as figuring out the track size is heuristics. */ 1272 RawDescriptor.pPartitions[i].cbPartitionData = RT_MIN(partitions.aPartitions[i].cPartDataSectors, 63) * 512; 1273 if (RawDescriptor.pPartitions[i].cbPartitionData) 1274 { 1275 Assert (RawDescriptor.pPartitions[i].cbPartitionData - 1276 (size_t)RawDescriptor.pPartitions[i].cbPartitionData == 0); 1277 void *pPartData = RTMemAlloc((size_t)RawDescriptor.pPartitions[i].cbPartitionData); 1213 1214 /** @todo the clipping below isn't 100% accurate, as it should 1215 * actually clip to the track size. However that's easier said 1216 * than done as figuring out the track size is heuristics. In 1217 * any case the clipping is adjusted later after sorting, to 1218 * prevent overlapping data areas on the resulting image. */ 1219 pPartDesc->cbData = RT_MIN(partitions.aPartitions[i].cPartDataSectors, 63) * 512; 1220 pPartDesc->uStart = partitions.aPartitions[i].uPartDataStart * 512; 1221 Assert(pPartDesc->cbData - (size_t)pPartDesc->cbData == 0); 1222 void *pPartData = RTMemAlloc((size_t)pPartDesc->cbData); 1278 1223 if (!pPartData) 1279 1224 { … … 1282 1227 goto out; 1283 1228 } 1284 vrc = RTFileReadAt(RawFile, partitions.aPartitions[i].uPartDataStart * 512, pPartData, (size_t)RawDescriptor.pPartitions[i].cbPartitionData, NULL); 1229 vrc = RTFileReadAt(RawFile, partitions.aPartitions[i].uPartDataStart * 512, 1230 pPartData, (size_t)pPartDesc->cbData, NULL); 1285 1231 if (RT_FAILURE(vrc)) 1286 1232 { … … 1307 1253 } 1308 1254 } 1309 RawDescriptor.pPartitions[i].pvPartitionData = pPartData; 1255 pPartDesc->pvPartitionData = pPartData; 1256 } 1257 1258 if (PARTTYPE_IS_EXTENDED(partitions.aPartitions[i].uType)) 1259 { 1260 /* Suppress exporting the actual extended partition. Only 1261 * logical partitions should be processed. However completely 1262 * ignoring it leads to leaving out the EBR data. */ 1263 continue; 1264 } 1265 1266 /* set up values for non-relative device names */ 1267 const char *pszRawName = rawdisk.raw(); 1268 uint64_t uStartOffset = partitions.aPartitions[i].uStart * 512; 1269 1270 pPartDesc = appendPartDesc(&RawDescriptor.cPartDescs, 1271 &RawDescriptor.pPartDescs); 1272 if (!pPartDesc) 1273 { 1274 RTPrintf("Out of memory allocating the partition list for '%s'\n", rawdisk.raw()); 1275 vrc = VERR_NO_MEMORY; 1276 goto out; 1277 } 1278 1279 if (uPartitions & RT_BIT(partitions.aPartitions[i].uIndex)) 1280 { 1281 if (fRelative) 1282 { 1283 #ifdef RT_OS_LINUX 1284 /* Refer to the correct partition and use offset 0. */ 1285 char *psz; 1286 vrc = RTStrAPrintf(&psz, "%s%u", rawdisk.raw(), 1287 partitions.aPartitions[i].uIndex); 1288 if (RT_FAILURE(vrc)) 1289 { 1290 RTPrintf("Error creating reference to individual partition %u, rc=%Rrc\n", 1291 partitions.aPartitions[i].uIndex, vrc); 1292 goto out; 1293 } 1294 pszRawName = psz; 1295 uStartOffset = 0; 1296 #elif defined(RT_OS_DARWIN) 1297 /* Refer to the correct partition and use offset 0. */ 1298 char *psz; 1299 vrc = RTStrAPrintf(&psz, "%ss%u", rawdisk.raw(), 1300 partitions.aPartitions[i].uIndex); 1301 if (RT_FAILURE(vrc)) 1302 { 1303 RTPrintf("Error creating reference to individual partition %u, rc=%Rrc\n", 1304 partitions.aPartitions[i].uIndex, vrc); 1305 goto out; 1306 } 1307 pszRawName = psz; 1308 uStartOffset = 0; 1309 #else 1310 /** @todo not implemented for other hosts. Treat just like 1311 * not specified (this code is actually never reached). */ 1312 #endif 1313 } 1314 1315 pPartDesc->pszRawDevice = pszRawName; 1316 pPartDesc->uStartOffset = uStartOffset; 1317 } 1318 else 1319 { 1320 pPartDesc->pszRawDevice = NULL; 1321 pPartDesc->uStartOffset = 0; 1322 } 1323 1324 pPartDesc->uStart = partitions.aPartitions[i].uStart * 512; 1325 pPartDesc->cbData = partitions.aPartitions[i].uSize * 512; 1326 } 1327 1328 /* Sort data areas in ascending order of start. */ 1329 for (unsigned i = 0; i < RawDescriptor.cPartDescs-1; i++) 1330 { 1331 unsigned uMinIdx = i; 1332 uint64_t uMinVal = RawDescriptor.pPartDescs[i].uStart; 1333 for (unsigned j = i + 1; j < RawDescriptor.cPartDescs; j++) 1334 { 1335 if (RawDescriptor.pPartDescs[j].uStart < uMinVal) 1336 { 1337 uMinIdx = j; 1338 uMinVal = RawDescriptor.pPartDescs[j].uStart; 1339 } 1340 } 1341 if (uMinIdx != i) 1342 { 1343 /* Swap entries at index i and uMinIdx. */ 1344 VBOXHDDRAWPARTDESC tmp; 1345 memcpy(&tmp, &RawDescriptor.pPartDescs[i], sizeof(tmp)); 1346 memcpy(&RawDescriptor.pPartDescs[i], &RawDescriptor.pPartDescs[uMinIdx], sizeof(tmp)); 1347 memcpy(&RawDescriptor.pPartDescs[uMinIdx], &tmp, sizeof(tmp)); 1348 } 1349 } 1350 1351 /* Have a second go at MBR/EPT area clipping. Now that the data areas 1352 * are sorted this is much easier to get 100% right. */ 1353 for (unsigned i = 0; i < RawDescriptor.cPartDescs-1; i++) 1354 { 1355 if (RawDescriptor.pPartDescs[i].pvPartitionData) 1356 { 1357 RawDescriptor.pPartDescs[i].cbData = RT_MIN(RawDescriptor.pPartDescs[i+1].uStart - RawDescriptor.pPartDescs[i].uStart, RawDescriptor.pPartDescs[i].cbData); 1358 if (!RawDescriptor.pPartDescs[i].cbData) 1359 { 1360 RTPrintf("MBR/EPT overlaps with data area\n"); 1361 vrc = VERR_INVALID_PARAMETER; 1362 goto out; 1363 } 1310 1364 } 1311 1365 } … … 1313 1367 1314 1368 RTFileClose(RawFile); 1369 1370 #ifdef DEBUG_klaus 1371 RTPrintf("# start length startoffset partdataptr device\n"); 1372 for (unsigned i = 0; i < RawDescriptor.cPartDescs; i++) 1373 { 1374 RTPrintf("%2u %14RU64 %14RU64 %14RU64 %#18p %s\n", i, 1375 RawDescriptor.pPartDescs[i].uStart, 1376 RawDescriptor.pPartDescs[i].cbData, 1377 RawDescriptor.pPartDescs[i].uStartOffset, 1378 RawDescriptor.pPartDescs[i].pvPartitionData, 1379 RawDescriptor.pPartDescs[i].pszRawDevice); 1380 } 1381 #endif 1315 1382 1316 1383 VDINTERFACE vdInterfaceError; … … 1319 1386 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR; 1320 1387 vdInterfaceErrorCallbacks.pfnError = handleVDError; 1321 vdInterfaceErrorCallbacks.pfnMessage = NULL;1388 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage; 1322 1389 1323 1390 vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR, … … 1357 1424 if (pszPartitions) 1358 1425 { 1359 for (unsigned i = 0; i < partitions.cPartitions; i++) 1360 { 1361 if (uPartitions & RT_BIT(partitions.aPartitions[i].uIndex)) 1362 { 1363 if (fRelative) 1364 { 1365 #ifdef RT_OS_LINUX 1366 /* Free memory allocated above. */ 1367 RTStrFree((char *)(void *)RawDescriptor.pPartitions[i].pszRawDevice); 1368 #endif /* RT_OS_LINUX */ 1369 } 1370 } 1371 } 1426 for (unsigned i = 0; i < RawDescriptor.cPartDescs; i++) 1427 { 1428 /* Free memory allocated for relative device name. */ 1429 if (RawDescriptor.pPartDescs[i].pszRawDevice) 1430 RTStrFree((char *)(void *)RawDescriptor.pPartDescs[i].pszRawDevice); 1431 if (RawDescriptor.pPartDescs[i].pvPartitionData) 1432 RTMemFree(RawDescriptor.pPartDescs[i].pvPartitionData); 1433 } 1434 if (RawDescriptor.pPartDescs) 1435 RTMemFree(RawDescriptor.pPartDescs); 1372 1436 } 1373 1437 … … 1429 1493 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR; 1430 1494 vdInterfaceErrorCallbacks.pfnError = handleVDError; 1431 vdInterfaceErrorCallbacks.pfnMessage = NULL;1495 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage; 1432 1496 1433 1497 int vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR, … … 1511 1575 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR; 1512 1576 vdInterfaceErrorCallbacks.pfnError = handleVDError; 1513 vdInterfaceErrorCallbacks.pfnMessage = NULL;1577 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage; 1514 1578 1515 1579 int vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR, … … 1676 1740 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR; 1677 1741 vdInterfaceErrorCallbacks.pfnError = handleVDError; 1678 vdInterfaceErrorCallbacks.pfnMessage = NULL;1742 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage; 1679 1743 1680 1744 vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
Note:
See TracChangeset
for help on using the changeset viewer.

