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.

550 lines
12 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cenumGroupCollection.cxx
  7. //
  8. // Contents: Windows NT 3.5 GroupCollection Enumeration Code
  9. //
  10. // CNDSGroupCollectionEnum::CNDSGroupCollectionEnum()
  11. // CNDSGroupCollectionEnum::CNDSGroupCollectionEnum
  12. // CNDSGroupCollectionEnum::EnumObjects
  13. // CNDSGroupCollectionEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "NDS.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CNDSEnumVariant::Create
  22. //
  23. // Synopsis:
  24. //
  25. // Arguments: [pCollection]
  26. // [ppEnumVariant]
  27. //
  28. // Returns: HRESULT
  29. //
  30. // Modifies:
  31. //
  32. // History: 01-30-95 krishnag Created.
  33. //
  34. //----------------------------------------------------------------------------
  35. HRESULT
  36. CNDSGroupCollectionEnum::Create(
  37. BSTR bstrGroupName,
  38. CCredentials& Credentials,
  39. CNDSGroupCollectionEnum FAR* FAR* ppenumvariant,
  40. VARIANT var,
  41. VARIANT varFilter
  42. )
  43. {
  44. HRESULT hr = NOERROR;
  45. CNDSGroupCollectionEnum FAR* penumvariant = NULL;
  46. *ppenumvariant = NULL;
  47. penumvariant = new CNDSGroupCollectionEnum();
  48. if (!penumvariant) {
  49. hr = E_OUTOFMEMORY;
  50. BAIL_ON_FAILURE(hr);
  51. }
  52. hr = ADsAllocString(bstrGroupName, &(penumvariant->_bstrGroupName));
  53. BAIL_ON_FAILURE(hr);
  54. hr = penumvariant->ValidateVariant(
  55. var
  56. );
  57. BAIL_ON_FAILURE(hr);
  58. penumvariant->_Credentials = Credentials;
  59. hr = ObjectTypeList::CreateObjectTypeList(
  60. varFilter,
  61. &penumvariant->_pObjList
  62. );
  63. BAIL_ON_FAILURE(hr);
  64. *ppenumvariant = penumvariant;
  65. RRETURN(hr);
  66. error:
  67. delete penumvariant;
  68. RRETURN_EXP_IF_ERR(hr);
  69. }
  70. CNDSGroupCollectionEnum::CNDSGroupCollectionEnum():
  71. _dwSLBound(0),
  72. _dwSUBound(0),
  73. _dwIndex(0),
  74. _dwMultiple(0),
  75. _bstrGroupName(0),
  76. _pObjList(NULL)
  77. {
  78. VariantInit(&_vMembers);
  79. }
  80. CNDSGroupCollectionEnum::~CNDSGroupCollectionEnum()
  81. {
  82. VariantClear(&_vMembers);
  83. if (_bstrGroupName) {
  84. ADsFreeString(_bstrGroupName);
  85. }
  86. if (_pObjList) {
  87. delete _pObjList;
  88. }
  89. }
  90. HRESULT
  91. CNDSGroupCollectionEnum::EnumGroupMembers(
  92. ULONG cElements,
  93. VARIANT FAR* pvar,
  94. ULONG FAR* pcElementFetched
  95. )
  96. {
  97. HRESULT hr = S_OK;
  98. IDispatch *pDispatch = NULL;
  99. DWORD i = 0;
  100. IADs * pIADs = NULL;
  101. BSTR pszClass = NULL;
  102. DWORD dwClassID;
  103. DWORD dwFilterID;
  104. BOOL fFound = FALSE;
  105. *pcElementFetched = 0;
  106. while (i < cElements) {
  107. if (_dwMultiple == MULTIPLE) {
  108. hr = GetGroupMultipleMemberObject(&pDispatch);
  109. }else if (_dwMultiple == SINGLE){
  110. hr = GetGroupSingleMemberObject(&pDispatch);
  111. }else {
  112. hr = S_FALSE;
  113. }
  114. if (hr == S_FALSE) {
  115. break;
  116. }
  117. //
  118. // Apply the IADsMembers::put_Filter filter.
  119. // If the enumerated object is not one of the types to be returned,
  120. // go on to the next member of the group.
  121. //
  122. hr = pDispatch->QueryInterface(IID_IADs, (void **)&pIADs);
  123. BAIL_ON_FAILURE(hr);
  124. //
  125. // Determine the object class of the enumerated object and the corresponding
  126. // object class ID number (as specified in the Filters global array).
  127. //
  128. hr = pIADs->get_Class(&pszClass);
  129. BAIL_ON_FAILURE(hr);
  130. hr = IsValidFilter(pszClass, &dwClassID, gpFilters, gdwMaxFilters);
  131. if (SUCCEEDED(hr)) {
  132. //
  133. // Enumerate through the object classes listed in the user-specified filter
  134. // until we either find a match (fFound = TRUE) or we reach the end of the
  135. // list.
  136. //
  137. hr = _pObjList->Reset();
  138. while (SUCCEEDED(hr)) {
  139. hr = _pObjList->GetCurrentObject(&dwFilterID);
  140. if (SUCCEEDED(hr)
  141. && (dwFilterID == dwClassID)
  142. ) {
  143. fFound = TRUE;
  144. break;
  145. }
  146. hr = _pObjList->Next();
  147. }
  148. if (!fFound) {
  149. //
  150. // not on the list of objects to return, try again
  151. // with the next member of the group
  152. //
  153. pDispatch->Release();
  154. pIADs->Release();
  155. if (pszClass) {
  156. ADsFreeString(pszClass);
  157. }
  158. continue;
  159. }
  160. }
  161. pIADs->Release();
  162. if (pszClass) {
  163. ADsFreeString(pszClass);
  164. }
  165. //
  166. // Return it.
  167. //
  168. VariantInit(&pvar[i]);
  169. pvar[i].vt = VT_DISPATCH;
  170. pvar[i].pdispVal = pDispatch;
  171. (*pcElementFetched)++;
  172. i++;
  173. }
  174. RRETURN_EXP_IF_ERR(hr);
  175. error:
  176. if (pDispatch) {
  177. pDispatch->Release();
  178. }
  179. if (pIADs) {
  180. pIADs->Release();
  181. }
  182. if (pszClass) {
  183. ADsFreeString(pszClass);
  184. }
  185. RRETURN_EXP_IF_ERR(hr);
  186. }
  187. HRESULT
  188. CNDSGroupCollectionEnum::GetGroupMultipleMemberObject(
  189. IDispatch ** ppDispatch
  190. )
  191. {
  192. VARIANT v;
  193. HRESULT hr = S_OK;
  194. WCHAR szADsPathName[MAX_PATH];
  195. WCHAR szNDSTreeName[MAX_PATH];
  196. LPWSTR pszUserName = NULL;
  197. LPWSTR pszPassword = NULL;
  198. *ppDispatch = NULL;
  199. if (_dwIndex > _dwSUBound) {
  200. RRETURN(S_FALSE);
  201. }
  202. VariantInit(&v);
  203. hr = SafeArrayGetElement(
  204. V_ARRAY(&_vMembers),
  205. (long FAR *)&_dwIndex,
  206. &v
  207. );
  208. BAIL_ON_FAILURE(hr);
  209. hr = BuildNDSTreeNameFromADsPath(
  210. _bstrGroupName,
  211. szNDSTreeName
  212. );
  213. BAIL_ON_FAILURE(hr);
  214. // Make the first two characters "//" instead of "\\"
  215. szNDSTreeName[0] = (WCHAR)'/';
  216. szNDSTreeName[1] = (WCHAR)'/';
  217. hr = BuildADsPathFromNDSPath(
  218. szNDSTreeName,
  219. v.bstrVal,
  220. szADsPathName
  221. );
  222. BAIL_ON_FAILURE(hr);
  223. hr = _Credentials.GetUserName(&pszUserName);
  224. BAIL_ON_FAILURE(hr);
  225. hr = _Credentials.GetPassword(&pszPassword);
  226. BAIL_ON_FAILURE(hr);
  227. hr = ADsOpenObject(
  228. szADsPathName,
  229. pszUserName,
  230. pszPassword,
  231. _Credentials.GetAuthFlags(),
  232. IID_IDispatch,
  233. (void **)ppDispatch
  234. );
  235. BAIL_ON_FAILURE(hr);
  236. _dwIndex++;
  237. error:
  238. VariantClear(&v);
  239. if (pszUserName) {
  240. FreeADsStr(pszUserName);
  241. }
  242. if (pszPassword) {
  243. FreeADsStr(pszPassword);
  244. }
  245. if (FAILED(hr)) {
  246. hr = S_FALSE;
  247. }
  248. RRETURN(hr);
  249. }
  250. HRESULT
  251. CNDSGroupCollectionEnum::GetGroupSingleMemberObject(
  252. IDispatch ** ppDispatch
  253. )
  254. {
  255. HRESULT hr = S_OK;
  256. WCHAR szADsPathName[MAX_PATH];
  257. WCHAR szNDSTreeName[MAX_PATH];
  258. LPWSTR pszUserName = NULL;
  259. LPWSTR pszPassword = NULL;
  260. *ppDispatch = NULL;
  261. if (_dwIndex == 1) {
  262. RRETURN(S_FALSE);
  263. }
  264. hr = BuildNDSTreeNameFromADsPath(
  265. _bstrGroupName,
  266. szNDSTreeName
  267. );
  268. BAIL_ON_FAILURE(hr);
  269. // Make the first two characters "//" instead of "\\"
  270. szNDSTreeName[0] = (WCHAR)'/';
  271. szNDSTreeName[1] = (WCHAR)'/';
  272. hr = BuildADsPathFromNDSPath(
  273. szNDSTreeName,
  274. _vMembers.bstrVal,
  275. szADsPathName
  276. );
  277. BAIL_ON_FAILURE(hr);
  278. hr = _Credentials.GetUserName(&pszUserName);
  279. BAIL_ON_FAILURE(hr);
  280. hr = _Credentials.GetPassword(&pszPassword);
  281. BAIL_ON_FAILURE(hr);
  282. hr = ADsOpenObject(
  283. szADsPathName,
  284. pszUserName,
  285. pszPassword,
  286. _Credentials.GetAuthFlags(),
  287. IID_IDispatch,
  288. (void **)ppDispatch
  289. );
  290. BAIL_ON_FAILURE(hr);
  291. _dwIndex++;
  292. error:
  293. if (pszUserName) {
  294. FreeADsStr(pszUserName);
  295. }
  296. if (pszPassword) {
  297. FreeADsStr(pszPassword);
  298. }
  299. if (FAILED(hr)) {
  300. hr = S_FALSE;
  301. }
  302. RRETURN(hr);
  303. }
  304. //+---------------------------------------------------------------------------
  305. //
  306. // Function: CNDSGroupCollectionEnum::Next
  307. //
  308. // Synopsis: Returns cElements number of requested NetOle objects in the
  309. // array supplied in pvar.
  310. //
  311. // Arguments: [cElements] -- The number of elements requested by client
  312. // [pvar] -- ptr to array of VARIANTs to for return objects
  313. // [pcElementFetched] -- if non-NULL, then number of elements
  314. // -- actually returned is placed here
  315. //
  316. // Returns: HRESULT -- S_OK if number of elements requested are returned
  317. // -- S_FALSE if number of elements is < requested
  318. //
  319. // Modifies:
  320. //
  321. // History: 11-3-95 krishnag Created.
  322. //
  323. //----------------------------------------------------------------------------
  324. STDMETHODIMP
  325. CNDSGroupCollectionEnum::Next(
  326. ULONG cElements,
  327. VARIANT FAR* pvar,
  328. ULONG FAR* pcElementFetched
  329. )
  330. {
  331. ULONG cElementFetched = 0;
  332. HRESULT hr = S_OK;
  333. hr = EnumGroupMembers(
  334. cElements,
  335. pvar,
  336. &cElementFetched
  337. );
  338. if (pcElementFetched) {
  339. *pcElementFetched = cElementFetched;
  340. }
  341. RRETURN_EXP_IF_ERR(hr);
  342. }
  343. HRESULT
  344. CNDSGroupCollectionEnum::ValidateVariant(
  345. VARIANT var
  346. )
  347. {
  348. if (V_VT(&var) == (VT_VARIANT|VT_ARRAY)) {
  349. _dwMultiple = MULTIPLE;
  350. RRETURN(ValidateMultipleVariant(var));
  351. }else if (V_VT(&var) == VT_BSTR){
  352. _dwMultiple = SINGLE;
  353. RRETURN(ValidateSingleVariant(var));
  354. }else if (V_VT(&var) == VT_EMPTY){
  355. _dwMultiple = EMPTY;
  356. RRETURN(S_OK);
  357. }
  358. RRETURN(E_FAIL);
  359. }
  360. HRESULT
  361. CNDSGroupCollectionEnum::ValidateMultipleVariant(
  362. VARIANT var
  363. )
  364. {
  365. HRESULT hr = S_OK;
  366. DWORD dwSLBound = 0;
  367. DWORD dwSUBound = 0;
  368. if (!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) {
  369. return(E_FAIL);
  370. }
  371. //
  372. // Check that there is only one dimension in this array
  373. //
  374. if ((V_ARRAY(&var))->cDims != 1) {
  375. hr = E_FAIL;
  376. BAIL_ON_FAILURE(hr);
  377. }
  378. //
  379. // Check that there is atleast one element in this array
  380. //
  381. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  382. hr = E_FAIL;
  383. BAIL_ON_FAILURE(hr);
  384. }
  385. //
  386. // We know that this is a valid single dimension array
  387. //
  388. hr = SafeArrayGetLBound(
  389. V_ARRAY(&var),
  390. 1,
  391. (long FAR *)&dwSLBound
  392. );
  393. BAIL_ON_FAILURE(hr);
  394. hr = SafeArrayGetUBound(
  395. V_ARRAY(&var),
  396. 1,
  397. (long FAR *)&dwSUBound
  398. );
  399. BAIL_ON_FAILURE(hr);
  400. hr = VariantCopy(&_vMembers, &var);
  401. BAIL_ON_FAILURE(hr);
  402. _dwSUBound = dwSUBound;
  403. _dwSLBound = dwSLBound;
  404. _dwIndex = dwSLBound;
  405. error:
  406. RRETURN(hr);
  407. }
  408. HRESULT
  409. CNDSGroupCollectionEnum::ValidateSingleVariant(
  410. VARIANT var
  411. )
  412. {
  413. HRESULT hr = S_OK;
  414. if(!( V_VT(&var) == VT_BSTR)){
  415. return(E_FAIL);
  416. }
  417. hr = VariantCopy(&_vMembers, &var);
  418. BAIL_ON_FAILURE(hr);
  419. _dwIndex = 0;
  420. error:
  421. RRETURN(hr);
  422. }