Index: /trunk/include/iprt/manifest.h
===================================================================
--- /trunk/include/iprt/manifest.h	(revision 29900)
+++ /trunk/include/iprt/manifest.h	(revision 29901)
@@ -52,4 +52,16 @@
 
 /**
+ * Manifest progress callback.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   uPercent    The progress completion percentage.
+ * @param   pvUser      The user defined parameter.
+ */
+typedef DECLCALLBACK(int) FNRTMANIFESTPROGRESS(unsigned uPercent, void *pvUser);
+/** Pointer to a manifest progress callback. */
+typedef FNRTMANIFESTPROGRESS *PFNRTMANIFESTPROGRESS;
+
+/**
  * Verify the given SHA1 digests against the entries in the manifest file.
  *
@@ -82,6 +94,8 @@
  *                               VERR_MANIFEST_DIGEST_MISMATCH error case
  *                               (optional).
+ * @param   pfnProgressCallback  optional callback for the progress indication
+ * @param   pvUser               user defined pointer for the callback
  */
-RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed);
+RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser);
 
 /**
@@ -95,6 +109,8 @@
  * @param   papszFiles           Array of files to create SHA1 sums for.
  * @param   cFiles               Number of entries in papszFiles.
+ * @param   pfnProgressCallback  optional callback for the progress indication
+ * @param   pvUser               user defined pointer for the callback
  */
-RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles);
+RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser);
 
 /** @} */
Index: /trunk/include/iprt/sha.h
===================================================================
--- /trunk/include/iprt/sha.h	(revision 29900)
+++ /trunk/include/iprt/sha.h	(revision 29901)
@@ -35,4 +35,16 @@
  * @{
  */
+
+/**
+ * SHA progress callback.
+ *
+ * @returns IPRT status code.
+ *
+ * @param   uPercent    The progress completion percentage.
+ * @param   pvUser      The user defined parameter.
+ */
+typedef DECLCALLBACK(int) FNRTSHAPROGRESS(unsigned uPercent, void *pvUser);
+/** Pointer to a SHA progress callback. */
+typedef FNRTSHAPROGRESS *PFNRTSHAPROGRESS;
 
 /** The size of a SHA-1 hash. */
@@ -90,5 +102,5 @@
 
 /**
- * Converts a SHA-512 hash to a digest string.
+ * Converts a SHA-1 hash to a digest string.
  *
  * @returns IPRT status code.
@@ -118,8 +130,10 @@
  * @returns iprt status code.
  *
- * @param   pszFile      Filename to create a SHA1 digest for.
- * @param   ppszDigest   On success the SHA1 digest.
- */
-RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest);
+ * @param   pszFile               Filename to create a SHA1 digest for.
+ * @param   ppszDigest            On success the SHA1 digest.
+ * @param   pfnProgressCallback   optional callback for the progress indication
+ * @param   pvUser                user defined pointer for the callback
+ */
+RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest, PFNRTSHAPROGRESS pfnProgressCallback, void *pvUser);
 
 
Index: /trunk/src/VBox/Main/ApplianceImplExport.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImplExport.cpp	(revision 29900)
+++ /trunk/src/VBox/Main/ApplianceImplExport.cpp	(revision 29901)
@@ -1608,5 +1608,5 @@
              ++it1, ++i)
             ppManifestFiles[i] = (*it1).c_str();
-        int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1);
+        int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1, NULL, NULL);
         RTMemFree(ppManifestFiles);
         if (RT_FAILURE(vrc))
Index: /trunk/src/VBox/Main/ApplianceImplImport.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImplImport.cpp	(revision 29900)
+++ /trunk/src/VBox/Main/ApplianceImplImport.cpp	(revision 29901)
@@ -671,5 +671,5 @@
         /* Create the SHA1 sum of the OVF file for later validation */
         char *pszDigest;
-        int vrc = RTSha1Digest(locInfo.strPath.c_str(), &pszDigest);
+        int vrc = RTSha1Digest(locInfo.strPath.c_str(), &pszDigest, NULL, NULL);
         if (RT_FAILURE(vrc))
             throw setError(VBOX_E_FILE_ERROR,
@@ -1065,5 +1065,5 @@
         {
             char* pszDigest;
-            vrc = RTSha1Digest((*it1).c_str(), &pszDigest);
+            vrc = RTSha1Digest((*it1).c_str(), &pszDigest, NULL, NULL);
             pTestList[i].pszTestFile = (char*)(*it1).c_str();
             pTestList[i].pszTestDigest = pszDigest;
Index: /trunk/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp	(revision 29900)
+++ /trunk/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp	(revision 29901)
@@ -33,19 +33,19 @@
 
 #include <iprt/assert.h>
-#include <iprt/err.h>
-#include <iprt/stream.h>
+#include <iprt/mem.h>
 #include <iprt/string.h>
+#include <iprt/file.h>
 
 #include <openssl/sha.h>
 
-
-
-RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest)
+RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest, PFNRTSHAPROGRESS pfnProgressCallback, void *pvUser)
 {
     /* Validate input */
     AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
     AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
+    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
 
     *ppszDigest = NULL;
+    int rc = VINF_SUCCESS;
 
     /* Initialize OpenSSL */
@@ -54,22 +54,35 @@
         return VERR_INTERNAL_ERROR;
 
-    /** @todo r=bird: Using a stream here doesn't really serve much purpose as
-     *        few stream implementations uses a buffer much larger than 4KB. (The
-     *        only I'm aware of is libc on OS/2, which uses 8KB.) */
+    /* Fetch the file size. Only needed if there is a progress callback. */
+    float multi = 0;
+    if (pfnProgressCallback)
+    {
+        uint64_t cbFile;
+        rc = RTFileQuerySize(pszFile, &cbFile);
+        if (RT_FAILURE(rc))
+            return rc;
+        multi = 100.0 / cbFile;
+    }
 
     /* Open the file to calculate a SHA1 sum of */
-    PRTSTREAM pStream;
-    int rc = RTStrmOpen(pszFile, "rb", &pStream);
+    RTFILE file;
+    rc = RTFileOpen(&file, pszFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
     if (RT_FAILURE(rc))
         return rc;
 
     /* Read that file in blocks */
-    void *pvBuf[4096];
+    void *pvBuf = RTMemTmpAlloc(_1M);
+    if (!pvBuf)
+    {
+        RTFileClose(file);
+        rc = VERR_NO_MEMORY;
+    }
     size_t cbRead;
-    do
+    size_t cbReadFull = 0;
+    for (;;)
     {
         cbRead = 0;
-        rc = RTStrmReadEx(pStream, pvBuf, 4096, &cbRead);
-        if (RT_FAILURE(rc))
+        rc = RTFileRead(file, pvBuf, _1M, &cbRead);
+        if (RT_FAILURE(rc) || !cbRead)
             break;
         if(!SHA1_Update(&ctx, pvBuf, cbRead))
@@ -78,6 +91,16 @@
             break;
         }
-    } while (cbRead > 0);
-    RTStrmClose(pStream);
+        cbReadFull += cbRead;
+        /* Call progress callback if some is defined */
+        if (   pfnProgressCallback
+            && RT_FAILURE(pfnProgressCallback((unsigned)(cbReadFull * multi), pvUser)))
+        {
+            /* Cancel support */
+            rc = VERR_CANCELLED;
+            break;
+        }
+    }
+    RTMemTmpFree(pvBuf);
+    RTFileClose(file);
 
     if (RT_FAILURE(rc))
@@ -85,5 +108,5 @@
 
     /* Finally calculate & format the SHA1 sum */
-    unsigned char auchDig[20];
+    unsigned char auchDig[RTSHA1_HASH_SIZE];
     if (!SHA1_Final(auchDig, &ctx))
         return VERR_INTERNAL_ERROR;
Index: /trunk/src/VBox/Runtime/common/checksum/manifest.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/checksum/manifest.cpp	(revision 29900)
+++ /trunk/src/VBox/Runtime/common/checksum/manifest.cpp	(revision 29901)
@@ -55,5 +55,21 @@
 typedef RTMANIFESTFILEENTRY* PRTMANIFESTFILEENTRY;
 
-
+/**
+ * Internal structure used for the progress callback
+ */
+typedef struct RTMANIFESTCALLBACKDATA
+{
+    PFNRTMANIFESTPROGRESS pfnProgressCallback;
+    void *pvUser;
+    uint32_t cMaxFiles;
+    uint32_t cCurrentFile;
+} RTMANIFESTCALLBACKDATA;
+typedef RTMANIFESTCALLBACKDATA* PRTMANIFESTCALLBACKDATA;
+
+int rtSHAProgressCallback(unsigned uPercent, void *pvUser)
+{
+    PRTMANIFESTCALLBACKDATA pData = (PRTMANIFESTCALLBACKDATA)pvUser;
+    return pData->pfnProgressCallback((unsigned)((uPercent + (float)pData->cCurrentFile * 100.0) / (float)pData->cMaxFiles), pData->pvUser);
+}
 
 RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
@@ -211,9 +227,12 @@
 
 
-RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed)
+RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser)
 {
     /* Validate input */
     AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
     AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
+    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
+
+    int rc = VINF_SUCCESS;
 
     /* Create our compare list */
@@ -222,10 +241,16 @@
         return VERR_NO_MEMORY;
 
+    RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
     /* Fill our compare list */
-    int rc = VINF_SUCCESS;
     for (size_t i = 0; i < cFiles; ++i)
     {
         char *pszDigest;
-        rc = RTSha1Digest(papszFiles[i], &pszDigest);
+        if (pfnProgressCallback)
+        {
+            callback.cCurrentFile = i;
+            rc = RTSha1Digest(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
+        }
+        else
+            rc = RTSha1Digest(papszFiles[i], &pszDigest, NULL, NULL);
         if (RT_FAILURE(rc))
             break;
@@ -250,9 +275,10 @@
 
 
-RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles)
+RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser)
 {
     /* Validate input */
     AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
     AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
+    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
 
     /* Open a file to stream in */
@@ -262,9 +288,16 @@
         return rc;
 
+    RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
     for (size_t i = 0; i < cFiles; ++i)
     {
         /* Calculate the SHA1 digest of every file */
         char *pszDigest;
-        rc = RTSha1Digest(papszFiles[i], &pszDigest);
+        if (pfnProgressCallback)
+        {
+            callback.cCurrentFile = i;
+            rc = RTSha1Digest(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
+        }
+        else
+            rc = RTSha1Digest(papszFiles[i], &pszDigest, NULL, NULL);
         if (RT_FAILURE(rc))
             break;
