VirtualBox

Changeset 29901 in vbox


Ignore:
Timestamp:
May 31, 2010 12:53:25 PM (15 years ago)
Author:
vboxsync
Message:

IPRT: added progress callback support to SHA1 digest calculation and manifest verification

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/manifest.h

    r28800 r29901  
    5252
    5353/**
     54 * Manifest progress callback.
     55 *
     56 * @returns IPRT status code.
     57 *
     58 * @param   uPercent    The progress completion percentage.
     59 * @param   pvUser      The user defined parameter.
     60 */
     61typedef DECLCALLBACK(int) FNRTMANIFESTPROGRESS(unsigned uPercent, void *pvUser);
     62/** Pointer to a manifest progress callback. */
     63typedef FNRTMANIFESTPROGRESS *PFNRTMANIFESTPROGRESS;
     64
     65/**
    5466 * Verify the given SHA1 digests against the entries in the manifest file.
    5567 *
     
    8294 *                               VERR_MANIFEST_DIGEST_MISMATCH error case
    8395 *                               (optional).
     96 * @param   pfnProgressCallback  optional callback for the progress indication
     97 * @param   pvUser               user defined pointer for the callback
    8498 */
    85 RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed);
     99RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser);
    86100
    87101/**
     
    95109 * @param   papszFiles           Array of files to create SHA1 sums for.
    96110 * @param   cFiles               Number of entries in papszFiles.
     111 * @param   pfnProgressCallback  optional callback for the progress indication
     112 * @param   pvUser               user defined pointer for the callback
    97113 */
    98 RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles);
     114RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser);
    99115
    100116/** @} */
  • trunk/include/iprt/sha.h

    r29821 r29901  
    3535 * @{
    3636 */
     37
     38/**
     39 * SHA progress callback.
     40 *
     41 * @returns IPRT status code.
     42 *
     43 * @param   uPercent    The progress completion percentage.
     44 * @param   pvUser      The user defined parameter.
     45 */
     46typedef DECLCALLBACK(int) FNRTSHAPROGRESS(unsigned uPercent, void *pvUser);
     47/** Pointer to a SHA progress callback. */
     48typedef FNRTSHAPROGRESS *PFNRTSHAPROGRESS;
    3749
    3850/** The size of a SHA-1 hash. */
     
    90102
    91103/**
    92  * Converts a SHA-512 hash to a digest string.
     104 * Converts a SHA-1 hash to a digest string.
    93105 *
    94106 * @returns IPRT status code.
     
    118130 * @returns iprt status code.
    119131 *
    120  * @param   pszFile      Filename to create a SHA1 digest for.
    121  * @param   ppszDigest   On success the SHA1 digest.
    122  */
    123 RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest);
     132 * @param   pszFile               Filename to create a SHA1 digest for.
     133 * @param   ppszDigest            On success the SHA1 digest.
     134 * @param   pfnProgressCallback   optional callback for the progress indication
     135 * @param   pvUser                user defined pointer for the callback
     136 */
     137RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest, PFNRTSHAPROGRESS pfnProgressCallback, void *pvUser);
    124138
    125139
  • trunk/src/VBox/Main/ApplianceImplExport.cpp

    r29875 r29901  
    16081608             ++it1, ++i)
    16091609            ppManifestFiles[i] = (*it1).c_str();
    1610         int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1);
     1610        int vrc = RTManifestWriteFiles(strMfFile.c_str(), ppManifestFiles, diskList.size()+1, NULL, NULL);
    16111611        RTMemFree(ppManifestFiles);
    16121612        if (RT_FAILURE(vrc))
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r29894 r29901  
    671671        /* Create the SHA1 sum of the OVF file for later validation */
    672672        char *pszDigest;
    673         int vrc = RTSha1Digest(locInfo.strPath.c_str(), &pszDigest);
     673        int vrc = RTSha1Digest(locInfo.strPath.c_str(), &pszDigest, NULL, NULL);
    674674        if (RT_FAILURE(vrc))
    675675            throw setError(VBOX_E_FILE_ERROR,
     
    10651065        {
    10661066            char* pszDigest;
    1067             vrc = RTSha1Digest((*it1).c_str(), &pszDigest);
     1067            vrc = RTSha1Digest((*it1).c_str(), &pszDigest, NULL, NULL);
    10681068            pTestList[i].pszTestFile = (char*)(*it1).c_str();
    10691069            pTestList[i].pszTestDigest = pszDigest;
  • trunk/src/VBox/Runtime/common/checksum/RTSha1Digest.cpp

    r29820 r29901  
    3333
    3434#include <iprt/assert.h>
    35 #include <iprt/err.h>
    36 #include <iprt/stream.h>
     35#include <iprt/mem.h>
    3736#include <iprt/string.h>
     37#include <iprt/file.h>
    3838
    3939#include <openssl/sha.h>
    4040
    41 
    42 
    43 RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest)
     41RTR3DECL(int) RTSha1Digest(const char *pszFile, char **ppszDigest, PFNRTSHAPROGRESS pfnProgressCallback, void *pvUser)
    4442{
    4543    /* Validate input */
    4644    AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
    4745    AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
     46    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
    4847
    4948    *ppszDigest = NULL;
     49    int rc = VINF_SUCCESS;
    5050
    5151    /* Initialize OpenSSL */
     
    5454        return VERR_INTERNAL_ERROR;
    5555
    56     /** @todo r=bird: Using a stream here doesn't really serve much purpose as
    57      *        few stream implementations uses a buffer much larger than 4KB. (The
    58      *        only I'm aware of is libc on OS/2, which uses 8KB.) */
     56    /* Fetch the file size. Only needed if there is a progress callback. */
     57    float multi = 0;
     58    if (pfnProgressCallback)
     59    {
     60        uint64_t cbFile;
     61        rc = RTFileQuerySize(pszFile, &cbFile);
     62        if (RT_FAILURE(rc))
     63            return rc;
     64        multi = 100.0 / cbFile;
     65    }
    5966
    6067    /* Open the file to calculate a SHA1 sum of */
    61     PRTSTREAM pStream;
    62     int rc = RTStrmOpen(pszFile, "rb", &pStream);
     68    RTFILE file;
     69    rc = RTFileOpen(&file, pszFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    6370    if (RT_FAILURE(rc))
    6471        return rc;
    6572
    6673    /* Read that file in blocks */
    67     void *pvBuf[4096];
     74    void *pvBuf = RTMemTmpAlloc(_1M);
     75    if (!pvBuf)
     76    {
     77        RTFileClose(file);
     78        rc = VERR_NO_MEMORY;
     79    }
    6880    size_t cbRead;
    69     do
     81    size_t cbReadFull = 0;
     82    for (;;)
    7083    {
    7184        cbRead = 0;
    72         rc = RTStrmReadEx(pStream, pvBuf, 4096, &cbRead);
    73         if (RT_FAILURE(rc))
     85        rc = RTFileRead(file, pvBuf, _1M, &cbRead);
     86        if (RT_FAILURE(rc) || !cbRead)
    7487            break;
    7588        if(!SHA1_Update(&ctx, pvBuf, cbRead))
     
    7891            break;
    7992        }
    80     } while (cbRead > 0);
    81     RTStrmClose(pStream);
     93        cbReadFull += cbRead;
     94        /* Call progress callback if some is defined */
     95        if (   pfnProgressCallback
     96            && RT_FAILURE(pfnProgressCallback((unsigned)(cbReadFull * multi), pvUser)))
     97        {
     98            /* Cancel support */
     99            rc = VERR_CANCELLED;
     100            break;
     101        }
     102    }
     103    RTMemTmpFree(pvBuf);
     104    RTFileClose(file);
    82105
    83106    if (RT_FAILURE(rc))
     
    85108
    86109    /* Finally calculate & format the SHA1 sum */
    87     unsigned char auchDig[20];
     110    unsigned char auchDig[RTSHA1_HASH_SIZE];
    88111    if (!SHA1_Final(auchDig, &ctx))
    89112        return VERR_INTERNAL_ERROR;
  • trunk/src/VBox/Runtime/common/checksum/manifest.cpp

    r28800 r29901  
    5555typedef RTMANIFESTFILEENTRY* PRTMANIFESTFILEENTRY;
    5656
    57 
     57/**
     58 * Internal structure used for the progress callback
     59 */
     60typedef struct RTMANIFESTCALLBACKDATA
     61{
     62    PFNRTMANIFESTPROGRESS pfnProgressCallback;
     63    void *pvUser;
     64    uint32_t cMaxFiles;
     65    uint32_t cCurrentFile;
     66} RTMANIFESTCALLBACKDATA;
     67typedef RTMANIFESTCALLBACKDATA* PRTMANIFESTCALLBACKDATA;
     68
     69int rtSHAProgressCallback(unsigned uPercent, void *pvUser)
     70{
     71    PRTMANIFESTCALLBACKDATA pData = (PRTMANIFESTCALLBACKDATA)pvUser;
     72    return pData->pfnProgressCallback((unsigned)((uPercent + (float)pData->cCurrentFile * 100.0) / (float)pData->cMaxFiles), pData->pvUser);
     73}
    5874
    5975RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
     
    211227
    212228
    213 RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed)
     229RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser)
    214230{
    215231    /* Validate input */
    216232    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
    217233    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
     234    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
     235
     236    int rc = VINF_SUCCESS;
    218237
    219238    /* Create our compare list */
     
    222241        return VERR_NO_MEMORY;
    223242
     243    RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
    224244    /* Fill our compare list */
    225     int rc = VINF_SUCCESS;
    226245    for (size_t i = 0; i < cFiles; ++i)
    227246    {
    228247        char *pszDigest;
    229         rc = RTSha1Digest(papszFiles[i], &pszDigest);
     248        if (pfnProgressCallback)
     249        {
     250            callback.cCurrentFile = i;
     251            rc = RTSha1Digest(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
     252        }
     253        else
     254            rc = RTSha1Digest(papszFiles[i], &pszDigest, NULL, NULL);
    230255        if (RT_FAILURE(rc))
    231256            break;
     
    250275
    251276
    252 RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles)
     277RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, PFNRTMANIFESTPROGRESS pfnProgressCallback, void *pvUser)
    253278{
    254279    /* Validate input */
    255280    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
    256281    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
     282    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
    257283
    258284    /* Open a file to stream in */
     
    262288        return rc;
    263289
     290    RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
    264291    for (size_t i = 0; i < cFiles; ++i)
    265292    {
    266293        /* Calculate the SHA1 digest of every file */
    267294        char *pszDigest;
    268         rc = RTSha1Digest(papszFiles[i], &pszDigest);
     295        if (pfnProgressCallback)
     296        {
     297            callback.cCurrentFile = i;
     298            rc = RTSha1Digest(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
     299        }
     300        else
     301            rc = RTSha1Digest(papszFiles[i], &pszDigest, NULL, NULL);
    269302        if (RT_FAILURE(rc))
    270303            break;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette