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.

785 lines
25 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. // ***************************************************************************
  5. //
  6. // Original Author: Rajesh Rao
  7. //
  8. // $Author: rajeshr $
  9. // $Date: 6/11/98 4:43p $
  10. // $Workfile:classpro.cpp $
  11. //
  12. // $Modtime: 6/11/98 11:21a $
  13. // $Revision: 1 $
  14. // $Nokeywords: $
  15. //
  16. //
  17. // Description: Contains implementation of the DS Class Associations Provider class.
  18. //
  19. //***************************************************************************
  20. #include "precomp.h"
  21. /////////////////////////////////////////
  22. // Initialize the static members
  23. /////////////////////////////////////////
  24. LPCWSTR CLDAPClassAsssociationsProvider :: s_LogFileName = L"wbem\\logs\\ldapascl.txt";
  25. LPCWSTR CLDAPClassAsssociationsProvider :: CHILD_CLASS_PROPERTY = L"ChildClass";
  26. LPCWSTR CLDAPClassAsssociationsProvider :: PARENT_CLASS_PROPERTY = L"ParentClass";
  27. LPCWSTR CLDAPClassAsssociationsProvider :: POSSIBLE_SUPERIORS = L"PossibleSuperiors";
  28. LPCWSTR CLDAPClassAsssociationsProvider :: SCHEMA_NAMING_CONTEXT = L"schemaNamingContext";
  29. LPCWSTR CLDAPClassAsssociationsProvider :: LDAP_SCHEMA = L"LDAP://Schema";
  30. LPCWSTR CLDAPClassAsssociationsProvider :: LDAP_SCHEMA_SLASH = L"LDAP://Schema/";
  31. //***************************************************************************
  32. //
  33. // CLDAPClassAsssociationsProvider::CLDAPClassAsssociationsProvider
  34. // CLDAPClassAsssociationsProvider::~CLDAPClassAsssociationsProvider
  35. //
  36. // Constructor Parameters:
  37. //
  38. //
  39. //***************************************************************************
  40. CLDAPClassAsssociationsProvider :: CLDAPClassAsssociationsProvider ()
  41. {
  42. InterlockedIncrement(&g_lComponents);
  43. m_lReferenceCount = 0 ;
  44. m_IWbemServices = NULL;
  45. m_pAssociationClass = NULL;
  46. m_lpszSchemaContainerSuffix = NULL;
  47. m_pDirectorySearchSchemaContainer = NULL;
  48. m_bInitializedSuccessfully = FALSE;
  49. CHILD_CLASS_PROPERTY_STR = SysAllocString(CHILD_CLASS_PROPERTY);
  50. PARENT_CLASS_PROPERTY_STR = SysAllocString(PARENT_CLASS_PROPERTY);
  51. CLASS_ASSOCIATION_CLASS_STR = SysAllocString(CLASS_ASSOCIATION_CLASS);
  52. POSSIBLE_SUPERIORS_STR = SysAllocString(POSSIBLE_SUPERIORS);
  53. }
  54. CLDAPClassAsssociationsProvider::~CLDAPClassAsssociationsProvider ()
  55. {
  56. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: DESTRUCTOR\r\n");
  57. InterlockedDecrement(&g_lComponents);
  58. if(m_IWbemServices)
  59. m_IWbemServices->Release();
  60. if(m_pDirectorySearchSchemaContainer)
  61. m_pDirectorySearchSchemaContainer->Release();
  62. if(m_pAssociationClass)
  63. m_pAssociationClass->Release();
  64. delete [] m_lpszSchemaContainerSuffix;
  65. SysFreeString(CHILD_CLASS_PROPERTY_STR);
  66. SysFreeString(PARENT_CLASS_PROPERTY_STR);
  67. SysFreeString(CLASS_ASSOCIATION_CLASS_STR);
  68. SysFreeString(POSSIBLE_SUPERIORS_STR);
  69. }
  70. //***************************************************************************
  71. //
  72. // CLDAPClassAsssociationsProvider::QueryInterface
  73. // CLDAPClassAsssociationsProvider::AddRef
  74. // CLDAPClassAsssociationsProvider::Release
  75. //
  76. // Purpose: Standard COM routines needed for all COM objects
  77. //
  78. //***************************************************************************
  79. STDMETHODIMP CLDAPClassAsssociationsProvider :: QueryInterface (
  80. REFIID iid ,
  81. LPVOID FAR *iplpv
  82. )
  83. {
  84. *iplpv = NULL ;
  85. if ( iid == IID_IUnknown )
  86. {
  87. *iplpv = ( LPVOID ) (IUnknown *)(IWbemProviderInit *)this ;
  88. }
  89. else if ( iid == IID_IWbemServices )
  90. {
  91. *iplpv = ( LPVOID ) (IWbemServices *)this ;
  92. }
  93. else if ( iid == IID_IWbemProviderInit )
  94. {
  95. *iplpv = ( LPVOID ) (IWbemProviderInit *)this ;
  96. }
  97. else
  98. {
  99. return E_NOINTERFACE;
  100. }
  101. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  102. return S_OK;
  103. }
  104. STDMETHODIMP_( ULONG ) CLDAPClassAsssociationsProvider :: AddRef ()
  105. {
  106. return InterlockedIncrement ( & m_lReferenceCount ) ;
  107. }
  108. STDMETHODIMP_(ULONG) CLDAPClassAsssociationsProvider :: Release ()
  109. {
  110. LONG ref ;
  111. if ( ( ref = InterlockedDecrement ( & m_lReferenceCount ) ) == 0 )
  112. {
  113. delete this ;
  114. return 0 ;
  115. }
  116. else
  117. {
  118. return ref ;
  119. }
  120. }
  121. HRESULT CLDAPClassAsssociationsProvider :: Initialize(
  122. LPWSTR wszUser,
  123. LONG lFlags,
  124. LPWSTR wszNamespace,
  125. LPWSTR wszLocale,
  126. IWbemServices __RPC_FAR *pNamespace,
  127. IWbemContext __RPC_FAR *pCtx,
  128. IWbemProviderInitSink __RPC_FAR *pInitSink)
  129. {
  130. // Validate the arguments
  131. if(pNamespace == NULL || lFlags != 0)
  132. {
  133. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Argument validation FAILED\r\n");
  134. pInitSink->SetStatus(WBEM_E_FAILED, 0);
  135. return WBEM_S_NO_ERROR;
  136. }
  137. // Store the IWbemServices pointer for future use
  138. m_IWbemServices = pNamespace;
  139. m_IWbemServices->AddRef();
  140. // Do LDAP Provider initialization
  141. if(!InitializeAssociationsProvider(pCtx))
  142. {
  143. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: InitializeAssociationsProvider FAILED\r\n");
  144. m_IWbemServices->Release();
  145. m_IWbemServices = NULL;
  146. m_bInitializedSuccessfully = FALSE;
  147. }
  148. else
  149. m_bInitializedSuccessfully = TRUE;
  150. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  151. return WBEM_S_NO_ERROR;
  152. }
  153. HRESULT CLDAPClassAsssociationsProvider :: OpenNamespace(
  154. /* [in] */ const BSTR strNamespace,
  155. /* [in] */ long lFlags,
  156. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  157. /* [unique][in][out] */ IWbemServices __RPC_FAR *__RPC_FAR *ppWorkingNamespace,
  158. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppResult)
  159. {
  160. return WBEM_E_NOT_SUPPORTED;
  161. }
  162. HRESULT CLDAPClassAsssociationsProvider :: CancelAsyncCall(
  163. /* [in] */ IWbemObjectSink __RPC_FAR *pSink)
  164. {
  165. return WBEM_E_NOT_SUPPORTED;
  166. }
  167. HRESULT CLDAPClassAsssociationsProvider :: QueryObjectSink(
  168. /* [in] */ long lFlags,
  169. /* [out] */ IWbemObjectSink __RPC_FAR *__RPC_FAR *ppResponseHandler)
  170. {
  171. return WBEM_E_NOT_SUPPORTED;
  172. }
  173. HRESULT CLDAPClassAsssociationsProvider :: GetObject(
  174. /* [in] */ const BSTR strObjectPath,
  175. /* [in] */ long lFlags,
  176. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  177. /* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppObject,
  178. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  179. {
  180. return WBEM_E_NOT_SUPPORTED;
  181. }
  182. HRESULT CLDAPClassAsssociationsProvider :: GetObjectAsync(
  183. /* [in] */ const BSTR strObjectPath,
  184. /* [in] */ long lFlags,
  185. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  186. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  187. {
  188. if(!m_bInitializedSuccessfully)
  189. {
  190. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Initialization status is FAILED, hence returning failure\n");
  191. return WBEM_E_FAILED;
  192. }
  193. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: GetObjectAsync() called for %s \r\n", strObjectPath);
  194. HRESULT result = S_OK;
  195. // Impersonate the client
  196. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  197. {
  198. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: GetObjectAsync() CoImpersonate FAILED for %s with %x\r\n", strObjectPath, result);
  199. return WBEM_E_FAILED;
  200. }
  201. // Validate the arguments
  202. if(strObjectPath == NULL || lFlags != 0)
  203. {
  204. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: GetObjectAsync() argument validation FAILED\r\n");
  205. return WBEM_E_INVALID_PARAMETER;
  206. }
  207. // Parse the object path
  208. CObjectPathParser theParser;
  209. ParsedObjectPath *theParsedObjectPath = NULL;
  210. switch(theParser.Parse(strObjectPath, &theParsedObjectPath))
  211. {
  212. case CObjectPathParser::NoError:
  213. break;
  214. default:
  215. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: GetObjectAsync() object path parsing FAILED\r\n");
  216. return WBEM_E_INVALID_PARAMETER;
  217. }
  218. // Check whether there are exactly 2 keys specified
  219. if(theParsedObjectPath->m_dwNumKeys != 2)
  220. result = WBEM_E_INVALID_PARAMETER;
  221. // Check whether these keys are
  222. KeyRef *pChildKeyRef = *(theParsedObjectPath->m_paKeys);
  223. KeyRef *pParentKeyRef = *(theParsedObjectPath->m_paKeys + 1);
  224. if(_wcsicmp(pChildKeyRef->m_pName, CHILD_CLASS_PROPERTY) != 0)
  225. {
  226. // Exchange them
  227. KeyRef *temp = pChildKeyRef;
  228. pChildKeyRef = pParentKeyRef;
  229. pParentKeyRef = pChildKeyRef;
  230. }
  231. // The status on the sink
  232. IWbemClassObject *ppReturnWbemClassObjects[1];
  233. ppReturnWbemClassObjects[0] = NULL;
  234. if(SUCCEEDED(result))
  235. {
  236. if(SUCCEEDED(result = IsContainedIn(pChildKeyRef->m_vValue.bstrVal, pParentKeyRef->m_vValue.bstrVal)))
  237. {
  238. if(result == S_OK)
  239. {
  240. if(SUCCEEDED(result = CreateInstance(pChildKeyRef->m_vValue.bstrVal, pParentKeyRef->m_vValue.bstrVal, ppReturnWbemClassObjects)))
  241. {
  242. result = pResponseHandler->Indicate(1, ppReturnWbemClassObjects);
  243. ppReturnWbemClassObjects[0]->Release();
  244. }
  245. }
  246. else // the instance was not found
  247. {
  248. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: returning WBEM_E_NOT_FOUND for %s \r\n", strObjectPath);
  249. result = WBEM_E_NOT_FOUND;
  250. }
  251. }
  252. else
  253. {
  254. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: IsContainedIn() FAILED with %x \r\n", result);
  255. }
  256. }
  257. // Free the parser object path
  258. theParser.Free(theParsedObjectPath);
  259. // Set the status of the request
  260. result = (SUCCEEDED(result)? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND);
  261. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE , result, NULL, NULL);
  262. return result;
  263. }
  264. HRESULT CLDAPClassAsssociationsProvider :: PutClass(
  265. /* [in] */ IWbemClassObject __RPC_FAR *pObject,
  266. /* [in] */ long lFlags,
  267. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  268. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  269. {
  270. return WBEM_E_NOT_SUPPORTED;
  271. }
  272. HRESULT CLDAPClassAsssociationsProvider :: PutClassAsync(
  273. /* [in] */ IWbemClassObject __RPC_FAR *pObject,
  274. /* [in] */ long lFlags,
  275. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  276. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  277. {
  278. return WBEM_E_NOT_SUPPORTED;
  279. }
  280. HRESULT CLDAPClassAsssociationsProvider :: DeleteClass(
  281. /* [in] */ const BSTR strClass,
  282. /* [in] */ long lFlags,
  283. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  284. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  285. {
  286. return WBEM_E_NOT_SUPPORTED;
  287. }
  288. HRESULT CLDAPClassAsssociationsProvider :: DeleteClassAsync(
  289. /* [in] */ const BSTR strClass,
  290. /* [in] */ long lFlags,
  291. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  292. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  293. {
  294. return WBEM_E_NOT_SUPPORTED;
  295. }
  296. HRESULT CLDAPClassAsssociationsProvider :: CreateClassEnum(
  297. /* [in] */ const BSTR strClass,
  298. /* [in] */ long lFlags,
  299. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  300. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  301. {
  302. return WBEM_E_NOT_SUPPORTED;
  303. }
  304. HRESULT CLDAPClassAsssociationsProvider :: CreateClassEnumAsync(
  305. /* [in] */ const BSTR strClass,
  306. /* [in] */ long lFlags,
  307. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  308. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  309. {
  310. return WBEM_E_NOT_SUPPORTED;
  311. }
  312. HRESULT CLDAPClassAsssociationsProvider :: PutInstance(
  313. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  314. /* [in] */ long lFlags,
  315. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  316. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  317. {
  318. return WBEM_E_NOT_SUPPORTED;
  319. }
  320. HRESULT CLDAPClassAsssociationsProvider :: PutInstanceAsync(
  321. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  322. /* [in] */ long lFlags,
  323. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  324. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  325. {
  326. return WBEM_E_NOT_SUPPORTED;
  327. }
  328. HRESULT CLDAPClassAsssociationsProvider :: DeleteInstance(
  329. /* [in] */ const BSTR strObjectPath,
  330. /* [in] */ long lFlags,
  331. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  332. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  333. {
  334. return WBEM_E_NOT_SUPPORTED;
  335. }
  336. HRESULT CLDAPClassAsssociationsProvider :: DeleteInstanceAsync(
  337. /* [in] */ const BSTR strObjectPath,
  338. /* [in] */ long lFlags,
  339. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  340. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  341. {
  342. return WBEM_E_NOT_SUPPORTED;
  343. }
  344. HRESULT CLDAPClassAsssociationsProvider :: CreateInstanceEnum(
  345. /* [in] */ const BSTR strClass,
  346. /* [in] */ long lFlags,
  347. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  348. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  349. {
  350. return WBEM_E_NOT_SUPPORTED;
  351. }
  352. HRESULT CLDAPClassAsssociationsProvider :: CreateInstanceEnumAsync(
  353. /* [in] */ const BSTR strClass,
  354. /* [in] */ long lFlags,
  355. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  356. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  357. {
  358. if(!m_bInitializedSuccessfully)
  359. {
  360. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Initialization status is FAILED, hence returning failure\n");
  361. return WBEM_E_FAILED;
  362. }
  363. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstanceEnumAsync() called\r\n");
  364. HRESULT result = S_OK;
  365. // Impersonate the client
  366. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  367. {
  368. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstanceEnumAsync() CoImpersonate FAILED with %x\r\n", result);
  369. return WBEM_E_FAILED;
  370. }
  371. // Get all the ADSI classes
  372. result = DoEnumeration(pResponseHandler);
  373. if(SUCCEEDED(result))
  374. {
  375. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
  376. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstanceEnumAsync() enumeration succeeded\r\n");
  377. return WBEM_S_NO_ERROR;
  378. }
  379. else
  380. {
  381. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_FAILED, NULL, NULL);
  382. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstanceEnumAsync() enumeration FAILED\r\n");
  383. return WBEM_E_FAILED;
  384. }
  385. return result;
  386. }
  387. HRESULT CLDAPClassAsssociationsProvider :: ExecQuery(
  388. /* [in] */ const BSTR strQueryLanguage,
  389. /* [in] */ const BSTR strQuery,
  390. /* [in] */ long lFlags,
  391. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  392. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  393. {
  394. return WBEM_E_NOT_SUPPORTED;
  395. }
  396. HRESULT CLDAPClassAsssociationsProvider :: ExecQueryAsync(
  397. /* [in] */ const BSTR strQueryLanguage,
  398. /* [in] */ const BSTR strQuery,
  399. /* [in] */ long lFlags,
  400. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  401. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  402. {
  403. return WBEM_E_PROVIDER_NOT_CAPABLE;
  404. }
  405. HRESULT CLDAPClassAsssociationsProvider :: ExecNotificationQuery(
  406. /* [in] */ const BSTR strQueryLanguage,
  407. /* [in] */ const BSTR strQuery,
  408. /* [in] */ long lFlags,
  409. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  410. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  411. {
  412. return WBEM_E_NOT_SUPPORTED;
  413. }
  414. HRESULT CLDAPClassAsssociationsProvider :: ExecNotificationQueryAsync(
  415. /* [in] */ const BSTR strQueryLanguage,
  416. /* [in] */ const BSTR strQuery,
  417. /* [in] */ long lFlags,
  418. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  419. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  420. {
  421. return WBEM_E_NOT_SUPPORTED;
  422. }
  423. HRESULT CLDAPClassAsssociationsProvider :: ExecMethod(
  424. /* [in] */ const BSTR strObjectPath,
  425. /* [in] */ const BSTR strMethodName,
  426. /* [in] */ long lFlags,
  427. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  428. /* [in] */ IWbemClassObject __RPC_FAR *pInParams,
  429. /* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppOutParams,
  430. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  431. {
  432. return WBEM_E_NOT_SUPPORTED;
  433. }
  434. HRESULT CLDAPClassAsssociationsProvider :: ExecMethodAsync(
  435. /* [in] */ const BSTR strObjectPath,
  436. /* [in] */ const BSTR strMethodName,
  437. /* [in] */ long lFlags,
  438. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  439. /* [in] */ IWbemClassObject __RPC_FAR *pInParams,
  440. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  441. {
  442. return WBEM_E_NOT_SUPPORTED;
  443. }
  444. //***************************************************************************
  445. //
  446. // CLDAPClassAsssociationsProvider::IsContainedIn
  447. //
  448. // Purpose: Checks whether a containment is valid
  449. //
  450. // Parameters:
  451. // lpszChildClass : The WBEM Name of the child class
  452. // lpszParentClass : The WBEM Name of the parent class
  453. //
  454. // Return Value: The COM status of the request
  455. //
  456. //***************************************************************************
  457. HRESULT CLDAPClassAsssociationsProvider :: IsContainedIn(LPCWSTR lpszChildClass, LPCWSTR lpszParentClass)
  458. {
  459. LPWSTR lpszLDAPChildClass = NULL;
  460. LPWSTR lpszLDAPParentClass = NULL;
  461. lpszLDAPChildClass = CLDAPHelper::UnmangleWBEMNameToLDAP(lpszChildClass);
  462. lpszLDAPParentClass = CLDAPHelper::UnmangleWBEMNameToLDAP(lpszParentClass);
  463. // Check whether these are valid names
  464. if(!lpszLDAPChildClass || !lpszLDAPParentClass)
  465. {
  466. delete [] lpszLDAPChildClass;
  467. delete [] lpszLDAPParentClass;
  468. return S_FALSE;
  469. }
  470. LPWSTR lpszADSIAbstractSchemaPath = new WCHAR[wcslen(LDAP_SCHEMA_SLASH) + wcslen(lpszLDAPChildClass) + 1];
  471. wcscpy(lpszADSIAbstractSchemaPath, LDAP_SCHEMA_SLASH);
  472. wcscat(lpszADSIAbstractSchemaPath, lpszLDAPChildClass);
  473. IADsClass *pADsChildClass;
  474. HRESULT result;
  475. if(SUCCEEDED(result = ADsOpenObject(lpszADSIAbstractSchemaPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsClass, (LPVOID *) &pADsChildClass)))
  476. {
  477. // Get the POSSIBLE_SUPERIORS_STR property. This property contains the possible superiors
  478. VARIANT variant;
  479. VariantInit(&variant);
  480. if(SUCCEEDED(result = pADsChildClass->get_PossibleSuperiors(&variant)))
  481. {
  482. // Check the lone possible superior
  483. if(variant.vt == VT_BSTR)
  484. {
  485. if(_wcsicmp(variant.bstrVal, lpszLDAPParentClass) == 0)
  486. result = S_OK;
  487. else
  488. result = S_FALSE;
  489. }
  490. else
  491. {
  492. // Go thru the list of possible superiorsV
  493. SAFEARRAY *pSafeArray = variant.parray;
  494. LONG lNumber = 0;
  495. VARIANT vTmp;
  496. if(SUCCEEDED(result = SafeArrayGetUBound(pSafeArray, 1, &lNumber)) )
  497. {
  498. result = S_FALSE;
  499. for(LONG index=0L; index<=lNumber; index++)
  500. {
  501. if(SUCCEEDED(SafeArrayGetElement(pSafeArray, &index, &vTmp) ))
  502. {
  503. if(_wcsicmp(vTmp.bstrVal, lpszLDAPParentClass) == 0)
  504. {
  505. result = S_OK;
  506. }
  507. VariantClear(&vTmp);
  508. if(result == S_OK)
  509. break;
  510. }
  511. }
  512. }
  513. }
  514. VariantClear(&variant);
  515. }
  516. pADsChildClass->Release();
  517. }
  518. delete [] lpszLDAPChildClass;
  519. delete [] lpszLDAPParentClass;
  520. delete [] lpszADSIAbstractSchemaPath;
  521. return result;
  522. }
  523. //***************************************************************************
  524. //
  525. // CLDAPClassAsssociationsProvider::InitializeAssociationsProvider
  526. //
  527. // Purpose: A helper function to do the ADSI LDAP provider specific initialization.
  528. //
  529. // Parameters:
  530. // pCtx The context object used in this call initialization
  531. //
  532. // Return Value: TRUE if the function successfully finishes the initializaion. FALSE
  533. // otherwise
  534. //***************************************************************************
  535. BOOLEAN CLDAPClassAsssociationsProvider :: InitializeAssociationsProvider(IWbemContext *pCtx)
  536. {
  537. // Get the class for which instances are provided by the provider
  538. HRESULT result = m_IWbemServices->GetObject(CLASS_ASSOCIATION_CLASS_STR, 0, pCtx, &m_pAssociationClass, NULL);
  539. if(SUCCEEDED(result))
  540. {
  541. // Get the ADSI path of the schema container and store it for future use
  542. IADs *pRootDSE = NULL;
  543. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)ROOT_DSE_PATH, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID *) &pRootDSE)))
  544. {
  545. // Get the location of the schema container
  546. BSTR strSchemaPropertyName = SysAllocString((LPWSTR) SCHEMA_NAMING_CONTEXT);
  547. // Get the schemaNamingContext property. This property contains the ADSI path
  548. // of the schema container
  549. VARIANT variant;
  550. VariantInit(&variant);
  551. if(SUCCEEDED(result = pRootDSE->Get(strSchemaPropertyName, &variant)))
  552. {
  553. // Store the ADSI path to the schema container
  554. m_lpszSchemaContainerSuffix = new WCHAR[wcslen(variant.bstrVal) + 1];
  555. wcscpy(m_lpszSchemaContainerSuffix, variant.bstrVal );
  556. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Got Schema Container as : %s\r\n", m_lpszSchemaContainerSuffix);
  557. // Form the schema container path
  558. LPWSTR lpszSchemaContainerPath = new WCHAR[wcslen(LDAP_PREFIX) + wcslen(m_lpszSchemaContainerSuffix) + 1];
  559. wcscpy(lpszSchemaContainerPath, LDAP_PREFIX);
  560. wcscat(lpszSchemaContainerPath, m_lpszSchemaContainerSuffix);
  561. if(SUCCEEDED(result = ADsOpenObject(lpszSchemaContainerPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *) &m_pDirectorySearchSchemaContainer)))
  562. {
  563. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Got IDirectorySearch on Schema Container \r\n");
  564. }
  565. else
  566. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: FAILED to get IDirectorySearch on Schema Container : %x\r\n", result);
  567. delete[] lpszSchemaContainerPath;
  568. }
  569. else
  570. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: Get on RootDSE FAILED : %x\r\n", result);
  571. SysFreeString(strSchemaPropertyName);
  572. VariantClear(&variant);
  573. pRootDSE->Release();
  574. }
  575. else
  576. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: InitializeLDAPProvider ADsOpenObject on RootDSE FAILED : %x\r\n", result);
  577. }
  578. else
  579. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: InitializeLDAPProvider GetClass on LDAP Association class FAILED : %x\r\n", result);
  580. return SUCCEEDED(result);
  581. }
  582. HRESULT CLDAPClassAsssociationsProvider :: DoEnumeration(IWbemObjectSink *pResponseHandler)
  583. {
  584. HRESULT result = E_FAIL;
  585. // Get the IADsContainer interface on the schema container
  586. IADsContainer *pADsContainer = NULL;
  587. IUnknown *pChild = NULL;
  588. // An instance of the association
  589. IWbemClassObject *pInstance = NULL;
  590. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)LDAP_SCHEMA, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsContainer, (LPVOID *) &pADsContainer)))
  591. {
  592. IEnumVARIANT *pEnum = NULL;
  593. if(SUCCEEDED(result = ADsBuildEnumerator(pADsContainer, &pEnum)))
  594. {
  595. IADsClass *pADsChildClass = NULL;
  596. VARIANT v;
  597. VariantInit(&v);
  598. while (SUCCEEDED(result = ADsEnumerateNext(pEnum, 1, &v, NULL)) && result != S_FALSE)
  599. {
  600. pChild = v.punkVal;
  601. if(SUCCEEDED(result = pChild->QueryInterface(IID_IADsClass, (LPVOID *) &pADsChildClass)))
  602. {
  603. BSTR strChildClassName;
  604. if(SUCCEEDED(result = pADsChildClass->get_Name(&strChildClassName)))
  605. {
  606. // Mangle the name to WBEM
  607. LPWSTR szChildName = CLDAPHelper::MangleLDAPNameToWBEM(strChildClassName);
  608. VARIANT variant;
  609. VariantInit(&variant);
  610. if(SUCCEEDED(result = pADsChildClass->get_PossibleSuperiors(&variant)))
  611. {
  612. // Check the lone possible superior
  613. if(variant.vt == VT_BSTR)
  614. {
  615. LPWSTR szParentName = CLDAPHelper::MangleLDAPNameToWBEM(variant.bstrVal);
  616. if(SUCCEEDED(result = CreateInstance(szChildName, szParentName, &pInstance)))
  617. {
  618. pResponseHandler->Indicate(1, &pInstance);
  619. pInstance->Release();
  620. }
  621. delete [] szParentName;
  622. }
  623. else // It is an array of variants
  624. {
  625. // Go thru the list of possible superiorsV
  626. SAFEARRAY *pSafeArray = variant.parray;
  627. VARIANT HUGEP *pVar;
  628. LONG lUbound = 0, lLbound = 0;
  629. if(SUCCEEDED(result = SafeArrayAccessData(pSafeArray, (void HUGEP* FAR*)&pVar) ) )
  630. {
  631. if( SUCCEEDED (result = SafeArrayGetLBound(pSafeArray, 1, &lLbound)) &&
  632. SUCCEEDED (result = SafeArrayGetUBound(pSafeArray, 1, &lUbound)) )
  633. {
  634. for(LONG index=lLbound; index<=lUbound; index++)
  635. {
  636. LPWSTR szParentName = CLDAPHelper::MangleLDAPNameToWBEM(pVar[index].bstrVal);
  637. if(SUCCEEDED(result = CreateInstance(szChildName, szParentName, &pInstance)))
  638. {
  639. pResponseHandler->Indicate(1, &pInstance);
  640. pInstance->Release();
  641. }
  642. delete [] szParentName;
  643. }
  644. }
  645. SafeArrayUnaccessData(pSafeArray);
  646. }
  647. }
  648. VariantClear(&variant);
  649. }
  650. delete [] szChildName;
  651. SysFreeString(strChildClassName);
  652. }
  653. pADsChildClass->Release();
  654. }
  655. VariantClear(&v);
  656. }
  657. ADsFreeEnumerator(pEnum);
  658. }
  659. pADsContainer->Release();
  660. }
  661. else
  662. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: FAILED to get IDirectoryObject on Schema Container : %x\r\n", result);
  663. return result;
  664. }
  665. HRESULT CLDAPClassAsssociationsProvider :: CreateInstance(BSTR strChildName, BSTR strParentName, IWbemClassObject **ppInstance)
  666. {
  667. HRESULT result = E_FAIL;
  668. *ppInstance = NULL;
  669. if(SUCCEEDED(result = m_pAssociationClass->SpawnInstance(0, ppInstance)))
  670. {
  671. // Put the property values
  672. if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, CHILD_CLASS_PROPERTY_STR, strChildName, FALSE)))
  673. {
  674. if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, PARENT_CLASS_PROPERTY_STR, strParentName, FALSE)))
  675. {
  676. }
  677. else
  678. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstance() PutBSTRProperty on parent property FAILED %x \r\n", result);
  679. }
  680. else
  681. g_pLogObject->WriteW( L"CLDAPClassAsssociationsProvider :: CreateInstance() PutBSTRProperty on child property FAILED %x \r\n", result);
  682. }
  683. if(FAILED(result) && *ppInstance)
  684. {
  685. (*ppInstance)->Release();
  686. *ppInstance = NULL;
  687. }
  688. return result;
  689. }