Index: trunk/include/iprt/err.h
===================================================================
--- trunk/include/iprt/err.h	(revision 46970)
+++ trunk/include/iprt/err.h	(revision 46971)
@@ -1696,4 +1696,6 @@
 /** Too long name or link string. */
 #define VERR_TAR_NAME_TOO_LONG                  (-947)
+/** A directory entry in the archive. */
+#define VINF_TAR_DIR_PATH                        (925)
 /** @} */
 
Index: trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 46970)
+++ trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 46971)
@@ -304,5 +304,11 @@
             if (RT_SUCCESS(rc))
             {
-                fFound = !strcmp(pszFilename, RTPathFilename(pszLocation));
+                if (rc == VINF_TAR_DIR_PATH)
+                {
+                    break;
+                }
+
+                fFound = !RTStrICmp(pszFilename, pszLocation);
+
                 RTStrFree(pszFilename);
                 if (fFound)
Index: trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 46970)
+++ trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 46971)
@@ -809,5 +809,15 @@
     {
         throw setError(VBOX_E_FILE_ERROR,
-               tr("Could not open the current file in the archive (%Rrc)"), vrc);
+               tr("Could not open the current file in the OVA package (%Rrc)"), vrc);
+    }
+    else
+    {
+        if (vrc == VINF_TAR_DIR_PATH)
+        {
+            throw setError(VBOX_E_FILE_ERROR,
+                   tr("Empty directory folder (%s) isn't allowed in the OVA package (%Rrc)"), 
+                      pszFilename,
+                      vrc);
+        }
     }
 
@@ -1077,4 +1087,18 @@
                 break;
             }
+
+            Utf8Str extension(RTPathExt(pszFilename));
+
+            if (!extension.endsWith(".ovf",Utf8Str::CaseInsensitive))
+            {
+                vrc = VERR_FILE_NOT_FOUND;
+                rc = setError(VBOX_E_FILE_ERROR,
+                              tr("First file in the OVA package must have the extension 'ovf'. "
+                                 "But the file '%s' has the different extension (%Rrc)"),
+                                 pszFilename,
+                                 vrc);
+                break;
+            }
+
             pTarIo = TarCreateInterface();
             if (!pTarIo)
@@ -1141,5 +1165,5 @@
         size_t cbSize = 0;
         int vrc = ShaReadBuf(strFilename.c_str(), &pvTmpBuf, &cbSize, pIfIo, pStorage);
-        if (   RT_FAILURE(vrc)
+        if (RT_FAILURE(vrc)
             || !pvTmpBuf)
             throw setError(VBOX_E_FILE_ERROR,
@@ -1587,4 +1611,14 @@
             throw setError(VBOX_E_IPRT_ERROR,
                            tr("Getting the current file within the archive failed (%Rrc)"), vrc);
+        else
+        {
+            if (vrc == VINF_TAR_DIR_PATH)
+            {
+                throw setError(VBOX_E_FILE_ERROR,
+                       tr("Empty directory folder (%s) isn't allowed in the OVA package (%Rrc)"), 
+                          pszFilename,
+                          vrc);
+            }
+        }
         /* Skip the OVF file, cause this was read in IAppliance::Read already. */
         vrc = RTTarSeekNextFile(tar);
@@ -1593,4 +1627,15 @@
             throw setError(VBOX_E_IPRT_ERROR,
                            tr("Seeking within the archive failed (%Rrc)"), vrc);
+        else
+        {
+            if (vrc == VINF_TAR_DIR_PATH)
+            {
+                RTTarCurrentFile(tar, &pszFilename);
+                throw setError(VBOX_E_FILE_ERROR,
+                       tr("Empty directory folder (%s) isn't allowed in the OVA package (%Rrc)"), 
+                          pszFilename,
+                          vrc);
+            }
+        }
 
         PVDINTERFACEIO pCallbacks = pShaIo;
@@ -1878,7 +1923,17 @@
     if (RT_SUCCESS(vrc))
     {
-        if (!strcmp(pszCurFile, RTPathFilename(strFile.c_str())))
-            rc = readManifestFile(strFile, ppvBuf, pcbSize, pCallbacks, pStorage);
-        RTStrFree(pszCurFile);
+        if (vrc == VINF_TAR_DIR_PATH)
+        {
+            rc = setError(VBOX_E_FILE_ERROR,
+                          tr("Empty directory folder (%s) isn't allowed in the OVA package (%Rrc)"),
+                             pszCurFile,
+                             vrc);
+        }
+        else
+        {
+            if (!strcmp(pszCurFile, RTPathFilename(strFile.c_str())))
+                rc = readManifestFile(strFile, ppvBuf, pcbSize, pCallbacks, pStorage);
+            RTStrFree(pszCurFile);
+        }
     }
     else if (vrc != VERR_TAR_END_OF_FILE)
@@ -2771,5 +2826,7 @@
                                 {
                                     throw setError(E_FAIL,
-                                                   tr("Internal inconsistency looking up disk image '%s'"),
+                                                   tr("Internal inconsistency looking up disk image '%s'. "
+                                                      "Check compliance OVA package structure and file names "
+                                                      "references in the section <References> in the OVF file."),
                                                    availableImage.c_str());
                                 }
@@ -3203,5 +3260,7 @@
                     {
                         throw setError(E_FAIL,
-                                       tr("Internal inconsistency looking up disk image '%s'"),
+                                       tr("Internal inconsistency looking up disk image '%s'. "
+                                          "Check compliance OVA package structure and file names "
+                                          "references in the section <References> in the OVF file."),
                                        availableImage.c_str());
                     }
Index: trunk/src/VBox/Runtime/common/zip/tar.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/zip/tar.cpp	(revision 46970)
+++ trunk/src/VBox/Runtime/common/zip/tar.cpp	(revision 46971)
@@ -136,4 +136,6 @@
     /** The open mode. */
     uint32_t        fOpenMode;
+    /** The link flag. */
+    char            linkflag;
 } RTTARFILEINTERNAL;
 /** Pointer to the internal data of a tar file.  */
@@ -1621,12 +1623,21 @@
     uint64_t offCur = RTFileTell(pInt->hTarFile);
     if (!(   pInt->pFileCache->offStart <= offCur
-          && offCur < pInt->pFileCache->offStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize))
+          && offCur <= pInt->pFileCache->offStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize))
         return VERR_INVALID_STATE;
 
     /* Seek to the next file header. */
     uint64_t offNext = RT_ALIGN(pInt->pFileCache->offStart + sizeof(RTTARRECORD) + pInt->pFileCache->cbSize, sizeof(RTTARRECORD));
-    rc = RTFileSeek(pInt->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL);
-    if (RT_FAILURE(rc))
-        return rc;
+    if (pInt->pFileCache->cbSize != 0)
+    {
+        rc = RTFileSeek(pInt->hTarFile, offNext - offCur, RTFILE_SEEK_CURRENT, NULL);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+    else
+    {
+        /* Else delete the last open file cache. Might be recreated below. */
+        rtDeleteTarFileInternal(pInt->pFileCache);
+        pInt->pFileCache = NULL;
+    }
 
     /* Again check the current filename to fill the cache with the new value. */
@@ -1652,6 +1663,11 @@
     if (pInt->pFileCache)
     {
-        /* Are we still direct behind that header? */
-        if (pInt->pFileCache->offStart + sizeof(RTTARRECORD) == RTFileTell(pInt->hTarFile))
+        if (pInt->pFileCache->offStart + sizeof(RTTARRECORD) < RTFileTell(pInt->hTarFile))
+        {
+            /* Else delete the last open file cache. Might be recreated below. */
+            rtDeleteTarFileInternal(pInt->pFileCache);
+            pInt->pFileCache = NULL;
+        }
+        else/* Are we still direct behind that header? */
         {
             /* Yes, so the streaming can start. Just return the cached file
@@ -1660,10 +1676,10 @@
             if (ppszFilename)
                 *ppszFilename = RTStrDup(pInt->pFileCache->pszFilename);
-            return VINF_SUCCESS;
-        }
-
-        /* Else delete the last open file cache. Might be recreated below. */
-        rtDeleteTarFileInternal(pInt->pFileCache);
-        pInt->pFileCache = NULL;
+            if (pInt->pFileCache->linkflag == LF_DIR)
+                return VINF_TAR_DIR_PATH;
+            else
+                return VINF_SUCCESS;
+        }
+
     }
 
@@ -1683,5 +1699,6 @@
         /* We support normal files only */
         if (   record.h.linkflag == LF_OLDNORMAL
-            || record.h.linkflag == LF_NORMAL)
+            || record.h.linkflag == LF_NORMAL
+            || record.h.linkflag == LF_DIR)
         {
             pFileInt = rtCreateTarFileInternal(pInt, record.h.name, fOpen);
@@ -1696,4 +1713,6 @@
             /* The start is -512 from here. */
             pFileInt->offStart = RTFileTell(pInt->hTarFile) - sizeof(RTTARRECORD);
+            /* remember the type of a file */
+            pFileInt->linkflag = record.h.linkflag;
 
             /* Copy the new file structure to our cache. */
@@ -1701,4 +1720,9 @@
             if (ppszFilename)
                 *ppszFilename = RTStrDup(pFileInt->pszFilename);
+
+            if (pFileInt->linkflag == LF_DIR)
+            {
+                rc = VINF_TAR_DIR_PATH;
+            }
         }
     } while (0);
