Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

349 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. pbagstm.h
  5. Abstract:
  6. This module contains the definition of the property bag stream
  7. Author:
  8. Keith Lau (keithlau@microsoft.com)
  9. Revision History:
  10. keithlau 07/09/97 created
  11. --*/
  12. #ifndef _PBAGSTM_H_
  13. #define _PBAGSTM_H_
  14. #include "cpool.h"
  15. #define MAX_PROPERTY_NAME_LENGTH 256
  16. typedef struct _TABLE_ENTRY
  17. {
  18. DWORD dwOffset;
  19. DWORD dwSize;
  20. DWORD dwNameSize;
  21. DWORD dwMaxSize;
  22. DWORD dwKey;
  23. WORD fFlags;
  24. WORD wIndex;
  25. } TABLE_ENTRY, *LPTABLE_ENTRY;
  26. typedef struct _STREAM_HEADER
  27. {
  28. DWORD dwSignature;
  29. WORD wVersionHigh;
  30. WORD wVersionLow;
  31. DWORD dwHeaderSize;
  32. DWORD dwProperties;
  33. DWORD dwDirectorySize;
  34. DWORD dwEndOfData;
  35. } STREAM_HEADER, *LPSTREAM_HEADER;
  36. #define _CACHE_SIZE 64
  37. typedef enum _PROPERTY_BAG_CREATORS
  38. {
  39. PBC_NONE = 0,
  40. PBC_BUILDQ,
  41. PBC_DIRNOT,
  42. PBC_ENV,
  43. PBC_LOCALQ,
  44. PBC_MAILQ,
  45. PBC_REMOTEQ,
  46. PBC_RRETRYQ,
  47. PBC_SMTPCLI
  48. } PROPERTY_BAG_CREATORS;
  49. typedef enum _PROPERTY_FLAG_OPERATIONS
  50. {
  51. PFO_NONE = 0,
  52. PFO_OR,
  53. PFO_ANDNOT
  54. } PROPERTY_FLAG_OPERATIONS;
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CPropertyBagStream
  57. //
  58. class CPropertyBagStream
  59. {
  60. public:
  61. CPropertyBagStream(DWORD dwContext = 0);
  62. ~CPropertyBagStream();
  63. static CPool Pool;
  64. // override the mem functions to use CPool functions
  65. void *operator new (size_t cSize)
  66. { return Pool.Alloc(); }
  67. void operator delete (void *pInstance)
  68. { Pool.Free(pInstance); }
  69. // Reference count methods ...
  70. ULONG AddRef();
  71. ULONG Release(BOOL fDeleteIfZeroRef = FALSE);
  72. HRESULT SetStreamFileName(LPSTR szStreamFileName);
  73. LPSTR GetStreamFileName() { return(m_szStreamName); }
  74. // Mechanisms for locking and unlocking the property bag
  75. HRESULT Lock();
  76. HRESULT Unlock();
  77. // Force opens the stream file if it is not already opened.
  78. // This is useful in checking if a stream file exists.
  79. HRESULT OpenStreamFile();
  80. // Access to properties as a whole
  81. HRESULT GetProperty(LPSTR pszName,
  82. LPVOID pvBuffer,
  83. LPDWORD pdwBufferLen);
  84. HRESULT SetProperty(LPSTR pszName,
  85. LPVOID pvBuffer,
  86. DWORD dwBufferLen);
  87. // Access to properties, providing specific access to
  88. // portions of the property data relative to the start
  89. // of the property data
  90. HRESULT GetPropertyAt(LPSTR pszName,
  91. DWORD dwOffsetFromStart,
  92. LPVOID pvBuffer,
  93. LPDWORD pdwBufferLen);
  94. HRESULT SetPropertyAt(LPSTR pszName,
  95. DWORD dwOffsetFromStart,
  96. LPVOID pvBuffer,
  97. DWORD dwBufferLen);
  98. // Ad-hoc function to allow access to a specific DWORD of
  99. // a property, treating the DWORD as a set of flags. The
  100. // dwOperation argument specifies what kind of binary operation
  101. // we would like to have performed on the original value.
  102. // If the property does not originally exist, this function
  103. // will fail.
  104. HRESULT UpdatePropertyFlagsAt(LPSTR pszName,
  105. DWORD dwOffsetFromStart,
  106. DWORD dwFlags,
  107. DWORD dwOperation);
  108. #ifdef USE_PROPERTY_ITEM_ISTREAM
  109. // Returns an IStream interface to the desired property
  110. // for random access
  111. HRESULT GetIStreamToProperty(LPSTR pszName,
  112. IStream **ppIStream);
  113. #endif
  114. BOOL DeleteStream();
  115. private:
  116. BOOL ReleaseStream();
  117. HRESULT Seek(DWORD dwOffset, DWORD dwMethod);
  118. HRESULT LoadIntoCache(DWORD dwStartIndex);
  119. LPTABLE_ENTRY FindFromCache(DWORD dwKey,
  120. LPDWORD pdwStartIndex);
  121. HRESULT FindFrom(LPSTR pszName,
  122. DWORD dwKey,
  123. DWORD dwStartIndex,
  124. BOOL fForward,
  125. LPVOID pvBuffer,
  126. LPDWORD pdwBufferLen,
  127. LPTABLE_ENTRY *ppEntry);
  128. HRESULT FindFromEx(LPSTR pszName,
  129. DWORD dwKey,
  130. DWORD dwStartIndex,
  131. BOOL fForward,
  132. DWORD dwOffsetFromStart,
  133. LPVOID pvBuffer,
  134. LPDWORD pdwBufferLen,
  135. LPTABLE_ENTRY *ppEntry);
  136. HRESULT GetRecordData(LPTABLE_ENTRY pEntry,
  137. LPVOID pvBuffer);
  138. HRESULT GetRecordName(LPTABLE_ENTRY pEntry,
  139. LPVOID pvBuffer);
  140. HRESULT GetRecordValue(LPTABLE_ENTRY pEntry,
  141. LPVOID pvBuffer);
  142. HRESULT GetRecordValueAt(LPTABLE_ENTRY pEntry,
  143. DWORD dwOffsetFromStart,
  144. LPVOID pvBuffer,
  145. DWORD dwBufferLen);
  146. HRESULT UpdateEntry(LPTABLE_ENTRY pEntry);
  147. HRESULT UpdateHeader();
  148. HRESULT UpdateHeaderUsingHandle(HANDLE hStream);
  149. HRESULT FindProperty(LPSTR pszName,
  150. LPVOID pvBuffer,
  151. LPDWORD pdwBufferLen,
  152. LPTABLE_ENTRY *ppEntry = NULL);
  153. HRESULT FindPropertyEx(LPSTR pszName,
  154. DWORD dwOffsetFromStart,
  155. LPVOID pvBuffer,
  156. LPDWORD pdwBufferLen,
  157. LPTABLE_ENTRY *ppEntry = NULL);
  158. HRESULT SetRecordData(LPTABLE_ENTRY pEntry,
  159. LPSTR pszName,
  160. LPVOID pvBuffer,
  161. DWORD dwBufferLen);
  162. HRESULT SetRecordDataAt(LPTABLE_ENTRY pEntry,
  163. LPSTR pszName,
  164. DWORD dwOffsetFromStart,
  165. LPVOID pvBuffer,
  166. DWORD dwBufferLen,
  167. BOOL fNewRecord = FALSE);
  168. HRESULT RelocateRecordData(LPTABLE_ENTRY pEntry);
  169. HRESULT DetermineIfCacheValid(BOOL *pfCacheInvalid);
  170. DWORD CreateKey(LPSTR pszName)
  171. {
  172. CHAR cKey[9];
  173. DWORD dwLen = 0;
  174. // Convert to lower case ...
  175. while (*pszName && (dwLen < 8))
  176. if ((*pszName >= 'A') && (*pszName <= 'Z'))
  177. cKey[dwLen++] = *pszName++ - 'A' + 'a';
  178. else
  179. cKey[dwLen++] = *pszName++;
  180. cKey[dwLen] = '\0';
  181. dwLen = lstrlen(cKey);
  182. // Create the key
  183. if (dwLen < 4)
  184. return((DWORD)cKey[dwLen - 1]);
  185. else if (dwLen < 8)
  186. return(*(DWORD *)cKey);
  187. else
  188. return(~*(DWORD *)cKey ^ *(DWORD *)(cKey + 4));
  189. }
  190. DWORD GetTotalHeaderSize()
  191. {
  192. return(sizeof(STREAM_HEADER) +
  193. (m_Header.dwDirectorySize * sizeof(TABLE_ENTRY)));
  194. }
  195. // Current context
  196. DWORD m_dwContext;
  197. // Base file name
  198. CHAR m_szStreamName[MAX_PATH + 1];
  199. // Handle to stream
  200. HANDLE m_hStream;
  201. // Stream header
  202. STREAM_HEADER m_Header;
  203. // Directory caching
  204. TABLE_ENTRY m_Cache[_CACHE_SIZE];
  205. DWORD m_dwCacheStart;
  206. DWORD m_dwCachedItems;
  207. // Reference counting
  208. LONG m_lRef;
  209. // This is a signature placed at the end to catch memory overwrite
  210. DWORD m_dwSignature;
  211. };
  212. /////////////////////////////////////////////////////////////////////////////
  213. // CPropertyItemStream
  214. //
  215. //
  216. // Not everyone wants to use the property IStream, so we don't expose
  217. // it if it's not wanted
  218. //
  219. #ifdef USE_PROPERTY_ITEM_ISTREAM
  220. class CPropertyItemStream : public IStream
  221. {
  222. public:
  223. CPropertyItemStream(LPSTR pszName,
  224. CPropertyBagStream *pBag)
  225. {
  226. m_cRef = 0;
  227. m_pParentBag = pBeg;
  228. m_szName = pszName;
  229. m_libOffset.QuadPart = (DWORDLONG)0;
  230. }
  231. ~CPropertyItemStream()
  232. {
  233. Cleanup();
  234. }
  235. // IUnknown
  236. STDMETHODIMP QueryInterface(REFIID, void**);
  237. STDMETHODIMP_(ULONG) AddRef(void);
  238. STDMETHODIMP_(ULONG) Release(void);
  239. void Cleanup() {}
  240. HRESULT ReadOffset(void *pv, ULONG cb, ULONG *pcbRead, ULARGE_INTEGER *plibOffset);
  241. HRESULT WriteOffset(void const* pv, ULONG cb, ULONG *pcbWritten, ULARGE_INTEGER *plibOffset);
  242. HRESULT GetSize(ULARGE_INTEGER *plibSize);
  243. HRESULT CopyToOffset(IStream *pstm, ULARGE_INTEGER libOffset, ULARGE_INTEGER *plibRead, ULARGE_INTEGER *plibWritten, ULARGE_INTEGER *plibOffset);
  244. HRESULT CloneOffset(IStream **pstm, ULARGE_INTEGER libOffset);
  245. // IStream
  246. public:
  247. HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead);
  248. HRESULT STDMETHODCALLTYPE Write(void const* pv, ULONG cb, ULONG *pcbWritten);
  249. HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *pdlibNewPosition);
  250. HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize);
  251. HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
  252. HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags);
  253. HRESULT STDMETHODCALLTYPE Revert(void);
  254. HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
  255. HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
  256. HRESULT STDMETHODCALLTYPE Stat(STATSTG * pstatstg, DWORD grfStatFlag);
  257. HRESULT STDMETHODCALLTYPE Clone(IStream **pstm);
  258. private:
  259. CPropertyBagStream *m_pParentBag;
  260. LPSTR m_szName;
  261. ULARGE_INTEGER m_libOffset;
  262. long m_cRef;
  263. };
  264. #endif // USE_PROPERTY_ISTREAM
  265. #endif