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.

1106 lines
33 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //***************************************************************************
  6. #include "wmicom.h"
  7. #include "wmimof.h"
  8. #include "wmimap.h"
  9. #include <stdlib.h>
  10. #include <winerror.h>
  11. #include <TCHAR.h>
  12. //
  13. // GlobalInterfaceTable
  14. //
  15. IGlobalInterfaceTable * g_pGIT = NULL;
  16. ////////////////////////////////////////////////////////////////////////////////////////////////
  17. //**********************************************************************************************
  18. // Global Utility Functions
  19. //**********************************************************************************************
  20. ////////////////////////////////////////////////////////////////////////////////////////////////
  21. BOOL IsBinaryMofResourceEvent(LPOLESTR pGuid, GUID gGuid)
  22. {
  23. HRESULT hr;
  24. GUID Guid;
  25. hr = CLSIDFromString(pGuid,&Guid);
  26. if( SUCCEEDED(hr) )
  27. {
  28. if( gGuid == Guid)
  29. {
  30. return TRUE;
  31. }
  32. }
  33. return FALSE;
  34. }
  35. /////////////////////////////////////////////////////////////////////
  36. BOOL GetParsedPropertiesAndClass( BSTR Query,WCHAR * wcsClass, int cchSize )
  37. {
  38. ParsedObjectPath * pParsedPath = NULL; // stdlibrary API
  39. CObjectPathParser Parser;
  40. BOOL fRc = FALSE;
  41. if( CObjectPathParser::NoError == Parser.Parse(Query, &pParsedPath))
  42. {
  43. try
  44. {
  45. // NTRaid:136400
  46. // 07/12/00
  47. if(pParsedPath && !IsBadReadPtr( pParsedPath, sizeof(ParsedObjectPath)))
  48. {
  49. KeyRef * pKeyRef = NULL;
  50. pKeyRef = *(pParsedPath->m_paKeys);
  51. if(!IsBadReadPtr( pKeyRef, sizeof(KeyRef)))
  52. {
  53. if ( SUCCEEDED ( StringCchCopyW (wcsClass,cchSize,pParsedPath->m_pClass) ) )
  54. {
  55. fRc = TRUE;
  56. }
  57. }
  58. }
  59. Parser.Free(pParsedPath);
  60. }
  61. catch(...)
  62. {
  63. Parser.Free(pParsedPath);
  64. throw;
  65. }
  66. }
  67. return fRc;
  68. }
  69. ////////////////////////////////////////////////////////////////////////////////////////////////
  70. HRESULT CheckIfThisIsAValidKeyProperty(WCHAR * wcsClass, WCHAR * wcsProperty, IWbemServices * p)
  71. {
  72. HRESULT hr = WBEM_E_FAILED;
  73. IWbemClassObject * pIHCO = NULL;
  74. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  75. long lType = 0L;
  76. BSTR strPath = NULL;
  77. strPath = SysAllocString(wcsClass);
  78. if(strPath == NULL)
  79. {
  80. hr = E_OUTOFMEMORY;
  81. }
  82. else
  83. {
  84. hr = p->GetObject(strPath, 0,NULL, &pIHCO, NULL);
  85. SysFreeString(strPath);
  86. if (WBEM_S_NO_ERROR != hr)
  87. return WBEM_E_INVALID_CLASS;
  88. if(wcsProperty){
  89. hr = pIHCO->GetPropertyQualifierSet(wcsProperty,&pIWbemQualifierSet);
  90. if( SUCCEEDED(hr) ){
  91. CVARIANT v;
  92. hr = pIWbemQualifierSet->Get(L"key", 0, &v, 0);
  93. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  94. }
  95. else{
  96. hr = WBEM_E_INVALID_OBJECT_PATH;
  97. }
  98. }
  99. //============================================================
  100. // Cleanup
  101. //============================================================
  102. SAFE_RELEASE_PTR(pIHCO);
  103. }
  104. return hr;
  105. }
  106. //====================================================================
  107. HRESULT GetParsedPath( BSTR ObjectPath, WCHAR * wcsClass, int cchSizeClass, WCHAR * wcsInstance, int cchSizeInstance, IWbemServices * p )
  108. {
  109. //============================================================
  110. // Get the path and instance name and check to make sure it
  111. // is valid
  112. //============================================================
  113. ParsedObjectPath * pParsedPath = NULL; // stdlibrary API
  114. CObjectPathParser Parser;
  115. HRESULT hr = WBEM_E_FAILED;
  116. if( 0 == Parser.Parse(ObjectPath, &pParsedPath))
  117. {
  118. try
  119. {
  120. // NTRaid:136395
  121. // 07/12/00
  122. if(pParsedPath && !IsBadReadPtr( pParsedPath, sizeof(ParsedObjectPath)))
  123. {
  124. KeyRef * pKeyRef = NULL;
  125. pKeyRef = *(pParsedPath->m_paKeys);
  126. if( !IsBadReadPtr( pKeyRef, sizeof(KeyRef)))
  127. {
  128. hr = CheckIfThisIsAValidKeyProperty(pParsedPath->m_pClass, pKeyRef->m_pName,p );
  129. if( SUCCEEDED(hr) )
  130. {
  131. if ( SUCCEEDED ( hr = StringCchCopyW (wcsClass,cchSizeClass,pParsedPath->m_pClass) ) )
  132. {
  133. hr = StringCchCopyW ( wcsInstance, cchSizeInstance, pKeyRef->m_vValue.bstrVal );
  134. }
  135. }
  136. }
  137. }
  138. Parser.Free(pParsedPath);
  139. }
  140. catch(...)
  141. {
  142. hr = WBEM_E_UNEXPECTED;
  143. Parser.Free(pParsedPath);
  144. throw;
  145. }
  146. }
  147. return hr;
  148. }
  149. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  150. BOOL GetUserThreadToken(HANDLE * phThreadTok)
  151. {
  152. BOOL fRc = FALSE;
  153. HRESULT hRes = WbemCoImpersonateClient();
  154. if (SUCCEEDED(hRes))
  155. {
  156. // Now, let's check the impersonation level. First, get the thread token
  157. if (!OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, phThreadTok))
  158. {
  159. // If the CoImpersonate works, but the OpenThreadToken fails, we are running under the
  160. // process token (either local system, or if we are running with /exe, the rights of
  161. // the logged in user). In either case, impersonation rights don't apply. We have the
  162. // full rights of that user.
  163. if(GetLastError() == ERROR_NO_TOKEN)
  164. {
  165. // Try getting the thread token. If it fails it's because we're a system thread and
  166. // we don't yet have a thread token, so just impersonate self and try again.
  167. if( ImpersonateSelf(SecurityImpersonation) )
  168. {
  169. if (!OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, phThreadTok))
  170. {
  171. fRc = FALSE;
  172. }
  173. else
  174. {
  175. fRc = TRUE;
  176. }
  177. }
  178. else
  179. {
  180. ERRORTRACE((THISPROVIDER,"ImpersonateSelf(SecurityImpersonation)failed\n"));
  181. }
  182. }
  183. }
  184. else
  185. {
  186. fRc = TRUE;
  187. }
  188. }
  189. if( !fRc )
  190. {
  191. ERRORTRACE((THISPROVIDER,IDS_ImpersonationFailed));
  192. }
  193. return fRc;
  194. }
  195. ////////////////////////////////////////////////////////////////////////////////////////////////
  196. SAFEARRAY * OMSSafeArrayCreate( IN VARTYPE vt, IN int iNumElements)
  197. {
  198. if(iNumElements < 1)
  199. {
  200. return NULL;
  201. }
  202. SAFEARRAYBOUND rgsabound[1];
  203. rgsabound[0].lLbound = 0;
  204. rgsabound[0].cElements = iNumElements;
  205. return SafeArrayCreate(vt,1,rgsabound);
  206. }
  207. ////////////////////////////////////////////////////////////////////////////////////////////////
  208. void TranslateAndLog( WCHAR * wcsMsg, BOOL bVerbose )
  209. {
  210. BOOL bContinue = FALSE ;
  211. if ( bVerbose )
  212. {
  213. if ( LoggingLevelEnabled ( 2 ) )
  214. {
  215. bContinue = TRUE ;
  216. }
  217. }
  218. else
  219. {
  220. bContinue = TRUE ;
  221. }
  222. if ( bContinue )
  223. {
  224. char * pStr = NULL;
  225. DWORD cCharacters = wcslen(wcsMsg)+1;
  226. pStr = new char[cCharacters*2];
  227. if (NULL != pStr)
  228. {
  229. try
  230. {
  231. // Convert to ANSI.
  232. if (0 != WideCharToMultiByte(CP_ACP, 0, wcsMsg, cCharacters, pStr, cCharacters*2, NULL, NULL))
  233. {
  234. if ( bVerbose )
  235. {
  236. DEBUGTRACE((THISPROVIDER,pStr));
  237. }
  238. else
  239. {
  240. ERRORTRACE((THISPROVIDER,pStr));
  241. }
  242. SAFE_DELETE_ARRAY(pStr);
  243. }
  244. }
  245. catch(...)
  246. {
  247. SAFE_DELETE_ARRAY(pStr);
  248. throw;
  249. }
  250. }
  251. if ( bVerbose )
  252. {
  253. DEBUGTRACE((THISPROVIDER,"\n"));
  254. }
  255. else
  256. {
  257. ERRORTRACE((THISPROVIDER,"\n"));
  258. }
  259. }
  260. }
  261. /////////////////////////////////////////////////////////////////////////////////////////////////
  262. bool IsNT(void)
  263. {
  264. OSVERSIONINFO os;
  265. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  266. if(!GetVersionEx(&os))
  267. return FALSE; // should never happen
  268. return os.dwPlatformId == VER_PLATFORM_WIN32_NT;
  269. }
  270. ////////////////////////////////////////////////////////////////////
  271. BOOL SetGuid(WCHAR * pwcsGuidString, CLSID & Guid)
  272. {
  273. BOOL fRc = FALSE;
  274. CAutoWChar wcsGuid(MAX_PATH+2);
  275. if( wcsGuid.Valid() )
  276. {
  277. if ( FAILED ( CLSIDFromString ( pwcsGuidString, &Guid ) ) )
  278. {
  279. if ( SUCCEEDED ( StringCchPrintfW ( wcsGuid, MAX_PATH+2, L"{%s}", pwcsGuidString ) ) )
  280. {
  281. if ( SUCCEEDED ( CLSIDFromString ( wcsGuid, &Guid ) ) )
  282. {
  283. fRc = TRUE;
  284. }
  285. }
  286. }
  287. else
  288. {
  289. fRc = TRUE;
  290. }
  291. }
  292. return fRc;
  293. }
  294. ////////////////////////////////////////////////////////////////////
  295. HRESULT AllocAndCopy(WCHAR * wcsSource, WCHAR ** pwcsDest )
  296. {
  297. HRESULT hr = WBEM_E_FAILED;
  298. int nLen = wcslen(wcsSource);
  299. if( nLen > 0 )
  300. {
  301. *pwcsDest = new WCHAR[nLen + 2 ];
  302. if( *pwcsDest )
  303. {
  304. hr = StringCchCopyW(*pwcsDest, nLen+2, wcsSource);
  305. }
  306. }
  307. return hr;
  308. }
  309. ////////////////////////////////////////////////////////////////////////////////////////////////
  310. //**********************************************************************************************
  311. // Utility Classes
  312. //**********************************************************************************************
  313. ////////////////////////////////////////////////////////////////////////////////////////////////
  314. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. void _WMIHandleMap::AddRef()
  316. {
  317. InterlockedIncrement((long*)&RefCount);
  318. }
  319. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  320. long _WMIHandleMap::Release()
  321. {
  322. ULONG cRef = InterlockedDecrement( (long*) &RefCount);
  323. if ( !cRef ){
  324. WmiCloseBlock(WMIHandle);
  325. return 0;
  326. }
  327. return cRef;
  328. }
  329. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  330. _WMIEventRequest::_WMIEventRequest()
  331. {
  332. pwcsClass = NULL ;
  333. pHandler = NULL;
  334. pCtx = NULL;
  335. }
  336. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  337. _WMIEventRequest::~_WMIEventRequest()
  338. {
  339. SAFE_RELEASE_PTR(pCtx);
  340. SAFE_DELETE_ARRAY(pwcsClass);
  341. }
  342. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  343. HRESULT _WMIEventRequest::AddPtrs (
  344. IWbemObjectSink __RPC_FAR * Handler,
  345. IWbemServices __RPC_FAR * Services,
  346. IWbemServices __RPC_FAR * Repository,
  347. IWbemContext __RPC_FAR * Ctx
  348. )
  349. {
  350. HRESULT hr = E_FAIL;
  351. if ( SUCCEEDED ( hr = gipServices.Globalize(Services) ) )
  352. {
  353. if ( SUCCEEDED ( hr = gipRepository.Globalize(Repository) ) )
  354. {
  355. pHandler = Handler;
  356. pCtx = Ctx;
  357. if( pCtx ){
  358. pCtx->AddRef();
  359. }
  360. }
  361. }
  362. return hr;
  363. }
  364. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  365. _AccessList::~_AccessList()
  366. {
  367. for( int i = 0; i < m_List.Size(); i++ )
  368. {
  369. IWbemObjectAccess * pPtr = (IWbemObjectAccess *)m_List[i];
  370. SAFE_RELEASE_PTR(pPtr);
  371. }
  372. m_List.Empty();
  373. }
  374. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  375. _IdList::~_IdList()
  376. {
  377. for( int i = 0; i < m_List.Size(); i++ )
  378. {
  379. ULONG_PTR* pPtr = (ULONG_PTR*)m_List[i];
  380. SAFE_DELETE_PTR(pPtr);
  381. }
  382. m_List.Empty();
  383. }
  384. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  385. _HandleList::~_HandleList()
  386. {
  387. for( int i = 0; i < m_List.Size(); i++ )
  388. {
  389. HANDLE * pPtr = (HANDLE*)m_List[i];
  390. SAFE_DELETE_PTR(pPtr);
  391. }
  392. m_List.Empty();
  393. }
  394. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  395. _InstanceList::~_InstanceList()
  396. {
  397. for( int i = 0; i < m_List.Size(); i++ )
  398. {
  399. WCHAR * p = (WCHAR*)m_List[i];
  400. SAFE_DELETE_ARRAY(p);
  401. }
  402. m_List.Empty();
  403. }
  404. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  405. _OldClassInfo::~_OldClassInfo()
  406. {
  407. SAFE_DELETE_ARRAY(m_pClass);
  408. SAFE_DELETE_ARRAY(m_pPath);
  409. m_pClass = m_pPath = NULL;
  410. }
  411. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  412. _OldClassList::~_OldClassList()
  413. {
  414. for( int i = 0; i < m_List.Size(); i++ )
  415. {
  416. OldClassInfo * p = (OldClassInfo*)m_List[i];
  417. SAFE_DELETE_PTR(p);
  418. }
  419. m_List.Empty();
  420. }
  421. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  422. _WMIHiPerfHandleMap::_WMIHiPerfHandleMap(CWMIProcessClass * p, IWbemHiPerfEnum * pEnum)
  423. {
  424. m_pEnum = pEnum;
  425. if( pEnum )
  426. {
  427. pEnum->AddRef();
  428. }
  429. m_pClass = p;
  430. m_fEnumerator = FALSE;
  431. lHiPerfId = 0;
  432. }
  433. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  434. _WMIHiPerfHandleMap::~_WMIHiPerfHandleMap()
  435. {
  436. SAFE_RELEASE_PTR(m_pEnum);
  437. lHiPerfId = 0;
  438. SAFE_DELETE_PTR(m_pClass);
  439. }
  440. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  441. // Hi Perf Handle Map = Handles are addref'd and when released, then the block is closed
  442. // Critical Sections are handled elsewhere
  443. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  444. HRESULT CHiPerfHandleMap::Add( HANDLE hCurrent, ULONG_PTR lHiPerfId, CWMIProcessClass * p, IWbemHiPerfEnum * pEnum)
  445. {
  446. HRESULT hr = S_OK;
  447. WMIHiPerfHandleMap * pWMIMap = new WMIHiPerfHandleMap(p,pEnum);
  448. if( pWMIMap )
  449. {
  450. try
  451. {
  452. pWMIMap->WMIHandle = hCurrent;
  453. pWMIMap->lHiPerfId = lHiPerfId;
  454. // 170635
  455. if(CFlexArray::out_of_memory == m_List.Add(pWMIMap))
  456. {
  457. SAFE_DELETE_PTR(pWMIMap);
  458. hr = E_OUTOFMEMORY;
  459. }
  460. }
  461. catch(...)
  462. {
  463. hr = WBEM_E_UNEXPECTED;
  464. SAFE_DELETE_PTR(pWMIMap);
  465. throw;
  466. }
  467. }
  468. return hr;
  469. }
  470. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  471. HRESULT CHiPerfHandleMap::FindHandleAndGetClassPtr( HANDLE & hCurrent, ULONG_PTR lHiPerfId,CWMIProcessClass *& p)
  472. {
  473. HRESULT hr = WBEM_E_NOT_FOUND;
  474. for( int i=0; i<m_List.Size(); i++)
  475. {
  476. //===================================================
  477. //
  478. //===================================================
  479. WMIHiPerfHandleMap * pMap = (WMIHiPerfHandleMap *) m_List[i];
  480. if( pMap->lHiPerfId == lHiPerfId )
  481. {
  482. hCurrent = pMap->WMIHandle;
  483. p = pMap->m_pClass;
  484. hr = S_OK;
  485. }
  486. }
  487. return hr;
  488. }
  489. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  490. HRESULT CHiPerfHandleMap::GetFirstHandle(HANDLE & hCurrent,CWMIProcessClass *& p, IWbemHiPerfEnum *& pEnum)
  491. {
  492. m_nIndex=0;
  493. return GetNextHandle(hCurrent,p,pEnum);
  494. }
  495. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  496. HRESULT CHiPerfHandleMap::GetNextHandle(HANDLE & hCurrent,CWMIProcessClass *& p, IWbemHiPerfEnum *& pEnum)
  497. {
  498. HRESULT hr = WBEM_S_NO_MORE_DATA;
  499. if( m_nIndex < m_List.Size() )
  500. {
  501. WMIHiPerfHandleMap * pMap = (WMIHiPerfHandleMap *) m_List[m_nIndex];
  502. hCurrent = pMap->WMIHandle;
  503. p = pMap->m_pClass;
  504. pEnum = pMap->m_pEnum;
  505. m_nIndex++;
  506. hr = S_OK;
  507. }
  508. return hr;
  509. }
  510. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  511. HRESULT CHiPerfHandleMap::Delete( HANDLE & hCurrent, ULONG_PTR lHiPerfId )
  512. {
  513. HRESULT hr = WBEM_E_NOT_FOUND;
  514. for( int i=0; i<m_List.Size(); i++)
  515. {
  516. //===================================================
  517. //
  518. //===================================================
  519. WMIHiPerfHandleMap * pMap = (WMIHiPerfHandleMap *) m_List[i];
  520. if( pMap->lHiPerfId == lHiPerfId )
  521. {
  522. hCurrent = pMap->WMIHandle;
  523. SAFE_DELETE_PTR(pMap);
  524. m_List.RemoveAt(i);
  525. hr = S_OK;
  526. break;
  527. }
  528. }
  529. return hr;
  530. }
  531. ////////////////////////////////////////////////////////////////////////////////////////////////
  532. // When this function is called, release all the handles kept
  533. // THis function is called in the destructor of the class to release all teh WMIHiPerfHandleMap
  534. // classes allocated
  535. ////////////////////////////////////////////////////////////////////////////////////////////////
  536. void CHiPerfHandleMap::CloseAndReleaseHandles()
  537. {
  538. //===================================
  539. // Go through the handles one at
  540. // a time and close them, then
  541. // delete the records from the
  542. // array
  543. //===================================
  544. CAutoBlock((CCriticalSection *)&m_HandleCs);
  545. if( m_List.Size() > 0 ){
  546. for(int i = 0; i < m_List.Size(); i++){
  547. WMIHiPerfHandleMap * pWMIMap = (WMIHiPerfHandleMap *) m_List[i];
  548. SAFE_DELETE_PTR(pWMIMap);
  549. }
  550. //==================================================
  551. // Remove it and deallocate memory
  552. //==================================================
  553. m_List.Empty();
  554. }
  555. }
  556. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  557. // Regular Handle Map = Expensize handles are always kept open - by default we, dont' know the lifetime
  558. // of these handles
  559. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  560. HRESULT CHandleMap::Add(CLSID Guid, HANDLE hCurrent, ULONG uDesiredAccess)
  561. {
  562. // Critical section is called elsewhere
  563. HRESULT hr = S_OK;
  564. WMIHandleMap * pWMIMap = new WMIHandleMap();
  565. if( pWMIMap )
  566. {
  567. try
  568. {
  569. pWMIMap->AddRef(); // Used for HiPerf counts, otherwise not referenced
  570. pWMIMap->WMIHandle = hCurrent;
  571. pWMIMap->Guid = Guid;
  572. pWMIMap->uDesiredAccess = uDesiredAccess;
  573. // 170635
  574. if(CFlexArray::out_of_memory == m_List.Add(pWMIMap))
  575. {
  576. hr = E_OUTOFMEMORY;
  577. SAFE_DELETE_PTR(pWMIMap);
  578. }
  579. }
  580. catch(...)
  581. {
  582. hr = WBEM_E_UNEXPECTED;
  583. SAFE_DELETE_PTR(pWMIMap);
  584. throw;
  585. }
  586. }
  587. return hr;
  588. }
  589. ////////////////////////////////////////////////////////////////////////////////////////////////
  590. int CHandleMap::ExistingHandleAlreadyExistsForThisGuidUseIt(CLSID Guid,
  591. HANDLE & hCurrentWMIHandle,
  592. BOOL & fCloseHandle,
  593. ULONG uDesiredAccess)
  594. {
  595. int nRc = ERROR_NOT_SUPPORTED;
  596. // Critical section is called elsewhere
  597. //=====================================================
  598. // Initialize stuff
  599. //=====================================================
  600. hCurrentWMIHandle = 0;
  601. fCloseHandle = TRUE;
  602. for(int i = 0; i < m_List.Size(); i++){
  603. WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i];
  604. //==================================================
  605. // Compare and see if this guid already has a
  606. // handle assigned for it with the access permissions
  607. // that we want to use
  608. //==================================================
  609. if( pWMIMap->Guid == Guid ){
  610. if( pWMIMap->uDesiredAccess == uDesiredAccess ){
  611. hCurrentWMIHandle = pWMIMap->WMIHandle;
  612. pWMIMap->AddRef(); // Used for HiPerf Handles, otherwise not needed
  613. nRc = ERROR_SUCCESS;
  614. fCloseHandle = FALSE;
  615. break;
  616. }
  617. }
  618. }
  619. return nRc;
  620. }
  621. ////////////////////////////////////////////////////////////////////////////////////////////////
  622. // When this function is called, we need to close all of the handles that may have been kept
  623. // open for accumulation purposes
  624. ////////////////////////////////////////////////////////////////////////////////////////////////
  625. void CHandleMap::CloseAllOutstandingWMIHandles()
  626. {
  627. //===================================
  628. // Go through the handles one at
  629. // a time and close them, then
  630. // delete the records from the
  631. // array
  632. //===================================
  633. CAutoBlock((CCriticalSection *)&m_HandleCs);
  634. if( m_List.Size() > 0 ){
  635. for(int i = 0; i < m_List.Size(); i++){
  636. WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i];
  637. //==================================================
  638. // Inform WMI we are done with this guy
  639. //==================================================
  640. try
  641. {
  642. WmiCloseBlock(pWMIMap->WMIHandle);
  643. }
  644. catch(...)
  645. {
  646. // don't throw
  647. }
  648. SAFE_DELETE_PTR(pWMIMap);
  649. }
  650. //==================================================
  651. // Remove it and deallocate memory
  652. //==================================================
  653. m_List.Empty();
  654. }
  655. }
  656. ////////////////////////////////////////////////////////////////////////////////////////////////
  657. // Used when we know the handles lifetimes
  658. ////////////////////////////////////////////////////////////////////////////////////////////////
  659. int CHandleMap::ReleaseHandle( HANDLE hCurrentWMIHandle )
  660. {
  661. int nRc = ERROR_NOT_SUPPORTED;
  662. CAutoBlock((CCriticalSection *)&m_HandleCs);
  663. for(int i = 0; i < m_List.Size(); i++){
  664. WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i];
  665. if( pWMIMap->WMIHandle == hCurrentWMIHandle )
  666. {
  667. long RefCount = pWMIMap->Release(); // Used for HiPerf Handles, otherwise not needed
  668. if( !RefCount )
  669. {
  670. // WmiCloseBlock(hCurrentWMIHandle);
  671. SAFE_DELETE_PTR( pWMIMap);
  672. m_List.RemoveAt(i);
  673. }
  674. nRc = ERROR_SUCCESS;
  675. break;
  676. }
  677. }
  678. return nRc;
  679. }
  680. ////////////////////////////////////////////////////////////////////////////////////////////////
  681. int CHandleMap::GetHandle(CLSID Guid, HANDLE & hCurrentWMIHandle )
  682. {
  683. int nRc = ERROR_NOT_SUPPORTED;
  684. CAutoBlock((CCriticalSection *)&m_HandleCs);
  685. //=====================================================
  686. // Initialize stuff
  687. //=====================================================
  688. hCurrentWMIHandle = 0;
  689. for(int i = 0; i < m_List.Size(); i++){
  690. WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i];
  691. if( pWMIMap->Guid == Guid ){
  692. hCurrentWMIHandle = pWMIMap->WMIHandle;
  693. pWMIMap->AddRef(); // Used for HiPerf Handles, otherwise not needed
  694. nRc = ERROR_SUCCESS;
  695. break;
  696. }
  697. }
  698. return nRc;
  699. }
  700. //************************************************************************************************************
  701. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  702. //
  703. // CWMIManagement
  704. //
  705. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  706. //************************************************************************************************************
  707. CWMIManagement::CWMIManagement( ) :
  708. m_pHandler ( NULL ) ,
  709. m_pServices ( NULL ) ,
  710. m_pRepository ( NULL ) ,
  711. m_pCtx ( NULL ) ,
  712. m_pHandleMap ( NULL )
  713. {
  714. }
  715. //////////////////////////////////////////////////////////////////////////////////////
  716. CWMIManagement::~CWMIManagement()
  717. {
  718. }
  719. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  720. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  721. void CWMIManagement::SendPrivilegeExtendedErrorObject( HRESULT hrToReturn,WCHAR * wcsClass)
  722. {
  723. HRESULT hr,hRes;
  724. IWbemClassObject * pClass = NULL, *pInst=NULL;
  725. BOOL fSetStatus = FALSE;
  726. if( hrToReturn == WBEM_E_ACCESS_DENIED ){
  727. TOKEN_PRIVILEGES * ptPriv = NULL;
  728. hr = GetListOfUserPrivileges(ptPriv);
  729. if( SUCCEEDED(hr ) ){
  730. BSTR strPrivelegeStat = NULL;
  731. strPrivelegeStat = SysAllocString(L"Win32_PrivilegesStatus");
  732. if(strPrivelegeStat != NULL)
  733. {
  734. hr = m_pRepository->GetObject(strPrivelegeStat, 0,m_pCtx, &pClass, NULL);
  735. if( hr == S_OK){
  736. //=============================================================
  737. // Get an instance of the extended class
  738. //=============================================================
  739. hr = pClass->SpawnInstance(0,&pInst);
  740. SAFE_RELEASE_PTR(pClass);
  741. if( pInst ){
  742. CVARIANT varTmp;
  743. //=========================================================
  744. // Fill in description
  745. //=========================================================
  746. varTmp.SetStr(IDS_ImpersonationFailedWide);
  747. hr = pInst->Put(L"Description", 0, &varTmp, NULL);
  748. //======================================================
  749. // Initialize all of the necessary stuff and get the
  750. // definition of the class we are working with
  751. //======================================================
  752. CWMIProcessClass ClassInfo(0);
  753. if( SUCCEEDED(ClassInfo.Initialize()) )
  754. {
  755. ClassInfo.WMI()->SetWMIPointers(m_pHandleMap,m_pServices,m_pRepository,m_pHandler,m_pCtx);
  756. ClassInfo.SetClass(wcsClass);
  757. SAFEARRAY *psaPrivNotHeld=NULL;
  758. SAFEARRAY *psaPrivReq=NULL;
  759. //=========================================================
  760. // Get PrivilegesRequired
  761. // The only place to get this, if possible, is from the
  762. // class
  763. //=========================================================
  764. hRes = ClassInfo.GetPrivilegesQualifer(&psaPrivReq);
  765. if( hRes == WBEM_S_NO_ERROR){
  766. //=========================================================
  767. // Get PrivilegesNotHeld
  768. //=========================================================
  769. ProcessPrivileges(ptPriv,psaPrivNotHeld,psaPrivReq);
  770. //=========================================================
  771. // Send it off
  772. //=========================================================
  773. VARIANT v;
  774. if( psaPrivReq ){
  775. VariantInit(&v);
  776. SAFEARRAY *pSafeArray = NULL;
  777. if ( SUCCEEDED ( SafeArrayCopy ((SAFEARRAY*)psaPrivReq , &pSafeArray ) ) ){
  778. v.vt = VT_BSTR | VT_ARRAY;
  779. v.parray = pSafeArray;
  780. pInst->Put(L"PrivilegesRequired", 0, &v, NULL);
  781. VariantClear(&v);
  782. }
  783. }
  784. if( psaPrivNotHeld ){
  785. VariantInit(&v);
  786. SAFEARRAY *pSafeArray = NULL;
  787. if ( SUCCEEDED ( SafeArrayCopy ((SAFEARRAY*)psaPrivNotHeld , &pSafeArray ) ) ){
  788. v.vt = VT_BSTR | VT_ARRAY;
  789. v.parray = pSafeArray;
  790. pInst->Put(L"PrivilegesNotHeld", 0, &v, NULL);
  791. VariantClear(&v);
  792. }
  793. }
  794. }
  795. //=========================================================
  796. // Now, send this guy off...
  797. //=========================================================
  798. fSetStatus = TRUE;
  799. hr = m_pHandler->SetStatus(0,hrToReturn,NULL,pInst);
  800. if (psaPrivNotHeld)
  801. SafeArrayDestroy(psaPrivNotHeld);
  802. if (psaPrivReq)
  803. SafeArrayDestroy(psaPrivReq);
  804. }
  805. }
  806. SAFE_RELEASE_PTR(pInst);
  807. }
  808. SysFreeString(strPrivelegeStat);
  809. }
  810. }
  811. SAFE_DELETE_ARRAY(ptPriv);
  812. }
  813. if( !fSetStatus ){
  814. hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL);
  815. }
  816. }
  817. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  818. HRESULT CWMIManagement::SetErrorMessage(HRESULT hrToReturn,WCHAR * wcsClass,WCHAR * wcsMsg)
  819. {
  820. HRESULT hr;
  821. IWbemClassObject * pClass = NULL, *pInst=NULL;
  822. BOOL fSetStatus = FALSE;
  823. if( m_pHandler )
  824. {
  825. BSTR strExtendedStat = NULL;
  826. switch( hrToReturn ){
  827. case WBEM_E_ACCESS_DENIED:
  828. SendPrivilegeExtendedErrorObject(hrToReturn,wcsClass);
  829. break;
  830. case S_OK :
  831. hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL);
  832. break;
  833. default:
  834. strExtendedStat = SysAllocString(L"__ExtendedStatus");
  835. if(strExtendedStat != NULL)
  836. {
  837. hr = m_pRepository->GetObject(strExtendedStat, 0,m_pCtx, &pClass, NULL);
  838. if( hr == S_OK){
  839. hr = pClass->SpawnInstance(0,&pInst);
  840. if( pInst ){
  841. CVARIANT varTmp;
  842. varTmp.SetStr(wcsMsg);
  843. hr = pInst->Put(L"Description", 0, &varTmp, NULL);
  844. hr = m_pHandler->SetStatus(0,hrToReturn,NULL,pInst);
  845. fSetStatus = TRUE;
  846. // Now log the error in the error log
  847. if( hrToReturn != S_OK ){
  848. TranslateAndLog(varTmp.GetStr());
  849. }
  850. }
  851. }
  852. if( !fSetStatus ){
  853. hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL);
  854. }
  855. SAFE_RELEASE_PTR(pClass);
  856. SAFE_RELEASE_PTR(pInst);
  857. SysFreeString(strExtendedStat);
  858. }
  859. else
  860. {
  861. hr = E_OUTOFMEMORY;
  862. }
  863. break;
  864. }
  865. }
  866. return hrToReturn;
  867. }
  868. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  869. HRESULT CWMIManagement::GetListOfUserPrivileges(TOKEN_PRIVILEGES *& ptPriv)
  870. {
  871. HRESULT hr = WBEM_E_FAILED;
  872. // Get the privileges this user has
  873. DWORD dwTokenInfoLength = 0;
  874. DWORD dwSize = 0;
  875. HANDLE hThreadTok;
  876. if (IsNT()){
  877. if( GetUserThreadToken(&hThreadTok) ){
  878. // get information
  879. if (!GetTokenInformation(hThreadTok, TokenPrivileges, NULL, dwTokenInfoLength, &dwSize)){
  880. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  881. {
  882. ptPriv = ( TOKEN_PRIVILEGES* ) new BYTE[dwSize];
  883. if( ptPriv )
  884. {
  885. try
  886. {
  887. dwTokenInfoLength = dwSize;
  888. if(GetTokenInformation(hThreadTok, TokenPrivileges, (LPVOID)ptPriv, dwTokenInfoLength, &dwSize))
  889. {
  890. hr = WBEM_NO_ERROR;
  891. }
  892. }
  893. catch(...)
  894. {
  895. SAFE_DELETE_ARRAY(ptPriv);
  896. hr = WBEM_E_UNEXPECTED;
  897. throw;
  898. }
  899. }
  900. }
  901. }
  902. // Done with this handle
  903. CloseHandle(hThreadTok);
  904. }
  905. }
  906. return hr;
  907. }
  908. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  909. void CWMIManagement::ProcessPrivileges(TOKEN_PRIVILEGES *ptPriv, SAFEARRAY *& psaPrivNotHeld, SAFEARRAY * psaPrivReq )
  910. {
  911. BOOL fFound = FALSE;
  912. //==============================================================
  913. // Create a temporary working array, we know the MAX can be
  914. // the number of priv held + the number of priv req, so
  915. // allocate it for that
  916. //==============================================================
  917. CSAFEARRAY PrivReq( psaPrivReq );
  918. long lMax = PrivReq.GetNumElements()+ptPriv->PrivilegeCount;
  919. psaPrivNotHeld = OMSSafeArrayCreate(VT_BSTR,lMax);
  920. long nCurrentIndex = 0;
  921. //==============================================================
  922. // Get how many privs are not held
  923. //==============================================================
  924. for( long n = 0; n < PrivReq.GetNumElements(); n++ ){
  925. //==============================================================
  926. // Now, get the privileges held array ready to put stuff in
  927. //==============================================================
  928. TCHAR * pPrivReq = NULL;
  929. CBSTR bstr;
  930. if( S_OK != PrivReq.Get(n, &bstr)){
  931. return;
  932. }
  933. fFound = FALSE;
  934. pPrivReq = (TCHAR *)bstr;
  935. // NTRaid:136384
  936. // 07/12/00
  937. if(pPrivReq)
  938. {
  939. for(int i=0;i < (int)ptPriv->PrivilegeCount;i++)
  940. {
  941. DWORD dwPriv=NAME_SIZE*2;
  942. TCHAR szPriv[NAME_SIZE*2];
  943. if( LookupPrivilegeName( NULL, &ptPriv->Privileges[i].Luid, szPriv, &dwPriv)){
  944. //==============================================
  945. // If we found the privilege, then the user has
  946. // it. break out
  947. //==============================================
  948. if( _tcscmp( pPrivReq,szPriv ) == 0 ){
  949. fFound = TRUE;
  950. break;
  951. }
  952. }
  953. //==================================================
  954. // If we didn't find it, then we need to add it to
  955. // the list so we can notify the user
  956. //==================================================
  957. if( !fFound ){
  958. if( S_OK == SafeArrayPutElement(psaPrivNotHeld, &nCurrentIndex, bstr))
  959. {
  960. nCurrentIndex++;
  961. }
  962. }
  963. }
  964. }
  965. pPrivReq = NULL;
  966. }
  967. SAFEARRAYBOUND rgsabound[1];
  968. rgsabound[0].lLbound = 0;
  969. rgsabound[0].cElements = nCurrentIndex;
  970. HRESULT hr = SafeArrayRedim(psaPrivNotHeld, rgsabound);
  971. PrivReq.Unbind();
  972. }