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.

384 lines
9.1 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. WCHAR szNDSTreeName[MAX_PATH];
  47. WCHAR szObjectFullName[MAX_PATH];
  48. WCHAR szObjectClassName[MAX_PATH];
  49. DWORD dwModificationTime = 0L;
  50. DWORD dwNumberOfEntries = 0L;
  51. DWORD dwStatus = 0L;
  52. *ppenumvariant = NULL;
  53. penumvariant = new CNDSClassEnum();
  54. if (!penumvariant)
  55. {
  56. hr = E_OUTOFMEMORY;
  57. BAIL_ON_FAILURE(hr);
  58. }
  59. hr = BuildNDSTreeNameFromADsPath(
  60. bstrADsPath,
  61. szNDSTreeName
  62. );
  63. BAIL_ON_FAILURE(hr);
  64. hr = ADsAllocString( szNDSTreeName, &penumvariant->_bstrNDSTreeName);
  65. BAIL_ON_FAILURE(hr);
  66. dwStatus = ADsNwNdsOpenObject(
  67. penumvariant->_bstrNDSTreeName,
  68. Credentials,
  69. &penumvariant->_hTree,
  70. szObjectFullName,
  71. szObjectClassName,
  72. &dwModificationTime,
  73. &dwNumberOfEntries
  74. );
  75. if (dwStatus) {
  76. hr = HRESULT_FROM_WIN32(GetLastError());
  77. BAIL_ON_FAILURE(hr);
  78. }
  79. hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
  80. BAIL_ON_FAILURE(hr);
  81. hr = ADsAllocString( bstrName, &penumvariant->_bstrName);
  82. BAIL_ON_FAILURE(hr);
  83. hr = ObjectTypeList::CreateObjectTypeList(
  84. var,
  85. &penumvariant->_pObjList );
  86. BAIL_ON_FAILURE(hr);
  87. penumvariant->_Credentials = Credentials;
  88. *ppenumvariant = penumvariant;
  89. RRETURN(hr);
  90. error:
  91. delete penumvariant;
  92. RRETURN_EXP_IF_ERR(hr);
  93. }
  94. CNDSClassEnum::CNDSClassEnum()
  95. : _bstrADsPath( NULL ),
  96. _bstrName( NULL ),
  97. _bstrNDSTreeName( NULL ),
  98. _pObjList( NULL ),
  99. _dwCurrentEntry( 0 ),
  100. _pPropNameList( NULL),
  101. _pCurrentEntry( NULL )
  102. {
  103. _hOperationData = NULL;
  104. _hTree = NULL;
  105. _lpClassDefs = NULL;
  106. _dwObjectCurrentEntry = 0;
  107. _dwObjectReturned = 0;
  108. _dwInfoType = 0;
  109. }
  110. CNDSClassEnum::~CNDSClassEnum()
  111. {
  112. ADsFreeString( _bstrName );
  113. ADsFreeString( _bstrADsPath );
  114. ADsFreeString( _bstrNDSTreeName );
  115. if ( _pObjList != NULL )
  116. {
  117. delete _pObjList;
  118. _pObjList = NULL;
  119. }
  120. }
  121. //+---------------------------------------------------------------------------
  122. //
  123. // Function: CNDSClassEnum::Next
  124. //
  125. // Synopsis: Returns cElements number of requested NetOle objects in the
  126. // array supplied in pvar.
  127. //
  128. // Arguments: [cElements] -- The number of elements requested by client
  129. // [pvar] -- ptr to array of VARIANTs to for return objects
  130. // [pcElementFetched] -- if non-NULL, then number of elements
  131. // -- actually returned is placed here
  132. //
  133. // Returns: HRESULT -- S_OK if number of elements requested are returned
  134. // -- S_FALSE if number of elements is < requested
  135. //
  136. // Modifies:
  137. //
  138. // History: 11-3-95 yihsins Created.
  139. //
  140. //----------------------------------------------------------------------------
  141. STDMETHODIMP
  142. CNDSClassEnum::Next(
  143. ULONG cElements,
  144. VARIANT FAR* pvar,
  145. ULONG FAR* pcElementFetched
  146. )
  147. {
  148. ULONG cElementFetched = 0;
  149. HRESULT hr = S_OK;
  150. hr = EnumProperties(
  151. cElements,
  152. pvar,
  153. &cElementFetched
  154. );
  155. if ( pcElementFetched )
  156. *pcElementFetched = cElementFetched;
  157. RRETURN_EXP_IF_ERR(hr);
  158. }
  159. HRESULT
  160. CNDSClassEnum::EnumObjects(
  161. DWORD ObjectType,
  162. ULONG cElements,
  163. VARIANT FAR * pvar,
  164. ULONG FAR * pcElementFetched
  165. )
  166. {
  167. switch (ObjectType)
  168. {
  169. case NDS_PROPERTY_ID:
  170. RRETURN (EnumProperties(cElements, pvar, pcElementFetched));
  171. default:
  172. RRETURN(S_FALSE);
  173. }
  174. }
  175. HRESULT
  176. CNDSClassEnum::EnumObjects(
  177. ULONG cElements,
  178. VARIANT FAR* pvar,
  179. ULONG FAR* pcElementFetched
  180. )
  181. {
  182. DWORD i;
  183. ULONG cRequested = 0;
  184. ULONG cFetchedByPath = 0;
  185. ULONG cTotalFetched = 0;
  186. VARIANT FAR* pPathvar = pvar;
  187. HRESULT hr = S_OK;
  188. DWORD ObjectType;
  189. for (i = 0; i < cElements; i++)
  190. VariantInit(&pvar[i]);
  191. cRequested = cElements;
  192. while ( SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
  193. && ((hr = EnumObjects( ObjectType,
  194. cRequested,
  195. pPathvar,
  196. &cFetchedByPath)) == S_FALSE )
  197. )
  198. {
  199. pPathvar += cFetchedByPath;
  200. cRequested -= cFetchedByPath;
  201. cTotalFetched += cFetchedByPath;
  202. cFetchedByPath = 0;
  203. if ( FAILED(_pObjList->Next()) )
  204. {
  205. if ( pcElementFetched )
  206. *pcElementFetched = cTotalFetched;
  207. RRETURN(S_FALSE);
  208. }
  209. _dwCurrentEntry = 0;
  210. }
  211. if ( pcElementFetched )
  212. *pcElementFetched = cTotalFetched + cFetchedByPath;
  213. RRETURN(hr);
  214. }
  215. HRESULT
  216. CNDSClassEnum::EnumProperties(
  217. ULONG cElements,
  218. VARIANT FAR* pvar,
  219. ULONG FAR* pcElementFetched
  220. )
  221. {
  222. HRESULT hr = S_OK;
  223. DWORD i = 0;
  224. IDispatch *pDispatch = NULL;
  225. while ( i < cElements )
  226. {
  227. hr = GetPropertyObject(&pDispatch);
  228. if ( hr == S_FALSE )
  229. break;
  230. VariantInit( &pvar[i] );
  231. pvar[i].vt = VT_DISPATCH;
  232. pvar[i].pdispVal = pDispatch;
  233. (*pcElementFetched)++;
  234. i++;
  235. }
  236. RRETURN(hr);
  237. }
  238. HRESULT
  239. CNDSClassEnum::GetPropertyObject(
  240. IDispatch ** ppDispatch
  241. )
  242. {
  243. HRESULT hr = S_OK;
  244. LPNDS_CLASS_DEF lpCurrentObject = NULL;
  245. DWORD dwStatus;
  246. *ppDispatch = NULL;
  247. if (!_hOperationData) {
  248. _dwObjectCurrentEntry = 0;
  249. _dwObjectReturned = 0;
  250. dwStatus = NwNdsCreateBuffer(
  251. NDS_SCHEMA_READ_CLASS_DEF,
  252. &_hOperationData
  253. );
  254. if (dwStatus) {
  255. hr = HRESULT_FROM_WIN32(GetLastError());
  256. BAIL_ON_FAILURE(hr);
  257. }
  258. dwStatus = NwNdsPutInBuffer(
  259. _bstrName,
  260. 0,
  261. NULL,
  262. 0,
  263. 0,
  264. _hOperationData
  265. );
  266. if (dwStatus) {
  267. hr = HRESULT_FROM_WIN32(GetLastError());
  268. BAIL_ON_FAILURE(hr);
  269. }
  270. dwStatus = NwNdsReadClassDef(
  271. _hTree,
  272. NDS_CLASS_INFO_EXPANDED_DEFS,
  273. &_hOperationData
  274. );
  275. if (dwStatus) {
  276. hr = HRESULT_FROM_WIN32(GetLastError());
  277. BAIL_ON_FAILURE(hr);
  278. }
  279. dwStatus = NwNdsGetClassDefListFromBuffer(
  280. _hOperationData,
  281. &_dwObjectReturned,
  282. &_dwInfoType,
  283. (LPVOID *) &_lpClassDefs
  284. );
  285. if (dwStatus) {
  286. hr = HRESULT_FROM_WIN32(GetLastError());
  287. BAIL_ON_FAILURE(hr);
  288. }
  289. //
  290. // Assert to check that we returned only 1 object
  291. //
  292. ADsAssert(_dwObjectReturned == 1);
  293. _pPropNameList = GeneratePropertyList(
  294. _lpClassDefs->lpMandatoryAttributes,
  295. _lpClassDefs->lpOptionalAttributes
  296. );
  297. if (!_pPropNameList) {
  298. hr = HRESULT_FROM_WIN32(GetLastError());
  299. BAIL_ON_FAILURE(hr);
  300. }
  301. _pCurrentEntry = _pPropNameList;
  302. }
  303. if (_pCurrentEntry){
  304. //
  305. // Now send back the current object
  306. //
  307. hr = CNDSProperty::CreateProperty(
  308. _bstrADsPath,
  309. _pCurrentEntry->pszPropName,
  310. _hTree,
  311. _Credentials,
  312. ADS_OBJECT_BOUND,
  313. IID_IDispatch,
  314. (void **)ppDispatch
  315. );
  316. BAIL_ON_FAILURE(hr);
  317. _pCurrentEntry = _pCurrentEntry->pNext;
  318. RRETURN(S_OK);
  319. }
  320. error:
  321. RRETURN(S_FALSE);
  322. }