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.

346 lines
7.5 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cenumUserCollection.cxx
  7. //
  8. // Contents: Windows NT 3.5 UserCollection Enumeration Code
  9. //
  10. // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum()
  11. // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum
  12. // CLDAPUserCollectionEnum::EnumObjects
  13. // CLDAPUserCollectionEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "ldap.hxx"
  18. #pragma hdrstop
  19. HRESULT
  20. BuildADsPathFromLDAPPath(
  21. LPWSTR szNamespace,
  22. LPWSTR szLdapDN,
  23. LPWSTR * ppszADsPathName
  24. );
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: CLDAPEnumVariant::Create
  28. //
  29. // Synopsis:
  30. //
  31. // Arguments: [pCollection]
  32. // [ppEnumVariant]
  33. //
  34. // Returns: HRESULT
  35. //
  36. // Modifies:
  37. //
  38. // History: 01-30-95 krishnag Created.
  39. //
  40. //----------------------------------------------------------------------------
  41. HRESULT
  42. CLDAPUserCollectionEnum::Create(
  43. BSTR bstrUserName,
  44. CLDAPUserCollectionEnum FAR* FAR* ppenumvariant,
  45. VARIANT var,
  46. CCredentials& Credentials
  47. )
  48. {
  49. HRESULT hr = NOERROR;
  50. CLDAPUserCollectionEnum FAR* penumvariant = NULL;
  51. DWORD dwSLBound = 0;
  52. DWORD dwSUBound = 0;
  53. if ( V_VT(&var) == VT_BSTR )
  54. {
  55. dwSLBound = 0;
  56. dwSUBound = 0;
  57. }
  58. else
  59. {
  60. if(!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) {
  61. return(E_FAIL);
  62. }
  63. //
  64. // Check that there is only one dimension in this array
  65. //
  66. if ((V_ARRAY(&var))->cDims != 1) {
  67. hr = E_FAIL;
  68. BAIL_ON_FAILURE(hr);
  69. }
  70. //
  71. // We know that this is a valid single dimension array
  72. //
  73. hr = SafeArrayGetLBound(
  74. V_ARRAY(&var),
  75. 1,
  76. (long FAR *)&dwSLBound
  77. );
  78. BAIL_ON_FAILURE(hr);
  79. hr = SafeArrayGetUBound(
  80. V_ARRAY(&var),
  81. 1,
  82. (long FAR *)&dwSUBound
  83. );
  84. BAIL_ON_FAILURE(hr);
  85. }
  86. *ppenumvariant = NULL;
  87. penumvariant = new CLDAPUserCollectionEnum();
  88. if (!penumvariant) {
  89. hr = E_OUTOFMEMORY;
  90. BAIL_ON_FAILURE(hr);
  91. }
  92. hr = ADsAllocString(bstrUserName, &(penumvariant->_bstrUserName));
  93. BAIL_ON_FAILURE(hr);
  94. hr = VariantCopy(&(penumvariant->_vMembers), &var);
  95. BAIL_ON_FAILURE(hr);
  96. penumvariant->_dwSUBound = dwSUBound;
  97. penumvariant->_dwSLBound = dwSLBound;
  98. penumvariant->_dwIndex = dwSLBound;
  99. penumvariant->_Credentials = Credentials;
  100. *ppenumvariant = penumvariant;
  101. RRETURN(hr);
  102. error:
  103. delete penumvariant;
  104. RRETURN_EXP_IF_ERR(hr);
  105. }
  106. CLDAPUserCollectionEnum::CLDAPUserCollectionEnum():
  107. _dwSLBound(0),
  108. _dwSUBound(0),
  109. _dwIndex(0),
  110. _bstrUserName(NULL)
  111. {
  112. VariantInit(&_vMembers);
  113. }
  114. CLDAPUserCollectionEnum::~CLDAPUserCollectionEnum()
  115. {
  116. VariantClear(&_vMembers);
  117. if ( _bstrUserName )
  118. ADsFreeString( _bstrUserName );
  119. }
  120. HRESULT
  121. CLDAPUserCollectionEnum::EnumUserMembers(
  122. ULONG cElements,
  123. VARIANT FAR* pvar,
  124. ULONG FAR* pcElementFetched
  125. )
  126. {
  127. HRESULT hr = S_OK;
  128. IDispatch *pDispatch = NULL;
  129. DWORD i = 0;
  130. while (i < cElements) {
  131. hr = GetUserMemberObject(&pDispatch);
  132. if (FAILED(hr)) {
  133. //
  134. // Enumerators support code can only handle S_FALSE and S_OK,
  135. // so we cannot return other failure hr's for now.
  136. //
  137. hr = S_FALSE;
  138. }
  139. if (hr == S_FALSE) {
  140. break;
  141. }
  142. VariantInit(&pvar[i]);
  143. pvar[i].vt = VT_DISPATCH;
  144. pvar[i].pdispVal = pDispatch;
  145. (*pcElementFetched)++;
  146. i++;
  147. }
  148. RRETURN_EXP_IF_ERR(hr);
  149. }
  150. HRESULT
  151. CLDAPUserCollectionEnum::GetUserMemberObject(
  152. IDispatch ** ppDispatch
  153. )
  154. {
  155. VARIANT v;
  156. HRESULT hr = S_OK;
  157. TCHAR *pszADsPathName = NULL;
  158. IUnknown *pObject = NULL;
  159. LPWSTR pszUserName = NULL;
  160. LPWSTR pszPassword = NULL;
  161. DWORD dwAuthFlags = 0;
  162. hr = _Credentials.GetUserName(&pszUserName);
  163. BAIL_ON_FAILURE(hr);
  164. hr = _Credentials.GetPassword(&pszPassword);
  165. BAIL_ON_FAILURE(hr);
  166. dwAuthFlags = _Credentials.GetAuthFlags();
  167. *ppDispatch = NULL;
  168. if (_dwIndex > _dwSUBound) {
  169. RRETURN(S_FALSE);
  170. }
  171. while ( TRUE )
  172. {
  173. VariantInit(&v);
  174. if ( _vMembers.vt == VT_BSTR )
  175. {
  176. hr = VariantCopy( &v, &_vMembers );
  177. }
  178. else
  179. {
  180. hr = SafeArrayGetElement(
  181. V_ARRAY(&_vMembers),
  182. (long FAR *)&_dwIndex,
  183. &v
  184. );
  185. }
  186. BAIL_ON_FAILURE(hr);
  187. _dwIndex++;
  188. hr = BuildADsPathFromLDAPPath( _bstrUserName,
  189. V_BSTR(&v),
  190. &pszADsPathName);
  191. BAIL_ON_FAILURE(hr);
  192. hr = ADsOpenObject(
  193. pszADsPathName,
  194. pszUserName,
  195. pszPassword,
  196. dwAuthFlags,
  197. IID_IUnknown,
  198. (LPVOID *)&pObject
  199. );
  200. if ( pszADsPathName )
  201. {
  202. FreeADsStr( pszADsPathName );
  203. pszADsPathName = NULL;
  204. }
  205. if (pszPassword) {
  206. FreeADsStr(pszPassword);
  207. pszPassword = NULL;
  208. }
  209. if (pszUserName) {
  210. FreeADsStr(pszUserName);
  211. pszUserName = NULL;
  212. }
  213. VariantClear(&v);
  214. //
  215. // If we failed to get the current object, continue with the next one
  216. //
  217. if ( FAILED(hr))
  218. continue;
  219. hr = pObject->QueryInterface( IID_IDispatch, (LPVOID *) ppDispatch );
  220. BAIL_ON_FAILURE(hr);
  221. pObject->Release();
  222. RRETURN(S_OK);
  223. }
  224. error:
  225. if ( pObject )
  226. pObject->Release();
  227. if ( pszADsPathName )
  228. FreeADsStr( pszADsPathName );
  229. if (pszPassword) {
  230. FreeADsStr(pszPassword);
  231. }
  232. if (pszUserName) {
  233. FreeADsStr(pszUserName);
  234. }
  235. VariantClear(&v);
  236. *ppDispatch = NULL;
  237. RRETURN(S_FALSE);
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Function: CLDAPUserCollectionEnum::Next
  242. //
  243. // Synopsis: Returns cElements number of requested NetOle objects in the
  244. // array supplied in pvar.
  245. //
  246. // Arguments: [cElements] -- The number of elements requested by client
  247. // [pvar] -- ptr to array of VARIANTs to for return objects
  248. // [pcElementFetched] -- if non-NULL, then number of elements
  249. // -- actually returned is placed here
  250. //
  251. // Returns: HRESULT -- S_OK if number of elements requested are returned
  252. // -- S_FALSE if number of elements is < requested
  253. //
  254. // Modifies:
  255. //
  256. // History: 11-3-95 krishnag Created.
  257. //
  258. //----------------------------------------------------------------------------
  259. STDMETHODIMP
  260. CLDAPUserCollectionEnum::Next(
  261. ULONG cElements,
  262. VARIANT FAR* pvar,
  263. ULONG FAR* pcElementFetched
  264. )
  265. {
  266. ULONG cElementFetched = 0;
  267. HRESULT hr = S_OK;
  268. hr = EnumUserMembers(
  269. cElements,
  270. pvar,
  271. &cElementFetched
  272. );
  273. if (pcElementFetched) {
  274. *pcElementFetched = cElementFetched;
  275. }
  276. RRETURN_EXP_IF_ERR(hr);
  277. }
  278.