windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/inc/pbagstm.h

350 lines
8.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
pbagstm.h
Abstract:
This module contains the definition of the property bag stream
Author:
Keith Lau (keithlau@microsoft.com)
Revision History:
keithlau 07/09/97 created
--*/
#ifndef _PBAGSTM_H_
#define _PBAGSTM_H_
#include "cpool.h"
#define MAX_PROPERTY_NAME_LENGTH 256
typedef struct _TABLE_ENTRY
{
DWORD dwOffset;
DWORD dwSize;
DWORD dwNameSize;
DWORD dwMaxSize;
DWORD dwKey;
WORD fFlags;
WORD wIndex;
} TABLE_ENTRY, *LPTABLE_ENTRY;
typedef struct _STREAM_HEADER
{
DWORD dwSignature;
WORD wVersionHigh;
WORD wVersionLow;
DWORD dwHeaderSize;
DWORD dwProperties;
DWORD dwDirectorySize;
DWORD dwEndOfData;
} STREAM_HEADER, *LPSTREAM_HEADER;
#define _CACHE_SIZE 64
typedef enum _PROPERTY_BAG_CREATORS
{
PBC_NONE = 0,
PBC_BUILDQ,
PBC_DIRNOT,
PBC_ENV,
PBC_LOCALQ,
PBC_MAILQ,
PBC_REMOTEQ,
PBC_RRETRYQ,
PBC_SMTPCLI
} PROPERTY_BAG_CREATORS;
typedef enum _PROPERTY_FLAG_OPERATIONS
{
PFO_NONE = 0,
PFO_OR,
PFO_ANDNOT
} PROPERTY_FLAG_OPERATIONS;
/////////////////////////////////////////////////////////////////////////////
// CPropertyBagStream
//
class CPropertyBagStream
{
public:
CPropertyBagStream(DWORD dwContext = 0);
~CPropertyBagStream();
static CPool Pool;
// override the mem functions to use CPool functions
void *operator new (size_t cSize)
{ return Pool.Alloc(); }
void operator delete (void *pInstance)
{ Pool.Free(pInstance); }
// Reference count methods ...
ULONG AddRef();
ULONG Release(BOOL fDeleteIfZeroRef = FALSE);
HRESULT SetStreamFileName(LPSTR szStreamFileName);
LPSTR GetStreamFileName() { return(m_szStreamName); }
// Mechanisms for locking and unlocking the property bag
HRESULT Lock();
HRESULT Unlock();
// Force opens the stream file if it is not already opened.
// This is useful in checking if a stream file exists.
HRESULT OpenStreamFile();
// Access to properties as a whole
HRESULT GetProperty(LPSTR pszName,
LPVOID pvBuffer,
LPDWORD pdwBufferLen);
HRESULT SetProperty(LPSTR pszName,
LPVOID pvBuffer,
DWORD dwBufferLen);
// Access to properties, providing specific access to
// portions of the property data relative to the start
// of the property data
HRESULT GetPropertyAt(LPSTR pszName,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
LPDWORD pdwBufferLen);
HRESULT SetPropertyAt(LPSTR pszName,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
DWORD dwBufferLen);
// Ad-hoc function to allow access to a specific DWORD of
// a property, treating the DWORD as a set of flags. The
// dwOperation argument specifies what kind of binary operation
// we would like to have performed on the original value.
// If the property does not originally exist, this function
// will fail.
HRESULT UpdatePropertyFlagsAt(LPSTR pszName,
DWORD dwOffsetFromStart,
DWORD dwFlags,
DWORD dwOperation);
#ifdef USE_PROPERTY_ITEM_ISTREAM
// Returns an IStream interface to the desired property
// for random access
HRESULT GetIStreamToProperty(LPSTR pszName,
IStream **ppIStream);
#endif
BOOL DeleteStream();
private:
BOOL ReleaseStream();
HRESULT Seek(DWORD dwOffset, DWORD dwMethod);
HRESULT LoadIntoCache(DWORD dwStartIndex);
LPTABLE_ENTRY FindFromCache(DWORD dwKey,
LPDWORD pdwStartIndex);
HRESULT FindFrom(LPSTR pszName,
DWORD dwKey,
DWORD dwStartIndex,
BOOL fForward,
LPVOID pvBuffer,
LPDWORD pdwBufferLen,
LPTABLE_ENTRY *ppEntry);
HRESULT FindFromEx(LPSTR pszName,
DWORD dwKey,
DWORD dwStartIndex,
BOOL fForward,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
LPDWORD pdwBufferLen,
LPTABLE_ENTRY *ppEntry);
HRESULT GetRecordData(LPTABLE_ENTRY pEntry,
LPVOID pvBuffer);
HRESULT GetRecordName(LPTABLE_ENTRY pEntry,
LPVOID pvBuffer);
HRESULT GetRecordValue(LPTABLE_ENTRY pEntry,
LPVOID pvBuffer);
HRESULT GetRecordValueAt(LPTABLE_ENTRY pEntry,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
DWORD dwBufferLen);
HRESULT UpdateEntry(LPTABLE_ENTRY pEntry);
HRESULT UpdateHeader();
HRESULT UpdateHeaderUsingHandle(HANDLE hStream);
HRESULT FindProperty(LPSTR pszName,
LPVOID pvBuffer,
LPDWORD pdwBufferLen,
LPTABLE_ENTRY *ppEntry = NULL);
HRESULT FindPropertyEx(LPSTR pszName,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
LPDWORD pdwBufferLen,
LPTABLE_ENTRY *ppEntry = NULL);
HRESULT SetRecordData(LPTABLE_ENTRY pEntry,
LPSTR pszName,
LPVOID pvBuffer,
DWORD dwBufferLen);
HRESULT SetRecordDataAt(LPTABLE_ENTRY pEntry,
LPSTR pszName,
DWORD dwOffsetFromStart,
LPVOID pvBuffer,
DWORD dwBufferLen,
BOOL fNewRecord = FALSE);
HRESULT RelocateRecordData(LPTABLE_ENTRY pEntry);
HRESULT DetermineIfCacheValid(BOOL *pfCacheInvalid);
DWORD CreateKey(LPSTR pszName)
{
CHAR cKey[9];
DWORD dwLen = 0;
// Convert to lower case ...
while (*pszName && (dwLen < 8))
if ((*pszName >= 'A') && (*pszName <= 'Z'))
cKey[dwLen++] = *pszName++ - 'A' + 'a';
else
cKey[dwLen++] = *pszName++;
cKey[dwLen] = '\0';
dwLen = lstrlen(cKey);
// Create the key
if (dwLen < 4)
return((DWORD)cKey[dwLen - 1]);
else if (dwLen < 8)
return(*(DWORD *)cKey);
else
return(~*(DWORD *)cKey ^ *(DWORD *)(cKey + 4));
}
DWORD GetTotalHeaderSize()
{
return(sizeof(STREAM_HEADER) +
(m_Header.dwDirectorySize * sizeof(TABLE_ENTRY)));
}
// Current context
DWORD m_dwContext;
// Base file name
CHAR m_szStreamName[MAX_PATH + 1];
// Handle to stream
HANDLE m_hStream;
// Stream header
STREAM_HEADER m_Header;
// Directory caching
TABLE_ENTRY m_Cache[_CACHE_SIZE];
DWORD m_dwCacheStart;
DWORD m_dwCachedItems;
// Reference counting
LONG m_lRef;
// This is a signature placed at the end to catch memory overwrite
DWORD m_dwSignature;
};
/////////////////////////////////////////////////////////////////////////////
// CPropertyItemStream
//
//
// Not everyone wants to use the property IStream, so we don't expose
// it if it's not wanted
//
#ifdef USE_PROPERTY_ITEM_ISTREAM
class CPropertyItemStream : public IStream
{
public:
CPropertyItemStream(LPSTR pszName,
CPropertyBagStream *pBag)
{
m_cRef = 0;
m_pParentBag = pBeg;
m_szName = pszName;
m_libOffset.QuadPart = (DWORDLONG)0;
}
~CPropertyItemStream()
{
Cleanup();
}
// IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
void Cleanup() {}
HRESULT ReadOffset(void *pv, ULONG cb, ULONG *pcbRead, ULARGE_INTEGER *plibOffset);
HRESULT WriteOffset(void const* pv, ULONG cb, ULONG *pcbWritten, ULARGE_INTEGER *plibOffset);
HRESULT GetSize(ULARGE_INTEGER *plibSize);
HRESULT CopyToOffset(IStream *pstm, ULARGE_INTEGER libOffset, ULARGE_INTEGER *plibRead, ULARGE_INTEGER *plibWritten, ULARGE_INTEGER *plibOffset);
HRESULT CloneOffset(IStream **pstm, ULARGE_INTEGER libOffset);
// IStream
public:
HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead);
HRESULT STDMETHODCALLTYPE Write(void const* pv, ULONG cb, ULONG *pcbWritten);
HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *pdlibNewPosition);
HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize);
HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags);
HRESULT STDMETHODCALLTYPE Revert(void);
HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
HRESULT STDMETHODCALLTYPE Stat(STATSTG * pstatstg, DWORD grfStatFlag);
HRESULT STDMETHODCALLTYPE Clone(IStream **pstm);
private:
CPropertyBagStream *m_pParentBag;
LPSTR m_szName;
ULARGE_INTEGER m_libOffset;
long m_cRef;
};
#endif // USE_PROPERTY_ISTREAM
#endif