Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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