manifest3.cpp revision a50db7974cba92b077fb1c9f555e48e460512337
/* $Id$ */
/** @file
* IPRT - Manifest, the bits with the most dependencies.
*/
/*
* Copyright (C) 2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/manifest.h>
#include <iprt/vfslowlevel.h>
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* Hashes data.
*
* Used when hashing a file, stream or similar.
*/
typedef struct RTMANIFESTHASHES
{
/** The desired attribute types.
* Only the hashes indicated by this will be calculated. */
/** The size. */
/** The MD5 context. */
/** The SHA-1 context. */
/** The SHA-256 context. */
/** The SHA-512 context. */
/** The MD5 digest. */
/** The SHA-1 digest. */
/** The SHA-256 digest. */
/** The SHA-512 digest. */
/** Pointer to a the hashes for a stream. */
typedef RTMANIFESTHASHES *PRTMANIFESTHASHES;
/**
* The internal data of a manifest passthru I/O stream.
*/
typedef struct RTMANIFESTPTIOS
{
/** The stream we're reading from or writing to. */
/** The hashes. */
/** Whether we're reading or writing. */
bool fReadOrWrite;
/** Whether we've already added the entry to the manifest. */
bool fAddedEntry;
/** The entry name. */
char *pszEntry;
/** The manifest to add the entry to. */
/** Pointer to a the internal data of a manifest passthru I/O stream. */
typedef RTMANIFESTPTIOS *PRTMANIFESTPTIOS;
/**
* Creates a hashes structure.
*
* @returns Pointer to a hashes structure.
* @param fAttrs The desired hashes, RTMANIFEST_ATTR_XXX.
*/
{
if (pHashes)
{
/*pHashes->cbStream = 0;*/
if (fAttrs & RTMANIFEST_ATTR_MD5)
if (fAttrs & RTMANIFEST_ATTR_SHA1)
if (fAttrs & RTMANIFEST_ATTR_SHA256)
if (fAttrs & RTMANIFEST_ATTR_SHA512)
}
return pHashes;
}
/**
* Updates the hashes with a block of data.
*
* @param pHashes The hashes structure.
* @param pvBuf The data block.
* @param cbBuf The size of the data block.
*/
{
}
/**
* Finalizes all the hashes.
*
* @param pHashes The hashes structure.
*/
{
}
/**
* Adds the hashes to a manifest entry.
*
* @returns IPRT status code.
* @param pHashes The hashes structure.
* @param hManifest The manifest to add them to.
* @param pszEntry The entry name.
*/
static int rtManifestHashesSetAttrs(PRTMANIFESTHASHES pHashes, RTMANIFEST hManifest, const char *pszEntry)
{
int rc = VINF_SUCCESS;
int rc2;
{
}
{
if (RT_SUCCESS(rc2))
}
{
if (RT_SUCCESS(rc2))
}
{
if (RT_SUCCESS(rc2))
}
{
if (RT_SUCCESS(rc2))
}
return rc;
}
/**
* Destroys the hashes.
*
* @param pHashes The hashes structure. NULL is ignored.
*/
{
}
/*
*
* M a n i f e s t p a s s t h r u I / O s t r e a m
* M a n i f e s t p a s s t h r u I / O s t r e a m
* M a n i f e s t p a s s t h r u I / O s t r e a m
*
*/
/**
* @interface_method_impl{RTVFSOBJOPS,pfnClose}
*/
{
int rc = VINF_SUCCESS;
if (!pThis->fAddedEntry)
{
}
return rc;
}
/**
* @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
*/
static DECLCALLBACK(int) rtManifestPtIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
{
}
/**
*
* @param pThis The passthru I/O stream instance data.
* @param cbLeft The number of bytes to take from the buffer.
*/
{
{
if (!cbLeft)
break;
}
}
/**
* @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
*/
static DECLCALLBACK(int) rtManifestPtIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
{
if (RT_SUCCESS(rc))
return rc;
}
/**
* @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
*/
static DECLCALLBACK(int) rtManifestPtIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
{
if (RT_SUCCESS(rc))
return rc;
}
/**
* @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
*/
{
}
/**
* @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
*/
static DECLCALLBACK(int) rtManifestPtIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
{
}
/**
* @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
*/
{
if (off < 0)
return (int)off;
*poffActual = off;
return VINF_SUCCESS;
}
/**
* The manifest passthru I/O stream vtable.
*/
{
{ /* Obj */
"manifest passthru I/O stream",
},
0,
NULL /* Skip */,
NULL /* ZeroFill */,
};
/**
* Add an entry for an I/O stream using a passthru stream.
*
* The passthru I/O stream will hash all the data read from or written to the
* stream and automatically add an entry to the manifest with the desired
* attributes when it is released. Alternatively one can call
* RTManifestPtIosAddEntryNow() to have more control over exactly when this
* action is performed and which status it yields.
*
* @returns IPRT status code.
* @param hManifest The manifest to add the entry to.
* @param pszEntry The entry name.
* @param fAttrs The attributes to create for this stream.
* @param fReadOrWrite Whether it's a read or write I/O stream.
* @param phVfsIosPassthru Where to return the new handle.
*/
RTDECL(int) RTManifestEntryAddPassthruIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry,
{
/*
* Validate input.
*/
/*
* Create an instace of the passthru I/O stream.
*/
int rc = RTVfsNewIoStream(&g_rtManifestPassthruIosOps, sizeof(*pThis), fReadOrWrite ? RTFILE_O_READ : RTFILE_O_WRITE,
if (RT_SUCCESS(rc))
{
pThis->fAddedEntry = false;
{
return VINF_SUCCESS;
}
}
else
{
}
return rc;
}
/**
* Adds the entry to the manifest right now.
*
* @returns IPRT status code.
* @param hVfsPtIos The manifest passthru I/O stream returned by
* RTManifestEntryAddPassthruIoStream().
*/
{
PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)RTVfsIoStreamToPrivate(hVfsPtIos, &g_rtManifestPassthruIosOps);
pThis->fAddedEntry = true;
}
/**
* Adds an entry for a file with the specified set of attributes.
*
* @returns IPRT status code.
*
* @param hManifest The manifest handle.
* @param hVfsIos The I/O stream handle of the entry. This will
* be processed to its end on successful return.
* (Must be positioned at the start to get
* the expected results.)
* @param pszEntry The entry name.
* @param fAttrs The attributes to create for this stream.
*/
RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs)
{
/*
* Note! This is a convenicence function, so just use the available public
* methods to get the job done.
*/
/*
* Allocate and initialize the hash contexts, hash digests and I/O buffer.
*/
if (!pHashes)
return VERR_NO_TMP_MEMORY;
int rc;
if (RT_UNLIKELY(!pvBuf))
{
}
{
/*
* Process the stream data.
*/
for (;;)
{
|| RT_FAILURE(rc))
break;
}
if (RT_SUCCESS(rc))
{
/*
* Add the entry with the finalized hashes.
*/
if (RT_SUCCESS(rc))
}
}
else
{
}
return rc;
}