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.

458 lines
9.2 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cenumacl.cxx
  7. //
  8. // Contents: Access Control List Enumerator Code
  9. //
  10. // CAccCtrlListEnum::Create
  11. // CAccCtrlListEnum::CAccCtrlListEnum
  12. // CAccCtrlListEnum::~CAccCtrlListEnum
  13. // CAccCtrlListEnum::QueryInterface
  14. // CAccCtrlListEnum::AddRef
  15. // CAccCtrlListEnum::Release
  16. // CAccCtrlListEnum::Next
  17. // CAccCtrlListEnum::Skip
  18. // CAccCtrlListEnum::Clone
  19. //
  20. // History: 03-26-98 AjayR Created.
  21. // This file was cloned from ldap\cenumvar.cxx
  22. //----------------------------------------------------------------------------
  23. #include "procs.hxx"
  24. #pragma hdrstop
  25. #include "oleds.hxx"
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Function: CAccCtrlListEnum::CAccCtrlListEnum
  29. //
  30. // Synopsis:
  31. //
  32. //
  33. // Arguments:
  34. //
  35. //
  36. // Returns:
  37. //
  38. // Modifies:
  39. //
  40. // History: 03-26-96 AjayR Cloned from ldap\cenumvar.
  41. //
  42. //----------------------------------------------------------------------------
  43. CAccCtrlListEnum::CAccCtrlListEnum()
  44. {
  45. //
  46. // Set the reference count on the enumerator.
  47. //
  48. _cRef = 1;
  49. _pACL = NULL;
  50. _curElement = 0;
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Function: CAccCtrlListEnum::~CAccCtrlListEnum
  55. //
  56. // Synopsis:
  57. //
  58. //
  59. // Arguments:
  60. //
  61. // Returns:
  62. //
  63. // Modifies:
  64. //
  65. // History: 01-30-95 krishnag Created.
  66. //
  67. //----------------------------------------------------------------------------
  68. CAccCtrlListEnum::~CAccCtrlListEnum()
  69. {
  70. //
  71. // Bump down the reference count on the Collection object
  72. //
  73. //
  74. // Remove its entry (in ACL) as an enumerator of the ACL
  75. //
  76. if (_pACL) {
  77. _pACL->RemoveEnumerator(this);
  78. }
  79. // Release the ACL if we have a ref on it
  80. if (_pACL) {
  81. _pACL->Release();
  82. _pACL = NULL;
  83. }
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Function: CAccCtrlListEnum::QueryInterface
  88. //
  89. // Synopsis:
  90. //
  91. // Arguments: [iid]
  92. // [ppv]
  93. //
  94. // Returns: HRESULT
  95. //
  96. // Modifies:
  97. //
  98. // History: 01-30-95 krishnag Created.
  99. //
  100. //----------------------------------------------------------------------------
  101. STDMETHODIMP
  102. CAccCtrlListEnum::QueryInterface(
  103. REFIID iid,
  104. void FAR* FAR* ppv
  105. )
  106. {
  107. if (ppv == NULL) {
  108. RRETURN(E_POINTER);
  109. }
  110. *ppv = NULL;
  111. if (iid == IID_IUnknown || iid == IID_IEnumVARIANT) {
  112. *ppv = this;
  113. }
  114. else {
  115. return ResultFromScode(E_NOINTERFACE);
  116. }
  117. AddRef();
  118. return NOERROR;
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Function: CAccCtrlListEnum::AddRef
  123. //
  124. // Synopsis:
  125. //
  126. // Arguments:
  127. //
  128. // Returns: HRESULT
  129. //
  130. // Modifies:
  131. //
  132. // History: 01-30-95 krishnag Created.
  133. //----------------------------------------------------------------------------
  134. STDMETHODIMP_(ULONG)
  135. CAccCtrlListEnum::AddRef(void)
  136. {
  137. return ++_cRef;
  138. }
  139. //+---------------------------------------------------------------------------
  140. //
  141. // Function: CAccCtrlListEnum::Release
  142. //
  143. // Synopsis:
  144. //
  145. //
  146. // Arguments: [void]
  147. //
  148. // Returns:
  149. //
  150. // Modifies:
  151. //
  152. // History: 01-30-95 krishnag Created.
  153. //----------------------------------------------------------------------------
  154. STDMETHODIMP_(ULONG)
  155. CAccCtrlListEnum::Release(void)
  156. {
  157. if(--_cRef == 0){
  158. delete this;
  159. return 0;
  160. }
  161. return _cRef;
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Function: CAccCtrlListEnum::Skip
  166. //
  167. // Synopsis:
  168. //
  169. // Arguments: [cElements]
  170. //
  171. // Returns: HRESULT
  172. //
  173. // Modifies:
  174. //
  175. // History: 01-30-95 krishnag Created.
  176. //
  177. //----------------------------------------------------------------------------
  178. STDMETHODIMP
  179. CAccCtrlListEnum::Skip(ULONG cElements)
  180. {
  181. RRETURN(E_NOTIMPL);
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Function: CAccCtrlListEnum::Reset
  186. //
  187. // Synopsis:
  188. //
  189. // Arguments: []
  190. //
  191. // Returns: HRESULT
  192. //
  193. // Modifies:
  194. //
  195. // History:
  196. //
  197. //----------------------------------------------------------------------------
  198. STDMETHODIMP
  199. CAccCtrlListEnum::Reset()
  200. {
  201. RRETURN(E_NOTIMPL);
  202. }
  203. //+---------------------------------------------------------------------------
  204. //
  205. // Function: CAccCtrlListEnum::Clone
  206. //
  207. // Synopsis:
  208. //
  209. // Arguments: [pCollection]
  210. // [ppEnum]
  211. //
  212. // Returns: HRESULT
  213. //
  214. // Modifies:
  215. //
  216. // History: 01-30-95 krishnag Created.
  217. //
  218. //----------------------------------------------------------------------------
  219. STDMETHODIMP
  220. CAccCtrlListEnum::Clone(IEnumVARIANT FAR* FAR* ppenum)
  221. {
  222. RRETURN(E_NOTIMPL);
  223. }
  224. //+---------------------------------------------------------------------------
  225. //
  226. // Function: CAccCtrlListEnum::Create
  227. //
  228. // Synopsis: Create the enumeration object and initialise the
  229. // the member variables with the appropritate values.
  230. //
  231. // Arguments: [ppEnumVariant]
  232. // [pACL] Pointer to CAccessControlList
  233. //
  234. // Returns: HRESULT
  235. //
  236. // Modifies: [ppEnumVariant]
  237. //
  238. //----------------------------------------------------------------------------
  239. HRESULT
  240. CAccCtrlListEnum::CreateAclEnum(
  241. CAccCtrlListEnum FAR* FAR* ppEnumVariant,
  242. CAccessControlList *pACL
  243. )
  244. {
  245. HRESULT hr = S_OK;
  246. CAccCtrlListEnum FAR* pEnumVariant = NULL;
  247. *ppEnumVariant = NULL;
  248. pEnumVariant = new CAccCtrlListEnum();
  249. if (!pEnumVariant) {
  250. hr = E_OUTOFMEMORY;
  251. BAIL_ON_FAILURE(hr);
  252. }
  253. // Note that we need to release this when we get rid of this object
  254. pACL->AddRef();
  255. pEnumVariant->_pACL = pACL;
  256. error:
  257. if (FAILED(hr))
  258. delete pEnumVariant;
  259. else
  260. *ppEnumVariant = pEnumVariant;
  261. RRETURN_EXP_IF_ERR(hr);
  262. }
  263. // This method only returns one element at a time even if more
  264. // than one element is asked for, of course pcElmentFetched is
  265. // returned as one.
  266. STDMETHODIMP
  267. CAccCtrlListEnum::Next(
  268. ULONG cElements,
  269. VARIANT FAR* pvar,
  270. ULONG FAR* pcElementFetched
  271. )
  272. {
  273. HRESULT hr = S_FALSE;
  274. DWORD dwAceCount = 0;
  275. IADsAccessControlEntry *pAce = NULL;
  276. IDispatch *pDispatch = NULL;
  277. PVARIANT pThisVar = pvar;
  278. if (pcElementFetched) {
  279. *pcElementFetched = 0;
  280. }
  281. if (_pACL == NULL) {
  282. RRETURN(hr = S_FALSE);
  283. }
  284. // Will get the ace count each time so that changes in the
  285. // ACL do not affect the enum object
  286. //
  287. // ** Changes in ACL does affect the enum object. We should still get
  288. // AceCount and check if _curElement within bounds as defensive
  289. // programming - especially since current model does not add critical
  290. // section protection on the enumerator for multi-threaded model.
  291. //
  292. hr = _pACL->get_AceCount((long *)&dwAceCount);
  293. BAIL_ON_FAILURE(hr);
  294. if (dwAceCount == 0) {
  295. hr = S_FALSE;
  296. RRETURN(hr);
  297. }
  298. //
  299. // valid dwAceCount here (See **)
  300. //
  301. if (_curElement < dwAceCount) {
  302. // bump up the curElement as we start at 0
  303. _curElement++;
  304. // get the corresponding acl pointer and QI it
  305. hr = _pACL->GetElement(_curElement, &pAce);
  306. BAIL_ON_FAILURE(hr);
  307. if (hr != S_FALSE) {
  308. hr = pAce->QueryInterface(
  309. IID_IDispatch,
  310. (void **)&pDispatch
  311. );
  312. BAIL_ON_FAILURE(hr);
  313. V_DISPATCH(pThisVar) = pDispatch;
  314. V_VT(pThisVar) = VT_DISPATCH;
  315. if (pcElementFetched) {
  316. *pcElementFetched = 1;
  317. }
  318. } else {
  319. RRETURN_EXP_IF_ERR(hr);
  320. }
  321. } else {
  322. // In this case, we need to set hr to S_FALSE
  323. // as we have returned all the aces.
  324. hr = S_FALSE;
  325. }
  326. RRETURN(hr);
  327. error:
  328. // if the disp pointer is valid then need to release on ACE
  329. if (pDispatch) {
  330. pAce->Release();
  331. }
  332. RRETURN(hr);
  333. }
  334. BOOL
  335. CAccCtrlListEnum::
  336. DecrementCurElement(
  337. )
  338. {
  339. if (_pACL && _curElement>=1) {
  340. _curElement--;
  341. return TRUE;
  342. } else { // !pACL || _curElement ==0
  343. //
  344. // do not decrement _curElement since lower bound limit on curElement
  345. // is 0.
  346. //
  347. return FALSE;
  348. }
  349. }
  350. BOOL
  351. CAccCtrlListEnum::
  352. IncrementCurElement(
  353. )
  354. {
  355. HRESULT hr = E_FAIL;
  356. DWORD dwAceCount;
  357. if (!_pACL)
  358. return FALSE;
  359. hr = _pACL->get_AceCount((long *)&dwAceCount);
  360. if (FAILED(hr)) {
  361. return FALSE;
  362. }
  363. if (_curElement>=dwAceCount-1) {
  364. //
  365. // do not increment _curElement since upper bound limit on curElement
  366. // already reached; upperbound limit is actually dwAceCount-1 since
  367. // Next() increment _curElement by 1 before calling
  368. // GetElement(_curElement). See Next() for details.
  369. //
  370. return FALSE;
  371. }
  372. _curElement++;
  373. return TRUE;
  374. }
  375. DWORD
  376. CAccCtrlListEnum::
  377. GetCurElement(
  378. )
  379. {
  380. return _curElement;
  381. }