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.

2104 lines
49 KiB

  1. /******************************************************************
  2. pingquery.CPP
  3. Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  4. Description:
  5. ******************************************************************/
  6. #include <stdafx.h>
  7. #include <ntddtcp.h>
  8. #include <ipinfo.h>
  9. #include <tdiinfo.h>
  10. #include <winsock2.h>
  11. #include <provimex.h>
  12. #include <provexpt.h>
  13. #include <provtempl.h>
  14. #include <provmt.h>
  15. #include <typeinfo.h>
  16. #include <provcont.h>
  17. #include <provevt.h>
  18. #include <provthrd.h>
  19. #include <provlog.h>
  20. #include <provval.h>
  21. #include <provtype.h>
  22. #include <provtree.h>
  23. #include <provdnf.h>
  24. #include <winsock.h>
  25. #include "ipexport.h"
  26. #include "icmpapi.h"
  27. #include ".\res_str.h"
  28. #include <Allocator.h>
  29. #include <Thread.h>
  30. #include <HashTable.h>
  31. #include <PingProv.h>
  32. #include <Pingtask.h>
  33. #include <Pingfac.h>
  34. CPingQueryAsync::CPingQueryAsync (CPingProvider *a_Provider ,
  35. BSTR a_QueryFormat ,
  36. BSTR a_Query ,
  37. ULONG a_Flag ,
  38. IWbemObjectSink *a_NotificationHandler ,
  39. IWbemContext *a_Ctx
  40. ) : m_QueryFormat(NULL),
  41. m_Query(NULL),
  42. CPingTaskObject (a_Provider, a_NotificationHandler, a_Ctx)
  43. {
  44. if (a_QueryFormat != NULL)
  45. {
  46. int t_len = wcslen(a_QueryFormat);
  47. if (t_len > 0)
  48. {
  49. m_QueryFormat = new WCHAR[t_len+1];
  50. m_QueryFormat[t_len] = L'\0';
  51. wcsncpy(m_QueryFormat, a_QueryFormat, t_len);
  52. }
  53. }
  54. if (a_Query != NULL)
  55. {
  56. int t_len = wcslen(a_Query);
  57. if (t_len > 0)
  58. {
  59. m_Query = new WCHAR[t_len+1];
  60. m_Query[t_len] = L'\0';
  61. wcsncpy(m_Query, a_Query, t_len);
  62. }
  63. }
  64. }
  65. CPingQueryAsync::~CPingQueryAsync ()
  66. {
  67. if (m_Query != NULL)
  68. {
  69. delete [] m_Query ;
  70. }
  71. if (m_QueryFormat != NULL)
  72. {
  73. delete [] m_QueryFormat ;
  74. }
  75. }
  76. QueryPreprocessor :: QuadState CPingQueryAsync :: Compare (
  77. LONG a_Operand1 ,
  78. LONG a_Operand2 ,
  79. ULONG a_Operand1Func ,
  80. ULONG a_Operand2Func ,
  81. WmiTreeNode &a_OperatorType
  82. )
  83. {
  84. QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
  85. switch ( a_Operand1Func )
  86. {
  87. case WmiValueNode :: WmiValueFunction :: Function_None:
  88. {
  89. }
  90. break ;
  91. default:
  92. {
  93. }
  94. break ;
  95. }
  96. switch ( a_Operand2Func )
  97. {
  98. case WmiValueNode :: WmiValueFunction :: Function_None:
  99. {
  100. }
  101. break ;
  102. default:
  103. {
  104. }
  105. break ;
  106. }
  107. if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
  108. {
  109. t_Status = a_Operand1 == a_Operand2
  110. ? QueryPreprocessor :: QuadState :: State_True
  111. : QueryPreprocessor :: QuadState :: State_False ;
  112. }
  113. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
  114. {
  115. t_Status = a_Operand1 != a_Operand2
  116. ? QueryPreprocessor :: QuadState :: State_True
  117. : QueryPreprocessor :: QuadState :: State_False ;
  118. }
  119. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
  120. {
  121. t_Status = a_Operand1 >= a_Operand2
  122. ? QueryPreprocessor :: QuadState :: State_True
  123. : QueryPreprocessor :: QuadState :: State_False ;
  124. }
  125. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
  126. {
  127. t_Status = a_Operand1 <= a_Operand2
  128. ? QueryPreprocessor :: QuadState :: State_True
  129. : QueryPreprocessor :: QuadState :: State_False ;
  130. }
  131. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
  132. {
  133. t_Status = a_Operand1 < a_Operand2
  134. ? QueryPreprocessor :: QuadState :: State_True
  135. : QueryPreprocessor :: QuadState :: State_False ;
  136. }
  137. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
  138. {
  139. t_Status = a_Operand1 > a_Operand2
  140. ? QueryPreprocessor :: QuadState :: State_True
  141. : QueryPreprocessor :: QuadState :: State_False ;
  142. }
  143. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
  144. {
  145. }
  146. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
  147. {
  148. }
  149. return t_Status ;
  150. }
  151. QueryPreprocessor :: QuadState CPingQueryAsync :: Compare (
  152. wchar_t *a_Operand1 ,
  153. wchar_t *a_Operand2 ,
  154. ULONG a_Operand1Func ,
  155. ULONG a_Operand2Func ,
  156. WmiTreeNode &a_OperatorType
  157. )
  158. {
  159. QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
  160. wchar_t *a_Operand1AfterFunc = NULL ;
  161. wchar_t *a_Operand2AfterFunc = NULL ;
  162. switch ( a_Operand1Func )
  163. {
  164. case WmiValueNode :: WmiValueFunction :: Function_None:
  165. {
  166. }
  167. break ;
  168. case WmiValueNode :: WmiValueFunction :: Function_Upper:
  169. {
  170. ULONG length = wcslen ( a_Operand1 ) ;
  171. wchar_t *a_Operand1AfterFunc = new wchar_t [ length + 1 ] ;
  172. for ( ULONG index = 0 ; index < length ; index ++ )
  173. {
  174. a_Operand1AfterFunc [ index ] = towupper ( a_Operand1 [ index ] ) ;
  175. }
  176. }
  177. break ;
  178. case WmiValueNode :: WmiValueFunction :: Function_Lower:
  179. {
  180. ULONG length = wcslen ( a_Operand1 ) ;
  181. wchar_t *a_Operand1AfterFunc = new wchar_t [ length + 1 ] ;
  182. for ( ULONG index = 0 ; index < length ; index ++ )
  183. {
  184. a_Operand1AfterFunc [ index ] = towlower ( a_Operand1 [ index ] ) ;
  185. }
  186. }
  187. break ;
  188. default:
  189. {
  190. }
  191. break ;
  192. }
  193. switch ( a_Operand2Func )
  194. {
  195. case WmiValueNode :: WmiValueFunction :: Function_None:
  196. {
  197. }
  198. break ;
  199. case WmiValueNode :: WmiValueFunction :: Function_Upper:
  200. {
  201. ULONG length = wcslen ( a_Operand2 ) ;
  202. wchar_t *a_Operand2AfterFunc = new wchar_t [ length + 1 ] ;
  203. for ( ULONG index = 0 ; index < length ; index ++ )
  204. {
  205. a_Operand2AfterFunc [ index ] = towupper ( a_Operand2 [ index ] ) ;
  206. }
  207. }
  208. break ;
  209. case WmiValueNode :: WmiValueFunction :: Function_Lower:
  210. {
  211. ULONG length = wcslen ( a_Operand2 ) ;
  212. wchar_t *a_Operand2AfterFunc = new wchar_t [ length + 1 ] ;
  213. for ( ULONG index = 0 ; index < length ; index ++ )
  214. {
  215. a_Operand2AfterFunc [ index ] = towlower ( a_Operand2 [ index ] ) ;
  216. }
  217. }
  218. break ;
  219. default:
  220. {
  221. }
  222. break ;
  223. }
  224. const wchar_t *t_Arg1 = a_Operand1AfterFunc ? a_Operand1AfterFunc : a_Operand1 ;
  225. const wchar_t *t_Arg2 = a_Operand2AfterFunc ? a_Operand2AfterFunc : a_Operand2 ;
  226. if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
  227. {
  228. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  229. {
  230. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) == 0
  231. ? QueryPreprocessor :: QuadState :: State_True
  232. : QueryPreprocessor :: QuadState :: State_False ;
  233. }
  234. else
  235. {
  236. if ( ( t_Arg1 ) || ( t_Arg2 ) )
  237. {
  238. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  239. }
  240. else
  241. {
  242. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  243. }
  244. }
  245. }
  246. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
  247. {
  248. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  249. {
  250. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) != 0
  251. ? QueryPreprocessor :: QuadState :: State_True
  252. : QueryPreprocessor :: QuadState :: State_False ;
  253. }
  254. else
  255. {
  256. if ( ( t_Arg1 ) || ( t_Arg2 ) )
  257. {
  258. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  259. }
  260. else
  261. {
  262. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  263. }
  264. }
  265. }
  266. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
  267. {
  268. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  269. {
  270. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) >= 0
  271. ? QueryPreprocessor :: QuadState :: State_True
  272. : QueryPreprocessor :: QuadState :: State_False ;
  273. }
  274. else
  275. {
  276. if ( t_Arg1 )
  277. {
  278. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  279. }
  280. else
  281. {
  282. if ( t_Arg2 )
  283. {
  284. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  285. }
  286. else
  287. {
  288. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  289. }
  290. }
  291. }
  292. }
  293. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
  294. {
  295. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  296. {
  297. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) <= 0
  298. ? QueryPreprocessor :: QuadState :: State_True
  299. : QueryPreprocessor :: QuadState :: State_False ;
  300. }
  301. else
  302. {
  303. if ( ( t_Arg1 ) )
  304. {
  305. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  306. }
  307. else
  308. {
  309. if ( t_Arg2 )
  310. {
  311. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  312. }
  313. else
  314. {
  315. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  316. }
  317. }
  318. }
  319. }
  320. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
  321. {
  322. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  323. {
  324. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) < 0
  325. ? QueryPreprocessor :: QuadState :: State_True
  326. : QueryPreprocessor :: QuadState :: State_False ;
  327. }
  328. else
  329. {
  330. if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
  331. {
  332. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  333. }
  334. else if ( t_Arg1 )
  335. {
  336. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  337. }
  338. else
  339. {
  340. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  341. }
  342. }
  343. }
  344. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
  345. {
  346. if ( ( t_Arg1 ) && ( t_Arg2 ) )
  347. {
  348. t_Status = wcscmp ( t_Arg1 , t_Arg2 ) > 0
  349. ? QueryPreprocessor :: QuadState :: State_True
  350. : QueryPreprocessor :: QuadState :: State_False ;
  351. }
  352. else
  353. {
  354. if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
  355. {
  356. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  357. }
  358. else if ( t_Arg1 )
  359. {
  360. t_Status = QueryPreprocessor :: QuadState :: State_True ;
  361. }
  362. else
  363. {
  364. t_Status = QueryPreprocessor :: QuadState :: State_False ;
  365. }
  366. }
  367. }
  368. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
  369. {
  370. }
  371. else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
  372. {
  373. }
  374. delete [] a_Operand1AfterFunc ;
  375. delete [] a_Operand2AfterFunc ;
  376. return t_Status ;
  377. }
  378. QueryPreprocessor :: QuadState CPingQueryAsync :: CompareString (
  379. IWbemClassObject *a_ClassObject ,
  380. BSTR a_PropertyName ,
  381. WmiTreeNode *a_Operator ,
  382. WmiTreeNode *a_Operand
  383. )
  384. {
  385. QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
  386. WmiStringNode *t_StringNode = ( WmiStringNode * ) a_Operand ;
  387. VARIANT t_Variant ;
  388. VariantInit ( & t_Variant ) ;
  389. HRESULT t_Result = a_ClassObject->Get ( a_PropertyName , 0 , &t_Variant , NULL , NULL ) ;
  390. if ( SUCCEEDED ( t_Result ) )
  391. {
  392. t_Status = Compare (
  393. t_StringNode->GetValue () ,
  394. t_Variant.bstrVal ,
  395. t_StringNode->GetPropertyFunction () ,
  396. t_StringNode->GetConstantFunction () ,
  397. *a_Operator
  398. ) ;
  399. }
  400. VariantClear ( & t_Variant ) ;
  401. return t_Status ;
  402. }
  403. QueryPreprocessor :: QuadState CPingQueryAsync :: CompareInteger (
  404. IWbemClassObject *a_ClassObject ,
  405. BSTR a_PropertyName ,
  406. WmiTreeNode *a_Operator ,
  407. WmiTreeNode *a_Operand
  408. )
  409. {
  410. QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True ;
  411. WmiSignedIntegerNode *t_IntegerNode = ( WmiSignedIntegerNode * ) a_Operand ;
  412. VARIANT t_Variant ;
  413. VariantInit ( & t_Variant ) ;
  414. HRESULT t_Result = a_ClassObject->Get ( a_PropertyName , 0 , &t_Variant , NULL , NULL ) ;
  415. if ( SUCCEEDED ( t_Result ) )
  416. {
  417. t_Status = Compare (
  418. t_IntegerNode->GetValue () ,
  419. t_Variant.lVal ,
  420. t_IntegerNode->GetPropertyFunction () ,
  421. t_IntegerNode->GetConstantFunction () ,
  422. *a_Operator
  423. ) ;
  424. }
  425. VariantClear ( & t_Variant ) ;
  426. return t_Status ;
  427. }
  428. WmiTreeNode *CPingQueryAsync :: AllocTypeNode (
  429. void *a_Context ,
  430. BSTR a_PropertyName ,
  431. VARIANT &a_Variant ,
  432. WmiValueNode :: WmiValueFunction a_PropertyFunction ,
  433. WmiValueNode :: WmiValueFunction a_ConstantFunction ,
  434. WmiTreeNode *a_Parent
  435. )
  436. {
  437. WmiTreeNode *t_Node = NULL ;
  438. VARTYPE t_VarType = VT_NULL ;
  439. if ( *a_PropertyName == L'_' )
  440. {
  441. // System property
  442. if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_CLASS ) == 0 &&
  443. (V_VT(&a_Variant) == VT_BSTR))
  444. {
  445. t_Node = new WmiStringNode (
  446. a_PropertyName ,
  447. a_Variant.bstrVal ,
  448. a_PropertyFunction ,
  449. a_ConstantFunction ,
  450. 0xFFFFFFFF ,
  451. a_Parent
  452. ) ;
  453. }
  454. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_SUPERCLASS ) == 0 &&
  455. (V_VT(&a_Variant) == VT_BSTR))
  456. {
  457. t_Node = new WmiStringNode (
  458. a_PropertyName ,
  459. a_Variant.bstrVal ,
  460. a_PropertyFunction ,
  461. a_ConstantFunction ,
  462. 0xFFFFFFFF ,
  463. a_Parent
  464. ) ;
  465. }
  466. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_GENUS ) == 0 &&
  467. (V_VT(&a_Variant) == VT_I4))
  468. {
  469. t_Node = new WmiSignedIntegerNode (
  470. a_PropertyName ,
  471. a_Variant.lVal ,
  472. 0xFFFFFFFF ,
  473. a_Parent
  474. ) ;
  475. }
  476. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_SERVER ) == 0 &&
  477. (V_VT(&a_Variant) == VT_BSTR))
  478. {
  479. t_Node = new WmiStringNode (
  480. a_PropertyName ,
  481. a_Variant.bstrVal ,
  482. a_PropertyFunction ,
  483. a_ConstantFunction ,
  484. 0xFFFFFFFF ,
  485. a_Parent
  486. ) ;
  487. }
  488. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_NAMESPACE ) == 0 &&
  489. (V_VT(&a_Variant) == VT_BSTR))
  490. {
  491. t_Node = new WmiStringNode (
  492. a_PropertyName ,
  493. a_Variant.bstrVal ,
  494. a_PropertyFunction ,
  495. a_ConstantFunction ,
  496. 0xFFFFFFFF ,
  497. a_Parent
  498. ) ;
  499. }
  500. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 &&
  501. (V_VT(&a_Variant) == VT_I4))
  502. {
  503. t_Node = new WmiSignedIntegerNode (
  504. a_PropertyName ,
  505. a_Variant.lVal ,
  506. 0xFFFFFFFF ,
  507. a_Parent
  508. ) ;
  509. }
  510. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_DYNASTY ) == 0 &&
  511. (V_VT(&a_Variant) == VT_BSTR))
  512. {
  513. t_Node = new WmiStringNode (
  514. a_PropertyName ,
  515. a_Variant.bstrVal ,
  516. a_PropertyFunction ,
  517. a_ConstantFunction ,
  518. 0xFFFFFFFF ,
  519. a_Parent
  520. ) ;
  521. }
  522. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_RELPATH ) == 0 &&
  523. (V_VT(&a_Variant) == VT_BSTR))
  524. {
  525. t_Node = new WmiStringNode (
  526. a_PropertyName ,
  527. a_Variant.bstrVal ,
  528. a_PropertyFunction ,
  529. a_ConstantFunction ,
  530. 0xFFFFFFFF ,
  531. a_Parent
  532. ) ;
  533. }
  534. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_PATH ) == 0 &&
  535. (V_VT(&a_Variant) == VT_BSTR))
  536. {
  537. t_Node = new WmiStringNode (
  538. a_PropertyName ,
  539. a_Variant.bstrVal ,
  540. a_PropertyFunction ,
  541. a_ConstantFunction ,
  542. 0xFFFFFFFF ,
  543. a_Parent
  544. ) ;
  545. }
  546. else if ( _wcsicmp ( a_PropertyName , SYSTEM_PROPERTY_DERIVATION ) == 0 )
  547. {
  548. }
  549. }
  550. else
  551. {
  552. IWbemClassObject *t_Object = NULL ;
  553. HRESULT t_Result = GetClassObject ( &t_Object ) ? WBEM_S_NO_ERROR : WBEM_E_FAILED ;
  554. if ( SUCCEEDED ( t_Result ) )
  555. {
  556. CIMTYPE t_VarType ;
  557. long t_Flavour ;
  558. VARIANT t_Variant ;
  559. VariantInit ( & t_Variant ) ;
  560. t_Result = t_Object->Get (
  561. a_PropertyName ,
  562. 0 ,
  563. & t_Variant ,
  564. & t_VarType ,
  565. & t_Flavour
  566. );
  567. if ( SUCCEEDED ( t_Result ) )
  568. {
  569. if ( t_VarType & CIM_FLAG_ARRAY )
  570. {
  571. }
  572. else
  573. {
  574. switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
  575. {
  576. case CIM_BOOLEAN:
  577. {
  578. if(V_VT(&a_Variant) == VT_I4)
  579. {
  580. t_Node = new WmiSignedIntegerNode (
  581. a_PropertyName ,
  582. a_Variant.lVal ,
  583. GetPriority ( a_PropertyName ) ,
  584. a_Parent
  585. ) ;
  586. }
  587. else if (V_VT(&a_Variant) == VT_BOOL)
  588. {
  589. t_Node = new WmiSignedIntegerNode (
  590. a_PropertyName ,
  591. (a_Variant.lVal == VARIANT_FALSE) ? 0 : 1,
  592. GetPriority ( a_PropertyName ) ,
  593. a_Parent
  594. ) ;
  595. }
  596. else if (V_VT(&a_Variant) == VT_NULL)
  597. {
  598. t_Node = new WmiNullNode (
  599. a_PropertyName ,
  600. GetPriority ( a_PropertyName ) ,
  601. a_Parent
  602. );
  603. }
  604. }
  605. break ;
  606. case CIM_SINT8:
  607. case CIM_SINT16:
  608. case CIM_CHAR16:
  609. case CIM_SINT32:
  610. {
  611. if(V_VT(&a_Variant) == VT_I4)
  612. {
  613. t_Node = new WmiSignedIntegerNode (
  614. a_PropertyName ,
  615. a_Variant.lVal ,
  616. GetPriority ( a_PropertyName ) ,
  617. a_Parent
  618. ) ;
  619. }
  620. else if (V_VT(&a_Variant) == VT_NULL)
  621. {
  622. t_Node = new WmiNullNode (
  623. a_PropertyName ,
  624. GetPriority ( a_PropertyName ) ,
  625. a_Parent
  626. );
  627. }
  628. }
  629. break ;
  630. case CIM_UINT8:
  631. case CIM_UINT16:
  632. case CIM_UINT32:
  633. {
  634. if(V_VT(&a_Variant) == VT_I4)
  635. {
  636. t_Node = new WmiUnsignedIntegerNode (
  637. a_PropertyName ,
  638. a_Variant.lVal ,
  639. GetPriority ( a_PropertyName ) ,
  640. a_Parent
  641. ) ;
  642. }
  643. else if (V_VT(&a_Variant) == VT_NULL)
  644. {
  645. t_Node = new WmiNullNode (
  646. a_PropertyName ,
  647. GetPriority ( a_PropertyName ) ,
  648. a_Parent
  649. );
  650. }
  651. }
  652. break ;
  653. case CIM_SINT64:
  654. case CIM_UINT64:
  655. {
  656. if(V_VT(&a_Variant) == VT_BSTR)
  657. {
  658. t_Node = new WmiStringNode (
  659. a_PropertyName ,
  660. a_Variant.bstrVal ,
  661. a_PropertyFunction ,
  662. a_ConstantFunction ,
  663. GetPriority ( a_PropertyName ) ,
  664. a_Parent
  665. ) ;
  666. }
  667. else if(V_VT(&a_Variant) == VT_I4)
  668. {
  669. _variant_t t_uintBuff (&a_Variant);
  670. t_Node = new WmiStringNode (
  671. a_PropertyName ,
  672. (BSTR)((_bstr_t) t_uintBuff),
  673. a_PropertyFunction ,
  674. a_ConstantFunction ,
  675. GetPriority ( a_PropertyName ) ,
  676. a_Parent
  677. ) ;
  678. }
  679. else if (V_VT(&a_Variant) == VT_NULL)
  680. {
  681. t_Node = new WmiNullNode (
  682. a_PropertyName ,
  683. GetPriority ( a_PropertyName ) ,
  684. a_Parent
  685. );
  686. }
  687. }
  688. break ;
  689. case CIM_STRING:
  690. case CIM_DATETIME:
  691. case CIM_REFERENCE:
  692. {
  693. if(V_VT(&a_Variant) == VT_BSTR)
  694. {
  695. t_Node = new WmiStringNode (
  696. a_PropertyName ,
  697. a_Variant.bstrVal ,
  698. a_PropertyFunction ,
  699. a_ConstantFunction ,
  700. GetPriority ( a_PropertyName ) ,
  701. a_Parent
  702. ) ;
  703. }
  704. else if (V_VT(&a_Variant) == VT_NULL)
  705. {
  706. t_Node = new WmiNullNode (
  707. a_PropertyName ,
  708. GetPriority ( a_PropertyName ) ,
  709. a_Parent
  710. );
  711. }
  712. }
  713. break ;
  714. case CIM_REAL32:
  715. case CIM_REAL64:
  716. {
  717. }
  718. break ;
  719. case CIM_OBJECT:
  720. case CIM_EMPTY:
  721. {
  722. }
  723. break ;
  724. default:
  725. {
  726. }
  727. break ;
  728. }
  729. }
  730. }
  731. t_Object->Release () ;
  732. VariantClear ( & t_Variant ) ;
  733. }
  734. }
  735. return t_Node ;
  736. }
  737. QueryPreprocessor :: QuadState CPingQueryAsync :: InvariantEvaluate (
  738. void *a_Context ,
  739. WmiTreeNode *a_Operator ,
  740. WmiTreeNode *a_Operand
  741. )
  742. {
  743. /*
  744. * If property and value are invariant i.e. will never change for all instances then return State_True.
  745. * If property is not indexable or keyed then return State_True to define an unknown number of possible values which we cannot optimise against.
  746. * If property and value can never occur then return State_False to imply empty set
  747. * If property and value do not infer anything then return State_Undefined.
  748. * If property and value are in error then return State_Error
  749. * Never return State_ReEvaluate.
  750. */
  751. QueryPreprocessor :: QuadState t_State = QueryPreprocessor :: QuadState :: State_Error ;
  752. IWbemClassObject *t_Object = NULL ;
  753. HRESULT t_Result = GetClassObject ( &t_Object ) ? WBEM_S_NO_ERROR : WBEM_E_FAILED ;
  754. if ( SUCCEEDED ( t_Result ) )
  755. {
  756. WmiValueNode *t_Node = ( WmiValueNode * ) a_Operand ;
  757. BSTR t_PropertyName = t_Node->GetPropertyName () ;
  758. if ( t_PropertyName != NULL )
  759. {
  760. if ( *t_PropertyName == L'_' )
  761. {
  762. // System property, must check values
  763. if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_CLASS ) == 0 )
  764. {
  765. t_State = CompareString (
  766. t_Object ,
  767. SYSTEM_PROPERTY_CLASS ,
  768. a_Operator ,
  769. a_Operand
  770. ) ;
  771. }
  772. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_SUPERCLASS ) == 0 )
  773. {
  774. t_State = CompareString (
  775. t_Object ,
  776. SYSTEM_PROPERTY_SUPERCLASS ,
  777. a_Operator ,
  778. a_Operand
  779. ) ;
  780. }
  781. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_GENUS ) == 0 )
  782. {
  783. t_State = CompareInteger (
  784. t_Object ,
  785. SYSTEM_PROPERTY_GENUS ,
  786. a_Operator ,
  787. a_Operand
  788. ) ;
  789. }
  790. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_SERVER ) == 0 )
  791. {
  792. t_State = CompareString (
  793. t_Object ,
  794. SYSTEM_PROPERTY_SERVER ,
  795. a_Operator ,
  796. a_Operand
  797. ) ;
  798. }
  799. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_NAMESPACE ) == 0 )
  800. {
  801. t_State = CompareString (
  802. t_Object ,
  803. SYSTEM_PROPERTY_NAMESPACE ,
  804. a_Operator ,
  805. a_Operand
  806. ) ;
  807. }
  808. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 )
  809. {
  810. t_State = CompareInteger (
  811. t_Object ,
  812. SYSTEM_PROPERTY_PROPERTY_COUNT ,
  813. a_Operator ,
  814. a_Operand
  815. ) ;
  816. }
  817. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_DYNASTY ) == 0 )
  818. {
  819. t_State = CompareString (
  820. t_Object ,
  821. SYSTEM_PROPERTY_DYNASTY ,
  822. a_Operator ,
  823. a_Operand
  824. ) ;
  825. }
  826. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_RELPATH ) == 0 )
  827. {
  828. t_State = CompareString (
  829. t_Object ,
  830. SYSTEM_PROPERTY_RELPATH ,
  831. a_Operator ,
  832. a_Operand
  833. ) ;
  834. }
  835. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_PATH ) == 0 )
  836. {
  837. t_State = CompareString (
  838. t_Object ,
  839. SYSTEM_PROPERTY_PATH ,
  840. a_Operator ,
  841. a_Operand
  842. ) ;
  843. }
  844. else if ( _wcsicmp ( t_PropertyName , SYSTEM_PROPERTY_DERIVATION ) == 0 )
  845. {
  846. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  847. }
  848. else
  849. {
  850. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  851. }
  852. }
  853. else
  854. {
  855. if ( typeid ( *a_Operand ) == typeid ( WmiNullNode ) )
  856. {
  857. t_State = QueryPreprocessor :: QuadState :: State_True ;
  858. }
  859. else
  860. {
  861. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  862. }
  863. #if 0
  864. else if ( typeid ( *a_Operand ) == typeid ( WmiStringNode ) )
  865. {
  866. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  867. }
  868. else if ( typeid ( *a_Operand ) == typeid ( WmiUnsignedIntegerNode ) )
  869. {
  870. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  871. }
  872. else if ( typeid ( *a_Operand ) == typeid ( WmiSignedIntegerNode ) )
  873. {
  874. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  875. }
  876. if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualNode ) )
  877. {
  878. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  879. }
  880. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorNotEqualNode ) )
  881. {
  882. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  883. }
  884. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
  885. {
  886. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  887. }
  888. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrLessNode ) )
  889. {
  890. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  891. }
  892. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorLessNode ) )
  893. {
  894. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  895. }
  896. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorGreaterNode ) )
  897. {
  898. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  899. }
  900. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorLikeNode ) )
  901. {
  902. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  903. }
  904. else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorNotLikeNode ) )
  905. {
  906. t_State = QueryPreprocessor :: QuadState :: State_Undefined ;
  907. }
  908. #endif
  909. }
  910. }
  911. else
  912. {
  913. t_State = QueryPreprocessor :: QuadState :: State_Undefined;
  914. }
  915. t_Object->Release () ;
  916. }
  917. return t_State ;
  918. }
  919. WmiRangeNode *CPingQueryAsync :: AllocInfiniteRangeNode (
  920. void *a_Context ,
  921. BSTR a_PropertyName
  922. )
  923. {
  924. WmiRangeNode *t_RangeNode = NULL ;
  925. IWbemClassObject *t_Object = NULL ;
  926. HRESULT t_Result = GetClassObject ( &t_Object ) ? WBEM_S_NO_ERROR : WBEM_E_FAILED ;
  927. if ( SUCCEEDED ( t_Result ) )
  928. {
  929. CIMTYPE t_VarType ;
  930. long t_Flavour ;
  931. VARIANT t_Variant ;
  932. VariantInit ( & t_Variant ) ;
  933. HRESULT t_Result = t_Object->Get (
  934. a_PropertyName ,
  935. 0 ,
  936. & t_Variant ,
  937. & t_VarType ,
  938. & t_Flavour
  939. );
  940. if ( SUCCEEDED ( t_Result ) )
  941. {
  942. if ( t_VarType & CIM_FLAG_ARRAY )
  943. {
  944. }
  945. else
  946. {
  947. switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
  948. {
  949. case CIM_BOOLEAN:
  950. case CIM_SINT8:
  951. case CIM_SINT16:
  952. case CIM_CHAR16:
  953. case CIM_SINT32:
  954. {
  955. t_RangeNode = new WmiSignedIntegerRangeNode (
  956. a_PropertyName ,
  957. 0xFFFFFFFF ,
  958. TRUE ,
  959. TRUE ,
  960. FALSE ,
  961. FALSE ,
  962. 0 ,
  963. 0 ,
  964. NULL ,
  965. NULL
  966. ) ;
  967. }
  968. break ;
  969. case CIM_UINT8:
  970. case CIM_UINT16:
  971. case CIM_UINT32:
  972. {
  973. t_RangeNode = new WmiUnsignedIntegerRangeNode (
  974. a_PropertyName ,
  975. 0xFFFFFFFF ,
  976. TRUE ,
  977. TRUE ,
  978. FALSE ,
  979. FALSE ,
  980. 0 ,
  981. 0 ,
  982. NULL ,
  983. NULL
  984. ) ;
  985. }
  986. break ;
  987. case CIM_SINT64:
  988. case CIM_UINT64:
  989. case CIM_STRING:
  990. case CIM_DATETIME:
  991. case CIM_REFERENCE:
  992. {
  993. t_RangeNode = new WmiStringRangeNode (
  994. a_PropertyName ,
  995. 0x0 ,
  996. TRUE ,
  997. TRUE ,
  998. FALSE ,
  999. FALSE ,
  1000. NULL ,
  1001. NULL ,
  1002. NULL ,
  1003. NULL
  1004. ) ;
  1005. }
  1006. break ;
  1007. case CIM_REAL32:
  1008. case CIM_REAL64:
  1009. {
  1010. }
  1011. break ;
  1012. case CIM_OBJECT:
  1013. case CIM_EMPTY:
  1014. {
  1015. }
  1016. break ;
  1017. default:
  1018. {
  1019. }
  1020. break ;
  1021. }
  1022. }
  1023. }
  1024. t_Object->Release () ;
  1025. VariantClear ( & t_Variant ) ;
  1026. }
  1027. return t_RangeNode ;
  1028. }
  1029. ULONG CPingQueryAsync :: GetPriority ( BSTR a_PropertyName )
  1030. {
  1031. if ( _wcsicmp ( a_PropertyName , Ping_Address ) == 0 )
  1032. {
  1033. return 0 ;
  1034. }
  1035. if ( _wcsicmp ( a_PropertyName , Ping_Timeout ) == 0 )
  1036. {
  1037. return 1 ;
  1038. }
  1039. if ( _wcsicmp ( a_PropertyName , Ping_TimeToLive ) == 0 )
  1040. {
  1041. return 2 ;
  1042. }
  1043. if ( _wcsicmp ( a_PropertyName , Ping_BufferSize ) == 0 )
  1044. {
  1045. return 3 ;
  1046. }
  1047. if ( _wcsicmp ( a_PropertyName , Ping_NoFragmentation ) == 0 )
  1048. {
  1049. return 4 ;
  1050. }
  1051. if ( _wcsicmp ( a_PropertyName , Ping_TypeofService ) == 0 )
  1052. {
  1053. return 5 ;
  1054. }
  1055. if ( _wcsicmp ( a_PropertyName , Ping_RecordRoute ) == 0 )
  1056. {
  1057. return 6 ;
  1058. }
  1059. if ( _wcsicmp ( a_PropertyName , Ping_TimestampRoute ) == 0 )
  1060. {
  1061. return 7 ;
  1062. }
  1063. if ( _wcsicmp ( a_PropertyName , Ping_SourceRouteType ) == 0 )
  1064. {
  1065. return 8 ;
  1066. }
  1067. if ( _wcsicmp ( a_PropertyName , Ping_SourceRoute ) == 0 )
  1068. {
  1069. return 9 ;
  1070. }
  1071. if ( _wcsicmp ( a_PropertyName , Ping_ResolveAddressNames ) == 0 )
  1072. {
  1073. return 10 ;
  1074. }
  1075. return 0xFFFFFFFF ;
  1076. }
  1077. HRESULT CPingQueryAsync :: RecurseAddress (
  1078. void *pMethodContext,
  1079. PartitionSet *a_PartitionSet
  1080. )
  1081. {
  1082. HRESULT t_Result = WBEM_E_FAILED ;
  1083. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1084. if (t_PartitionCount == 0)
  1085. {
  1086. t_Result = S_OK ;
  1087. }
  1088. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1089. {
  1090. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1091. WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_PropertyPartition->GetRange () ;
  1092. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1093. ! t_Node->InfiniteUpperBound () &&
  1094. t_Node->ClosedLowerBound () &&
  1095. t_Node->ClosedUpperBound () &&
  1096. ( wcscmp ( t_Node->LowerBound () , t_Node->UpperBound () ) == 0 ) ;
  1097. if ( ! t_Unique )
  1098. {
  1099. SetErrorInfo(IDS_QUERY_ADDR,
  1100. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1101. break ;
  1102. }
  1103. else
  1104. {
  1105. ULONG t_Address = 0 ;
  1106. ULONG t_ResolveErr = 0 ;
  1107. if ( FAILED ( Icmp_ResolveAddress ( t_Node->LowerBound () , t_Address , &t_ResolveErr ) ) && (t_ResolveErr == 0))
  1108. {
  1109. t_ResolveErr = WSAHOST_NOT_FOUND;
  1110. }
  1111. //if even one call succeeds return success
  1112. if (SUCCEEDED( RecurseTimeOut (pMethodContext ,
  1113. t_Node->LowerBound () ,
  1114. t_Address,
  1115. t_PropertyPartition,
  1116. t_ResolveErr)
  1117. && FAILED (t_Result) ) )
  1118. {
  1119. t_Result = S_OK;
  1120. }
  1121. }
  1122. }
  1123. return t_Result ;
  1124. }
  1125. HRESULT CPingQueryAsync :: RecurseTimeOut (
  1126. void *pMethodContext,
  1127. wchar_t *a_AddressString ,
  1128. ULONG a_Address ,
  1129. PartitionSet *a_PartitionSet ,
  1130. ULONG a_ResolveError
  1131. )
  1132. {
  1133. HRESULT t_Result = WBEM_E_FAILED ;
  1134. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1135. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1136. {
  1137. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1138. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1139. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1140. ! t_Node->InfiniteUpperBound () &&
  1141. t_Node->ClosedLowerBound () &&
  1142. t_Node->ClosedUpperBound () &&
  1143. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1144. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1145. if ( ! t_Unique && ! t_UnSpecified )
  1146. {
  1147. SetErrorInfo(IDS_QUERY_TO,
  1148. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1149. break ;
  1150. }
  1151. else
  1152. {
  1153. t_Result = RecurseTimeToLive (
  1154. pMethodContext,
  1155. a_AddressString ,
  1156. a_Address ,
  1157. t_UnSpecified ? DEFAULT_TIMEOUT : t_Node->LowerBound () ,
  1158. t_PropertyPartition ,
  1159. a_ResolveError
  1160. ) ;
  1161. }
  1162. }
  1163. return t_Result ;
  1164. }
  1165. HRESULT CPingQueryAsync :: RecurseTimeToLive (
  1166. void *pMethodContext,
  1167. wchar_t *a_AddressString ,
  1168. ULONG a_Address ,
  1169. ULONG a_TimeOut ,
  1170. PartitionSet *a_PartitionSet,
  1171. ULONG a_ResolveError
  1172. )
  1173. {
  1174. HRESULT t_Result = WBEM_E_FAILED ;
  1175. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1176. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1177. {
  1178. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1179. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1180. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1181. ! t_Node->InfiniteUpperBound () &&
  1182. t_Node->ClosedLowerBound () &&
  1183. t_Node->ClosedUpperBound () &&
  1184. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1185. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1186. if ( ! t_Unique && ! t_UnSpecified )
  1187. {
  1188. SetErrorInfo(IDS_QUERY_TTL,
  1189. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1190. break ;
  1191. }
  1192. else
  1193. {
  1194. t_Result = RecurseBufferSize (
  1195. pMethodContext,
  1196. a_AddressString ,
  1197. a_Address ,
  1198. a_TimeOut ,
  1199. t_UnSpecified ? DEFAULT_TTL : t_Node->LowerBound () ,
  1200. t_PropertyPartition ,
  1201. a_ResolveError
  1202. ) ;
  1203. }
  1204. }
  1205. return t_Result ;
  1206. }
  1207. HRESULT CPingQueryAsync :: RecurseBufferSize (
  1208. void *pMethodContext,
  1209. wchar_t *a_AddressString ,
  1210. ULONG a_Address ,
  1211. ULONG a_TimeOut ,
  1212. ULONG a_TimeToLive ,
  1213. PartitionSet *a_PartitionSet,
  1214. ULONG a_ResolveError
  1215. )
  1216. {
  1217. HRESULT t_Result = WBEM_E_FAILED ;
  1218. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1219. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1220. {
  1221. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1222. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1223. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1224. ! t_Node->InfiniteUpperBound () &&
  1225. t_Node->ClosedLowerBound () &&
  1226. t_Node->ClosedUpperBound () &&
  1227. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1228. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1229. if ( ! t_Unique && ! t_UnSpecified )
  1230. {
  1231. SetErrorInfo(IDS_QUERY_BUF,
  1232. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1233. break ;
  1234. }
  1235. else
  1236. {
  1237. if ( t_UnSpecified == FALSE && ( t_Node->LowerBound () > 65500 ) )
  1238. {
  1239. SetErrorInfo(IDS_BUFFSIZE_VALUE,WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1240. break ;
  1241. }
  1242. t_Result = RecurseNoFragmentation (
  1243. pMethodContext,
  1244. a_AddressString ,
  1245. a_Address ,
  1246. a_TimeOut ,
  1247. a_TimeToLive,
  1248. t_UnSpecified ? DEFAULT_SEND_SIZE : t_Node->LowerBound () ,
  1249. t_PropertyPartition,
  1250. a_ResolveError
  1251. ) ;
  1252. }
  1253. }
  1254. return t_Result ;
  1255. }
  1256. HRESULT CPingQueryAsync :: RecurseNoFragmentation (
  1257. void *pMethodContext,
  1258. wchar_t *a_AddressString ,
  1259. ULONG a_Address ,
  1260. ULONG a_TimeOut ,
  1261. ULONG a_TimeToLive,
  1262. ULONG a_SendSize,
  1263. PartitionSet *a_PartitionSet,
  1264. ULONG a_ResolveError
  1265. )
  1266. {
  1267. HRESULT t_Result = WBEM_E_FAILED ;
  1268. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1269. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1270. {
  1271. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1272. WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1273. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1274. ! t_Node->InfiniteUpperBound () &&
  1275. t_Node->ClosedLowerBound () &&
  1276. t_Node->ClosedUpperBound () &&
  1277. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1278. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1279. if ( ! t_Unique && ! t_UnSpecified )
  1280. {
  1281. SetErrorInfo(IDS_QUERY_NOFRAG,
  1282. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1283. break ;
  1284. }
  1285. else
  1286. {
  1287. t_Result = RecurseTypeOfService (
  1288. pMethodContext,
  1289. a_AddressString ,
  1290. a_Address ,
  1291. a_TimeOut ,
  1292. a_TimeToLive,
  1293. a_SendSize,
  1294. t_UnSpecified ? FALSE : t_Node->LowerBound () ,
  1295. t_PropertyPartition,
  1296. a_ResolveError
  1297. ) ;
  1298. }
  1299. }
  1300. return t_Result ;
  1301. }
  1302. HRESULT CPingQueryAsync :: RecurseTypeOfService (
  1303. void *pMethodContext,
  1304. wchar_t *a_AddressString ,
  1305. ULONG a_Address ,
  1306. ULONG a_TimeOut ,
  1307. ULONG a_TimeToLive,
  1308. ULONG a_SendSize,
  1309. BOOL a_NoFragmentation ,
  1310. PartitionSet *a_PartitionSet,
  1311. ULONG a_ResolveError
  1312. )
  1313. {
  1314. HRESULT t_Result = WBEM_E_FAILED ;
  1315. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1316. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1317. {
  1318. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1319. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1320. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1321. ! t_Node->InfiniteUpperBound () &&
  1322. t_Node->ClosedLowerBound () &&
  1323. t_Node->ClosedUpperBound () &&
  1324. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1325. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1326. if ( ! t_Unique && ! t_UnSpecified )
  1327. {
  1328. SetErrorInfo(IDS_QUERY_TOS,
  1329. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1330. break ;
  1331. }
  1332. else
  1333. {
  1334. t_Result = RecurseRecordRoute (
  1335. pMethodContext,
  1336. a_AddressString ,
  1337. a_Address ,
  1338. a_TimeOut ,
  1339. a_TimeToLive,
  1340. a_SendSize,
  1341. a_NoFragmentation ,
  1342. t_UnSpecified ? 0 : t_Node->LowerBound () ,
  1343. t_PropertyPartition,
  1344. a_ResolveError
  1345. ) ;
  1346. }
  1347. }
  1348. return t_Result ;
  1349. }
  1350. HRESULT CPingQueryAsync :: RecurseRecordRoute (
  1351. void *pMethodContext,
  1352. wchar_t *a_AddressString ,
  1353. ULONG a_Address ,
  1354. ULONG a_TimeOut ,
  1355. ULONG a_TimeToLive,
  1356. ULONG a_SendSize,
  1357. BOOL a_NoFragmentation ,
  1358. ULONG a_TypeOfService,
  1359. PartitionSet *a_PartitionSet,
  1360. ULONG a_ResolveError
  1361. )
  1362. {
  1363. HRESULT t_Result = WBEM_E_FAILED ;
  1364. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1365. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1366. {
  1367. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1368. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1369. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1370. ! t_Node->InfiniteUpperBound () &&
  1371. t_Node->ClosedLowerBound () &&
  1372. t_Node->ClosedUpperBound () &&
  1373. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1374. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1375. if ( ! t_Unique && ! t_UnSpecified )
  1376. {
  1377. SetErrorInfo(IDS_QUERY_RR,
  1378. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1379. break ;
  1380. }
  1381. else
  1382. {
  1383. t_Result = RecurseTimestampRoute (
  1384. pMethodContext,
  1385. a_AddressString ,
  1386. a_Address ,
  1387. a_TimeOut ,
  1388. a_TimeToLive,
  1389. a_SendSize,
  1390. a_NoFragmentation ,
  1391. a_TypeOfService ,
  1392. t_UnSpecified ? 0 : t_Node->LowerBound () ,
  1393. t_PropertyPartition,
  1394. a_ResolveError
  1395. ) ;
  1396. }
  1397. }
  1398. return t_Result ;
  1399. }
  1400. HRESULT CPingQueryAsync :: RecurseTimestampRoute (
  1401. void *pMethodContext,
  1402. wchar_t *a_AddressString ,
  1403. ULONG a_Address ,
  1404. ULONG a_TimeOut ,
  1405. ULONG a_TimeToLive,
  1406. ULONG a_SendSize,
  1407. BOOL a_NoFragmentation ,
  1408. ULONG a_TypeOfService,
  1409. ULONG a_RecordRoute,
  1410. PartitionSet *a_PartitionSet,
  1411. ULONG a_ResolveError
  1412. )
  1413. {
  1414. HRESULT t_Result = WBEM_E_FAILED ;
  1415. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1416. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1417. {
  1418. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1419. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1420. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1421. ! t_Node->InfiniteUpperBound () &&
  1422. t_Node->ClosedLowerBound () &&
  1423. t_Node->ClosedUpperBound () &&
  1424. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1425. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1426. if ( ! t_Unique && ! t_UnSpecified )
  1427. {
  1428. SetErrorInfo(IDS_QUERY_TS,
  1429. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1430. break ;
  1431. }
  1432. else
  1433. {
  1434. t_Result = RecurseSourceRouteType (
  1435. pMethodContext,
  1436. a_AddressString ,
  1437. a_Address ,
  1438. a_TimeOut ,
  1439. a_TimeToLive,
  1440. a_SendSize,
  1441. a_NoFragmentation ,
  1442. a_TypeOfService,
  1443. a_RecordRoute,
  1444. t_UnSpecified ? 0 : t_Node->LowerBound () ,
  1445. t_PropertyPartition,
  1446. a_ResolveError
  1447. ) ;
  1448. }
  1449. }
  1450. return t_Result ;
  1451. }
  1452. HRESULT CPingQueryAsync :: RecurseSourceRouteType (
  1453. void *pMethodContext,
  1454. wchar_t *a_AddressString ,
  1455. ULONG a_Address ,
  1456. ULONG a_TimeOut ,
  1457. ULONG a_TimeToLive,
  1458. ULONG a_SendSize,
  1459. BOOL a_NoFragmentation ,
  1460. ULONG a_TypeOfService,
  1461. ULONG a_RecordRoute,
  1462. ULONG a_TimestampRoute,
  1463. PartitionSet *a_PartitionSet,
  1464. ULONG a_ResolveError
  1465. )
  1466. {
  1467. HRESULT t_Result = WBEM_E_FAILED ;
  1468. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1469. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1470. {
  1471. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1472. WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1473. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1474. ! t_Node->InfiniteUpperBound () &&
  1475. t_Node->ClosedLowerBound () &&
  1476. t_Node->ClosedUpperBound () &&
  1477. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1478. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1479. if ( ! t_Unique && ! t_UnSpecified )
  1480. {
  1481. SetErrorInfo(IDS_QUERY_SRT,
  1482. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1483. break ;
  1484. }
  1485. else
  1486. {
  1487. t_Result = RecurseSourceRoute (
  1488. pMethodContext,
  1489. a_AddressString ,
  1490. a_Address ,
  1491. a_TimeOut ,
  1492. a_TimeToLive,
  1493. a_SendSize,
  1494. a_NoFragmentation ,
  1495. a_TypeOfService,
  1496. a_RecordRoute,
  1497. a_TimestampRoute,
  1498. t_UnSpecified ? 0 : t_Node->LowerBound () ,
  1499. t_PropertyPartition,
  1500. a_ResolveError
  1501. ) ;
  1502. }
  1503. }
  1504. return t_Result ;
  1505. }
  1506. HRESULT CPingQueryAsync :: RecurseSourceRoute (
  1507. void *pMethodContext,
  1508. wchar_t *a_AddressString ,
  1509. ULONG a_Address ,
  1510. ULONG a_TimeOut ,
  1511. ULONG a_TimeToLive,
  1512. ULONG a_SendSize,
  1513. BOOL a_NoFragmentation ,
  1514. ULONG a_TypeOfService,
  1515. ULONG a_RecordRoute,
  1516. ULONG a_TimestampRoute,
  1517. ULONG a_SourceRouteType,
  1518. PartitionSet *a_PartitionSet,
  1519. ULONG a_ResolveError
  1520. )
  1521. {
  1522. HRESULT t_Result = WBEM_E_FAILED ;
  1523. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1524. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1525. {
  1526. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1527. WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_PropertyPartition->GetRange () ;
  1528. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1529. ! t_Node->InfiniteUpperBound () &&
  1530. t_Node->ClosedLowerBound () &&
  1531. t_Node->ClosedUpperBound () &&
  1532. ( wcscmp ( t_Node->LowerBound () , t_Node->UpperBound () ) == 0 ) ;
  1533. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1534. if ( ! t_Unique && ! t_UnSpecified )
  1535. {
  1536. SetErrorInfo(IDS_QUERY_SR,
  1537. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1538. break ;
  1539. }
  1540. else
  1541. {
  1542. t_Result = RecurseResolveAddressNames (
  1543. pMethodContext,
  1544. a_AddressString ,
  1545. a_Address ,
  1546. a_TimeOut ,
  1547. a_TimeToLive,
  1548. a_SendSize,
  1549. a_NoFragmentation ,
  1550. a_TypeOfService,
  1551. a_RecordRoute,
  1552. a_TimestampRoute,
  1553. a_SourceRouteType,
  1554. t_UnSpecified ? NULL : t_Node->LowerBound () ,
  1555. t_PropertyPartition,
  1556. a_ResolveError
  1557. ) ;
  1558. }
  1559. }
  1560. return t_Result ;
  1561. }
  1562. HRESULT CPingQueryAsync :: RecurseResolveAddressNames (
  1563. void *pMethodContext,
  1564. wchar_t *a_AddressString ,
  1565. ULONG a_Address ,
  1566. ULONG a_TimeOut ,
  1567. ULONG a_TimeToLive,
  1568. ULONG a_SendSize,
  1569. BOOL a_NoFragmentation ,
  1570. ULONG a_TypeOfService,
  1571. ULONG a_RecordRoute,
  1572. ULONG a_TimestampRoute,
  1573. ULONG a_SourceRouteType,
  1574. LPCWSTR a_SourceRoute,
  1575. PartitionSet *a_PartitionSet,
  1576. ULONG a_ResolveError
  1577. )
  1578. {
  1579. HRESULT t_Result = WBEM_E_FAILED ;
  1580. ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount () ;
  1581. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1582. {
  1583. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1584. WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1585. BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
  1586. ! t_Node->InfiniteUpperBound () &&
  1587. t_Node->ClosedLowerBound () &&
  1588. t_Node->ClosedUpperBound () &&
  1589. ( t_Node->LowerBound () == t_Node->UpperBound () ) ;
  1590. BOOL t_UnSpecified = t_Node->InfiniteLowerBound () && t_Node->InfiniteUpperBound () ;
  1591. if ( ! t_Unique && ! t_UnSpecified )
  1592. {
  1593. SetErrorInfo(IDS_QUERY_RA,
  1594. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1595. break ;
  1596. }
  1597. else
  1598. {
  1599. for ( ulong t_Partition = 0 ; t_Partition < t_PartitionCount ; t_Partition ++ )
  1600. {
  1601. PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition ) ;
  1602. WmiSignedIntegerRangeNode *t_Node = ( WmiSignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
  1603. InterlockedIncrement(&m_PingCount);
  1604. t_Result = Icmp_RequestResponse (
  1605. a_AddressString ,
  1606. a_Address ,
  1607. a_TimeToLive,
  1608. a_TimeOut ,
  1609. a_SendSize,
  1610. a_NoFragmentation ,
  1611. a_TypeOfService,
  1612. a_RecordRoute,
  1613. a_TimestampRoute,
  1614. a_SourceRouteType,
  1615. a_SourceRoute ,
  1616. t_UnSpecified ? FALSE : t_Node->LowerBound (),
  1617. a_ResolveError
  1618. ) ;
  1619. if ( FAILED ( t_Result ) )
  1620. {
  1621. DecrementPingCount();
  1622. }
  1623. }
  1624. }
  1625. }
  1626. return t_Result ;
  1627. }
  1628. BOOL CPingQueryAsync::ExecQuery ()
  1629. {
  1630. BOOL t_Result = FALSE ;
  1631. InterlockedIncrement(&m_PingCount);
  1632. SQL_LEVEL_1_RPN_EXPRESSION *t_RpnExpression = NULL ;
  1633. QueryPreprocessor :: QuadState t_State = Query (
  1634. m_Query ,
  1635. t_RpnExpression
  1636. ) ;
  1637. if ( t_State == QueryPreprocessor :: QuadState :: State_True )
  1638. {
  1639. WmiTreeNode *t_Root = NULL ;
  1640. t_State = PreProcess (
  1641. NULL ,
  1642. t_RpnExpression ,
  1643. t_Root
  1644. ) ;
  1645. PartitionSet *t_PartitionSet = NULL ;
  1646. try
  1647. {
  1648. switch ( t_State )
  1649. {
  1650. case QueryPreprocessor :: QuadState :: State_True:
  1651. {
  1652. BSTR t_PropertyContainer [ PING_KEY_PROPERTY_COUNT ] ;
  1653. memset (t_PropertyContainer , 0 , sizeof(BSTR) * PING_KEY_PROPERTY_COUNT );
  1654. try
  1655. {
  1656. t_PropertyContainer [ 0 ] = SysAllocString ( Ping_Address ) ;
  1657. t_PropertyContainer [ 1 ] = SysAllocString ( Ping_Timeout ) ;
  1658. t_PropertyContainer [ 2 ] = SysAllocString ( Ping_TimeToLive ) ;
  1659. t_PropertyContainer [ 3 ] = SysAllocString ( Ping_BufferSize ) ;
  1660. t_PropertyContainer [ 4 ] = SysAllocString ( Ping_NoFragmentation ) ;
  1661. t_PropertyContainer [ 5 ] = SysAllocString ( Ping_TypeofService ) ;
  1662. t_PropertyContainer [ 6 ] = SysAllocString ( Ping_RecordRoute ) ;
  1663. t_PropertyContainer [ 7 ] = SysAllocString ( Ping_TimestampRoute ) ;
  1664. t_PropertyContainer [ 8 ] = SysAllocString ( Ping_SourceRouteType ) ;
  1665. t_PropertyContainer [ 9 ] = SysAllocString ( Ping_SourceRoute ) ;
  1666. t_PropertyContainer [ 10 ] = SysAllocString ( Ping_ResolveAddressNames ) ;
  1667. if ( !t_PropertyContainer [ 0 ] ||
  1668. !t_PropertyContainer [ 1 ] ||
  1669. !t_PropertyContainer [ 2 ] ||
  1670. !t_PropertyContainer [ 3 ] ||
  1671. !t_PropertyContainer [ 4 ] ||
  1672. !t_PropertyContainer [ 5 ] ||
  1673. !t_PropertyContainer [ 6 ] ||
  1674. !t_PropertyContainer [ 7 ] ||
  1675. !t_PropertyContainer [ 8 ] ||
  1676. !t_PropertyContainer [ 9 ] ||
  1677. !t_PropertyContainer [ 10 ]
  1678. )
  1679. {
  1680. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR );
  1681. }
  1682. t_State = PreProcess (
  1683. NULL ,
  1684. t_RpnExpression ,
  1685. t_Root ,
  1686. PING_KEY_PROPERTY_COUNT ,
  1687. t_PropertyContainer ,
  1688. t_PartitionSet
  1689. ) ;
  1690. for ( ULONG index = 0; index < PING_KEY_PROPERTY_COUNT; index++ )
  1691. {
  1692. if ( t_PropertyContainer [ index ] )
  1693. {
  1694. SysFreeString ( t_PropertyContainer [ index ] ) ;
  1695. t_PropertyContainer [ index ] = NULL;
  1696. }
  1697. }
  1698. }
  1699. catch ( ... )
  1700. {
  1701. for ( ULONG index = 0; index < PING_KEY_PROPERTY_COUNT; index++ )
  1702. {
  1703. if ( t_PropertyContainer [ index ] )
  1704. {
  1705. SysFreeString ( t_PropertyContainer [ index ] ) ;
  1706. t_PropertyContainer [ index ] = NULL;
  1707. }
  1708. }
  1709. throw;
  1710. }
  1711. switch ( t_State )
  1712. {
  1713. case QueryPreprocessor :: QuadState :: State_True :
  1714. {
  1715. SetErrorInfo(IDS_QUERY_BROAD,
  1716. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1717. }
  1718. break ;
  1719. case QueryPreprocessor :: QuadState :: State_False :
  1720. {
  1721. /*
  1722. * Empty set
  1723. */
  1724. SetErrorInfo(IDS_QUERY_NARROW,
  1725. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1726. }
  1727. break ;
  1728. case QueryPreprocessor :: QuadState :: State_Undefined :
  1729. {
  1730. t_Result = SUCCEEDED(RecurseAddress ( NULL , t_PartitionSet ) );
  1731. delete t_PartitionSet ;
  1732. t_PartitionSet = NULL;
  1733. }
  1734. break ;
  1735. default:
  1736. {
  1737. SetErrorInfo(IDS_QUERY_UNUSABLE,
  1738. WBEM_E_PROVIDER_NOT_CAPABLE ) ;
  1739. }
  1740. break ;
  1741. }
  1742. delete t_Root ;
  1743. t_Root = NULL ;
  1744. }
  1745. break ;
  1746. default:
  1747. {
  1748. SetErrorInfo(IDS_QUERY_ANALYZE,
  1749. WBEM_E_FAILED ) ;
  1750. }
  1751. break ;
  1752. }
  1753. delete t_RpnExpression ;
  1754. t_RpnExpression = NULL ;
  1755. }
  1756. catch (...)
  1757. {
  1758. if ( t_PartitionSet )
  1759. {
  1760. delete t_PartitionSet;
  1761. t_PartitionSet = NULL;
  1762. }
  1763. if ( t_Root )
  1764. {
  1765. delete t_Root;
  1766. t_Root = NULL;
  1767. }
  1768. if ( t_RpnExpression )
  1769. {
  1770. delete t_RpnExpression ;
  1771. t_RpnExpression = NULL ;
  1772. }
  1773. DecrementPingCount();
  1774. throw;
  1775. }
  1776. }
  1777. else
  1778. {
  1779. SetErrorInfo(IDS_QUERY_PARSE,
  1780. WBEM_E_FAILED ) ;
  1781. }
  1782. DecrementPingCount();
  1783. return t_Result ;
  1784. }
  1785. void CPingQueryAsync::HandleResponse (CPingCallBackObject *a_reply)
  1786. {
  1787. try
  1788. {
  1789. if (FAILED(Icmp_DecodeAndIndicate (a_reply)) )
  1790. {
  1791. SetErrorInfo(IDS_DECODE_QUERY,
  1792. WBEM_E_FAILED ) ;
  1793. }
  1794. }
  1795. catch (...)
  1796. {
  1797. DecrementPingCount();
  1798. }
  1799. DecrementPingCount();
  1800. }
  1801. void CPingQueryAsync::HandleErrorResponse (DWORD a_ErrMsgID, HRESULT a_HRes)
  1802. {
  1803. try
  1804. {
  1805. SetErrorInfo(a_ErrMsgID , a_HRes) ;
  1806. }
  1807. catch (...)
  1808. {
  1809. DecrementPingCount();
  1810. }
  1811. DecrementPingCount();
  1812. }