f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/* $Id$ */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** @file
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * IPRT - Manifest, the bits with the most dependencies.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2011 Oracle Corporation
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * available from http://www.virtualbox.org. This file is free software;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * you can redistribute it and/or modify it under the terms of the GNU
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * General Public License (GPL) as published by the Free Software
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The contents of this file may alternatively be used under the terms
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * of the Common Development and Distribution License Version 1.0
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * VirtualBox OSE distribution, in which case the provisions of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * CDDL are applicable instead of those of the GPL.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * You may elect to license modified versions of this file under the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * terms and conditions of either the GPL or the CDDL or both.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*******************************************************************************
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync* Header Files *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync*******************************************************************************/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include "internal/iprt.h"
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/manifest.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/asm.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/assert.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/err.h>
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync#include <iprt/file.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/md5.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/mem.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/sha.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/string.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/vfs.h>
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync#include <iprt/vfslowlevel.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*******************************************************************************
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync* Structures and Typedefs *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync*******************************************************************************/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Hashes data.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Used when hashing a file, stream or similar.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef struct RTMANIFESTHASHES
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The desired attribute types.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Only the hashes indicated by this will be calculated. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t fAttrs;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The size. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTFOFF cbStream;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The MD5 context. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMD5CONTEXT Md5Ctx;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-1 context. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSHA1CONTEXT Sha1Ctx;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-256 context. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSHA256CONTEXT Sha256Ctx;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-512 context. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSHA512CONTEXT Sha512Ctx;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The MD5 digest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint8_t abMd5Digest[RTMD5_HASH_SIZE];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-1 digest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint8_t abSha1Digest[RTSHA1_HASH_SIZE];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-256 digest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint8_t abSha256Digest[RTSHA256_HASH_SIZE];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The SHA-512 digest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint8_t abSha512Digest[RTSHA512_HASH_SIZE];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync} RTMANIFESTHASHES;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** Pointer to a the hashes for a stream. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef RTMANIFESTHASHES *PRTMANIFESTHASHES;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * The internal data of a manifest passthru I/O stream.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsynctypedef struct RTMANIFESTPTIOS
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** The stream we're reading from or writing to. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSIOSTREAM hVfsIos;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** The hashes. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTHASHES pHashes;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** Whether we're reading or writing. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync bool fReadOrWrite;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** Whether we've already added the entry to the manifest. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync bool fAddedEntry;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** The entry name. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync char *pszEntry;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /** The manifest to add the entry to. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTMANIFEST hManifest;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync} RTMANIFESTPTIOS;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/** Pointer to a the internal data of a manifest passthru I/O stream. */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsynctypedef RTMANIFESTPTIOS *PRTMANIFESTPTIOS;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Creates a hashes structure.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns Pointer to a hashes structure.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fAttrs The desired hashes, RTMANIFEST_ATTR_XXX.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic PRTMANIFESTHASHES rtManifestHashesCreate(uint32_t fAttrs)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTHASHES pHashes = (PRTMANIFESTHASHES)RTMemTmpAllocZ(sizeof(*pHashes));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pHashes->fAttrs = fAttrs;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*pHashes->cbStream = 0;*/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fAttrs & RTMANIFEST_ATTR_MD5)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMd5Init(&pHashes->Md5Ctx);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fAttrs & RTMANIFEST_ATTR_SHA1)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha1Init(&pHashes->Sha1Ctx);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fAttrs & RTMANIFEST_ATTR_SHA256)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha256Init(&pHashes->Sha256Ctx);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fAttrs & RTMANIFEST_ATTR_SHA512)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha512Init(&pHashes->Sha512Ctx);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return pHashes;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Updates the hashes with a block of data.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pHashes The hashes structure.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pvBuf The data block.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param cbBuf The size of the data block.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic void rtManifestHashesUpdate(PRTMANIFESTHASHES pHashes, void const *pvBuf, size_t cbBuf)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pHashes->cbStream += cbBuf;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_MD5)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMd5Update(&pHashes->Md5Ctx, pvBuf, cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA1)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha1Update(&pHashes->Sha1Ctx, pvBuf, cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA256)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha256Update(&pHashes->Sha256Ctx, pvBuf, cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA512)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha512Update(&pHashes->Sha512Ctx, pvBuf, cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Finalizes all the hashes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pHashes The hashes structure.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic void rtManifestHashesFinal(PRTMANIFESTHASHES pHashes)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_MD5)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMd5Final(pHashes->abMd5Digest, &pHashes->Md5Ctx);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA1)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha1Final(&pHashes->Sha1Ctx, pHashes->abSha1Digest);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA256)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha256Final(&pHashes->Sha256Ctx, pHashes->abSha256Digest);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA512)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSha512Final(&pHashes->Sha512Ctx, pHashes->abSha512Digest);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Adds the hashes to a manifest entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pHashes The hashes structure.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest to add them to.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestHashesSetAttrs(PRTMANIFESTHASHES pHashes, RTMANIFEST hManifest, const char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char szValue[RTSHA512_DIGEST_LEN + 8];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = VINF_SUCCESS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SIZE)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrPrintf(szValue, sizeof(szValue), "%RU64", (uint64_t)pHashes->cbStream);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTManifestEntrySetAttr(hManifest, pszEntry, "SIZE", szValue, RTMANIFEST_ATTR_SIZE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_MD5)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTMd5ToString(pHashes->abMd5Digest, szValue, sizeof(szValue));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc2))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTManifestEntrySetAttr(hManifest, pszEntry, "MD5", szValue, RTMANIFEST_ATTR_MD5);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA1)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTSha1ToString(pHashes->abSha1Digest, szValue, sizeof(szValue));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc2))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTManifestEntrySetAttr(hManifest, pszEntry, "SHA1", szValue, RTMANIFEST_ATTR_SHA1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA256)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTSha256ToString(pHashes->abSha256Digest, szValue, sizeof(szValue));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc2))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTManifestEntrySetAttr(hManifest, pszEntry, "SHA256", szValue, RTMANIFEST_ATTR_SHA256);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pHashes->fAttrs & RTMANIFEST_ATTR_SHA512)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTSha512ToString(pHashes->abSha512Digest, szValue, sizeof(szValue));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc2))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc2 = RTManifestEntrySetAttr(hManifest, pszEntry, "SHA512", szValue, RTMANIFEST_ATTR_SHA512);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rc2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Destroys the hashes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pHashes The hashes structure. NULL is ignored.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic void rtManifestHashesDestroy(PRTMANIFESTHASHES pHashes)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemTmpFree(pHashes);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/*
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * M a n i f e s t p a s s t h r u I / O s t r e a m
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * M a n i f e s t p a s s t h r u I / O s t r e a m
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * M a n i f e s t p a s s t h r u I / O s t r e a m
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSOBJOPS,pfnClose}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_Close(void *pvThis)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync int rc = VINF_SUCCESS;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (!pThis->fAddedEntry)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync {
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestHashesFinal(pThis->pHashes);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rc = rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync }
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVfsIoStrmRelease(pThis->hVfsIos);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->hVfsIos = NIL_RTVFSIOSTREAM;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestHashesDestroy(pThis->pHashes);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->pHashes = NULL;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTStrFree(pThis->pszEntry);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->pszEntry = NULL;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTManifestRelease(pThis->hManifest);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->hManifest = NIL_RTMANIFEST;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return rc;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * Updates the hashes with a scather/gather buffer.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param pThis The passthru I/O stream instance data.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param pSgBuf The scather/gather buffer.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param cbLeft The number of bytes to take from the buffer.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic void rtManifestPtIos_UpdateHashes(PRTMANIFESTPTIOS pThis, PCRTSGBUF pSgBuf, size_t cbLeft)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync {
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync size_t cbSeg = pSgBuf->paSegs[iSeg].cbSeg;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (cbSeg > cbLeft)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync cbSeg = cbLeft;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestHashesUpdate(pThis->pHashes, pSgBuf->paSegs[iSeg].pvSeg, cbSeg);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync cbLeft -= cbSeg;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (!cbLeft)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync break;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync }
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync int rc = RTVfsIoStrmSgRead(pThis->hVfsIos, pSgBuf, fBlocking, pcbRead);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (RT_SUCCESS(rc))
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbRead ? *pcbRead : ~(size_t)0);
bd7c18002f48884a132bb0967408b6111dec326evboxsync Assert(off == -1); NOREF(off);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return rc;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync int rc = RTVfsIoStrmSgWrite(pThis->hVfsIos, pSgBuf, fBlocking, pcbWritten);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (RT_SUCCESS(rc))
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_UpdateHashes(pThis, pSgBuf, pcbWritten ? *pcbWritten : ~(size_t)0);
bd7c18002f48884a132bb0967408b6111dec326evboxsync Assert(off == -1); NOREF(off);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return rc;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_Flush(void *pvThis)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return RTVfsIoStrmFlush(pThis->hVfsIos);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync uint32_t *pfRetEvents)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return RTVfsIoStrmPoll(pThis->hVfsIos, fEvents, cMillies, fIntr, pfRetEvents);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic DECLCALLBACK(int) rtManifestPtIos_Tell(void *pvThis, PRTFOFF poffActual)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTFOFF off = RTVfsIoStrmTell(pThis->hVfsIos);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (off < 0)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return (int)off;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *poffActual = off;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return VINF_SUCCESS;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * The manifest passthru I/O stream vtable.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncstatic RTVFSIOSTREAMOPS g_rtManifestPassthruIosOps =
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync { /* Obj */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSOBJOPS_VERSION,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSOBJTYPE_IO_STREAM,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync "manifest passthru I/O stream",
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_Close,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_QueryInfo,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSOBJOPS_VERSION
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync },
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSIOSTREAMOPS_VERSION,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync 0,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_Read,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_Write,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_Flush,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_PollOne,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestPtIos_Tell,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync NULL /* Skip */,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync NULL /* ZeroFill */,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSIOSTREAMOPS_VERSION,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync};
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * Add an entry for an I/O stream using a passthru stream.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * The passthru I/O stream will hash all the data read from or written to the
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * stream and automatically add an entry to the manifest with the desired
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * attributes when it is released. Alternatively one can call
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * RTManifestPtIosAddEntryNow() to have more control over exactly when this
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * action is performed and which status it yields.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @returns IPRT status code.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param hManifest The manifest to add the entry to.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param hVfsIos The I/O stream to pass thru to/from.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param pszEntry The entry name.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param fAttrs The attributes to create for this stream.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param fReadOrWrite Whether it's a read or write I/O stream.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param phVfsIosPassthru Where to return the new handle.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncRTDECL(int) RTManifestEntryAddPassthruIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync uint32_t fAttrs, bool fReadOrWrite, PRTVFSIOSTREAM phVfsIosPassthru)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /*
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * Validate input.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync AssertPtr(pszEntry);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync AssertPtr(phVfsIosPassthru);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync uint32_t cRefs = RTManifestRetain(hManifest);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync cRefs = RTVfsIoStrmRetain(hVfsIos);
403ffbcef0c8edb7053953a9bbc0e935b83e7cccvboxsync AssertReturnStmt(cRefs != UINT32_MAX, RTManifestRelease(hManifest), VERR_INVALID_HANDLE);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync /*
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * Create an instace of the passthru I/O stream.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVFSIOSTREAM hVfsPtIos;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync int rc = RTVfsNewIoStream(&g_rtManifestPassthruIosOps, sizeof(*pThis), fReadOrWrite ? RTFILE_O_READ : RTFILE_O_WRITE,
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync NIL_RTVFS, NIL_RTVFSLOCK, &hVfsPtIos, (void **)&pThis);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (RT_SUCCESS(rc))
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync {
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->hVfsIos = hVfsIos;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->pHashes = rtManifestHashesCreate(fAttrs);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->hManifest = hManifest;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->fReadOrWrite = fReadOrWrite;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->fAddedEntry = false;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->pszEntry = RTStrDup(pszEntry);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync if (pThis->pszEntry && pThis->pHashes)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync {
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *phVfsIosPassthru = hVfsPtIos;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return VINF_SUCCESS;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync }
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVfsIoStrmRelease(hVfsPtIos);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync }
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync else
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync {
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTVfsIoStrmRelease(hVfsIos);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync RTManifestRelease(hManifest);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync }
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return rc;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync/**
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * Adds the entry to the manifest right now.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync *
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @returns IPRT status code.
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * @param hVfsPtIos The manifest passthru I/O stream returned by
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync * RTManifestEntryAddPassthruIoStream().
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync */
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsyncRTDECL(int) RTManifestPtIosAddEntryNow(RTVFSIOSTREAM hVfsPtIos)
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync{
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)RTVfsIoStreamToPrivate(hVfsPtIos, &g_rtManifestPassthruIosOps);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync AssertReturn(pThis, VERR_INVALID_HANDLE);
b8bcae0d284d8a3870658f49687625a25d5fc8e1vboxsync AssertReturn(!pThis->fAddedEntry, VERR_WRONG_ORDER);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync pThis->fAddedEntry = true;
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync rtManifestHashesFinal(pThis->pHashes);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync return rtManifestHashesSetAttrs(pThis->pHashes, pThis->hManifest, pThis->pszEntry);
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync}
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
835ac9173220411ef9fe578c3d4c03e5edfa20bevboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Adds an entry for a file with the specified set of attributes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hVfsIos The I/O stream handle of the entry. This will
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * be processed to its end on successful return.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * (Must be positioned at the start to get
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * the expected results.)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fAttrs The attributes to create for this stream.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Note! This is a convenicence function, so just use the available public
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * methods to get the job done.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Allocate and initialize the hash contexts, hash digests and I/O buffer.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTHASHES pHashes = rtManifestHashesCreate(fAttrs);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!pHashes)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NO_TMP_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cbBuf = _1M;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync void *pvBuf = RTMemTmpAlloc(cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_UNLIKELY(!pvBuf))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync cbBuf = _4K;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pvBuf = RTMemTmpAlloc(cbBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_LIKELY(pvBuf))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Process the stream data.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync for (;;)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cbRead;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbBuf, true /*fBlocking*/, &cbRead);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if ( (rc == VINF_EOF && cbRead == 0)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync || RT_FAILURE(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync break;
f5e968755e8a553874d48ba15f80df71659951b8vboxsync rtManifestHashesUpdate(pHashes, pvBuf, cbRead);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
a50db7974cba92b077fb1c9f555e48e460512337vboxsync RTMemTmpFree(pvBuf);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Add the entry with the finalized hashes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestHashesFinal(pHashes);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = RTManifestEntryAdd(hManifest, pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestHashesSetAttrs(pHashes, hManifest, pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestHashesDestroy(pHashes);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = VERR_NO_TMP_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync