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.

486 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. membag.h
  5. Abstract:
  6. This module contains the definition for the
  7. ISEODictionary object in memory.
  8. Author:
  9. Andy Jacobs (andyj@microsoft.com)
  10. Revision History:
  11. andyj 02/10/97 created
  12. andyj 02/12/97 Converted PropertyBag's to Dictonary's
  13. --*/
  14. // MEMBAG.h : Declaration of the CSEOMemDictionary
  15. #include "tfdlist.h"
  16. #include "rwnew.h"
  17. enum DataType {Empty, DWord, String, Interface};
  18. class DataItem {
  19. public:
  20. typedef DLIST_ENTRY* (*PFNDLIST)( class DataItem*);
  21. DataItem() {
  22. m_pszKey = NULL;
  23. eType = Empty;
  24. };
  25. DataItem(DWORD d) {
  26. eType = DWord;
  27. dword = d;
  28. };
  29. DataItem(LPCSTR s, int iSize = -1) {
  30. eType = String;
  31. iStringSize = ((iSize >= 0) ? iSize : (lstrlen(s) + 1));
  32. pStr = (LPSTR) MyMalloc(iStringSize);
  33. if (pStr) {
  34. strncpy(pStr, s, iStringSize);
  35. }
  36. m_pszKey = NULL;
  37. };
  38. DataItem(LPCWSTR s, int iSize = -1) {
  39. eType = String;
  40. iStringSize = sizeof(WCHAR) * ((iSize >= 0) ? iSize : (wcslen(s) + 1));
  41. pStr = (LPSTR) MyMalloc(iStringSize);
  42. if (pStr) {
  43. ATLW2AHELPER(pStr, s, iStringSize);
  44. }
  45. m_pszKey = NULL;
  46. };
  47. DataItem(IUnknown *p) {
  48. eType = Interface;
  49. pUnk = p;
  50. if(pUnk) pUnk->AddRef();
  51. m_pszKey = NULL;
  52. }
  53. DataItem(const DataItem &diItem) {
  54. eType = diItem.eType;
  55. if(eType == DWord) dword = diItem.dword;
  56. else if(eType == String) {
  57. iStringSize = diItem.iStringSize;
  58. pStr = (LPSTR) MyMalloc(iStringSize);
  59. if (pStr) {
  60. strncpy(pStr, diItem.pStr, iStringSize);
  61. }
  62. } else if(eType == Interface) {
  63. pUnk = diItem.pUnk;
  64. if(pUnk) pUnk->AddRef();
  65. }
  66. if (diItem.m_pszKey) {
  67. m_pszKey = (LPSTR) MyMalloc(lstrlen(diItem.m_pszKey) + 1);
  68. if (m_pszKey) {
  69. strcpy(m_pszKey, diItem.m_pszKey);
  70. }
  71. } else {
  72. m_pszKey = NULL;
  73. }
  74. };
  75. DataItem &operator=(const DataItem &diItem) {
  76. eType = diItem.eType;
  77. if(eType == DWord) dword = diItem.dword;
  78. else if(eType == String) {iStringSize = diItem.iStringSize;
  79. pStr = (LPSTR) MyMalloc(iStringSize);
  80. if (pStr) {
  81. strncpy(pStr, diItem.pStr, iStringSize);}
  82. }
  83. else if(eType == Interface) {pUnk = diItem.pUnk;
  84. if(pUnk) pUnk->AddRef();}
  85. if (diItem.m_pszKey) {
  86. m_pszKey = (LPSTR) MyMalloc(lstrlen(diItem.m_pszKey) + 1);
  87. if (m_pszKey) {
  88. strcpy(m_pszKey, diItem.m_pszKey);
  89. }
  90. } else {
  91. m_pszKey = NULL;
  92. }
  93. return *this;
  94. };
  95. DataItem(VARIANT *pVar);
  96. ~DataItem() {
  97. if(eType == String) MyFree(pStr);
  98. else if((eType == Interface) && pUnk) pUnk->Release();
  99. eType = Empty;
  100. if (m_pszKey) {
  101. MyFree(m_pszKey);
  102. m_pszKey = NULL;
  103. }
  104. };
  105. BOOL SetKey(LPCSTR pszKey) {
  106. if (m_pszKey) {
  107. MyFree(m_pszKey);
  108. m_pszKey = NULL;
  109. }
  110. m_pszKey = (LPSTR) MyMalloc(lstrlen(pszKey) + 1);
  111. if (!m_pszKey) return FALSE;
  112. strcpy(m_pszKey, pszKey);
  113. return TRUE;
  114. }
  115. BOOL IsEmpty() const {return (eType == Empty);};
  116. BOOL IsDWORD() const {return (eType == DWord);};
  117. BOOL IsString() const {return (eType == String);};
  118. BOOL IsInterface() const {return (eType == Interface);};
  119. operator DWORD() const {return (const) (IsDWORD() ? dword : 0);};
  120. operator LPCSTR() const {return (IsString() ? pStr : NULL);};
  121. LPCSTR GetString() const {return (IsString() ? pStr : NULL);};
  122. operator LPUNKNOWN() const {return (IsInterface() ? pUnk : NULL);};
  123. HRESULT AsVARIANT(VARIANT *pVar) const;
  124. int StringSize() const {return iStringSize;};
  125. static DLIST_ENTRY *GetListEntry(DataItem *p) {
  126. return &p->m_listentry;
  127. }
  128. LPCSTR GetKey() {
  129. return m_pszKey;
  130. }
  131. private:
  132. DataType eType;
  133. int iStringSize;
  134. union {
  135. DWORD dword;
  136. LPSTR pStr;
  137. LPUNKNOWN pUnk;
  138. };
  139. DLIST_ENTRY m_listentry;
  140. LPSTR m_pszKey;
  141. };
  142. class ComparableString {
  143. public:
  144. ComparableString(LPCSTR p = NULL) : m_ptr(0), m_bAlloc(TRUE) {
  145. if(!p) return;
  146. m_ptr = (LPSTR) MyMalloc(lstrlen(p) + 1);
  147. if (m_ptr) {
  148. lstrcpy(m_ptr, p);
  149. }
  150. };
  151. ComparableString(const ComparableString &csOther) : m_ptr(0) {
  152. LPCSTR p = csOther.m_ptr;
  153. m_ptr = (LPSTR) MyMalloc(lstrlen(p) + 1);
  154. if (m_ptr) {
  155. lstrcpy(m_ptr, p);
  156. }
  157. };
  158. ~ComparableString() {if(m_bAlloc&&m_ptr) MyFree(m_ptr);};
  159. LPCSTR Data() const {return m_ptr;};
  160. bool operator<(const ComparableString &csOther) const {
  161. if (!m_ptr || !csOther.m_ptr) {
  162. if (csOther.m_ptr) {
  163. return (true);
  164. }
  165. return (false);
  166. }
  167. return (lstrcmpi(m_ptr, csOther.m_ptr) < 0);};
  168. protected:
  169. LPSTR m_ptr;
  170. BOOL m_bAlloc;
  171. };
  172. class ComparableStringRef : public ComparableString {
  173. public:
  174. ComparableStringRef(LPCSTR p) {
  175. m_ptr = (LPSTR) p;
  176. m_bAlloc = FALSE;
  177. };
  178. };
  179. typedef TDListHead<DataItem, &DataItem::GetListEntry> OurList;
  180. class OurMap {
  181. public:
  182. class iterator : public TDListIterator<OurList> {
  183. public:
  184. iterator(OurList *pHead)
  185. : TDListIterator<OurList>(pHead)
  186. {
  187. m_fFound = FALSE;
  188. }
  189. // get the key for the current item
  190. LPCSTR GetKey() {
  191. return Current()->GetKey();
  192. }
  193. // get the data for the current item
  194. DataItem *GetData() {
  195. return Current();
  196. }
  197. void operator++() {
  198. Next();
  199. }
  200. DataItem *operator*() {
  201. return Current();
  202. }
  203. void SetList(OurMap *pMap) {
  204. ReBind(&(pMap->m_list));
  205. }
  206. // point the iterator to a specific item in the list
  207. // arguments:
  208. // pszKey - key to find
  209. // iMatchType - -1 == point at first item with smaller key
  210. // 0 == point at item with key
  211. // 1 == point at first item with larger key
  212. // returns:
  213. // TRUE if a match was found, FALSE otherwise
  214. BOOL find(LPCSTR pszKey, DWORD iMatchType = 0) {
  215. if (strncmp(pszKey, "-1", 2) == 0) DebugBreak();
  216. // reset the iterator
  217. Front();
  218. // walk until we match the key
  219. while (!AtEnd()) {
  220. const char *pszCurrentKey = Current()->GetKey();
  221. if (lstrcmpi(pszCurrentKey, pszKey) == iMatchType) {
  222. m_fFound = TRUE;
  223. return TRUE;
  224. }
  225. Next();
  226. }
  227. m_fFound = FALSE;
  228. return FALSE;
  229. };
  230. // did the last search succeed?
  231. BOOL Found() {
  232. return m_fFound;
  233. }
  234. private:
  235. BOOL m_fFound;
  236. };
  237. friend iterator;
  238. OurMap() {
  239. m_cList = 0;
  240. }
  241. ~OurMap() {
  242. // remove all items from the list
  243. while (m_cList) {
  244. delete m_list.PopFront();
  245. m_cList--;
  246. }
  247. _ASSERT(m_list.IsEmpty());
  248. }
  249. void erase(iterator i) {
  250. m_cList--;
  251. delete i.RemoveItem();
  252. }
  253. BOOL insert(LPCSTR pszKey, DataItem di) {
  254. char buf[255];
  255. OurMap::iterator it(&m_list);
  256. DataItem *pDI = new DataItem();
  257. if (pDI == NULL) return FALSE;
  258. // copy the data item to the one that we will insert into
  259. // our list
  260. *pDI = di;
  261. if (!pDI->SetKey(pszKey)) {
  262. delete pDI;
  263. return FALSE;
  264. }
  265. // find the first item with a larger key. if no such item was
  266. // found then insert at head of list
  267. if (it.find(pszKey, 1)) {
  268. it.InsertBefore(pDI);
  269. } else {
  270. m_list.PushFront(pDI);
  271. }
  272. m_cList++;
  273. return TRUE;
  274. }
  275. iterator find(LPCSTR pszKey) {
  276. OurMap::iterator it(&m_list);
  277. it.find(pszKey);
  278. return it;
  279. }
  280. iterator begin() {
  281. OurMap::iterator it(&m_list);
  282. return it;
  283. }
  284. long size() {
  285. return m_cList;
  286. }
  287. private:
  288. OurList m_list;
  289. long m_cList;
  290. };
  291. /////////////////////////////////////////////////////////////////////////////
  292. // CSEOMemDictionary
  293. class ATL_NO_VTABLE CSEOMemDictionary :
  294. public CComObjectRootEx<CComMultiThreadModelNoCS>,
  295. public CComCoClass<CSEOMemDictionary, &CLSID_CSEOMemDictionary>,
  296. public IDispatchImpl<ISEODictionary, &IID_ISEODictionary, &LIBID_SEOLib>,
  297. public IPropertyBag,
  298. public IDispatchImpl<IEventPropertyBag, &IID_IEventPropertyBag, &LIBID_SEOLib>
  299. {
  300. friend class CSEOMemDictionaryEnum; // Helper class
  301. public:
  302. HRESULT FinalConstruct();
  303. void FinalRelease();
  304. DECLARE_PROTECT_FINAL_CONSTRUCT();
  305. DECLARE_REGISTRY_RESOURCEID_EX(IDR_StdAfx,
  306. L"SEOMemDictionary Class",
  307. L"SEO.SEOMemDictionary.1",
  308. L"SEO.SEOMemDictionary");
  309. BEGIN_COM_MAP(CSEOMemDictionary)
  310. COM_INTERFACE_ENTRY(ISEODictionary)
  311. COM_INTERFACE_ENTRY(IPropertyBag)
  312. COM_INTERFACE_ENTRY(IEventPropertyBag)
  313. COM_INTERFACE_ENTRY_IID(IID_IDispatch, IEventPropertyBag)
  314. COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
  315. END_COM_MAP()
  316. // ISEODictionary
  317. public:
  318. virtual /* [id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get_Item(
  319. /* [in] */ VARIANT __RPC_FAR *pvarName,
  320. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
  321. virtual /* [propput][helpstring] */ HRESULT STDMETHODCALLTYPE put_Item(
  322. /* [in] */ VARIANT __RPC_FAR *pvarName,
  323. /* [in] */ VARIANT __RPC_FAR *pvarValue);
  324. virtual /* [hidden][id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
  325. /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
  326. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantA(
  327. /* [in] */ LPCSTR pszName,
  328. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
  329. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantW(
  330. /* [in] */ LPCWSTR pszName,
  331. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
  332. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantA(
  333. /* [in] */ LPCSTR pszName,
  334. /* [in] */ VARIANT __RPC_FAR *pvarValue);
  335. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantW(
  336. /* [in] */ LPCWSTR pszName,
  337. /* [in] */ VARIANT __RPC_FAR *pvarValue);
  338. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringA(
  339. /* [in] */ LPCSTR pszName,
  340. /* [out][in] */ DWORD __RPC_FAR *pchCount,
  341. /* [retval][size_is][out] */ LPSTR pszResult);
  342. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringW(
  343. /* [in] */ LPCWSTR pszName,
  344. /* [out][in] */ DWORD __RPC_FAR *pchCount,
  345. /* [retval][size_is][out] */ LPWSTR pszResult);
  346. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringA(
  347. /* [in] */ LPCSTR pszName,
  348. /* [in] */ DWORD chCount,
  349. /* [size_is][in] */ LPCSTR pszValue);
  350. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringW(
  351. /* [in] */ LPCWSTR pszName,
  352. /* [in] */ DWORD chCount,
  353. /* [size_is][in] */ LPCWSTR pszValue);
  354. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordA(
  355. /* [in] */ LPCSTR pszName,
  356. /* [retval][out] */ DWORD __RPC_FAR *pdwResult);
  357. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordW(
  358. /* [in] */ LPCWSTR pszName,
  359. /* [retval][out] */ DWORD __RPC_FAR *pdwResult);
  360. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordA(
  361. /* [in] */ LPCSTR pszName,
  362. /* [in] */ DWORD dwValue);
  363. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordW(
  364. /* [in] */ LPCWSTR pszName,
  365. /* [in] */ DWORD dwValue);
  366. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceA(
  367. /* [in] */ LPCSTR pszName,
  368. /* [in] */ REFIID iidDesired,
  369. /* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
  370. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceW(
  371. /* [in] */ LPCWSTR pszName,
  372. /* [in] */ REFIID iidDesired,
  373. /* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
  374. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceA(
  375. /* [in] */ LPCSTR pszName,
  376. /* [in] */ IUnknown __RPC_FAR *punkValue);
  377. virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceW(
  378. /* [in] */ LPCWSTR pszName,
  379. /* [in] */ IUnknown __RPC_FAR *punkValue);
  380. DECLARE_GET_CONTROLLING_UNKNOWN();
  381. // IPropertyBag
  382. public:
  383. HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog);
  384. HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT *pVar);
  385. // IEventPropertyBag
  386. public:
  387. HRESULT STDMETHODCALLTYPE Item(VARIANT *pvarPropDesired, VARIANT *pvarPropValue);
  388. HRESULT STDMETHODCALLTYPE Name(long lPropIndex, BSTR *pbstrPropName);
  389. HRESULT STDMETHODCALLTYPE Add(BSTR pszPropName, VARIANT *pvarPropValue);
  390. HRESULT STDMETHODCALLTYPE Remove(VARIANT *pvarPropDesired);
  391. HRESULT STDMETHODCALLTYPE get_Count(long *plCount);
  392. /* Just use the get__NewEnum from ISEODictionary
  393. HRESULT STDMETHODCALLTYPE get__NewEnum(IUnknown **ppUnkEnum); */
  394. protected:
  395. HRESULT Insert(LPCSTR pszName, const DataItem &diItem);
  396. private: // Private data
  397. OurMap m_mData;
  398. CShareLockNH m_lock;
  399. CComPtr<IUnknown> m_pUnkMarshaler;
  400. };