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.

354 lines
7.3 KiB

  1. /**************************************************************************
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright 1998 Microsoft Corporation. All Rights Reserved.
  7. **************************************************************************/
  8. /**************************************************************************
  9. File: EnumIDL.cpp
  10. Description: Implements IEnumIDList.
  11. **************************************************************************/
  12. /**************************************************************************
  13. #include statements
  14. **************************************************************************/
  15. #include "EnumIDL.h"
  16. #include "ShlFldr.h"
  17. #include "mshtml.h"
  18. #include "msxml.h"
  19. #include "ParseXML.h"
  20. /**************************************************************************
  21. CEnumIDList::CEnumIDList
  22. **************************************************************************/
  23. CEnumIDList::CEnumIDList(IXMLDocument *pXMLDoc, DWORD dwFlags)
  24. {
  25. g_DllRefCount++;
  26. m_pFirst = m_pLast = m_pCurrent = NULL;
  27. m_pXMLRoot = NULL;
  28. m_dwFlags = dwFlags;
  29. m_fFolder = FALSE;
  30. m_pXMLDoc = pXMLDoc;
  31. m_pPidlMgr = new CPidlMgr();
  32. if(!m_pPidlMgr)
  33. {
  34. delete this;
  35. return;
  36. }
  37. //get the shell's IMalloc pointer
  38. //we'll keep this until we get destroyed
  39. if(FAILED(SHGetMalloc(&m_pMalloc)))
  40. {
  41. delete this;
  42. return;
  43. }
  44. if(!CreateEnumList())
  45. {
  46. delete this;
  47. return;
  48. }
  49. m_ObjRefCount = 1;
  50. }
  51. /**************************************************************************
  52. CEnumIDList::~CEnumIDList
  53. **************************************************************************/
  54. CEnumIDList::~CEnumIDList()
  55. {
  56. DeleteList();
  57. if(m_pMalloc)
  58. m_pMalloc->Release();
  59. if(m_pPidlMgr)
  60. delete m_pPidlMgr;
  61. g_DllRefCount--;
  62. }
  63. /**************************************************************************
  64. CEnumIDList::QueryInterface
  65. **************************************************************************/
  66. STDMETHODIMP CEnumIDList::QueryInterface(REFIID riid, LPVOID *ppReturn)
  67. {
  68. *ppReturn = NULL;
  69. //IUnknown
  70. if(IsEqualIID(riid, IID_IUnknown))
  71. {
  72. *ppReturn = this;
  73. }
  74. //IEnumIDList
  75. else if(IsEqualIID(riid, IID_IEnumIDList))
  76. {
  77. *ppReturn = (IEnumIDList*)this;
  78. }
  79. if(*ppReturn)
  80. {
  81. (*(LPUNKNOWN*)ppReturn)->AddRef();
  82. return S_OK;
  83. }
  84. return E_NOINTERFACE;
  85. }
  86. /**************************************************************************
  87. CEnumIDList::AddRef
  88. **************************************************************************/
  89. STDMETHODIMP_(DWORD) CEnumIDList::AddRef()
  90. {
  91. return ++m_ObjRefCount;
  92. }
  93. /**************************************************************************
  94. CEnumIDList::Release
  95. **************************************************************************/
  96. STDMETHODIMP_(DWORD) CEnumIDList::Release()
  97. {
  98. if(--m_ObjRefCount == 0)
  99. {
  100. delete this;
  101. return 0;
  102. }
  103. return m_ObjRefCount;
  104. }
  105. /**************************************************************************
  106. CEnumIDList::Next()
  107. **************************************************************************/
  108. STDMETHODIMP CEnumIDList::Next(DWORD dwElements, LPITEMIDLIST apidl[], LPDWORD pdwFetched)
  109. {
  110. DWORD dwIndex;
  111. HRESULT hr = S_OK;
  112. if(dwElements > 1 && !pdwFetched)
  113. return E_INVALIDARG;
  114. for(dwIndex = 0; dwIndex < dwElements; dwIndex++)
  115. {
  116. //is this the last item in the list?
  117. if(!m_pCurrent)
  118. {
  119. hr = S_FALSE;
  120. break;
  121. }
  122. apidl[dwIndex] = m_pPidlMgr->Copy(m_pCurrent->pidl);
  123. m_pCurrent = m_pCurrent->pNext;
  124. }
  125. if(pdwFetched)
  126. *pdwFetched = dwIndex;
  127. return hr;
  128. }
  129. /**************************************************************************
  130. CEnumIDList::Skip()
  131. **************************************************************************/
  132. STDMETHODIMP CEnumIDList::Skip(DWORD dwSkip)
  133. {
  134. DWORD dwIndex;
  135. HRESULT hr = S_OK;
  136. for(dwIndex = 0; dwIndex < dwSkip; dwIndex++)
  137. {
  138. //is this the last item in the list?
  139. if(!m_pCurrent)
  140. {
  141. hr = S_FALSE;
  142. break;
  143. }
  144. m_pCurrent = m_pCurrent->pNext;
  145. }
  146. return hr;
  147. }
  148. /**************************************************************************
  149. CEnumIDList::Reset()
  150. **************************************************************************/
  151. STDMETHODIMP CEnumIDList::Reset(VOID)
  152. {
  153. m_pCurrent = m_pFirst;
  154. return S_OK;
  155. }
  156. /**************************************************************************
  157. CEnumIDList::Clone()
  158. **************************************************************************/
  159. STDMETHODIMP CEnumIDList::Clone(LPENUMIDLIST *ppEnum)
  160. {
  161. HRESULT hr = E_OUTOFMEMORY;
  162. *ppEnum = new CEnumIDList(m_pXMLDoc, m_dwFlags);
  163. if(*ppEnum)
  164. {
  165. LPENUMLIST pTemp;
  166. //synchronize the current pointer
  167. for(pTemp = m_pFirst; pTemp != m_pCurrent; pTemp = pTemp->pNext)
  168. {
  169. (*ppEnum)->Skip(1);
  170. }
  171. hr = S_OK;
  172. }
  173. return hr;
  174. }
  175. /**************************************************************************
  176. CEnumIDList::CreateEnumList()
  177. **************************************************************************/
  178. BOOL CEnumIDList::CreateEnumList(VOID)
  179. {
  180. HRESULT hr;
  181. // Get the sourse XML
  182. if (m_pXMLDoc == NULL)
  183. {
  184. return FALSE;
  185. }
  186. if (m_pXMLRoot == NULL)
  187. {
  188. hr = m_pXMLDoc->get_root(&m_pXMLRoot);
  189. if (!SUCCEEDED(hr) || !m_pXMLRoot)
  190. {
  191. SAFERELEASE(m_pXMLRoot);
  192. return FALSE;
  193. }
  194. }
  195. //enumerate the folders
  196. //
  197. // Now walk the OM
  198. //
  199. // Dump the top level meta nodes of the document.
  200. //
  201. DumpElement(NULL, m_pPidlMgr, this, m_pXMLRoot, T_ROOT);
  202. // Done
  203. SAFERELEASE(m_pXMLRoot);
  204. return TRUE;
  205. }
  206. /**************************************************************************
  207. CEnumIDList::AddToEnumList()
  208. **************************************************************************/
  209. BOOL CEnumIDList::AddToEnumList(LPITEMIDLIST pidl)
  210. {
  211. LPENUMLIST pNew;
  212. pNew = (LPENUMLIST)m_pMalloc->Alloc(sizeof(ENUMLIST));
  213. if(pNew)
  214. {
  215. //set the next pointer
  216. pNew->pNext = NULL;
  217. pNew->pidl = pidl;
  218. //is this the first item in the list?
  219. if(!m_pFirst)
  220. {
  221. m_pFirst = pNew;
  222. m_pCurrent = m_pFirst;
  223. }
  224. if(m_pLast)
  225. {
  226. //add the new item to the end of the list
  227. m_pLast->pNext = pNew;
  228. }
  229. //update the last item pointer
  230. m_pLast = pNew;
  231. return TRUE;
  232. }
  233. return FALSE;
  234. }
  235. /**************************************************************************
  236. CEnumIDList::DeleteList()
  237. **************************************************************************/
  238. BOOL CEnumIDList::DeleteList(VOID)
  239. {
  240. LPENUMLIST pDelete;
  241. while(m_pFirst)
  242. {
  243. pDelete = m_pFirst;
  244. m_pFirst = pDelete->pNext;
  245. //free the pidl
  246. m_pPidlMgr->Delete(pDelete->pidl);
  247. //free the list item
  248. m_pMalloc->Free(pDelete);
  249. }
  250. m_pFirst = m_pLast = m_pCurrent = NULL;
  251. return TRUE;
  252. }