Leaked source code of windows server 2003
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.

469 lines
14 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: strtable.h
  7. *
  8. * Contents: Interface file for CStringTable
  9. *
  10. * History: 25-Jun-98 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #ifndef STRTABLE_H
  14. #define STRTABLE_H
  15. #pragma once
  16. #include <exception> // for class exception
  17. #include <string> // for string relational operators
  18. #include "guidhelp.h" // for GUID relational operators
  19. #include "stgio.h"
  20. #include "strings.h"
  21. #ifdef DBG
  22. #define DECLARE_DIAGNOSITICS() \
  23. public: void Dump() const;
  24. #else
  25. #define DECLARE_DIAGNOSITICS() \
  26. public: void Dump() const {}
  27. #endif
  28. #ifdef DBG
  29. extern CTraceTag tagStringTable;
  30. #endif // DBG
  31. /*--------------------------------------------------------------------------
  32. * IdentifierRange should be private to CIdentifierPool, but
  33. * compiler bugs prevent it.
  34. */
  35. template<class T>
  36. class IdentifierRange
  37. {
  38. public:
  39. IdentifierRange(T idMin_ = T(), T idMax_ = T())
  40. : idMin (idMin_), idMax (idMax_)
  41. { ASSERT (idMin <= idMax); }
  42. bool operator== (const IdentifierRange<T>& other) const
  43. { return ((idMin == other.idMin) && (idMax == other.idMax)); }
  44. bool operator!= (const IdentifierRange<T>& other) const
  45. { return (!(*this == other.idMin)); }
  46. T idMin;
  47. T idMax;
  48. };
  49. template<class T = int>
  50. class CIdentifierPool : public CXMLObject
  51. {
  52. public:
  53. typedef IdentifierRange<T> Range;
  54. typedef std::list<Range> RangeList;
  55. private:
  56. #if _MSC_VER > 1300
  57. template <class U>
  58. friend IStream& operator>> (IStream& stm, CIdentifierPool<U>& pool);
  59. template <class U>
  60. friend IStream& operator<< (IStream& stm, const CIdentifierPool<U>& pool);
  61. #else
  62. // VC7 bug - doesn't handle template friends properly. By luck, this works.
  63. friend IStream& operator>> (IStream& stm, CIdentifierPool<T>& pool);
  64. friend IStream& operator<< (IStream& stm, const CIdentifierPool<T>& pool);
  65. #endif
  66. virtual void Persist(CPersistor &persistor);
  67. DEFINE_XML_TYPE(XML_TAG_IDENTIFIER_POOL);
  68. SC ScInvertRangeList (RangeList& rlInvert) const;
  69. #ifdef DBG
  70. void DumpRangeList (const RangeList& l) const;
  71. #endif
  72. public:
  73. DECLARE_DIAGNOSITICS();
  74. CIdentifierPool (T idMin, T idMax);
  75. CIdentifierPool (IStream& stm);
  76. T Reserve();
  77. bool Release(T idRelease);
  78. bool IsValid () const;
  79. bool IsRangeListValid (const RangeList& rl) const;
  80. SC ScGenerate (const RangeList& rlUsedIDs);
  81. static bool AddToRangeList (RangeList& rl, const Range& rangeToAdd);
  82. static bool AddToRangeList (RangeList& rl, T idAdd);
  83. class pool_exhausted : public exception
  84. {
  85. public:
  86. pool_exhausted(const char *_S = "pool exhausted") _THROW0()
  87. : exception(_S) {}
  88. virtual ~pool_exhausted() _THROW0()
  89. {}
  90. };
  91. private:
  92. RangeList m_AvailableIDs;
  93. RangeList m_StaleIDs;
  94. T m_idAbsoluteMin;
  95. T m_idAbsoluteMax;
  96. T m_idNextAvailable;
  97. };
  98. typedef CIdentifierPool<MMC_STRING_ID> CStringIDPool;
  99. /*--------------------------------------------------------------------------
  100. * CEntry and CStoredEntry should be private to CStringTable,
  101. * but compiler bugs prevent it.
  102. */
  103. /*
  104. * represents a string table entry in memory
  105. */
  106. class CEntry : public CXMLObject
  107. {
  108. friend class CStringTable;
  109. friend class CStringEnumerator;
  110. friend struct CompareEntriesByID;
  111. friend struct CompareEntriesByString;
  112. friend struct IdentifierReleaser;
  113. friend IStream& operator>> (IStream& stm, CEntry& entry);
  114. friend IStream& operator<< (IStream& stm, const CEntry& entry);
  115. public:
  116. DECLARE_DIAGNOSITICS();
  117. CEntry () : m_id(0), m_cRefs(0) {}
  118. CEntry (const std::wstring& str, MMC_STRING_ID id)
  119. : m_str(str), m_id(id), m_cRefs(0)
  120. {}
  121. virtual LPCTSTR GetXMLType() {return XML_TAG_STRING_TABLE_STRING;}
  122. virtual void Persist(CPersistor& persistor);
  123. private:
  124. /*
  125. * This ctor is only used by CStringTable when reconstructing
  126. * the entry from a file.
  127. */
  128. CEntry (const std::wstring& str, MMC_STRING_ID id, DWORD cRefs)
  129. : m_str(str) , m_id(id), m_cRefs(cRefs)
  130. {}
  131. private:
  132. bool operator< (const LPCWSTR psz) const
  133. { return (m_str < psz); }
  134. bool operator< (const CEntry& other) const
  135. { return (m_str < other.m_str); }
  136. bool operator== (const LPCWSTR psz) const
  137. { return (m_str == psz); }
  138. bool operator== (const CEntry& other) const
  139. { return (m_str == other.m_str); }
  140. //private:
  141. public: // temp!
  142. std::wstring m_str;
  143. MMC_STRING_ID m_id;
  144. DWORD m_cRefs;
  145. };
  146. struct CompareEntriesByID :
  147. public std::binary_function<const CEntry&, const CEntry&, bool>
  148. {
  149. bool operator() (const CEntry& entry1, const CEntry& entry2) const
  150. { return (entry1.m_id < entry2.m_id); }
  151. };
  152. struct CompareEntriesByString :
  153. public std::binary_function<const CEntry&, const CEntry&, bool>
  154. {
  155. bool operator() (const CEntry& entry1, const CEntry& entry2) const
  156. { return (entry1 < entry2); }
  157. };
  158. struct IdentifierReleaser :
  159. public std::unary_function<CEntry&, bool>
  160. {
  161. IdentifierReleaser (CStringIDPool& pool) : m_pool (pool) {}
  162. bool operator() (CEntry& entry) const
  163. { return (m_pool.Release (entry.m_id)); }
  164. private:
  165. CStringIDPool& m_pool;
  166. };
  167. /*
  168. * Because the string and ID indexes map their keys to CEntry
  169. * pointers, we must use a collection that doesn't move its
  170. * elements once they're inserted. The only STL collection
  171. * that meets this requirement is a list.
  172. */
  173. typedef std::list<CEntry> EntryList;
  174. typedef XMLListCollectionWrap<EntryList> CStringTable_base;
  175. class CStringTable : public CStringTable_base
  176. {
  177. friend IStream& operator>> (IStream& stm, CStringTable& entry);
  178. friend IStream& operator<< (IStream& stm, const CStringTable& entry);
  179. public:
  180. DECLARE_DIAGNOSITICS();
  181. CStringTable (CStringIDPool* pIDPool);
  182. CStringTable (CStringIDPool* pIDPool, IStream& stm);
  183. ~CStringTable ();
  184. CStringTable (const CStringTable& other);
  185. CStringTable& operator= (const CStringTable& other);
  186. /*
  187. * IStringTable methods. Note that object doesn't implement
  188. * IStringTable, because IUnknown isn't implemented.
  189. */
  190. STDMETHOD(AddString) (LPCOLESTR pszAdd, MMC_STRING_ID* pID);
  191. STDMETHOD(GetString) (MMC_STRING_ID id, ULONG cchBuffer, LPOLESTR lpBuffer, ULONG* pcchOut) const;
  192. STDMETHOD(GetStringLength) (MMC_STRING_ID id, ULONG* pcchString) const;
  193. STDMETHOD(DeleteString) (MMC_STRING_ID id);
  194. STDMETHOD(DeleteAllStrings) ();
  195. STDMETHOD(FindString) (LPCOLESTR pszFind, MMC_STRING_ID* pID) const;
  196. STDMETHOD(Enumerate) (IEnumString** ppEnum) const;
  197. size_t size() const
  198. { return (m_Entries.size()); }
  199. virtual void Persist(CPersistor& persistor)
  200. {
  201. CStringTable_base::Persist(persistor);
  202. if (persistor.IsLoading())
  203. IndexAllEntries ();
  204. }
  205. SC ScCollectInUseIDs (CStringIDPool::RangeList& l) const;
  206. private:
  207. void IndexAllEntries ()
  208. { IndexEntries (m_Entries.begin(), m_Entries.end()); }
  209. void IndexEntries (EntryList::iterator first, EntryList::iterator last)
  210. {
  211. for (; first != last; ++first)
  212. IndexEntry (first);
  213. }
  214. void IndexEntry (EntryList::iterator);
  215. typedef std::map<std::wstring, EntryList::iterator> StringToEntryMap;
  216. typedef std::map<MMC_STRING_ID, EntryList::iterator> IDToEntryMap;
  217. EntryList::iterator LookupEntryByString (const std::wstring&) const;
  218. EntryList::iterator LookupEntryByID (MMC_STRING_ID) const;
  219. EntryList::iterator FindInsertionPointForEntry (const CEntry& entry) const;
  220. #ifdef DBG
  221. static void AssertValid (const CStringTable* pTable);
  222. #define ASSERT_VALID_(p) do { AssertValid(p); } while(0)
  223. #else
  224. #define ASSERT_VALID_(p) ((void) 0)
  225. #endif
  226. private:
  227. EntryList m_Entries;
  228. StringToEntryMap m_StringIndex;
  229. IDToEntryMap m_IDIndex;
  230. CStringIDPool* m_pIDPool;
  231. };
  232. extern const CLSID CLSID_MMC;
  233. /*+-------------------------------------------------------------------------*
  234. * class CLSIDToStringTableMap
  235. *
  236. *
  237. * PURPOSE: stl::map derived class that maps snapin_clsid to stringtable
  238. * and supports XML persistence of the map collection
  239. *
  240. * NOTE: Throws exceptions!
  241. *+-------------------------------------------------------------------------*/
  242. typedef std::map<CLSID, CStringTable> ST_base;
  243. class CLSIDToStringTableMap : public XMLMapCollection<ST_base>
  244. {
  245. public:
  246. // this method is provided as alternative to Persist, whic allows
  247. // to cache parameter to be used to create new string tables
  248. void PersistSelf(CStringIDPool *pIDPool, CPersistor& persistor)
  249. {
  250. m_pIDPersistPool = pIDPool;
  251. persistor.Persist(*this, NULL);
  252. }
  253. protected:
  254. // XML persistence implementation
  255. virtual LPCTSTR GetXMLType() {return XML_TAG_STRING_TABLE_MAP;}
  256. virtual void OnNewElement(CPersistor& persistKey,CPersistor& persistVal)
  257. {
  258. CLSID key;
  259. ZeroMemory(&key,sizeof(key));
  260. persistKey.Persist(key);
  261. CStringTable val(m_pIDPersistPool);
  262. persistVal.Persist(val);
  263. insert(ST_base::value_type(key,val));
  264. }
  265. private:
  266. CStringIDPool *m_pIDPersistPool;
  267. };
  268. typedef CLSIDToStringTableMap::value_type TableMapValue;
  269. class CMasterStringTable : public IStringTablePrivate, public CComObjectRoot, public CXMLObject
  270. {
  271. friend IStorage& operator>> (IStorage& stg, CMasterStringTable& mst);
  272. friend IStorage& operator<< (IStorage& stg, const CMasterStringTable& mst);
  273. public:
  274. DECLARE_DIAGNOSITICS();
  275. CMasterStringTable ();
  276. ~CMasterStringTable ();
  277. public:
  278. DEFINE_XML_TYPE(XML_TAG_MMC_STRING_TABLE);
  279. virtual void Persist(CPersistor& persistor);
  280. SC ScPurgeUnusedStrings();
  281. public:
  282. /*
  283. * ATL COM map
  284. */
  285. BEGIN_COM_MAP (CMasterStringTable)
  286. COM_INTERFACE_ENTRY (IStringTablePrivate)
  287. END_COM_MAP ()
  288. /*
  289. * IStringTablePrivate methods
  290. */
  291. STDMETHOD(AddString) (LPCOLESTR pszAdd, MMC_STRING_ID* pID, const CLSID* pclsid);
  292. STDMETHOD(GetString) (MMC_STRING_ID id, ULONG cchBuffer, LPOLESTR lpBuffer, ULONG* pcchOut, const CLSID* pclsid);
  293. STDMETHOD(GetStringLength) (MMC_STRING_ID id, ULONG* pcchString, const CLSID* pclsid);
  294. STDMETHOD(DeleteString) (MMC_STRING_ID id, const CLSID* pclsid);
  295. STDMETHOD(DeleteAllStrings) (const CLSID* pclsid);
  296. STDMETHOD(FindString) (LPCOLESTR pszFind, MMC_STRING_ID* pID, const CLSID* pclsid);
  297. STDMETHOD(Enumerate) (IEnumString** ppEnum, const CLSID* pclsid);
  298. /*
  299. * Shorthand into IStringTablePrivate (simulating a default parameter)
  300. */
  301. STDMETHOD(AddString) (LPCOLESTR pszAdd, MMC_STRING_ID* pID)
  302. { return (AddString (pszAdd, pID, &CLSID_MMC)); }
  303. STDMETHOD(GetString) (MMC_STRING_ID id, ULONG cchBuffer, LPOLESTR lpBuffer, ULONG* pcchOut)
  304. { return (GetString (id, cchBuffer, lpBuffer, pcchOut, &CLSID_MMC)); }
  305. STDMETHOD(GetStringLength) (MMC_STRING_ID id, ULONG* pcchString)
  306. { return (GetStringLength (id, pcchString, &CLSID_MMC)); }
  307. STDMETHOD(DeleteString) (MMC_STRING_ID id)
  308. { return (DeleteString (id, &CLSID_MMC)); }
  309. STDMETHOD(DeleteAllStrings) ()
  310. { return (DeleteAllStrings (&CLSID_MMC)); }
  311. STDMETHOD(FindString) (LPCOLESTR pszFind, MMC_STRING_ID* pID)
  312. { return (FindString (pszFind, pID, &CLSID_MMC)); }
  313. STDMETHOD(Enumerate) (IEnumString** ppEnum)
  314. { return (Enumerate (ppEnum, &CLSID_MMC)); }
  315. private:
  316. CStringTable* LookupStringTableByCLSID (const CLSID* pclsid) const;
  317. SC ScGenerateIDPool ();
  318. private:
  319. CStringIDPool m_IDPool;
  320. CLSIDToStringTableMap m_TableMap;
  321. static const WCHAR s_pszIDPoolStream[];
  322. static const WCHAR s_pszStringsStream[];
  323. };
  324. class CStringEnumerator : public IEnumString, public CComObjectRoot
  325. {
  326. public:
  327. CStringEnumerator ();
  328. ~CStringEnumerator ();
  329. public:
  330. /*
  331. * ATL COM map
  332. */
  333. BEGIN_COM_MAP (CStringEnumerator)
  334. COM_INTERFACE_ENTRY (IEnumString)
  335. END_COM_MAP ()
  336. /*
  337. * IEnumString methods
  338. */
  339. STDMETHOD(Next) (ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched);
  340. STDMETHOD(Skip) (ULONG celt);
  341. STDMETHOD(Reset) ();
  342. STDMETHOD(Clone) (IEnumString **ppenum);
  343. static HRESULT CreateInstanceWrapper (
  344. CComObject<CStringEnumerator>** ppEnumObject,
  345. IEnumString** ppEnumIface);
  346. bool Init (const EntryList& entries);
  347. private:
  348. typedef std::vector<std::wstring> StringVector;
  349. StringVector m_Strings;
  350. size_t m_cStrings;
  351. size_t m_nCurrentIndex;
  352. };
  353. IStorage& operator>> (IStorage& stg, CMasterStringTable& mst);
  354. IStorage& operator<< (IStorage& stg, const CMasterStringTable& mst);
  355. IStorage& operator>> (IStorage& stg, CComObject<CMasterStringTable>& mst);
  356. IStorage& operator<< (IStorage& stg, const CComObject<CMasterStringTable>& mst);
  357. IStream& operator>> (IStream& stm, CStringTable& st);
  358. IStream& operator<< (IStream& stm, const CStringTable& st);
  359. IStream& operator>> (IStream& stm, CEntry& entry);
  360. IStream& operator<< (IStream& stm, const CEntry& entry);
  361. template<class T>
  362. IStream& operator>> (IStream& stm, CIdentifierPool<T>& pool);
  363. template<class T>
  364. IStream& operator<< (IStream& stm, const CIdentifierPool<T>& pool);
  365. #include "strtable.inl"
  366. #endif /* STRTABLE_H */