Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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