Index: /trunk/include/VBox/vd-ifs.h
===================================================================
--- /trunk/include/VBox/vd-ifs.h	(revision 43786)
+++ /trunk/include/VBox/vd-ifs.h	(revision 43787)
@@ -308,5 +308,5 @@
     va_list va;
     va_start(va, pszFormat);
-    if (pIfError)
+    if (pIfError && pIfError->pfnMessage)
         rc = pIfError->pfnMessage(pIfError->Core.pvUser, pszFormat, va);
     va_end(va);
Index: /trunk/src/VBox/Storage/VD.cpp
===================================================================
--- /trunk/src/VBox/Storage/VD.cpp	(revision 43786)
+++ /trunk/src/VBox/Storage/VD.cpp	(revision 43787)
@@ -5451,4 +5451,33 @@
                                       pDisk->enmType,
                                       &pImage->pBackendData);
+        /*
+         * If the image is corrupted and there is a repair method try to repair it
+         * first if it was openend in read-write mode and open again afterwards.
+         */
+        if (   RT_UNLIKELY(rc == VERR_VD_IMAGE_CORRUPTED)
+            && pImage->Backend->pfnRepair)
+        {
+            rc = pImage->Backend->pfnRepair(pszFilename, pDisk->pVDIfsDisk, pImage->pVDIfsImage, 0 /* fFlags */);
+            if (RT_SUCCESS(rc))
+                rc = pImage->Backend->pfnOpen(pImage->pszFilename,
+                                              uOpenFlags & ~(VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS),
+                                              pDisk->pVDIfsDisk,
+                                              pImage->pVDIfsImage,
+                                              pDisk->enmType,
+                                              &pImage->pBackendData);
+            else
+            {
+                rc = vdError(pDisk, rc, RT_SRC_POS,
+                             N_("VD: error %Rrc repairing corrupted image file '%s'"), rc, pszFilename);
+                break;
+            }
+        }
+        else if (RT_UNLIKELY(rc == VERR_VD_IMAGE_CORRUPTED))
+        {
+            rc = vdError(pDisk, rc, RT_SRC_POS,
+                         N_("VD: Image file '%s' is corrupted and can't be opened"), pszFilename);
+            break;
+        }
+
         /* If the open in read-write mode failed, retry in read-only mode. */
         if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Storage/VHD.cpp
===================================================================
--- /trunk/src/VBox/Storage/VHD.cpp	(revision 43786)
+++ /trunk/src/VBox/Storage/VHD.cpp	(revision 43787)
@@ -793,6 +793,26 @@
     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, pImage->uCurrentEndOfFile,
                                &vhdFooter, sizeof(VHDFooter), NULL);
-    if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0)
-        return VERR_VD_VHD_INVALID_HEADER;
+    if (RT_SUCCESS(rc))
+    {
+        if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0)
+        {
+            /*
+             * There is also a backup header at the beginning in case the image got corrupted.
+             * Such corrupted images are detected here to let the open handler repair it later.
+             */
+            rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0,
+                                       &vhdFooter, sizeof(VHDFooter), NULL);
+            if (RT_SUCCESS(rc))
+            {
+                if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0)
+                    rc = VERR_VD_VHD_INVALID_HEADER;
+                else
+                    rc = VERR_VD_IMAGE_CORRUPTED;
+            }
+        }
+    }
+
+    if (RT_FAILURE(rc))
+        return rc;
 
     switch (RT_BE2H_U32(vhdFooter.DiskType))
@@ -1222,11 +1242,24 @@
     rc = vdIfIoIntFileReadSync(pIfIo, pStorage, cbFile - sizeof(VHDFooter),
                                &vhdFooter, sizeof(VHDFooter), NULL);
-    if (RT_FAILURE(rc) || (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0))
+    if (RT_SUCCESS(rc))
+    {
+        if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0)
+        {
+            /*
+             * There is also a backup header at the beginning in case the image got corrupted.
+             * Such corrupted images are detected here to let the open handler repair it later.
+             */
+            rc = vdIfIoIntFileReadSync(pIfIo, pStorage, 0,
+                                       &vhdFooter, sizeof(VHDFooter), NULL);
+            if (   RT_FAILURE(rc)
+                || (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0))
+                   rc = VERR_VD_VHD_INVALID_HEADER;
+        }
+
+        if (RT_SUCCESS(rc))
+            *penmType = VDTYPE_HDD;
+    }
+    else
         rc = VERR_VD_VHD_INVALID_HEADER;
-    else
-    {
-        *penmType = VDTYPE_HDD;
-        rc = VINF_SUCCESS;
-    }
 
     vdIfIoIntFileClose(pIfIo, pStorage);
