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: cenumsch.cxx
  7. //
  8. // Contents: NDS Schema Enumeration Code
  9. //
  10. // CNDSSchemaEnum::CNDSSchemaEnum()
  11. // CNDSSchemaEnum::CNDSSchemaEnum
  12. // CNDSSchemaEnum::EnumObjects
  13. // CNDSSchemaEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "NDS.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CNDSSchemaEnum::Create
  22. //
  23. // Synopsis:
  24. //
  25. // Arguments: [pCollection]
  26. // [ppEnumVariant]
  27. //
  28. // Returns: HRESULT
  29. //
  30. // Modifies:
  31. //
  32. // History: 01-30-95 yihsins Created.
  33. //
  34. //----------------------------------------------------------------------------
  35. HRESULT
  36. CNDSSchemaEnum::Create(
  37. CNDSSchemaEnum FAR* FAR* ppenumvariant,
  38. BSTR bstrNDSTreeName,
  39. BSTR bstrADsPath,
  40. BSTR bstrName,
  41. VARIANT var,
  42. CCredentials& Credentials
  43. )
  44. {
  45. HRESULT hr = S_OK;
  46. CNDSSchemaEnum FAR* penumvariant = NULL;
  47. *ppenumvariant = NULL;
  48. penumvariant = new CNDSSchemaEnum();
  49. if (!penumvariant)
  50. {
  51. hr = E_OUTOFMEMORY;
  52. BAIL_ON_FAILURE(hr);
  53. }
  54. hr = ADsAllocString( bstrNDSTreeName, &penumvariant->_bstrNDSTreeName);
  55. BAIL_ON_FAILURE(hr);
  56. hr = ADsNdsOpenContext(
  57. penumvariant->_bstrNDSTreeName,
  58. Credentials,
  59. &penumvariant->_hADsContext
  60. );
  61. BAIL_ON_FAILURE(hr);
  62. hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
  63. BAIL_ON_FAILURE(hr);
  64. hr = ADsAllocString( bstrName, &penumvariant->_bstrName);
  65. BAIL_ON_FAILURE(hr);
  66. hr = ObjectTypeList::CreateObjectTypeList(
  67. var,
  68. &penumvariant->_pObjList
  69. );
  70. BAIL_ON_FAILURE(hr);
  71. penumvariant->_Credentials = Credentials;
  72. *ppenumvariant = penumvariant;
  73. RRETURN(hr);
  74. error:
  75. delete penumvariant;
  76. RRETURN(hr);
  77. }
  78. CNDSSchemaEnum::CNDSSchemaEnum()
  79. : _bstrADsPath( NULL ),
  80. _bstrName( NULL ),
  81. _bstrNDSTreeName( NULL ),
  82. _pObjList( NULL ),
  83. _dwCurrentEntry( 0 ),
  84. _dwSyntaxCurrentEntry( 0 )
  85. {
  86. _hOperationData = NULL;
  87. _hADsContext = NULL;
  88. _lpClassDefs = NULL;
  89. _dwObjectCurrentEntry = 0;
  90. _dwObjectReturned = 0;
  91. _dwInfoType = 0;
  92. _dwPropCurrentEntry = 0;
  93. _hPropOperationData = NULL;
  94. _lpAttrDefs = NULL;
  95. _dwPropObjectCurrentEntry = 0;
  96. _dwPropObjectReturned = 0;
  97. _dwPropInfoType = 0;
  98. _bNoMore = FALSE;
  99. _bNoMoreProp = FALSE;
  100. }
  101. CNDSSchemaEnum::~CNDSSchemaEnum()
  102. {
  103. ADsFreeString( _bstrName );
  104. ADsFreeString( _bstrADsPath );
  105. ADsFreeString( _bstrNDSTreeName );
  106. ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned);
  107. ADsNdsFreeAttrDefList(_lpAttrDefs, _dwPropObjectReturned);
  108. ADsNdsFreeBuffer( _hOperationData );
  109. ADsNdsFreeBuffer( _hPropOperationData );
  110. if (_hADsContext) {
  111. ADsNdsCloseContext(_hADsContext);
  112. }
  113. if ( _pObjList != NULL )
  114. {
  115. delete _pObjList;
  116. _pObjList = NULL;
  117. }
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Function: CNDSSchemaEnum::Next
  122. //
  123. // Synopsis: Returns cElements number of requested NetOle objects in the
  124. // array supplied in pvar.
  125. //
  126. // Arguments: [cElements] -- The number of elements requested by client
  127. // [pvar] -- ptr to array of VARIANTs to for return objects
  128. // [pcElementFetched] -- if non-NULL, then number of elements
  129. // -- actually returned is placed here
  130. //
  131. // Returns: HRESULT -- S_OK if number of elements requested are returned
  132. // -- S_FALSE if number of elements is < requested
  133. //
  134. // Modifies:
  135. //
  136. // History: 11-3-95 yihsins Created.
  137. //
  138. //----------------------------------------------------------------------------
  139. STDMETHODIMP
  140. CNDSSchemaEnum::Next(
  141. ULONG cElements,
  142. VARIANT FAR* pvar,
  143. ULONG FAR* pcElementFetched
  144. )
  145. {
  146. ULONG cElementFetched = 0;
  147. HRESULT hr = S_OK;
  148. hr = EnumObjects(
  149. cElements,
  150. pvar,
  151. &cElementFetched
  152. );
  153. if ( pcElementFetched )
  154. *pcElementFetched = cElementFetched;
  155. RRETURN(hr);
  156. }
  157. HRESULT
  158. CNDSSchemaEnum::EnumObjects(
  159. DWORD ObjectType,
  160. ULONG cElements,
  161. VARIANT FAR * pvar,
  162. ULONG FAR * pcElementFetched
  163. )
  164. {
  165. switch (ObjectType)
  166. {
  167. case NDS_CLASS_ID:
  168. RRETURN (EnumClasses(cElements, pvar, pcElementFetched));
  169. case NDS_PROPERTY_ID:
  170. RRETURN (EnumProperties(cElements, pvar, pcElementFetched));
  171. case NDS_SYNTAX_ID:
  172. RRETURN(EnumSyntaxes(cElements, pvar, pcElementFetched));
  173. default:
  174. RRETURN(S_FALSE);
  175. }
  176. }
  177. HRESULT
  178. CNDSSchemaEnum::EnumObjects(
  179. ULONG cElements,
  180. VARIANT FAR* pvar,
  181. ULONG FAR* pcElementFetched
  182. )
  183. {
  184. DWORD i;
  185. ULONG cRequested = 0;
  186. ULONG cFetchedByPath = 0;
  187. ULONG cTotalFetched = 0;
  188. VARIANT FAR* pPathvar = pvar;
  189. HRESULT hr = S_OK;
  190. DWORD ObjectType;
  191. for (i = 0; i < cElements; i++)
  192. VariantInit(&pvar[i]);
  193. cRequested = cElements;
  194. while ( SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
  195. && ((hr = EnumObjects( ObjectType,
  196. cRequested,
  197. pPathvar,
  198. &cFetchedByPath)) == S_FALSE )
  199. )
  200. {
  201. pPathvar += cFetchedByPath;
  202. cRequested -= cFetchedByPath;
  203. cTotalFetched += cFetchedByPath;
  204. cFetchedByPath = 0;
  205. if ( FAILED(_pObjList->Next()) )
  206. {
  207. if ( pcElementFetched )
  208. *pcElementFetched = cTotalFetched;
  209. RRETURN(S_FALSE);
  210. }
  211. _dwCurrentEntry = 0;
  212. }
  213. if ( pcElementFetched )
  214. *pcElementFetched = cTotalFetched + cFetchedByPath;
  215. RRETURN(hr);
  216. }
  217. HRESULT
  218. CNDSSchemaEnum::EnumClasses(
  219. ULONG cElements,
  220. VARIANT FAR* pvar,
  221. ULONG FAR* pcElementFetched
  222. )
  223. {
  224. HRESULT hr = S_OK;
  225. DWORD i = 0;
  226. IDispatch *pDispatch = NULL;
  227. while ( i < cElements )
  228. {
  229. hr = GetClassObject(&pDispatch);
  230. if ( hr == S_FALSE )
  231. break;
  232. VariantInit( &pvar[i] );
  233. pvar[i].vt = VT_DISPATCH;
  234. pvar[i].pdispVal = pDispatch;
  235. (*pcElementFetched)++;
  236. i++;
  237. }
  238. RRETURN(hr);
  239. }
  240. HRESULT
  241. CNDSSchemaEnum::GetClassObject(
  242. IDispatch ** ppDispatch
  243. )
  244. {
  245. HRESULT hr = S_OK;
  246. PNDS_CLASS_DEF lpCurrentObject = NULL;
  247. if (!_hOperationData || (_dwObjectCurrentEntry == _dwObjectReturned)) {
  248. _dwObjectCurrentEntry = 0;
  249. _dwObjectReturned = 0;
  250. if (_hOperationData) {
  251. ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned);
  252. _lpClassDefs = NULL;
  253. }
  254. if (_bNoMore) {
  255. hr = S_FALSE;
  256. goto error;
  257. }
  258. hr = ADsNdsReadClassDef(
  259. _hADsContext,
  260. DS_CLASS_DEFS,
  261. NULL,
  262. (DWORD) -1,
  263. &_hOperationData
  264. );
  265. BAIL_ON_FAILURE(hr);
  266. if (hr == S_ADS_NOMORE_ROWS) {
  267. _bNoMore = TRUE;
  268. }
  269. hr = ADsNdsGetClassDefListFromBuffer(
  270. _hADsContext,
  271. _hOperationData,
  272. &_dwObjectReturned,
  273. &_dwInfoType,
  274. &_lpClassDefs
  275. );
  276. BAIL_ON_FAILURE(hr);
  277. if (_dwObjectReturned == 0 ) {
  278. RRETURN (S_FALSE);
  279. goto error;
  280. }
  281. }
  282. if (_dwObjectCurrentEntry < _dwObjectReturned) {
  283. //
  284. // Now send back the current object
  285. //
  286. lpCurrentObject = _lpClassDefs + _dwObjectCurrentEntry;
  287. hr = CNDSClass::CreateClass(
  288. _bstrADsPath,
  289. lpCurrentObject->szClassName,
  290. lpCurrentObject,
  291. _Credentials,
  292. ADS_OBJECT_BOUND,
  293. IID_IDispatch,
  294. (void **)ppDispatch
  295. );
  296. BAIL_ON_FAILURE(hr);
  297. _dwObjectCurrentEntry++;
  298. RRETURN(S_OK);
  299. }
  300. error:
  301. *ppDispatch = NULL;
  302. RRETURN(S_FALSE);
  303. }
  304. HRESULT
  305. CNDSSchemaEnum::EnumProperties(
  306. ULONG cElements,
  307. VARIANT FAR* pvar,
  308. ULONG FAR* pcElementFetched
  309. )
  310. {
  311. HRESULT hr = S_OK;
  312. DWORD i = 0;
  313. IDispatch *pDispatch = NULL;
  314. while ( i < cElements )
  315. {
  316. hr = GetPropertyObject(&pDispatch);
  317. if ( hr == S_FALSE )
  318. break;
  319. VariantInit( &pvar[i] );
  320. pvar[i].vt = VT_DISPATCH;
  321. pvar[i].pdispVal = pDispatch;
  322. (*pcElementFetched)++;
  323. i++;
  324. }
  325. RRETURN(hr);
  326. }
  327. HRESULT
  328. CNDSSchemaEnum::GetPropertyObject(
  329. IDispatch ** ppDispatch
  330. )
  331. {
  332. HRESULT hr = S_OK;
  333. LPNDS_ATTR_DEF lpCurrentPropObject = NULL;
  334. DWORD dwStatus;
  335. if (!_hPropOperationData || (_dwPropObjectCurrentEntry == _dwPropObjectReturned)) {
  336. _dwPropObjectCurrentEntry = 0;
  337. _dwPropObjectReturned = 0;
  338. if (_hPropOperationData) {
  339. ADsNdsFreeAttrDefList(_lpAttrDefs, _dwPropObjectReturned);
  340. _lpAttrDefs = NULL;
  341. }
  342. if (_bNoMoreProp) {
  343. hr = S_FALSE;
  344. goto error;
  345. }
  346. hr = ADsNdsReadAttrDef(
  347. _hADsContext,
  348. DS_ATTR_DEFS,
  349. NULL,
  350. (DWORD) -1,
  351. &_hPropOperationData
  352. );
  353. BAIL_ON_FAILURE(hr);
  354. if (hr == S_ADS_NOMORE_COLUMNS) {
  355. _bNoMoreProp = TRUE;
  356. }
  357. hr = ADsNdsGetAttrDefListFromBuffer(
  358. _hADsContext,
  359. _hPropOperationData,
  360. &_dwPropObjectReturned,
  361. &_dwInfoType,
  362. &_lpAttrDefs
  363. );
  364. BAIL_ON_FAILURE(hr);
  365. if (_dwPropObjectReturned == 0 ) {
  366. RRETURN (S_FALSE);
  367. goto error;
  368. }
  369. }
  370. if (_dwPropObjectCurrentEntry < _dwPropObjectReturned) {
  371. //
  372. // Now send back the current object
  373. //
  374. lpCurrentPropObject = _lpAttrDefs + _dwPropObjectCurrentEntry;
  375. hr = CNDSProperty::CreateProperty(
  376. _bstrADsPath,
  377. lpCurrentPropObject->szAttributeName,
  378. lpCurrentPropObject,
  379. _Credentials,
  380. ADS_OBJECT_BOUND,
  381. IID_IDispatch,
  382. (void **)ppDispatch
  383. );
  384. BAIL_ON_FAILURE(hr);
  385. _dwPropObjectCurrentEntry++;
  386. RRETURN(S_OK);
  387. }
  388. error:
  389. *ppDispatch = NULL;
  390. RRETURN(S_FALSE);
  391. }
  392. HRESULT
  393. CNDSSchemaEnum::EnumSyntaxes(
  394. ULONG cElements,
  395. VARIANT FAR* pvar,
  396. ULONG FAR* pcElementFetched
  397. )
  398. {
  399. HRESULT hr = S_OK;
  400. DWORD i = 0;
  401. IDispatch *pDispatch = NULL;
  402. while ( i < cElements )
  403. {
  404. hr = GetSyntaxObject(&pDispatch);
  405. if ( hr == S_FALSE )
  406. break;
  407. VariantInit( &pvar[i] );
  408. pvar[i].vt = VT_DISPATCH;
  409. pvar[i].pdispVal = pDispatch;
  410. (*pcElementFetched)++;
  411. i++;
  412. }
  413. RRETURN(hr);
  414. }
  415. HRESULT
  416. CNDSSchemaEnum::GetSyntaxObject(
  417. IDispatch ** ppDispatch
  418. )
  419. {
  420. HRESULT hr = S_OK;
  421. //
  422. // Now send back the current object
  423. //
  424. if ( _dwSyntaxCurrentEntry >= g_cNDSSyntax )
  425. goto error;
  426. hr = CNDSSyntax::CreateSyntax(
  427. _bstrADsPath,
  428. &g_aNDSSyntax[_dwSyntaxCurrentEntry],
  429. ADS_OBJECT_BOUND,
  430. IID_IDispatch,
  431. (void **)ppDispatch
  432. );
  433. BAIL_ON_FAILURE(hr);
  434. _dwSyntaxCurrentEntry++;
  435. RRETURN(S_OK);
  436. error:
  437. *ppDispatch = NULL;
  438. RRETURN(S_FALSE);
  439. }