f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/* $Id$ */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** @file
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * IPRT - Manifest, the core.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2012 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>
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync#include <iprt/ctype.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/err.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/mem.h>
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync#include <iprt/param.h>
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync#include <iprt/md5.h>
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync#include <iprt/sha.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/string.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include <iprt/vfs.h>
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#include "internal/magics.h"
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*******************************************************************************
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync* Structures and Typedefs *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync*******************************************************************************/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest attribute.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Used both for entries and manifest attributes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef struct RTMANIFESTATTR
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The string space core (szName). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSTRSPACECORE StrCore;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The property value. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char *pszValue;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The attribute type if applicable, RTMANIFEST_ATTR_UNKNOWN if not. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t fType;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Whether it was visited by the equals operation or not. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync bool fVisited;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The normalized property name that StrCore::pszString points at. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char szName[1];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync} RTMANIFESTATTR;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** Pointer to a manifest attribute. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef RTMANIFESTATTR *PRTMANIFESTATTR;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef struct RTMANIFESTENTRY
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The string space core (szName). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSTRSPACECORE StrCore;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The entry attributes (hashes, checksums, size, etc) -
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFESTATTR. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSTRSPACE Attributes;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of attributes. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cAttributes;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Whether it was visited by the equals operation or not. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync bool fVisited;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The normalized entry name that StrCore::pszString points at. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char szName[1];
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync} RTMANIFESTENTRY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** Pointer to a manifest entry. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef RTMANIFESTENTRY *PRTMANIFESTENTRY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest handle data.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsynctypedef struct RTMANIFESTINT
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** Magic value (RTMANIFEST_MAGIC). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t u32Magic;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The number of references to this manifest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t volatile cRefs;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** String space of the entries covered by this manifest -
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFESTENTRY. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTSTRSPACE Entries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of entries. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cEntries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The entry for the manifest itself. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTMANIFESTENTRY SelfEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync} RTMANIFESTINT;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** The value of RTMANIFESTINT::u32Magic. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync#define RTMANIFEST_MAGIC UINT32_C(0x99998866)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync/**
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * Argument package passed to rtManifestWriteStdAttr by rtManifestWriteStdEntry
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * and RTManifestWriteStandard.
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsynctypedef struct RTMANIFESTWRITESTDATTR
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync{
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync /** The entry name. */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync const char *pszEntry;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync /** The output I/O stream. */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTVFSIOSTREAM hVfsIos;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync} RTMANIFESTWRITESTDATTR;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Argument package used by RTManifestEqualsEx to pass its arguments to the
956230513f1e35e9d694c219c7009034b71bb836vboxsync * enumeration callback functions.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsynctypedef struct RTMANIFESTEQUALS
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Name of entries to ignore. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync const char * const *papszIgnoreEntries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Name of attributes to ignore. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync const char * const *papszIgnoreAttr;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Flags governing the comparision. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t fFlags;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Where to return an error message (++) on failure. Can be NULL. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync char *pszError;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The size of the buffer pszError points to. Can be 0. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync size_t cbError;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Pointer to the 2nd manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTMANIFESTINT *pThis2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of ignored entries from the 1st manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cIgnoredEntries2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of entries processed from the 2nd manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cEntries2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of ignored attributes from the 1st manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cIgnoredAttributes1;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of ignored attributes from the 1st manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cIgnoredAttributes2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The number of attributes processed from the 2nd manifest. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync uint32_t cAttributes2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** Pointer to the string space to get matching attributes from. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTSTRSPACE pAttributes2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync /** The name of the current entry.
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Points to an empty string it's the manifest attributes. */
956230513f1e35e9d694c219c7009034b71bb836vboxsync const char *pszCurEntry;
956230513f1e35e9d694c219c7009034b71bb836vboxsync} RTMANIFESTEQUALS;
956230513f1e35e9d694c219c7009034b71bb836vboxsync/** Pointer to an RTManifestEqualEx argument packet. */
956230513f1e35e9d694c219c7009034b71bb836vboxsynctypedef RTMANIFESTEQUALS *PRTMANIFESTEQUALS;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync/**
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Argument package used by rtMainfestQueryAttrWorker to pass its search
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * criteria to rtMainfestQueryAttrEnumCallback and get a result back.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsynctypedef struct RTMANIFESTQUERYATTRARGS
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync{
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /** The attribute types we're hunting for. */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync uint32_t fType;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /** What we've found. */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync PRTMANIFESTATTR pAttr;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync} RTMANIFESTQUERYATTRARGS;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync/** Pointer to a rtMainfestQueryAttrEnumCallback argument packet. */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsynctypedef RTMANIFESTQUERYATTRARGS *PRTMANIFESTQUERYATTRARGS;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Creates an empty manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fFlags Flags, MBZ.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param phManifest Where to return the handle to the manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestCreate(uint32_t fFlags, PRTMANIFEST phManifest)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(phManifest);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = (RTMANIFESTINT *)RTMemAlloc(sizeof(*pThis));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!pThis)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NO_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pThis->u32Magic = RTMANIFEST_MAGIC;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pThis->cRefs = 1;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pThis->Entries = NULL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->cEntries = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->SelfEntry.StrCore.pszString = "main";
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->SelfEntry.StrCore.cchString = 4;
7cd65b78ef52a960d2237ca56abb05385a12217cvboxsync pThis->SelfEntry.Attributes = NULL;
7cd65b78ef52a960d2237ca56abb05385a12217cvboxsync pThis->SelfEntry.cAttributes = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->SelfEntry.fVisited = false;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->SelfEntry.szName[0] = '\0';
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *phManifest = pThis;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VINF_SUCCESS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Retains a reference to the manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns The new reference count, UINT32_MAX if the handle is invalid.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to retain.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(uint32_t) RTManifestRetain(RTMANIFEST hManifest)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, UINT32_MAX);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync Assert(cRefs > 1 && cRefs < _1M);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return cRefs;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTATTR.}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic DECLCALLBACK(int) rtManifestDestroyAttribute(PRTSTRSPACECORE pStr, void *pvUser)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrFree(pAttr->pszValue);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->pszValue = NULL;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pAttr);
bd7c18002f48884a132bb0967408b6111dec326evboxsync NOREF(pvUser);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return 0;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTENTRY.}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic DECLCALLBACK(int) rtManifestDestroyEntry(PRTSTRSPACECORE pStr, void *pvUser)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrSpaceDestroy(&pEntry->Attributes, rtManifestDestroyAttribute, pvUser);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return 0;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Releases a reference to the manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns The new reference count, 0 if free. UINT32_MAX is returned if the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * handle is invalid.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to release.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * NIL is quietly ignored (returns 0).
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(uint32_t) RTManifestRelease(RTMANIFEST hManifest)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis == NIL_RTMANIFEST)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return 0;
666edc71e2906904545617ad6fae769f7d0bbf08vboxsync AssertPtrReturn(pThis, UINT32_MAX);
666edc71e2906904545617ad6fae769f7d0bbf08vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync Assert(cRefs < _1M);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!cRefs)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTMANIFEST_MAGIC);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceDestroy(&pThis->Entries, rtManifestDestroyEntry,pThis);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceDestroy(&pThis->SelfEntry.Attributes, rtManifestDestroyAttribute, pThis);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pThis);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return cRefs;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Creates a duplicate of the specified manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifestSrc The manifest to clone.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param phManifestDst Where to store the handle to the duplicate.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestDup(RTMANIFEST hManifestSrc, PRTMANIFEST phManifestDst)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifestSrc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(phManifestDst);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** @todo implement cloning. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NOT_IMPLEMENTED;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestAttributeClearVisited(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr->fVisited = false;
bd7c18002f48884a132bb0967408b6111dec326evboxsync NOREF(pvUser);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestEntryClearVisited(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceEnumerate(&pEntry->Attributes, rtManifestAttributeClearVisited, NULL);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry->fVisited = false;
bd7c18002f48884a132bb0967408b6111dec326evboxsync NOREF(pvUser);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Finds the first missing.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestAttributeFindMissing2(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Already visited?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pAttr->fVisited)
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Ignore this entry?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync char const * const *ppsz = pEquals->papszIgnoreAttr;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync while (*ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!strcmp(*ppsz, pAttr->szName))
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync ppsz++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Gotcha!
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (*pEquals->pszCurEntry)
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError,
956230513f1e35e9d694c219c7009034b71bb836vboxsync "Attribute '%s' on '%s' was not found in the 1st manifest",
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr->szName, pEquals->pszCurEntry);
956230513f1e35e9d694c219c7009034b71bb836vboxsync else
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError, "Attribute '%s' was not found in the 1st manifest", pAttr->szName);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_NOT_EQUAL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Finds the first missing.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestEntryFindMissing2(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Already visited?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pEntry->fVisited)
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Ignore this entry?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync char const * const *ppsz = pEquals->papszIgnoreEntries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync while (*ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!strcmp(*ppsz, pEntry->StrCore.pszString))
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync ppsz++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Gotcha!
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError, "'%s' was not found in the 1st manifest", pEntry->StrCore.pszString);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_NOT_EQUAL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Compares attributes.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestAttributeCompare(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTATTR pAttr1 = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTATTR pAttr2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync Assert(!pAttr1->fVisited);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr1->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Ignore this entry?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync char const * const *ppsz = pEquals->papszIgnoreAttr;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync while (*ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!strcmp(*ppsz, pAttr1->szName))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr2 = (PRTMANIFESTATTR)RTStrSpaceGet(pEquals->pAttributes2, pAttr1->szName);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pAttr2)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync Assert(!pAttr2->fVisited);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr2->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cIgnoredAttributes2++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cIgnoredAttributes1++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync ppsz++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Find the matching attribute.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr2 = (PRTMANIFESTATTR)RTStrSpaceGet(pEquals->pAttributes2, pAttr1->szName);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!pAttr2)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pEquals->fFlags & RTMANIFEST_EQUALS_IGN_MISSING_ATTRS)
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (*pEquals->pszCurEntry)
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError,
956230513f1e35e9d694c219c7009034b71bb836vboxsync "Attribute '%s' on '%s' was not found in the 2nd manifest",
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr1->szName, pEquals->pszCurEntry);
956230513f1e35e9d694c219c7009034b71bb836vboxsync else
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError, "Attribute '%s' was not found in the 2nd manifest", pAttr1->szName);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_NOT_EQUAL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync Assert(!pAttr2->fVisited);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr2->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cAttributes2++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Compare them.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (strcmp(pAttr1->pszValue, pAttr2->pszValue))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (*pEquals->pszCurEntry)
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError,
956230513f1e35e9d694c219c7009034b71bb836vboxsync "Attribute '%s' on '%s' does not match ('%s' vs. '%s')",
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr1->szName, pEquals->pszCurEntry, pAttr1->pszValue, pAttr2->pszValue);
956230513f1e35e9d694c219c7009034b71bb836vboxsync else
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError,
956230513f1e35e9d694c219c7009034b71bb836vboxsync "Attribute '%s' does not match ('%s' vs. '%s')",
956230513f1e35e9d694c219c7009034b71bb836vboxsync pAttr1->szName, pAttr1->pszValue, pAttr2->pszValue);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_NOT_EQUAL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncDECLINLINE (int) rtManifestEntryCompare2(PRTMANIFESTEQUALS pEquals, PRTMANIFESTENTRY pEntry1, PRTMANIFESTENTRY pEntry2)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Compare the attributes. It's a bit ugly with all this counting, but
956230513f1e35e9d694c219c7009034b71bb836vboxsync * how else to efficiently implement RTMANIFEST_EQUALS_IGN_MISSING_ATTRS?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cIgnoredAttributes1 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cIgnoredAttributes2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cAttributes2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->pszCurEntry = &pEntry2->szName[0];
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->pAttributes2 = &pEntry2->Attributes;
956230513f1e35e9d694c219c7009034b71bb836vboxsync int rc = RTStrSpaceEnumerate(&pEntry1->Attributes, rtManifestAttributeCompare, pEquals);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (RT_SUCCESS(rc))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Check that we matched all that is required.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if ( pEquals->cAttributes2 + pEquals->cIgnoredAttributes2 != pEntry2->cAttributes
956230513f1e35e9d694c219c7009034b71bb836vboxsync && ( !(pEquals->fFlags & RTMANIFEST_EQUALS_IGN_MISSING_ATTRS)
956230513f1e35e9d694c219c7009034b71bb836vboxsync || pEquals->cIgnoredAttributes1 == pEntry1->cAttributes))
956230513f1e35e9d694c219c7009034b71bb836vboxsync rc = RTStrSpaceEnumerate(&pEntry2->Attributes, rtManifestAttributeFindMissing2, pEquals);
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rc;
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync/**
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.}
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic DECLCALLBACK(int) rtManifestEntryCompare(PRTSTRSPACECORE pStr, void *pvUser)
956230513f1e35e9d694c219c7009034b71bb836vboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser;
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTENTRY pEntry1 = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTENTRY pEntry2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Ignore this entry.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync char const * const *ppsz = pEquals->papszIgnoreEntries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync while (*ppsz)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!strcmp(*ppsz, pStr->pszString))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry2 = (PRTMANIFESTENTRY)RTStrSpaceGet(&pEquals->pThis2->Entries, pStr->pszString);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pEntry2)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry2->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cIgnoredEntries2++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry1->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync return 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync ppsz++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Try find the entry in the other manifest.
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry2 = (PRTMANIFESTENTRY)RTStrSpaceGet(&pEquals->pThis2->Entries, pEntry1->StrCore.pszString);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!pEntry2)
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrPrintf(pEquals->pszError, pEquals->cbError, "'%s' not found in the 2nd manifest", pEntry1->StrCore.pszString);
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_NOT_EQUAL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync Assert(!pEntry1->fVisited);
956230513f1e35e9d694c219c7009034b71bb836vboxsync Assert(!pEntry2->fVisited);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry1->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry2->fVisited = true;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEquals->cEntries2++;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rtManifestEntryCompare2(pEquals, pEntry1, pEntry2);
956230513f1e35e9d694c219c7009034b71bb836vboxsync}
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEqualsEx(RTMANIFEST hManifest1, RTMANIFEST hManifest2, const char * const *papszIgnoreEntries,
956230513f1e35e9d694c219c7009034b71bb836vboxsync const char * const *papszIgnoreAttr, uint32_t fFlags, char *pszError, size_t cbError)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync /*
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync * Validate input.
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync AssertPtrNullReturn(pszError, VERR_INVALID_POINTER);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (pszError && cbError)
956230513f1e35e9d694c219c7009034b71bb836vboxsync *pszError = '\0';
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis1 = hManifest1;
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTMANIFESTINT *pThis2 = hManifest2;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis1 != NIL_RTMANIFEST)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertPtrReturn(pThis1, VERR_INVALID_HANDLE);
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertReturn(pThis1->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis2 != NIL_RTMANIFEST)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertPtrReturn(pThis2, VERR_INVALID_HANDLE);
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertReturn(pThis2->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync AssertReturn(!(fFlags & ~(RTMANIFEST_EQUALS_IGN_MISSING_ATTRS)), VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The simple cases.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis1 == pThis2)
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync return VINF_SUCCESS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis1 == NIL_RTMANIFEST || pThis2 == NIL_RTMANIFEST)
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync return VERR_NOT_EQUAL;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Since we have to use callback style enumeration, we have to mark the
956230513f1e35e9d694c219c7009034b71bb836vboxsync * entries and attributes to make sure we've covered them all.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceEnumerate(&pThis1->Entries, rtManifestEntryClearVisited, NULL);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceEnumerate(&pThis2->Entries, rtManifestEntryClearVisited, NULL);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceEnumerate(&pThis1->SelfEntry.Attributes, rtManifestAttributeClearVisited, NULL);
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTStrSpaceEnumerate(&pThis2->SelfEntry.Attributes, rtManifestAttributeClearVisited, NULL);
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync RTMANIFESTEQUALS Equals;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.pThis2 = pThis2;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.fFlags = fFlags;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.papszIgnoreEntries = papszIgnoreEntries;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.papszIgnoreAttr = papszIgnoreAttr;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.pszError = pszError;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cbError = cbError;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cIgnoredEntries2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cEntries2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cIgnoredAttributes1 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cIgnoredAttributes2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.cAttributes2 = 0;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.pAttributes2 = NULL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync Equals.pszCurEntry = NULL;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync int rc = rtManifestEntryCompare2(&Equals, &pThis1->SelfEntry, &pThis2->SelfEntry);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (RT_SUCCESS(rc))
956230513f1e35e9d694c219c7009034b71bb836vboxsync rc = RTStrSpaceEnumerate(&pThis1->Entries, rtManifestEntryCompare, &Equals);
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (RT_SUCCESS(rc))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync /*
956230513f1e35e9d694c219c7009034b71bb836vboxsync * Did we cover all entries of the 2nd manifest?
956230513f1e35e9d694c219c7009034b71bb836vboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (Equals.cEntries2 + Equals.cIgnoredEntries2 != pThis2->cEntries)
956230513f1e35e9d694c219c7009034b71bb836vboxsync rc = RTStrSpaceEnumerate(&pThis1->Entries, rtManifestEntryFindMissing2, &Equals);
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEquals(RTMANIFEST hManifest1, RTMANIFEST hManifest2)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync return RTManifestEqualsEx(hManifest1, hManifest2,
956230513f1e35e9d694c219c7009034b71bb836vboxsync NULL /*papszIgnoreEntries*/, NULL /*papszIgnoreAttrs*/,
956230513f1e35e9d694c219c7009034b71bb836vboxsync 0 /*fFlags*/, NULL, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Worker common to RTManifestSetAttr and RTManifestEntrySetAttr.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @param pEntry Pointer to the entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The name of the attribute to add.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type type.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic int rtManifestSetAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, const char *pszValue, uint32_t fType)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char *pszValueCopy;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = RTStrDupEx(&pszValueCopy, pszValue);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Does the attribute exist already?
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrFree(pAttr->pszValue);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->pszValue = pszValueCopy;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->fType = fType;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cbName = strlen(pszAttr) + 1;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr = (PRTMANIFESTATTR)RTMemAllocVar(RT_OFFSETOF(RTMANIFESTATTR, szName[cbName]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!pAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrFree(pszValueCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NO_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync memcpy(pAttr->szName, pszAttr, cbName);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->StrCore.pszString = pAttr->szName;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->StrCore.cchString = cbName - 1;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->pszValue = pszValueCopy;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr->fType = fType;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (RT_UNLIKELY(!RTStrSpaceInsert(&pEntry->Attributes, &pAttr->StrCore)))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertFailed();
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrFree(pszValueCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_INTERNAL_ERROR_4;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry->cAttributes++;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VINF_SUCCESS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Sets a manifest attribute.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name. If this already exists,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * its value will be replaced.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type, pass
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFEST_ATTR_UNKNOWN if not known.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestSetAttr(RTMANIFEST hManifest, const char *pszAttr, const char *pszValue, uint32_t fType)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszValue);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rtManifestSetAttrWorker(&pThis->SelfEntry, pszAttr, pszValue, fType);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Worker common to RTManifestUnsetAttr and RTManifestEntryUnsetAttr.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
956230513f1e35e9d694c219c7009034b71bb836vboxsync * @param pEntry Pointer to the entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The name of the attribute to remove.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
956230513f1e35e9d694c219c7009034b71bb836vboxsyncstatic int rtManifestUnsetAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
956230513f1e35e9d694c219c7009034b71bb836vboxsync PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(&pEntry->Attributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!pStrCore)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VWRN_NOT_FOUND;
956230513f1e35e9d694c219c7009034b71bb836vboxsync pEntry->cAttributes--;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestDestroyAttribute(pStrCore, NULL);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VINF_SUCCESS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Unsets (removes) a manifest attribute if it exists.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_NOT_FOUND if not found.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestUnsetAttr(RTMANIFEST hManifest, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rtManifestUnsetAttrWorker(&pThis->SelfEntry, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync/**
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Callback employed by rtManifestQueryAttrWorker to search by attribute type.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync *
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @returns VINF_SUCCESS or VINF_CALLBACK_RETURN.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pStr The attribute string node.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pvUser The argument package.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsyncstatic DECLCALLBACK(int) rtMainfestQueryAttrEnumCallback(PRTSTRSPACECORE pStr, void *pvUser)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync{
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)pStr;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync PRTMANIFESTQUERYATTRARGS pArgs = (PRTMANIFESTQUERYATTRARGS)pvUser;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (pAttr->fType & pArgs->fType)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync {
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync pArgs->pAttr = pAttr;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VINF_CALLBACK_RETURN;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync }
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VINF_SUCCESS;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync}
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync/**
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Worker common to RTManifestQueryAttr and RTManifestEntryQueryAttr.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync *
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @returns IPRT status code.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pEntry The entry.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pszAttr The attribute name. If NULL, it will be
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * selected by @a fType alone.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param fType The attribute types the entry should match. Pass
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Pass RTMANIFEST_ATTR_ANY match any. If more
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * than one is given, the first matching one is
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * returned.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pszValue Where to return value.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param cbValue The size of the buffer @a pszValue points to.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * @param pfType Where to return the attribute type value.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsyncstatic int rtManifestQueryAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, uint32_t fType,
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync char *pszValue, size_t cbValue, uint32_t *pfType)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync{
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /*
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Find the requested attribute.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync PRTMANIFESTATTR pAttr;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (pszAttr)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync {
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /* By name. */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (!pAttr)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VERR_MANIFEST_ATTR_NOT_FOUND;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (!(pAttr->fType & fType))
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VERR_MANIFEST_ATTR_TYPE_MISMATCH;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync }
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync else
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync {
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /* By type. */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync RTMANIFESTQUERYATTRARGS Args;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync Args.fType = fType;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync Args.pAttr = NULL;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync int rc = RTStrSpaceEnumerate(&pEntry->Attributes, rtMainfestQueryAttrEnumCallback, &Args);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertRCReturn(rc, rc);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync pAttr = Args.pAttr;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (!pAttr)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VERR_MANIFEST_ATTR_TYPE_NOT_FOUND;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync }
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /*
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Set the return values.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (cbValue || pszValue)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync {
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync size_t cbNeeded = strlen(pAttr->pszValue) + 1;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (cbNeeded > cbValue)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VERR_BUFFER_OVERFLOW;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync memcpy(pszValue, pAttr->pszValue, cbNeeded);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync }
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (pfType)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync *pfType = pAttr->fType;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return VINF_SUCCESS;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync}
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsyncRTDECL(int) RTManifestQueryAttr(RTMANIFEST hManifest, const char *pszAttr, uint32_t fType,
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync char *pszValue, size_t cbValue, uint32_t *pfType)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync{
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync RTMANIFESTINT *pThis = hManifest;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtrNull(pszAttr);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtr(pszValue);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return rtManifestQueryAttrWorker(&pThis->SelfEntry, pszAttr, fType, pszValue, cbValue, pfType);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync}
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Validates the name entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name to validate.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pfNeedNormalization Where to return whether it needs normalization
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * or not. Optional.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pcchEntry Where to return the length. Optional.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestValidateNameEntry(const char *pszEntry, bool *pfNeedNormalization, size_t *pcchEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync bool fNeedNormalization = false;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync const char *pszCur = pszEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync for (;;)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTUNICP uc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = RTStrGetCpEx(&pszCur, &uc);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_FAILURE(rc))
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!uc)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync break;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (uc == '\\')
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync fNeedNormalization = true;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else if (uc < 32 || uc == ':' || uc == '(' || uc == ')')
956230513f1e35e9d694c219c7009034b71bb836vboxsync return VERR_INVALID_NAME;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pfNeedNormalization)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *pfNeedNormalization = fNeedNormalization;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync size_t cchEntry = pszCur - pszEntry - 1;
956230513f1e35e9d694c219c7009034b71bb836vboxsync if (!cchEntry)
956230513f1e35e9d694c219c7009034b71bb836vboxsync rc = VERR_INVALID_NAME;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pcchEntry)
956230513f1e35e9d694c219c7009034b71bb836vboxsync *pcchEntry = cchEntry;
956230513f1e35e9d694c219c7009034b71bb836vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Normalizes a entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name to normalize.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic void rtManifestNormalizeEntry(char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char ch;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync while ((ch = *pszEntry))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (ch == '\\')
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *pszEntry = '/';
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pszEntry++;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Gets an entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pThis The manifest to work with.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fNeedNormalization Whether rtManifestValidateNameEntry said it
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * needed normalization.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param cchEntry The length of the name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param ppEntry Where to return the entry pointer on success.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY *ppEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!fNeedNormalization)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_UNLIKELY(!pszCopy))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NO_TMP_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync memcpy(pszCopy, pszEntry, cchEntry + 1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestNormalizeEntry(pszCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemTmpFree(pszCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *ppEntry = pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Sets an attribute of a manifest entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name. This will automatically be
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * added if there was no previous call to
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTManifestEntryAdd for this name. See
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTManifestEntryAdd for the entry name rules.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name. If this already exists,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * its value will be replaced.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type, pass
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFEST_ATTR_UNKNOWN if not known.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntrySetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync const char *pszValue, uint32_t fType)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszValue);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync bool fNeedNormalization;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertRCReturn(rc, rc);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Resolve the entry, adding one if necessary.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (rc == VERR_NOT_FOUND)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!pEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_NO_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->StrCore.cchString = cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->StrCore.pszString = pEntry->szName;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->Attributes = NULL;
8f827447008ecf94b4c101b6ac2b795b760d802dvboxsync pEntry->cAttributes = 0;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync memcpy(pEntry->szName, pszEntry, cchEntry + 1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fNeedNormalization)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestNormalizeEntry(pEntry->szName);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return VERR_INTERNAL_ERROR_4;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->cEntries++;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else if (RT_FAILURE(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
956230513f1e35e9d694c219c7009034b71bb836vboxsync return rtManifestSetAttrWorker(pEntry, pszAttr, pszValue, fType);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Unsets (removes) an attribute of a manifest entry if they both exist.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_NOT_FOUND if not found.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryUnsetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync bool fNeedNormalization;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertRCReturn(rc, rc);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Resolve the entry and hand it over to the worker.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc))
956230513f1e35e9d694c219c7009034b71bb836vboxsync rc = rtManifestUnsetAttrWorker(pEntry, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsyncRTDECL(int) RTManifestEntryQueryAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr, uint32_t fType,
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync char *pszValue, size_t cbValue, uint32_t *pfType)
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync{
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync RTMANIFESTINT *pThis = hManifest;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtr(pszEntry);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtrNull(pszAttr);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertPtr(pszValue);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync /*
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync * Look up the entry.
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync */
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync bool fNeedNormalization;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync size_t cchEntry;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync AssertRCReturn(rc, rc);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync PRTMANIFESTENTRY pEntry;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync if (RT_SUCCESS(rc))
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync rc = rtManifestQueryAttrWorker(pEntry, pszAttr, fType, pszValue, cbValue, pfType);
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync return rc;
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync}
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
49bcf64aaacb2de9703cdd3633eec0a2610c3cf3vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Adds a new entry to a manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The entry name rules:
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - The entry name can contain any character defined by unicode, except
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * control characters, ':', '(' and ')'. The exceptions are mainly there
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * because of uncertainty around how various formats handles these.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - It is considered case sensitive.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - Forward (unix) and backward (dos) slashes are considered path
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * separators and converted to forward slashes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_ALREADY_EXISTS if the entry already exists.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name (UTF-8).
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @remarks Some manifest formats will not be able to store an entry without
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * any attributes. So, this is just here in case it comes in handy
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * when dealing with formats which can.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryAdd(RTMANIFEST hManifest, const char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync bool fNeedNormalization;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertRCReturn(rc, rc);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Only add one if it does not already exist.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (rc == VERR_NOT_FOUND)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->StrCore.cchString = cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->StrCore.pszString = pEntry->szName;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry->Attributes = NULL;
8f827447008ecf94b4c101b6ac2b795b760d802dvboxsync pEntry->cAttributes = 0;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync memcpy(pEntry->szName, pszEntry, cchEntry + 1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (fNeedNormalization)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestNormalizeEntry(pEntry->szName);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
956230513f1e35e9d694c219c7009034b71bb836vboxsync {
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->cEntries++;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = VINF_SUCCESS;
956230513f1e35e9d694c219c7009034b71bb836vboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMemFree(pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = VERR_INTERNAL_ERROR_4;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = VERR_NO_MEMORY;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else if (RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = VWRN_ALREADY_EXISTS;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/**
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Removes an entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryRemove(RTMANIFEST hManifest, const char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = hManifest;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertPtr(pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync bool fNeedNormalization;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync size_t cchEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertRCReturn(rc, rc);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /*
35d0bfb0c568c691325cade7618555e3d3df918avboxsync * Look it up before removing it.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_SUCCESS(rc))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync {
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(&pThis->Entries, pEntry->StrCore.pszString);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pStrCore, VERR_INTERNAL_ERROR_3);
956230513f1e35e9d694c219c7009034b71bb836vboxsync pThis->cEntries--;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rtManifestDestroyEntry(pStrCore, pThis);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync }
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
35d0bfb0c568c691325cade7618555e3d3df918avboxsyncRTDECL(bool) RTManifestEntryExists(RTMANIFEST hManifest, const char *pszEntry)
35d0bfb0c568c691325cade7618555e3d3df918avboxsync{
35d0bfb0c568c691325cade7618555e3d3df918avboxsync RTMANIFESTINT *pThis = hManifest;
35d0bfb0c568c691325cade7618555e3d3df918avboxsync AssertPtrReturn(pThis, false);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, false);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync AssertPtr(pszEntry);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync
35d0bfb0c568c691325cade7618555e3d3df918avboxsync bool fNeedNormalization;
35d0bfb0c568c691325cade7618555e3d3df918avboxsync size_t cchEntry;
35d0bfb0c568c691325cade7618555e3d3df918avboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync AssertRCReturn(rc, false);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync
35d0bfb0c568c691325cade7618555e3d3df918avboxsync /*
35d0bfb0c568c691325cade7618555e3d3df918avboxsync * Check if it exists.
35d0bfb0c568c691325cade7618555e3d3df918avboxsync */
35d0bfb0c568c691325cade7618555e3d3df918avboxsync PRTMANIFESTENTRY pEntry;
35d0bfb0c568c691325cade7618555e3d3df918avboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync return RT_SUCCESS_NP(rc);
35d0bfb0c568c691325cade7618555e3d3df918avboxsync}
35d0bfb0c568c691325cade7618555e3d3df918avboxsync
35d0bfb0c568c691325cade7618555e3d3df918avboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync/**
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Reads a line from a VFS I/O stream.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync *
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * @todo Replace this with a buffered I/O stream layer.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync *
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * @returns IPRT status code. VERR_EOF when trying to read beyond the stream
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * end.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * @param hVfsIos The I/O stream to read from.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * @param pszLine Where to store what we've read.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * @param cbLine The number of bytes to read.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsyncstatic int rtManifestReadLine(RTVFSIOSTREAM hVfsIos, char *pszLine, size_t cbLine)
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync{
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync /* This is horribly slow right now, but it's not a biggy as the input is
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync usually cached in memory somewhere... */
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync *pszLine = '\0';
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync while (cbLine > 1)
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync char ch;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync int rc = RTVfsIoStrmRead(hVfsIos, &ch, 1, true /*fBLocking*/, NULL);
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return rc;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /* \r\n */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (ch == '\r')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (cbLine <= 2)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[0] = ch;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[1] = '\0';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VINF_BUFFER_OVERFLOW;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync rc = RTVfsIoStrmRead(hVfsIos, &ch, 1, true /*fBLocking*/, NULL);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (RT_SUCCESS(rc) && ch == '\n')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VINF_SUCCESS;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[0] = '\r';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[1] = ch;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[2] = '\0';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (RT_FAILURE(rc))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return rc == VERR_EOF ? VINF_EOF : rc;
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /* \n */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (ch == '\n')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VINF_SUCCESS;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /* add character. */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[0] = ch;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine[1] = '\0';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /* advance */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszLine++;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync cbLine--;
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VINF_BUFFER_OVERFLOW;
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync}
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsyncRTDECL(int) RTManifestReadStandardEx(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, char *pszErr, size_t cbErr)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync{
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync /*
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * Validate input.
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync AssertPtrNull(pszErr);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (pszErr && cbErr)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync *pszErr = '\0';
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTMANIFESTINT *pThis = hManifest;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync /*
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * Process the stream line by line.
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync uint32_t iLine = 0;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync for (;;)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Read a line from the input stream.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync iLine++;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync char szLine[RTPATH_MAX + RTSHA512_DIGEST_LEN + 32];
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync int rc = rtManifestReadLine(hVfsIos, szLine, sizeof(szLine));
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (RT_FAILURE(rc))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (rc == VERR_EOF)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VINF_SUCCESS;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Error reading line #u: %Rrc", iLine, rc);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return rc;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (rc != VINF_SUCCESS)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Line number %u is too long", iLine);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_OUT_OF_RANGE;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Strip it and skip if empty.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync char *psz = RTStrStrip(szLine);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (!*psz)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync continue;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Read the attribute name.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync const char * const pszAttr = psz;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync do
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync psz++;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync while (!RT_C_IS_BLANK(*psz) && *psz);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (*psz)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync *psz++ = '\0';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * The entry name is enclosed in parenthesis and followed by a '='.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync psz = RTStrStripL(psz);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (*psz != '(')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Expected '(' after %zu on line %u", psz - szLine, iLine);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_PARSE_ERROR;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync const char * const pszName = ++psz;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync while (*psz)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (*psz == ')')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync char *psz2 = RTStrStripL(psz + 1);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (*psz2 == '=')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync *psz = '\0';
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync psz = psz2;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync break;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync psz++;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (*psz != '=')
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Expected ')=' at %zu on line %u", psz - szLine, iLine);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_PARSE_ERROR;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * The value.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync psz = RTStrStrip(psz + 1);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync const char * const pszValue = psz;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (!*psz)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Expected value at %zu on line %u", psz - szLine, iLine);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_PARSE_ERROR;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Detect attribute type and sanity check the value.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync uint32_t fType = RTMANIFEST_ATTR_UNKNOWN;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync static const struct
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync const char *pszAttr;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync uint32_t fType;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync unsigned cBits;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync unsigned uBase;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync } s_aDecAttrs[] =
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync { "SIZE", RTMANIFEST_ATTR_SIZE, 64, 10}
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync };
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync for (unsigned i = 0; i < RT_ELEMENTS(s_aDecAttrs); i++)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (!strcmp(s_aDecAttrs[i].pszAttr, pszAttr))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync fType = s_aDecAttrs[i].fType;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync rc = RTStrToUInt64Full(pszValue, s_aDecAttrs[i].uBase, NULL);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (rc != VINF_SUCCESS)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Malformed value ('%s') at %zu on line %u: %Rrc", pszValue, psz - szLine, iLine, rc);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_PARSE_ERROR;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync break;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (fType == RTMANIFEST_ATTR_UNKNOWN)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync static const struct
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync const char *pszAttr;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync uint32_t fType;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync unsigned cchHex;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync } s_aHexAttrs[] =
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync { "MD5", RTMANIFEST_ATTR_MD5, RTMD5_DIGEST_LEN },
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync { "SHA1", RTMANIFEST_ATTR_SHA1, RTSHA1_DIGEST_LEN },
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync { "SHA256", RTMANIFEST_ATTR_SHA256, RTSHA256_DIGEST_LEN },
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync { "SHA512", RTMANIFEST_ATTR_SHA512, RTSHA512_DIGEST_LEN }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync };
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync for (unsigned i = 0; i < RT_ELEMENTS(s_aHexAttrs); i++)
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (!strcmp(s_aHexAttrs[i].pszAttr, pszAttr))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync fType = s_aHexAttrs[i].fType;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync for (unsigned off = 0; off < s_aHexAttrs[i].cchHex; off++)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (!RT_C_IS_XDIGIT(pszValue[off]))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "Expected hex digit at %zu on line %u (value '%s', pos %u)",
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszValue - szLine + off, iLine, pszValue, off);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return VERR_PARSE_ERROR;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync break;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync /*
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync * Finally, add it.
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync */
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync rc = RTManifestEntrySetAttr(hManifest, pszName, pszAttr, pszValue, fType);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync if (RT_FAILURE(rc))
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync {
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync RTStrPrintf(pszErr, cbErr, "RTManifestEntrySetAttr(,'%s','%s', '%s', %#x) failed on line %u: %Rrc",
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync pszName, pszAttr, pszValue, fType, iLine, rc);
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return rc;
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync }
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync}
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
a917e98de4393d1090e536fdbeb04c285f98c92evboxsync return RTManifestReadStandardEx(hManifest, hVfsIos, NULL, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync/**
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes RTMANIFESTATTR.}
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsyncstatic DECLCALLBACK(int) rtManifestWriteStdAttr(PRTSTRSPACECORE pStr, void *pvUser)
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync{
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTMANIFESTWRITESTDATTR *pArgs = (RTMANIFESTWRITESTDATTR *)pvUser;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync char szLine[RTPATH_MAX + RTSHA512_DIGEST_LEN + 32];
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync size_t cchLine = RTStrPrintf(szLine, sizeof(szLine), "%s (%s) = %s\n", pAttr->szName, pArgs->pszEntry, pAttr->pszValue);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync if (cchLine >= sizeof(szLine) - 1)
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync return VERR_BUFFER_OVERFLOW;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync return RTVfsIoStrmWrite(pArgs->hVfsIos, szLine, cchLine, true /*fBlocking*/, NULL);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync}
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync/**
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes RTMANIFESTENTRY.}
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync */
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsyncstatic DECLCALLBACK(int) rtManifestWriteStdEntry(PRTSTRSPACECORE pStr, void *pvUser)
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync{
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTMANIFESTWRITESTDATTR Args;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync Args.hVfsIos = (RTVFSIOSTREAM)pvUser;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync Args.pszEntry = pStr->pszString;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync return RTStrSpaceEnumerate(&pEntry->Attributes, rtManifestWriteStdAttr, &Args);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync}
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync{
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTMANIFESTINT *pThis = hManifest;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync RTMANIFESTWRITESTDATTR Args;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync Args.hVfsIos = hVfsIos;
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync Args.pszEntry = "main";
956230513f1e35e9d694c219c7009034b71bb836vboxsync int rc = RTStrSpaceEnumerate(&pThis->SelfEntry.Attributes, rtManifestWriteStdAttr, &Args);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync if (RT_SUCCESS(rc))
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync rc = RTStrSpaceEnumerate(&pThis->Entries, rtManifestWriteStdEntry, hVfsIos);
110a95f133a07d2c98a580d226abf8850bc2bd47vboxsync return rc;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync