Leaked source code of windows server 2003
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.

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