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.

3439 lines
114 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: 9/16/98 4:43p $
  10. // $Workfile:instprov.cpp $
  11. //
  12. // $Modtime: 9/16/98 11:21a $
  13. // $Revision: 1 $
  14. // $Nokeywords: $
  15. //
  16. //
  17. // Description: Contains implementation of the DS Instance Provider class.
  18. //
  19. //***************************************************************************
  20. #include "precomp.h"
  21. #include <helper.h>
  22. /////////////////////////////////////////
  23. // Initialize the static members
  24. /////////////////////////////////////////
  25. LPCWSTR CLDAPInstanceProvider :: DEFAULT_NAMING_CONTEXT_ATTR = L"defaultNamingContext";
  26. LPCWSTR CLDAPInstanceProvider :: OBJECT_CLASS_EQUALS = L"(objectClass=";
  27. LPCWSTR CLDAPInstanceProvider :: QUERY_FORMAT = L"select * from DSClass_To_DNInstance where DSClass=\"%s\"";
  28. BSTR CLDAPInstanceProvider :: CLASS_STR = NULL;
  29. BSTR CLDAPInstanceProvider :: DN_PROPERTY = NULL;
  30. BSTR CLDAPInstanceProvider :: ROOT_DN_PROPERTY = NULL;
  31. BSTR CLDAPInstanceProvider :: QUERY_LANGUAGE = NULL;
  32. BSTR CLDAPInstanceProvider :: ADSI_PATH_STR = NULL;
  33. BSTR CLDAPInstanceProvider :: UINT8ARRAY_STR = NULL;
  34. BSTR CLDAPInstanceProvider :: DN_WITH_STRING_CLASS_STR = NULL;
  35. BSTR CLDAPInstanceProvider :: DN_WITH_BINARY_CLASS_STR = NULL;
  36. BSTR CLDAPInstanceProvider :: VALUE_PROPERTY_STR = NULL;
  37. BSTR CLDAPInstanceProvider :: DN_STRING_PROPERTY_STR = NULL;
  38. BSTR CLDAPInstanceProvider :: INSTANCE_ASSOCIATION_CLASS_STR = NULL;
  39. BSTR CLDAPInstanceProvider :: CHILD_INSTANCE_PROPERTY_STR = NULL;
  40. BSTR CLDAPInstanceProvider :: PARENT_INSTANCE_PROPERTY_STR = NULL;
  41. BSTR CLDAPInstanceProvider :: RELPATH_STR = NULL;
  42. BSTR CLDAPInstanceProvider :: ATTRIBUTE_SYNTAX_STR = NULL;
  43. BSTR CLDAPInstanceProvider :: DEFAULT_OBJECT_CATEGORY_STR = NULL;
  44. BSTR CLDAPInstanceProvider :: LDAP_DISPLAY_NAME_STR = NULL;
  45. BSTR CLDAPInstanceProvider :: PUT_EXTENSIONS_STR = NULL;
  46. BSTR CLDAPInstanceProvider :: PUT_EXT_PROPERTIES_STR = NULL;
  47. BSTR CLDAPInstanceProvider :: CIMTYPE_STR = NULL;
  48. // Names of the RootDSE attributes
  49. BSTR CLDAPInstanceProvider :: SUBSCHEMASUBENTRY_STR = NULL;
  50. BSTR CLDAPInstanceProvider :: CURRENTTIME_STR = NULL;
  51. BSTR CLDAPInstanceProvider :: SERVERNAME_STR = NULL;
  52. BSTR CLDAPInstanceProvider :: NAMINGCONTEXTS_STR = NULL;
  53. BSTR CLDAPInstanceProvider :: DEFAULTNAMINGCONTEXT_STR = NULL;
  54. BSTR CLDAPInstanceProvider :: SCHEMANAMINGCONTEXT_STR = NULL;
  55. BSTR CLDAPInstanceProvider :: CONFIGURATIONNAMINGCONTEXT_STR = NULL;
  56. BSTR CLDAPInstanceProvider :: ROOTDOMAINNAMINGCONTEXT_STR = NULL;
  57. BSTR CLDAPInstanceProvider :: SUPPORTEDCONTROLS_STR = NULL;
  58. BSTR CLDAPInstanceProvider :: SUPPORTEDVERSION_STR = NULL;
  59. BSTR CLDAPInstanceProvider :: DNSHOSTNAME_STR = NULL;
  60. BSTR CLDAPInstanceProvider :: DSSERVICENAME_STR = NULL;
  61. BSTR CLDAPInstanceProvider :: HIGHESTCOMMITEDUSN_STR = NULL;
  62. BSTR CLDAPInstanceProvider :: LDAPSERVICENAME_STR = NULL;
  63. BSTR CLDAPInstanceProvider :: SUPPORTEDCAPABILITIES_STR = NULL;
  64. BSTR CLDAPInstanceProvider :: SUPPORTEDLDAPPOLICIES_STR = NULL;
  65. BSTR CLDAPInstanceProvider :: SUPPORTEDSASLMECHANISMS_STR = NULL;
  66. //***************************************************************************
  67. //
  68. // CLDAPInstanceProvider::CLDAPInstanceProvider
  69. // CLDAPInstanceProvider::~CLDAPInstanceProvider
  70. //
  71. // Constructor Parameters:
  72. //
  73. //
  74. //***************************************************************************
  75. CLDAPInstanceProvider :: CLDAPInstanceProvider ()
  76. {
  77. InterlockedIncrement(&g_lComponents);
  78. // Initialize the search preferences often used
  79. m_pSearchInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  80. m_pSearchInfo[0].vValue.dwType = ADSTYPE_INTEGER;
  81. m_pSearchInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
  82. m_pSearchInfo[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  83. m_pSearchInfo[1].vValue.dwType = ADSTYPE_INTEGER;
  84. m_pSearchInfo[1].vValue.Integer = 1024;
  85. m_lReferenceCount = 0 ;
  86. m_IWbemServices = NULL;
  87. m_pWbemUin8ArrayClass = NULL;
  88. m_pWbemDNWithBinaryClass = NULL;
  89. m_pWbemDNWithStringClass = NULL;
  90. m_pAssociationsClass = NULL;
  91. m_lpszTopLevelContainerPath = NULL;
  92. m_bInitializedSuccessfully = FALSE;
  93. if(g_pLogObject)
  94. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CONSTRUCTOR\r\n");
  95. }
  96. CLDAPInstanceProvider::~CLDAPInstanceProvider ()
  97. {
  98. if(g_pLogObject)
  99. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DESCTRUVTOR\r\n");
  100. if (m_lpszTopLevelContainerPath)
  101. {
  102. delete [] m_lpszTopLevelContainerPath;
  103. }
  104. if(m_IWbemServices)
  105. m_IWbemServices->Release();
  106. if(m_pWbemUin8ArrayClass)
  107. m_pWbemUin8ArrayClass->Release();
  108. if(m_pWbemDNWithBinaryClass)
  109. m_pWbemDNWithBinaryClass->Release();
  110. if(m_pWbemDNWithStringClass)
  111. m_pWbemDNWithStringClass->Release();
  112. if(m_pAssociationsClass)
  113. m_pAssociationsClass->Release();
  114. InterlockedDecrement(&g_lComponents);
  115. }
  116. //***************************************************************************
  117. //
  118. // CLDAPInstanceProvider::QueryInterface
  119. // CLDAPInstanceProvider::AddRef
  120. // CLDAPInstanceProvider::Release
  121. //
  122. // Purpose: Standard COM routines needed for all COM objects
  123. //
  124. //***************************************************************************
  125. STDMETHODIMP CLDAPInstanceProvider :: QueryInterface (
  126. REFIID iid ,
  127. LPVOID FAR *iplpv
  128. )
  129. {
  130. *iplpv = NULL ;
  131. if ( iid == IID_IUnknown )
  132. {
  133. *iplpv = ( LPVOID ) (IUnknown *)(IWbemProviderInit *)this ;
  134. }
  135. else if ( iid == IID_IWbemServices )
  136. {
  137. *iplpv = ( LPVOID ) (IWbemServices *)this ;
  138. }
  139. else if ( iid == IID_IWbemProviderInit )
  140. {
  141. *iplpv = ( LPVOID ) (IWbemProviderInit *)this ;
  142. }
  143. else
  144. {
  145. return E_NOINTERFACE;
  146. }
  147. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  148. return S_OK;
  149. }
  150. STDMETHODIMP_( ULONG ) CLDAPInstanceProvider :: AddRef ()
  151. {
  152. return InterlockedIncrement ( & m_lReferenceCount ) ;
  153. }
  154. STDMETHODIMP_(ULONG) CLDAPInstanceProvider :: Release ()
  155. {
  156. LONG ref ;
  157. if ( ( ref = InterlockedDecrement ( & m_lReferenceCount ) ) == 0 )
  158. {
  159. delete this ;
  160. return 0 ;
  161. }
  162. else
  163. {
  164. return ref ;
  165. }
  166. }
  167. HRESULT CLDAPInstanceProvider :: Initialize(
  168. LPWSTR wszUser,
  169. LONG lFlags,
  170. LPWSTR wszNamespace,
  171. LPWSTR wszLocale,
  172. IWbemServices __RPC_FAR *pNamespace,
  173. IWbemContext __RPC_FAR *pCtx,
  174. IWbemProviderInitSink __RPC_FAR *pInitSink)
  175. {
  176. // Validate the arguments
  177. if(pNamespace == NULL || lFlags != 0)
  178. {
  179. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Argument validation FAILED\r\n");
  180. pInitSink->SetStatus(WBEM_E_FAILED, 0);
  181. return WBEM_S_NO_ERROR;
  182. }
  183. // Store the IWbemServices pointer for future use
  184. m_IWbemServices = pNamespace;
  185. m_IWbemServices->AddRef();
  186. // Get the DefaultNamingContext to get at the top level container
  187. // Get the ADSI path of the schema container and store it for future use
  188. IADs *pRootDSE = NULL;
  189. HRESULT result;
  190. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)ROOT_DSE_PATH, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID *) &pRootDSE)))
  191. {
  192. // Get the location of the schema container
  193. BSTR strDefaultNamingContext = SysAllocString((LPWSTR) DEFAULT_NAMING_CONTEXT_ATTR);
  194. // Get the DEFAULT_NAMING_CONTEXT property. This property contains the ADSI path
  195. // of the top level container
  196. VARIANT variant;
  197. VariantInit(&variant);
  198. if(SUCCEEDED(result = pRootDSE->Get(strDefaultNamingContext, &variant)))
  199. {
  200. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Got Top Level Container as : %s\r\n", variant.bstrVal);
  201. // Form the top level container path
  202. m_lpszTopLevelContainerPath = new WCHAR[wcslen(LDAP_PREFIX) + wcslen(variant.bstrVal) + 1];
  203. wcscpy(m_lpszTopLevelContainerPath, LDAP_PREFIX);
  204. wcscat(m_lpszTopLevelContainerPath, variant.bstrVal);
  205. // Get the Uint8Array Class
  206. if(SUCCEEDED(result = m_IWbemServices->GetObject(UINT8ARRAY_STR, 0, pCtx, &m_pWbemUin8ArrayClass, NULL)))
  207. {
  208. // Get the DNWIthBinary Class
  209. if(SUCCEEDED(result = m_IWbemServices->GetObject(DN_WITH_BINARY_CLASS_STR, 0, pCtx, &m_pWbemDNWithBinaryClass, NULL)))
  210. {
  211. // Get the DNWIthBinary Class
  212. if(SUCCEEDED(result = m_IWbemServices->GetObject(DN_WITH_STRING_CLASS_STR, 0, pCtx, &m_pWbemDNWithStringClass, NULL)))
  213. {
  214. // Get the Associations Class
  215. if(SUCCEEDED(result = m_IWbemServices->GetObject(INSTANCE_ASSOCIATION_CLASS_STR, 0, pCtx, &m_pAssociationsClass, NULL)))
  216. {
  217. }
  218. else
  219. {
  220. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get Instance Associations class %x\r\n", result);
  221. }
  222. }
  223. else
  224. {
  225. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get DNWithString class %x\r\n", result);
  226. }
  227. }
  228. else
  229. {
  230. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get DNWithBinary class %x\r\n", result);
  231. }
  232. }
  233. else
  234. {
  235. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FAILED to get Uint8Array class %x\r\n", result);
  236. }
  237. VariantClear(&variant);
  238. }
  239. SysFreeString(strDefaultNamingContext);
  240. pRootDSE->Release();
  241. }
  242. if(SUCCEEDED(result))
  243. {
  244. m_bInitializedSuccessfully = TRUE;
  245. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  246. }
  247. else
  248. {
  249. m_bInitializedSuccessfully = FALSE;
  250. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialize() FAILED \r\n");
  251. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  252. }
  253. return WBEM_S_NO_ERROR;
  254. }
  255. HRESULT CLDAPInstanceProvider :: OpenNamespace(
  256. /* [in] */ const BSTR strNamespace,
  257. /* [in] */ long lFlags,
  258. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  259. /* [unique][in][out] */ IWbemServices __RPC_FAR *__RPC_FAR *ppWorkingNamespace,
  260. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppResult)
  261. {
  262. return WBEM_E_NOT_SUPPORTED;
  263. }
  264. HRESULT CLDAPInstanceProvider :: CancelAsyncCall(
  265. /* [in] */ IWbemObjectSink __RPC_FAR *pSink)
  266. {
  267. return WBEM_E_NOT_SUPPORTED;
  268. }
  269. HRESULT CLDAPInstanceProvider :: QueryObjectSink(
  270. /* [in] */ long lFlags,
  271. /* [out] */ IWbemObjectSink __RPC_FAR *__RPC_FAR *ppResponseHandler)
  272. {
  273. return WBEM_E_NOT_SUPPORTED;
  274. }
  275. HRESULT CLDAPInstanceProvider :: GetObject(
  276. /* [in] */ const BSTR strObjectPath,
  277. /* [in] */ long lFlags,
  278. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  279. /* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppObject,
  280. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  281. {
  282. return WBEM_E_NOT_SUPPORTED;
  283. }
  284. HRESULT CLDAPInstanceProvider :: GetObjectAsync(
  285. /* [in] */ const BSTR strObjectPath,
  286. /* [in] */ long lFlags,
  287. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  288. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  289. {
  290. if(!m_bInitializedSuccessfully)
  291. {
  292. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
  293. return WBEM_E_FAILED;
  294. }
  295. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() called for %s \r\n", strObjectPath);
  296. HRESULT result = S_OK;
  297. // Impersonate the client
  298. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  299. {
  300. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() CoImpersonate FAILED for %s with %x\r\n", strObjectPath, result);
  301. return WBEM_E_FAILED;
  302. }
  303. // Validate the arguments
  304. if(strObjectPath == NULL)
  305. {
  306. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() argument validation FAILED\r\n");
  307. return WBEM_E_INVALID_PARAMETER;
  308. }
  309. // Parse the object path
  310. CObjectPathParser theParser;
  311. ParsedObjectPath *theParsedObjectPath = NULL;
  312. switch(theParser.Parse(strObjectPath, &theParsedObjectPath))
  313. {
  314. case CObjectPathParser::NoError:
  315. break;
  316. default:
  317. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() object path parsing FAILED\r\n");
  318. return WBEM_E_INVALID_PARAMETER;
  319. }
  320. try
  321. {
  322. // Check if this is for associations
  323. if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0)
  324. {
  325. // Check whether there are exactly 2 keys specified
  326. if(theParsedObjectPath->m_dwNumKeys != 2)
  327. result = WBEM_E_INVALID_PARAMETER;
  328. // Check whether these keys are
  329. KeyRef *pChildKeyRef = *(theParsedObjectPath->m_paKeys);
  330. KeyRef *pParentKeyRef = *(theParsedObjectPath->m_paKeys + 1);
  331. if(_wcsicmp(pChildKeyRef->m_pName, CHILD_INSTANCE_PROPERTY_STR) != 0)
  332. {
  333. // Exchange them
  334. KeyRef *temp = pChildKeyRef;
  335. pChildKeyRef = pParentKeyRef;
  336. pParentKeyRef = pChildKeyRef;
  337. }
  338. // The status on the sink
  339. IWbemClassObject *ppReturnWbemClassObjects[1];
  340. ppReturnWbemClassObjects[0] = NULL;
  341. if(SUCCEEDED(result))
  342. {
  343. // Convert the key values to ADSI paths
  344. LPWSTR pszChildADSIPath = NULL;
  345. LPWSTR pszParentADSIPath = NULL;
  346. try
  347. {
  348. pszChildADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pChildKeyRef->m_vValue.bstrVal);
  349. pszParentADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pParentKeyRef->m_vValue.bstrVal);
  350. if(SUCCEEDED(result = IsContainedIn(pszChildADSIPath, pszParentADSIPath)))
  351. {
  352. if(result == S_OK)
  353. {
  354. if(SUCCEEDED(result = CreateWBEMInstance(pChildKeyRef->m_vValue.bstrVal, pParentKeyRef->m_vValue.bstrVal, ppReturnWbemClassObjects)))
  355. {
  356. result = pResponseHandler->Indicate(1, ppReturnWbemClassObjects);
  357. ppReturnWbemClassObjects[0]->Release();
  358. }
  359. }
  360. else // the instance was not found
  361. {
  362. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: returning WBEM_E_NOT_FOUND for %s \r\n", strObjectPath);
  363. result = WBEM_E_NOT_FOUND;
  364. }
  365. }
  366. else
  367. {
  368. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: IsContainedIn() FAILED with %x \r\n", result);
  369. }
  370. }
  371. catch ( ... )
  372. {
  373. if ( pszChildADSIPath )
  374. {
  375. delete [] pszChildADSIPath;
  376. pszChildADSIPath = NULL;
  377. }
  378. if ( pszParentADSIPath )
  379. {
  380. delete [] pszParentADSIPath;
  381. pszParentADSIPath = NULL;
  382. }
  383. throw;
  384. }
  385. if ( pszChildADSIPath )
  386. {
  387. delete [] pszChildADSIPath;
  388. pszChildADSIPath = NULL;
  389. }
  390. if ( pszParentADSIPath )
  391. {
  392. delete [] pszParentADSIPath;
  393. pszParentADSIPath = NULL;
  394. }
  395. }
  396. }
  397. // Check if this is for the RootDSE class
  398. else if(_wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0)
  399. {
  400. result = ProcessRootDSEGetObject(theParsedObjectPath->m_pClass, pResponseHandler, pCtx);
  401. }
  402. else // It is for ADSI instances
  403. {
  404. // Check whether there is exactly 1 key specified
  405. if(theParsedObjectPath->m_dwNumKeys != 1 )
  406. result = WBEM_E_INVALID_PARAMETER;
  407. // Get the key
  408. KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
  409. // Check to see that the key name is correct, if it is present
  410. if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
  411. result = WBEM_E_INVALID_PARAMETER;
  412. // The status on the sink
  413. IWbemClassObject *ppReturnWbemClassObjects[1];
  414. ppReturnWbemClassObjects[0] = NULL;
  415. if(SUCCEEDED(result))
  416. {
  417. // Get the ADSI object
  418. CADSIInstance *pADSIObject = NULL;
  419. if(SUCCEEDED(result = CLDAPHelper::GetADSIInstance(pKeyRef->m_vValue.bstrVal, &pADSIObject, g_pLogObject)))
  420. {
  421. try
  422. {
  423. // Get the class to spawn an instance
  424. IWbemClassObject *pWbemClass = NULL;
  425. if(SUCCEEDED(result = m_IWbemServices->GetObject(theParsedObjectPath->m_pClass, 0, pCtx, &pWbemClass, NULL)))
  426. {
  427. try
  428. {
  429. // Spawn a instance of the WBEM Class
  430. if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, ppReturnWbemClassObjects)))
  431. {
  432. // Map it to WBEM
  433. if(SUCCEEDED(result = MapADSIInstance(pADSIObject, ppReturnWbemClassObjects[0], pWbemClass)))
  434. {
  435. // Indicate the result
  436. if(FAILED(result = pResponseHandler->Indicate(1, ppReturnWbemClassObjects)))
  437. {
  438. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : Indicate() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
  439. }
  440. }
  441. else
  442. {
  443. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : MapADSIInstance() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
  444. }
  445. ppReturnWbemClassObjects[0]->Release();
  446. }
  447. else
  448. {
  449. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: SpawnInstance() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
  450. }
  451. }
  452. catch ( ... )
  453. {
  454. pWbemClass->Release();
  455. pWbemClass = NULL;
  456. throw;
  457. }
  458. pWbemClass->Release();
  459. }
  460. else
  461. {
  462. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() GetObject() for %s FAILED with %x \r\n", theParsedObjectPath->m_pClass, result);
  463. }
  464. }
  465. catch ( ... )
  466. {
  467. pADSIObject->Release();
  468. pADSIObject = NULL;
  469. throw;
  470. }
  471. pADSIObject->Release();
  472. }
  473. else
  474. {
  475. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync : GetADSIInstance() FAILED with %x \r\n", result);
  476. }
  477. }
  478. else
  479. {
  480. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: GetObjectAsync() Argument processing FAILED \r\n");
  481. }
  482. }
  483. }
  484. catch ( ... )
  485. {
  486. theParser.Free(theParsedObjectPath);
  487. throw;
  488. }
  489. // Free the parser object path
  490. theParser.Free(theParsedObjectPath);
  491. // Set the status of the request
  492. result = (SUCCEEDED(result)? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND);
  493. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, result, NULL, NULL);
  494. if(SUCCEEDED(result))
  495. g_pLogObject->WriteW( L"XXXXXXXXXXXXXXXXX CLDAPInstanceProvider :: GetObjectAsync() succeeded for %s\r\n", strObjectPath);
  496. else
  497. g_pLogObject->WriteW( L"XXXXXXXXXXXXXXXXX CLDAPInstanceProvider :: GetObjectAsync() FAILED for %s\r\n", strObjectPath);
  498. return WBEM_S_NO_ERROR;
  499. }
  500. HRESULT CLDAPInstanceProvider :: PutClass(
  501. /* [in] */ IWbemClassObject __RPC_FAR *pObject,
  502. /* [in] */ long lFlags,
  503. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  504. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  505. {
  506. return WBEM_E_NOT_SUPPORTED;
  507. }
  508. HRESULT CLDAPInstanceProvider :: PutClassAsync(
  509. /* [in] */ IWbemClassObject __RPC_FAR *pObject,
  510. /* [in] */ long lFlags,
  511. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  512. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  513. {
  514. return WBEM_E_NOT_SUPPORTED;
  515. }
  516. HRESULT CLDAPInstanceProvider :: DeleteClass(
  517. /* [in] */ const BSTR strClass,
  518. /* [in] */ long lFlags,
  519. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  520. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  521. {
  522. return WBEM_E_NOT_SUPPORTED;
  523. }
  524. HRESULT CLDAPInstanceProvider :: DeleteClassAsync(
  525. /* [in] */ const BSTR strClass,
  526. /* [in] */ long lFlags,
  527. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  528. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  529. {
  530. return WBEM_E_NOT_SUPPORTED;
  531. }
  532. HRESULT CLDAPInstanceProvider :: CreateClassEnum(
  533. /* [in] */ const BSTR strClass,
  534. /* [in] */ long lFlags,
  535. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  536. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  537. {
  538. return WBEM_E_NOT_SUPPORTED;
  539. }
  540. HRESULT CLDAPInstanceProvider :: CreateClassEnumAsync(
  541. /* [in] */ const BSTR strClass,
  542. /* [in] */ long lFlags,
  543. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  544. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  545. {
  546. return WBEM_E_NOT_SUPPORTED;
  547. }
  548. HRESULT CLDAPInstanceProvider :: PutInstance(
  549. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  550. /* [in] */ long lFlags,
  551. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  552. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  553. {
  554. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstance() called\r\n");
  555. return WBEM_E_NOT_SUPPORTED;
  556. }
  557. HRESULT CLDAPInstanceProvider :: PutInstanceAsync(
  558. /* [in] */ IWbemClassObject __RPC_FAR *pInst,
  559. /* [in] */ long lFlags,
  560. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  561. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  562. {
  563. if(!m_bInitializedSuccessfully)
  564. {
  565. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
  566. return WBEM_E_FAILED;
  567. }
  568. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() called\r\n");
  569. HRESULT result = WBEM_S_NO_ERROR;
  570. // Impersonate the client
  571. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  572. {
  573. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CoImpersonate FAILED forwith %x\r\n", result);
  574. return WBEM_E_FAILED;
  575. }
  576. // Get the object ref of the instance being put
  577. BSTR strRelPath = NULL;
  578. if(SUCCEEDED(CWBEMHelper::GetBSTRProperty(pInst, RELPATH_STR, &strRelPath)))
  579. {
  580. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() calledfor %s\r\n", strRelPath);
  581. // Check to see if the ADSI Path is present.
  582. // Parse the object path
  583. // Parse the object path
  584. CObjectPathParser theParser;
  585. ParsedObjectPath *theParsedObjectPath = NULL;
  586. LPWSTR pszADSIPath = NULL;
  587. LPWSTR pszWBEMClass = NULL;
  588. LPWSTR pszADSIClass = NULL;
  589. try
  590. {
  591. switch(theParser.Parse((LPWSTR)strRelPath, &theParsedObjectPath))
  592. {
  593. case CObjectPathParser::NoError:
  594. {
  595. KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
  596. // Check to see that there is 1 key specified and that its type is VT_BSTR
  597. if(pKeyRef && theParsedObjectPath->m_dwNumKeys == 1 && pKeyRef->m_vValue.vt == VT_BSTR)
  598. {
  599. try
  600. {
  601. // If the name of the key is specified, check the name
  602. if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
  603. break;
  604. pszADSIPath = new WCHAR[wcslen((*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal) + 1];
  605. wcscpy(pszADSIPath, (*theParsedObjectPath->m_paKeys)->m_vValue.bstrVal);
  606. pszWBEMClass = new WCHAR[wcslen(theParsedObjectPath->m_pClass) + 1];
  607. wcscpy(pszWBEMClass, theParsedObjectPath->m_pClass);
  608. }
  609. catch ( ... )
  610. {
  611. theParser.Free(theParsedObjectPath);
  612. throw;
  613. }
  614. }
  615. break;
  616. }
  617. default:
  618. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() Parsing of RELPATH FAILED\r\n");
  619. SysFreeString(strRelPath);
  620. return WBEM_E_FAILED;
  621. break;
  622. }
  623. try
  624. {
  625. if(pszWBEMClass)
  626. {
  627. // CHeck to see if the class is the containment/RootDSE class, if so disallow the operation
  628. if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0 ||
  629. _wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0 )
  630. {
  631. result = WBEM_E_PROVIDER_NOT_CAPABLE;
  632. }
  633. else
  634. pszADSIClass = CLDAPHelper::UnmangleWBEMNameToLDAP(pszWBEMClass);
  635. }
  636. }
  637. catch ( ... )
  638. {
  639. theParser.Free(theParsedObjectPath);
  640. throw;
  641. }
  642. // Free the parser object path
  643. theParser.Free(theParsedObjectPath);
  644. if ( strRelPath )
  645. {
  646. SysFreeString(strRelPath);
  647. strRelPath = NULL;
  648. }
  649. if ( pszWBEMClass )
  650. {
  651. delete [] pszWBEMClass;
  652. pszWBEMClass = NULL;
  653. }
  654. if(pszADSIPath && pszADSIClass && SUCCEEDED(result))
  655. {
  656. // Try to retreive the existing object
  657. // Get the ADSI object
  658. CADSIInstance *pADSIObject = NULL;
  659. result = CLDAPHelper::GetADSIInstance(pszADSIPath, &pADSIObject, g_pLogObject);
  660. try
  661. {
  662. // Check if the WBEM_FLAG_UPDATE_ONLY flag is specified
  663. if(lFlags & WBEM_FLAG_UPDATE_ONLY)
  664. {
  665. if(!pADSIObject)
  666. result = WBEM_E_FAILED;
  667. }
  668. // Check if the WBEM_FLAG_CREATE_ONLY flag is specified
  669. if(SUCCEEDED(result) && lFlags & WBEM_FLAG_CREATE_ONLY)
  670. {
  671. if(pADSIObject)
  672. result = WBEM_E_ALREADY_EXISTS;
  673. }
  674. else
  675. result = WBEM_S_NO_ERROR;
  676. if(SUCCEEDED(result))
  677. {
  678. if(pADSIObject)
  679. {
  680. if(SUCCEEDED(result = ModifyExistingADSIInstance(pInst, pszADSIPath, pADSIObject, pszADSIClass, pCtx)))
  681. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() ModifyExistingInstance succeeded for %s\r\n", pszADSIPath);
  682. else
  683. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() ModifyExistingInstance FAILED for %s with %x\r\n", pszADSIPath, result);
  684. }
  685. else
  686. {
  687. if(SUCCEEDED(result = CreateNewADSIInstance(pInst, pszADSIPath, pszADSIClass)))
  688. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CreateNewInstance succeeded for %s\r\n", pszADSIPath);
  689. else
  690. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() CreateNewInstance FAILED for %s with %x\r\n", pszADSIPath, result);
  691. }
  692. }
  693. }
  694. catch ( ... )
  695. {
  696. // Release any existing object
  697. if(pADSIObject)
  698. {
  699. pADSIObject->Release();
  700. pADSIObject = NULL;
  701. }
  702. throw;
  703. }
  704. // Release any existing object
  705. if(pADSIObject)
  706. pADSIObject->Release();
  707. }
  708. else
  709. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() one of ADSIPath or ADSIClass is NULL\r\n");
  710. }
  711. catch ( ... )
  712. {
  713. if ( strRelPath )
  714. {
  715. SysFreeString(strRelPath);
  716. strRelPath = NULL;
  717. }
  718. if ( pszWBEMClass )
  719. {
  720. delete [] pszWBEMClass;
  721. pszWBEMClass = NULL;
  722. }
  723. if ( pszADSIClass )
  724. {
  725. delete [] pszADSIClass;
  726. pszADSIClass = NULL;
  727. }
  728. if ( pszADSIPath )
  729. {
  730. delete [] pszADSIPath;
  731. pszADSIPath = NULL;
  732. }
  733. throw;
  734. }
  735. delete [] pszADSIClass;
  736. delete [] pszADSIPath;
  737. }
  738. else
  739. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: PutInstanceAsync() FAILED to get RELPATH \r\n");
  740. // Set the status of the request
  741. result = (SUCCEEDED(result)? WBEM_S_NO_ERROR : WBEM_E_FAILED);
  742. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, result, NULL, NULL);
  743. return result;
  744. }
  745. HRESULT CLDAPInstanceProvider :: DeleteInstance(
  746. /* [in] */ const BSTR strObjectPath,
  747. /* [in] */ long lFlags,
  748. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  749. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  750. {
  751. return WBEM_E_NOT_SUPPORTED;
  752. }
  753. HRESULT CLDAPInstanceProvider :: DeleteInstanceAsync(
  754. /* [in] */ const BSTR strObjectPath,
  755. /* [in] */ long lFlags,
  756. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  757. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  758. {
  759. if(!m_bInitializedSuccessfully)
  760. {
  761. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
  762. return WBEM_E_FAILED;
  763. }
  764. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() called for %s\r\n", strObjectPath);
  765. HRESULT result = S_OK;
  766. // Impersonate the client
  767. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  768. {
  769. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() CoImpersonate FAILED for %s with %x\r\n", strObjectPath, result);
  770. return WBEM_E_FAILED;
  771. }
  772. // Validate the arguments
  773. if(strObjectPath == NULL)
  774. {
  775. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() argument validation FAILED\r\n");
  776. return WBEM_E_INVALID_PARAMETER;
  777. }
  778. // Parse the object path
  779. CObjectPathParser theParser;
  780. ParsedObjectPath *theParsedObjectPath = NULL;
  781. switch(theParser.Parse(strObjectPath, &theParsedObjectPath))
  782. {
  783. case CObjectPathParser::NoError:
  784. break;
  785. default:
  786. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() object path parsing FAILED\r\n");
  787. return WBEM_E_INVALID_PARAMETER;
  788. }
  789. // CHeck to see if the class is the containment/RootDSE class, if so disallow the operation
  790. if(_wcsicmp(theParsedObjectPath->m_pClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0 ||
  791. _wcsicmp(theParsedObjectPath->m_pClass, ROOTDSE_CLASS) == 0 )
  792. {
  793. result = WBEM_E_PROVIDER_NOT_CAPABLE;
  794. }
  795. // Check whether there is exactly 1 key specified
  796. if(theParsedObjectPath->m_dwNumKeys != 1 )
  797. result = WBEM_E_INVALID_PARAMETER;
  798. // Get the key
  799. KeyRef *pKeyRef = *(theParsedObjectPath->m_paKeys);
  800. // Check to see that the key name is correct, if it is present
  801. if(pKeyRef->m_pName && _wcsicmp(pKeyRef->m_pName, ADSI_PATH_STR) != 0)
  802. result = WBEM_E_INVALID_PARAMETER;
  803. // Unfortunately, ADSI uses different interfaces to delete containers and non-containers
  804. //=======================================================================================
  805. if(SUCCEEDED(result))
  806. {
  807. IDirectoryObject *pDirectoryObject = NULL;
  808. if(SUCCEEDED(result = ADsOpenObject(pKeyRef->m_vValue.bstrVal, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *)&pDirectoryObject)))
  809. {
  810. PADS_OBJECT_INFO pObjectInfo = NULL;
  811. if(SUCCEEDED(result = pDirectoryObject->GetObjectInformation(&pObjectInfo)))
  812. {
  813. // CHeck whether it is the same class as the class being deleted.
  814. LPWSTR pszWbemClass = CLDAPHelper::MangleLDAPNameToWBEM(pObjectInfo->pszClassName);
  815. if(_wcsicmp(theParsedObjectPath->m_pClass, pszWbemClass) == 0)
  816. {
  817. // Get its parent. THis should be the container from which the child is deleted
  818. IADsContainer *pParent = NULL;
  819. if(SUCCEEDED(result = ADsOpenObject(pObjectInfo->pszParentDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsContainer, (LPVOID *)&pParent)))
  820. {
  821. if(SUCCEEDED(result = pParent->Delete(pObjectInfo->pszClassName, pObjectInfo->pszRDN)))
  822. {
  823. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() Deleted %s successfully\r\n", pKeyRef->m_vValue.bstrVal);
  824. result = WBEM_S_NO_ERROR;
  825. }
  826. else
  827. {
  828. if (HRESULT_CODE(result) == ERROR_DS_CANT_ON_NON_LEAF)
  829. {
  830. // this is non-empty container we wanted to delete here
  831. IADsDeleteOps *pADsDeleteOps = NULL;
  832. if(SUCCEEDED(result = ADsOpenObject(pKeyRef->m_vValue.bstrVal, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsDeleteOps, (LPVOID *)&pADsDeleteOps)))
  833. {
  834. if(FAILED(result = pADsDeleteOps->DeleteObject(0)))
  835. {
  836. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() DeleteObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
  837. if ( result == ERROR_DS_AUTH_METHOD_NOT_SUPPORTED )
  838. {
  839. result = WBEM_E_ACCESS_DENIED;
  840. }
  841. else
  842. {
  843. result = WBEM_E_FAILED;
  844. }
  845. }
  846. pADsDeleteOps->Release();
  847. }
  848. }
  849. else
  850. {
  851. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() DeleteDSObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
  852. result = WBEM_E_FAILED;
  853. }
  854. }
  855. pParent->Release();
  856. }
  857. else
  858. {
  859. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() ADsOpenObject on parent FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
  860. result = WBEM_E_FAILED;
  861. }
  862. }
  863. else
  864. {
  865. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() wrong class returning success\r\n");
  866. result = WBEM_S_NO_ERROR;
  867. }
  868. delete [] pszWbemClass;
  869. FreeADsMem((LPVOID *) pObjectInfo);
  870. }
  871. else
  872. {
  873. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() GetObjectInformation FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
  874. result = WBEM_E_NOT_FOUND;
  875. }
  876. pDirectoryObject->Release();
  877. }
  878. else
  879. {
  880. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: DeleteInstanceAsync() ADsOpenObject FAILED on %s with %x\r\n", pKeyRef->m_vValue.bstrVal, result);
  881. result = WBEM_E_NOT_FOUND;
  882. }
  883. }
  884. // Free the parser object path
  885. theParser.Free(theParsedObjectPath);
  886. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE , result, NULL, NULL);
  887. return WBEM_S_NO_ERROR;
  888. }
  889. HRESULT CLDAPInstanceProvider :: CreateInstanceEnum(
  890. /* [in] */ const BSTR strClass,
  891. /* [in] */ long lFlags,
  892. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  893. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  894. {
  895. return WBEM_E_NOT_SUPPORTED;
  896. }
  897. HRESULT CLDAPInstanceProvider :: CreateInstanceEnumAsync(
  898. /* [in] */ const BSTR strClass,
  899. /* [in] */ long lFlags,
  900. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  901. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  902. {
  903. if(!m_bInitializedSuccessfully)
  904. {
  905. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
  906. return WBEM_E_FAILED;
  907. }
  908. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync() called for %s Class \r\n", strClass );
  909. HRESULT result;
  910. // Impersonate the client
  911. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  912. {
  913. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync() CoImpersonate FAILED for %s with %x\r\n", strClass, result);
  914. return WBEM_E_FAILED;
  915. }
  916. // CHeck to see if the class is the containment class, if so disallow an enumeration
  917. if(_wcsicmp(strClass, INSTANCE_ASSOCIATION_CLASS_STR) == 0)
  918. {
  919. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CLDAPInstanceProvider() Enumeration called on the containment class. Returning FAILED : WBEM_E_PROVIDER_NOT_CAPABLE\r\n");
  920. return WBEM_E_PROVIDER_NOT_CAPABLE;
  921. }
  922. // Check if this is for the RootDSE class
  923. else if(_wcsicmp(strClass, ROOTDSE_CLASS) == 0)
  924. {
  925. result = ProcessRootDSEGetObject(strClass, pResponseHandler, pCtx);
  926. }
  927. else // The rest of the classes
  928. {
  929. // Fetch the class from CIMOM
  930. IWbemClassObject *pWbemClass = NULL;
  931. if(SUCCEEDED(result = m_IWbemServices->GetObject(strClass, 0, pCtx, &pWbemClass, NULL)))
  932. {
  933. // We need the object category information
  934. LPWSTR pszLDAPQuery = new WCHAR[10*(wcslen(strClass) + 25) + 50];
  935. if(SUCCEEDED(CWBEMHelper::FormulateInstanceQuery(m_IWbemServices, pCtx, strClass, pWbemClass, pszLDAPQuery, LDAP_DISPLAY_NAME_STR, DEFAULT_OBJECT_CATEGORY_STR)))
  936. {
  937. // Check to see if the client has specified any hints as to the DN of the object from
  938. // which the search should start
  939. BOOLEAN bRootDNSpecified = FALSE;
  940. LPWSTR *ppszRootDN = NULL;
  941. DWORD dwRootDNCount = 0;
  942. if(SUCCEEDED(GetRootDN(strClass, &ppszRootDN, &dwRootDNCount, pCtx)) && dwRootDNCount)
  943. bRootDNSpecified = TRUE;
  944. // Enumerate the ADSI Instances
  945. // If any RootDNs were specified, use them. Otherwise use the default naming context
  946. if(bRootDNSpecified)
  947. {
  948. for( DWORD i=0; i<dwRootDNCount; i++)
  949. {
  950. DoSingleQuery(strClass, pWbemClass, ppszRootDN[i], pszLDAPQuery, pResponseHandler);
  951. }
  952. }
  953. else
  954. {
  955. DoSingleQuery(strClass, pWbemClass, m_lpszTopLevelContainerPath, pszLDAPQuery, pResponseHandler);
  956. }
  957. if(bRootDNSpecified)
  958. {
  959. for(DWORD i=0; i<dwRootDNCount; i++)
  960. {
  961. delete [] ppszRootDN[i];
  962. }
  963. delete [] ppszRootDN;
  964. }
  965. }
  966. else
  967. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync : FormulateInstanceQuery() FAILED for %s with %x \r\n", strClass, result);
  968. delete [] pszLDAPQuery;
  969. pWbemClass->Release();
  970. }
  971. else
  972. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync : GetObject() FAILED for %s with %x \r\n", strClass, result);
  973. }
  974. if(SUCCEEDED(result))
  975. {
  976. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
  977. g_pLogObject->WriteW( L"XXXXXXXXXXXXX CLDAPInstanceProvider :: CreateInstanceEnumAsync() Enumeration succeeded for %s\r\n", strClass);
  978. return WBEM_S_NO_ERROR;
  979. }
  980. else
  981. {
  982. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_FAILED, NULL, NULL);
  983. g_pLogObject->WriteW( L"XXXXXXXXXXXXX CLDAPInstanceProvider :: CreateInstanceEnumAsync() Enumeration FAILED for %s\r\n", strClass);
  984. return WBEM_S_NO_ERROR;
  985. }
  986. }
  987. HRESULT CLDAPInstanceProvider :: ExecQuery(
  988. /* [in] */ const BSTR strQueryLanguage,
  989. /* [in] */ const BSTR strQuery,
  990. /* [in] */ long lFlags,
  991. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  992. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  993. {
  994. return WBEM_E_NOT_SUPPORTED;
  995. }
  996. HRESULT CLDAPInstanceProvider :: ExecQueryAsync(
  997. /* [in] */ const BSTR strQueryLanguage,
  998. /* [in] */ const BSTR strQuery,
  999. /* [in] */ long lFlags,
  1000. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1001. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1002. {
  1003. if(!m_bInitializedSuccessfully)
  1004. {
  1005. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: Initialization status is FAILED, hence returning failure\n");
  1006. return WBEM_E_FAILED;
  1007. }
  1008. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() called with %s\r\n", strQuery);
  1009. HRESULT result;
  1010. // Impersonate the client
  1011. if(!SUCCEEDED(result = WbemCoImpersonateClient()))
  1012. {
  1013. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() CoImpersonate FAILED for %s with %x\r\n", strQuery, result);
  1014. return WBEM_E_FAILED;
  1015. }
  1016. // Create Parser for the Query.
  1017. CTextLexSource src(strQuery);
  1018. SQL1_Parser parser(&src);
  1019. // Get the class name
  1020. wchar_t classbuf[128];
  1021. *classbuf = 0;
  1022. parser.GetQueryClass(classbuf, 127);
  1023. // Compare to see if it is the association class, Otherwise do an enuemration
  1024. if(_wcsicmp(classbuf, INSTANCE_ASSOCIATION_CLASS_STR) != 0)
  1025. {
  1026. BSTR strClass = SysAllocString((LPWSTR)classbuf);
  1027. // Ask CIMOM to postprocess the result
  1028. pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_S_NO_ERROR, NULL, NULL);
  1029. // Try to process the query myself. If not successful, enumerate
  1030. if(SUCCEEDED(result = ProcessInstanceQuery(strClass, strQuery, pCtx, pResponseHandler, &parser)))
  1031. {
  1032. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
  1033. }
  1034. else
  1035. {
  1036. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ExecQueryAsync() FAILED to process query %s. Resorting to enumeration\r\n", strQuery);
  1037. CreateInstanceEnumAsync(strClass, 0, pCtx, pResponseHandler);
  1038. }
  1039. SysFreeString(strClass);
  1040. }
  1041. else
  1042. {
  1043. // Process query for associations
  1044. result = ProcessAssociationQuery(pCtx, pResponseHandler, &parser);
  1045. }
  1046. return WBEM_S_NO_ERROR;
  1047. }
  1048. HRESULT CLDAPInstanceProvider :: ExecNotificationQuery(
  1049. /* [in] */ const BSTR strQueryLanguage,
  1050. /* [in] */ const BSTR strQuery,
  1051. /* [in] */ long lFlags,
  1052. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1053. /* [out] */ IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum)
  1054. {
  1055. return WBEM_E_NOT_SUPPORTED;
  1056. }
  1057. HRESULT CLDAPInstanceProvider :: ExecNotificationQueryAsync(
  1058. /* [in] */ const BSTR strQueryLanguage,
  1059. /* [in] */ const BSTR strQuery,
  1060. /* [in] */ long lFlags,
  1061. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1062. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1063. {
  1064. return WBEM_E_NOT_SUPPORTED;
  1065. }
  1066. HRESULT CLDAPInstanceProvider :: ExecMethod(
  1067. /* [in] */ const BSTR strObjectPath,
  1068. /* [in] */ const BSTR strMethodName,
  1069. /* [in] */ long lFlags,
  1070. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1071. /* [in] */ IWbemClassObject __RPC_FAR *pInParams,
  1072. /* [unique][in][out] */ IWbemClassObject __RPC_FAR *__RPC_FAR *ppOutParams,
  1073. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppCallResult)
  1074. {
  1075. return WBEM_E_NOT_SUPPORTED;
  1076. }
  1077. HRESULT CLDAPInstanceProvider :: ExecMethodAsync(
  1078. /* [in] */ const BSTR strObjectPath,
  1079. /* [in] */ const BSTR strMethodName,
  1080. /* [in] */ long lFlags,
  1081. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  1082. /* [in] */ IWbemClassObject __RPC_FAR *pInParams,
  1083. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  1084. {
  1085. return WBEM_E_NOT_SUPPORTED;
  1086. }
  1087. // Maps an ADSI Instance to WBEM
  1088. HRESULT CLDAPInstanceProvider :: MapADSIInstance(CADSIInstance *pADSIObject, IWbemClassObject *pWbemObject, IWbemClassObject *pWbemClass)
  1089. {
  1090. DWORD dwNumAttributes = 0;
  1091. PADS_ATTR_INFO pAttributeEntries = pADSIObject->GetAttributes(&dwNumAttributes);
  1092. HRESULT result;
  1093. for(DWORD i=0; i<dwNumAttributes; i++)
  1094. {
  1095. PADS_ATTR_INFO pNextAttribute = pAttributeEntries+i;
  1096. // Get the WBEM Property Name
  1097. LPWSTR pszWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pNextAttribute->pszAttrName);
  1098. BSTR strWbemName = SysAllocString(pszWbemName);
  1099. delete[] pszWbemName;
  1100. // No point in checking the return code, except for logging
  1101. if(SUCCEEDED(result = MapPropertyValueToWBEM(strWbemName, pWbemClass, pWbemObject, pNextAttribute)))
  1102. {
  1103. }
  1104. else if( result != WBEM_E_NOT_FOUND )
  1105. {
  1106. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() MapPropertyValueToWBEM FAILED with %x for attribute %s\r\n", result, strWbemName);
  1107. }
  1108. SysFreeString(strWbemName);
  1109. }
  1110. // Map the key property and other properties of the base-most class
  1111. PADS_OBJECT_INFO pObjectInfo = pADSIObject->GetObjectInfo();
  1112. if(!SUCCEEDED(result = CWBEMHelper::PutBSTRPropertyT(pWbemObject, ADSI_PATH_STR, pObjectInfo->pszObjectDN, FALSE)))
  1113. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() Put FAILED for Key Property with %x\r\n", result);
  1114. return S_OK;
  1115. }
  1116. // Gets the IDIrectoryObject interface on an ADSI instance
  1117. HRESULT CLDAPInstanceProvider :: MapPropertyValueToWBEM(BSTR strWbemName, IWbemClassObject *pWbemClass, IWbemClassObject *pWbemObject, PADS_ATTR_INFO pAttribute)
  1118. {
  1119. // This happens in WMI Stress sometimes.
  1120. if(pAttribute->dwADsType == ADSTYPE_INVALID || pAttribute->dwADsType == ADSTYPE_PROV_SPECIFIC)
  1121. return E_FAIL;
  1122. VARIANT variant;
  1123. VariantInit(&variant);
  1124. CIMTYPE cimType;
  1125. // Get the CIM TYPE of the property
  1126. VARIANT dummyUnused;
  1127. VariantInit(&dummyUnused);
  1128. HRESULT result = pWbemClass->Get(strWbemName, 0, &dummyUnused, &cimType, NULL);
  1129. VariantClear(&dummyUnused);
  1130. // Whether the value was mapped successfully;
  1131. BOOLEAN bMappedValue = FALSE;
  1132. if(SUCCEEDED(result))
  1133. {
  1134. if(cimType & CIM_FLAG_ARRAY)
  1135. {
  1136. switch(cimType & ~CIM_FLAG_ARRAY)
  1137. {
  1138. case CIM_BOOLEAN:
  1139. {
  1140. // Create the safe array elements
  1141. SAFEARRAY *safeArray;
  1142. DWORD dwLength = pAttribute->dwNumValues;
  1143. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1144. safeArrayBounds[0].lLbound = 0;
  1145. safeArrayBounds[0].cElements = dwLength;
  1146. safeArray = SafeArrayCreate(VT_BOOL, 1, safeArrayBounds);
  1147. PADSVALUE pNextValue = pAttribute->pADsValues;
  1148. for ( long index = 0; index<(long)dwLength; index ++ )
  1149. {
  1150. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , &(pNextValue->Boolean))))
  1151. break;
  1152. pNextValue ++;
  1153. }
  1154. if(SUCCEEDED(result))
  1155. {
  1156. variant.vt = VT_ARRAY | VT_BOOL;
  1157. variant.parray = safeArray;
  1158. bMappedValue = TRUE;
  1159. }
  1160. else
  1161. SafeArrayDestroy(safeArray);
  1162. break;
  1163. }
  1164. case CIM_SINT32:
  1165. {
  1166. // Create the safe array elements
  1167. SAFEARRAY *safeArray;
  1168. DWORD dwLength = pAttribute->dwNumValues;
  1169. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1170. safeArrayBounds[0].lLbound = 0;
  1171. safeArrayBounds[0].cElements = dwLength;
  1172. safeArray = SafeArrayCreate(VT_I4, 1, safeArrayBounds);
  1173. PADSVALUE pNextValue = pAttribute->pADsValues;
  1174. for ( long index = 0; index<(long)dwLength; index ++ )
  1175. {
  1176. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , &(pNextValue->Integer))))
  1177. break;
  1178. pNextValue ++;
  1179. }
  1180. if(SUCCEEDED(result))
  1181. {
  1182. variant.vt = VT_ARRAY | VT_I4;
  1183. variant.parray = safeArray;
  1184. bMappedValue = TRUE;
  1185. }
  1186. else
  1187. SafeArrayDestroy(safeArray);
  1188. break;
  1189. }
  1190. case CIM_SINT64:
  1191. {
  1192. // Create the safe array elements
  1193. SAFEARRAY *safeArray;
  1194. DWORD dwLength = pAttribute->dwNumValues;
  1195. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1196. safeArrayBounds[0].lLbound = 0;
  1197. safeArrayBounds[0].cElements = dwLength;
  1198. safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
  1199. PADSVALUE pNextValue = pAttribute->pADsValues;
  1200. WCHAR temp[22]; // number of characters for biggest i64 plus sign and terminator
  1201. BSTR strTemp = NULL;
  1202. for ( long index = 0; index<(long)dwLength; index ++ )
  1203. {
  1204. swprintf(temp, L"%I64d", (pNextValue->LargeInteger).QuadPart);
  1205. strTemp = SysAllocString(temp);
  1206. OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
  1207. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
  1208. {
  1209. break;
  1210. }
  1211. pNextValue ++;
  1212. }
  1213. if(SUCCEEDED(result))
  1214. {
  1215. variant.vt = VT_ARRAY | VT_BSTR;
  1216. variant.parray = safeArray;
  1217. bMappedValue = TRUE;
  1218. }
  1219. else
  1220. SafeArrayDestroy(safeArray);
  1221. break;
  1222. }
  1223. case CIM_STRING:
  1224. {
  1225. // Create the safe array elements
  1226. SAFEARRAY *safeArray;
  1227. DWORD dwLength = pAttribute->dwNumValues;
  1228. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1229. safeArrayBounds[0].lLbound = 0;
  1230. safeArrayBounds[0].cElements = dwLength;
  1231. safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
  1232. PADSVALUE pNextValue = pAttribute->pADsValues;
  1233. BSTR strTemp = NULL;
  1234. for ( long index = 0; index<(long)dwLength; index ++ )
  1235. {
  1236. strTemp = SysAllocString(pNextValue->DNString);
  1237. OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
  1238. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
  1239. {
  1240. break;
  1241. }
  1242. pNextValue ++;
  1243. }
  1244. if(SUCCEEDED(result))
  1245. {
  1246. variant.vt = VT_ARRAY | VT_BSTR;
  1247. variant.parray = safeArray;
  1248. bMappedValue = TRUE;
  1249. }
  1250. else
  1251. SafeArrayDestroy(safeArray);
  1252. break;
  1253. }
  1254. case CIM_DATETIME:
  1255. {
  1256. // Create the safe array elements
  1257. SAFEARRAY *safeArray;
  1258. DWORD dwLength = pAttribute->dwNumValues;
  1259. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1260. safeArrayBounds[0].lLbound = 0;
  1261. safeArrayBounds[0].cElements = dwLength;
  1262. safeArray = SafeArrayCreate(VT_BSTR, 1, safeArrayBounds);
  1263. PADSVALUE pNextValue = pAttribute->pADsValues;
  1264. BSTR strTemp = NULL;
  1265. for ( long index = 0; index<(long)dwLength; index ++ )
  1266. {
  1267. WBEMTime wbemValue(pNextValue->UTCTime);
  1268. strTemp = wbemValue.GetDMTF(TRUE);
  1269. OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> dm(strTemp);
  1270. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , strTemp)))
  1271. {
  1272. break;
  1273. }
  1274. pNextValue ++;
  1275. }
  1276. if(SUCCEEDED(result))
  1277. {
  1278. variant.vt = VT_ARRAY | VT_BSTR;
  1279. variant.parray = safeArray;
  1280. bMappedValue = TRUE;
  1281. }
  1282. else
  1283. SafeArrayDestroy(safeArray);
  1284. break;
  1285. }
  1286. case CIM_OBJECT:
  1287. {
  1288. // Get its cimType Qualifier to determine the "type" of the embedded object
  1289. IWbemQualifierSet *pQualifierSet = NULL;
  1290. if(SUCCEEDED(pWbemClass->GetPropertyQualifierSet(strWbemName, &pQualifierSet)))
  1291. {
  1292. LPWSTR pszQualifierValue = NULL;
  1293. if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, CIMTYPE_STR, &pszQualifierValue, NULL)))
  1294. {
  1295. // Create the safe array elements
  1296. SAFEARRAY *safeArray;
  1297. DWORD dwLength = pAttribute->dwNumValues;
  1298. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1299. safeArrayBounds[0].lLbound = 0;
  1300. safeArrayBounds[0].cElements = dwLength;
  1301. safeArray = SafeArrayCreate(VT_UNKNOWN, 1, safeArrayBounds);
  1302. PADSVALUE pNextValue = pAttribute->pADsValues;
  1303. IUnknown *pNextObject = NULL;
  1304. for ( long index = 0; index<(long)dwLength; index ++ )
  1305. {
  1306. // Put the Embedded object in the array
  1307. if(SUCCEEDED(MapEmbeddedObjectToWBEM(pNextValue, pszQualifierValue, &pNextObject)))
  1308. {
  1309. OnDelete<IUnknown *,VOID(*)(IUnknown *),RM> dm(pNextObject);
  1310. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , pNextObject)))
  1311. {
  1312. break;
  1313. }
  1314. pNextObject = NULL;
  1315. }
  1316. else
  1317. break;
  1318. pNextValue ++;
  1319. }
  1320. if(SUCCEEDED(result))
  1321. {
  1322. variant.vt = VT_ARRAY | VT_UNKNOWN;
  1323. variant.parray = safeArray;
  1324. if(index == (long)dwLength)
  1325. bMappedValue = TRUE;
  1326. }
  1327. else
  1328. SafeArrayDestroy(safeArray);
  1329. delete[] pszQualifierValue;
  1330. }
  1331. pQualifierSet->Release();
  1332. }
  1333. break;
  1334. }
  1335. default:
  1336. break;
  1337. }
  1338. }
  1339. else
  1340. {
  1341. switch(cimType)
  1342. {
  1343. case CIM_BOOLEAN:
  1344. variant.vt = VT_BOOL;
  1345. variant.boolVal = (pAttribute->pADsValues->Boolean)? VARIANT_TRUE : VARIANT_FALSE;
  1346. bMappedValue = TRUE;
  1347. break;
  1348. case CIM_SINT32:
  1349. variant.vt = VT_I4;
  1350. variant.lVal = pAttribute->pADsValues->Integer;
  1351. bMappedValue = TRUE;
  1352. break;
  1353. case CIM_SINT64:
  1354. variant.vt = VT_BSTR;
  1355. WCHAR temp[22]; // number of characters for biggest i64 plus sign an terminator
  1356. swprintf(temp, L"%I64d", (pAttribute->pADsValues->LargeInteger).QuadPart);
  1357. variant.bstrVal = SysAllocString(temp);
  1358. bMappedValue = TRUE;
  1359. break;
  1360. case CIM_STRING:
  1361. variant.vt = VT_BSTR;
  1362. if(pAttribute->pADsValues->DNString)
  1363. {
  1364. variant.bstrVal = SysAllocString(pAttribute->pADsValues->DNString);
  1365. bMappedValue = TRUE;
  1366. }
  1367. break;
  1368. case CIM_OBJECT:
  1369. {
  1370. // Get its cimType Qualifier to determine the "type" of the embedded object
  1371. IWbemQualifierSet *pQualifierSet = NULL;
  1372. if(SUCCEEDED(pWbemClass->GetPropertyQualifierSet(strWbemName, &pQualifierSet)))
  1373. {
  1374. LPWSTR pszQualifierValue = NULL;
  1375. if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, CIMTYPE_STR, &pszQualifierValue, NULL)))
  1376. {
  1377. IUnknown *pEmbeddedObject = NULL;
  1378. if(SUCCEEDED(MapEmbeddedObjectToWBEM(pAttribute->pADsValues, pszQualifierValue, &pEmbeddedObject)))
  1379. {
  1380. variant.vt = VT_UNKNOWN;
  1381. variant.punkVal = pEmbeddedObject;
  1382. bMappedValue = TRUE;
  1383. }
  1384. delete[] pszQualifierValue;
  1385. }
  1386. pQualifierSet->Release();
  1387. }
  1388. }
  1389. break;
  1390. case CIM_DATETIME:
  1391. {
  1392. variant.vt = VT_BSTR;
  1393. WBEMTime wbemValue(pAttribute->pADsValues->UTCTime);
  1394. if(variant.bstrVal = wbemValue.GetDMTF(TRUE))
  1395. bMappedValue = TRUE;
  1396. }
  1397. break;
  1398. default:
  1399. break;
  1400. }
  1401. }
  1402. }
  1403. if(bMappedValue && FAILED(result = pWbemObject->Put(strWbemName, 0, &variant, NULL)))
  1404. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapADSIInstance() Put FAILED for %s with %x\r\n", strWbemName, result);
  1405. VariantClear(&variant);
  1406. return result;
  1407. }
  1408. HRESULT CLDAPInstanceProvider :: MapEmbeddedObjectToWBEM(PADSVALUE pAttribute, LPCWSTR pszQualifierName, IUnknown **ppEmbeddedObject)
  1409. {
  1410. HRESULT result = WBEM_E_FAILED;
  1411. // Skip the "object:" prefix while comparing
  1412. //===========================================
  1413. if (_wcsicmp(pszQualifierName+7, UINT8ARRAY_STR) == 0)
  1414. result = MapUint8ArrayToWBEM(pAttribute, ppEmbeddedObject);
  1415. else if(_wcsicmp(pszQualifierName+7, DN_WITH_BINARY_CLASS_STR) == 0)
  1416. result = MapDNWithBinaryToWBEM(pAttribute, ppEmbeddedObject);
  1417. else if (_wcsicmp(pszQualifierName+7, DN_WITH_STRING_CLASS_STR) == 0)
  1418. result = MapDNWithStringToWBEM(pAttribute, ppEmbeddedObject);
  1419. else
  1420. result = E_FAIL;
  1421. return result;
  1422. }
  1423. HRESULT CLDAPInstanceProvider :: MapUint8ArrayToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
  1424. {
  1425. HRESULT result = E_FAIL;
  1426. *ppEmbeddedObject = NULL;
  1427. IWbemClassObject *pEmbeddedObject;
  1428. if(SUCCEEDED(result = m_pWbemUin8ArrayClass->SpawnInstance(0, &pEmbeddedObject)))
  1429. {
  1430. if(SUCCEEDED(result = MapByteArray((pAttribute->OctetString).lpValue ,(pAttribute->OctetString).dwLength, VALUE_PROPERTY_STR, pEmbeddedObject)))
  1431. {
  1432. // Get the IUnknown interface of the embedded object
  1433. if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
  1434. {
  1435. }
  1436. }
  1437. pEmbeddedObject->Release();
  1438. }
  1439. return result;
  1440. }
  1441. HRESULT CLDAPInstanceProvider :: MapByteArray(LPBYTE lpBinaryValue, DWORD dwLength, const BSTR strPropertyName, IWbemClassObject *pInstance)
  1442. {
  1443. HRESULT result = S_OK;
  1444. // Create the safe array of uint8 elements
  1445. SAFEARRAY *safeArray = NULL;
  1446. SAFEARRAYBOUND safeArrayBounds [ 1 ];
  1447. safeArrayBounds[0].lLbound = 0;
  1448. safeArrayBounds[0].cElements = dwLength;
  1449. safeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBounds);
  1450. for ( long index = 0; index<(long)dwLength; index ++ )
  1451. {
  1452. if(FAILED(result = SafeArrayPutElement ( safeArray , &index , lpBinaryValue+index)))
  1453. break;
  1454. }
  1455. if(SUCCEEDED(result))
  1456. {
  1457. VARIANT embeddedVariant;
  1458. VariantInit(&embeddedVariant);
  1459. embeddedVariant.vt = VT_ARRAY | VT_UI1;
  1460. embeddedVariant.parray = safeArray;
  1461. result = pInstance->Put(strPropertyName, 0, &embeddedVariant, 0);
  1462. VariantClear(&embeddedVariant);
  1463. }
  1464. else
  1465. SafeArrayDestroy(safeArray);
  1466. return result;
  1467. }
  1468. HRESULT CLDAPInstanceProvider :: MapDNWithBinaryToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
  1469. {
  1470. HRESULT result = E_FAIL;
  1471. IWbemClassObject *pEmbeddedObject;
  1472. if(SUCCEEDED(result = m_pWbemDNWithBinaryClass->SpawnInstance(0, &pEmbeddedObject)))
  1473. {
  1474. if(pAttribute->pDNWithBinary->pszDNString && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, DN_STRING_PROPERTY_STR, SysAllocString(pAttribute->pDNWithBinary->pszDNString), TRUE)))
  1475. {
  1476. if(SUCCEEDED(result = MapByteArray(pAttribute->pDNWithBinary->lpBinaryValue, pAttribute->pDNWithBinary->dwLength, VALUE_PROPERTY_STR, pEmbeddedObject)))
  1477. {
  1478. // Get the IUnknown interface of the embedded object
  1479. if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
  1480. {
  1481. }
  1482. }
  1483. }
  1484. pEmbeddedObject->Release();
  1485. }
  1486. return result;
  1487. }
  1488. HRESULT CLDAPInstanceProvider :: MapDNWithStringToWBEM(PADSVALUE pAttribute, IUnknown **ppEmbeddedObject)
  1489. {
  1490. HRESULT result = E_FAIL;
  1491. IWbemClassObject *pEmbeddedObject;
  1492. if(SUCCEEDED(result = m_pWbemDNWithStringClass->SpawnInstance(0, &pEmbeddedObject)))
  1493. {
  1494. if(pAttribute->pDNWithString->pszDNString && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, DN_STRING_PROPERTY_STR, SysAllocString(pAttribute->pDNWithString->pszDNString), TRUE)))
  1495. {
  1496. if(pAttribute->pDNWithString->pszStringValue && SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(pEmbeddedObject, VALUE_PROPERTY_STR, SysAllocString(pAttribute->pDNWithString->pszStringValue), TRUE)))
  1497. {
  1498. // Get the IUnknown interface of the embedded object
  1499. if(SUCCEEDED(result = pEmbeddedObject->QueryInterface(IID_IUnknown, (LPVOID *)ppEmbeddedObject)))
  1500. {
  1501. }
  1502. }
  1503. }
  1504. pEmbeddedObject->Release();
  1505. }
  1506. return result;
  1507. }
  1508. //***************************************************************************
  1509. //
  1510. // CLDAPInstanceProvider::IsContainedIn
  1511. //
  1512. // Purpose: See Header File
  1513. //
  1514. //***************************************************************************
  1515. HRESULT CLDAPInstanceProvider :: IsContainedIn(LPCWSTR pszChildInstance, LPCWSTR pszParentInstance)
  1516. {
  1517. IDirectoryObject *pDirectoryObject = NULL;
  1518. HRESULT result = S_FALSE;
  1519. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszChildInstance, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pDirectoryObject)))
  1520. {
  1521. PADS_OBJECT_INFO pObjectInfo = NULL;
  1522. if(SUCCEEDED(result = pDirectoryObject->GetObjectInformation(&pObjectInfo)))
  1523. {
  1524. if(_wcsicmp(pszParentInstance, pObjectInfo->pszParentDN) == 0)
  1525. result = S_OK;
  1526. else
  1527. result = S_FALSE;
  1528. FreeADsMem((LPVOID *)pObjectInfo);
  1529. }
  1530. pDirectoryObject->Release();
  1531. }
  1532. return result;
  1533. }
  1534. //***************************************************************************
  1535. //
  1536. // CLDAPInstanceProvider::CreateWBEMInstance
  1537. //
  1538. // Purpose: See Header File
  1539. //
  1540. //***************************************************************************
  1541. HRESULT CLDAPInstanceProvider :: CreateWBEMInstance(BSTR strChildName, BSTR strParentName, IWbemClassObject **ppInstance)
  1542. {
  1543. HRESULT result;
  1544. if(SUCCEEDED(result = m_pAssociationsClass->SpawnInstance(0, ppInstance)))
  1545. {
  1546. // Put the property values
  1547. if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, CHILD_INSTANCE_PROPERTY_STR, strChildName, FALSE)))
  1548. {
  1549. if(SUCCEEDED(result = CWBEMHelper::PutBSTRProperty(*ppInstance, PARENT_INSTANCE_PROPERTY_STR, strParentName, FALSE)))
  1550. {
  1551. }
  1552. else
  1553. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateWBEMInstance() PutBSTRProperty on parent property FAILED %x \r\n", result);
  1554. }
  1555. else
  1556. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateWBEMInstance() PutBSTRProperty on child property FAILED %x \r\n", result);
  1557. }
  1558. return result;
  1559. }
  1560. //***************************************************************************
  1561. //
  1562. // CLDAPInstanceProvider::DoChildContainmentQuery
  1563. //
  1564. // Purpose: See Header File
  1565. //
  1566. //***************************************************************************
  1567. HRESULT CLDAPInstanceProvider :: DoChildContainmentQuery(LPCWSTR pszChildPath, IWbemObjectSink *pResponseHandler, CNamesList *pListIndicatedSoFar)
  1568. {
  1569. IDirectoryObject *pChildObject = NULL;
  1570. HRESULT result = S_FALSE;
  1571. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszChildPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pChildObject)))
  1572. {
  1573. PADS_OBJECT_INFO pChildInfo = NULL;
  1574. if(SUCCEEDED(result = pChildObject->GetObjectInformation(&pChildInfo)))
  1575. {
  1576. IDirectoryObject *pParentObject = NULL;
  1577. if(SUCCEEDED(result = ADsOpenObject(pChildInfo->pszParentDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *) &pParentObject)))
  1578. {
  1579. PADS_OBJECT_INFO pParentInfo = NULL;
  1580. if(SUCCEEDED(result = pParentObject->GetObjectInformation(&pParentInfo)))
  1581. {
  1582. IWbemClassObject *pAssociationInstance = NULL;
  1583. // Get the WBEM names of the LDAP classes
  1584. LPWSTR pszChildClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pChildInfo->pszClassName);
  1585. LPWSTR pszParentClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(pParentInfo->pszClassName);
  1586. BSTR strChildPath = CWBEMHelper::GetObjectRefFromADSIPath(pszChildPath, pszChildClassWbemName);
  1587. BSTR strParentPath = CWBEMHelper::GetObjectRefFromADSIPath(pParentInfo->pszObjectDN, pszParentClassWbemName);
  1588. delete [] pszChildClassWbemName;
  1589. delete [] pszParentClassWbemName;
  1590. // Check to see if it has already been indicated
  1591. LPWSTR pszCombinedName = NULL;
  1592. if(pszCombinedName = new WCHAR[wcslen(pszChildPath) + wcslen(pParentInfo->pszObjectDN) + 1])
  1593. {
  1594. wcscpy(pszCombinedName,pszChildPath);
  1595. wcscat(pszCombinedName,pParentInfo->pszObjectDN);
  1596. if(!pListIndicatedSoFar->IsNamePresent(pszCombinedName))
  1597. {
  1598. if(SUCCEEDED(result = CreateWBEMInstance(strChildPath, strParentPath, &pAssociationInstance)))
  1599. {
  1600. result = pResponseHandler->Indicate(1, &pAssociationInstance);
  1601. pAssociationInstance->Release();
  1602. // Add it to the list of objects indicated so far
  1603. pListIndicatedSoFar->AddName(pszCombinedName);
  1604. }
  1605. }
  1606. delete [] pszCombinedName;
  1607. }
  1608. else
  1609. result = E_OUTOFMEMORY;
  1610. SysFreeString(strChildPath);
  1611. SysFreeString(strParentPath);
  1612. FreeADsMem((LPVOID *)pParentInfo);
  1613. }
  1614. pParentObject->Release();
  1615. }
  1616. FreeADsMem((LPVOID *)pChildInfo);
  1617. }
  1618. pChildObject->Release();
  1619. }
  1620. return result;
  1621. }
  1622. //***************************************************************************
  1623. //
  1624. // CLDAPInstanceProvider::DoParentContainmentQuery
  1625. //
  1626. // Purpose: See Header File
  1627. //
  1628. //***************************************************************************
  1629. HRESULT CLDAPInstanceProvider :: DoParentContainmentQuery(LPCWSTR pszParentPath, IWbemObjectSink *pResponseHandler, CNamesList *pListIndicatedSoFar)
  1630. {
  1631. // We *have* to use the IADs interfaces since there are no container in
  1632. IADsContainer *pContainer = NULL;
  1633. IADs *pChild = NULL;
  1634. VARIANT variant;
  1635. VariantInit(&variant);
  1636. HRESULT result;
  1637. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszParentPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADsContainer, (LPVOID *) &pContainer)))
  1638. {
  1639. IADs *pParent = NULL;
  1640. if(SUCCEEDED(result = pContainer->QueryInterface(IID_IADs, (LPVOID *)&pParent)))
  1641. {
  1642. BSTR strParentClass = NULL;
  1643. if(SUCCEEDED(result = pParent->get_Class(&strParentClass)))
  1644. {
  1645. // Get the WBEM names of the LDAP class
  1646. LPWSTR pszParentClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(strParentClass);
  1647. BSTR strParentWBEMPath = CWBEMHelper::GetObjectRefFromADSIPath(pszParentPath, pszParentClassWbemName);
  1648. delete [] pszParentClassWbemName;
  1649. SysFreeString(strParentClass);
  1650. IEnumVARIANT *pEnum = NULL;
  1651. if(SUCCEEDED(result = ADsBuildEnumerator(pContainer, &pEnum)))
  1652. {
  1653. bool bDone = false;
  1654. while(!bDone && SUCCEEDED(result = ADsEnumerateNext(pEnum, 1, &variant, NULL)) && result != S_FALSE)
  1655. {
  1656. if(SUCCEEDED(result = (variant.pdispVal)->QueryInterface(IID_IADs, (LPVOID *)&pChild)))
  1657. {
  1658. BSTR strChildADSIPath = NULL;
  1659. if(SUCCEEDED(result = pChild->get_ADsPath(&strChildADSIPath)))
  1660. {
  1661. BSTR strChildClass = NULL;
  1662. if(SUCCEEDED(result = pChild->get_Class(&strChildClass)))
  1663. {
  1664. // Create an instance of the association class
  1665. IWbemClassObject *pAssociationInstance = NULL;
  1666. // Get the WBEM Name oo the child class
  1667. LPWSTR pszChildClassWbemName = CLDAPHelper::MangleLDAPNameToWBEM(strChildClass);
  1668. BSTR strChildWBEMPath = CWBEMHelper::GetObjectRefFromADSIPath(strChildADSIPath, pszChildClassWbemName);
  1669. delete [] pszChildClassWbemName;
  1670. // Check to see if it has already been indicated
  1671. LPWSTR pszCombinedName = NULL;
  1672. if(pszCombinedName = new WCHAR[wcslen(strChildADSIPath) + wcslen(pszParentPath) + 1])
  1673. {
  1674. wcscpy(pszCombinedName,strChildADSIPath);
  1675. wcscat(pszCombinedName,pszParentPath);
  1676. if(!pListIndicatedSoFar->IsNamePresent(pszCombinedName))
  1677. {
  1678. if(SUCCEEDED(result = CreateWBEMInstance(strChildWBEMPath, strParentWBEMPath, &pAssociationInstance)))
  1679. {
  1680. if(FAILED(result = pResponseHandler->Indicate(1, &pAssociationInstance)))
  1681. bDone = true;
  1682. pAssociationInstance->Release();
  1683. // Add it to the list of objects indicated so far
  1684. pListIndicatedSoFar->AddName(pszCombinedName);
  1685. }
  1686. }
  1687. delete [] pszCombinedName;
  1688. }
  1689. else
  1690. result = E_OUTOFMEMORY;
  1691. SysFreeString(strChildClass);
  1692. SysFreeString(strChildWBEMPath);
  1693. }
  1694. SysFreeString(strChildADSIPath);
  1695. }
  1696. pChild->Release();
  1697. }
  1698. VariantClear(&variant);
  1699. VariantInit(&variant);
  1700. }
  1701. ADsFreeEnumerator(pEnum);
  1702. }
  1703. SysFreeString(strParentWBEMPath);
  1704. }
  1705. pParent->Release();
  1706. }
  1707. pContainer->Release();
  1708. }
  1709. return result;
  1710. }
  1711. //***************************************************************************
  1712. //
  1713. // CLDAPInstanceProvider::ModifyExistingADSIInstance
  1714. //
  1715. // Purpose: See Header File
  1716. //
  1717. //***************************************************************************
  1718. HRESULT CLDAPInstanceProvider :: ModifyExistingADSIInstance(IWbemClassObject *pWbemInstance,
  1719. LPCWSTR pszADSIPath,
  1720. CADSIInstance *pExistingObject,
  1721. LPCWSTR pszADSIClass,
  1722. IWbemContext *pCtx)
  1723. {
  1724. HRESULT result = S_OK;
  1725. BOOLEAN bPartialUpdate = FALSE;
  1726. DWORD dwPartialUpdateCount = 0;
  1727. BSTR *pstrProperyNames = NULL;
  1728. SAFEARRAY *pArray = NULL;
  1729. // See if the partial property list is indicated in the context
  1730. VARIANT v1, v2;
  1731. VariantInit(&v1);
  1732. VariantInit(&v2);
  1733. if(SUCCEEDED(result = pCtx->GetValue(PUT_EXTENSIONS_STR, 0, &v1)))
  1734. {
  1735. if(SUCCEEDED(result = pCtx->GetValue(PUT_EXT_PROPERTIES_STR, 0, &v2)))
  1736. {
  1737. switch(v2.vt)
  1738. {
  1739. case VT_BSTR | VT_ARRAY:
  1740. {
  1741. pArray = v2.parray;
  1742. LONG lUbound = 0, lLbound = 0;
  1743. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pstrProperyNames) ) &&
  1744. SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  1745. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  1746. {
  1747. dwPartialUpdateCount = lUbound - lLbound + 1;
  1748. bPartialUpdate = TRUE;
  1749. }
  1750. }
  1751. break;
  1752. default:
  1753. result = WBEM_E_FAILED;
  1754. break;
  1755. }
  1756. }
  1757. VariantClear(&v1);
  1758. }
  1759. else
  1760. result = S_OK; // Reset it, there was no request for partial update
  1761. if (FAILED(result))
  1762. return WBEM_E_FAILED;
  1763. // Find the number of properties first by doing an enumeration
  1764. if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
  1765. {
  1766. DWORD dwNumProperties = 0;
  1767. while(SUCCEEDED(result = pWbemInstance->Next(0, NULL, NULL, NULL, NULL)) && result != WBEM_S_NO_MORE_DATA )
  1768. dwNumProperties ++;
  1769. pWbemInstance->EndEnumeration();
  1770. // Allocate ADSI structures for these properties
  1771. PADS_ATTR_INFO pAttributeEntries = NULL;
  1772. if(pAttributeEntries = new ADS_ATTR_INFO [dwNumProperties])
  1773. {
  1774. // Now go thru each wbem property and map it
  1775. if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
  1776. {
  1777. DWORD dwNumPropertiesMapped = 0;
  1778. BSTR strPropertyName = NULL;
  1779. VARIANT vPropertyValue;
  1780. CIMTYPE cType;
  1781. LONG lFlavour;
  1782. while(SUCCEEDED(result = pWbemInstance->Next(0, &strPropertyName, &vPropertyValue, &cType, &lFlavour)) && result != WBEM_S_NO_MORE_DATA )
  1783. {
  1784. // Skip those properties that should not go to ADSI
  1785. if(_wcsicmp(strPropertyName, ADSI_PATH_STR) == 0 )
  1786. {
  1787. }
  1788. else // Map the property to ADSI
  1789. {
  1790. BOOLEAN bMapProperty = FALSE;
  1791. if(bPartialUpdate)
  1792. {
  1793. if(CWBEMHelper::IsPresentInBstrList(pstrProperyNames, dwPartialUpdateCount, strPropertyName))
  1794. bMapProperty = TRUE;
  1795. }
  1796. else
  1797. bMapProperty = TRUE;
  1798. if(bMapProperty)
  1799. {
  1800. if(vPropertyValue.vt == VT_NULL)
  1801. {
  1802. (pAttributeEntries + dwNumPropertiesMapped)->dwControlCode = ADS_ATTR_CLEAR;
  1803. (pAttributeEntries + dwNumPropertiesMapped)->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(strPropertyName);
  1804. dwNumPropertiesMapped ++;
  1805. }
  1806. else if(SUCCEEDED(MapPropertyValueToADSI(pWbemInstance, strPropertyName, vPropertyValue, cType, lFlavour, pAttributeEntries + dwNumPropertiesMapped)))
  1807. {
  1808. // Set the "attribute has been modified" flag
  1809. (pAttributeEntries + dwNumPropertiesMapped)->dwControlCode = ADS_ATTR_UPDATE;
  1810. dwNumPropertiesMapped ++;
  1811. }
  1812. else
  1813. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ModifyExistingADSIInstance() MapPropertyValueToADSI FAILED %x for %s\r\n", result, strPropertyName);
  1814. }
  1815. else
  1816. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ModifyExistingADSIInstance() Skipping %s since it is not in Context list\r\n", strPropertyName);
  1817. }
  1818. SysFreeString(strPropertyName);
  1819. VariantClear(&vPropertyValue);
  1820. }
  1821. pWbemInstance->EndEnumeration();
  1822. // Logging
  1823. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: The %d attributes being put are:\r\n", dwNumPropertiesMapped);
  1824. for(DWORD i=0; i<dwNumPropertiesMapped; i++)
  1825. g_pLogObject->WriteW( L"%s\r\n", (pAttributeEntries + i)->pszAttrName);
  1826. // Get the actual object from ADSI to find out which attributes have changed.
  1827. DWORD dwNumModified = 0;
  1828. IDirectoryObject *pDirectoryObject = pExistingObject->GetDirectoryObject();
  1829. if(SUCCEEDED(result = pDirectoryObject->SetObjectAttributes(pAttributeEntries, dwNumPropertiesMapped, &dwNumModified)))
  1830. {
  1831. }
  1832. else
  1833. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: SetObjectAttributes FAILED with %x\r\n", result);
  1834. pDirectoryObject->Release();
  1835. // Delete the contents of each of the attributes
  1836. for(i=0; i<dwNumPropertiesMapped; i++)
  1837. {
  1838. if((pAttributeEntries + i)->dwControlCode != ADS_ATTR_CLEAR)
  1839. CLDAPHelper::DeleteAttributeContents(pAttributeEntries + i);
  1840. }
  1841. }
  1842. delete [] pAttributeEntries;
  1843. }
  1844. else
  1845. result = E_OUTOFMEMORY;
  1846. }
  1847. if(bPartialUpdate)
  1848. {
  1849. SafeArrayUnaccessData(pArray);
  1850. VariantClear(&v2);
  1851. }
  1852. return result;
  1853. }
  1854. //***************************************************************************
  1855. //
  1856. // CLDAPInstanceProvider::CreateNewADSIInstance
  1857. //
  1858. // Purpose: See Header File
  1859. //
  1860. //***************************************************************************
  1861. HRESULT CLDAPInstanceProvider :: CreateNewADSIInstance(IWbemClassObject *pWbemInstance, LPCWSTR pszADSIPath, LPCWSTR pszADSIClass)
  1862. {
  1863. // Find the ADSI path of the parent and the RDN of the child
  1864. BSTR strRDNName = NULL;
  1865. BSTR strParentADSIPath = NULL;
  1866. BSTR strParentADSIPathWithoutLDAP = NULL;
  1867. BSTR strParentPlusRDNADSIPath = NULL;
  1868. HRESULT result = WBEM_E_FAILED;
  1869. // Get the parentADSI path and RDN from the ADSI Path
  1870. IADsPathname *pADsPathName = NULL;
  1871. BSTR strADSIPath = SysAllocString(pszADSIPath);
  1872. if(SUCCEEDED(result = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_ALL, IID_IADsPathname, (LPVOID *)&pADsPathName)))
  1873. {
  1874. if(SUCCEEDED(result = pADsPathName->Set(strADSIPath, ADS_SETTYPE_FULL)))
  1875. {
  1876. // This gives "<Parent>" without the "LDAP://" prefix
  1877. if(SUCCEEDED(result = pADsPathName->Retrieve(ADS_FORMAT_X500_PARENT, &strParentADSIPathWithoutLDAP)))
  1878. {
  1879. // This gives "CN=Administrator,<Parent>"
  1880. if(SUCCEEDED(result = pADsPathName->Retrieve(ADS_FORMAT_X500_DN, &strParentPlusRDNADSIPath)))
  1881. {
  1882. // Form the RDN - Dont ignore the comma.
  1883. DWORD dwRDNLength = wcslen(strParentPlusRDNADSIPath) - wcslen(strParentADSIPathWithoutLDAP);
  1884. LPWSTR pszRDN = NULL;
  1885. if(pszRDN = new WCHAR [dwRDNLength])
  1886. {
  1887. wcsncpy(pszRDN, strParentPlusRDNADSIPath, dwRDNLength-1);
  1888. pszRDN[dwRDNLength-1] = NULL;
  1889. strRDNName = SysAllocString(pszRDN);
  1890. delete [] pszRDN;
  1891. }
  1892. else
  1893. result = E_OUTOFMEMORY;
  1894. if(SUCCEEDED(result))
  1895. {
  1896. LPWSTR pszParentADSIPath = NULL;
  1897. if(pszParentADSIPath = new WCHAR[wcslen(strParentADSIPathWithoutLDAP) + wcslen(LDAP_PREFIX) + 1])
  1898. {
  1899. wcscpy(pszParentADSIPath, LDAP_PREFIX);
  1900. wcscat(pszParentADSIPath, strParentADSIPathWithoutLDAP);
  1901. strParentADSIPath = SysAllocString(pszParentADSIPath);
  1902. delete [] pszParentADSIPath;
  1903. }
  1904. else
  1905. result = E_OUTOFMEMORY;
  1906. }
  1907. // Find the number of properties first by doing an enumeration
  1908. if(SUCCEEDED(result) && SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
  1909. {
  1910. DWORD dwNumProperties = 0;
  1911. while(SUCCEEDED(result = pWbemInstance->Next(0, NULL, NULL, NULL, NULL)) && result != WBEM_S_NO_MORE_DATA )
  1912. dwNumProperties ++;
  1913. pWbemInstance->EndEnumeration();
  1914. // Allocate ADSI structures for these properties. An additional one for the "objectclass" property
  1915. PADS_ATTR_INFO pAttributeEntries = NULL;
  1916. if(pAttributeEntries = new ADS_ATTR_INFO [dwNumProperties + 1])
  1917. {
  1918. // Now go thru each wbem property and map it
  1919. if(SUCCEEDED(result = pWbemInstance->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY)))
  1920. {
  1921. DWORD dwNumPropertiesMapped = 0;
  1922. BSTR strPropertyName = NULL;
  1923. VARIANT vPropertyValue;
  1924. CIMTYPE cType;
  1925. LONG lFlavour;
  1926. while(SUCCEEDED(result = pWbemInstance->Next(0, &strPropertyName, &vPropertyValue, &cType, &lFlavour)) && result != WBEM_S_NO_MORE_DATA )
  1927. {
  1928. if(vPropertyValue.vt != VT_NULL)
  1929. {
  1930. // Skip those properties that should not go to ADSI
  1931. if(_wcsicmp(strPropertyName, ADSI_PATH_STR) == 0 ||
  1932. _wcsicmp(strPropertyName, OBJECT_CLASS_PROPERTY) == 0)
  1933. {
  1934. }
  1935. else // Map the property to ADSI
  1936. {
  1937. if(SUCCEEDED(MapPropertyValueToADSI(pWbemInstance, strPropertyName, vPropertyValue, cType, lFlavour, pAttributeEntries + dwNumPropertiesMapped)))
  1938. dwNumPropertiesMapped ++;
  1939. else
  1940. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateNewADSIInstance() MapPropertyValueToADSI FAILED %x for %s\r\n", result, strPropertyName);
  1941. }
  1942. }
  1943. SysFreeString(strPropertyName);
  1944. VariantClear(&vPropertyValue);
  1945. }
  1946. pWbemInstance->EndEnumeration();
  1947. // Set the objectClass attribute too
  1948. SetObjectClassAttribute(pAttributeEntries + dwNumPropertiesMapped, pszADSIClass);
  1949. dwNumPropertiesMapped++;
  1950. // Now get the parent ADSI object
  1951. IDirectoryObject *pParentObject = NULL;
  1952. if(SUCCEEDED(result = ADsOpenObject(strParentADSIPath, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (LPVOID *)&pParentObject)))
  1953. {
  1954. if(SUCCEEDED(result = pParentObject->CreateDSObject(strRDNName, pAttributeEntries, dwNumPropertiesMapped, NULL)))
  1955. {
  1956. }
  1957. else
  1958. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateDSObject on parent FAILED with %x\r\n", result);
  1959. pParentObject->Release();
  1960. }
  1961. else
  1962. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ADsOpenObject on parent %s FAILED with %x\r\n", strParentADSIPath, result);
  1963. // Delete the contents of each of the attributes
  1964. for(DWORD i=0; i<dwNumPropertiesMapped; i++)
  1965. CLDAPHelper::DeleteAttributeContents(pAttributeEntries + i);
  1966. }
  1967. delete [] pAttributeEntries;
  1968. }
  1969. else
  1970. result = E_OUTOFMEMORY;
  1971. }
  1972. SysFreeString(strParentPlusRDNADSIPath);
  1973. SysFreeString(strParentADSIPath);
  1974. }
  1975. SysFreeString(strParentADSIPathWithoutLDAP);
  1976. }
  1977. }
  1978. pADsPathName->Release();
  1979. }
  1980. else
  1981. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CoCreateInstance() on IADsPathName FAILED %x\r\n", result);
  1982. SysFreeString(strADSIPath);
  1983. return result;
  1984. }
  1985. //***************************************************************************
  1986. //
  1987. // CLDAPInstanceProvider::MapPropertyValueToADSI
  1988. //
  1989. // Purpose: See Header File
  1990. //
  1991. //***************************************************************************
  1992. HRESULT CLDAPInstanceProvider :: MapPropertyValueToADSI(IWbemClassObject *pWbemInstance, BSTR strPropertyName, VARIANT vPropertyValue, CIMTYPE cType, LONG lFlavour, PADS_ATTR_INFO pAttributeEntry)
  1993. {
  1994. // Set its fields to 0;
  1995. memset((LPVOID)pAttributeEntry, 0, sizeof(ADS_ATTR_INFO));
  1996. HRESULT result = E_FAIL;
  1997. // Set the name
  1998. pAttributeEntry->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(strPropertyName);
  1999. IWbemQualifierSet *pQualifierSet = NULL;
  2000. if(SUCCEEDED(result = pWbemInstance->GetPropertyQualifierSet(strPropertyName, &pQualifierSet)))
  2001. {
  2002. // Get its attributeSyntax qualifer
  2003. LPWSTR pszAttributeSyntax = NULL;
  2004. if(SUCCEEDED(CWBEMHelper::GetBSTRQualifierT(pQualifierSet, ATTRIBUTE_SYNTAX_STR, &pszAttributeSyntax, NULL)))
  2005. {
  2006. if(_wcsicmp(pszAttributeSyntax, DISTINGUISHED_NAME_OID) == 0)
  2007. {
  2008. pAttributeEntry->dwADsType = ADSTYPE_DN_STRING;
  2009. result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
  2010. }
  2011. else if(_wcsicmp(pszAttributeSyntax, OBJECT_IDENTIFIER_OID) == 0)
  2012. {
  2013. pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  2014. result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
  2015. }
  2016. else if(_wcsicmp(pszAttributeSyntax, CASE_SENSITIVE_STRING_OID) == 0)
  2017. {
  2018. pAttributeEntry->dwADsType = ADSTYPE_CASE_EXACT_STRING;
  2019. result = SetStringValues(pAttributeEntry, ADSTYPE_CASE_EXACT_STRING, &vPropertyValue);
  2020. }
  2021. else if(_wcsicmp(pszAttributeSyntax, CASE_INSENSITIVE_STRING_OID) == 0)
  2022. {
  2023. pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  2024. result = SetStringValues(pAttributeEntry, ADSTYPE_CASE_IGNORE_STRING, &vPropertyValue);
  2025. }
  2026. else if(_wcsicmp(pszAttributeSyntax, PRINT_CASE_STRING_OID) == 0)
  2027. {
  2028. pAttributeEntry->dwADsType = ADSTYPE_PRINTABLE_STRING;
  2029. result = SetStringValues(pAttributeEntry, ADSTYPE_PRINTABLE_STRING, &vPropertyValue);
  2030. }
  2031. else if(_wcsicmp(pszAttributeSyntax, NUMERIC_STRING_OID) == 0)
  2032. {
  2033. pAttributeEntry->dwADsType = ADSTYPE_NUMERIC_STRING;
  2034. result = SetStringValues(pAttributeEntry, ADSTYPE_NUMERIC_STRING, &vPropertyValue);
  2035. }
  2036. else if(_wcsicmp(pszAttributeSyntax, DN_WITH_STRING_OID) == 0)
  2037. {
  2038. pAttributeEntry->dwADsType = ADSTYPE_DN_WITH_STRING;
  2039. result = SetDNWithStringValues(pAttributeEntry, ADSTYPE_DN_WITH_STRING, &vPropertyValue);
  2040. }
  2041. else if(_wcsicmp(pszAttributeSyntax, DN_WITH_BINARY_OID) == 0)
  2042. {
  2043. pAttributeEntry->dwADsType = ADSTYPE_DN_WITH_BINARY;
  2044. result = SetDNWithBinaryValues(pAttributeEntry, ADSTYPE_DN_WITH_BINARY, &vPropertyValue);
  2045. }
  2046. else if(_wcsicmp(pszAttributeSyntax, BOOLEAN_OID) == 0)
  2047. {
  2048. pAttributeEntry->dwADsType = ADSTYPE_BOOLEAN;
  2049. result = SetBooleanValues(pAttributeEntry, ADSTYPE_BOOLEAN, &vPropertyValue);
  2050. }
  2051. else if(_wcsicmp(pszAttributeSyntax, INTEGER_OID) == 0)
  2052. {
  2053. pAttributeEntry->dwADsType = ADSTYPE_INTEGER;
  2054. result = SetIntegerValues(pAttributeEntry, ADSTYPE_INTEGER, &vPropertyValue);
  2055. }
  2056. else if(_wcsicmp(pszAttributeSyntax, OCTET_STRING_OID) == 0)
  2057. {
  2058. pAttributeEntry->dwADsType = ADSTYPE_OCTET_STRING;
  2059. result = SetOctetStringValues(pAttributeEntry, ADSTYPE_OCTET_STRING, &vPropertyValue);
  2060. }
  2061. else if(_wcsicmp(pszAttributeSyntax, TIME_OID) == 0)
  2062. {
  2063. pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  2064. result = SetTimeValues(pAttributeEntry, ADSTYPE_CASE_IGNORE_STRING, &vPropertyValue);
  2065. }
  2066. else if(_wcsicmp(pszAttributeSyntax, UNICODE_STRING_OID) == 0)
  2067. {
  2068. pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  2069. result = SetStringValues(pAttributeEntry, ADSTYPE_DN_STRING, &vPropertyValue);
  2070. }
  2071. else if(_wcsicmp(pszAttributeSyntax, NT_SECURITY_DESCRIPTOR_OID) == 0)
  2072. {
  2073. pAttributeEntry->dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  2074. result = SetOctetStringValues(pAttributeEntry, ADSTYPE_NT_SECURITY_DESCRIPTOR, &vPropertyValue);
  2075. }
  2076. else if(_wcsicmp(pszAttributeSyntax, LARGE_INTEGER_OID) == 0)
  2077. {
  2078. pAttributeEntry->dwADsType = ADSTYPE_LARGE_INTEGER;
  2079. result = SetLargeIntegerValues(pAttributeEntry, ADSTYPE_LARGE_INTEGER, &vPropertyValue);
  2080. }
  2081. else if(_wcsicmp(pszAttributeSyntax, SID_OID) == 0)
  2082. {
  2083. pAttributeEntry->dwADsType = ADSTYPE_OCTET_STRING;
  2084. result = SetOctetStringValues(pAttributeEntry, ADSTYPE_OCTET_STRING, &vPropertyValue);
  2085. }
  2086. else
  2087. {
  2088. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapPropertyValueToADSI() Unknown attributeSyntax %s\r\n", pszAttributeSyntax);
  2089. result = E_FAIL;
  2090. }
  2091. delete[] pszAttributeSyntax;
  2092. }
  2093. else
  2094. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: MapPropertyValueToADSI() Get on attributeSyntax FAILED %x\r\n", result);
  2095. pQualifierSet->Release();
  2096. }
  2097. return WBEM_S_NO_ERROR;
  2098. }
  2099. //***************************************************************************
  2100. //
  2101. // CLDAPInstanceProvider::SetStringValues
  2102. //
  2103. // Purpose: See Header File
  2104. //
  2105. //***************************************************************************
  2106. HRESULT CLDAPInstanceProvider :: SetStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2107. {
  2108. HRESULT result = S_OK;
  2109. switch(pvPropertyValue->vt)
  2110. {
  2111. case VT_BSTR:
  2112. {
  2113. if(pvPropertyValue->bstrVal)
  2114. {
  2115. pAttributeEntry->dwNumValues = 1;
  2116. pAttributeEntry->pADsValues = NULL;
  2117. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2118. {
  2119. pAttributeEntry->pADsValues->dwType = adType;
  2120. pAttributeEntry->pADsValues->DNString = NULL;
  2121. if(pAttributeEntry->pADsValues->DNString = new WCHAR[wcslen(pvPropertyValue->bstrVal) + 1])
  2122. wcscpy(pAttributeEntry->pADsValues->DNString, pvPropertyValue->bstrVal);
  2123. else
  2124. result = E_OUTOFMEMORY;
  2125. }
  2126. else
  2127. result = E_OUTOFMEMORY;
  2128. }
  2129. }
  2130. break;
  2131. case VT_BSTR | VT_ARRAY:
  2132. {
  2133. SAFEARRAY *pArray = pvPropertyValue->parray;
  2134. BSTR HUGEP *pbstr;
  2135. LONG lUbound = 0, lLbound = 0;
  2136. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ))
  2137. {
  2138. if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2139. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2140. {
  2141. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2142. {
  2143. pAttributeEntry->pADsValues = NULL;
  2144. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2145. {
  2146. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2147. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2148. {
  2149. pValues->dwType = adType;
  2150. pValues->DNString = NULL;
  2151. if(pValues->DNString = new WCHAR[wcslen(pbstr[i]) + 1])
  2152. wcscpy(pValues->DNString, pbstr[i]);
  2153. pValues ++;
  2154. }
  2155. }
  2156. else
  2157. result = E_OUTOFMEMORY;
  2158. }
  2159. }
  2160. SafeArrayUnaccessData(pArray);
  2161. }
  2162. }
  2163. break;
  2164. default:
  2165. return E_FAIL;
  2166. }
  2167. return result;
  2168. }
  2169. //***************************************************************************
  2170. //
  2171. // CLDAPInstanceProvider::SetIntegerValues
  2172. //
  2173. // Purpose: See Header File
  2174. //
  2175. //***************************************************************************
  2176. HRESULT CLDAPInstanceProvider :: SetIntegerValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2177. {
  2178. HRESULT result = S_OK;
  2179. switch(pvPropertyValue->vt)
  2180. {
  2181. case VT_I4:
  2182. {
  2183. pAttributeEntry->dwNumValues = 1;
  2184. pAttributeEntry->pADsValues = NULL;
  2185. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2186. {
  2187. pAttributeEntry->pADsValues->dwType = adType;
  2188. pAttributeEntry->pADsValues->Integer = pvPropertyValue->lVal;
  2189. }
  2190. else
  2191. result = E_OUTOFMEMORY;
  2192. }
  2193. break;
  2194. case VT_I4 | VT_ARRAY:
  2195. {
  2196. SAFEARRAY *pArray = pvPropertyValue->parray;
  2197. LONG HUGEP *pl;
  2198. LONG lUbound = 0, lLbound = 0;
  2199. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pl) ) &&
  2200. SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2201. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2202. {
  2203. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2204. {
  2205. pAttributeEntry->pADsValues = NULL;
  2206. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2207. {
  2208. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2209. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2210. {
  2211. pValues->dwType = adType;
  2212. pValues->Integer = pl[i];
  2213. pValues ++;
  2214. }
  2215. }
  2216. else
  2217. result = E_OUTOFMEMORY;
  2218. }
  2219. SafeArrayUnaccessData(pArray);
  2220. }
  2221. }
  2222. break;
  2223. default:
  2224. return E_FAIL;
  2225. }
  2226. return result;
  2227. }
  2228. //***************************************************************************
  2229. //
  2230. // CLDAPInstanceProvider::SetBooleanValues
  2231. //
  2232. // Purpose: See Header File
  2233. //
  2234. //***************************************************************************
  2235. HRESULT CLDAPInstanceProvider :: SetBooleanValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2236. {
  2237. HRESULT result = S_OK;
  2238. switch(pvPropertyValue->vt)
  2239. {
  2240. case VT_BOOL:
  2241. {
  2242. pAttributeEntry->dwNumValues = 1;
  2243. pAttributeEntry->pADsValues = NULL;
  2244. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2245. {
  2246. pAttributeEntry->pADsValues->dwType = adType;
  2247. pAttributeEntry->pADsValues->Boolean = pvPropertyValue->boolVal;
  2248. }
  2249. else
  2250. result = E_OUTOFMEMORY;
  2251. }
  2252. break;
  2253. case VT_BOOL | VT_ARRAY:
  2254. {
  2255. SAFEARRAY *pArray = pvPropertyValue->parray;
  2256. VARIANT_BOOL HUGEP *pb;
  2257. LONG lUbound = 0, lLbound = 0;
  2258. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pb) ) &&
  2259. SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2260. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2261. {
  2262. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2263. {
  2264. pAttributeEntry->pADsValues = NULL;
  2265. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2266. {
  2267. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2268. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2269. {
  2270. pValues->dwType = adType;
  2271. pValues->Boolean = (pb[i] == VARIANT_TRUE)? TRUE : FALSE;
  2272. pValues ++;
  2273. }
  2274. }
  2275. else
  2276. result = E_OUTOFMEMORY;
  2277. }
  2278. SafeArrayUnaccessData(pArray);
  2279. }
  2280. }
  2281. break;
  2282. default:
  2283. return E_FAIL;
  2284. }
  2285. return result;
  2286. }
  2287. //***************************************************************************
  2288. //
  2289. // CLDAPInstanceProvider::SetOctetStringValues
  2290. //
  2291. // Purpose: See Header File
  2292. //
  2293. //***************************************************************************
  2294. HRESULT CLDAPInstanceProvider :: SetOctetStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2295. {
  2296. HRESULT result = E_FAIL;
  2297. switch(pvPropertyValue->vt)
  2298. {
  2299. case VT_UNKNOWN:
  2300. {
  2301. pAttributeEntry->dwNumValues = 1;
  2302. pAttributeEntry->pADsValues = NULL;
  2303. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2304. {
  2305. pAttributeEntry->pADsValues->dwType = adType;
  2306. // Get the array
  2307. IWbemClassObject *pEmbeddedObject = NULL;
  2308. if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2309. {
  2310. if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->OctetString.lpValue), &(pAttributeEntry->pADsValues->OctetString.dwLength) )))
  2311. {
  2312. }
  2313. pEmbeddedObject->Release();
  2314. }
  2315. }
  2316. else
  2317. result = E_OUTOFMEMORY;
  2318. }
  2319. break;
  2320. case VT_UNKNOWN | VT_ARRAY:
  2321. {
  2322. SAFEARRAY *pArray = pvPropertyValue->parray;
  2323. LONG lUbound = 0, lLbound = 0;
  2324. if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2325. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2326. {
  2327. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2328. {
  2329. pAttributeEntry->pADsValues = NULL;
  2330. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2331. {
  2332. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2333. IUnknown *pNextElement = NULL;
  2334. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2335. {
  2336. pValues->dwType = adType;
  2337. if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
  2338. {
  2339. IWbemClassObject *pEmbeddedObject = NULL;
  2340. if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2341. {
  2342. if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pValues->OctetString.lpValue), &(pValues->OctetString.dwLength))))
  2343. {
  2344. }
  2345. pEmbeddedObject->Release();
  2346. }
  2347. pNextElement->Release();
  2348. }
  2349. pValues ++;
  2350. }
  2351. }
  2352. else
  2353. result = E_OUTOFMEMORY;
  2354. }
  2355. }
  2356. }
  2357. break;
  2358. default:
  2359. return E_FAIL;
  2360. }
  2361. return result;
  2362. }
  2363. //***************************************************************************
  2364. //
  2365. // CLDAPInstanceProvider::SetDNWithStringValues
  2366. //
  2367. // Purpose: See Header File
  2368. //
  2369. //***************************************************************************
  2370. HRESULT CLDAPInstanceProvider :: SetDNWithStringValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2371. {
  2372. HRESULT result = E_FAIL;
  2373. switch(pvPropertyValue->vt)
  2374. {
  2375. case VT_UNKNOWN:
  2376. {
  2377. pAttributeEntry->dwNumValues = 1;
  2378. pAttributeEntry->pADsValues = NULL;
  2379. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2380. {
  2381. pAttributeEntry->pADsValues->dwType = adType;
  2382. pAttributeEntry->pADsValues->pDNWithString = NULL;
  2383. if(pAttributeEntry->pADsValues->pDNWithString = new ADS_DN_WITH_STRING)
  2384. {
  2385. IWbemClassObject *pEmbeddedObject = NULL;
  2386. if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2387. {
  2388. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithString->pszStringValue) )))
  2389. {
  2390. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithString->pszDNString) )))
  2391. {
  2392. }
  2393. }
  2394. pEmbeddedObject->Release();
  2395. }
  2396. }
  2397. else
  2398. result = E_OUTOFMEMORY;
  2399. }
  2400. else
  2401. result = E_OUTOFMEMORY;
  2402. }
  2403. break;
  2404. case VT_UNKNOWN | VT_ARRAY:
  2405. {
  2406. SAFEARRAY *pArray = pvPropertyValue->parray;
  2407. LONG lUbound = 0, lLbound = 0;
  2408. if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2409. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2410. {
  2411. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2412. {
  2413. pAttributeEntry->pADsValues = NULL;
  2414. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2415. {
  2416. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2417. IUnknown *pNextElement = NULL;
  2418. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2419. {
  2420. pValues->dwType = adType;
  2421. if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
  2422. {
  2423. IWbemClassObject *pEmbeddedObject = NULL;
  2424. if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2425. {
  2426. if(pValues->pDNWithString = new ADS_DN_WITH_STRING)
  2427. {
  2428. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, VALUE_PROPERTY_STR, &(pValues->pDNWithString->pszStringValue) )))
  2429. {
  2430. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pValues->pDNWithString->pszDNString) )))
  2431. {
  2432. }
  2433. }
  2434. }
  2435. pEmbeddedObject->Release();
  2436. }
  2437. pNextElement->Release();
  2438. }
  2439. pValues ++;
  2440. }
  2441. }
  2442. else
  2443. result = E_OUTOFMEMORY;
  2444. }
  2445. }
  2446. }
  2447. break;
  2448. default:
  2449. return E_FAIL;
  2450. }
  2451. return result;
  2452. }
  2453. //***************************************************************************
  2454. //
  2455. // CLDAPInstanceProvider::SetDNWithBinaryValues
  2456. //
  2457. // Purpose: See Header File
  2458. //
  2459. //***************************************************************************
  2460. HRESULT CLDAPInstanceProvider :: SetDNWithBinaryValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2461. {
  2462. HRESULT result = E_FAIL;
  2463. switch(pvPropertyValue->vt)
  2464. {
  2465. case VT_UNKNOWN:
  2466. {
  2467. pAttributeEntry->dwNumValues = 1;
  2468. pAttributeEntry->pADsValues = NULL;
  2469. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2470. {
  2471. pAttributeEntry->pADsValues->dwType = adType;
  2472. pAttributeEntry->pADsValues->pDNWithBinary = NULL;
  2473. if(pAttributeEntry->pADsValues->pDNWithBinary = new ADS_DN_WITH_BINARY)
  2474. {
  2475. IWbemClassObject *pEmbeddedObject = NULL;
  2476. if(SUCCEEDED(result = (pvPropertyValue->punkVal)->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2477. {
  2478. if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->lpBinaryValue), &(pAttributeEntry->pADsValues->pDNWithBinary->dwLength) )))
  2479. {
  2480. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->pszDNString) )))
  2481. {
  2482. }
  2483. }
  2484. pEmbeddedObject->Release();
  2485. }
  2486. }
  2487. else
  2488. result = E_OUTOFMEMORY;
  2489. }
  2490. else
  2491. result = E_OUTOFMEMORY;
  2492. }
  2493. break;
  2494. case VT_UNKNOWN | VT_ARRAY:
  2495. {
  2496. SAFEARRAY *pArray = pvPropertyValue->parray;
  2497. LONG lUbound = 0, lLbound = 0;
  2498. if(SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2499. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2500. {
  2501. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2502. {
  2503. pAttributeEntry->pADsValues = NULL;
  2504. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2505. {
  2506. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2507. IUnknown *pNextElement = NULL;
  2508. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2509. {
  2510. pValues->dwType = adType;
  2511. if(SUCCEEDED(result = SafeArrayGetElement(pArray, (LONG *)&i, (LPVOID )&pNextElement )))
  2512. {
  2513. IWbemClassObject *pEmbeddedObject = NULL;
  2514. if(SUCCEEDED(result = pNextElement->QueryInterface(IID_IWbemClassObject, (LPVOID *)&pEmbeddedObject)))
  2515. {
  2516. if(pValues->pDNWithBinary = new ADS_DN_WITH_BINARY)
  2517. {
  2518. if(SUCCEEDED(result = CWBEMHelper::GetUint8ArrayProperty(pEmbeddedObject, VALUE_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->lpBinaryValue), &(pAttributeEntry->pADsValues->pDNWithBinary->dwLength) )))
  2519. {
  2520. if(SUCCEEDED(result = CWBEMHelper::GetBSTRPropertyT(pEmbeddedObject, DN_STRING_PROPERTY_STR, &(pAttributeEntry->pADsValues->pDNWithBinary->pszDNString) )))
  2521. {
  2522. }
  2523. }
  2524. }
  2525. pEmbeddedObject->Release();
  2526. }
  2527. pNextElement->Release();
  2528. }
  2529. pValues ++;
  2530. }
  2531. }
  2532. else
  2533. result = E_OUTOFMEMORY;
  2534. }
  2535. }
  2536. }
  2537. break;
  2538. default:
  2539. return E_FAIL;
  2540. }
  2541. return result;
  2542. }
  2543. //***************************************************************************
  2544. //
  2545. // CLDAPInstanceProvider::SetTimeValues
  2546. //
  2547. // Purpose: See Header File
  2548. //
  2549. //***************************************************************************
  2550. HRESULT CLDAPInstanceProvider :: SetTimeValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2551. {
  2552. HRESULT result = S_OK;
  2553. switch(pvPropertyValue->vt)
  2554. {
  2555. case VT_BSTR:
  2556. {
  2557. //199880819014734.000000+000 to 19980819014734.0Z to
  2558. pAttributeEntry->dwNumValues = 1;
  2559. pAttributeEntry->pADsValues = NULL;
  2560. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2561. {
  2562. pAttributeEntry->pADsValues->dwType = adType;
  2563. pAttributeEntry->pADsValues->DNString = NULL;
  2564. if(pAttributeEntry->pADsValues->DNString = new WCHAR[27])
  2565. {
  2566. wcscpy(pAttributeEntry->pADsValues->DNString, pvPropertyValue->bstrVal);
  2567. (pAttributeEntry->pADsValues->DNString)[16] = L'Z';
  2568. (pAttributeEntry->pADsValues->DNString)[17] = NULL;
  2569. }
  2570. else
  2571. result = E_OUTOFMEMORY;
  2572. }
  2573. else
  2574. result = E_OUTOFMEMORY;
  2575. }
  2576. break;
  2577. case VT_BSTR | VT_ARRAY:
  2578. {
  2579. SAFEARRAY *pArray = pvPropertyValue->parray;
  2580. BSTR HUGEP *pbstr;
  2581. LONG lUbound = 0, lLbound = 0;
  2582. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ) &&
  2583. SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2584. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2585. {
  2586. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2587. {
  2588. pAttributeEntry->pADsValues = NULL;
  2589. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2590. {
  2591. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2592. bool bError = false;
  2593. for(DWORD i=0; !bError && (i<pAttributeEntry->dwNumValues); i++)
  2594. {
  2595. pValues->dwType = adType;
  2596. pValues->DNString = NULL;
  2597. if(pValues->DNString = new WCHAR[27])
  2598. {
  2599. wcscpy(pValues->DNString, pbstr[i]);
  2600. (pValues->DNString)[16] = L'Z';
  2601. (pValues->DNString)[17] = NULL;
  2602. pValues ++;
  2603. }
  2604. else
  2605. {
  2606. bError = true;
  2607. result = E_OUTOFMEMORY;
  2608. }
  2609. }
  2610. }
  2611. else
  2612. result = E_OUTOFMEMORY;
  2613. }
  2614. SafeArrayUnaccessData(pArray);
  2615. }
  2616. }
  2617. break;
  2618. default:
  2619. return E_FAIL;
  2620. }
  2621. return result;
  2622. }
  2623. //***************************************************************************
  2624. //
  2625. // CLDAPInstanceProvider::SetLargeIntegerValues
  2626. //
  2627. // Purpose: See Header File
  2628. //
  2629. //***************************************************************************
  2630. HRESULT CLDAPInstanceProvider :: SetLargeIntegerValues(PADS_ATTR_INFO pAttributeEntry, ADSTYPE adType, VARIANT *pvPropertyValue)
  2631. {
  2632. HRESULT result = S_OK;
  2633. switch(pvPropertyValue->vt)
  2634. {
  2635. case VT_BSTR:
  2636. {
  2637. pAttributeEntry->dwNumValues = 1;
  2638. pAttributeEntry->pADsValues = NULL;
  2639. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2640. {
  2641. pAttributeEntry->pADsValues->dwType = adType;
  2642. swscanf(pvPropertyValue->bstrVal, L"%I64d", &((pAttributeEntry->pADsValues->LargeInteger).QuadPart));
  2643. }
  2644. else
  2645. result = E_OUTOFMEMORY;
  2646. }
  2647. break;
  2648. case VT_BSTR | VT_ARRAY:
  2649. {
  2650. SAFEARRAY *pArray = pvPropertyValue->parray;
  2651. BSTR HUGEP *pbstr;
  2652. LONG lUbound = 0, lLbound = 0;
  2653. if(SUCCEEDED(result = SafeArrayAccessData(pArray, (void HUGEP* FAR*)&pbstr) ) &&
  2654. SUCCEEDED (result = SafeArrayGetLBound(pArray, 1, &lLbound)) &&
  2655. SUCCEEDED (result = SafeArrayGetUBound(pArray, 1, &lUbound)) )
  2656. {
  2657. if(pAttributeEntry->dwNumValues = lUbound - lLbound + 1)
  2658. {
  2659. pAttributeEntry->pADsValues = NULL;
  2660. if(pAttributeEntry->pADsValues = new ADSVALUE[pAttributeEntry->dwNumValues])
  2661. {
  2662. PADSVALUE pValues = pAttributeEntry->pADsValues;
  2663. for(DWORD i=0; i<pAttributeEntry->dwNumValues; i++)
  2664. {
  2665. pValues->dwType = adType;
  2666. swscanf(pbstr[i], L"%I64d", &((pValues->LargeInteger).QuadPart));
  2667. pValues ++;
  2668. }
  2669. }
  2670. else
  2671. result = E_OUTOFMEMORY;
  2672. }
  2673. SafeArrayUnaccessData(pArray);
  2674. }
  2675. }
  2676. break;
  2677. default:
  2678. return E_FAIL;
  2679. }
  2680. return result;
  2681. }
  2682. //***************************************************************************
  2683. //
  2684. // CLDAPInstanceProvider::SetObjectClassAttribute
  2685. //
  2686. // Purpose: See Header File
  2687. //
  2688. //***************************************************************************
  2689. void CLDAPInstanceProvider :: SetObjectClassAttribute(PADS_ATTR_INFO pAttributeEntry, LPCWSTR pszADSIClassName)
  2690. {
  2691. // Set its fields to 0;
  2692. memset((LPVOID)pAttributeEntry, 0, sizeof(ADS_ATTR_INFO));
  2693. // Set the name
  2694. pAttributeEntry->pszAttrName = CLDAPHelper::UnmangleWBEMNameToLDAP(OBJECT_CLASS_PROPERTY);
  2695. // Set the value
  2696. pAttributeEntry->dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  2697. pAttributeEntry->dwNumValues = 1;
  2698. pAttributeEntry->pADsValues = NULL;
  2699. if(pAttributeEntry->pADsValues = new ADSVALUE)
  2700. {
  2701. pAttributeEntry->pADsValues->dwType = ADSTYPE_DN_STRING;
  2702. pAttributeEntry->pADsValues->DNString = NULL;
  2703. if(pAttributeEntry->pADsValues->DNString = new WCHAR[wcslen(pszADSIClassName) + 1])
  2704. wcscpy(pAttributeEntry->pADsValues->DNString, pszADSIClassName);
  2705. }
  2706. }
  2707. // Process query for associations
  2708. HRESULT CLDAPInstanceProvider :: ProcessAssociationQuery(
  2709. IWbemContext __RPC_FAR *pCtx,
  2710. IWbemObjectSink __RPC_FAR *pResponseHandler,
  2711. SQL1_Parser *pParser)
  2712. {
  2713. HRESULT result = WBEM_S_NO_ERROR;
  2714. // Parse the query
  2715. SQL_LEVEL_1_RPN_EXPRESSION *pExp = 0;
  2716. if(!pParser->Parse(&pExp))
  2717. {
  2718. // Check to see that it has exactly 1 or 2 clauses, and
  2719. // if 2 clauses are present, these should be different ones, and the operator should be an AND
  2720. // This is because we support only the following kinds of queries
  2721. // Select * From DS_LDAP_CONTAINMENT_CLASS Where parentInstance = <something>
  2722. // Select * From DS_LDAP_CONTAINMENT_CLASS Where childInstance = <something>
  2723. // For all other queries, if there is a NOT operator, we do not support it.
  2724. // Otherwise we just take the individual clauses and return theri union, asking CIMOM to postprocess
  2725. int iNumTokens = pExp->nNumTokens;
  2726. // Go thru the tokens to see that NOT is not present
  2727. SQL_LEVEL_1_TOKEN *pNextToken = pExp->pArrayOfTokens;
  2728. for(int i=0; i<iNumTokens; i++)
  2729. {
  2730. if(pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::TOKEN_NOT ||
  2731. (pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION && pNextToken->nOperator == SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL))
  2732. {
  2733. result = WBEM_E_PROVIDER_NOT_CAPABLE;
  2734. break;
  2735. }
  2736. pNextToken ++;
  2737. }
  2738. // No NOT was found
  2739. if(result != WBEM_E_PROVIDER_NOT_CAPABLE)
  2740. {
  2741. // Ask CIMOM to postprocess the result
  2742. pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_S_NO_ERROR, NULL, NULL);
  2743. // Duplicates need to be avoided. So keep a list of objects indicated so far.
  2744. // The key in the list is formed by concatenating the child and parent ADSI paths
  2745. //===========================================================================
  2746. CNamesList listIndicatedSoFar;
  2747. pNextToken = pExp->pArrayOfTokens;
  2748. i=0;
  2749. while(i<iNumTokens && result != WBEM_E_PROVIDER_NOT_CAPABLE)
  2750. {
  2751. if(pNextToken->nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION)
  2752. {
  2753. LPWSTR pszADSIPath = CWBEMHelper::GetADSIPathFromObjectPath(pNextToken->vConstValue.bstrVal);
  2754. if(_wcsicmp(pNextToken->pPropertyName, CHILD_INSTANCE_PROPERTY_STR) == 0)
  2755. {
  2756. DoChildContainmentQuery(pszADSIPath, pResponseHandler, &listIndicatedSoFar);
  2757. result = WBEM_S_NO_ERROR;
  2758. }
  2759. else if (_wcsicmp(pNextToken->pPropertyName, PARENT_INSTANCE_PROPERTY_STR) == 0)
  2760. {
  2761. DoParentContainmentQuery(pszADSIPath, pResponseHandler, &listIndicatedSoFar);
  2762. result = WBEM_S_NO_ERROR;
  2763. }
  2764. else
  2765. result = WBEM_E_PROVIDER_NOT_CAPABLE;
  2766. delete [] pszADSIPath;
  2767. }
  2768. i++;
  2769. pNextToken ++;
  2770. }
  2771. }
  2772. }
  2773. else
  2774. result = WBEM_E_FAILED;
  2775. delete pExp;
  2776. if(SUCCEEDED(result))
  2777. {
  2778. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, NULL, NULL);
  2779. result = WBEM_S_NO_ERROR;
  2780. }
  2781. else
  2782. {
  2783. pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_FAILED, NULL, NULL);
  2784. result = WBEM_S_NO_ERROR;
  2785. }
  2786. return result;
  2787. }
  2788. // Process Query for DS instances
  2789. HRESULT CLDAPInstanceProvider :: ProcessInstanceQuery(
  2790. BSTR strClass,
  2791. BSTR strQuery,
  2792. IWbemContext __RPC_FAR *pCtx,
  2793. IWbemObjectSink __RPC_FAR *pResponseHandler,
  2794. SQL1_Parser *pParser)
  2795. {
  2796. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() called for %s Class and query %s\r\n", strClass, strQuery);
  2797. HRESULT result = WBEM_E_FAILED;
  2798. // Parse the query
  2799. SQL_LEVEL_1_RPN_EXPRESSION *pExp = NULL;
  2800. if(!pParser->Parse(&pExp))
  2801. {
  2802. // Fetch the class from CIMOM
  2803. IWbemClassObject *pWbemClass = NULL;
  2804. if(SUCCEEDED(result = m_IWbemServices->GetObject(strClass, 0, pCtx, &pWbemClass, NULL)))
  2805. {
  2806. // We need the object category information
  2807. LPWSTR pszLDAPQuery = NULL;
  2808. int nLength = 6*(2*wcslen(strClass) + 75) + wcslen(strQuery) + 500;
  2809. if(pszLDAPQuery = new WCHAR[nLength])
  2810. {
  2811. pszLDAPQuery[0] = LEFT_BRACKET_STR[0];
  2812. pszLDAPQuery[1] = AMPERSAND_STR[0];
  2813. pszLDAPQuery[2] = NULL;
  2814. if(SUCCEEDED(CWBEMHelper::FormulateInstanceQuery(m_IWbemServices, pCtx, strClass, pWbemClass, pszLDAPQuery + 2, LDAP_DISPLAY_NAME_STR, DEFAULT_OBJECT_CATEGORY_STR)))
  2815. {
  2816. // Check to see if it can be converted to an LDAP query
  2817. if(SUCCEEDED(result = ConvertWQLToLDAPQuery(pExp, pszLDAPQuery, nLength)))
  2818. {
  2819. // Complete the query string
  2820. DWORD dwLen = wcslen(pszLDAPQuery);
  2821. pszLDAPQuery[dwLen] = RIGHT_BRACKET_STR[0];
  2822. pszLDAPQuery[dwLen + 1] = NULL;
  2823. // Check to see if the client has specified any hints as to the DN of the object from
  2824. // which the search should start
  2825. BOOLEAN bRootDNSpecified = FALSE;
  2826. LPWSTR *ppszRootDN = NULL;
  2827. DWORD dwRootDNCount = 0;
  2828. if(SUCCEEDED(GetRootDN(strClass, &ppszRootDN, &dwRootDNCount, pCtx)) && dwRootDNCount)
  2829. bRootDNSpecified = TRUE;
  2830. // Enumerate the ADSI Instances
  2831. if(bRootDNSpecified)
  2832. {
  2833. for( DWORD i=0; i<dwRootDNCount; i++)
  2834. {
  2835. DoSingleQuery(strClass, pWbemClass, ppszRootDN[i], pszLDAPQuery, pResponseHandler);
  2836. }
  2837. }
  2838. else
  2839. {
  2840. DoSingleQuery(strClass, pWbemClass, m_lpszTopLevelContainerPath, pszLDAPQuery, pResponseHandler);
  2841. }
  2842. if(bRootDNSpecified)
  2843. {
  2844. for(DWORD i=0; i<dwRootDNCount; i++)
  2845. {
  2846. delete [] ppszRootDN[i];
  2847. }
  2848. delete [] ppszRootDN;
  2849. }
  2850. }
  2851. }
  2852. else
  2853. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: FormulateInstanceQuery() on WBEM class %s FAILED with %x on query %s \r\n", strClass, result, strQuery);
  2854. }
  2855. else
  2856. result = E_OUTOFMEMORY;
  2857. pWbemClass->Release();
  2858. delete [] pszLDAPQuery;
  2859. }
  2860. else
  2861. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() Getting WBEM class %s FAILED with %x on query %s \r\n", strClass, result, strQuery);
  2862. }
  2863. else
  2864. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ProcessInstanceQuery() Parse() FAILED on query %s \r\n", strQuery);
  2865. delete pExp;
  2866. return result;
  2867. }
  2868. HRESULT CLDAPInstanceProvider :: ConvertWQLToLDAPQuery(SQL_LEVEL_1_RPN_EXPRESSION *pExp, LPWSTR pszLDAPQuery, int nLength)
  2869. {
  2870. HRESULT result = E_FAIL;
  2871. DWORD dwLength = wcslen(pszLDAPQuery);
  2872. // Append to the existing string
  2873. if(QueryConvertor::ConvertQueryToLDAP(pExp, pszLDAPQuery + dwLength, nLength-dwLength-1))
  2874. {
  2875. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ConvertWQLToLDAPQuery() Query converted to %s \r\n", pszLDAPQuery);
  2876. result = S_OK;
  2877. }
  2878. else
  2879. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: ConvertWQLToLDAPQuery() FAILED \r\n");
  2880. return result;
  2881. }
  2882. HRESULT CLDAPInstanceProvider :: GetRootDN( LPCWSTR pszClass, LPWSTR **pppszRootDN, DWORD *pdwCount, IWbemContext *pCtx)
  2883. {
  2884. *pppszRootDN = NULL;
  2885. *pdwCount = 0;
  2886. HRESULT result = WBEM_E_FAILED;
  2887. // For the correct query
  2888. LPWSTR pszQuery = new WCHAR[wcslen(pszClass) + wcslen(QUERY_FORMAT) + 10];
  2889. swprintf(pszQuery, QUERY_FORMAT, pszClass);
  2890. BSTR strQuery = SysAllocString(pszQuery);
  2891. delete [] pszQuery;
  2892. IEnumWbemClassObject *pEnum = NULL;
  2893. if(SUCCEEDED(result = m_IWbemServices->ExecQuery(QUERY_LANGUAGE, strQuery, WBEM_FLAG_BIDIRECTIONAL, pCtx, &pEnum)))
  2894. {
  2895. // We ignore more than one instance in this implementation
  2896. // Walk thru the enumeration and examine each class
  2897. IWbemClassObject *pInstance = NULL;
  2898. ULONG dwNextReturned = 0;
  2899. while(SUCCEEDED(result = pEnum->Next( WBEM_INFINITE, 1, &pInstance, &dwNextReturned)) && dwNextReturned == 1)
  2900. {
  2901. (*pdwCount)++;
  2902. pInstance->Release();
  2903. }
  2904. if(*pdwCount)
  2905. {
  2906. if(SUCCEEDED(result = pEnum->Reset()))
  2907. {
  2908. *pppszRootDN = new LPWSTR[*pdwCount];
  2909. DWORD i =0;
  2910. while(SUCCEEDED(result = pEnum->Next( WBEM_INFINITE, 1, &pInstance, &dwNextReturned)) && dwNextReturned == 1)
  2911. {
  2912. // Get the ROOT_DN_PROPERTY, which has the instance
  2913. BSTR strInstancePath = NULL;
  2914. if(SUCCEEDED(result = CWBEMHelper::GetBSTRProperty(pInstance, ROOT_DN_PROPERTY, &strInstancePath)))
  2915. {
  2916. // Now get the object
  2917. IWbemClassObject *pDNInstance = NULL;
  2918. if(SUCCEEDED(result = m_IWbemServices->GetObject(strInstancePath, 0, pCtx, &pDNInstance, NULL)))
  2919. {
  2920. // Now get the DN_PROPERTY from the instance
  2921. BSTR strRootDN = NULL;
  2922. if(SUCCEEDED(result = CWBEMHelper::GetBSTRProperty(pDNInstance, DN_PROPERTY, &strRootDN)))
  2923. {
  2924. (*pppszRootDN)[i] = new WCHAR[wcslen(strRootDN) + 1];
  2925. wcscpy((*pppszRootDN)[i], strRootDN);
  2926. SysFreeString(strRootDN);
  2927. i++;
  2928. }
  2929. pDNInstance->Release();
  2930. }
  2931. SysFreeString(strInstancePath);
  2932. }
  2933. pInstance->Release();
  2934. }
  2935. *pdwCount = i;
  2936. }
  2937. }
  2938. else
  2939. result = WBEM_E_FAILED; // To satisfy the return semantics of the function
  2940. pEnum->Release();
  2941. }
  2942. SysFreeString(strQuery);
  2943. return result;
  2944. }
  2945. // Process query for associations
  2946. HRESULT CLDAPInstanceProvider :: ProcessRootDSEGetObject(BSTR strClassName, IWbemObjectSink *pResponseHandler, IWbemContext *pCtx)
  2947. {
  2948. HRESULT result = E_FAIL;
  2949. // First get the object rom ADSI
  2950. //==============================
  2951. IADs *pADSIRootDSE = NULL;
  2952. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)ROOT_DSE_PATH, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, (LPVOID *) &pADSIRootDSE)))
  2953. {
  2954. // Get the class to spawn an instance
  2955. IWbemClassObject *pWbemClass = NULL;
  2956. if(SUCCEEDED(result = m_IWbemServices->GetObject(strClassName, 0, pCtx, &pWbemClass, NULL)))
  2957. {
  2958. IWbemClassObject *pWBEMRootDSE = NULL;
  2959. // Spawn a instance of the WBEM Class
  2960. if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, &pWBEMRootDSE)))
  2961. {
  2962. // Map it to WBEM
  2963. if(SUCCEEDED(result = MapRootDSE(pADSIRootDSE, pWBEMRootDSE)))
  2964. {
  2965. // Indicate the result
  2966. result = pResponseHandler->Indicate(1, &pWBEMRootDSE);
  2967. }
  2968. pWBEMRootDSE->Release();
  2969. }
  2970. pWbemClass->Release();
  2971. }
  2972. pADSIRootDSE->Release();
  2973. }
  2974. return result;
  2975. }
  2976. HRESULT CLDAPInstanceProvider :: MapRootDSE(IADs *pADSIRootDSE, IWbemClassObject *pWBEMRootDSE)
  2977. {
  2978. // Map the properties one-by-one
  2979. //=================================
  2980. VARIANT variant;
  2981. VariantInit(&variant);
  2982. if(SUCCEEDED(pADSIRootDSE->Get(SUBSCHEMASUBENTRY_STR, &variant)))
  2983. pWBEMRootDSE->Put(SUBSCHEMASUBENTRY_STR, 0, &variant, 0);
  2984. VariantClear(&variant);
  2985. VariantInit(&variant);
  2986. if(SUCCEEDED(pADSIRootDSE->Get(SERVERNAME_STR, &variant)))
  2987. pWBEMRootDSE->Put(SERVERNAME_STR, 0, &variant, 0);
  2988. VariantClear(&variant);
  2989. VariantInit(&variant);
  2990. if(SUCCEEDED(pADSIRootDSE->Get(DEFAULTNAMINGCONTEXT_STR, &variant)))
  2991. pWBEMRootDSE->Put(DEFAULTNAMINGCONTEXT_STR, 0, &variant, 0);
  2992. VariantClear(&variant);
  2993. VariantInit(&variant);
  2994. if(SUCCEEDED(pADSIRootDSE->Get(SCHEMANAMINGCONTEXT_STR, &variant)))
  2995. pWBEMRootDSE->Put(SCHEMANAMINGCONTEXT_STR, 0, &variant, 0);
  2996. VariantClear(&variant);
  2997. VariantInit(&variant);
  2998. if(SUCCEEDED(pADSIRootDSE->Get(CONFIGURATIONNAMINGCONTEXT_STR, &variant)))
  2999. pWBEMRootDSE->Put(CONFIGURATIONNAMINGCONTEXT_STR, 0, &variant, 0);
  3000. VariantClear(&variant);
  3001. VariantInit(&variant);
  3002. if(SUCCEEDED(pADSIRootDSE->Get(ROOTDOMAINNAMINGCONTEXT_STR, &variant)))
  3003. pWBEMRootDSE->Put(ROOTDOMAINNAMINGCONTEXT_STR, 0, &variant, 0);
  3004. VariantClear(&variant);
  3005. VariantInit(&variant);
  3006. if(SUCCEEDED(pADSIRootDSE->Get(CURRENTTIME_STR, &variant)))
  3007. pWBEMRootDSE->Put(CURRENTTIME_STR, 0, &variant, 0);
  3008. VariantClear(&variant);
  3009. VariantInit(&variant);
  3010. if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDVERSION_STR, &variant)))
  3011. CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDVERSION_STR, &variant);
  3012. VariantClear(&variant);
  3013. VariantInit(&variant);
  3014. if(SUCCEEDED(pADSIRootDSE->Get(NAMINGCONTEXTS_STR, &variant)))
  3015. CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, NAMINGCONTEXTS_STR, &variant);
  3016. VariantClear(&variant);
  3017. VariantInit(&variant);
  3018. if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDCONTROLS_STR, &variant)))
  3019. CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDCONTROLS_STR, &variant);
  3020. VariantClear(&variant);
  3021. VariantInit(&variant);
  3022. if(SUCCEEDED(pADSIRootDSE->Get(DNSHOSTNAME_STR, &variant)))
  3023. pWBEMRootDSE->Put(DNSHOSTNAME_STR, 0, &variant, 0);
  3024. VariantClear(&variant);
  3025. VariantInit(&variant);
  3026. if(SUCCEEDED(pADSIRootDSE->Get(DSSERVICENAME_STR, &variant)))
  3027. pWBEMRootDSE->Put(DSSERVICENAME_STR, 0, &variant, 0);
  3028. VariantClear(&variant);
  3029. VariantInit(&variant);
  3030. if(SUCCEEDED(pADSIRootDSE->Get(HIGHESTCOMMITEDUSN_STR, &variant)))
  3031. pWBEMRootDSE->Put(HIGHESTCOMMITEDUSN_STR, 0, &variant, 0);
  3032. VariantClear(&variant);
  3033. VariantInit(&variant);
  3034. if(SUCCEEDED(pADSIRootDSE->Get(LDAPSERVICENAME_STR, &variant)))
  3035. pWBEMRootDSE->Put(LDAPSERVICENAME_STR, 0, &variant, 0);
  3036. VariantClear(&variant);
  3037. VariantInit(&variant);
  3038. if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDCAPABILITIES_STR, &variant)))
  3039. pWBEMRootDSE->Put(SUPPORTEDCAPABILITIES_STR, 0, &variant, 0);
  3040. VariantClear(&variant);
  3041. VariantInit(&variant);
  3042. if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDLDAPPOLICIES_STR, &variant)))
  3043. CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDLDAPPOLICIES_STR, &variant);
  3044. VariantClear(&variant);
  3045. VariantInit(&variant);
  3046. if(SUCCEEDED(pADSIRootDSE->Get(SUPPORTEDSASLMECHANISMS_STR, &variant)))
  3047. CWBEMHelper::PutBSTRArrayProperty(pWBEMRootDSE, SUPPORTEDSASLMECHANISMS_STR, &variant);
  3048. VariantClear(&variant);
  3049. return S_OK;
  3050. }
  3051. HRESULT CLDAPInstanceProvider :: DoSingleQuery(BSTR strClass, IWbemClassObject *pWbemClass, LPCWSTR pszRootDN, LPCWSTR pszLDAPQuery, IWbemObjectSink *pResponseHandler)
  3052. {
  3053. // Initialize the return values
  3054. HRESULT result = E_FAIL;
  3055. // Bind to the node from which the search should start
  3056. IDirectorySearch *pDirectorySearchContainer = NULL;
  3057. if(SUCCEEDED(result = ADsOpenObject((LPWSTR)pszRootDN, NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (LPVOID *)&pDirectorySearchContainer)))
  3058. {
  3059. OnDelete<IUnknown *,void(*)(IUnknown *),RM> dm1(pDirectorySearchContainer);
  3060. // Now perform a search for the attribute DISTINGUISHED_NAME_ATTR name
  3061. if(SUCCEEDED(result = pDirectorySearchContainer->SetSearchPreference(m_pSearchInfo, 2)))
  3062. {
  3063. ADS_SEARCH_HANDLE hADSSearchOuter;
  3064. if(SUCCEEDED(result = pDirectorySearchContainer->ExecuteSearch((LPWSTR) pszLDAPQuery, (LPWSTR *)&ADS_PATH_ATTR, 1, &hADSSearchOuter)))
  3065. {
  3066. OnDeleteObj<ADS_SEARCH_HANDLE,
  3067. IDirectorySearch,
  3068. HRESULT(_stdcall IDirectorySearch::*)(ADS_SEARCH_HANDLE),
  3069. &IDirectorySearch::CloseSearchHandle> CloseSHandle(pDirectorySearchContainer,hADSSearchOuter);
  3070. bool bDone = false;
  3071. // Calculate the number of rows first.
  3072. while(!bDone && SUCCEEDED(result = pDirectorySearchContainer->GetNextRow(hADSSearchOuter)) &&
  3073. result != S_ADS_NOMORE_ROWS)
  3074. {
  3075. CADSIInstance *pADSIInstance = NULL;
  3076. // Get the columns for the attributes
  3077. ADS_SEARCH_COLUMN adsColumn;
  3078. // Store each of the LDAP class attributes
  3079. if(SUCCEEDED(pDirectorySearchContainer->GetColumn(hADSSearchOuter, (LPWSTR)ADS_PATH_ATTR, &adsColumn)))
  3080. {
  3081. OnDeleteObj<ADS_SEARCH_COLUMN *,
  3082. IDirectorySearch,
  3083. HRESULT(_stdcall IDirectorySearch::*)(ADS_SEARCH_COLUMN *),
  3084. &IDirectorySearch::FreeColumn> FreeCol(pDirectorySearchContainer,&adsColumn);
  3085. if(adsColumn.pADsValues->dwType != ADSTYPE_PROV_SPECIFIC)
  3086. {
  3087. // Create the CADSIInstance
  3088. if(SUCCEEDED(result = CLDAPHelper:: GetADSIInstance(adsColumn.pADsValues->DNString, &pADSIInstance, g_pLogObject)))
  3089. {
  3090. OnDeleteObj0<CADSIInstance,void(CADSIInstance::*)(),&CADSIInstance::Release> dm(pADSIInstance);
  3091. // Spawn a instance of the WBEM Class
  3092. IWbemClassObject *pWbemInstance = NULL;
  3093. if(SUCCEEDED(result = pWbemClass->SpawnInstance(0, &pWbemInstance)))
  3094. {
  3095. OnDelete<IUnknown *,void(*)(IUnknown *),RM> dm(pWbemInstance);
  3096. // Map it to WBEM
  3097. if(SUCCEEDED(result = MapADSIInstance(pADSIInstance, pWbemInstance, pWbemClass)))
  3098. {
  3099. // Indicate the result
  3100. if(FAILED(result = pResponseHandler->Indicate(1, &pWbemInstance)))
  3101. {
  3102. bDone = true;
  3103. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync Indicate() FAILED with %x \r\n", result);
  3104. }
  3105. }
  3106. else
  3107. g_pLogObject->WriteW( L"CLDAPInstanceProvider :: CreateInstanceEnumAsync MapADSIInstance() FAILED with %x \r\n", result);
  3108. }
  3109. }
  3110. }
  3111. }
  3112. }
  3113. } // ExecuteSearch()
  3114. else
  3115. g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery ExecuteSearch() %s FAILED with %x\r\n", pszLDAPQuery, result);
  3116. } // SetSearchPreference()
  3117. else
  3118. g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery SetSearchPreference() on %s FAILED with %x \r\n", pszLDAPQuery, result);
  3119. } // ADsOpenObject
  3120. else
  3121. g_pLogObject->WriteW( L"CLDAPHelper :: ExecuteQuery ADsOpenObject() on %s FAILED with %x \r\n", pszRootDN, result);
  3122. return result;
  3123. }