From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- public/sdk/inc/propstm.hxx | 678 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 public/sdk/inc/propstm.hxx (limited to 'public/sdk/inc/propstm.hxx') diff --git a/public/sdk/inc/propstm.hxx b/public/sdk/inc/propstm.hxx new file mode 100644 index 000000000..e97ac516b --- /dev/null +++ b/public/sdk/inc/propstm.hxx @@ -0,0 +1,678 @@ +//+-------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1993 +// +// File: propstm.hxx +// +// Contents: property set definitions +// +// History: 15-Jul-94 brianb created +// 15-Aug-94 SethuR revised +// 22-Feb-96 MikeHill Added several new member functions. +// 29-Feb-96 MikeHill Removed include of propmac.hxx +// Moved 2 inlines to propstm.cxx +// 09-May-96 MikeHill Update _InitSection & _FixSummaryInformation +// prototypes. +// 22-May-96 MikeHill Update prototypes for new OSVersion parameter, +// and for callee-allocated property name buffers. +// 01-Jul-96 MikeHill - Modified to allow removal of Win32 SEH. +// - Added byte-swapping support. +// 08-Nov-96 MikeHill Restore NT4 export signatures. +// +// +// Notes: This implementation of property streams has no notion of +// sections in a property set. +// +//--------------------------------------------------------------------------- + +#ifndef _PROPSTM_HXX_ +#define _PROPSTM_HXX_ + +#include // CBaseStorageVariant declarations +#include // Appendix B Property set structure definitions + +#ifndef _MAC_NODOC +#include // For CP_WINUNICODE +#include +#endif + +#include +#include + +typedef enum _PROPOP +{ + PROPOP_IGNORE = 1, + PROPOP_DELETE = 2, + PROPOP_INSERT = 3, + PROPOP_MOVE = 4, + PROPOP_UPDATE = 5, +} PROPOP; + +typedef struct tagPROPERTY_INFORMATION // pinfo +{ + PROPID pid; + +#ifdef KERNEL + SERIALIZEDPROPERTYVALUE *pprop; // Only the Kernel serializes to temp buf +#endif + + ULONG cbprop; + PROPOP operation; + +} PROPERTY_INFORMATION; + +#define VT_DICTIONARY (VT_VECTOR | VT_ILLEGALMASKED) + + + +// Validate the endian flags. Either BIGENDIAN or LITTLEENDIAN, but not +// both, must be defined as 1. + +#if !defined(BIGENDIAN) && !defined(LITTLEENDIAN) +#define LITTLEENDIAN 1 +#endif + + + +//+------------------------------------------------------------------------- +// Class: CMappedStream +// +// Purpose: defines the interface for a mapped Stream. This enables us to +// have multiple implementations of the stream (one kernel mode +// and multiple user mode implementations) without virtual methods +// in kernel mode, and just one implementation for parsing the +// contents of the stream (CPropertySetStream) +//-------------------------------------------------------------------------- + + + +//+------------------------------------------------------------------------- +// Class: CMappedStream (user mode implementation) +// +// Note: Implemented in CNtMappedStream for native property sets +// Implemented in CDfMappedStream for DocFile property sets +//-------------------------------------------------------------------------- + +class CMappedStream +{ +public: + virtual VOID Open(IN NTPROP np, OUT LONG *phr) = 0; + virtual VOID Close(OUT LONG *phr) = 0; + virtual VOID ReOpen(IN OUT VOID **ppv, OUT LONG *phr) = 0; + virtual VOID Quiesce(VOID) = 0; + virtual VOID Map(IN BOOLEAN fCreate, OUT VOID **ppv) = 0; + virtual VOID Unmap(IN BOOLEAN fFlush, IN OUT VOID **ppv) = 0; + virtual VOID Flush(OUT LONG *phr) = 0; + + virtual ULONG GetSize(OUT LONG *phr) = 0; + virtual VOID SetSize(IN ULONG cb, IN BOOLEAN fPersistent, IN OUT VOID **ppv, OUT LONG *phr) = 0; + virtual NTSTATUS Lock(IN BOOLEAN fExclusive) = 0; + virtual NTSTATUS Unlock(VOID) = 0; + virtual VOID QueryTimeStamps(OUT STATPROPSETSTG *pspss, BOOLEAN fNonSimple) const = 0; + virtual BOOLEAN QueryModifyTime(OUT LONGLONG *pll) const = 0; + virtual BOOLEAN QuerySecurity(OUT ULONG *pul) const = 0; + + virtual BOOLEAN IsWriteable(VOID) const = 0; + virtual BOOLEAN IsModified(VOID) const = 0; + virtual VOID SetModified(VOID) = 0; + virtual HANDLE GetHandle(VOID) const = 0; +#if DBGPROP + virtual BOOLEAN SetChangePending(BOOLEAN fChangePending) = 0; + virtual BOOLEAN IsNtMappedStream(VOID) const = 0; +#endif +}; + + +//+------------------------------------------------------------------------- +// Class: CStreamChunkList +// +// Purpose: Used to support efficient in-place compaction/expansion of +// property set streams for CPropertySetStorage. +//-------------------------------------------------------------------------- + +struct CStreamChunk // scnk +{ + ULONG oOld; + LONG cbChange; +}; + +class CStreamChunkList // scl +{ +public: + CStreamChunkList(ULONG cMaxChunks, CStreamChunk *ascnk); + + CStreamChunk *GetFreeChunk(OUT NTSTATUS *pstatus); + CStreamChunk const *GetChunk(ULONG i) const; + ULONG Count(VOID) const; + VOID SortByStartAddress(VOID); + VOID Delete(VOID); + +#if DBGPROP + VOID AssertCbChangeTotal( + CStreamChunk const *pscnk, + ULONG cbChangeTotal) const; +#endif + +private: + ULONG _cMaxChunks; // elements in _ascnk + ULONG _cChunks; // elements allocated from _ascnk + CStreamChunk *_ascnk; + BOOLEAN _fDelete; // TRUE if _ascnk allocated from heap +}; + + +//+------------------------------------------------------------------------- +// Class: CPropertySetStream +// +// Purpose: class for parsing the contents of a property set stream. +//-------------------------------------------------------------------------- + +#ifdef KERNEL +#define _MSTM(fn) _mstm.fn +#else +#define _MSTM(fn) _pmstm->fn +#endif + +#ifdef KERNEL +#define CPSS_PROPHEADER 0x01 // has property header +#endif + +#define CPSS_DOWNLEVEL 0x02 // Downlevel property set. +#define CPSS_PACKEDPROPERTIES 0x04 // Packed property values +#define CPSS_DOCUMENTSUMMARYINFO 0x08 // DocumentSummaryInfo propset +#define CPSS_USERDEFINEDPROPERTIES 0x10 // DocumentSummaryInfo: second section +#define CPSS_MULTIPLESECTIONS 0x20 // Multiple property sections +#define CPSS_USERDEFINEDDELETED 0x40 // second section deleted +#define CPSS_VARIANTVECTOR 0x80 // Only for recursion + + +typedef enum tagLOADSTATE +{ + LOADSTATE_FAIL = 0, // load failed + LOADSTATE_DONE = 1, // load succeeded + LOADSTATE_BADFMTID = 2, // fmtid mismatch + LOADSTATE_USERDEFINEDNOTFOUND = 3, // user defined section missing + LOADSTATE_USERDEFINEDDELETE = 4, // delete user defined section +} LOADSTATE; + + +typedef enum tagPATCHOP +{ + PATCHOP_COMPUTESIZE = 0, // just compute expanded size + PATCHOP_ALIGNLENGTHS = 1, // just align string lengths + PATCHOP_EXPAND = 2, // expand property in-place +} PATCHOP; + + +// Create a macro that tells us the type +// of OLECHARs. + +#ifdef OLE2ANSI +#define OLECHAR_IS_UNICODE FALSE +#else +#define OLECHAR_IS_UNICODE TRUE +#endif + +// IsOLECHARString calls IsUnicodeString or IsAnsiString, +// whichever is appropriate for this compilation. + +#if DBGPROP + inline BOOLEAN IsOLECHARString( OLECHAR const *posz, ULONG cb ) + { + #if OLECHAR_IS_UNICODE + return( IsUnicodeString( posz, cb )); + #else + return( IsAnsiString( posz, cb )); + #endif + } +#endif + + +class CPropertySetStream +{ +public: + CPropertySetStream( + IN USHORT Flags, // NONSIMPLE|*1* of READ/WRITE/CREATE/CREATEIF/DELETE + IN CMappedStream *pmstm, // mapped stream implementation + IN PMemoryAllocator *pma // caller's memory allocator + ); + + + VOID Close(OUT NTSTATUS *pstatus); + VOID SetValue( + IN ULONG cprop, + OPTIONAL IN OUT INDIRECTPROPERTY **ppip, + IN PROPVARIANT const avar[], + IN PROPERTY_INFORMATION *ppinfo, + OUT NTSTATUS *pstatus); + + SERIALIZEDPROPERTYVALUE const *GetValue(IN PROPID pid, OUT ULONG *pcbprop, + OUT NTSTATUS *pstatus); + + PROPID QueryPropid(IN OLECHAR const *poszName, OUT NTSTATUS *pstatus); + USHORT GetCodePage(VOID) const { return(_CodePage); } + +#if DBGPROP + VOID Validate(OUT NTSTATUS *pstatus); +#else + VOID Validate(OUT NTSTATUS *pstatus) const { *pstatus = STATUS_SUCCESS; } +#endif + + BOOLEAN IsModified(VOID) const { return(_MSTM(IsModified)()); } + NTSTATUS Lock(IN BOOLEAN fExclusive) { return(_MSTM(Lock)(fExclusive)); } + NTSTATUS Unlock(VOID) { return(_MSTM(Unlock)()); } + VOID Flush(OUT NTSTATUS *pstatus) + { + PROPASSERT(PROPSET_BYTEORDER == _pph->wByteOrder); + _MSTM(Flush)(pstatus); + PROPASSERT(PROPSET_BYTEORDER == _pph->wByteOrder); + } + + + VOID Open( + OPTIONAL IN GUID const *pfmtid, // property set fmtid (create or Word95) + OPTIONAL IN GUID const *pclsid, // CLASSID of propset code (create only) + IN ULONG LocaleId, // Locale Id (create only) + OPTIONAL OUT ULONG *pOSVersion, // OS Version field in the propset header + IN USHORT CodePage, // CodePage of propset (create only) + OUT NTSTATUS *pstatus); // Return code. + ULONG ReOpen(OUT NTSTATUS *pstatus); + + // Property Dictionary Lookup and Manipulation. + BOOLEAN EnumeratePropids( + IN OUT ULONG *pkey, + IN OUT ULONG *pcprop, + OUT PROPID *apid, + OUT NTSTATUS *pstatus); + + OLECHAR *DuplicatePropertyName( + IN OLECHAR const *poszName, + IN ULONG cbName, + OUT NTSTATUS *pstatus) const; + + BOOLEAN QueryPropertyNameBuf( + IN PROPID pid, + OUT OLECHAR *aocName, + IN OUT ULONG *pcbName, + OUT NTSTATUS *pstatus); + + BOOLEAN QueryPropertyNames( + IN ULONG cprop, + IN PROPID const *apid, + OUT OLECHAR *aposz[], + OUT NTSTATUS *pstatus); + + VOID SetPropertyNames( + IN ULONG cprop, + IN PROPID const *apid, + IN OPTIONAL OLECHAR const * const aposz[], + OUT NTSTATUS *pstatus); + + VOID QueryPropertySet(OUT STATPROPSETSTG *pspss, OUT NTSTATUS *pstatus) const; + VOID SetClassId(IN GUID const *pclsid, OUT NTSTATUS *pstatus); + HANDLE GetHandle(VOID) const { return(_MSTM(GetHandle)()); } + PMemoryAllocator *GetAllocator(VOID) const { return(_pma); } + + VOID ByteSwapHeaders( IN PROPERTYSETHEADER *psh, + IN ULONG cbstm, + OUT NTSTATUS *pstatus ); + + // Convert a character count to a byte count based on the _CodePage + + ULONG CCh2CB( ULONG cch ) const + { + return( _CodePage == CP_WINUNICODE + ? cch * sizeof( WCHAR ) + : cch * sizeof( CHAR ) + ); + } + + // Convert a byte count to a character count based on the _CodePage + // If for some reason the given byte-count is odd, the return + // value won't include that last half-character. + + ULONG CB2CCh( ULONG cb ) const + { + return( _CodePage == CP_WINUNICODE + ? cb / sizeof( WCHAR ) + : cb / sizeof( CHAR ) + ); + } + + +private: + + // Private methods. + + VOID _Create( + IN GUID const *pfmtid, + OPTIONAL IN GUID const *pclsid, + IN ULONG LocaleId, + IN USHORT CodePage, + IN LOADSTATE LoadState, + OUT NTSTATUS *pstatus); + BOOLEAN _HasPropHeader(VOID) const { return(TRUE); } + BOOLEAN _CreateUserDefinedSection( + IN LOADSTATE LoadState, + IN ULONG LocaleId, + OUT NTSTATUS *pstatus); + VOID _InitSection( + IN FORMATIDOFFSET *pfo, + IN ULONG LocaleId, + IN BOOL fCreateDictionary ); + VOID _FixSummaryInformation(IN OUT ULONG *pcbstm, OUT NTSTATUS *pstatus); + VOID _FixPackedPropertySet(OUT NTSTATUS *pstatus); + + BOOLEAN _FixDocPartsVector( + IN PATCHOP PatchOp, + IN OUT SERIALIZEDPROPERTYVALUE *pprop, + OUT ULONG *pcbprop); + BOOLEAN _FixDocPartsElements( + IN PATCHOP PatchOp, + IN ULONG cString, + OUT VOID *pvDst, + IN VOID UNALIGNED const *pvSrc, + OUT ULONG *pcbprop); + + BOOLEAN _FixHeadingPairVector( + IN PATCHOP PatchOp, + IN OUT SERIALIZEDPROPERTYVALUE *pprop, + OUT ULONG *pcbprop); + BOOLEAN _FixHeadingPairElements( + IN PATCHOP PatchOp, + IN ULONG cPairs, + OUT SERIALIZEDPROPERTYVALUE *ppropDst, + IN SERIALIZEDPROPERTYVALUE UNALIGNED const *ppropSrc, + OUT ULONG *pcbprop); + + BOOLEAN _IsMapped(VOID) const { return(_pph != NULL); } + LOADSTATE _LoadHeader(OPTIONAL IN GUID const *pfmtid, IN BYTE Mode, + OUT NTSTATUS *pstatus); + + PROPERTYSECTIONHEADER *_LoadPropertyOffsetPointers( + OUT PROPERTYIDOFFSET **pppo, + OUT PROPERTYIDOFFSET **pppoMax, + OUT NTSTATUS *pstatus); + + SERIALIZEDPROPERTYVALUE *_LoadProperty(IN PROPID pid, OUT ULONG *pcbprop, + OUT NTSTATUS *pstatus); + PROPERTYSECTIONHEADER *_GetSectionHeader(VOID) const; + VOID _SearchForCodePage( OUT NTSTATUS *pstatus); + PROPERTYSECTIONHEADER *_GetSectionHeader(IN ULONG iSection, OUT NTSTATUS *pstatus); + FORMATIDOFFSET *_GetFormatidOffset(IN ULONG iSection) const; + + VOID *_MapOffsetToAddress(IN ULONG oOffset) const; + ULONG _MapAddressToOffset(IN VOID const *pvAddr) const; + + VOID *_MapAbsOffsetToAddress(IN ULONG oAbsolute) const; + ULONG _MapAddressToAbsOffset(IN VOID const *pvAddr) const; + + ULONG _GetNewOffset( + IN CStreamChunkList const *pscl, + IN ULONG oOld) const; + + ULONG _DictionaryEntryLength( + IN ENTRY UNALIGNED const * pent ) const; + + + ULONG _DictionaryLength( + IN DICTIONARY const *pdy, + IN ULONG cbbuf, + OUT NTSTATUS *pstatus) const; + + ENTRY UNALIGNED + *_NextDictionaryEntry( + IN ENTRY UNALIGNED const * pent ) const; + + ULONG _CountFreePropertyOffsets(OUT NTSTATUS *pstatus); + + VOID _DeleteMovePropertyOffsets( + IN PROPERTY_INFORMATION const *apinfo, + IN ULONG cprop, + OUT NTSTATUS *pstatus); + + VOID _UpdatePropertyOffsets( + IN CStreamChunkList const *pscl, + OUT NTSTATUS *pstatus); + + VOID _InsertMovePropertyOffsets( + IN PROPERTY_INFORMATION const *apinfo, + IN ULONG cprop, + IN ULONG oInsert, + IN ULONG cpoReserve, + OUT NTSTATUS *pstatus); + + VOID _CompactStream(IN CStreamChunkList const *pscl); + + VOID _CompactChunk( + IN CStreamChunk const *pscnk, + IN LONG cbChangeTotal, + IN ULONG oOldNext); + + VOID _PatchSectionOffsets(LONG cbChange); + + ULONG _ComputeMinimumSize(ULONG cbstm, OUT NTSTATUS *pstatus); +#if DBGPROP + VOID _ValidateStructure(OUT NTSTATUS *pstatus); + VOID _ValidateProperties(OUT NTSTATUS *pstatus) const; + VOID _ValidateDictionary(OUT NTSTATUS *pstatus); + VOID _StatusCorruption(char *szReason, OUT NTSTATUS *pstatus) const; +#else + VOID _StatusCorruption(OUT NTSTATUS *pstatus) const; +#endif + VOID _SetModified(VOID) { _MSTM(SetModified)(); } + +#if DBGPROP +public: // public for fnEntryNameCompare only! +#endif + BOOLEAN _ComparePropertyNames( + IN VOID const *pvName1, + IN VOID const *pvName2, + IN BOOL fSameByteOrder, + IN ULONG cbName) const; +#if DBGPROP +private: +#endif + + BOOLEAN _PropertyNameLength( + IN VOID const *pvName, + OUT ULONG *pcbName) const; + + + VOID _MultiByteToWideChar( + IN CHAR const *pch, + IN ULONG cb, + IN USHORT CodePage, + OUT WCHAR **ppwc, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus); + + VOID _OLECHARToWideChar( + IN OLECHAR const *poc, + IN ULONG cb, + IN USHORT CodePage, + OUT WCHAR **ppwc, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus) + { + PROPASSERT( sizeof(OLECHAR) == sizeof(CHAR) ); + + // Since OLECHAR may be MultiByte or WideChar for this + // compilation, explicitely cast 'poc' to a CHAR* to prevent + // a compilation error. + + _MultiByteToWideChar( (CHAR*) poc, cb, CodePage, ppwc, pcb, pstatus ); + } + + VOID _MultiByteToOLECHAR( + IN CHAR const *pch, + IN ULONG cb, + IN USHORT CodePage, + OUT OLECHAR **ppoc, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus) + { + PROPASSERT( sizeof(OLECHAR) == sizeof(WCHAR) ); + + // Since OLECHAR may be MultiByte or WideChar for this + // compilation, explicitely cast 'ppoc' to a WCHAR** to prevent + // a compilation error. + + _MultiByteToWideChar( pch, cb, CodePage, (WCHAR**)ppoc, pcb, pstatus ); + } + + VOID _WideCharToMultiByte( + IN WCHAR const *pwc, + IN ULONG cch, + IN USHORT CodePage, + OUT CHAR **ppch, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus); + + VOID _OLECHARToMultiByte( + IN OLECHAR const *poc, + IN ULONG cch, + IN USHORT CodePage, + OUT CHAR **ppch, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus) + { + PROPASSERT( sizeof(OLECHAR) == sizeof(WCHAR) ); + + // Since OLECHAR may be MultiByte or WideChar for this + // compilation, explicitely cast 'poc' to a WCHAR* to prevent + // a compilation error. + + _WideCharToMultiByte( (WCHAR*) poc, cch, CodePage, ppch, pcb, pstatus ); + } + + VOID _WideCharToOLECHAR( + IN WCHAR const *pwc, + IN ULONG cch, + IN USHORT CodePage, + OUT OLECHAR **ppoc, + OUT ULONG *pcb, + OUT NTSTATUS *pstatus) + { + PROPASSERT( sizeof(OLECHAR) == sizeof(CHAR) ); + + // Since OLECHAR may be MultiByte or WideChar for this + // compilation, explicitely cast 'ppoc' to a CHAR** to prevent + // a compilation error. + + _WideCharToMultiByte( pwc, cch, CodePage, (CHAR**) ppoc, pcb, pstatus ); + } + + + PROPERTYSETHEADER *_pph; + ULONG _oSection; + ULONG _cSection; + USHORT _CodePage; + BYTE _Flags; + BYTE _State; + ULONG _cbTail; + PMemoryAllocator *_pma; + CMappedStream *_pmstm; // user mode: replacable virtual class +}; + + +#ifdef WINNT +VOID CopyPropertyValue( + IN OPTIONAL SERIALIZEDPROPERTYVALUE const *pprop, + IN ULONG cb, + OUT SERIALIZEDPROPERTYVALUE *ppropDst, + OUT ULONG *pcb); + +ULONG PropertyLengthAsVariant( + IN SERIALIZEDPROPERTYVALUE const *pprop, + IN ULONG cbprop, + IN USHORT CodePage, + IN BYTE flags); + +ULONG PropertyLengthAsVariantNoEH( // No NT Exception Handling version + IN SERIALIZEDPROPERTYVALUE const *pprop, + IN ULONG cbprop, + IN USHORT CodePage, + IN BYTE flags, + OUT NTSTATUS *pstatus); + +#endif + +ULONG PropertyLength( + IN SERIALIZEDPROPERTYVALUE const *pprop, + IN ULONG cbbuf, + IN BYTE flags); + +ULONG PropertyLengthNoEH( // No NT Exception Handling version + IN SERIALIZEDPROPERTYVALUE const *pprop, + IN ULONG cbbuf, + IN BYTE flags, + OUT NTSTATUS *pstatus); + + + +// ------------ +// PBS Routines +// ------------ + +// PBS routines (Property Byte Swap) perform specialized byte-swapping +// in the big-endian build, and do nothing in the little-endian +// build (in which case they are inlined). + +#ifdef BIGENDIAN + +VOID PBSCopy( OUT VOID *pvDest, + IN VOID const *pvSource, + IN ULONG cbCopy, + IN LONG cbByteSwap ); + +VOID PBSAllocAndCopy( OUT VOID **ppvDest, + IN VOID const *pvSource, + ULONG cbSize, + LONG cbByteSwap, + OUT NTSTATUS *pstatus); + +VOID PBSInPlaceAlloc( IN OUT WCHAR** ppwszResult, + OUT WCHAR** ppwszBuffer, + OUT NTSTATUS *pstatus ); + +VOID PBSBuffer( IN OUT VOID *pv, + IN ULONG cbSize, + IN ULONG cbByteSwap ); + +#else // Little-endian build + +inline VOID PBSCopy( OUT VOID *pvDest, + IN VOID const *pvSource, + IN ULONG cbCopy, + IN LONG cbByteSwap ) +{ +} + +inline VOID PBSAllocAndCopy( OUT VOID **ppvDest, + IN VOID const *pvSource, + ULONG cbSize, + LONG cbByteSwap, + OUT NTSTATUS *pstatus) +{ + *pstatus = STATUS_SUCCESS; +} + +inline VOID PBSInPlaceAlloc( IN OUT WCHAR** ppwszResult, + OUT WCHAR** ppwszBuffer, + OUT NTSTATUS *pstatus ) +{ + *pstatus = STATUS_SUCCESS; +} + +inline VOID PBSBuffer( IN OUT VOID *pv, + IN ULONG cbSize, + IN ULONG cbByteSwap ) +{ +} + +#endif // #ifdef BIGENDIAN ... #else + + +#endif // _PROPSTM_HXX_ -- cgit v1.2.3