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.

372 lines
8.6 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cenumsch.cxx
  7. //
  8. // Contents: NDS Class Enumeration Code
  9. //
  10. // CNDSClassEnum::CNDSClassEnum()
  11. // CNDSClassEnum::CNDSClassEnum
  12. // CNDSClassEnum::EnumObjects
  13. // CNDSClassEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "NDS.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CNDSClassEnum::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. CNDSClassEnum::Create(
  37. CNDSClassEnum FAR* FAR* ppenumvariant,
  38. BSTR bstrADsPath,
  39. BSTR bstrName,
  40. VARIANT var,
  41. CCredentials& Credentials
  42. )
  43. {
  44. HRESULT hr = S_OK;
  45. CNDSClassEnum FAR* penumvariant = NULL;
  46. LPWSTR pszDn = NULL;
  47. if (!ppenumvariant) {
  48. RRETURN(E_FAIL);
  49. }
  50. *ppenumvariant = NULL;
  51. penumvariant = new CNDSClassEnum();
  52. if (!penumvariant)
  53. {
  54. hr = E_OUTOFMEMORY;
  55. BAIL_ON_FAILURE(hr);
  56. }
  57. hr = BuildNDSPathFromADsPath2(
  58. bstrADsPath,
  59. &penumvariant->_pszNDSTreeName,
  60. &pszDn
  61. );
  62. BAIL_ON_FAILURE(hr);
  63. hr = ADsNdsOpenContext(
  64. penumvariant->_pszNDSTreeName,
  65. Credentials,
  66. &penumvariant->_hADsContext
  67. );
  68. BAIL_ON_FAILURE(hr);
  69. hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
  70. BAIL_ON_FAILURE(hr);
  71. hr = ADsAllocString( bstrName, &penumvariant->_bstrName);
  72. BAIL_ON_FAILURE(hr);
  73. hr = ObjectTypeList::CreateObjectTypeList(
  74. var,
  75. &penumvariant->_pObjList );
  76. BAIL_ON_FAILURE(hr);
  77. penumvariant->_Credentials = Credentials;
  78. *ppenumvariant = penumvariant;
  79. RRETURN(hr);
  80. error:
  81. delete penumvariant;
  82. RRETURN(hr);
  83. }
  84. CNDSClassEnum::CNDSClassEnum()
  85. : _bstrADsPath( NULL ),
  86. _bstrName( NULL ),
  87. _pszNDSTreeName( NULL ),
  88. _pObjList( NULL ),
  89. _dwCurrentEntry( 0 ),
  90. _pPropNameList( NULL),
  91. _pCurrentEntry( NULL ),
  92. _bNoMore(FALSE)
  93. {
  94. _hOperationData = NULL;
  95. _hADsContext = NULL;
  96. _lpClassDefs = NULL;
  97. _dwObjectCurrentEntry = 0;
  98. _dwObjectReturned = 0;
  99. _dwInfoType = DS_EXPANDED_CLASS_DEFS;
  100. }
  101. CNDSClassEnum::~CNDSClassEnum()
  102. {
  103. ADsFreeString( _bstrName );
  104. ADsFreeString( _bstrADsPath );
  105. ADsFreeString( _pszNDSTreeName );
  106. ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned);
  107. ADsNdsFreeBuffer(_hOperationData);
  108. if (_hADsContext) {
  109. ADsNdsCloseContext(_hADsContext);
  110. }
  111. if ( _pObjList != NULL )
  112. {
  113. delete _pObjList;
  114. _pObjList = NULL;
  115. }
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Function: CNDSClassEnum::Next
  120. //
  121. // Synopsis: Returns cElements number of requested NetOle objects in the
  122. // array supplied in pvar.
  123. //
  124. // Arguments: [cElements] -- The number of elements requested by client
  125. // [pvar] -- ptr to array of VARIANTs to for return objects
  126. // [pcElementFetched] -- if non-NULL, then number of elements
  127. // -- actually returned is placed here
  128. //
  129. // Returns: HRESULT -- S_OK if number of elements requested are returned
  130. // -- S_FALSE if number of elements is < requested
  131. //
  132. // Modifies:
  133. //
  134. // History: 11-3-95 yihsins Created.
  135. //
  136. //----------------------------------------------------------------------------
  137. STDMETHODIMP
  138. CNDSClassEnum::Next(
  139. ULONG cElements,
  140. VARIANT FAR* pvar,
  141. ULONG FAR* pcElementFetched
  142. )
  143. {
  144. ULONG cElementFetched = 0;
  145. HRESULT hr = S_OK;
  146. hr = EnumProperties(
  147. cElements,
  148. pvar,
  149. &cElementFetched
  150. );
  151. if ( pcElementFetched )
  152. *pcElementFetched = cElementFetched;
  153. RRETURN(hr);
  154. }
  155. HRESULT
  156. CNDSClassEnum::EnumObjects(
  157. DWORD ObjectType,
  158. ULONG cElements,
  159. VARIANT FAR * pvar,
  160. ULONG FAR * pcElementFetched
  161. )
  162. {
  163. switch (ObjectType)
  164. {
  165. case NDS_PROPERTY_ID:
  166. RRETURN (EnumProperties(cElements, pvar, pcElementFetched));
  167. default:
  168. RRETURN(S_FALSE);
  169. }
  170. }
  171. HRESULT
  172. CNDSClassEnum::EnumObjects(
  173. ULONG cElements,
  174. VARIANT FAR* pvar,
  175. ULONG FAR* pcElementFetched
  176. )
  177. {
  178. DWORD i;
  179. ULONG cRequested = 0;
  180. ULONG cFetchedByPath = 0;
  181. ULONG cTotalFetched = 0;
  182. VARIANT FAR* pPathvar = pvar;
  183. HRESULT hr = S_OK;
  184. DWORD ObjectType;
  185. for (i = 0; i < cElements; i++)
  186. VariantInit(&pvar[i]);
  187. cRequested = cElements;
  188. while ( SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
  189. && ((hr = EnumObjects( ObjectType,
  190. cRequested,
  191. pPathvar,
  192. &cFetchedByPath)) == S_FALSE )
  193. )
  194. {
  195. pPathvar += cFetchedByPath;
  196. cRequested -= cFetchedByPath;
  197. cTotalFetched += cFetchedByPath;
  198. cFetchedByPath = 0;
  199. if ( FAILED(_pObjList->Next()) )
  200. {
  201. if ( pcElementFetched )
  202. *pcElementFetched = cTotalFetched;
  203. RRETURN(S_FALSE);
  204. }
  205. _dwCurrentEntry = 0;
  206. }
  207. if ( pcElementFetched )
  208. *pcElementFetched = cTotalFetched + cFetchedByPath;
  209. RRETURN(hr);
  210. }
  211. HRESULT
  212. CNDSClassEnum::EnumProperties(
  213. ULONG cElements,
  214. VARIANT FAR* pvar,
  215. ULONG FAR* pcElementFetched
  216. )
  217. {
  218. HRESULT hr = S_OK;
  219. DWORD i = 0;
  220. IDispatch *pDispatch = NULL;
  221. while ( i < cElements )
  222. {
  223. hr = GetPropertyObject(&pDispatch);
  224. if ( hr == S_FALSE )
  225. break;
  226. VariantInit( &pvar[i] );
  227. pvar[i].vt = VT_DISPATCH;
  228. pvar[i].pdispVal = pDispatch;
  229. (*pcElementFetched)++;
  230. i++;
  231. }
  232. RRETURN(hr);
  233. }
  234. HRESULT
  235. CNDSClassEnum::GetPropertyObject(
  236. IDispatch ** ppDispatch
  237. )
  238. {
  239. HRESULT hr = S_OK;
  240. PNDS_CLASS_DEF lpCurrentObject = NULL;
  241. *ppDispatch = NULL;
  242. if (!_hOperationData || (_dwObjectCurrentEntry == _dwObjectReturned)) {
  243. _dwObjectCurrentEntry = 0;
  244. _dwObjectReturned = 0;
  245. if (_hOperationData) {
  246. ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned);
  247. _lpClassDefs = NULL;
  248. }
  249. if (_bNoMore) {
  250. hr = S_FALSE;
  251. goto error;
  252. }
  253. hr = ADsNdsReadClassDef(
  254. _hADsContext,
  255. DS_EXPANDED_CLASS_DEFS,
  256. &_bstrName,
  257. (DWORD) 1,
  258. &_hOperationData
  259. );
  260. BAIL_ON_FAILURE(hr);
  261. if (hr == S_ADS_NOMORE_ROWS) {
  262. _bNoMore = TRUE;
  263. }
  264. hr = ADsNdsGetClassDefListFromBuffer(
  265. _hADsContext,
  266. _hOperationData,
  267. &_dwObjectReturned,
  268. &_dwInfoType,
  269. &_lpClassDefs
  270. );
  271. BAIL_ON_FAILURE(hr);
  272. if (_dwObjectReturned == 0 ) {
  273. RRETURN (S_FALSE);
  274. goto error;
  275. }
  276. //
  277. // Assert to check that we returned only 1 object
  278. //
  279. ADsAssert(_dwObjectReturned == 1);
  280. _pPropNameList = GeneratePropertyList(
  281. _lpClassDefs->lpMandatoryAttributes,
  282. _lpClassDefs->lpOptionalAttributes
  283. );
  284. if (!_pPropNameList) {
  285. hr = HRESULT_FROM_WIN32(GetLastError());
  286. BAIL_ON_FAILURE(hr);
  287. }
  288. _pCurrentEntry = _pPropNameList;
  289. }
  290. if (_pCurrentEntry) {
  291. //
  292. // Now send back the current object
  293. //
  294. hr = CNDSProperty::CreateProperty(
  295. _bstrADsPath,
  296. _pCurrentEntry->pszPropName,
  297. _hOperationData,
  298. _Credentials,
  299. ADS_OBJECT_BOUND,
  300. IID_IDispatch,
  301. (void **)ppDispatch
  302. );
  303. BAIL_ON_FAILURE(hr);
  304. _pCurrentEntry = _pCurrentEntry->pNext;
  305. RRETURN(S_OK);
  306. }
  307. error:
  308. RRETURN(S_FALSE);
  309. }