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.

552 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. SecureZeroMemory(pszPassword, wcslen(pszPassword)*sizeof(WCHAR));
  244. FreeADsStr(pszPassword);
  245. }
  246. if (FAILED(hr)) {
  247. hr = S_FALSE;
  248. }
  249. RRETURN(hr);
  250. }
  251. HRESULT
  252. CNDSGroupCollectionEnum::GetGroupSingleMemberObject(
  253. IDispatch ** ppDispatch
  254. )
  255. {
  256. HRESULT hr = S_OK;
  257. WCHAR szADsPathName[MAX_PATH];
  258. WCHAR szNDSTreeName[MAX_PATH];
  259. LPWSTR pszUserName = NULL;
  260. LPWSTR pszPassword = NULL;
  261. *ppDispatch = NULL;
  262. if (_dwIndex == 1) {
  263. RRETURN(S_FALSE);
  264. }
  265. hr = BuildNDSTreeNameFromADsPath(
  266. _bstrGroupName,
  267. szNDSTreeName
  268. );
  269. BAIL_ON_FAILURE(hr);
  270. // Make the first two characters "//" instead of "\\"
  271. szNDSTreeName[0] = (WCHAR)'/';
  272. szNDSTreeName[1] = (WCHAR)'/';
  273. hr = BuildADsPathFromNDSPath(
  274. szNDSTreeName,
  275. _vMembers.bstrVal,
  276. szADsPathName
  277. );
  278. BAIL_ON_FAILURE(hr);
  279. hr = _Credentials.GetUserName(&pszUserName);
  280. BAIL_ON_FAILURE(hr);
  281. hr = _Credentials.GetPassword(&pszPassword);
  282. BAIL_ON_FAILURE(hr);
  283. hr = ADsOpenObject(
  284. szADsPathName,
  285. pszUserName,
  286. pszPassword,
  287. _Credentials.GetAuthFlags(),
  288. IID_IDispatch,
  289. (void **)ppDispatch
  290. );
  291. BAIL_ON_FAILURE(hr);
  292. _dwIndex++;
  293. error:
  294. if (pszUserName) {
  295. FreeADsStr(pszUserName);
  296. }
  297. if (pszPassword) {
  298. SecureZeroMemory(pszPassword, wcslen(pszPassword)*sizeof(WCHAR));
  299. FreeADsStr(pszPassword);
  300. }
  301. if (FAILED(hr)) {
  302. hr = S_FALSE;
  303. }
  304. RRETURN(hr);
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // Function: CNDSGroupCollectionEnum::Next
  309. //
  310. // Synopsis: Returns cElements number of requested NetOle objects in the
  311. // array supplied in pvar.
  312. //
  313. // Arguments: [cElements] -- The number of elements requested by client
  314. // [pvar] -- ptr to array of VARIANTs to for return objects
  315. // [pcElementFetched] -- if non-NULL, then number of elements
  316. // -- actually returned is placed here
  317. //
  318. // Returns: HRESULT -- S_OK if number of elements requested are returned
  319. // -- S_FALSE if number of elements is < requested
  320. //
  321. // Modifies:
  322. //
  323. // History: 11-3-95 krishnag Created.
  324. //
  325. //----------------------------------------------------------------------------
  326. STDMETHODIMP
  327. CNDSGroupCollectionEnum::Next(
  328. ULONG cElements,
  329. VARIANT FAR* pvar,
  330. ULONG FAR* pcElementFetched
  331. )
  332. {
  333. ULONG cElementFetched = 0;
  334. HRESULT hr = S_OK;
  335. hr = EnumGroupMembers(
  336. cElements,
  337. pvar,
  338. &cElementFetched
  339. );
  340. if (pcElementFetched) {
  341. *pcElementFetched = cElementFetched;
  342. }
  343. RRETURN_EXP_IF_ERR(hr);
  344. }
  345. HRESULT
  346. CNDSGroupCollectionEnum::ValidateVariant(
  347. VARIANT var
  348. )
  349. {
  350. if (V_VT(&var) == (VT_VARIANT|VT_ARRAY)) {
  351. _dwMultiple = MULTIPLE;
  352. RRETURN(ValidateMultipleVariant(var));
  353. }else if (V_VT(&var) == VT_BSTR){
  354. _dwMultiple = SINGLE;
  355. RRETURN(ValidateSingleVariant(var));
  356. }else if (V_VT(&var) == VT_EMPTY){
  357. _dwMultiple = EMPTY;
  358. RRETURN(S_OK);
  359. }
  360. RRETURN(E_FAIL);
  361. }
  362. HRESULT
  363. CNDSGroupCollectionEnum::ValidateMultipleVariant(
  364. VARIANT var
  365. )
  366. {
  367. HRESULT hr = S_OK;
  368. DWORD dwSLBound = 0;
  369. DWORD dwSUBound = 0;
  370. if (!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) {
  371. return(E_FAIL);
  372. }
  373. //
  374. // Check that there is only one dimension in this array
  375. //
  376. if ((V_ARRAY(&var))->cDims != 1) {
  377. hr = E_FAIL;
  378. BAIL_ON_FAILURE(hr);
  379. }
  380. //
  381. // Check that there is atleast one element in this array
  382. //
  383. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  384. hr = E_FAIL;
  385. BAIL_ON_FAILURE(hr);
  386. }
  387. //
  388. // We know that this is a valid single dimension array
  389. //
  390. hr = SafeArrayGetLBound(
  391. V_ARRAY(&var),
  392. 1,
  393. (long FAR *)&dwSLBound
  394. );
  395. BAIL_ON_FAILURE(hr);
  396. hr = SafeArrayGetUBound(
  397. V_ARRAY(&var),
  398. 1,
  399. (long FAR *)&dwSUBound
  400. );
  401. BAIL_ON_FAILURE(hr);
  402. hr = VariantCopy(&_vMembers, &var);
  403. BAIL_ON_FAILURE(hr);
  404. _dwSUBound = dwSUBound;
  405. _dwSLBound = dwSLBound;
  406. _dwIndex = dwSLBound;
  407. error:
  408. RRETURN(hr);
  409. }
  410. HRESULT
  411. CNDSGroupCollectionEnum::ValidateSingleVariant(
  412. VARIANT var
  413. )
  414. {
  415. HRESULT hr = S_OK;
  416. if(!( V_VT(&var) == VT_BSTR)){
  417. return(E_FAIL);
  418. }
  419. hr = VariantCopy(&_vMembers, &var);
  420. BAIL_ON_FAILURE(hr);
  421. _dwIndex = 0;
  422. error:
  423. RRETURN(hr);
  424. }