/*+--------------------------------------------------------------------------*/ /* */ /* Microsoft Windows */ /* Copyright (C) Microsoft Corporation, 1993 */ /* */ /* File: propvar.h */ /* */ /* Contents: PROPVARIANT manipulation code */ /* */ /*---------------------------------------------------------------------------*/ #ifndef _PROPVAR_HXX_ #define _PROPVAR_HXX_ #include "propset.hxx" // forward declarations class PMemoryAllocator; SERIALIZEDPROPERTYVALUE * RtlConvertVariantToProperty( IN PROPVARIANT const *pvar, IN USHORT CodePage, OUT SERIALIZEDPROPERTYVALUE *pprop, IN OUT ULONG *pcb, IN PROPID pid, IN BOOLEAN fVariantVector, OUT NTSTATUS *pstatus); VOID RtlConvertPropertyToVariant( IN SERIALIZEDPROPERTYVALUE const *pprop, IN USHORT CodePage, OUT PROPVARIANT *pvar, IN PMemoryAllocator *pma, OUT NTSTATUS *pstatus); VOID CleanupVariants( IN PROPVARIANT *pvar, IN ULONG cprop, IN PMemoryAllocator *pma); /*+-------------------------------------------------------------------------- Function: SignalOverflow, SignalInvalidParameter, SignalStatus Synopsis: ASSERT and raise data corrupt/overflow/specified error Arguments: [szReason] -- string explanation [Status] -- Status to raise (SignalStatus only) Returns: None +--------------------------------------------------------------------------*/ #define StatusOverflow(pstatus, szReason) \ *(pstatus) = STATUS_BUFFER_OVERFLOW; \ TraceStatus(szReason) #define StatusAccessDenied(pstatus, szReason) \ *(pstatus) = STATUS_ACCESS_DENIED; \ TraceStatus(szReason); #define StatusInvalidParameter(pstatus, szReason) \ *(pstatus) = STATUS_INVALID_PARAMETER; \ TraceStatus(szReason); #define StatusNoMemory(pstatus, szReason) \ *(pstatus) = STATUS_INSUFFICIENT_RESOURCES;\ TraceStatus(szReason); #define StatusDiskFull(pstatus, szReason) \ *(pstatus) = STATUS_DISK_FULL; \ TraceStatus(szReason); #define StatusError(pstatus, szReason, Status) \ *(pstatus) = Status; \ TraceStatus(szReason); #define StatusKBufferOverflow(pstatus, szReason) StatusNoMemory(pstatus, szReason) #define KERNELSELECT(k, u) u #define DBGPROPASSERT KERNELSELECT(DBGPROP, DBG) #if DBGPROPASSERT #define TraceStatus(szReason) \ { \ DebugTrace(0, DEBTRACE_ERROR, (szReason "\n")); \ PROPASSERTMSG(szReason, !(DebugLevel & DEBTRACE_WARN)); \ } #else #define TraceStatus(szReason) #endif #define AssertVarField(field, cb) \ PROPASSERT(FIELD_OFFSET(PROPVARIANT, iVal) == FIELD_OFFSET(PROPVARIANT, field) && \ sizeof(((PROPVARIANT *) 0)->field) == (cb)) #define AssertVarVector(field, cbElem) \ PROPASSERT(FIELD_OFFSET(PROPVARIANT, cai.cElems) == \ FIELD_OFFSET(PROPVARIANT, field.cElems) && \ FIELD_OFFSET(PROPVARIANT, cai.pElems) == \ FIELD_OFFSET(PROPVARIANT, field.pElems) && \ sizeof(((PROPVARIANT *) 0)->field.pElems[0]) == (cbElem)) #define AssertByteField(field) AssertVarField(field, sizeof(BYTE)) #define AssertShortField(field) AssertVarField(field, sizeof(SHORT)) #define AssertLongField(field) AssertVarField(field, sizeof(LONG)) #define AssertLongLongField(field) AssertVarField(field, sizeof(LONGLONG)) #define AssertStringField(field) AssertVarField(field, sizeof(VOID *)) #define AssertByteVector(field) AssertVarVector(field, sizeof(BYTE)) #define AssertShortVector(field) AssertVarVector(field, sizeof(SHORT)) #define AssertLongVector(field) AssertVarVector(field, sizeof(LONG)) #define AssertLongLongVector(field) AssertVarVector(field, sizeof(LONGLONG)) #define AssertStringVector(field) AssertVarVector(field, sizeof(VOID *)) #define AssertVariantVector(field) AssertVarVector(field, sizeof(PROPVARIANT)) #define BSTRLEN(bstrVal) *((ULONG *) bstrVal - 1) /*+------------------------------------------------------------------- Class: CBufferAllocator, private Synopsis: allocation from a buffer Notes: The Summary catalog APIs use a single buffer to serialize row values on input and deserialize them on output. This class encapsulates the memory allocation routines for these APIs. -----------------------------------------------------------------------*/ class CBufferAllocator : public PMemoryAllocator { public: inline CBufferAllocator(ULONG cbBuffer, VOID *pvBuffer) { _cbFree = cbBuffer; _pvCur = _pvBuffer = pvBuffer; #if _X86_ /* stack variables on x86 are not aligned*/ PROPASSERT(((ULONG) _pvCur & (sizeof(LONG) - 1)) == 0); #else /* RISC*/ PROPASSERT(((ULONG) _pvCur & (sizeof(LONGLONG) - 1)) == 0); #endif /* X86/RISC*/ } VOID *Allocate(ULONG cbSize); VOID Free(VOID *pv) { } inline ULONG GetFreeSize(VOID) { return(_cbFree); } private: ULONG _cbFree; VOID *_pvCur; VOID *_pvBuffer; }; /*+------------------------------------------------------------------- Member: CBufferAllocator::Allocate, private Synopsis: allocation from a buffer Arguments: [cb] -- Count of bytes to be allocated. Returns: pointer to 'allocated' memory -- NULL if no space left ----------------------------------------------------------------------*/ #define DEFINE_CBufferAllocator__Allocate \ VOID * \ CBufferAllocator::Allocate(ULONG cb) \ { \ VOID *pv; \ \ cb = (cb + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1); \ if (cb > _cbFree) \ { \ return(NULL); \ } \ pv = _pvCur; \ _pvCur = (BYTE *) _pvCur + cb; \ _cbFree -= cb; \ return(pv); \ } #endif /* #ifndef _PROPVAR_HXX_ */