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.

387 lines
8.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: C O M P L I S T . C P P
  7. //
  8. // Contents: Implements the basic datatype for a collection of component
  9. // pointers.
  10. //
  11. // Notes:
  12. //
  13. // Author: shaunco 15 Jan 1999
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.h>
  17. #pragma hdrstop
  18. #include "bindings.h"
  19. #include "complist.h"
  20. #include "nceh.h"
  21. #include "stable.h"
  22. VOID
  23. CComponentList::FreeComponentsNotInOtherComponentList (
  24. IN const CComponentList* pOtherList)
  25. {
  26. Assert (this);
  27. Assert (pOtherList);
  28. CComponentList::iterator iter;
  29. CComponent* pComponent;
  30. iter = begin();
  31. while (iter != end())
  32. {
  33. pComponent = *iter;
  34. Assert (pComponent);
  35. if (!pOtherList->FComponentInList (pComponent))
  36. {
  37. erase (iter);
  38. delete pComponent;
  39. }
  40. else
  41. {
  42. iter++;
  43. }
  44. }
  45. }
  46. HRESULT
  47. CComponentList::HrCopyComponentList (
  48. IN const CComponentList* pSourceList)
  49. {
  50. HRESULT hr;
  51. Assert (this);
  52. Assert (pSourceList);
  53. NC_TRY
  54. {
  55. *this = *pSourceList;
  56. hr = S_OK;
  57. }
  58. NC_CATCH_BAD_ALLOC
  59. {
  60. hr = E_OUTOFMEMORY;
  61. }
  62. TraceHr (ttidError, FAL, hr, FALSE, "CComponentList::HrCopyComponentList");
  63. return hr;
  64. }
  65. HRESULT
  66. CComponentList::HrAddComponentsInList1ButNotInList2 (
  67. IN const CComponentList* pList1,
  68. IN const CComponentList* pList2)
  69. {
  70. HRESULT hr;
  71. CComponentList::const_iterator iter;
  72. CComponent* pComponent;
  73. Assert (this);
  74. Assert (pList1);
  75. Assert (pList2);
  76. hr = S_OK;
  77. for (iter = pList1->begin(); iter != pList1->end(); iter++)
  78. {
  79. pComponent = *iter;
  80. Assert (pComponent);
  81. if (pList2->FComponentInList (pComponent))
  82. {
  83. continue;
  84. }
  85. hr = HrInsertComponent (pComponent, INS_IGNORE_IF_DUP | INS_SORTED);
  86. if (S_OK != hr)
  87. {
  88. break;
  89. }
  90. }
  91. TraceHr (ttidError, FAL, hr, FALSE,
  92. "CComponentList::HrAddComponentsInList1ButNotInList2");
  93. return hr;
  94. }
  95. HRESULT
  96. CComponentList::HrInsertComponent (
  97. IN const CComponent* pComponent,
  98. IN DWORD dwFlags /* INS_FLAGS */)
  99. {
  100. HRESULT hr;
  101. Assert (this);
  102. Assert (pComponent);
  103. Assert (dwFlags);
  104. Assert ((dwFlags & INS_ASSERT_IF_DUP) || (dwFlags & INS_IGNORE_IF_DUP));
  105. Assert ((dwFlags & INS_SORTED) || (dwFlags & INS_NON_SORTED));
  106. Assert (!(INS_APPEND & dwFlags) && !(INS_INSERT & dwFlags));
  107. if (FComponentInList (pComponent))
  108. {
  109. // If the caller didn't tell us to ignore duplicates, we assert
  110. // if there is one because it is bad, bad, bad to have duplicate
  111. // components in the list.
  112. //
  113. // If we have a dup, we want the caller to be aware that it
  114. // is possible, and pass us the flag telling us to ignore it.
  115. // Otherwise, we assert to let them know. (And we still ignore
  116. // it.)
  117. Assert (dwFlags & INS_IGNORE_IF_DUP);
  118. return S_OK;
  119. }
  120. // Assert there is not already a component in the list with the
  121. // same instance guid.
  122. //
  123. Assert (!PFindComponentByInstanceGuid (&pComponent->m_InstanceGuid));
  124. iterator iter = end();
  125. if (dwFlags & INS_SORTED)
  126. {
  127. // For 'cleanliness sake', keep the components sorted
  128. // in class order.
  129. //
  130. for (iter = begin(); iter != end(); iter++)
  131. {
  132. if ((UINT)pComponent->Class() >= (UINT)(*iter)->Class())
  133. {
  134. break;
  135. }
  136. }
  137. }
  138. NC_TRY
  139. {
  140. insert (iter, const_cast<CComponent*>(pComponent));
  141. hr = S_OK;
  142. }
  143. NC_CATCH_BAD_ALLOC
  144. {
  145. hr = E_OUTOFMEMORY;
  146. }
  147. TraceHr (ttidError, FAL, hr, FALSE, "CComponentList::HrInsertComponent");
  148. return hr;
  149. }
  150. HRESULT
  151. CComponentList::HrReserveRoomForComponents (
  152. IN UINT cComponents)
  153. {
  154. HRESULT hr;
  155. NC_TRY
  156. {
  157. reserve (cComponents);
  158. hr = S_OK;
  159. }
  160. NC_CATCH_BAD_ALLOC
  161. {
  162. hr = E_OUTOFMEMORY;
  163. }
  164. TraceHr (ttidError, FAL, hr, FALSE,
  165. "CComponentList::HrReserveRoomForComponents");
  166. return hr;
  167. }
  168. CComponent*
  169. CComponentList::PFindComponentByBindForm (
  170. IN NETCLASS Class OPTIONAL,
  171. IN PCWSTR pszBindForm) const
  172. {
  173. const_iterator iter;
  174. CComponent* pComponent;
  175. Assert (this);
  176. Assert (pszBindForm && *pszBindForm);
  177. for (iter = begin(); iter != end(); iter++)
  178. {
  179. pComponent = *iter;
  180. Assert (pComponent);
  181. // Having a bindform is optional. Skip those who don't have one.
  182. //
  183. if (!pComponent->Ext.PszBindForm())
  184. {
  185. continue;
  186. }
  187. // Skip components that don't match the class optionally
  188. // specified by the caller.
  189. //
  190. if (FIsValidNetClass(Class) && (Class != pComponent->Class()))
  191. {
  192. continue;
  193. }
  194. Assert (pComponent->Ext.PszBindForm());
  195. if (0 == _wcsicmp (pszBindForm, pComponent->Ext.PszBindForm()))
  196. {
  197. return pComponent;
  198. }
  199. }
  200. return NULL;
  201. }
  202. CComponent*
  203. CComponentList::PFindComponentByBindName (
  204. IN NETCLASS Class OPTIONAL,
  205. IN PCWSTR pszBindName) const
  206. {
  207. const_iterator iter;
  208. CComponent* pComponent;
  209. Assert (this);
  210. Assert (pszBindName && *pszBindName);
  211. for (iter = begin(); iter != end(); iter++)
  212. {
  213. pComponent = *iter;
  214. Assert (pComponent);
  215. // Skip components that don't match the class optionally
  216. // specified by the caller.
  217. //
  218. if (FIsValidNetClass(Class) && (Class != pComponent->Class()))
  219. {
  220. continue;
  221. }
  222. Assert (pComponent->Ext.PszBindName());
  223. if (0 == _wcsicmp (pszBindName, pComponent->Ext.PszBindName()))
  224. {
  225. return pComponent;
  226. }
  227. }
  228. return NULL;
  229. }
  230. CComponent*
  231. CComponentList::PFindComponentByInstanceGuid (
  232. IN const GUID* pInstanceGuid) const
  233. {
  234. const_iterator iter;
  235. CComponent* pComponent;
  236. Assert (this);
  237. Assert (pInstanceGuid);
  238. for (iter = begin(); iter != end(); iter++)
  239. {
  240. pComponent = *iter;
  241. Assert (pComponent);
  242. if (*pInstanceGuid == pComponent->m_InstanceGuid)
  243. {
  244. return pComponent;
  245. }
  246. }
  247. return NULL;
  248. }
  249. CComponent*
  250. CComponentList::PFindComponentByInfId (
  251. IN PCWSTR pszInfId,
  252. IN OUT ULONG* pulIndex OPTIONAL) const
  253. {
  254. const_iterator iter;
  255. CComponent* pComponent;
  256. Assert (this);
  257. Assert (pszInfId && *pszInfId);
  258. iter = begin();
  259. if (pulIndex && (*pulIndex <= size()))
  260. {
  261. iter = begin() + *pulIndex;
  262. Assert (iter <= end());
  263. }
  264. for (; iter != end(); iter++)
  265. {
  266. pComponent = *iter;
  267. Assert (pComponent);
  268. Assert (pComponent->m_pszInfId && *pComponent->m_pszInfId);
  269. if (0 == _wcsicmp (pszInfId, pComponent->m_pszInfId))
  270. {
  271. if (pulIndex)
  272. {
  273. Assert (iter >= begin());
  274. *pulIndex = (ULONG)(iter - begin());
  275. }
  276. return pComponent;
  277. }
  278. }
  279. return NULL;
  280. }
  281. CComponent*
  282. CComponentList::PFindComponentByPnpId (
  283. IN PCWSTR pszPnpId) const
  284. {
  285. const_iterator iter;
  286. CComponent* pComponent;
  287. Assert (this);
  288. Assert (pszPnpId && *pszPnpId);
  289. for (iter = begin(); iter != end(); iter++)
  290. {
  291. pComponent = *iter;
  292. Assert (pComponent);
  293. if (!pComponent->m_pszPnpId)
  294. {
  295. continue;
  296. }
  297. Assert (pComponent->m_pszPnpId && *pComponent->m_pszPnpId);
  298. if (0 == _wcsicmp (pszPnpId, pComponent->m_pszPnpId))
  299. {
  300. return pComponent;
  301. }
  302. }
  303. return NULL;
  304. }
  305. VOID
  306. CComponentList::RemoveComponent (
  307. IN const CComponent* pComponent)
  308. {
  309. iterator iter;
  310. Assert (this);
  311. Assert (pComponent);
  312. iter = find (begin(), end(), pComponent);
  313. // Component should be found.
  314. //
  315. Assert (iter != end());
  316. erase (iter);
  317. // Should not be any dups. If there are, the list
  318. // is bogus to begin with.
  319. //
  320. Assert (end() == find (begin(), end(), pComponent));
  321. }