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.

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