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.

1128 lines
20 KiB

  1. //***************************************************************************
  2. //
  3. // PINGPROV.CPP
  4. //
  5. // Module: WMI PING PROVIDER
  6. //
  7. // Purpose: Implementation for the CPingProvider class.
  8. //
  9. // Copyright (c) 2000-2002 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include <initguid.h>
  13. #ifndef INITGUID
  14. #define INITGUID
  15. #endif
  16. #include <stdafx.h>
  17. #include <ntddtcp.h>
  18. #include <ipinfo.h>
  19. #include <tdiinfo.h>
  20. #include <winsock2.h>
  21. #include <provimex.h>
  22. #include <provexpt.h>
  23. #include <provtempl.h>
  24. #include <provmt.h>
  25. #include <typeinfo.h>
  26. #include <provcont.h>
  27. #include <provevt.h>
  28. #include <provthrd.h>
  29. #include <provlog.h>
  30. #include <provval.h>
  31. #include <provtype.h>
  32. #include <provtree.h>
  33. #include <provdnf.h>
  34. #include <winsock.h>
  35. #include "ipexport.h"
  36. #include "icmpapi.h"
  37. #include <Allocator.h>
  38. #include <Thread.h>
  39. #include <HashTable.h>
  40. #include <pingprov.h>
  41. #include <pingfac.h>
  42. #include <pingtask.h>
  43. #include <scopeguard.h>
  44. /////////////////////////////////////////////////////////////////////////////
  45. // Functions constructor, destructor and IUnknown
  46. //***************************************************************************
  47. //
  48. // CPingProvider ::CPingProvider
  49. // CPingProvider ::~CPingProvider
  50. //
  51. //***************************************************************************
  52. CRITICAL_SECTION CPingProvider::s_CS;
  53. CPingThread *CPingProvider::s_PingThread = NULL;
  54. WmiAllocator *CPingProvider::s_Allocator = NULL;
  55. WmiHashTable <CKeyEntry, ULONG, 12> *CPingProvider::s_HashTable = NULL;
  56. LPCWSTR CPingProvider::s_KeyTable[PING_KEY_PROPERTY_COUNT] = {
  57. Ping_Address,
  58. Ping_Timeout,
  59. Ping_TimeToLive,
  60. Ping_BufferSize,
  61. Ping_NoFragmentation,
  62. Ping_TypeofService,
  63. Ping_RecordRoute,
  64. Ping_TimestampRoute,
  65. Ping_SourceRouteType,
  66. Ping_SourceRoute,
  67. Ping_ResolveAddressNames
  68. };
  69. LONG CompareElement ( const CKeyEntry &a_Arg1 , const CKeyEntry & a_Arg2 )
  70. {
  71. LPCWSTR t_a1 = a_Arg1.Get();
  72. LPCWSTR t_a2 = a_Arg2.Get();
  73. if (t_a1 == t_a2)
  74. {
  75. return 0;
  76. }
  77. else if ((t_a1 == NULL) && (t_a1 != NULL))
  78. {
  79. return 1;
  80. }
  81. else if ((t_a1 == NULL) && (t_a1 != NULL))
  82. {
  83. return -1;
  84. }
  85. else
  86. {
  87. return (_wcsicmp(t_a1, t_a2));
  88. }
  89. }
  90. BOOL operator== ( const CKeyEntry &a_Arg1 , const CKeyEntry &a_Arg2 )
  91. {
  92. return (CompareElement(a_Arg1, a_Arg2) == 0);
  93. }
  94. BOOL operator< ( const CKeyEntry &a_Arg1 , const CKeyEntry &a_Arg2 )
  95. {
  96. return (CompareElement(a_Arg1, a_Arg2) == -1);
  97. }
  98. ULONG Hash ( const CKeyEntry & a_Arg )
  99. {
  100. LPCWSTR t_a = a_Arg.Get();
  101. ULONG t_RetVal = 0;
  102. if (t_a != NULL)
  103. {
  104. switch (*t_a)
  105. {
  106. case L'A':
  107. case L'a':
  108. {
  109. t_RetVal = 1;
  110. }
  111. break;
  112. case L'B':
  113. case L'b':
  114. {
  115. t_RetVal = 2;
  116. }
  117. break;
  118. case L'N':
  119. case L'n':
  120. {
  121. t_RetVal = 3;
  122. }
  123. break;
  124. case L'R':
  125. case L'r':
  126. {
  127. switch (wcslen(t_a))
  128. {
  129. case 11 : //wcslen(RecordRoute)
  130. {
  131. t_RetVal = 4;
  132. }
  133. break;
  134. case 19 : //wcslen(ResolveAddressNames)
  135. {
  136. t_RetVal = 5;
  137. }
  138. break;
  139. default:
  140. {
  141. }
  142. }
  143. }
  144. break;
  145. case L'S':
  146. case L's':
  147. {
  148. switch (wcslen(t_a))
  149. {
  150. case 11 : //wcslen(SourceRoute)
  151. {
  152. t_RetVal = 6;
  153. }
  154. break;
  155. case 15 : //wcslen(SourceRouteType)
  156. {
  157. t_RetVal = 7;
  158. }
  159. break;
  160. default:
  161. {
  162. }
  163. }
  164. }
  165. break;
  166. case L'T':
  167. case L't':
  168. {
  169. switch (wcslen(t_a))
  170. {
  171. case 7 : //wcslen(TimeOut)
  172. {
  173. t_RetVal = 8;
  174. }
  175. break;
  176. case 10 : //wcslen(TimeToLive)
  177. {
  178. t_RetVal = 9;
  179. }
  180. break;
  181. case 13 : //wcslen(TypeOfService)
  182. {
  183. t_RetVal = 10;
  184. }
  185. break;
  186. case 14 : //wcslen(TimeStampRoute)
  187. {
  188. t_RetVal = 11;
  189. }
  190. break;
  191. default:
  192. {
  193. }
  194. }
  195. }
  196. break;
  197. default:
  198. {
  199. }
  200. }
  201. }
  202. return t_RetVal ;
  203. }
  204. CPingThread::CPingThread (WmiAllocator & a_Allocator)
  205. : WmiThread < ULONG > ( a_Allocator , L"PingProviderThread") ,
  206. m_Allocator ( a_Allocator ), m_Init(FALSE)
  207. {
  208. }
  209. CPingThread::~CPingThread ()
  210. {
  211. }
  212. WmiStatusCode CPingThread :: Initialize_Callback ()
  213. {
  214. WmiStatusCode t_RetVal = e_StatusCode_NotInitialized;
  215. if (SUCCEEDED( CoInitializeEx ( NULL , COINIT_MULTITHREADED )) )
  216. {
  217. WSADATA t_WsaData ;
  218. if (0 == WSAStartup (0x0101, & t_WsaData))
  219. {
  220. t_RetVal = e_StatusCode_Success ;
  221. m_Init = TRUE;
  222. }
  223. else
  224. {
  225. CoUninitialize () ;
  226. }
  227. }
  228. return t_RetVal ;
  229. }
  230. WmiStatusCode CPingThread :: UnInitialize_Callback ()
  231. {
  232. if (m_Init)
  233. {
  234. WSACleanup () ;
  235. CoUninitialize () ;
  236. }
  237. return e_StatusCode_Success ;
  238. }
  239. CPingProvider ::CPingProvider () : m_referenceCount(0),
  240. m_server(NULL),
  241. m_notificationClassObject(NULL),
  242. m_ClassObject(NULL),
  243. m_bInitial(FALSE)
  244. {
  245. InterlockedIncrement ( & CPingProviderClassFactory :: s_ObjectsInProgress ) ;
  246. }
  247. CPingProvider ::~CPingProvider()
  248. {
  249. if ( m_server != NULL )
  250. {
  251. m_server->Release () ;
  252. }
  253. if ( m_ClassObject != NULL )
  254. {
  255. m_ClassObject->Release () ;
  256. }
  257. if ( m_notificationClassObject != NULL )
  258. {
  259. m_notificationClassObject->Release () ;
  260. }
  261. InterlockedDecrement ( & CPingProviderClassFactory :: s_ObjectsInProgress ) ;
  262. }
  263. HRESULT CPingProvider :: Global_Startup ()
  264. {
  265. HRESULT t_Result = S_OK ;
  266. if ( s_Allocator)
  267. {
  268. if ( !s_PingThread )
  269. {
  270. WmiStatusCode t_StatusCode = WmiThread <ULONG> :: Static_Initialize ( *s_Allocator ) ;
  271. if ( t_StatusCode != e_StatusCode_Success )
  272. {
  273. t_Result = WBEM_E_FAILED;
  274. }
  275. else
  276. {
  277. try
  278. {
  279. s_HashTable = ::new WmiHashTable <CKeyEntry, ULONG, 12> ( *s_Allocator ) ;
  280. t_StatusCode = s_HashTable->Initialize () ;
  281. if ( t_StatusCode != e_StatusCode_Success )
  282. {
  283. Global_Shutdown();
  284. t_Result = WBEM_E_FAILED;
  285. }
  286. else
  287. {
  288. for (int x = 0; x < PING_KEY_PROPERTY_COUNT; x++)
  289. {
  290. CKeyEntry t_KeyEntry(s_KeyTable[x]);
  291. t_StatusCode = s_HashTable->Insert ( t_KeyEntry , x ) ;
  292. if ( t_StatusCode != e_StatusCode_Success )
  293. {
  294. Global_Shutdown();
  295. t_Result = WBEM_E_FAILED;
  296. break;
  297. }
  298. }
  299. if (SUCCEEDED(t_Result))
  300. {
  301. s_PingThread = ::new CPingThread( *s_Allocator ) ;
  302. s_PingThread->AddRef();
  303. t_StatusCode = s_PingThread->Initialize () ;
  304. if ( t_StatusCode != e_StatusCode_Success )
  305. {
  306. Global_Shutdown();
  307. t_Result = WBEM_E_FAILED;
  308. }
  309. }
  310. }
  311. }
  312. catch(...)
  313. {
  314. Global_Shutdown();
  315. throw;
  316. }
  317. }
  318. }
  319. }
  320. else
  321. {
  322. t_Result = WBEM_E_FAILED;
  323. }
  324. return t_Result ;
  325. }
  326. HRESULT CPingProvider :: Global_Shutdown ()
  327. {
  328. HRESULT t_Result = S_OK ;
  329. if (s_Allocator && s_PingThread )
  330. {
  331. try
  332. {
  333. if (s_PingThread != NULL)
  334. {
  335. if (s_PingThread->GetHandle ())
  336. {
  337. HANDLE t_ThreadHandle = NULL ;
  338. BOOL t_Status = DuplicateHandle (
  339. GetCurrentProcess () ,
  340. s_PingThread->GetHandle () ,
  341. GetCurrentProcess () ,
  342. & t_ThreadHandle,
  343. 0 ,
  344. FALSE ,
  345. DUPLICATE_SAME_ACCESS
  346. ) ;
  347. s_PingThread->Release();
  348. WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
  349. CloseHandle ( t_ThreadHandle ) ;
  350. }
  351. else
  352. {
  353. s_PingThread->Release();
  354. }
  355. }
  356. WmiStatusCode t_StatusCode = WmiThread <ULONG> :: Static_UnInitialize ( *s_Allocator ) ;
  357. }
  358. catch(...)
  359. {
  360. t_Result = WBEM_E_OUT_OF_MEMORY ;
  361. }
  362. s_PingThread = NULL;
  363. try
  364. {
  365. if (s_HashTable)
  366. {
  367. for (int x = 0; x < PING_KEY_PROPERTY_COUNT; x++)
  368. {
  369. CKeyEntry t_KeyEntry(s_KeyTable[x]);
  370. s_HashTable->Delete ( t_KeyEntry ) ;
  371. }
  372. s_HashTable->UnInitialize () ;
  373. ::delete s_HashTable;
  374. }
  375. }
  376. catch(...)
  377. {
  378. t_Result = WBEM_E_OUT_OF_MEMORY ;
  379. }
  380. s_HashTable = NULL;
  381. }
  382. return t_Result ;
  383. }
  384. //***************************************************************************
  385. //
  386. // CPingProvider ::QueryInterface
  387. // CPingProvider ::AddRef
  388. // CPingProvider ::Release
  389. //
  390. // Purpose: IUnknown members for CPingProvider object.
  391. //***************************************************************************
  392. STDMETHODIMP CPingProvider ::QueryInterface (
  393. REFIID iid ,
  394. LPVOID FAR *iplpv
  395. )
  396. {
  397. HRESULT t_hr = S_OK ;
  398. SetStructuredExceptionHandler seh;
  399. try
  400. {
  401. *iplpv = NULL ;
  402. if ( iid == IID_IUnknown )
  403. {
  404. *iplpv = ( LPVOID ) ( IWbemProviderInit * ) this ;
  405. }
  406. else if ( iid == IID_IWbemProviderInit )
  407. {
  408. *iplpv = ( LPVOID ) ( IWbemProviderInit * ) this ;
  409. }
  410. else if ( iid == IID_IWbemServices )
  411. {
  412. *iplpv = ( LPVOID ) ( IWbemServices * ) this ;
  413. }
  414. if ( *iplpv )
  415. {
  416. ( ( LPUNKNOWN ) *iplpv )->AddRef () ;
  417. }
  418. else
  419. {
  420. t_hr = E_NOINTERFACE ;
  421. }
  422. }
  423. catch(Structured_Exception e_SE)
  424. {
  425. t_hr = E_UNEXPECTED;
  426. }
  427. catch(Heap_Exception e_HE)
  428. {
  429. t_hr = E_OUTOFMEMORY;
  430. }
  431. catch(...)
  432. {
  433. t_hr = E_UNEXPECTED;
  434. }
  435. return t_hr;
  436. }
  437. STDMETHODIMP_(ULONG) CPingProvider ::AddRef(void)
  438. {
  439. SetStructuredExceptionHandler seh;
  440. try
  441. {
  442. return InterlockedIncrement ( & m_referenceCount ) ;
  443. }
  444. catch(Structured_Exception e_SE)
  445. {
  446. return 0;
  447. }
  448. catch(Heap_Exception e_HE)
  449. {
  450. return 0;
  451. }
  452. catch(...)
  453. {
  454. return 0;
  455. }
  456. }
  457. STDMETHODIMP_(ULONG) CPingProvider ::Release(void)
  458. {
  459. LONG t_Ref = 0;
  460. SetStructuredExceptionHandler seh;
  461. try
  462. {
  463. if ( ( t_Ref = InterlockedDecrement ( & m_referenceCount ) ) == 0 )
  464. {
  465. delete this ;
  466. return 0 ;
  467. }
  468. else
  469. {
  470. return t_Ref ;
  471. }
  472. }
  473. catch(Structured_Exception e_SE)
  474. {
  475. return 0;
  476. }
  477. catch(Heap_Exception e_HE)
  478. {
  479. return 0;
  480. }
  481. catch(...)
  482. {
  483. return 0;
  484. }
  485. }
  486. BOOL CPingProvider :: GetNotificationObject ( IWbemContext *a_Ctx , IWbemClassObject **a_ppObj )
  487. {
  488. *a_ppObj = NULL;
  489. if ( m_notificationClassObject == NULL )
  490. {
  491. CreateNotificationObject ( a_Ctx ) ;
  492. }
  493. if ( m_notificationClassObject != NULL )
  494. {
  495. if ( FAILED (m_notificationClassObject->SpawnInstance(0, a_ppObj)) )
  496. {
  497. *a_ppObj = NULL;
  498. }
  499. }
  500. return (*a_ppObj != NULL) ;
  501. }
  502. BOOL CPingProvider :: ImpersonateClient ( )
  503. {
  504. return SUCCEEDED(WbemCoImpersonateClient());
  505. }
  506. BOOL CPingProvider::GetClassObject (IWbemClassObject **a_ppClass )
  507. {
  508. BOOL t_RetVal = TRUE;
  509. if ((a_ppClass == NULL) || (m_ClassObject == NULL))
  510. {
  511. t_RetVal = FALSE;
  512. }
  513. else
  514. {
  515. *a_ppClass = m_ClassObject;
  516. (*a_ppClass)->AddRef();
  517. }
  518. return t_RetVal;
  519. }
  520. BOOL CPingProvider :: CreateNotificationObject (
  521. IWbemContext *a_Ctx
  522. )
  523. {
  524. BOOL t_Status = TRUE ;
  525. HRESULT t_Result = m_server->GetObject (
  526. WBEM_CLASS_EXTENDEDSTATUS ,
  527. 0 ,
  528. a_Ctx,
  529. & m_notificationClassObject ,
  530. NULL
  531. ) ;
  532. if ( ! SUCCEEDED ( t_Result ) )
  533. {
  534. t_Status = FALSE ;
  535. }
  536. return t_Status ;
  537. }
  538. /////////////////////////////////////////////////////////////////////////////
  539. // Functions for the IWbemServices interface that are handled here
  540. HRESULT CPingProvider ::OpenNamespace (
  541. BSTR ObjectPath,
  542. long lFlags,
  543. IWbemContext FAR* pCtx,
  544. IWbemServices FAR* FAR* ppNewContext,
  545. IWbemCallResult FAR* FAR* ppErrorObject
  546. )
  547. {
  548. return WBEM_E_NOT_SUPPORTED ;
  549. }
  550. HRESULT CPingProvider :: CancelAsyncCall (
  551. IWbemObjectSink __RPC_FAR *pSink
  552. )
  553. {
  554. return WBEM_E_NOT_SUPPORTED ;
  555. }
  556. HRESULT CPingProvider :: QueryObjectSink (
  557. long lFlags,
  558. IWbemObjectSink FAR* FAR* ppHandler
  559. )
  560. {
  561. return WBEM_E_NOT_SUPPORTED ;
  562. }
  563. HRESULT CPingProvider :: GetObject (
  564. BSTR ObjectPath,
  565. long lFlags,
  566. IWbemContext FAR *pCtx,
  567. IWbemClassObject FAR* FAR *ppObject,
  568. IWbemCallResult FAR* FAR *ppCallResult
  569. )
  570. {
  571. return WBEM_E_NOT_SUPPORTED ;
  572. }
  573. HRESULT CPingProvider :: GetObjectAsync (
  574. BSTR ObjectPath,
  575. long lFlags,
  576. IWbemContext FAR *pCtx,
  577. IWbemObjectSink FAR* pHandler
  578. )
  579. {
  580. HRESULT t_Result = S_OK ;
  581. SetStructuredExceptionHandler seh;
  582. try
  583. {
  584. if (ImpersonateClient())
  585. {
  586. //
  587. // auto CoRevertToSelf
  588. //
  589. ScopeGuard AutoCoRevertToSelf = MakeGuard ( CoRevertToSelf ) ;
  590. /*
  591. * Create Asynchronous GetObjectByPath object
  592. */
  593. WSADATA t_WsaData ;
  594. if (0 == WSAStartup (0x0101, & t_WsaData))
  595. {
  596. //
  597. // auto WSA cleanup
  598. //
  599. ON_BLOCK_EXIT ( WSACleanup ) ;
  600. CPingGetAsync *t_AsyncEvent = new CPingGetAsync ( this , ObjectPath , lFlags , pHandler , pCtx ) ;
  601. if (t_AsyncEvent->GetThreadToken())
  602. {
  603. t_AsyncEvent->GetObject();
  604. }
  605. else
  606. {
  607. // Note that ExecQuery will delete this for us.
  608. delete t_AsyncEvent;
  609. }
  610. }
  611. else
  612. {
  613. t_Result = WBEM_E_FAILED;
  614. }
  615. #ifdef _DBG
  616. //
  617. // test return value in checked build
  618. //
  619. AutoCoRevertToSelf.Dismiss () ;
  620. ASSERT ( S_OK == CoRevertToSelf() ) ;
  621. #endif _DBG
  622. }
  623. else
  624. {
  625. t_Result = WBEM_E_ACCESS_DENIED;
  626. }
  627. }
  628. catch(Structured_Exception e_SE)
  629. {
  630. t_Result = WBEM_E_UNEXPECTED;
  631. }
  632. catch(Heap_Exception e_HE)
  633. {
  634. t_Result = WBEM_E_OUT_OF_MEMORY;
  635. }
  636. catch(...)
  637. {
  638. t_Result = E_UNEXPECTED;
  639. }
  640. return t_Result ;
  641. }
  642. HRESULT CPingProvider :: PutClass (
  643. IWbemClassObject FAR* pClass ,
  644. long lFlags,
  645. IWbemContext FAR *pCtx,
  646. IWbemCallResult FAR* FAR* ppCallResult
  647. )
  648. {
  649. return WBEM_E_NOT_SUPPORTED ;
  650. }
  651. HRESULT CPingProvider :: PutClassAsync (
  652. IWbemClassObject FAR* pClass,
  653. long lFlags,
  654. IWbemContext FAR *pCtx,
  655. IWbemObjectSink FAR* pHandler
  656. )
  657. {
  658. return WBEM_E_NOT_SUPPORTED ;
  659. }
  660. HRESULT CPingProvider :: DeleteClass (
  661. BSTR Class,
  662. long lFlags,
  663. IWbemContext FAR *pCtx,
  664. IWbemCallResult FAR* FAR* ppCallResult
  665. )
  666. {
  667. return WBEM_E_NOT_SUPPORTED ;
  668. }
  669. HRESULT CPingProvider :: DeleteClassAsync (
  670. BSTR Class,
  671. long lFlags,
  672. IWbemContext FAR *pCtx,
  673. IWbemObjectSink FAR* pHandler
  674. )
  675. {
  676. return WBEM_E_NOT_SUPPORTED ;
  677. }
  678. HRESULT CPingProvider :: CreateClassEnum (
  679. BSTR Superclass,
  680. long lFlags,
  681. IWbemContext FAR *pCtx,
  682. IEnumWbemClassObject FAR *FAR *ppEnum
  683. )
  684. {
  685. return WBEM_E_NOT_SUPPORTED ;
  686. }
  687. SCODE CPingProvider :: CreateClassEnumAsync (
  688. BSTR Superclass,
  689. long lFlags,
  690. IWbemContext FAR* pCtx,
  691. IWbemObjectSink FAR* pHandler
  692. )
  693. {
  694. return WBEM_E_NOT_SUPPORTED ;
  695. }
  696. HRESULT CPingProvider :: PutInstance (
  697. IWbemClassObject FAR *pInstance,
  698. long lFlags,
  699. IWbemContext FAR *pCtx,
  700. IWbemCallResult FAR *FAR *ppCallResult
  701. )
  702. {
  703. return WBEM_E_NOT_SUPPORTED ;
  704. }
  705. HRESULT CPingProvider :: PutInstanceAsync (
  706. IWbemClassObject FAR* pInstance,
  707. long lFlags,
  708. IWbemContext FAR *pCtx,
  709. IWbemObjectSink FAR* pHandler
  710. )
  711. {
  712. return WBEM_E_NOT_SUPPORTED ;
  713. }
  714. HRESULT CPingProvider :: DeleteInstance (
  715. BSTR ObjectPath,
  716. long lFlags,
  717. IWbemContext FAR *pCtx,
  718. IWbemCallResult FAR *FAR *ppCallResult
  719. )
  720. {
  721. return WBEM_E_NOT_SUPPORTED ;
  722. }
  723. HRESULT CPingProvider :: DeleteInstanceAsync (
  724. BSTR ObjectPath,
  725. long lFlags,
  726. IWbemContext __RPC_FAR *pCtx,
  727. IWbemObjectSink __RPC_FAR *pHandler
  728. )
  729. {
  730. return WBEM_E_NOT_SUPPORTED ;
  731. }
  732. HRESULT CPingProvider :: CreateInstanceEnum (
  733. BSTR Class,
  734. long lFlags,
  735. IWbemContext FAR *pCtx,
  736. IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum
  737. )
  738. {
  739. return WBEM_E_NOT_SUPPORTED ;
  740. }
  741. HRESULT CPingProvider :: CreateInstanceEnumAsync (
  742. BSTR Class,
  743. long lFlags,
  744. IWbemContext __RPC_FAR *pCtx,
  745. IWbemObjectSink FAR* pHandler
  746. )
  747. {
  748. return WBEM_E_NOT_SUPPORTED ;
  749. }
  750. HRESULT CPingProvider :: ExecQuery (
  751. BSTR QueryLanguage,
  752. BSTR Query,
  753. long lFlags,
  754. IWbemContext FAR *pCtx,
  755. IEnumWbemClassObject FAR *FAR *ppEnum
  756. )
  757. {
  758. return WBEM_E_NOT_SUPPORTED ;
  759. }
  760. HRESULT CPingProvider :: ExecQueryAsync (
  761. BSTR QueryFormat,
  762. BSTR Query,
  763. long lFlags,
  764. IWbemContext FAR* pCtx,
  765. IWbemObjectSink FAR* pHandler
  766. )
  767. {
  768. HRESULT t_Result = S_OK ;
  769. SetStructuredExceptionHandler seh;
  770. try
  771. {
  772. if (ImpersonateClient())
  773. {
  774. //
  775. // auto CoRevertToSelf
  776. //
  777. ScopeGuard AutoCoRevertToSelf = MakeGuard ( CoRevertToSelf ) ;
  778. /*
  779. * Create Synchronous Query Instance object
  780. */
  781. WSADATA t_WsaData ;
  782. if (0 == WSAStartup (0x0101, & t_WsaData))
  783. {
  784. //
  785. // auto WSA cleanup
  786. //
  787. ON_BLOCK_EXIT ( WSACleanup ) ;
  788. CPingQueryAsync *t_AsyncEvent = new CPingQueryAsync ( this , QueryFormat , Query , lFlags , pHandler , pCtx ) ;
  789. if (t_AsyncEvent->GetThreadToken())
  790. {
  791. t_AsyncEvent->ExecQuery();
  792. }
  793. else
  794. {
  795. // Note that ExecQuery will delete this for us.
  796. delete t_AsyncEvent;
  797. }
  798. }
  799. else
  800. {
  801. t_Result = WBEM_E_FAILED;
  802. }
  803. #ifdef _DBG
  804. //
  805. // test return value in checked build
  806. //
  807. AutoCoRevertToSelf.Dismiss () ;
  808. ASSERT ( S_OK == CoRevertToSelf() ) ;
  809. #endif _DBG
  810. }
  811. else
  812. {
  813. t_Result = WBEM_E_ACCESS_DENIED;
  814. }
  815. }
  816. catch(Structured_Exception e_SE)
  817. {
  818. t_Result = WBEM_E_UNEXPECTED;
  819. }
  820. catch(Heap_Exception e_HE)
  821. {
  822. t_Result = WBEM_E_OUT_OF_MEMORY;
  823. }
  824. catch(...)
  825. {
  826. t_Result = WBEM_E_UNEXPECTED;
  827. }
  828. return t_Result ;
  829. }
  830. HRESULT CPingProvider :: ExecNotificationQuery (
  831. BSTR QueryLanguage,
  832. BSTR Query,
  833. long lFlags,
  834. IWbemContext __RPC_FAR *pCtx,
  835. IEnumWbemClassObject __RPC_FAR *__RPC_FAR *ppEnum
  836. )
  837. {
  838. return WBEM_E_NOT_SUPPORTED ;
  839. }
  840. HRESULT CPingProvider :: ExecNotificationQueryAsync (
  841. BSTR QueryLanguage,
  842. BSTR Query,
  843. long lFlags,
  844. IWbemContext __RPC_FAR *pCtx,
  845. IWbemObjectSink __RPC_FAR *pHandler
  846. )
  847. {
  848. return WBEM_E_NOT_SUPPORTED ;
  849. }
  850. HRESULT STDMETHODCALLTYPE CPingProvider :: ExecMethod (
  851. BSTR ObjectPath,
  852. BSTR MethodName,
  853. long lFlags,
  854. IWbemContext FAR *pCtx,
  855. IWbemClassObject FAR *pInParams,
  856. IWbemClassObject FAR *FAR *ppOutParams,
  857. IWbemCallResult FAR *FAR *ppCallResult
  858. )
  859. {
  860. return WBEM_E_NOT_SUPPORTED ;
  861. }
  862. HRESULT STDMETHODCALLTYPE CPingProvider :: ExecMethodAsync (
  863. BSTR ObjectPath,
  864. BSTR MethodName,
  865. long lFlags,
  866. IWbemContext FAR *pCtx,
  867. IWbemClassObject FAR *pInParams,
  868. IWbemObjectSink FAR *pResponseHandler
  869. )
  870. {
  871. return WBEM_E_NOT_SUPPORTED ;
  872. }
  873. HRESULT CPingProvider :: Initialize(
  874. LPWSTR pszUser,
  875. LONG lFlags,
  876. LPWSTR pszNamespace,
  877. LPWSTR pszLocale,
  878. IWbemServices *pCIMOM, // For anybody
  879. IWbemContext *pCtx,
  880. IWbemProviderInitSink *pInitSink // For init signals
  881. )
  882. {
  883. HRESULT t_result = S_OK;
  884. SetStructuredExceptionHandler seh;
  885. try
  886. {
  887. if ((pCIMOM == NULL) || (pCtx == NULL) || (pInitSink == NULL))
  888. {
  889. t_result = WBEM_E_FAILED;
  890. }
  891. if (SUCCEEDED(t_result))
  892. {
  893. CCritSecAutoUnlock t_lock( &s_CS ) ;
  894. try
  895. {
  896. t_result = Global_Startup ();
  897. if (SUCCEEDED(t_result))
  898. {
  899. if (!m_bInitial)
  900. {
  901. m_bInitial = TRUE;
  902. m_server = pCIMOM ;
  903. m_server->AddRef();
  904. IWbemClassObject *t_Object = NULL;
  905. if ( GetNotificationObject ( pCtx, &t_Object ) )
  906. {
  907. t_Object->Release () ;
  908. t_result = m_server->GetObject (
  909. PROVIDER_NAME_CPINGPROVIDER ,
  910. 0 ,
  911. pCtx,
  912. & m_ClassObject ,
  913. NULL
  914. ) ;
  915. if ( FAILED(t_result))
  916. {
  917. m_ClassObject = NULL ;
  918. t_result = WBEM_E_FAILED ;
  919. }
  920. }
  921. else
  922. {
  923. t_result = WBEM_E_FAILED ;
  924. }
  925. }
  926. }
  927. }
  928. catch (...)
  929. {
  930. t_result = WBEM_E_FAILED;
  931. }
  932. try
  933. {
  934. pInitSink->SetStatus ( SUCCEEDED(t_result) ? (LONG)WBEM_S_INITIALIZED : (LONG)WBEM_E_FAILED , 0 ) ;
  935. t_result = S_OK;
  936. }
  937. catch(...)
  938. {
  939. t_result = WBEM_E_FAILED;
  940. }
  941. }
  942. }
  943. catch(Structured_Exception e_SE)
  944. {
  945. t_result = WBEM_E_UNEXPECTED;
  946. }
  947. catch(Heap_Exception e_HE)
  948. {
  949. t_result = WBEM_E_OUT_OF_MEMORY;
  950. }
  951. catch(...)
  952. {
  953. t_result = WBEM_E_UNEXPECTED;
  954. }
  955. return t_result ;
  956. }