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.

624 lines
13 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cenumdom.cxx
  7. //
  8. // Contents: NDS Object Enumeration Code
  9. //
  10. // CNDSGenObjectEnum::CNDSGenObjectEnum()
  11. // CNDSGenObjectEnum::CNDSGenObjectEnum
  12. // CNDSGenObjectEnum::EnumObjects
  13. // CNDSGenObjectEnum::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. CNDSGenObjectEnum::Create(
  37. CNDSGenObjectEnum FAR* FAR* ppenumvariant,
  38. BSTR ADsPath,
  39. VARIANT var,
  40. CCredentials& Credentials
  41. )
  42. {
  43. HRESULT hr = S_OK;
  44. CNDSGenObjectEnum FAR* penumvariant = NULL;
  45. if (!ppenumvariant) {
  46. RRETURN(E_FAIL);
  47. }
  48. *ppenumvariant = NULL;
  49. penumvariant = new CNDSGenObjectEnum();
  50. if (!penumvariant) {
  51. hr = E_OUTOFMEMORY;
  52. BAIL_ON_FAILURE(hr);
  53. }
  54. hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath);
  55. BAIL_ON_FAILURE(hr);
  56. hr = BuildNDSFilterArray(
  57. var,
  58. (LPBYTE *)&penumvariant->_pNdsFilterList
  59. );
  60. if (FAILED(hr)) {
  61. penumvariant->_pNdsFilterList = NULL;
  62. }
  63. /*
  64. hr = ObjectTypeList::CreateObjectTypeList(
  65. var,
  66. &penumvariant->_pObjList
  67. );
  68. BAIL_ON_FAILURE(hr);
  69. */
  70. penumvariant->_Credentials = Credentials;
  71. hr = BuildNDSPathFromADsPath2(
  72. ADsPath,
  73. &penumvariant->_pszTreeName,
  74. &penumvariant->_pszDn
  75. );
  76. BAIL_ON_FAILURE(hr);
  77. hr = ADsNdsOpenContext(
  78. penumvariant->_pszTreeName,
  79. Credentials,
  80. &penumvariant->_hADsContext
  81. );
  82. *ppenumvariant = penumvariant;
  83. RRETURN(hr);
  84. error:
  85. if (penumvariant) {
  86. delete penumvariant;
  87. *ppenumvariant = NULL;
  88. }
  89. RRETURN(hr);
  90. }
  91. CNDSGenObjectEnum::CNDSGenObjectEnum():
  92. _ADsPath(NULL), _pszTreeName(NULL), _pszDn(NULL)
  93. {
  94. _pObjList = NULL;
  95. _dwObjectReturned = 0;
  96. _dwObjectCurrentEntry = 0;
  97. _hOperationData = NULL;
  98. _lpObjects = NULL;
  99. _pNdsFilterList = NULL;
  100. _bNoMore = FALSE;
  101. }
  102. CNDSGenObjectEnum::~CNDSGenObjectEnum()
  103. {
  104. if (_ADsPath) {
  105. ADsFreeString(_ADsPath);
  106. }
  107. if (_pszTreeName) {
  108. FreeADsStr(_pszTreeName);
  109. }
  110. if (_pszDn) {
  111. FreeADsStr(_pszDn);
  112. }
  113. if (_pNdsFilterList) {
  114. FreeFilterList((LPBYTE)_pNdsFilterList);
  115. }
  116. if (_hADsContext) {
  117. ADsNdsCloseContext(_hADsContext);
  118. }
  119. ADsNdsFreeNdsObjInfoList(_lpObjects, _dwObjectReturned);
  120. }
  121. HRESULT
  122. CNDSGenObjectEnum::EnumObjects(
  123. DWORD ObjectType,
  124. ULONG cElements,
  125. VARIANT FAR * pvar,
  126. ULONG FAR * pcElementFetched
  127. )
  128. {
  129. //
  130. // Multi-level detection of Objects may not be necessary for NDS code
  131. //
  132. RRETURN(EnumGenericObjects(cElements, pvar, pcElementFetched));
  133. //
  134. // BugBug- commenting out this layer of code
  135. //
  136. /*
  137. switch (ObjectType) {
  138. default:
  139. RRETURN(EnumObjects(cElements, pvar, pcElementFetched));
  140. } */
  141. }
  142. HRESULT
  143. CNDSGenObjectEnum::EnumObjects(
  144. ULONG cElements,
  145. VARIANT FAR* pvar,
  146. ULONG FAR* pcElementFetched
  147. )
  148. {
  149. DWORD i;
  150. ULONG cRequested = 0;
  151. ULONG cFetchedByPath = 0;
  152. ULONG cTotalFetched = 0;
  153. VARIANT FAR* pPathvar = pvar;
  154. HRESULT hr;
  155. DWORD ObjectType;
  156. for (i = 0; i < cElements; i++) {
  157. VariantInit(&pvar[i]);
  158. }
  159. cRequested = cElements;
  160. while (SUCCEEDED(_pObjList->GetCurrentObject(&ObjectType)) &&
  161. ((hr = EnumObjects(ObjectType,
  162. cRequested,
  163. pPathvar,
  164. &cFetchedByPath)) == S_FALSE )) {
  165. pPathvar += cFetchedByPath;
  166. cRequested -= cFetchedByPath;
  167. cTotalFetched += cFetchedByPath;
  168. cFetchedByPath = 0;
  169. if (FAILED(_pObjList->Next())){
  170. if (pcElementFetched)
  171. *pcElementFetched = cTotalFetched;
  172. RRETURN(S_FALSE);
  173. }
  174. }
  175. if (pcElementFetched) {
  176. *pcElementFetched = cTotalFetched + cFetchedByPath;
  177. }
  178. RRETURN(hr);
  179. }
  180. HRESULT
  181. CNDSGenObjectEnum::EnumGenericObjects(
  182. ULONG cElements,
  183. VARIANT FAR* pvar,
  184. ULONG FAR* pcElementFetched
  185. )
  186. {
  187. HRESULT hr = S_OK;
  188. IDispatch *pDispatch = NULL;
  189. DWORD i = 0;
  190. while (i < cElements ) {
  191. hr = GetGenObject(&pDispatch);
  192. if (FAILED(hr)) {
  193. continue;
  194. }
  195. if (hr == S_FALSE) {
  196. break;
  197. }
  198. VariantInit(&pvar[i]);
  199. pvar[i].vt = VT_DISPATCH;
  200. pvar[i].pdispVal = pDispatch;
  201. (*pcElementFetched)++;
  202. i++;
  203. }
  204. return(hr);
  205. }
  206. HRESULT
  207. CNDSGenObjectEnum::GetGenObject(
  208. IDispatch ** ppDispatch
  209. )
  210. {
  211. HRESULT hr = S_OK;
  212. PADSNDS_OBJECT_INFO lpCurrentObject = NULL;
  213. IADs * pADs = NULL;
  214. *ppDispatch = NULL;
  215. if (!_hOperationData || (_dwObjectCurrentEntry == _dwObjectReturned)) {
  216. if (_hOperationData) {
  217. ADsNdsFreeNdsObjInfoList(_lpObjects, _dwObjectReturned);
  218. _lpObjects = NULL;
  219. }
  220. _dwObjectCurrentEntry = 0;
  221. _dwObjectReturned = 0;
  222. if (_bNoMore) {
  223. hr = S_FALSE;
  224. goto error;
  225. }
  226. hr = ADsNdsListObjects(
  227. _hADsContext,
  228. _pszDn,
  229. L"",
  230. L"",
  231. NULL,
  232. FALSE,
  233. &_hOperationData
  234. );
  235. BAIL_ON_FAILURE(hr);
  236. if (hr == S_ADS_NOMORE_ROWS) {
  237. _bNoMore = TRUE;
  238. }
  239. hr = ADsNdsGetObjectListFromBuffer(
  240. _hADsContext,
  241. _hOperationData,
  242. &_dwObjectReturned,
  243. &_lpObjects
  244. );
  245. BAIL_ON_FAILURE(hr);
  246. if (_dwObjectReturned == 0 ) {
  247. RRETURN (S_FALSE);
  248. goto error;
  249. }
  250. }
  251. //
  252. // Now send back the current object
  253. //
  254. lpCurrentObject = _lpObjects + _dwObjectCurrentEntry;
  255. //
  256. // Bump up the object count. The instantiation of this object
  257. // may fail; if we come into this function again, we do not want
  258. // to pick up the same object.
  259. //
  260. _dwObjectCurrentEntry++;
  261. hr = CNDSGenObject::CreateGenericObject(
  262. _ADsPath,
  263. lpCurrentObject->szObjectName,
  264. lpCurrentObject->szObjectClass,
  265. _Credentials,
  266. ADS_OBJECT_BOUND,
  267. IID_IADs,
  268. (void **)&pADs
  269. );
  270. BAIL_ON_FAILURE(hr);
  271. //
  272. // InstantiateDerivedObject should addref this pointer for us.
  273. //
  274. hr = InstantiateDerivedObject(
  275. pADs,
  276. _Credentials,
  277. IID_IDispatch,
  278. (void **)ppDispatch
  279. );
  280. if (FAILED(hr)) {
  281. hr = pADs->QueryInterface(
  282. IID_IDispatch,
  283. (void **)ppDispatch
  284. );
  285. BAIL_ON_FAILURE(hr);
  286. }
  287. error:
  288. if (hr == S_FALSE) {
  289. ADsNdsFreeBuffer(_hOperationData);
  290. _hOperationData = NULL;
  291. }
  292. //
  293. // Free the intermediate pADs pointer.
  294. //
  295. if (pADs) {
  296. pADs->Release();
  297. }
  298. RRETURN(hr);
  299. }
  300. //+---------------------------------------------------------------------------
  301. //
  302. // Function: CNDSGenObjectEnum::Next
  303. //
  304. // Synopsis: Returns cElements number of requested NetOle objects in the
  305. // array supplied in pvar.
  306. //
  307. // Arguments: [cElements] -- The number of elements requested by client
  308. // [pvar] -- ptr to array of VARIANTs to for return objects
  309. // [pcElementFetched] -- if non-NULL, then number of elements
  310. // -- actually returned is placed here
  311. //
  312. // Returns: HRESULT -- S_OK if number of elements requested are returned
  313. // -- S_FALSE if number of elements is < requested
  314. //
  315. // Modifies:
  316. //
  317. // History: 11-3-95 krishnag Created.
  318. //
  319. //----------------------------------------------------------------------------
  320. STDMETHODIMP
  321. CNDSGenObjectEnum::Next(
  322. ULONG cElements,
  323. VARIANT FAR* pvar,
  324. ULONG FAR* pcElementFetched
  325. )
  326. {
  327. ULONG cElementFetched = 0;
  328. HRESULT hr = S_OK;
  329. hr = EnumGenericObjects(
  330. cElements,
  331. pvar,
  332. &cElementFetched
  333. );
  334. if (pcElementFetched) {
  335. *pcElementFetched = cElementFetched;
  336. }
  337. RRETURN(hr);
  338. }
  339. HRESULT
  340. BuildNDSFilterArray(
  341. VARIANT var,
  342. LPBYTE * ppContigFilter
  343. )
  344. {
  345. LONG uDestCount = 0;
  346. LONG dwSLBound = 0;
  347. LONG dwSUBound = 0;
  348. VARIANT v;
  349. LONG i;
  350. HRESULT hr = S_OK;
  351. LPNDS_FILTER_LIST pNdsFilterList = NULL;
  352. LPBYTE pContigFilter = NULL;
  353. if(!((V_VT(&var) & VT_VARIANT) && V_ISARRAY(&var))) {
  354. RRETURN(E_FAIL);
  355. }
  356. //
  357. // Check that there is only one dimension in this array
  358. //
  359. if ((V_ARRAY(&var))->cDims != 1) {
  360. hr = E_FAIL;
  361. BAIL_ON_FAILURE(hr);
  362. }
  363. //
  364. // Check that there is atleast one element in this array
  365. //
  366. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  367. hr = E_FAIL;
  368. BAIL_ON_FAILURE(hr);
  369. }
  370. //
  371. // We know that this is a valid single dimension array
  372. //
  373. hr = SafeArrayGetLBound(V_ARRAY(&var),
  374. 1,
  375. (long FAR *)&dwSLBound
  376. );
  377. BAIL_ON_FAILURE(hr);
  378. hr = SafeArrayGetUBound(V_ARRAY(&var),
  379. 1,
  380. (long FAR *)&dwSUBound
  381. );
  382. BAIL_ON_FAILURE(hr);
  383. pContigFilter = (LPBYTE)AllocADsMem(
  384. sizeof(NDS_FILTER_LIST)
  385. - sizeof(NDS_FILTER)
  386. );
  387. if (!pContigFilter) {
  388. hr = E_FAIL;
  389. BAIL_ON_FAILURE(hr);
  390. }
  391. for (i = dwSLBound; i <= dwSUBound; i++) {
  392. VariantInit(&v);
  393. hr = SafeArrayGetElement(V_ARRAY(&var),
  394. (long FAR *)&i,
  395. &v
  396. );
  397. if (FAILED(hr)) {
  398. continue;
  399. }
  400. //
  401. // Create an entry in the filter block
  402. // Append it to the existing block
  403. //
  404. pContigFilter = CreateAndAppendFilterEntry(
  405. pContigFilter,
  406. V_BSTR(&v)
  407. );
  408. VariantClear(&v);
  409. if (!pContigFilter) {
  410. hr = E_FAIL;
  411. BAIL_ON_FAILURE(hr);
  412. }
  413. }
  414. pNdsFilterList = (LPNDS_FILTER_LIST)pContigFilter;
  415. if (!pNdsFilterList->dwNumberOfFilters){
  416. hr = E_FAIL;
  417. BAIL_ON_FAILURE(hr);
  418. }
  419. *ppContigFilter = pContigFilter;
  420. RRETURN(S_OK);
  421. error:
  422. if (pContigFilter){
  423. FreeFilterList(
  424. pContigFilter
  425. );
  426. }
  427. *ppContigFilter = NULL;
  428. RRETURN(hr);
  429. }
  430. LPBYTE
  431. CreateAndAppendFilterEntry(
  432. LPBYTE pContigFilter,
  433. LPWSTR lpObjectClass
  434. )
  435. {
  436. LPWSTR pszFilter = NULL;
  437. LPNDS_FILTER_LIST pNdsFilterList = NULL;
  438. DWORD dwFilterCount = 0;
  439. LPBYTE pNewContigFilter = NULL;
  440. LPNDS_FILTER pNewEntry = NULL;
  441. pszFilter = (LPWSTR)AllocADsStr(lpObjectClass);
  442. if (!pszFilter) {
  443. return(pContigFilter);
  444. }
  445. pNdsFilterList = (LPNDS_FILTER_LIST)pContigFilter;
  446. dwFilterCount = pNdsFilterList->dwNumberOfFilters;
  447. pNewContigFilter = (LPBYTE)ReallocADsMem(
  448. pContigFilter,
  449. sizeof(NDS_FILTER_LIST) +
  450. (dwFilterCount - 1)* sizeof(NDS_FILTER),
  451. sizeof(NDS_FILTER_LIST)
  452. + dwFilterCount * sizeof(NDS_FILTER)
  453. );
  454. if (!pNewContigFilter) {
  455. return(pContigFilter);
  456. }
  457. pNewEntry = (LPNDS_FILTER)(pNewContigFilter + sizeof(NDS_FILTER_LIST)
  458. + (dwFilterCount - 1)* sizeof(NDS_FILTER));
  459. pNewEntry->szObjectClass = pszFilter;
  460. pNdsFilterList = (LPNDS_FILTER_LIST)pNewContigFilter;
  461. pNdsFilterList->dwNumberOfFilters = dwFilterCount + 1;
  462. return(pNewContigFilter);
  463. }
  464. void
  465. FreeFilterList(
  466. LPBYTE lpContigFilter
  467. )
  468. {
  469. LPNDS_FILTER_LIST lpNdsFilterList = (LPNDS_FILTER_LIST)lpContigFilter;
  470. DWORD dwNumFilters = 0;
  471. LPNDS_FILTER lpNdsFilter = NULL;
  472. DWORD i = 0;
  473. dwNumFilters = lpNdsFilterList->dwNumberOfFilters;
  474. if (dwNumFilters){
  475. lpNdsFilter = (LPNDS_FILTER)(lpContigFilter + sizeof(NDS_FILTER_LIST)
  476. - sizeof(NDS_FILTER));
  477. for (i = 0; i < dwNumFilters; i++) {
  478. FreeADsStr((lpNdsFilter + i)->szObjectClass);
  479. }
  480. }
  481. FreeADsMem(lpContigFilter);
  482. }