Index: /trunk/src/VBox/Storage/VDI.cpp
===================================================================
--- /trunk/src/VBox/Storage/VDI.cpp	(revision 40935)
+++ /trunk/src/VBox/Storage/VDI.cpp	(revision 40936)
@@ -32,4 +32,8 @@
 
 #define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M
+
+/** Macros for endianess conversion. */
+#define SET_ENDIAN_U32(conv, u32) (conv == VDIECONV_H2F ? RT_H2LE_U32(u32) : RT_LE2H_U32(u32))
+#define SET_ENDIAN_U64(conv, u64) (conv == VDIECONV_H2F ? RT_H2LE_U64(u64) : RT_LE2H_U64(u64))
 
 /*******************************************************************************
@@ -62,4 +66,127 @@
 
 /**
+ * Internal: Convert the PreHeader fields to the appropriate endianess.
+ * @param   enmConv     Direction of the conversion.
+ * @param   pPreHdrConv Where to store the converted pre header.
+ * @param   pPreHdr     PreHeader pointer.
+ */
+static void vdiConvPreHeaderEndianess(VDIECONV enmConv, PVDIPREHEADER pPreHdrConv,
+                                      PVDIPREHEADER pPreHdr)
+{
+    pPreHdrConv->u32Signature = SET_ENDIAN_U32(enmConv, pPreHdr->u32Signature);
+    pPreHdrConv->u32Version   = SET_ENDIAN_U32(enmConv, pPreHdr->u32Version);
+}
+
+/**
+ * Internal: Convert the VDIDISKGEOMETRY fields to the appropriate endianess.
+ * @param   enmConv      Direction of the conversion.
+ * @param   pDiskGeoConv Where to store the converted geometry.
+ * @param   pDiskGeo     Pointer to the disk geometry to convert.
+ */
+static void vdiConvGeometryEndianess(VDIECONV enmConv, PVDIDISKGEOMETRY pDiskGeoConv,
+                                     PVDIDISKGEOMETRY pDiskGeo)
+{
+    pDiskGeoConv->cCylinders = SET_ENDIAN_U32(enmConv, pDiskGeo->cCylinders);
+    pDiskGeoConv->cHeads     = SET_ENDIAN_U32(enmConv, pDiskGeo->cHeads);
+    pDiskGeoConv->cSectors   = SET_ENDIAN_U32(enmConv, pDiskGeo->cSectors);
+    pDiskGeoConv->cbSector   = SET_ENDIAN_U32(enmConv, pDiskGeo->cbSector);
+}
+
+/**
+ * Internal: Convert the Header - version 0 fields to the appropriate endianess.
+ * @param   enmConv      Direction of the conversion.
+ * @param   pHdrConv     Where to store the converted header.
+ * @param   pHdr         Pointer to the version 0 header.
+ */
+static void vdiConvHeaderEndianessV0(VDIECONV enmConv, PVDIHEADER0 pHdrConv,
+                                     PVDIHEADER0 pHdr)
+{
+    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
+    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
+    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
+    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
+    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
+    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
+    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
+    /* Don't convert the RTUUID fields. */
+    pHdrConv->uuidCreate       = pHdr->uuidCreate;
+    pHdrConv->uuidModify       = pHdr->uuidModify;
+    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
+}
+
+/**
+ * Internal: Set the Header - version 1 fields to the appropriate endianess.
+ * @param   enmConv      Direction of the conversion.
+ * @param   pHdrConv     Where to store the converted header.
+ * @param   pHdr         Version 1 Header pointer.
+ */
+static void vdiConvHeaderEndianessV1(VDIECONV enmConv, PVDIHEADER1 pHdrConv,
+                                     PVDIHEADER1 pHdr)
+{
+    pHdrConv->cbHeader         = SET_ENDIAN_U32(enmConv, pHdr->cbHeader);
+    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
+    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
+    pHdrConv->offBlocks        = SET_ENDIAN_U32(enmConv, pHdr->offBlocks);
+    pHdrConv->offData          = SET_ENDIAN_U32(enmConv, pHdr->offData);
+    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
+    pHdrConv->u32Dummy         = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy);
+    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
+    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
+    pHdrConv->cbBlockExtra     = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra);
+    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
+    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
+    /* Don't convert the RTUUID fields. */
+    pHdrConv->uuidCreate       = pHdr->uuidCreate;
+    pHdrConv->uuidModify       = pHdr->uuidModify;
+    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
+    pHdrConv->uuidParentModify = pHdr->uuidParentModify;
+}
+
+/**
+ * Internal: Set the Header - version 1plus fields to the appropriate endianess.
+ * @param   enmConv      Direction of the conversion.
+ * @param   pHdrConv     Where to store the converted header.
+ * @param   pHdr         Version 1+ Header pointer.
+ */
+static void vdiConvHeaderEndianessV1p(VDIECONV enmConv, PVDIHEADER1PLUS pHdrConv,
+                                      PVDIHEADER1PLUS pHdr)
+{
+    pHdrConv->cbHeader         = SET_ENDIAN_U32(enmConv, pHdr->cbHeader);
+    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
+    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
+    pHdrConv->offBlocks        = SET_ENDIAN_U32(enmConv, pHdr->offBlocks);
+    pHdrConv->offData          = SET_ENDIAN_U32(enmConv, pHdr->offData);
+    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
+    pHdrConv->u32Dummy         = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy);
+    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
+    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
+    pHdrConv->cbBlockExtra     = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra);
+    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
+    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
+    /* Don't convert the RTUUID fields. */
+    pHdrConv->uuidCreate       = pHdr->uuidCreate;
+    pHdrConv->uuidModify       = pHdr->uuidModify;
+    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
+    pHdrConv->uuidParentModify = pHdr->uuidParentModify;
+    vdiConvGeometryEndianess(enmConv, &pHdrConv->LCHSGeometry, &pHdr->LCHSGeometry);
+}
+
+/**
+ * Internal: Set the appropriate endianess on all the Blocks pointed.
+ * @param   enmConv      Direction of the conversion.
+ * @param   paBlocks     Pointer to the block array.
+ * @param   cEntries     Number of entries in the block array.
+ *
+ * @note Unlike the other conversion functions this method does an in place conversion
+ *       to avoid temporary memory allocations when writing the block array.
+ */
+static void vdiConvBlocksEndianess(VDIECONV enmConv, PVDIIMAGEBLOCKPOINTER paBlocks,
+                                   unsigned cEntries)
+{
+    for (unsigned i = 0; i < cEntries; i++)
+        paBlocks[i] = SET_ENDIAN_U32(enmConv, paBlocks[i]);
+}
+
+/**
  * Internal: Flush the image file to disk.
  */
@@ -509,6 +636,8 @@
 
     /* Write pre-header. */
+    VDIPREHEADER PreHeader;
+    vdiConvPreHeaderEndianess(VDIECONV_H2F, &PreHeader, &pImage->PreHeader);
     rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 0,
-                                &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
+                                &PreHeader, sizeof(PreHeader), NULL);
     if (RT_FAILURE(rc))
     {
@@ -519,6 +648,8 @@
 
     /* Write header. */
+    VDIHEADER1PLUS Hdr;
+    vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
     rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(pImage->PreHeader),
-                                &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
+                                &Hdr, sizeof(Hdr), NULL);
     if (RT_FAILURE(rc))
     {
@@ -528,7 +659,9 @@
     }
 
+    vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, getImageBlocks(&pImage->Header));
     rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, pImage->paBlocks,
                                 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
                                 NULL);
+    vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header));
     if (RT_FAILURE(rc))
     {
@@ -631,6 +764,7 @@
 
     /* Read pre-header. */
+    VDIPREHEADER PreHeader;
     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0,
-                               &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
+                               &PreHeader, sizeof(PreHeader), NULL);
     if (RT_FAILURE(rc))
     {
@@ -639,4 +773,5 @@
         goto out;
     }
+    vdiConvPreHeaderEndianess(VDIECONV_F2H, &pImage->PreHeader, &PreHeader);
     rc = vdiValidatePreHeader(&pImage->PreHeader);
     if (RT_FAILURE(rc))
@@ -659,4 +794,5 @@
                 goto out;
             }
+            vdiConvHeaderEndianessV0(VDIECONV_F2H, &pImage->Header.u.v0, &pImage->Header.u.v0);
             break;
         case 1:
@@ -669,4 +805,5 @@
                 goto out;
             }
+            vdiConvHeaderEndianessV1(VDIECONV_F2H, &pImage->Header.u.v1, &pImage->Header.u.v1);
             /* Convert VDI 1.1 images to VDI 1.1+ on open in read/write mode.
              * Conversion is harmless, as any VirtualBox version supporting VDI
@@ -694,4 +831,5 @@
                     goto out;
                 }
+                vdiConvHeaderEndianessV1p(VDIECONV_F2H, &pImage->Header.u.v1plus, &pImage->Header.u.v1plus);
             }
             break;
@@ -723,4 +861,10 @@
                                getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
                                NULL);
+    if (RT_FAILURE(rc))
+    {
+        rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VDI: Error reading the block table in '%s'"), pImage->pszFilename);
+        goto out;
+    }
+    vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header));
 
     if (uOpenFlags & VD_OPEN_FLAGS_DISCARD)
@@ -782,17 +926,26 @@
     {
         case 0:
+        {
+            VDIHEADER0 Hdr;
+            vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0);
             rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
-                                        &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),
-                                        NULL);
+                                        &Hdr, sizeof(Hdr), NULL);
             break;
+        }
         case 1:
             if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
+            {
+                VDIHEADER1 Hdr;
+                vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1);
                 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
-                                            &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),
-                                            NULL);
+                                            &Hdr, sizeof(Hdr), NULL);
+            }
             else
+            {
+                VDIHEADER1PLUS Hdr;
+                vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
                 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
-                                            &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus),
-                                            NULL);
+                                            &Hdr, sizeof(Hdr), NULL);
+            }
             break;
         default:
@@ -813,20 +966,29 @@
     {
         case 0:
+        {
+            VDIHEADER0 Hdr;
+            vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0);
             rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
-                                             sizeof(VDIPREHEADER), &pImage->Header.u.v0,
-                                             sizeof(pImage->Header.u.v0),
+                                             sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
                                              pIoCtx, NULL, NULL);
             break;
+        }
         case 1:
             if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
+            {
+                VDIHEADER1 Hdr;
+                vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1);
                 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
-                                                 sizeof(VDIPREHEADER), &pImage->Header.u.v1,
-                                                 sizeof(pImage->Header.u.v1),
+                                                 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
                                                  pIoCtx, NULL, NULL);
+            }
             else
+            {
+                VDIHEADER1PLUS Hdr;
+                vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
                 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
-                                                 sizeof(VDIPREHEADER), &pImage->Header.u.v1plus,
-                                                 sizeof(pImage->Header.u.v1plus),
+                                                 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
                                                  pIoCtx, NULL, NULL);
+            }
             break;
         default:
@@ -849,7 +1011,8 @@
     {
         /* write only one block pointer. */
+        VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]);
         rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
                                     pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
-                                    &pImage->paBlocks[uBlock], sizeof(VDIIMAGEBLOCKPOINTER),
+                                    &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER),
                                     NULL);
         AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n",
@@ -874,8 +1037,8 @@
     {
         /* write only one block pointer. */
+        VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]);
         rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
                                          pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
-                                         &pImage->paBlocks[uBlock],
-                                         sizeof(VDIIMAGEBLOCKPOINTER),
+                                         &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER),
                                          pIoCtx, NULL, NULL);
         AssertMsg(RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS,
@@ -2880,6 +3043,8 @@
 
             /* Write the block array before updating the rest. */
+            vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, cBlocksNew);
             rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks,
                                         pImage->paBlocks, cbBlockspaceNew, NULL);
+            vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, cBlocksNew);
 
             if (RT_SUCCESS(rc))
@@ -3232,4 +3397,5 @@
             break;
         }
+        vdiConvPreHeaderEndianess(VDIECONV_F2H, &PreHdr, &PreHdr);
         rc = vdiValidatePreHeader(&PreHdr);
         if (RT_FAILURE(rc))
@@ -3241,5 +3407,5 @@
 
         /* Read header. */
-        Hdr.uVersion = RT_H2LE_U32(PreHdr.u32Version);
+        Hdr.uVersion = PreHdr.u32Version;
         switch (GET_MAJOR_HEADER_VERSION(&Hdr))
         {
@@ -3251,4 +3417,5 @@
                     rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v0 header in '%s'"),
                                    pszFilename);
+                vdiConvHeaderEndianessV0(VDIECONV_F2H, &Hdr.u.v0, &Hdr.u.v0);
                 break;
             case 1:
@@ -3260,4 +3427,5 @@
                                    pszFilename);
                 }
+                vdiConvHeaderEndianessV1(VDIECONV_F2H, &Hdr.u.v1, &Hdr.u.v1);
                 if (Hdr.u.v1.cbHeader >= sizeof(Hdr.u.v1plus))
                 {
@@ -3269,4 +3437,5 @@
                         rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v1.1+ header in '%s'"),
                                        pszFilename);
+                    vdiConvHeaderEndianessV1p(VDIECONV_F2H, &Hdr.u.v1plus, &Hdr.u.v1plus);
                 }
                 break;
@@ -3317,7 +3486,5 @@
             break;
         }
-
-        for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)
-            paBlocks[i] = RT_LE2H_U32(paBlocks[i]);
+        vdiConvBlocksEndianess(VDIECONV_F2H, paBlocks, getImageBlocks(&Hdr));
 
         pu32BlockBitmap = (uint32_t *)RTMemAllocZ(RT_ALIGN_Z(getImageBlocks(&Hdr) / 8, 4));
@@ -3362,9 +3529,7 @@
         else if (!(fFlags & VD_REPAIR_DRY_RUN))
         {
-            for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)
-                paBlocks[i] = RT_H2LE_U32(paBlocks[i]);
-
             vdIfErrorMessage(pIfError, "Writing repaired block allocation table...\n");
 
+            vdiConvBlocksEndianess(VDIECONV_H2F, paBlocks, getImageBlocks(&Hdr));
             rc = vdIfIoIntFileWriteSync(pIfIo, pStorage, offStartBlocks, paBlocks,
                                         getImageBlocks(&Hdr) * sizeof(VDIIMAGEBLOCKPOINTER),
Index: /trunk/src/VBox/Storage/VDICore.h
===================================================================
--- /trunk/src/VBox/Storage/VDICore.h	(revision 40935)
+++ /trunk/src/VBox/Storage/VDICore.h	(revision 40936)
@@ -605,4 +605,15 @@
 } VDIASYNCBLOCKALLOC, *PVDIASYNCBLOCKALLOC;
 
+/**
+ * Endianess conversion direction.
+ */
+typedef enum VDIECONV
+{
+    /** Host to file endianess. */
+    VDIECONV_H2F = 0,
+    /** File to host endianess. */
+    VDIECONV_F2H
+} VDIECONV;
+
 #endif
 
