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.

3138 lines
72 KiB

  1. //***************************************************************************
  2. //
  3. // VPTASKS.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the common methods taskobject implementation
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. //need the following three lines
  13. //to get the security stuff to work
  14. #include "precomp.h"
  15. #include <provexpt.h>
  16. #include <provcoll.h>
  17. #include <provtempl.h>
  18. #include <provmt.h>
  19. #include <typeinfo.h>
  20. #include <process.h>
  21. #include <objbase.h>
  22. #include <objidl.h>
  23. #include <stdio.h>
  24. #include <wbemidl.h>
  25. #include <provcont.h>
  26. #include <provevt.h>
  27. #include <provthrd.h>
  28. #include <provlog.h>
  29. #include <cominit.h>
  30. #include <dsgetdc.h>
  31. #include <lmcons.h>
  32. #include <lmapibuf.h>
  33. #include <instpath.h>
  34. #include <genlex.h>
  35. #include <sql_1.h>
  36. #include <objpath.h>
  37. #include <vpdefs.h>
  38. #include <vpcfac.h>
  39. #include <vpquals.h>
  40. #include <vpserv.h>
  41. #include <vptasks.h>
  42. extern BOOL bAreWeLocal(WCHAR* pServerMachine);
  43. #ifdef VP_BUILD_AS_EXE
  44. HRESULT EnableAllPrivileges(BOOL bProcess)
  45. {
  46. // Open thread token
  47. // =================
  48. HANDLE hToken = NULL;
  49. BOOL bRes = FALSE;
  50. if (bProcess)
  51. {
  52. bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken);
  53. }
  54. else
  55. {
  56. bRes = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, TRUE, &hToken);
  57. }
  58. if(!bRes)
  59. return WBEM_E_ACCESS_DENIED;
  60. // Get the privileges
  61. // ==================
  62. DWORD dwLen;
  63. TOKEN_USER tu;
  64. memset(&tu,0,sizeof(TOKEN_USER));
  65. bRes = GetTokenInformation(hToken, TokenPrivileges, &tu, sizeof(TOKEN_USER), &dwLen);
  66. BYTE* pBuffer = new BYTE[dwLen];
  67. if(pBuffer == NULL)
  68. {
  69. CloseHandle(hToken);
  70. return WBEM_E_OUT_OF_MEMORY;
  71. }
  72. bRes = GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwLen,
  73. &dwLen);
  74. if(!bRes)
  75. {
  76. CloseHandle(hToken);
  77. delete [] pBuffer;
  78. return WBEM_E_ACCESS_DENIED;
  79. }
  80. // Iterate through all the privileges and enable them all
  81. // ======================================================
  82. TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
  83. for(DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
  84. {
  85. pPrivs->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED;
  86. }
  87. // Store the information back into the token
  88. // =========================================
  89. bRes = AdjustTokenPrivileges(hToken, FALSE, pPrivs, 0, NULL, NULL);
  90. delete [] pBuffer;
  91. CloseHandle(hToken);
  92. if(!bRes)
  93. return WBEM_E_ACCESS_DENIED;
  94. else
  95. return WBEM_S_NO_ERROR;
  96. }
  97. #endif
  98. #ifdef UNICODE
  99. HRESULT GetCurrentSecuritySettings(DWORD *pdwAuthnSvc, DWORD *pdwAuthzSvc,
  100. DWORD *pdwAuthLevel, DWORD *pdwImpLevel,
  101. DWORD *pdwCapabilities)
  102. {
  103. HRESULT hr = WBEM_E_FAILED;
  104. IServerSecurity * pss = NULL;
  105. hr = WbemCoGetCallContext(IID_IServerSecurity, (void**)&pss);
  106. #if 0
  107. DWORD dwBuffSz = 1024;
  108. wchar_t strBuff[1024];
  109. GetUserName(strBuff, &dwBuffSz);
  110. #endif
  111. if(S_OK == hr)
  112. {
  113. pss->QueryBlanket(pdwAuthnSvc, pdwAuthzSvc, NULL,
  114. pdwAuthLevel, NULL, NULL, pdwCapabilities);
  115. pss->Release();
  116. }
  117. else
  118. {
  119. if (SUCCEEDED(hr))
  120. {
  121. hr = WBEM_E_FAILED;
  122. }
  123. }
  124. if (SUCCEEDED(hr))
  125. {
  126. DWORD dwVersion = GetVersion();
  127. if (dwVersion < 0x80000000)
  128. {
  129. if ( 4 < (DWORD)(LOBYTE(LOWORD(dwVersion))) )
  130. {
  131. //we're on win2k force static cloaking...
  132. *pdwCapabilities = EOAC_STATIC_CLOAKING;
  133. }
  134. }
  135. //get implevel...
  136. HANDLE hThreadTok = NULL;
  137. hr = WBEM_E_FAILED;
  138. if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hThreadTok) )
  139. {
  140. DWORD dwBytesReturned = 0;
  141. DWORD dwThreadImpLevel = 0;
  142. if (GetTokenInformation(hThreadTok, TokenImpersonationLevel, &dwThreadImpLevel,
  143. sizeof(DWORD), &dwBytesReturned))
  144. {
  145. hr = WBEM_NO_ERROR;
  146. switch(dwThreadImpLevel)
  147. {
  148. case SecurityAnonymous:
  149. {
  150. *pdwImpLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
  151. }
  152. break;
  153. case SecurityIdentification:
  154. {
  155. *pdwImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
  156. }
  157. break;
  158. case SecurityImpersonation:
  159. {
  160. *pdwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  161. }
  162. break;
  163. case SecurityDelegation:
  164. {
  165. *pdwImpLevel = RPC_C_IMP_LEVEL_DELEGATE;
  166. }
  167. break;
  168. default:
  169. {
  170. hr = WBEM_E_FAILED;
  171. }
  172. }
  173. #ifdef VP_BUILD_AS_EXE
  174. if (*pdwImpLevel < RPC_C_IMP_LEVEL_IMPERSONATE)
  175. {
  176. *pdwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  177. }
  178. #endif
  179. }
  180. CloseHandle(hThreadTok);
  181. }
  182. }
  183. return hr;
  184. }
  185. #endif
  186. HRESULT SetSecurityLevelAndCloaking(IUnknown* pInterface, const wchar_t* prncpl)
  187. {
  188. #ifdef UNICODE
  189. //first get current security info then set it on the proxy...
  190. DWORD dwAuthnSvc = 0;
  191. DWORD dwAuthzSvc = 0;
  192. DWORD dwAuthLevel = 0;
  193. DWORD dwImpLevel = 0;
  194. DWORD dwCapabilities = 0;
  195. HRESULT hr = GetCurrentSecuritySettings(&dwAuthnSvc, &dwAuthzSvc, &dwAuthLevel, &dwImpLevel, &dwCapabilities);
  196. if (SUCCEEDED(hr))
  197. {
  198. #ifdef VP_BUILD_AS_EXE
  199. EnableAllPrivileges(FALSE);
  200. #endif
  201. DWORD dwVersion = GetVersion();
  202. OLECHAR *t_pname = NULL;
  203. if (dwVersion < 0x80000000)
  204. {
  205. if ( 4 < (DWORD)(LOBYTE(LOWORD(dwVersion))) )
  206. {
  207. //we're on win2k force COLE_DEFAULT_PRINCIPAL...
  208. t_pname = COLE_DEFAULT_PRINCIPAL;
  209. if ((dwImpLevel > 3) && (prncpl != COLE_DEFAULT_PRINCIPAL))
  210. {
  211. dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS;
  212. }
  213. }
  214. }
  215. hr = WbemSetProxyBlanket(pInterface,
  216. dwAuthnSvc,//16
  217. dwAuthzSvc,//RPC_C_AUTHZ_NONE
  218. t_pname, //prncpl,
  219. dwAuthLevel, //RPC_C_AUTHN_LEVEL_CONNECT
  220. dwImpLevel, //RPC_C_IMP_LEVEL_IMPERSONATE
  221. NULL,
  222. dwCapabilities); //0x20
  223. //there is no IClientSecurity, we must be running inproc!
  224. if (hr == E_NOINTERFACE)
  225. {
  226. hr = S_OK;
  227. }
  228. #if 0
  229. if (SUCCEEDED(hr))
  230. {
  231. IClientSecurity *t_pCliSec = NULL;
  232. HRESULT t_hr = pInterface->QueryInterface(IID_IClientSecurity, (void **) &t_pCliSec);
  233. if (SUCCEEDED(t_hr))
  234. {
  235. DWORD t_AuthnSvc = 0;
  236. DWORD t_AuthzSvc = 0;
  237. wchar_t *t_pServerPrincName = NULL;
  238. DWORD t_AuthnLevel = 0;
  239. DWORD t_ImpLevel = 0;
  240. DWORD t_Capabilities = 0;
  241. t_hr = t_pCliSec->QueryBlanket(pInterface, &t_AuthnSvc,
  242. &t_AuthzSvc, &t_pServerPrincName,
  243. &t_AuthnLevel, &t_ImpLevel,
  244. NULL, &t_Capabilities);
  245. if (SUCCEEDED(t_hr))
  246. {
  247. if (t_pServerPrincName)
  248. {
  249. CoTaskMemFree(t_pServerPrincName);
  250. }
  251. }
  252. t_pCliSec->Release();
  253. }
  254. }
  255. #endif
  256. }
  257. #else
  258. HRESULT hr = WBEM_NO_ERROR;
  259. #endif
  260. return hr;
  261. }
  262. BOOL IsInObjectPath(ParsedObjectPath *a_ParsedObjectPath, const wchar_t *a_key)
  263. {
  264. if ( (!a_ParsedObjectPath->IsInstance()) || (a_ParsedObjectPath->m_bSingletonObj) || (a_ParsedObjectPath->m_paKeys == NULL) )
  265. {
  266. return FALSE;
  267. }
  268. for (int x = 0; x < a_ParsedObjectPath->m_dwNumKeys; x++)
  269. {
  270. if ((a_ParsedObjectPath->m_paKeys[x]->m_pName != NULL)
  271. && (_wcsicmp(a_key, a_ParsedObjectPath->m_paKeys[x]->m_pName) == 0))
  272. {
  273. return TRUE;
  274. }
  275. }
  276. return FALSE;
  277. }
  278. //returns TRUE if VARIANTs are equal
  279. BOOL CompareKeyValueVariants(const VARIANT &a_v1, const VARIANT &a_v2)
  280. {
  281. BOOL retVal = FALSE;
  282. if (a_v1.vt == a_v2.vt)
  283. {
  284. switch (a_v1.vt)
  285. {
  286. case VT_BSTR:
  287. {
  288. retVal = (_wcsicmp(a_v1.bstrVal, a_v2.bstrVal) == 0);
  289. break;
  290. }
  291. case VT_I4:
  292. {
  293. retVal = (a_v1.lVal == a_v2.lVal);
  294. break;
  295. }
  296. case VT_I2:
  297. {
  298. retVal = (a_v1.iVal == a_v2.iVal);
  299. break;
  300. }
  301. case VT_UI1:
  302. {
  303. retVal = (a_v1.bVal == a_v2.bVal);
  304. break;
  305. }
  306. case VT_BOOL:
  307. {
  308. retVal = (V_BOOL(&a_v1) == V_BOOL(&a_v2));
  309. break;
  310. }
  311. default:
  312. {
  313. }
  314. }
  315. }
  316. return retVal;
  317. }
  318. //this function assumes class 1 is derived from class2 or vice versa
  319. //returns TRUE if paths are equal
  320. BOOL CompareInstPaths(const wchar_t *a_path1, const wchar_t *a_path2)
  321. {
  322. BOOL retVal = FALSE;
  323. if ((a_path1 == NULL) || (a_path2 == NULL))
  324. {
  325. return retVal;
  326. }
  327. CObjectPathParser t_objectPathParser;
  328. wchar_t* t_objPath1 = UnicodeStringDuplicate(a_path1);
  329. wchar_t* t_objPath2 = UnicodeStringDuplicate(a_path2);
  330. ParsedObjectPath *t_parsedpath1 = NULL;
  331. ParsedObjectPath *t_parsedpath2 = NULL;
  332. if ( (t_objectPathParser.Parse(t_objPath1, &t_parsedpath1) == 0) &&
  333. (t_objectPathParser.Parse(t_objPath2, &t_parsedpath2) == 0) &&
  334. t_parsedpath1->IsInstance() && t_parsedpath2->IsInstance())
  335. {
  336. if (t_parsedpath1->m_dwNumKeys == t_parsedpath2->m_dwNumKeys)
  337. {
  338. retVal = TRUE;
  339. //single properties
  340. if ((t_parsedpath1->m_dwNumKeys == 1) &&
  341. ((t_parsedpath1->m_paKeys[0]->m_pName == NULL) || (t_parsedpath2->m_paKeys[0]->m_pName == NULL)))
  342. {
  343. //compare the values...
  344. retVal = CompareKeyValueVariants(t_parsedpath1->m_paKeys[0]->m_vValue,
  345. t_parsedpath2->m_paKeys[0]->m_vValue);
  346. }
  347. else
  348. {
  349. //any property mismatch set retVal FALSE!
  350. for (DWORD i = 0; retVal && (i < t_parsedpath1->m_dwNumKeys); i++)
  351. {
  352. retVal = FALSE;
  353. if(t_parsedpath1->m_paKeys[i]->m_pName == NULL)
  354. {
  355. break;
  356. }
  357. for (DWORD j = 0; j < t_parsedpath2->m_dwNumKeys; j++)
  358. {
  359. if(t_parsedpath2->m_paKeys[j]->m_pName == NULL)
  360. {
  361. break;
  362. }
  363. if (_wcsicmp(t_parsedpath1->m_paKeys[i]->m_pName, t_parsedpath2->m_paKeys[j]->m_pName) == 0)
  364. {
  365. //compare the values...
  366. retVal = CompareKeyValueVariants(t_parsedpath1->m_paKeys[i]->m_vValue,
  367. t_parsedpath2->m_paKeys[j]->m_vValue);
  368. }
  369. }
  370. }
  371. }
  372. }
  373. }
  374. delete [] t_objPath1;
  375. delete [] t_objPath2;
  376. if (t_parsedpath1 != NULL)
  377. {
  378. delete t_parsedpath1;
  379. }
  380. if (t_parsedpath2 != NULL)
  381. {
  382. delete t_parsedpath2;
  383. }
  384. return retVal;
  385. }
  386. WbemTaskObject :: WbemTaskObject (
  387. CViewProvServ *a_Provider ,
  388. IWbemObjectSink *a_NotificationHandler ,
  389. ULONG a_OperationFlag ,
  390. IWbemContext *a_Ctx,
  391. IWbemServices *a_Serv,
  392. CWbemServerWrap *a_ServerWrap
  393. ) :m_OperationFlag ( a_OperationFlag ) ,
  394. m_Provider ( NULL ) ,
  395. m_NotificationHandler ( NULL ) ,
  396. m_Ctx ( NULL ) ,
  397. m_ClassObject ( NULL ),
  398. m_RPNPostFilter( NULL),
  399. m_ClassName(NULL),
  400. m_Ref ( 1 ),
  401. m_iQueriesAnswered ( 0 ),
  402. m_iQueriesAsked ( 0 ),
  403. m_StatusHandle(NULL),
  404. m_bAssoc ( FALSE ),
  405. m_bSingleton ( FALSE ),
  406. m_Serv ( NULL ),
  407. m_bIndicate ( TRUE ) ,
  408. m_ResultReceived ( FALSE ),
  409. m_ServerWrap (NULL)
  410. {
  411. m_Provider = a_Provider ;
  412. m_Provider->AddRef () ;
  413. m_Serv = a_Serv;
  414. if (m_Serv != NULL)
  415. {
  416. m_Serv->AddRef();
  417. }
  418. m_ServerWrap = a_ServerWrap;
  419. if (m_ServerWrap != NULL)
  420. {
  421. m_ServerWrap->AddRef();
  422. }
  423. if ((m_Serv == NULL) && (m_ServerWrap == NULL))
  424. {
  425. m_Serv = m_Provider->GetServer();
  426. }
  427. m_NotificationHandler = a_NotificationHandler ;
  428. m_NotificationHandler->AddRef () ;
  429. if (a_Ctx)
  430. {
  431. m_Ctx = a_Ctx ;
  432. m_Ctx->AddRef () ;
  433. }
  434. }
  435. WbemTaskObject :: ~WbemTaskObject ()
  436. {
  437. if (m_NotificationHandler)
  438. {
  439. m_NotificationHandler->Release () ;
  440. }
  441. if (m_Ctx)
  442. {
  443. m_Ctx->Release () ;
  444. }
  445. if (m_ClassName)
  446. {
  447. SysFreeString(m_ClassName);
  448. }
  449. if ( m_ClassObject )
  450. {
  451. m_ClassObject->Release () ;
  452. }
  453. if (m_Serv != NULL)
  454. {
  455. m_Serv->Release();
  456. }
  457. if (m_ServerWrap != NULL)
  458. {
  459. m_ServerWrap->Release();
  460. }
  461. int isrc = m_SourceArray.GetSize();
  462. int ins = m_NSpaceArray.GetSize();
  463. int i = isrc;
  464. if (isrc > ins)
  465. {
  466. i = ins;
  467. for (int x = ins; x < isrc; x++)
  468. {
  469. delete m_SourceArray[x];
  470. }
  471. }
  472. else if (isrc < ins)
  473. {
  474. for (int x = isrc; x < ins; x++)
  475. {
  476. delete m_NSpaceArray[x];
  477. }
  478. }
  479. for (int x = 0; x < i; x++)
  480. {
  481. delete m_SourceArray[x];
  482. delete m_NSpaceArray[x];
  483. }
  484. m_SourceArray.RemoveAll();
  485. m_NSpaceArray.RemoveAll();
  486. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  487. {
  488. if (m_ObjSinkArray[x] != NULL)
  489. {
  490. m_ObjSinkArray[x]->Release();
  491. }
  492. }
  493. m_ObjSinkArray.RemoveAll();
  494. m_ClassToIndexMap.RemoveAll();
  495. m_EnumerateClasses.RemoveAll();
  496. //this decrements objectsinprogress so MUST be done LAST!!
  497. if (m_Provider)
  498. m_Provider->Release ();
  499. }
  500. WbemProvErrorObject &WbemTaskObject :: GetErrorObject ()
  501. {
  502. return m_ErrorObject ;
  503. }
  504. BOOL WbemTaskObject :: SetClass(const wchar_t* a_Class)
  505. {
  506. m_ClassName = SysAllocString(a_Class);
  507. BOOL ret = GetClassObject(m_Serv, m_ClassName, &m_ClassObject, &m_ServerWrap);
  508. return ret;
  509. }
  510. BOOL WbemTaskObject :: GetClassObject ( IWbemServices* pServ, BSTR a_Class, IWbemClassObject** ppClass, CWbemServerWrap **a_pServWrap)
  511. {
  512. if ((NULL == a_Class) || (NULL == ppClass) ||
  513. ((NULL == pServ) && ((NULL == a_pServWrap) || (NULL == (*a_pServWrap))))
  514. )
  515. {
  516. return FALSE;
  517. }
  518. else
  519. {
  520. *ppClass = NULL;
  521. }
  522. HRESULT t_Result = WBEM_E_FAILED;
  523. if (*a_pServWrap)
  524. {
  525. IWbemServices *ptmpServ = (*a_pServWrap)->GetServerOrProxy();
  526. if (ptmpServ)
  527. {
  528. t_Result = ptmpServ->GetObject(a_Class, 0, m_Ctx, ppClass, NULL);
  529. if ( FAILED(t_Result) && (HRESULT_FACILITY(t_Result) != FACILITY_ITF) && (*a_pServWrap)->IsRemote())
  530. {
  531. if ( SUCCEEDED(UpdateConnection(a_pServWrap, &ptmpServ)) )
  532. {
  533. if (ptmpServ)
  534. {
  535. t_Result = ptmpServ->GetObject(a_Class, 0, m_Ctx, ppClass, NULL);
  536. }
  537. }
  538. }
  539. if (ptmpServ)
  540. {
  541. (*a_pServWrap)->ReturnServerOrProxy(ptmpServ);
  542. }
  543. }
  544. }
  545. else
  546. {
  547. t_Result = pServ->GetObject(a_Class, 0, m_Ctx, ppClass, NULL);
  548. }
  549. if (FAILED(t_Result))
  550. {
  551. *ppClass = NULL;
  552. return FALSE;
  553. }
  554. return TRUE;
  555. }
  556. BOOL WbemTaskObject :: GetExtendedNotifyStatusObject ( IWbemClassObject **a_NotifyObject )
  557. {
  558. IWbemClassObject *t_NotificationClassObject = NULL ;
  559. IWbemClassObject *t_ErrorObject = NULL ;
  560. BOOL t_Status = TRUE ;
  561. WbemProvErrorObject t_ErrorStatusObject ;
  562. if ( t_NotificationClassObject = m_Provider->GetExtendedNotificationObject ( t_ErrorStatusObject, m_Ctx ) )
  563. {
  564. HRESULT t_Result = t_NotificationClassObject->SpawnInstance ( 0 , a_NotifyObject ) ;
  565. if ( SUCCEEDED ( t_Result ) )
  566. {
  567. VARIANT t_Variant ;
  568. VariantInit ( &t_Variant ) ;
  569. t_Variant.vt = VT_I4 ;
  570. t_Variant.lVal = m_ErrorObject.GetWbemStatus () ;
  571. t_Result = (*a_NotifyObject)->Put ( WBEM_PROPERTY_STATUSCODE , 0 , &t_Variant , 0 ) ;
  572. VariantClear ( &t_Variant ) ;
  573. if ( SUCCEEDED ( t_Result ) )
  574. {
  575. t_Variant.vt = VT_I4 ;
  576. t_Variant.lVal = m_ErrorObject.GetStatus () ;
  577. t_Result = (*a_NotifyObject)->Put ( WBEM_PROPERTY_PROVSTATUSCODE , 0 , &t_Variant , 0 ) ;
  578. VariantClear ( &t_Variant ) ;
  579. if ( SUCCEEDED ( t_Result ) )
  580. {
  581. if ( m_ErrorObject.GetMessage () )
  582. {
  583. t_Variant.vt = VT_BSTR ;
  584. t_Variant.bstrVal = SysAllocString ( m_ErrorObject.GetMessage () ) ;
  585. t_Result = (*a_NotifyObject)->Put ( WBEM_PROPERTY_PROVSTATUSMESSAGE , 0 , &t_Variant , 0 ) ;
  586. VariantClear ( &t_Variant ) ;
  587. if ( ! SUCCEEDED ( t_Result ) )
  588. {
  589. (*a_NotifyObject)->Release () ;
  590. t_Status = GetNotifyStatusObject ( a_NotifyObject ) ;
  591. }
  592. }
  593. }
  594. else
  595. {
  596. (*a_NotifyObject)->Release () ;
  597. t_Status = GetNotifyStatusObject ( a_NotifyObject ) ;
  598. }
  599. }
  600. else
  601. {
  602. (*a_NotifyObject)->Release () ;
  603. t_Status = GetNotifyStatusObject ( a_NotifyObject ) ;
  604. }
  605. t_NotificationClassObject->Release () ;
  606. }
  607. else
  608. {
  609. t_Status = GetNotifyStatusObject ( a_NotifyObject ) ;
  610. }
  611. }
  612. else
  613. {
  614. t_Status = GetNotifyStatusObject ( a_NotifyObject ) ;
  615. }
  616. return t_Status ;
  617. }
  618. BOOL WbemTaskObject :: GetNotifyStatusObject ( IWbemClassObject **a_NotifyObject )
  619. {
  620. IWbemClassObject *t_NotificationClassObject = NULL ;
  621. BOOL t_Status = TRUE ;
  622. WbemProvErrorObject t_ErrorStatusObject ;
  623. if ( t_NotificationClassObject = m_Provider->GetNotificationObject ( t_ErrorStatusObject, m_Ctx ) )
  624. {
  625. HRESULT t_Result = t_NotificationClassObject->SpawnInstance ( 0 , a_NotifyObject ) ;
  626. if ( SUCCEEDED ( t_Result ) )
  627. {
  628. VARIANT t_Variant ;
  629. VariantInit ( &t_Variant ) ;
  630. t_Variant.vt = VT_I4 ;
  631. t_Variant.lVal = m_ErrorObject.GetWbemStatus () ;
  632. t_Result = (*a_NotifyObject)->Put ( WBEM_PROPERTY_STATUSCODE , 0 , &t_Variant , 0 ) ;
  633. if ( SUCCEEDED ( t_Result ) )
  634. {
  635. if ( m_ErrorObject.GetMessage () )
  636. {
  637. t_Variant.vt = VT_BSTR ;
  638. t_Variant.bstrVal = SysAllocString ( m_ErrorObject.GetMessage () ) ;
  639. t_Result = (*a_NotifyObject)->Put ( WBEM_PROPERTY_PROVSTATUSMESSAGE , 0 , &t_Variant , 0 ) ;
  640. VariantClear ( &t_Variant ) ;
  641. if ( ! SUCCEEDED ( t_Result ) )
  642. {
  643. t_Status = FALSE ;
  644. (*a_NotifyObject)->Release () ;
  645. (*a_NotifyObject)=NULL ;
  646. }
  647. }
  648. }
  649. else
  650. {
  651. (*a_NotifyObject)->Release () ;
  652. (*a_NotifyObject)=NULL ;
  653. t_Status = FALSE ;
  654. }
  655. VariantClear ( &t_Variant ) ;
  656. t_NotificationClassObject->Release () ;
  657. }
  658. else
  659. {
  660. t_Status = FALSE ;
  661. }
  662. }
  663. else
  664. {
  665. t_Status = FALSE ;
  666. }
  667. return t_Status ;
  668. }
  669. BOOL WbemTaskObject :: ParseAndProcessClassQualifiers(WbemProvErrorObject &a_ErrorObject,
  670. ParsedObjectPath *a_ParsedObjectPath,
  671. CMap<CStringW, LPCWSTR, int, int> *parentMap)
  672. {
  673. if (m_ClassObject == NULL)
  674. {
  675. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  676. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  677. a_ErrorObject.SetMessage ( L"Failed to get class object representing this class." ) ;
  678. return FALSE;
  679. }
  680. IWbemQualifierSet *pQuals = NULL;
  681. if ( FAILED(m_ClassObject->GetQualifierSet(&pQuals)) )
  682. {
  683. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  684. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  685. a_ErrorObject.SetMessage ( L"Failed to get qualifiers for this class." ) ;
  686. return FALSE;
  687. }
  688. VARIANT v;
  689. VariantInit(&v);
  690. BOOL bUnion = FALSE;
  691. BOOL retVal = TRUE;
  692. if (SUCCEEDED(pQuals->Get(VIEW_QUAL_PROVIDER, 0, &v, NULL)) )
  693. {
  694. if (v.vt == VT_BSTR)
  695. {
  696. m_ProviderName = v.bstrVal;
  697. }
  698. else
  699. {
  700. retVal = FALSE;
  701. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  702. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  703. a_ErrorObject.SetMessage ( L"Provider qualifier is incorrect for this class." ) ;
  704. }
  705. }
  706. else
  707. {
  708. retVal = FALSE;
  709. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  710. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  711. a_ErrorObject.SetMessage ( L"Provider qualifier should be present for this class." ) ;
  712. }
  713. VariantClear(&v);
  714. VariantInit(&v);
  715. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_FILTER, 0, &v, NULL)) )
  716. {
  717. if (v.vt == VT_BSTR)
  718. {
  719. CTextLexSource querySource(v.bstrVal);
  720. SQL1_Parser sqlParser(&querySource);
  721. if (SQL1_Parser::SUCCESS == sqlParser.Parse(&m_RPNPostFilter))
  722. {
  723. if (_wcsicmp(m_ClassName, m_RPNPostFilter->bsClassName) == 0)
  724. {
  725. if (m_RPNPostFilter->nNumberOfProperties != 0)
  726. {
  727. retVal = FALSE;
  728. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  729. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  730. a_ErrorObject.SetMessage ( L"PostJoinFilter qualifier may not limit the properties returned." ) ;
  731. }
  732. }
  733. else
  734. {
  735. retVal = FALSE;
  736. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  737. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  738. a_ErrorObject.SetMessage ( L"PostJoinFilter qualifier does not match this class." ) ;
  739. }
  740. }
  741. else
  742. {
  743. retVal = FALSE;
  744. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  745. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  746. a_ErrorObject.SetMessage ( L"Failed to parse PostJoinFilter qualifier." ) ;
  747. }
  748. }
  749. else
  750. {
  751. retVal = FALSE;
  752. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  753. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  754. a_ErrorObject.SetMessage ( L"PostJoinFilter qualifier should be a single WQL string." ) ;
  755. }
  756. }
  757. VariantClear(&v);
  758. VariantInit(&v);
  759. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_JOIN, 0, &v, NULL)) )
  760. {
  761. if (v.vt == VT_BSTR)
  762. {
  763. retVal = m_JoinOnArray.Set(v.bstrVal);
  764. if (!retVal)
  765. {
  766. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  767. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  768. a_ErrorObject.SetMessage ( L"Failed to parse JoinOn qualifier." ) ;
  769. }
  770. }
  771. else
  772. {
  773. retVal = FALSE;
  774. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  775. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  776. a_ErrorObject.SetMessage ( L"JoinOn qualifier should be a single string." ) ;
  777. }
  778. }
  779. VariantClear(&v);
  780. VariantInit(&v);
  781. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_UNION, 0, &v, NULL)) )
  782. {
  783. if (v.vt == VT_BOOL)
  784. {
  785. bUnion = (v.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  786. }
  787. else
  788. {
  789. retVal = FALSE;
  790. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  791. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  792. a_ErrorObject.SetMessage ( L"Union qualifier should be a boolean." ) ;
  793. }
  794. }
  795. VariantClear(&v);
  796. VariantInit(&v);
  797. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_ASSOC, 0, &v, NULL)) )
  798. {
  799. if (v.vt == VT_BOOL)
  800. {
  801. m_bAssoc = (v.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  802. }
  803. else
  804. {
  805. retVal = FALSE;
  806. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  807. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  808. a_ErrorObject.SetMessage ( L"Association qualifier should be a boolean." ) ;
  809. }
  810. }
  811. VariantClear(&v);
  812. VariantInit(&v);
  813. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_SNGLTN, 0, &v, NULL)) )
  814. {
  815. if (v.vt == VT_BOOL)
  816. {
  817. m_bSingleton = (v.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  818. }
  819. else
  820. {
  821. retVal = FALSE;
  822. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  823. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  824. a_ErrorObject.SetMessage ( L"Singleton qualifier should be a boolean." ) ;
  825. }
  826. }
  827. VariantClear(&v);
  828. VariantInit(&v);
  829. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_ENUM_CLASS, 0, &v, NULL)) )
  830. {
  831. if (v.vt == VT_BSTR)
  832. {
  833. m_EnumerateClasses.SetAt(v.bstrVal, 0);
  834. }
  835. else if (v.vt == (VT_BSTR | VT_ARRAY))
  836. {
  837. if (SafeArrayGetDim(v.parray) == 1)
  838. {
  839. LONG count = v.parray->rgsabound[0].cElements;
  840. BSTR HUGEP *pbstr;
  841. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pbstr)) )
  842. {
  843. for (LONG x = 0; x < count; x++)
  844. {
  845. m_EnumerateClasses.SetAt(pbstr[x], 0);
  846. }
  847. SafeArrayUnaccessData(v.parray);
  848. }
  849. else
  850. {
  851. retVal = FALSE;
  852. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  853. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  854. a_ErrorObject.SetMessage (L"Failed to access EnumerateClasses array.");
  855. }
  856. }
  857. else
  858. {
  859. retVal = FALSE;
  860. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  861. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  862. a_ErrorObject.SetMessage (L"EnumerateClasses array qualifier has incorrect dimensions.");
  863. }
  864. }
  865. else
  866. {
  867. retVal = FALSE;
  868. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  869. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  870. a_ErrorObject.SetMessage (L"EnumerateClasses qualifier should be an array of strings.");
  871. }
  872. }
  873. VariantClear(&v);
  874. VariantInit(&v);
  875. if (retVal &&
  876. ((bUnion && !m_bAssoc && !m_JoinOnArray.IsValid()) ||
  877. (!bUnion && m_bAssoc && !m_JoinOnArray.IsValid()) ||
  878. (!bUnion && !m_bAssoc && m_JoinOnArray.IsValid())))
  879. {
  880. if (m_JoinOnArray.IsValid())
  881. {
  882. if (!m_JoinOnArray.ValidateJoin())
  883. {
  884. retVal = FALSE;
  885. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  886. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  887. a_ErrorObject.SetMessage (L"Join validation failed");
  888. }
  889. }
  890. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_SOURCES, 0, &v, NULL)) )
  891. {
  892. if (v.vt == VT_BSTR)
  893. {
  894. CSourceQualifierItem* srcItem = new CSourceQualifierItem(v.bstrVal);
  895. if (srcItem->IsValid())
  896. {
  897. int indx = m_SourceArray.Add(srcItem);
  898. m_ClassToIndexMap.SetAt(srcItem->GetClassName(), indx);
  899. }
  900. else
  901. {
  902. retVal = FALSE;
  903. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  904. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  905. a_ErrorObject.SetMessage (L"Invalid source query.");
  906. delete srcItem;
  907. }
  908. }
  909. else if (v.vt == (VT_BSTR | VT_ARRAY))
  910. {
  911. if (SafeArrayGetDim(v.parray) == 1)
  912. {
  913. LONG count = v.parray->rgsabound[0].cElements;
  914. BSTR HUGEP *pbstr;
  915. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pbstr)) )
  916. {
  917. for (LONG x = 0; x < count; x++)
  918. {
  919. CSourceQualifierItem* srcItem = new CSourceQualifierItem(pbstr[x]);
  920. if (srcItem->IsValid())
  921. {
  922. int indx = m_SourceArray.Add(srcItem);
  923. m_ClassToIndexMap.SetAt(srcItem->GetClassName(), indx);
  924. }
  925. else
  926. {
  927. retVal = FALSE;
  928. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  929. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  930. a_ErrorObject.SetMessage (L"Invalid source query.");
  931. delete srcItem;
  932. break;
  933. }
  934. }
  935. SafeArrayUnaccessData(v.parray);
  936. }
  937. else
  938. {
  939. retVal = FALSE;
  940. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  941. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  942. a_ErrorObject.SetMessage (L"Invalid source array qualifier.");
  943. }
  944. }
  945. else
  946. {
  947. retVal = FALSE;
  948. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  949. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  950. a_ErrorObject.SetMessage (L"Invalid source array qualifier dimensions.");
  951. }
  952. }
  953. else
  954. {
  955. retVal = FALSE;
  956. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  957. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  958. a_ErrorObject.SetMessage (L"Invalid source array qualifier type.");
  959. }
  960. }
  961. else
  962. {
  963. if (retVal)
  964. {
  965. retVal = FALSE;
  966. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  967. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  968. a_ErrorObject.SetMessage (L"Source array qualifier not found.");
  969. }
  970. }
  971. VariantClear(&v);
  972. VariantInit(&v);
  973. if (retVal && SUCCEEDED(pQuals->Get(VIEW_QUAL_NAMESPACES, 0, &v, NULL)) )
  974. {
  975. if (v.vt == VT_BSTR)
  976. {
  977. CNSpaceQualifierItem* nsItem = new CNSpaceQualifierItem(v.bstrVal);
  978. if (nsItem->IsValid())
  979. {
  980. m_NSpaceArray.Add(nsItem);
  981. }
  982. else
  983. {
  984. retVal = FALSE;
  985. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  986. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  987. a_ErrorObject.SetMessage (L"Invalid Namespace in namespaces array.");
  988. delete nsItem;
  989. }
  990. }
  991. else if (v.vt == (VT_BSTR | VT_ARRAY))
  992. {
  993. if (SafeArrayGetDim(v.parray) == 1)
  994. {
  995. LONG count = v.parray->rgsabound[0].cElements;
  996. BSTR HUGEP *pbstr;
  997. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pbstr)) )
  998. {
  999. for (LONG x = 0; x < count; x++)
  1000. {
  1001. CNSpaceQualifierItem* nsItem = new CNSpaceQualifierItem(pbstr[x]);
  1002. if (nsItem->IsValid())
  1003. {
  1004. m_NSpaceArray.Add(nsItem);
  1005. }
  1006. else
  1007. {
  1008. retVal = FALSE;
  1009. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1010. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1011. a_ErrorObject.SetMessage (L"Invalid Namespace in namespaces array qualifier.");
  1012. delete nsItem;
  1013. break;
  1014. }
  1015. }
  1016. SafeArrayUnaccessData(v.parray);
  1017. }
  1018. else
  1019. {
  1020. retVal = FALSE;
  1021. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1022. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1023. a_ErrorObject.SetMessage (L"Failed to access Namespace array qualifier.");
  1024. }
  1025. }
  1026. else
  1027. {
  1028. retVal = FALSE;
  1029. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1030. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1031. a_ErrorObject.SetMessage (L"Namespace array qualifier has invalid dimensions.");
  1032. }
  1033. }
  1034. else
  1035. {
  1036. retVal = FALSE;
  1037. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1038. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1039. a_ErrorObject.SetMessage (L"Namespace array qualifier has invalid type.");
  1040. }
  1041. }
  1042. else
  1043. {
  1044. if (retVal)
  1045. {
  1046. retVal = FALSE;
  1047. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1048. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1049. a_ErrorObject.SetMessage (L"Namespace array qualifier not found.");
  1050. }
  1051. }
  1052. VariantClear(&v);
  1053. if (retVal && (m_NSpaceArray.GetSize() != m_SourceArray.GetSize()))
  1054. {
  1055. retVal = FALSE;
  1056. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1057. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1058. a_ErrorObject.SetMessage (L"Namespace array qualifier does not match source array qualifier size.");
  1059. }
  1060. if (retVal && m_bAssoc && m_SourceArray.GetSize() != 1)
  1061. {
  1062. if (retVal)
  1063. {
  1064. retVal = FALSE;
  1065. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1066. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1067. a_ErrorObject.SetMessage (L"Association views may only have a single source.");
  1068. }
  1069. }
  1070. }
  1071. else
  1072. {
  1073. if (retVal)
  1074. {
  1075. retVal = FALSE;
  1076. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1077. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1078. a_ErrorObject.SetMessage (L"ONE class qualifier out of \"JoinOn\", \"Union\" or \"Association\" MUST be specified.");
  1079. }
  1080. }
  1081. pQuals->Release();
  1082. //connect and get classes!
  1083. if (retVal)
  1084. {
  1085. IWbemClassObject*** arrayOfArrayOfObjs = new IWbemClassObject**[m_NSpaceArray.GetSize()];
  1086. for (int x = 0; x < m_NSpaceArray.GetSize(); x++)
  1087. {
  1088. UINT nsCount = m_NSpaceArray[x]->GetCount();
  1089. CWbemServerWrap** servArray = new CWbemServerWrap*[nsCount];
  1090. IWbemClassObject** classArray = new IWbemClassObject*[nsCount];
  1091. IWbemClassObject* classObj = NULL;
  1092. CStringW* pathArray = m_NSpaceArray[x]->GetNamespacePaths();
  1093. for (UINT i = 0; i < nsCount; i++)
  1094. {
  1095. classArray[i] = NULL;
  1096. if ( FAILED(Connect(pathArray[i], &(servArray[i]))) )
  1097. {
  1098. servArray[i] = NULL;
  1099. }
  1100. else if (servArray[i] != NULL)
  1101. {
  1102. if (GetClassObject(NULL, m_SourceArray[x]->GetClassName(), &classArray[i], &servArray[i])
  1103. && (classObj == NULL))
  1104. {
  1105. classObj = classArray[i];
  1106. }
  1107. }
  1108. }
  1109. if (NULL != classObj)
  1110. {
  1111. m_SourceArray[x]->SetClassObject(classObj);
  1112. }
  1113. arrayOfArrayOfObjs[x] = classArray;
  1114. m_NSpaceArray[x]->SetServerPtrs(servArray);
  1115. }
  1116. //check properties and keys
  1117. SAFEARRAY* pNames = NULL;
  1118. DWORD dwKeyCount = 0;
  1119. BOOL bKeysOK = TRUE;
  1120. if (retVal && SUCCEEDED(m_ClassObject->GetNames(NULL, WBEM_FLAG_NONSYSTEM_ONLY, NULL, &pNames)) )
  1121. {
  1122. if (SafeArrayGetDim(pNames) == 1)
  1123. {
  1124. LONG arraylen = pNames->rgsabound[0].cElements;
  1125. BSTR HUGEP *pbstr;
  1126. if ( SUCCEEDED(SafeArrayAccessData(pNames, (void HUGEP**)&pbstr)) )
  1127. {
  1128. for (LONG i = 0; retVal && (i < arraylen); i++)
  1129. {
  1130. IWbemQualifierSet* pPropQuals = NULL;
  1131. if ( SUCCEEDED(m_ClassObject->GetPropertyQualifierSet(pbstr[i], &pPropQuals)) )
  1132. {
  1133. BOOL bHidden = FALSE;
  1134. BOOL bKey = FALSE;
  1135. CIMTYPE ct = 0;
  1136. if ( SUCCEEDED(pPropQuals->Get(VIEW_QUAL_HIDDEN, 0, &v, NULL)) )
  1137. {
  1138. if (v.vt == VT_BOOL)
  1139. {
  1140. bHidden = (v.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  1141. }
  1142. else
  1143. {
  1144. retVal = FALSE;
  1145. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1146. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1147. a_ErrorObject.SetMessage (L"Hidden qualifier should be boolean.");
  1148. }
  1149. }
  1150. VariantInit(&v);
  1151. if ( SUCCEEDED(pPropQuals->Get(VIEW_QUAL_KEY, 0, &v, NULL)) )
  1152. {
  1153. if (v.vt == VT_BOOL)
  1154. {
  1155. if (v.boolVal == VARIANT_TRUE)
  1156. {
  1157. bKey = TRUE;
  1158. dwKeyCount++;
  1159. if (bKeysOK && (a_ParsedObjectPath != NULL))
  1160. {
  1161. bKeysOK = IsInObjectPath(a_ParsedObjectPath, pbstr[i]);
  1162. if ((!bKeysOK) && (dwKeyCount > 1))
  1163. {
  1164. retVal = FALSE;
  1165. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_PARAMETER);
  1166. a_ErrorObject.SetWbemStatus (WBEM_E_INVALID_OBJECT_PATH);
  1167. a_ErrorObject.SetMessage (L"Keys of class do not match those in the object path passed.");
  1168. }
  1169. }
  1170. }
  1171. else
  1172. {
  1173. bKey = FALSE;
  1174. }
  1175. }
  1176. else
  1177. {
  1178. retVal = FALSE;
  1179. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1180. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1181. a_ErrorObject.SetMessage (L"Key qualifier should be boolean.");
  1182. }
  1183. }
  1184. VariantClear(&v);
  1185. CStringW refStr;
  1186. BOOL bDirect = FALSE;
  1187. if ( SUCCEEDED(m_ClassObject->Get(pbstr[i], 0, NULL, &ct, NULL)) )
  1188. {
  1189. if (ct == CIM_REFERENCE)
  1190. {
  1191. VariantInit(&v);
  1192. if ( SUCCEEDED(pPropQuals->Get(VIEW_QUAL_TYPE, 0, &v, NULL)) )
  1193. {
  1194. if (v.vt == VT_BSTR)
  1195. {
  1196. //bstrVal is either "ref" OR ref:classname
  1197. wchar_t* tmp = v.bstrVal;
  1198. tmp += 4;
  1199. if (*tmp != '\0')
  1200. {
  1201. refStr = tmp;
  1202. }
  1203. VARIANT vDirect;
  1204. VariantInit(&vDirect);
  1205. if ( SUCCEEDED(pPropQuals->Get(VIEW_QUAL_DIRECT, 0, &vDirect, NULL)) )
  1206. {
  1207. if (vDirect.vt == VT_BOOL)
  1208. {
  1209. bDirect = (vDirect.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
  1210. }
  1211. else
  1212. {
  1213. retVal = FALSE;
  1214. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1215. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1216. a_ErrorObject.SetMessage (L"Direct qualifier should be boolean");
  1217. }
  1218. VariantClear(&vDirect);
  1219. }
  1220. }
  1221. else
  1222. {
  1223. retVal = FALSE;
  1224. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1225. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1226. a_ErrorObject.SetMessage (L"Cimtype qualifier should be a string");
  1227. }
  1228. VariantClear(&v);
  1229. }
  1230. else
  1231. {
  1232. retVal = FALSE;
  1233. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1234. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1235. a_ErrorObject.SetMessage (L"Failed to get the property type from the class definition");
  1236. }
  1237. }
  1238. }
  1239. else
  1240. {
  1241. retVal = FALSE;
  1242. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1243. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1244. a_ErrorObject.SetMessage (L"Failed to get a property type from the class definition");
  1245. }
  1246. VariantInit(&v);
  1247. if ( retVal && SUCCEEDED(pPropQuals->Get(VIEW_QUAL_PROPERTY, 0, &v, NULL)) )
  1248. {
  1249. CPropertyQualifierItem* propItem = new CPropertyQualifierItem(pbstr[i], bHidden, bKey, ct, refStr, bDirect);
  1250. if (v.vt == VT_BSTR)
  1251. {
  1252. if (1 != m_SourceArray.GetSize())
  1253. {
  1254. retVal = FALSE;
  1255. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1256. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1257. a_ErrorObject.SetMessage (L"Property sources qualifier array size does not match source list.");
  1258. }
  1259. else
  1260. {
  1261. CStringW t_propNameEntry(v.bstrVal);
  1262. t_propNameEntry.TrimLeft();
  1263. t_propNameEntry.TrimRight();
  1264. if (t_propNameEntry.IsEmpty())
  1265. {
  1266. retVal = FALSE;
  1267. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1268. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1269. a_ErrorObject.SetMessage (L"Property sources qualifier must name at least one source property.");
  1270. }
  1271. else
  1272. {
  1273. propItem->m_SrcPropertyNames.Add(t_propNameEntry);
  1274. }
  1275. }
  1276. }
  1277. else if (v.vt == (VT_BSTR | VT_ARRAY))
  1278. {
  1279. if (SafeArrayGetDim(v.parray) == 1)
  1280. {
  1281. LONG count = v.parray->rgsabound[0].cElements;
  1282. BSTR HUGEP *pPropbstr;
  1283. if (count != m_SourceArray.GetSize())
  1284. {
  1285. retVal = FALSE;
  1286. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1287. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1288. a_ErrorObject.SetMessage (L"Property sources qualifier array size does not match source list.");
  1289. }
  1290. else
  1291. {
  1292. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pPropbstr)) )
  1293. {
  1294. BOOL bNoName = TRUE;
  1295. for (LONG x = 0; retVal && (x < count); x++)
  1296. {
  1297. if ((pPropbstr[x] != NULL) && (*(pPropbstr[x]) != L'\0'))
  1298. {
  1299. IWbemClassObject* t_srcObj = m_SourceArray[x]->GetClassObject();
  1300. if (t_srcObj != NULL)
  1301. {
  1302. CIMTYPE src_ct;
  1303. if (SUCCEEDED(t_srcObj->Get(pPropbstr[x], 0, NULL, &src_ct, NULL)))
  1304. {
  1305. if (src_ct != ct)
  1306. {
  1307. retVal = FALSE;
  1308. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1309. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1310. a_ErrorObject.SetMessage (L"Source property type does not match view class.");
  1311. }
  1312. }
  1313. else
  1314. {
  1315. retVal = FALSE;
  1316. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1317. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1318. a_ErrorObject.SetMessage (L"Source property not found in source class.");
  1319. }
  1320. t_srcObj->Release();
  1321. }
  1322. }
  1323. CStringW t_propNameEntry(pPropbstr[x]);
  1324. t_propNameEntry.TrimLeft();
  1325. t_propNameEntry.TrimRight();
  1326. propItem->m_SrcPropertyNames.Add(t_propNameEntry);
  1327. if (bNoName && !t_propNameEntry.IsEmpty())
  1328. {
  1329. bNoName = FALSE;
  1330. }
  1331. }
  1332. if (bNoName)
  1333. {
  1334. retVal = FALSE;
  1335. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1336. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1337. a_ErrorObject.SetMessage (L"Property sources qualifier must name at least one source property.");
  1338. }
  1339. SafeArrayUnaccessData(v.parray);
  1340. }
  1341. else
  1342. {
  1343. retVal = FALSE;
  1344. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1345. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1346. a_ErrorObject.SetMessage (L"Property sources qualifier array has incorrect dimensions.");
  1347. }
  1348. }
  1349. }
  1350. else
  1351. {
  1352. retVal = FALSE;
  1353. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1354. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1355. a_ErrorObject.SetMessage (L"Failed to access property sources array qualifier.");
  1356. }
  1357. }
  1358. else
  1359. {
  1360. retVal = FALSE;
  1361. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1362. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1363. a_ErrorObject.SetMessage (L"Property sources qualifier has incorrect type.");
  1364. }
  1365. VariantClear(&v);
  1366. m_PropertyMap.SetAt(pbstr[i], propItem);
  1367. }
  1368. else
  1369. {
  1370. if (retVal)
  1371. {
  1372. retVal = FALSE;
  1373. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1374. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1375. a_ErrorObject.SetMessage (L"Failed to get property sources qualifier.");
  1376. }
  1377. }
  1378. pPropQuals->Release();
  1379. }
  1380. else
  1381. {
  1382. retVal = FALSE;
  1383. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1384. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1385. a_ErrorObject.SetMessage (L"Failed to access property qualifiers.");
  1386. }
  1387. }
  1388. SafeArrayUnaccessData(pNames);
  1389. }
  1390. else
  1391. {
  1392. retVal = FALSE;
  1393. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1394. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1395. a_ErrorObject.SetMessage (L"Could not access class property names array.");
  1396. }
  1397. }
  1398. else
  1399. {
  1400. retVal = FALSE;
  1401. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1402. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1403. a_ErrorObject.SetMessage (L"Class property names array has invalid dimensions.");
  1404. }
  1405. SafeArrayDestroy(pNames);
  1406. }
  1407. else
  1408. {
  1409. if (retVal)
  1410. {
  1411. retVal = FALSE;
  1412. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1413. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1414. a_ErrorObject.SetMessage (L"Failed to get class property names.");
  1415. }
  1416. }
  1417. if (retVal)
  1418. {
  1419. if (a_ParsedObjectPath != NULL)
  1420. {
  1421. if (bKeysOK)
  1422. {
  1423. if (dwKeyCount != a_ParsedObjectPath->m_dwNumKeys)
  1424. {
  1425. retVal = FALSE;
  1426. }
  1427. }
  1428. else
  1429. {
  1430. if ((dwKeyCount != 1) || (a_ParsedObjectPath->m_dwNumKeys != 1) || (a_ParsedObjectPath->m_paKeys[0]->m_pName != NULL))
  1431. {
  1432. retVal = FALSE;
  1433. }
  1434. }
  1435. if (!retVal)
  1436. {
  1437. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_PARAMETER);
  1438. a_ErrorObject.SetWbemStatus (WBEM_E_INVALID_OBJECT_PATH);
  1439. a_ErrorObject.SetMessage (L"Keys of class do not match those in the object path passed.");
  1440. }
  1441. }
  1442. }
  1443. //final verifications
  1444. //===================
  1445. if (retVal)
  1446. {
  1447. //make sure all enumeration classes exist
  1448. POSITION pos = m_EnumerateClasses.GetStartPosition();
  1449. while (pos)
  1450. {
  1451. int val;
  1452. CStringW tmpStr;
  1453. m_EnumerateClasses.GetNextAssoc(pos, tmpStr, val);
  1454. if (!m_ClassToIndexMap.Lookup(tmpStr, val))
  1455. {
  1456. retVal = FALSE;
  1457. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1458. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1459. a_ErrorObject.SetMessage (L"EnumerateClasses qualifier contains an entry not found in the source list.");
  1460. break;
  1461. }
  1462. }
  1463. }
  1464. if (retVal)
  1465. {
  1466. if (m_EnumerateClasses.GetCount() == m_SourceArray.GetSize())
  1467. {
  1468. //pointless qualifier if all classes mentioned
  1469. m_EnumerateClasses.RemoveAll();
  1470. }
  1471. if (m_JoinOnArray.IsValid())
  1472. {
  1473. if (!ValidateJoin())
  1474. {
  1475. retVal = FALSE;
  1476. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1477. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1478. a_ErrorObject.SetMessage (L"JoinOn qualifier is semantically invalid.");
  1479. }
  1480. }
  1481. #if 0
  1482. else
  1483. {
  1484. //check all union and assoc source keys are view
  1485. //keys this is done in ValidateClassDependencies
  1486. //since both checks need to loop through the arrays
  1487. //of class objects
  1488. }
  1489. #endif
  1490. }
  1491. //must delete each sub-array in ValidateClassDependencies
  1492. //as well as release all the ClassObjects!!
  1493. if (retVal)
  1494. {
  1495. if (!ValidateClassDependencies(arrayOfArrayOfObjs, parentMap))
  1496. {
  1497. retVal = FALSE;
  1498. a_ErrorObject.SetStatus (WBEM_PROV_E_INVALID_CLASS);
  1499. a_ErrorObject.SetWbemStatus (WBEM_E_FAILED);
  1500. if (m_JoinOnArray.IsValid())
  1501. {
  1502. a_ErrorObject.SetMessage (L"Loop in provided classes detected.");
  1503. }
  1504. else
  1505. {
  1506. a_ErrorObject.SetMessage (L"Loop in provided classes detected or key mismatch between view and source class.");
  1507. }
  1508. }
  1509. }
  1510. else
  1511. {
  1512. for (int x = 0; x < m_NSpaceArray.GetSize(); x++)
  1513. {
  1514. UINT nsCount = m_NSpaceArray[x]->GetCount();
  1515. for (UINT i = 0; i < nsCount; i++)
  1516. {
  1517. if (arrayOfArrayOfObjs[x][i] != NULL)
  1518. {
  1519. arrayOfArrayOfObjs[x][i]->Release();
  1520. }
  1521. }
  1522. delete [] arrayOfArrayOfObjs[x];
  1523. }
  1524. }
  1525. delete [] arrayOfArrayOfObjs;
  1526. }
  1527. return retVal;
  1528. }
  1529. //takes an object path to a view class and translates it
  1530. //to the object path of the source instance requested and optionally
  1531. //returns the object.
  1532. BSTR WbemTaskObject::MapFromView(BSTR path, const wchar_t* src, IWbemClassObject** pInst, BOOL bAllprops)
  1533. {
  1534. BSTR retVal = NULL;
  1535. if (path == NULL)
  1536. {
  1537. return retVal;
  1538. }
  1539. CObjectPathParser objectPathParser;
  1540. wchar_t* objPath = UnicodeStringDuplicate(path);
  1541. ParsedObjectPath *parsedObjectPath = NULL;
  1542. if (objectPathParser.Parse(objPath, &parsedObjectPath) == 0)
  1543. {
  1544. wchar_t* tmp = parsedObjectPath->GetNamespacePart();
  1545. CWbemServerWrap *pServ = NULL;
  1546. if (tmp != NULL)
  1547. {
  1548. BOOL bServOK = TRUE;
  1549. if (parsedObjectPath->m_pServer != NULL)
  1550. {
  1551. if (wcscmp(parsedObjectPath->m_pServer, L".") != 0)
  1552. {
  1553. bServOK = FALSE;
  1554. VARIANT v;
  1555. if ( SUCCEEDED(m_ClassObject->Get(WBEM_PROPERTY_SERVER, 0, &v, NULL, NULL)))
  1556. {
  1557. if ((v.vt == VT_BSTR) && (_wcsicmp(v.bstrVal, parsedObjectPath->m_pServer) == 0))
  1558. {
  1559. bServOK = TRUE;
  1560. }
  1561. }
  1562. VariantClear(&v);
  1563. }
  1564. }
  1565. if (bServOK)
  1566. {
  1567. wchar_t* tmppath = m_Provider->GetNamespacePath()->GetNamespacePath();
  1568. if (tmppath != NULL)
  1569. {
  1570. if (_wcsicmp(tmppath, tmp) == 0)
  1571. {
  1572. Connect(tmppath, &pServ);
  1573. }
  1574. delete [] tmppath;
  1575. }
  1576. }
  1577. delete [] tmp;
  1578. }
  1579. else
  1580. {
  1581. wchar_t* tmppath = m_Provider->GetNamespacePath()->GetNamespacePath();
  1582. if (tmppath != NULL)
  1583. {
  1584. Connect(tmppath, &pServ);
  1585. delete [] tmppath;
  1586. }
  1587. }
  1588. if (pServ != NULL)
  1589. {
  1590. GetObjectTaskObject *t_AsyncEvent = new GetObjectTaskObject (m_Provider,
  1591. path, 0, m_NotificationHandler, m_Ctx,
  1592. NULL, pServ);
  1593. IWbemClassObject* pInstObj = NULL;
  1594. if (t_AsyncEvent->GetSourceObject(src, &pInstObj, bAllprops) && pInstObj != NULL)
  1595. {
  1596. VARIANT v;
  1597. if (SUCCEEDED(pInstObj->Get(WBEM_PROPERTY_PATH, 0, &v, NULL, NULL)) )
  1598. {
  1599. if (v.vt == VT_BSTR)
  1600. {
  1601. retVal = SysAllocString(v.bstrVal);
  1602. if (pInst != NULL)
  1603. {
  1604. pInstObj->AddRef();
  1605. *pInst = pInstObj;
  1606. }
  1607. }
  1608. }
  1609. VariantClear(&v);
  1610. pInstObj->Release();
  1611. }
  1612. t_AsyncEvent->Release();
  1613. pServ->Release();
  1614. }
  1615. }
  1616. delete [] objPath;
  1617. if (parsedObjectPath != NULL)
  1618. {
  1619. delete parsedObjectPath;
  1620. }
  1621. return retVal;
  1622. }
  1623. //takes an object path to a source and translates it
  1624. //to the object path of the view instance requested.
  1625. BSTR WbemTaskObject::MapToView(BSTR path, const wchar_t* src, CWbemServerWrap **a_ns)
  1626. {
  1627. BSTR retVal = NULL;
  1628. wchar_t* tmppath = m_Provider->GetNamespacePath()->GetNamespacePath();
  1629. CWbemServerWrap *pServ = NULL;
  1630. if (tmppath != NULL)
  1631. {
  1632. Connect(tmppath, &pServ);
  1633. delete [] tmppath;
  1634. }
  1635. if (pServ != NULL)
  1636. {
  1637. BSTR queryLBStr = SysAllocString(WBEM_QUERY_LANGUAGE_SQL1);
  1638. if (queryLBStr == NULL)
  1639. {
  1640. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1641. }
  1642. BSTR queryBStr = SysAllocStringLen(NULL, 45 + wcslen(src));
  1643. if (queryBStr == NULL)
  1644. {
  1645. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1646. }
  1647. wcscpy(queryBStr, META_CLASS_QUERY_START);
  1648. wcscat(queryBStr, src);
  1649. wcscat(queryBStr, END_QUOTE);
  1650. IWbemContext * t_pCtx = m_Ctx;
  1651. if (pServ->IsRemote())
  1652. {
  1653. t_pCtx = NULL; //don't use context for remote calls
  1654. }
  1655. IWbemServices *ptmpServ = pServ->GetServerOrProxy();
  1656. if (ptmpServ)
  1657. {
  1658. IEnumWbemClassObject *t_pEnum = NULL;
  1659. HRESULT t_hr = ptmpServ->ExecQuery(queryLBStr, queryBStr, 0, t_pCtx, &t_pEnum);
  1660. if ( FAILED(t_hr) && (HRESULT_FACILITY(t_hr) != FACILITY_ITF) && pServ->IsRemote())
  1661. {
  1662. if ( SUCCEEDED(UpdateConnection(&pServ, &ptmpServ)) )
  1663. {
  1664. if (ptmpServ)
  1665. {
  1666. t_hr = ptmpServ->ExecQuery(queryLBStr, queryBStr, 0, t_pCtx, &t_pEnum);
  1667. }
  1668. }
  1669. }
  1670. if (ptmpServ)
  1671. {
  1672. pServ->ReturnServerOrProxy(ptmpServ);
  1673. }
  1674. if (SUCCEEDED(t_hr))
  1675. {
  1676. if (pServ->IsRemote())
  1677. {
  1678. t_hr = SetSecurityLevelAndCloaking(t_pEnum, pServ->GetPrincipal());
  1679. }
  1680. if (SUCCEEDED(t_hr))
  1681. {
  1682. //now use the enumerator and see if there is a result...
  1683. ULONG t_count = 0;
  1684. IWbemClassObject* t_pClsObj = NULL;
  1685. BOOL t_bContinueEnum = TRUE;
  1686. //test each class in the derivation chain...
  1687. while (t_bContinueEnum && (S_OK == t_pEnum->Next(WBEM_INFINITE, 1, &t_pClsObj, &t_count)) )
  1688. {
  1689. if (t_pClsObj)
  1690. {
  1691. //get the class name and use the helper object...
  1692. VARIANT vCls;
  1693. VariantInit(&vCls);
  1694. if ( SUCCEEDED(t_pClsObj->Get(WBEM_PROPERTY_CLASS, 0, &vCls, NULL, NULL)) )
  1695. {
  1696. if (vCls.vt == VT_BSTR)
  1697. {
  1698. //do this for src and all classes derived from src...
  1699. //====================================================
  1700. HelperTaskObject* validationObj = new HelperTaskObject(m_Provider,
  1701. vCls.bstrVal,
  1702. 0,
  1703. m_NotificationHandler,
  1704. m_Ctx,
  1705. NULL,
  1706. NULL,
  1707. pServ);
  1708. IWbemClassObject* pInst = NULL;
  1709. try
  1710. {
  1711. if (validationObj->GetViewObject(path, &pInst, a_ns))
  1712. {
  1713. VARIANT v;
  1714. if (SUCCEEDED(pInst->Get(WBEM_PROPERTY_PATH, 0, &v, NULL, NULL)) )
  1715. {
  1716. if (v.vt == VT_BSTR)
  1717. {
  1718. if (retVal == NULL)
  1719. {
  1720. retVal = SysAllocString(v.bstrVal);
  1721. }
  1722. else
  1723. {
  1724. //make sure they are the
  1725. //same object else fail
  1726. //TO DO: Use the most derived instance
  1727. //too expensive for little gain since
  1728. //traversal will still get correct instance
  1729. //==========================================
  1730. if (!CompareInstPaths(retVal, v.bstrVal))
  1731. {
  1732. SysFreeString(retVal);
  1733. retVal = NULL;
  1734. //ambiguous results, quit!
  1735. t_bContinueEnum = FALSE;
  1736. }
  1737. }
  1738. }
  1739. }
  1740. VariantClear(&v);
  1741. pInst->Release();
  1742. }
  1743. }
  1744. catch (...)
  1745. {
  1746. validationObj->Release();
  1747. VariantClear(&vCls);
  1748. t_pClsObj->Release();
  1749. t_pEnum->Release();
  1750. pServ->Release();
  1751. SysFreeString(queryLBStr);
  1752. SysFreeString(queryBStr);
  1753. throw;
  1754. }
  1755. validationObj->Release();
  1756. }
  1757. VariantClear(&vCls);
  1758. }
  1759. t_pClsObj->Release();
  1760. t_pClsObj = NULL;
  1761. }
  1762. t_count = 0;
  1763. }
  1764. }
  1765. t_pEnum->Release();
  1766. }
  1767. }
  1768. SysFreeString(queryLBStr);
  1769. SysFreeString(queryBStr);
  1770. if (pServ)
  1771. {
  1772. pServ->Release();
  1773. }
  1774. }
  1775. return retVal;
  1776. }
  1777. //takes a reference and maps to the "real world" or to a view
  1778. //------------------------------------------------------------
  1779. BOOL WbemTaskObject::TransposeReference(CPropertyQualifierItem* pItm,
  1780. VARIANT vSrc, VARIANT* pvDst,
  1781. BOOL bMapToView, CWbemServerWrap **a_ns)
  1782. {
  1783. //make sure reference normalisation/non-normalisation is OK.
  1784. //Done the best I can.....
  1785. //==========================================================
  1786. if (pvDst != NULL)
  1787. {
  1788. VariantInit(pvDst);
  1789. }
  1790. else
  1791. {
  1792. return FALSE;
  1793. }
  1794. if (vSrc.vt != VT_BSTR)
  1795. {
  1796. return FALSE;
  1797. }
  1798. BOOL retVal = FALSE;
  1799. //associations are the only classes that this
  1800. //method gets called for, therefore, only a
  1801. //single source class to interrogate!
  1802. //=============================================
  1803. IWbemClassObject* pCls = m_SourceArray[0]->GetClassObject();
  1804. if (pCls != NULL)
  1805. {
  1806. CIMTYPE ct;
  1807. //associations are the only classes that this
  1808. //method gets called for, therefore, only a
  1809. //single source class to interrogate!
  1810. //=============================================
  1811. BSTR strClass = pItm->m_SrcPropertyNames[0].AllocSysString();
  1812. if ( SUCCEEDED(pCls->Get(strClass, 0, NULL, &ct, NULL)) )
  1813. {
  1814. if (ct == CIM_REFERENCE)
  1815. {
  1816. IWbemQualifierSet* pQuals = NULL;
  1817. if ( SUCCEEDED(pCls->GetPropertyQualifierSet(strClass, &pQuals)) )
  1818. {
  1819. VARIANT v;
  1820. if ( SUCCEEDED(pQuals->Get(VIEW_QUAL_TYPE, 0, &v, NULL)) )
  1821. {
  1822. if (v.vt == VT_BSTR)
  1823. {
  1824. //bstrVal is either "ref" OR ref:classname
  1825. wchar_t* tmp = v.bstrVal;
  1826. tmp += 4;
  1827. if (*tmp != '\0')
  1828. {
  1829. if (!pItm->GetReferenceClass().IsEmpty())
  1830. {
  1831. if (pItm->IsDirect())
  1832. {
  1833. if (FAILED(VariantCopy(pvDst, &vSrc)))
  1834. {
  1835. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1836. }
  1837. retVal = TRUE;
  1838. }
  1839. else
  1840. {
  1841. if (bMapToView)
  1842. {
  1843. BSTR refStr = MapToView(vSrc.bstrVal, pItm->GetReferenceClass(), a_ns);
  1844. if (refStr != NULL)
  1845. {
  1846. pvDst->vt = VT_BSTR;
  1847. pvDst->bstrVal = refStr;
  1848. retVal = TRUE;
  1849. }
  1850. }
  1851. else
  1852. {
  1853. //map reference back to source class
  1854. BSTR refStr = MapFromView(vSrc.bstrVal, tmp);
  1855. if (refStr != NULL)
  1856. {
  1857. pvDst->vt = VT_BSTR;
  1858. pvDst->bstrVal = refStr;
  1859. retVal = TRUE;
  1860. }
  1861. }
  1862. }
  1863. }
  1864. }
  1865. else
  1866. {
  1867. if (pItm->GetReferenceClass().IsEmpty())
  1868. {
  1869. if (FAILED(VariantCopy(pvDst, &vSrc)))
  1870. {
  1871. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  1872. }
  1873. retVal = TRUE;
  1874. }
  1875. }
  1876. }
  1877. VariantClear(&v);
  1878. }
  1879. pQuals->Release();
  1880. }
  1881. }
  1882. }
  1883. SysFreeString(strClass);
  1884. pCls->Release();
  1885. }
  1886. return retVal;
  1887. }
  1888. //Must release all ClassObjects and free all sub-arrays
  1889. //=====================================================
  1890. BOOL WbemTaskObject::ValidateClassDependencies(IWbemClassObject*** arrayofArrayOfObjs, CMap<CStringW, LPCWSTR, int, int>* parentMap)
  1891. {
  1892. CMap<CStringW, LPCWSTR, int, int> namespaceClassMap;
  1893. if (parentMap != NULL)
  1894. {
  1895. POSITION pos = parentMap->GetStartPosition();
  1896. while (pos)
  1897. {
  1898. CStringW tmpStr;
  1899. int tmpInt;
  1900. parentMap->GetNextAssoc(pos, tmpStr, tmpInt);
  1901. namespaceClassMap.SetAt(tmpStr, tmpInt);
  1902. }
  1903. }
  1904. BOOL retVal = TRUE;
  1905. VARIANT v;
  1906. VariantInit(&v);
  1907. if (SUCCEEDED(m_ClassObject->Get(WBEM_PROPERTY_PATH, 0, &v, NULL, NULL)) )
  1908. {
  1909. if (v.vt != VT_BSTR)
  1910. {
  1911. retVal = FALSE;
  1912. }
  1913. else
  1914. {
  1915. int dummyInt;
  1916. if (namespaceClassMap.Lookup(v.bstrVal, dummyInt))
  1917. {
  1918. retVal = FALSE;
  1919. }
  1920. else
  1921. {
  1922. namespaceClassMap.SetAt(v.bstrVal, 0);
  1923. }
  1924. }
  1925. }
  1926. else
  1927. {
  1928. retVal = FALSE;
  1929. }
  1930. VariantClear(&v);
  1931. for (int x = 0; x < m_NSpaceArray.GetSize(); x++)
  1932. {
  1933. UINT nsCount = m_NSpaceArray[x]->GetCount();
  1934. for (UINT i = 0; i < nsCount; i++)
  1935. {
  1936. if (arrayofArrayOfObjs[x][i] != NULL)
  1937. {
  1938. IWbemQualifierSet* pQuals = NULL;
  1939. if (retVal && SUCCEEDED(arrayofArrayOfObjs[x][i]->GetQualifierSet(&pQuals)) )
  1940. {
  1941. VariantInit(&v);
  1942. if (SUCCEEDED(pQuals->Get(VIEW_QUAL_PROVIDER, 0, &v, NULL)) )
  1943. {
  1944. if (v.vt == VT_BSTR)
  1945. {
  1946. if (m_ProviderName.CompareNoCase(v.bstrVal) == 0)
  1947. {
  1948. VariantClear(&v);
  1949. VariantInit(&v);
  1950. if ( SUCCEEDED(arrayofArrayOfObjs[x][i]->Get(WBEM_PROPERTY_PATH, 0, &v, NULL, NULL)) )
  1951. {
  1952. if (v.vt == VT_BSTR)
  1953. {
  1954. HelperTaskObject* validationObj = new HelperTaskObject(m_Provider,
  1955. v.bstrVal, 0, m_NotificationHandler, m_Ctx,
  1956. NULL,
  1957. m_NSpaceArray[x]->GetServerPtrs()[i]->GetPrincipal(),
  1958. m_NSpaceArray[x]->GetServerPtrs()[i]);
  1959. try
  1960. {
  1961. retVal = validationObj->Validate(&namespaceClassMap);
  1962. }
  1963. catch (...)
  1964. {
  1965. validationObj->Release();
  1966. throw;
  1967. }
  1968. validationObj->Release();
  1969. }
  1970. else
  1971. {
  1972. retVal = FALSE;
  1973. }
  1974. }
  1975. else
  1976. {
  1977. retVal = FALSE;
  1978. }
  1979. VariantClear(&v);
  1980. }
  1981. }
  1982. else
  1983. {
  1984. retVal = FALSE;
  1985. }
  1986. }
  1987. VariantClear(&v);
  1988. pQuals->Release();
  1989. }
  1990. else
  1991. {
  1992. retVal = FALSE;
  1993. }
  1994. //Check union, assoc key properties here
  1995. SAFEARRAY* pNames = NULL;
  1996. if (retVal && !m_JoinOnArray.IsValid())
  1997. {
  1998. if ( SUCCEEDED(arrayofArrayOfObjs[x][i]->GetNames(NULL, WBEM_FLAG_KEYS_ONLY, NULL, &pNames)) )
  1999. {
  2000. if (SafeArrayGetDim(pNames) == 1)
  2001. {
  2002. LONG arraylen = pNames->rgsabound[0].cElements;
  2003. BSTR HUGEP *pbstr;
  2004. if ( SUCCEEDED(SafeArrayAccessData(pNames, (void HUGEP**)&pbstr)) )
  2005. {
  2006. for (LONG i = 0; retVal && (i < arraylen); i++)
  2007. {
  2008. //find pbstr[i] as a key in the view class
  2009. //as the xth property name ('cos we're checking the
  2010. //xth source class) in the property arrays
  2011. //of m_PropertyMap...
  2012. retVal = FALSE;
  2013. POSITION pos = m_PropertyMap.GetStartPosition();
  2014. while (pos)
  2015. {
  2016. CPropertyQualifierItem* pItm;
  2017. CStringW itmName;
  2018. m_PropertyMap.GetNextAssoc(pos, itmName, pItm);
  2019. if (pItm->IsKey() && (_wcsicmp(pbstr[i], pItm->m_SrcPropertyNames[x]) == 0) )
  2020. {
  2021. retVal = TRUE;
  2022. break;
  2023. }
  2024. }
  2025. }
  2026. SafeArrayUnaccessData(pNames);
  2027. }
  2028. else
  2029. {
  2030. retVal = FALSE;
  2031. }
  2032. }
  2033. else
  2034. {
  2035. retVal = FALSE;
  2036. }
  2037. SafeArrayDestroy(pNames);
  2038. }
  2039. else
  2040. {
  2041. retVal = FALSE;
  2042. }
  2043. }
  2044. arrayofArrayOfObjs[x][i]->Release();
  2045. }
  2046. }
  2047. delete [] arrayofArrayOfObjs[x];
  2048. }
  2049. namespaceClassMap.RemoveAll();
  2050. return retVal;
  2051. }
  2052. LONG WbemTaskObject::AddRef()
  2053. {
  2054. return InterlockedIncrement(&m_Ref);
  2055. }
  2056. LONG WbemTaskObject::Release()
  2057. {
  2058. LONG t_Ref;
  2059. if ( (t_Ref = InterlockedDecrement(&m_Ref)) == 0 )
  2060. {
  2061. delete this ;
  2062. return 0 ;
  2063. }
  2064. else
  2065. {
  2066. return t_Ref ;
  2067. }
  2068. }
  2069. HRESULT WbemTaskObject :: UpdateConnection(CWbemServerWrap **a_pServ, IWbemServices **a_proxy)
  2070. {
  2071. HRESULT retVal = WBEM_NO_ERROR;
  2072. #ifdef UNICODE
  2073. if ((*a_pServ)->IsRemote())
  2074. {
  2075. if ((*a_pServ)->ProxyBelongsTo(*a_proxy))
  2076. {
  2077. retVal = Connect((*a_pServ)->GetPath(), a_pServ, TRUE);
  2078. }
  2079. (*a_proxy)->Release();
  2080. if ( SUCCEEDED(retVal) && (*a_pServ) )
  2081. {
  2082. *a_proxy = (*a_pServ)->GetServerOrProxy();
  2083. }
  2084. else
  2085. {
  2086. *a_proxy = NULL;
  2087. }
  2088. }
  2089. #endif
  2090. return retVal;
  2091. }
  2092. HRESULT WbemTaskObject :: Connect(const wchar_t* path, CWbemServerWrap** ppServ, BOOL a_bUpdate)
  2093. {
  2094. //this function must lock the critsec and unlock it in a balnaced way
  2095. //and must also not be locked when calling back into CIMOM...
  2096. if (ppServ == NULL)
  2097. {
  2098. return WBEM_E_INVALID_PARAMETER;
  2099. }
  2100. else
  2101. {
  2102. if (!a_bUpdate)
  2103. {
  2104. *ppServ = NULL;
  2105. }
  2106. }
  2107. if ((m_Provider->sm_ConnectionMade == NULL) || !m_Provider->sm_ServerMap.Lock())
  2108. {
  2109. return WBEM_E_UNEXPECTED;
  2110. }
  2111. //possibility of deadlock if ObjectsInProgress == 0 at this point!
  2112. //therefore Connect should never be called by an object which hasn't
  2113. //previously incremented ObjectsInProgress!!!
  2114. BOOL bFound = FALSE;
  2115. if (!a_bUpdate && !m_Provider->sm_ServerMap.IsEmpty() &&
  2116. m_Provider->sm_ServerMap.Lookup(path, *ppServ) )
  2117. {
  2118. (*ppServ)->AddRef();
  2119. bFound = TRUE;
  2120. }
  2121. HRESULT hr = WBEM_NO_ERROR;
  2122. if (!bFound)
  2123. {
  2124. //check the map of outstanding connections...
  2125. int dummyInt = 0;
  2126. if (!m_Provider->sm_OutStandingConnections.IsEmpty() &&
  2127. m_Provider->sm_OutStandingConnections.Lookup(path, dummyInt) )
  2128. {
  2129. bFound = TRUE;
  2130. }
  2131. else
  2132. {
  2133. m_Provider->sm_OutStandingConnections[path] = 0;
  2134. }
  2135. m_Provider->sm_ServerMap.Unlock();
  2136. BOOL t_bWait = TRUE;
  2137. while (bFound && t_bWait)
  2138. {
  2139. DWORD dwWait = WbemWaitForSingleObject(m_Provider->sm_ConnectionMade, VP_CONNECTION_TIMEOUT);
  2140. if (dwWait == WAIT_OBJECT_0)
  2141. {
  2142. if (m_Provider->sm_ServerMap.Lock())
  2143. {
  2144. if (!m_Provider->sm_OutStandingConnections.IsEmpty() &&
  2145. m_Provider->sm_OutStandingConnections.Lookup(path, dummyInt) )
  2146. {
  2147. ResetEvent(m_Provider->sm_ConnectionMade);
  2148. }
  2149. else
  2150. {
  2151. //no longer outstanding!
  2152. t_bWait = FALSE;;
  2153. }
  2154. m_Provider->sm_ServerMap.Unlock();
  2155. }
  2156. else
  2157. {
  2158. //error
  2159. hr = WBEM_E_FAILED;
  2160. bFound = FALSE;
  2161. }
  2162. }
  2163. else
  2164. {
  2165. //error
  2166. hr = WBEM_E_FAILED;
  2167. bFound = FALSE;
  2168. }
  2169. }
  2170. if (SUCCEEDED (hr))
  2171. {
  2172. if (bFound)
  2173. {
  2174. if (a_bUpdate)
  2175. {
  2176. //another thread did the update on this clear this pointer
  2177. //chances is are it is the same one and use the one in the map
  2178. (*ppServ)->Release();
  2179. *ppServ = NULL;
  2180. }
  2181. if (m_Provider->sm_ServerMap.Lock())
  2182. {
  2183. if ( !m_Provider->sm_ServerMap.IsEmpty() &&
  2184. m_Provider->sm_ServerMap.Lookup(path, *ppServ) )
  2185. {
  2186. (*ppServ)->AddRef();
  2187. }
  2188. else
  2189. {
  2190. //it just failed in another thread
  2191. //don't try it again this time....
  2192. hr = WBEM_E_FAILED;
  2193. }
  2194. m_Provider->sm_ServerMap.Unlock();
  2195. }
  2196. else
  2197. {
  2198. hr = WBEM_E_FAILED;
  2199. }
  2200. }
  2201. else
  2202. {
  2203. BSTR bstrPath = SysAllocString(path);
  2204. //calling back into winmgmt cannot have a lock...
  2205. hr = DoConnectServer(bstrPath, ppServ, a_bUpdate);
  2206. SysFreeString(bstrPath);
  2207. if (FAILED(hr))
  2208. {
  2209. if (a_bUpdate)
  2210. {
  2211. //we failed to update, remove the item from the map
  2212. if (m_Provider->sm_ServerMap.Lock())
  2213. {
  2214. m_Provider->sm_ServerMap.RemoveKey(path);
  2215. m_Provider->sm_ServerMap.Unlock();
  2216. }
  2217. (*ppServ)->Release();
  2218. }
  2219. *ppServ = NULL;
  2220. }
  2221. else
  2222. {
  2223. if (m_Provider->sm_ServerMap.Lock())
  2224. {
  2225. if (!a_bUpdate)
  2226. {
  2227. (*ppServ)->AddRef();
  2228. m_Provider->sm_ServerMap[path] = *ppServ;
  2229. }
  2230. else
  2231. {
  2232. //has the object been removed in another thread
  2233. CWbemServerWrap *t_pSrvInMap = NULL;
  2234. if (m_Provider->sm_ServerMap.IsEmpty() ||
  2235. !m_Provider->sm_ServerMap.Lookup(path, t_pSrvInMap))
  2236. {
  2237. (*ppServ)->AddRef();
  2238. m_Provider->sm_ServerMap[path] = *ppServ;
  2239. }
  2240. }
  2241. m_Provider->sm_ServerMap.Unlock();
  2242. }
  2243. else
  2244. {
  2245. (*ppServ)->Release();
  2246. *ppServ = NULL;
  2247. hr = WBEM_E_FAILED;
  2248. }
  2249. }
  2250. if (m_Provider->sm_ServerMap.Lock())
  2251. {
  2252. m_Provider->sm_OutStandingConnections.RemoveKey(path);
  2253. SetEvent(m_Provider->sm_ConnectionMade);
  2254. m_Provider->sm_ServerMap.Unlock();
  2255. }
  2256. }
  2257. }
  2258. else
  2259. {
  2260. if (a_bUpdate)
  2261. {
  2262. //we failed to update, remove the item from the map
  2263. if (m_Provider->sm_ServerMap.Lock())
  2264. {
  2265. m_Provider->sm_ServerMap.RemoveKey(path);
  2266. m_Provider->sm_ServerMap.Unlock();
  2267. }
  2268. (*ppServ)->Release();
  2269. *ppServ = NULL;
  2270. }
  2271. }
  2272. }
  2273. else
  2274. {
  2275. m_Provider->sm_ServerMap.Unlock();
  2276. }
  2277. return hr;
  2278. }
  2279. //Remote connections for NT4+ only,
  2280. //Delegation connections for NT5 only.
  2281. HRESULT WbemTaskObject :: DoConnectServer (BSTR bstrPath, CWbemServerWrap **a_ppServ, BOOL a_bUpdate)
  2282. {
  2283. WCHAR wszMachine[MAX_PATH];
  2284. wszMachine[0] = L'\0';
  2285. // Determine if it is local
  2286. if (bstrPath != NULL)
  2287. {
  2288. if ( (wcslen(bstrPath) > 4) && (bstrPath[0] == L'\\') && (bstrPath[1] == L'\\') )
  2289. {
  2290. WCHAR *t_ServerMachine = &bstrPath[2];
  2291. while (*t_ServerMachine)
  2292. {
  2293. if ( L'\\' == *t_ServerMachine )
  2294. {
  2295. break ;
  2296. }
  2297. t_ServerMachine++;
  2298. }
  2299. if ((*t_ServerMachine != L'\\') || (t_ServerMachine == &bstrPath[2]))
  2300. {
  2301. return WBEM_E_FAILED;
  2302. }
  2303. *t_ServerMachine = L'\0';
  2304. wcscpy(wszMachine, &bstrPath[2]);
  2305. *t_ServerMachine = L'\\';
  2306. }
  2307. }
  2308. BOOL t_Local = bAreWeLocal ( wszMachine ) ;
  2309. IWbemServices* pServ = NULL;
  2310. HRESULT retVal = WBEM_NO_ERROR;
  2311. wchar_t *prncpl = NULL;
  2312. if (!t_Local)
  2313. {
  2314. //Are we on NT5?
  2315. DWORD dwVersion = GetVersion();
  2316. if (dwVersion < 0x80000000)
  2317. {
  2318. #ifdef UNICODE
  2319. // we are on Windows 2000+
  2320. if ( 5 <= (DWORD)(LOBYTE(LOWORD(dwVersion))) )
  2321. {
  2322. if (a_bUpdate)
  2323. {
  2324. prncpl = new wchar_t[wcslen((*a_ppServ)->GetPrincipal()) + 1];
  2325. wcscpy(prncpl, (*a_ppServ)->GetPrincipal());
  2326. }
  2327. else
  2328. {
  2329. // set up the security structures for a remote connection
  2330. // Setup the authentication structures
  2331. HINSTANCE t_LibraryInstance = LoadLibrary ( CONST_NETAPI_LIBRARY ) ;
  2332. if ( t_LibraryInstance )
  2333. {
  2334. NETAPI_PROC_DsGetDcName t_DsGetDcNameW = ( NETAPI_PROC_DsGetDcName ) GetProcAddress ( t_LibraryInstance , CONST_NETAPI_DSPROC ) ;
  2335. NETAPI_PROC_NetApiBufferFree t_NetApiBufferFree = ( NETAPI_PROC_NetApiBufferFree ) GetProcAddress ( t_LibraryInstance , CONST_NETAPI_NETPROC ) ;
  2336. if ( t_DsGetDcNameW && t_NetApiBufferFree )
  2337. {
  2338. //get the principal name
  2339. PDOMAIN_CONTROLLER_INFO pDomInfo = NULL;
  2340. DWORD dwRet = t_DsGetDcNameW ((const wchar_t*)wszMachine, NULL, NULL, NULL, 0, &pDomInfo);
  2341. if (dwRet == NO_ERROR)
  2342. {
  2343. if (pDomInfo->DomainName != NULL)
  2344. {
  2345. prncpl = new wchar_t[wcslen(pDomInfo->DomainName) + wcslen(wszMachine) + 2];
  2346. wcscpy(prncpl, pDomInfo->DomainName);
  2347. wcscat(prncpl, L"\\");
  2348. wcscat(prncpl, wszMachine);
  2349. }
  2350. t_NetApiBufferFree ((void*)pDomInfo);
  2351. }
  2352. }
  2353. FreeLibrary ( t_LibraryInstance ) ;
  2354. }
  2355. }
  2356. //just try the machine name for the principal
  2357. if (prncpl == NULL)
  2358. {
  2359. prncpl = new wchar_t[wcslen(wszMachine) + 1];
  2360. wcscpy(prncpl, wszMachine);
  2361. }
  2362. if (prncpl != NULL)
  2363. {
  2364. COAUTHIDENTITY authident;
  2365. memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
  2366. authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  2367. COSERVERINFO si;
  2368. si.pwszName = wszMachine;
  2369. si.dwReserved1 = 0;
  2370. si.dwReserved2 = 0;
  2371. si.pAuthInfo = NULL;
  2372. COAUTHINFO ai;
  2373. si.pAuthInfo = &ai;
  2374. ai.pwszServerPrincName = prncpl;
  2375. ai.pAuthIdentityData = NULL;
  2376. retVal = GetCurrentSecuritySettings(&ai.dwAuthnSvc, &ai.dwAuthzSvc,
  2377. &ai.dwAuthnLevel, &ai.dwImpersonationLevel,
  2378. &ai.dwCapabilities);
  2379. //ai.dwAuthnSvc = 16;
  2380. //ai.dwAuthzSvc = RPC_C_AUTHZ_NONE ;
  2381. //ai.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  2382. //ai.dwImpersonationLevel = RPC_C_IMP_LEVEL_DELEGATE;
  2383. //ai.dwCapabilities = 0X20;
  2384. if (SUCCEEDED(retVal))
  2385. {
  2386. retVal = CoCreateForConnectServer(bstrPath, &si, &authident, &pServ);
  2387. }
  2388. }
  2389. else
  2390. {
  2391. retVal = WBEM_E_FAILED;
  2392. }
  2393. }
  2394. else
  2395. #endif //UNICODE
  2396. {
  2397. retVal = WBEM_E_FAILED;
  2398. }
  2399. }
  2400. else
  2401. {
  2402. retVal = WBEM_E_FAILED;
  2403. }
  2404. }
  2405. else
  2406. {
  2407. retVal = LocalConnectServer(bstrPath, &pServ);
  2408. }
  2409. if (SUCCEEDED(retVal) && pServ != NULL)
  2410. {
  2411. if (!a_bUpdate)
  2412. {
  2413. *a_ppServ = new CWbemServerWrap(pServ, prncpl, bstrPath);
  2414. (*a_ppServ)->AddRef();
  2415. }
  2416. else
  2417. {
  2418. (*a_ppServ)->SetMainServer(pServ);
  2419. }
  2420. pServ->Release();
  2421. }
  2422. else
  2423. {
  2424. if (!a_bUpdate)
  2425. {
  2426. *a_ppServ = NULL;
  2427. }
  2428. }
  2429. if (prncpl != NULL)
  2430. {
  2431. delete [] prncpl;
  2432. }
  2433. return retVal;
  2434. }
  2435. #ifdef UNICODE
  2436. HRESULT WbemTaskObject :: CoCreateForConnectServer(BSTR bstrPath, COSERVERINFO* psi, COAUTHIDENTITY* pauthid, IWbemServices** ppServ)
  2437. {
  2438. MULTI_QI mqi;
  2439. mqi.pIID = &IID_IWbemLevel1Login;
  2440. mqi.pItf = 0;
  2441. mqi.hr = 0;
  2442. //delegation doesn't really work with CoCreateInstance....
  2443. DWORD dwImp = psi->pAuthInfo->dwImpersonationLevel;
  2444. if (dwImp > RPC_C_IMP_LEVEL_IMPERSONATE)
  2445. {
  2446. psi->pAuthInfo->dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  2447. }
  2448. HRESULT retVal = g_pfnCoCreateInstanceEx (
  2449. CLSID_WbemLevel1Login,
  2450. NULL,
  2451. CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
  2452. psi ,
  2453. 1,
  2454. &mqi
  2455. );
  2456. psi->pAuthInfo->dwImpersonationLevel = dwImp;
  2457. if ( retVal == S_OK )
  2458. {
  2459. IWbemLevel1Login* t_pLevel1 = (IWbemLevel1Login*) mqi.pItf ;
  2460. // If remote, do the security negotiation
  2461. if (psi)
  2462. {
  2463. retVal = SetSecurityLevelAndCloaking(t_pLevel1, psi->pAuthInfo->pwszServerPrincName);
  2464. }
  2465. if(retVal == S_OK)
  2466. {
  2467. //use null context for remote cimoms...
  2468. retVal = t_pLevel1->NTLMLogin(bstrPath, 0, 0, 0, ppServ);
  2469. if(retVal == S_OK)
  2470. {
  2471. if (psi)
  2472. {
  2473. retVal = SetSecurityLevelAndCloaking(*ppServ, psi->pAuthInfo->pwszServerPrincName);
  2474. if (retVal != S_OK)
  2475. {
  2476. (*ppServ)->Release();
  2477. (*ppServ) = NULL;
  2478. }
  2479. }
  2480. }
  2481. }
  2482. t_pLevel1->Release();
  2483. }
  2484. else
  2485. {
  2486. retVal = WBEM_E_FAILED;
  2487. }
  2488. return retVal;
  2489. }
  2490. #endif //UNICODE
  2491. HRESULT WbemTaskObject :: LocalConnectServer(BSTR bstrPath, IWbemServices** ppServ)
  2492. {
  2493. IWbemLocator *pLoc = NULL;
  2494. HRESULT retVal = m_Provider->GetLocator(&pLoc);
  2495. if (SUCCEEDED (retVal))
  2496. {
  2497. #ifdef UNICODE
  2498. retVal = pLoc->ConnectServer(bstrPath, NULL, NULL, NULL, 0, NULL, m_Ctx, ppServ);
  2499. #else
  2500. retVal = pLoc->ConnectServer(bstrPath, m_Provider->GetUserName(), NULL, NULL, 0, NULL, m_Ctx, ppServ);
  2501. #endif
  2502. pLoc->Release();
  2503. }
  2504. if (SUCCEEDED(retVal))
  2505. {
  2506. retVal = SetSecurityLevelAndCloaking(*ppServ, COLE_DEFAULT_PRINCIPAL);
  2507. if (FAILED(retVal))
  2508. {
  2509. (*ppServ)->Release();
  2510. *ppServ = NULL;
  2511. }
  2512. }
  2513. return retVal;
  2514. }
  2515. void WbemTaskObject::SetResultReceived()
  2516. {
  2517. if (m_ArrayLock.Lock())
  2518. {
  2519. m_ResultReceived = TRUE;
  2520. m_ArrayLock.Unlock();
  2521. }
  2522. }
  2523. void WbemTaskObject::SetStatus(HRESULT hr, DWORD index)
  2524. {
  2525. if (m_ArrayLock.Lock())
  2526. {
  2527. m_ResultReceived = TRUE;
  2528. m_iQueriesAnswered++;
  2529. if (m_iQueriesAsked == m_iQueriesAnswered)
  2530. {
  2531. SetEvent(m_StatusHandle);
  2532. }
  2533. m_ArrayLock.Unlock();
  2534. }
  2535. }
  2536. void WbemTaskObject::CleanUpObjSinks(BOOL a_bDisconnect)
  2537. {
  2538. for (int x = 0; x < m_ObjSinkArray.GetSize(); x++)
  2539. {
  2540. if (m_ObjSinkArray[x] != NULL)
  2541. {
  2542. if (a_bDisconnect)
  2543. {
  2544. m_ObjSinkArray[x]->Disconnect();
  2545. }
  2546. m_ObjSinkArray[x]->Release();
  2547. }
  2548. }
  2549. m_ObjSinkArray.RemoveAll();
  2550. }
  2551. DWORD WbemTaskObject::GetIndexList(const wchar_t* a_src, DWORD** a_pdwArray)
  2552. {
  2553. if (NULL == a_pdwArray)
  2554. {
  2555. return 0;
  2556. }
  2557. DWORD retVal = 0;
  2558. for (DWORD i = 0; i < m_SourceArray.GetSize(); i++)
  2559. {
  2560. BOOL t_bAdd = FALSE;
  2561. if (_wcsicmp(m_SourceArray[i]->GetClassName(), a_src) == 0)
  2562. {
  2563. //try classname match...
  2564. //=======================
  2565. t_bAdd = TRUE;
  2566. }
  2567. else
  2568. {
  2569. //try parentclass match...
  2570. //========================
  2571. IWbemClassObject *t_pCls = m_SourceArray[i]->GetClassObject();
  2572. if (t_pCls)
  2573. {
  2574. VARIANT v;
  2575. VariantInit(&v);
  2576. if ( SUCCEEDED(t_pCls->Get(WBEM_PROPERTY_DERIVATION, 0, &v, NULL, NULL)) )
  2577. {
  2578. if (v.vt == VT_BSTR)
  2579. {
  2580. if (_wcsicmp(v.bstrVal, a_src) == 0)
  2581. {
  2582. t_bAdd = TRUE;
  2583. }
  2584. }
  2585. else if (v.vt == (VT_ARRAY | VT_BSTR))
  2586. {
  2587. if (SafeArrayGetDim(v.parray) == 1)
  2588. {
  2589. LONG count = v.parray->rgsabound[0].cElements;
  2590. BSTR HUGEP *pbstr;
  2591. if ( SUCCEEDED(SafeArrayAccessData(v.parray, (void HUGEP**)&pbstr)) )
  2592. {
  2593. for (LONG x = 0; x < count; x++)
  2594. {
  2595. if (_wcsicmp(pbstr[x], a_src) == 0)
  2596. {
  2597. t_bAdd = TRUE;
  2598. break;
  2599. }
  2600. }
  2601. SafeArrayUnaccessData(v.parray);
  2602. }
  2603. }
  2604. }
  2605. VariantClear(&v);
  2606. }
  2607. t_pCls->Release();
  2608. }
  2609. }
  2610. if (!t_bAdd)
  2611. {
  2612. //try derived class match...i.e. execute the query...
  2613. //select * from meta_class where __this isa "classname" AND __class = "a_src"
  2614. //======================================================================================
  2615. CWbemServerWrap** nsPtrs = m_NSpaceArray[i]->GetServerPtrs();
  2616. for (DWORD j = 0; j < m_NSpaceArray[i]->GetCount(); j++)
  2617. {
  2618. if (nsPtrs[j] != NULL)
  2619. {
  2620. BSTR queryLBStr = SysAllocString(WBEM_QUERY_LANGUAGE_SQL1);
  2621. if (queryLBStr == NULL)
  2622. {
  2623. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  2624. }
  2625. BSTR queryBStr = SysAllocStringLen(NULL, 61 + wcslen(m_SourceArray[i]->GetClassName()) + wcslen(a_src));
  2626. if (queryBStr == NULL)
  2627. {
  2628. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  2629. }
  2630. wcscpy(queryBStr, META_CLASS_QUERY_START);
  2631. wcscat(queryBStr, m_SourceArray[i]->GetClassName());
  2632. wcscat(queryBStr, META_CLASS_QUERY_MID);
  2633. wcscat(queryBStr, a_src);
  2634. wcscat(queryBStr, END_QUOTE);
  2635. IWbemContext * t_pCtx = m_Ctx;
  2636. if (nsPtrs[j]->IsRemote())
  2637. {
  2638. t_pCtx = NULL; //don't use context for remote calls
  2639. }
  2640. IWbemServices *ptmpServ = nsPtrs[j]->GetServerOrProxy();
  2641. if (ptmpServ)
  2642. {
  2643. IEnumWbemClassObject *t_pEnum = NULL;
  2644. HRESULT t_hr = ptmpServ->ExecQuery(queryLBStr, queryBStr, 0, t_pCtx, &t_pEnum);
  2645. if ( FAILED(t_hr) && (HRESULT_FACILITY(t_hr) != FACILITY_ITF) && nsPtrs[j]->IsRemote())
  2646. {
  2647. if ( SUCCEEDED(UpdateConnection(&(nsPtrs[j]), &ptmpServ)) )
  2648. {
  2649. if (ptmpServ)
  2650. {
  2651. t_hr = ptmpServ->ExecQuery(queryLBStr, queryBStr, 0, t_pCtx, &t_pEnum);
  2652. }
  2653. }
  2654. }
  2655. if (ptmpServ)
  2656. {
  2657. nsPtrs[j]->ReturnServerOrProxy(ptmpServ);
  2658. }
  2659. if (SUCCEEDED(t_hr))
  2660. {
  2661. if (nsPtrs[j]->IsRemote())
  2662. {
  2663. t_hr = SetSecurityLevelAndCloaking(t_pEnum, nsPtrs[j]->GetPrincipal());
  2664. }
  2665. if (SUCCEEDED(t_hr))
  2666. {
  2667. //now use the enumerator and see if there is a result...
  2668. IWbemClassObject* t_pClsObj = NULL;
  2669. ULONG t_count = 0;
  2670. //test that a class was returned...
  2671. if ( S_OK == t_pEnum->Next(WBEM_INFINITE, 1, &t_pClsObj, &t_count) )
  2672. {
  2673. if (t_pClsObj)
  2674. {
  2675. t_bAdd = TRUE;
  2676. t_pClsObj->Release();
  2677. }
  2678. }
  2679. }
  2680. t_pEnum->Release();
  2681. }
  2682. }
  2683. //only check one namespace, class defns should match
  2684. break;
  2685. }
  2686. }
  2687. }
  2688. if (t_bAdd)
  2689. {
  2690. if (*a_pdwArray == NULL)
  2691. {
  2692. *a_pdwArray = new DWORD[m_SourceArray.GetSize() - i];
  2693. }
  2694. (*a_pdwArray)[retVal] = i;
  2695. retVal++;
  2696. }
  2697. }
  2698. return retVal;
  2699. }