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.

507 lines
12 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cenumsch.cxx
  7. //
  8. // Contents: LDAP Schema Enumeration Code
  9. //
  10. // CLDAPSchemaEnum::CLDAPSchemaEnum()
  11. // CLDAPSchemaEnum::CLDAPSchemaEnum
  12. // CLDAPSchemaEnum::EnumObjects
  13. // CLDAPSchemaEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "ldap.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CLDAPSchemaEnum::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. CLDAPSchemaEnum::Create(
  37. CLDAPSchemaEnum FAR* FAR* ppenumvariant,
  38. BSTR bstrADsPath,
  39. BSTR bstrServerPath,
  40. VARIANT vFilter,
  41. CCredentials& Credentials
  42. )
  43. {
  44. HRESULT hr = S_OK;
  45. CLDAPSchemaEnum FAR* penumvariant = NULL;
  46. OBJECTINFO ObjectInfo;
  47. POBJECTINFO pObjectInfo = &ObjectInfo;
  48. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  49. *ppenumvariant = NULL;
  50. penumvariant = new CLDAPSchemaEnum();
  51. if (!penumvariant)
  52. {
  53. hr = E_OUTOFMEMORY;
  54. BAIL_ON_FAILURE(hr);
  55. }
  56. hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
  57. BAIL_ON_FAILURE(hr);
  58. hr = ADsAllocString( bstrServerPath, &penumvariant->_bstrServerPath);
  59. BAIL_ON_FAILURE(hr);
  60. hr = ADsObject(bstrADsPath, pObjectInfo);
  61. BAIL_ON_FAILURE(hr);
  62. hr = SchemaOpen(
  63. bstrServerPath,
  64. &(penumvariant->_hSchema),
  65. Credentials,
  66. pObjectInfo->PortNumber
  67. );
  68. BAIL_ON_FAILURE(hr);
  69. hr = SchemaGetObjectCount(
  70. penumvariant->_hSchema,
  71. &(penumvariant->_nNumOfClasses),
  72. &(penumvariant->_nNumOfProperties) );
  73. BAIL_ON_FAILURE(hr);
  74. hr = ObjectTypeList::CreateObjectTypeList(
  75. vFilter,
  76. &penumvariant->_pObjList );
  77. BAIL_ON_FAILURE(hr);
  78. penumvariant->_Credentials = Credentials;
  79. *ppenumvariant = penumvariant;
  80. FreeObjectInfo(pObjectInfo);
  81. RRETURN(hr);
  82. error:
  83. FreeObjectInfo(pObjectInfo);
  84. delete penumvariant;
  85. RRETURN_EXP_IF_ERR(hr);
  86. }
  87. CLDAPSchemaEnum::CLDAPSchemaEnum()
  88. : _bstrADsPath( NULL ),
  89. _bstrServerPath( NULL ),
  90. _hSchema( NULL ),
  91. _pObjList( NULL ),
  92. _dwCurrentEntry( 0 ),
  93. _nNumOfClasses( 0 ),
  94. _nNumOfProperties( 0 )
  95. {
  96. }
  97. CLDAPSchemaEnum::~CLDAPSchemaEnum()
  98. {
  99. ADsFreeString( _bstrADsPath );
  100. ADsFreeString( _bstrServerPath );
  101. if ( _hSchema )
  102. {
  103. SchemaClose( &_hSchema );
  104. }
  105. if ( _pObjList != NULL )
  106. {
  107. delete _pObjList;
  108. _pObjList = NULL;
  109. }
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Function: CLDAPSchemaEnum::Next
  114. //
  115. // Synopsis: Returns cElements number of requested NetOle objects in the
  116. // array supplied in pvar.
  117. //
  118. // Arguments: [cElements] -- The number of elements requested by client
  119. // [pvar] -- ptr to array of VARIANTs to for return objects
  120. // [pcElementFetched] -- if non-NULL, then number of elements
  121. // -- actually returned is placed here
  122. //
  123. // Returns: HRESULT -- S_OK if number of elements requested are returned
  124. // -- S_FALSE if number of elements is < requested
  125. //
  126. // Modifies:
  127. //
  128. // History: 11-3-95 yihsins Created.
  129. //
  130. //----------------------------------------------------------------------------
  131. STDMETHODIMP
  132. CLDAPSchemaEnum::Next(
  133. ULONG cElements,
  134. VARIANT FAR* pvar,
  135. ULONG FAR* pcElementFetched
  136. )
  137. {
  138. ULONG cElementFetched = 0;
  139. HRESULT hr = S_OK;
  140. hr = EnumObjects( cElements,
  141. pvar,
  142. &cElementFetched );
  143. if ( pcElementFetched )
  144. *pcElementFetched = cElementFetched;
  145. RRETURN_EXP_IF_ERR(hr);
  146. }
  147. HRESULT
  148. CLDAPSchemaEnum::EnumObjects(
  149. DWORD ObjectType,
  150. ULONG cElements,
  151. VARIANT FAR * pvar,
  152. ULONG FAR * pcElementFetched
  153. )
  154. {
  155. HRESULT hr;
  156. switch (ObjectType)
  157. {
  158. case LDAP_CLASS_ID:
  159. hr = EnumClasses(cElements, pvar, pcElementFetched);
  160. break;
  161. case LDAP_PROPERTY_ID:
  162. hr = EnumProperties(cElements, pvar, pcElementFetched);
  163. break;
  164. case LDAP_SYNTAX_ID:
  165. hr = EnumSyntaxObjects(cElements, pvar, pcElementFetched);
  166. break;
  167. default:
  168. hr = S_FALSE;
  169. }
  170. RRETURN(hr);
  171. }
  172. HRESULT
  173. CLDAPSchemaEnum::EnumObjects(
  174. ULONG cElements,
  175. VARIANT FAR* pvar,
  176. ULONG FAR* pcElementFetched
  177. )
  178. {
  179. DWORD i;
  180. ULONG cRequested = 0;
  181. ULONG cFetchedByPath = 0;
  182. ULONG cTotalFetched = 0;
  183. VARIANT FAR* pPathvar = pvar;
  184. HRESULT hr = S_FALSE;
  185. DWORD ObjectType;
  186. for (i = 0; i < cElements; i++)
  187. VariantInit(&pvar[i]);
  188. cRequested = cElements;
  189. while ( SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
  190. && ((hr = EnumObjects( ObjectType,
  191. cRequested,
  192. pPathvar,
  193. &cFetchedByPath)) == S_FALSE )
  194. )
  195. {
  196. pPathvar += cFetchedByPath;
  197. cRequested -= cFetchedByPath;
  198. cTotalFetched += cFetchedByPath;
  199. cFetchedByPath = 0;
  200. if ( FAILED(_pObjList->Next()) )
  201. {
  202. if ( pcElementFetched )
  203. *pcElementFetched = cTotalFetched;
  204. RRETURN(S_FALSE);
  205. }
  206. _dwCurrentEntry = 0;
  207. }
  208. if ( pcElementFetched )
  209. *pcElementFetched = cTotalFetched + cFetchedByPath;
  210. RRETURN_EXP_IF_ERR(hr);
  211. }
  212. HRESULT
  213. CLDAPSchemaEnum::EnumClasses(
  214. ULONG cElements,
  215. VARIANT FAR* pvar,
  216. ULONG FAR* pcElementFetched
  217. )
  218. {
  219. HRESULT hr = S_OK;
  220. DWORD i = 0;
  221. IDispatch *pDispatch = NULL;
  222. while ( i < cElements )
  223. {
  224. hr = GetClassObject(&pDispatch);
  225. if ( hr == S_FALSE )
  226. break;
  227. VariantInit( &pvar[i] );
  228. pvar[i].vt = VT_DISPATCH;
  229. pvar[i].pdispVal = pDispatch;
  230. (*pcElementFetched)++;
  231. i++;
  232. }
  233. RRETURN(hr);
  234. }
  235. HRESULT
  236. CLDAPSchemaEnum::GetClassObject(
  237. IDispatch ** ppDispatch
  238. )
  239. {
  240. HRESULT hr = S_OK;
  241. CLASSINFO *pClassInfo = NULL;
  242. //
  243. // Now send back the current object
  244. //
  245. if ( _dwCurrentEntry >= _nNumOfClasses )
  246. goto error;
  247. hr = SchemaGetClassInfoByIndex(
  248. _hSchema,
  249. _dwCurrentEntry,
  250. &pClassInfo );
  251. BAIL_ON_FAILURE(hr);
  252. if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
  253. //
  254. // If we are in Umi land, then we cannot ask for dispatch.
  255. //
  256. hr = CLDAPClass::CreateClass(
  257. _bstrADsPath,
  258. _hSchema,
  259. pClassInfo->pszName,
  260. pClassInfo,
  261. _Credentials,
  262. ADS_OBJECT_BOUND,
  263. IID_IUnknown,
  264. (void **) ppDispatch
  265. );
  266. }
  267. else {
  268. hr = CLDAPClass::CreateClass(
  269. _bstrADsPath,
  270. _hSchema,
  271. pClassInfo->pszName,
  272. pClassInfo,
  273. _Credentials,
  274. ADS_OBJECT_BOUND,
  275. IID_IDispatch,
  276. (void **)ppDispatch
  277. );
  278. }
  279. BAIL_ON_FAILURE(hr);
  280. _dwCurrentEntry++;
  281. RRETURN(S_OK);
  282. error:
  283. *ppDispatch = NULL;
  284. RRETURN(S_FALSE);
  285. }
  286. HRESULT
  287. CLDAPSchemaEnum::EnumProperties(
  288. ULONG cElements,
  289. VARIANT FAR* pvar,
  290. ULONG FAR* pcElementFetched
  291. )
  292. {
  293. HRESULT hr = S_OK;
  294. DWORD i = 0;
  295. IDispatch *pDispatch = NULL;
  296. while ( i < cElements )
  297. {
  298. hr = GetPropertyObject(&pDispatch);
  299. if ( hr == S_FALSE )
  300. break;
  301. VariantInit( &pvar[i] );
  302. pvar[i].vt = VT_DISPATCH;
  303. pvar[i].pdispVal = pDispatch;
  304. (*pcElementFetched)++;
  305. i++;
  306. }
  307. RRETURN(hr);
  308. }
  309. HRESULT
  310. CLDAPSchemaEnum::GetPropertyObject(
  311. IDispatch ** ppDispatch
  312. )
  313. {
  314. HRESULT hr = S_OK;
  315. PROPERTYINFO *pPropertyInfo = NULL;
  316. //
  317. // Now send back the current object
  318. //
  319. if ( _dwCurrentEntry >= _nNumOfProperties )
  320. goto error;
  321. hr = SchemaGetPropertyInfoByIndex(
  322. _hSchema,
  323. _dwCurrentEntry,
  324. &pPropertyInfo );
  325. BAIL_ON_FAILURE(hr);
  326. if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
  327. //
  328. // In Umi land ask for IID_IUnknown.
  329. //
  330. hr = CLDAPProperty::CreateProperty(
  331. _bstrADsPath,
  332. _hSchema,
  333. pPropertyInfo->pszPropertyName,
  334. pPropertyInfo,
  335. _Credentials,
  336. ADS_OBJECT_BOUND,
  337. IID_IUnknown,
  338. (void **)ppDispatch
  339. );
  340. }
  341. else {
  342. hr = CLDAPProperty::CreateProperty(
  343. _bstrADsPath,
  344. _hSchema,
  345. pPropertyInfo->pszPropertyName,
  346. pPropertyInfo,
  347. _Credentials,
  348. ADS_OBJECT_BOUND,
  349. IID_IDispatch,
  350. (void **)ppDispatch
  351. );
  352. }
  353. BAIL_ON_FAILURE(hr);
  354. _dwCurrentEntry++;
  355. RRETURN(S_OK);
  356. error:
  357. *ppDispatch = NULL;
  358. RRETURN(S_FALSE);
  359. }
  360. HRESULT
  361. CLDAPSchemaEnum::EnumSyntaxObjects(
  362. ULONG cElements,
  363. VARIANT FAR* pvar,
  364. ULONG FAR* pcElementFetched
  365. )
  366. {
  367. HRESULT hr = S_OK;
  368. DWORD i = 0;
  369. IDispatch *pDispatch = NULL;
  370. while ( i < cElements )
  371. {
  372. hr = GetSyntaxObject(&pDispatch);
  373. if ( hr == S_FALSE )
  374. break;
  375. VariantInit( &pvar[i] );
  376. pvar[i].vt = VT_DISPATCH;
  377. pvar[i].pdispVal = pDispatch;
  378. (*pcElementFetched)++;
  379. i++;
  380. }
  381. RRETURN(hr);
  382. }
  383. HRESULT
  384. CLDAPSchemaEnum::GetSyntaxObject(
  385. IDispatch ** ppDispatch
  386. )
  387. {
  388. HRESULT hr = S_OK;
  389. //
  390. // Now send back the current object
  391. //
  392. if ( _dwCurrentEntry >= g_cLDAPSyntax )
  393. goto error;
  394. if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
  395. //
  396. // In Umi land ask for IID_IUnknown not dispatch.
  397. //
  398. hr = CLDAPSyntax::CreateSyntax(
  399. _bstrADsPath,
  400. &g_aLDAPSyntax[_dwCurrentEntry],
  401. _Credentials,
  402. ADS_OBJECT_BOUND,
  403. IID_IUnknown,
  404. (void **)ppDispatch
  405. );
  406. }
  407. else {
  408. hr = CLDAPSyntax::CreateSyntax(
  409. _bstrADsPath,
  410. &g_aLDAPSyntax[_dwCurrentEntry],
  411. _Credentials,
  412. ADS_OBJECT_BOUND,
  413. IID_IDispatch,
  414. (void **)ppDispatch
  415. );
  416. }
  417. BAIL_ON_FAILURE(hr);
  418. _dwCurrentEntry++;
  419. RRETURN(S_OK);
  420. error:
  421. *ppDispatch = NULL;
  422. RRETURN(S_FALSE);
  423. }