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.

549 lines
13 KiB

  1. /******************************************************************
  2. pingcallback.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. VOID static NTAPI ApcRoutine( // This is called when ping completes
  35. IN PVOID Context, // The above structure
  36. IN PIO_STATUS_BLOCK Ignored1, // Unused param
  37. IN ULONG Ignored2 // Unused param
  38. )
  39. {
  40. CPingCallBackObject *t_request = (CPingCallBackObject *)Context;
  41. t_request->HandleResponse();
  42. t_request->Release();
  43. }
  44. CPingCallBackObject::CPingCallBackObject(CPingTaskObject *a_ParentTask,
  45. LPCWSTR a_AddressString,
  46. ULONG a_Address,
  47. ULONG a_TimeToLive,
  48. ULONG a_Timeout,
  49. ULONG a_SendSize,
  50. BOOL a_NoFragmentation,
  51. ULONG a_TypeofService,
  52. ULONG a_RecordRoute,
  53. ULONG a_TimestampRoute,
  54. ULONG a_SourceRouteType,
  55. LPCWSTR a_SourceRoute,
  56. BOOL a_ResolveAddress,
  57. ULONG a_ResolveError)
  58. :
  59. WmiTask < ULONG > ( *CPingProvider :: s_Allocator ) ,
  60. m_ParentTask(NULL),
  61. m_ReplyBuffer(NULL),
  62. m_SendBuffer(NULL),
  63. m_ReplySize(0),
  64. m_SourceRouteCount(0),
  65. m_IcmpHandle(INVALID_HANDLE_VALUE),
  66. m_ResolveError(a_ResolveError)
  67. {
  68. InterlockedIncrement ( & CPingProviderClassFactory :: s_ObjectsInProgress ) ;
  69. m_ParentTask = a_ParentTask;
  70. m_Address = a_Address;
  71. m_TimeToLive = a_TimeToLive;
  72. m_Timeout = a_Timeout;
  73. m_SendSize = a_SendSize;
  74. m_NoFragmentation = a_NoFragmentation;
  75. m_TypeofService = a_TypeofService;
  76. m_RecordRoute = a_RecordRoute;
  77. m_TimestampRoute = a_TimestampRoute;
  78. m_SourceRouteType = a_SourceRouteType;
  79. m_ResolveAddress = a_ResolveAddress;
  80. if (a_SourceRoute != NULL)
  81. {
  82. m_SourceRoute = a_SourceRoute;
  83. }
  84. if (a_AddressString != NULL)
  85. {
  86. m_AddressString = a_AddressString;
  87. }
  88. }
  89. CPingCallBackObject::~CPingCallBackObject()
  90. {
  91. if (m_ParentTask != NULL)
  92. {
  93. SendError(IDS_CALLBACK_PREMATURE, WBEM_E_FAILED);
  94. }
  95. if (m_ReplyBuffer != NULL)
  96. {
  97. delete [] m_ReplyBuffer;
  98. m_ReplyBuffer = NULL;
  99. }
  100. if (m_SendBuffer != NULL)
  101. {
  102. delete [] m_SendBuffer;
  103. m_SendBuffer = NULL;
  104. }
  105. if (INVALID_HANDLE_VALUE != m_IcmpHandle)
  106. {
  107. IcmpCloseHandle ( m_IcmpHandle );
  108. }
  109. InterlockedDecrement ( & CPingProviderClassFactory :: s_ObjectsInProgress ) ;
  110. }
  111. BOOL CPingCallBackObject::GetIcmpHandle()
  112. {
  113. if (m_IcmpHandle == INVALID_HANDLE_VALUE)
  114. {
  115. m_IcmpHandle = IcmpCreateFile () ;
  116. }
  117. return (m_IcmpHandle != INVALID_HANDLE_VALUE);
  118. }
  119. void CPingCallBackObject :: SendError(DWORD a_ErrMsgID, HRESULT a_HRes)
  120. {
  121. if (m_ParentTask != NULL)
  122. {
  123. m_ParentTask->HandleErrorResponse(a_ErrMsgID, a_HRes);
  124. Disconnect();
  125. }
  126. }
  127. void CPingCallBackObject :: HandleResponse()
  128. {
  129. if (m_ParentTask != NULL)
  130. {
  131. m_ParentTask->HandleResponse(this);
  132. m_ParentTask->SetThreadToken(TRUE);
  133. Disconnect();
  134. }
  135. }
  136. WmiStatusCode CPingCallBackObject :: Process ( WmiThread <ULONG> &a_Thread )
  137. {
  138. SendEcho () ;
  139. return e_StatusCode_Success ;
  140. }
  141. BOOL CPingCallBackObject::ParseSourceRoute()
  142. {
  143. BOOL t_RetVal = TRUE;
  144. CStringW t_Src(m_SourceRoute);
  145. t_Src.TrimLeft();
  146. t_Src.TrimRight();
  147. if (!t_Src.IsEmpty())
  148. {
  149. int t_Index = 0;
  150. while (t_Index != -1)
  151. {
  152. t_Index = t_Src.Find(L',');
  153. if (t_Index == 0)
  154. {
  155. t_RetVal = FALSE;
  156. break;
  157. }
  158. CStringW t_AddrStr;
  159. if (t_Index == -1)
  160. {
  161. t_AddrStr = t_Src;
  162. }
  163. else
  164. {
  165. t_AddrStr = t_Src.Left(t_Index);
  166. int t_len = t_Src.GetLength() - t_Index - 1;
  167. if (t_len == 0)
  168. {
  169. t_RetVal = FALSE;
  170. break;
  171. }
  172. else
  173. {
  174. t_Src = t_Src.Right(t_len);
  175. }
  176. }
  177. t_AddrStr.TrimLeft();
  178. t_AddrStr.TrimRight();
  179. if (!t_AddrStr.IsEmpty())
  180. {
  181. if ( SUCCEEDED ( CPingTaskObject::Icmp_ResolveAddress ( t_AddrStr , m_SourceRouteArray[m_SourceRouteCount] ) ) )
  182. {
  183. m_SourceRouteCount++;
  184. if ((m_SourceRouteCount == PING_MAX_IPS) && (t_Index != -1))
  185. {
  186. t_RetVal = FALSE;
  187. break;
  188. }
  189. }
  190. else
  191. {
  192. t_RetVal = FALSE;
  193. break;
  194. }
  195. }
  196. else
  197. {
  198. t_RetVal = FALSE;
  199. break;
  200. }
  201. }
  202. }
  203. return t_RetVal;
  204. }
  205. void CPingCallBackObject::SendEcho()
  206. {
  207. if (m_ParentTask != NULL)
  208. {
  209. if (m_ParentTask->SetThreadToken(FALSE))
  210. {
  211. HRESULT t_Result = GetIcmpHandle() ? S_OK : WBEM_E_FAILED;
  212. BOOL t_SourceRouting = FALSE ;
  213. uchar t_SendOptions [ MAX_OPT_SIZE ] ;
  214. uint t_OptionLength = 0;
  215. int t_OptionIndex = 0 ;
  216. int t_SourceRouteIndex = -1 ;
  217. uchar t_Flags = m_NoFragmentation ? IP_FLAG_DF : 0 ;
  218. if (FAILED(t_Result))
  219. {
  220. SendError (IDS_ICMPCREATEFILE_FAIL, WBEM_E_FAILED);
  221. }
  222. else
  223. {
  224. if ( m_RecordRoute )
  225. {
  226. if ( ( t_OptionIndex + 3 ) <= MAX_OPT_SIZE )
  227. {
  228. ULONG t_RouteRecordCount = ( m_RecordRoute * sizeof ( ULONG ) ) + 3 ;
  229. if ( ( t_RouteRecordCount + t_OptionIndex ) <= MAX_OPT_SIZE)
  230. {
  231. uchar *t_Options = t_SendOptions ;
  232. t_Options [ t_OptionIndex ] = IP_OPT_RR ;
  233. t_Options [ t_OptionIndex + 1 ] = t_RouteRecordCount ;
  234. t_Options [ t_OptionIndex + 2 ] = 4; // Set initial pointer value
  235. t_OptionLength += t_RouteRecordCount;
  236. t_OptionIndex += t_RouteRecordCount ;
  237. t_SourceRouting = TRUE;
  238. }
  239. else
  240. {
  241. t_Result = WBEM_E_FAILED ;
  242. SendError (IDS_RR_MAX, WBEM_E_FAILED);
  243. }
  244. }
  245. else
  246. {
  247. t_Result = WBEM_E_FAILED ;
  248. SendError (IDS_RR_MAX_INDEX, WBEM_E_FAILED);
  249. }
  250. }
  251. }
  252. if (SUCCEEDED (t_Result))
  253. {
  254. if ( m_TimestampRoute )
  255. {
  256. if ( ( t_OptionIndex + 4 ) <= MAX_OPT_SIZE )
  257. {
  258. ULONG t_TimestampRecordCount = ( m_TimestampRoute * sizeof ( ULONG ) * 2 ) + 4 ;
  259. if ( ( t_TimestampRecordCount + t_OptionIndex ) <= MAX_OPT_SIZE)
  260. {
  261. uchar *t_Options = t_SendOptions ;
  262. t_Options [ t_OptionIndex ] = IP_OPT_TS ;
  263. t_Options [ t_OptionIndex + 1 ] = t_TimestampRecordCount ;
  264. t_Options [ t_OptionIndex + 2 ] = 5; // Set initial pointer value
  265. t_Options [ t_OptionIndex + 3 ] = 1 ;
  266. t_OptionLength += t_TimestampRecordCount ;
  267. t_OptionIndex += t_TimestampRecordCount ;
  268. t_SourceRouting = TRUE;
  269. }
  270. else
  271. {
  272. t_Result = WBEM_E_FAILED ;
  273. SendError (IDS_TS_MAX, WBEM_E_FAILED);
  274. }
  275. }
  276. else
  277. {
  278. t_Result = WBEM_E_FAILED ;
  279. SendError (IDS_TS_MAX_INDEX, WBEM_E_FAILED);
  280. }
  281. }
  282. }
  283. if (SUCCEEDED (t_Result))
  284. {
  285. switch ( m_SourceRouteType )
  286. {
  287. case 1:
  288. {
  289. if ( ParseSourceRoute() )
  290. {
  291. if ( ( t_OptionIndex + 3 ) <= MAX_OPT_SIZE )
  292. {
  293. if ( ( t_OptionIndex + 3 + ( ( m_SourceRouteCount + 1 ) * 4 ) ) <= MAX_OPT_SIZE )
  294. {
  295. uchar *t_Options = t_SendOptions ;
  296. t_Options [ t_OptionIndex ] = IP_OPT_LSRR ;
  297. t_Options [ t_OptionIndex + 1 ] = 3;
  298. t_Options [ t_OptionIndex + 2 ] = 4;
  299. t_OptionLength += 3 ;
  300. for ( ULONG t_SourceIndex = 0 ; t_SourceIndex < m_SourceRouteCount ; t_SourceIndex ++ )
  301. {
  302. ULONG t_RouteIndex = t_Options [ t_OptionIndex + 1 ] ;
  303. //* ( ULONG * ) &t_Options [ t_RouteIndex + t_OptionIndex ] = m_SourceRouteArray [ t_SourceIndex ] ;
  304. memcpy ( &t_Options [ t_RouteIndex + t_OptionIndex ], &m_SourceRouteArray [ t_SourceIndex ], sizeof ( ULONG ) );
  305. t_Options [ t_OptionIndex + 1 ] += 4 ;
  306. t_OptionLength += 4 ;
  307. }
  308. t_SourceRouteIndex = t_Options [ t_OptionIndex + 1 ] + t_OptionIndex ;
  309. t_Options [ t_OptionIndex + 1 ] += 4 ; // Save space for dest. addr
  310. t_OptionIndex += t_Options [ t_OptionIndex + 1 ] ;
  311. t_OptionLength += 4 ;
  312. t_SourceRouting = TRUE;
  313. }
  314. else
  315. {
  316. t_Result = WBEM_E_FAILED ;
  317. SendError (IDS_SR_MAX, WBEM_E_FAILED);
  318. }
  319. }
  320. else
  321. {
  322. t_Result = WBEM_E_FAILED ;
  323. SendError (IDS_SR_MAX_INDEX, WBEM_E_FAILED);
  324. }
  325. }
  326. else
  327. {
  328. t_Result = WBEM_E_FAILED ;
  329. SendError (IDS_SR_PARSE, WBEM_E_FAILED);
  330. }
  331. }
  332. break ;
  333. case 2:
  334. {
  335. if ( ParseSourceRoute() )
  336. {
  337. if ( ( t_OptionIndex + 3 ) <= MAX_OPT_SIZE )
  338. {
  339. if ( ( t_OptionIndex + 3 + ( ( m_SourceRouteCount + 1 ) * 4 ) ) <= MAX_OPT_SIZE )
  340. {
  341. uchar *t_Options = t_SendOptions ;
  342. t_Options [ t_OptionIndex ] = IP_OPT_SSRR ;
  343. t_Options [ t_OptionIndex + 1 ] = 3;
  344. t_Options [ t_OptionIndex + 2 ] = 4;
  345. t_OptionLength += 3 ;
  346. for ( ULONG t_SourceIndex = 0 ; t_SourceIndex < m_SourceRouteCount ; t_SourceIndex ++ )
  347. {
  348. ULONG t_RouteIndex = t_Options [ t_OptionIndex + 1 ] ;
  349. //* ( ULONG * ) &t_Options [ t_RouteIndex + t_OptionIndex ] = m_SourceRouteArray [ t_SourceIndex ] ;
  350. memcpy ( &t_Options [ t_RouteIndex + t_OptionIndex ], &m_SourceRouteArray [ t_SourceIndex ], sizeof ( ULONG ) );
  351. t_Options [ t_OptionIndex + 1 ] += 4 ;
  352. t_OptionLength += 4 ;
  353. }
  354. t_SourceRouteIndex = t_Options [ t_OptionIndex + 1 ] + t_OptionIndex ;
  355. t_Options [ t_OptionIndex + 1 ] += 4 ; // Save space for dest. addr
  356. t_OptionIndex += t_Options [ t_OptionIndex + 1 ] ;
  357. t_OptionLength += 4 ;
  358. t_SourceRouting = TRUE;
  359. }
  360. else
  361. {
  362. t_Result = WBEM_E_FAILED ;
  363. SendError (IDS_SR_MAX, WBEM_E_FAILED);
  364. }
  365. }
  366. else
  367. {
  368. t_Result = WBEM_E_FAILED ;
  369. SendError (IDS_SR_MAX_INDEX, WBEM_E_FAILED);
  370. }
  371. }
  372. else
  373. {
  374. t_Result = WBEM_E_FAILED ;
  375. SendError (IDS_SR_PARSE, WBEM_E_FAILED);
  376. }
  377. }
  378. break ;
  379. case 0:
  380. default:
  381. {
  382. }
  383. break ;
  384. }
  385. }
  386. if (SUCCEEDED (t_Result))
  387. {
  388. if ( t_SourceRouteIndex != -1 )
  389. {
  390. //* ( ULONG *) & t_SendOptions [ t_SourceRouteIndex ] = m_Address ;
  391. memcpy ( & t_SendOptions [ t_SourceRouteIndex ], &m_Address, sizeof ( ULONG ) );
  392. }
  393. m_SendBuffer = new UCHAR[m_SendSize] ;
  394. //
  395. // Calculate receive buffer size and try to allocate it.
  396. //
  397. if ( m_SendSize <= DEFAULT_SEND_SIZE )
  398. {
  399. m_ReplySize = DEFAULT_BUFFER_SIZE ;
  400. }
  401. else
  402. {
  403. m_ReplySize = MAX_BUFFER_SIZE ;
  404. }
  405. m_ReplyBuffer = new UCHAR[m_ReplySize] ;
  406. //
  407. // Initialize the send buffer pattern.
  408. //
  409. for ( ULONG t_Index = 0; t_Index < m_SendSize; t_Index ++)
  410. {
  411. m_SendBuffer [ t_Index ] = 'a' + ( t_Index % 23 ) ;
  412. }
  413. //
  414. // Initialize the send options
  415. //
  416. IP_OPTION_INFORMATION t_SendOptionInformation ;
  417. t_SendOptionInformation.OptionsData = t_SendOptions ;
  418. t_SendOptionInformation.OptionsSize = (uchar) t_OptionLength ;
  419. t_SendOptionInformation.Ttl = m_TimeToLive ;
  420. t_SendOptionInformation.Tos = m_TypeofService ;
  421. t_SendOptionInformation.Flags = t_Flags ;
  422. //will always return 0 in async case!
  423. ULONG t_ReplyStatus = IcmpSendEcho2 (
  424. m_IcmpHandle,
  425. 0,
  426. ApcRoutine,
  427. (PVOID)this ,
  428. m_Address,
  429. m_SendBuffer ,
  430. (unsigned short) m_SendSize ,
  431. & t_SendOptionInformation ,
  432. m_ReplyBuffer,
  433. m_ReplySize,
  434. m_Timeout
  435. );
  436. //we're async get the return val elsewhere
  437. t_ReplyStatus = GetLastError();
  438. if( (ERROR_SUCCESS != t_ReplyStatus) && (ERROR_IO_PENDING != t_ReplyStatus) )
  439. {
  440. SendError (IDS_ICMPSENDECHO2, WBEM_E_FAILED);
  441. }
  442. }
  443. m_ParentTask->SetThreadToken(TRUE);
  444. if (FAILED(t_Result))
  445. {
  446. Release();
  447. }
  448. }
  449. else
  450. {
  451. SendError(IDS_IMPERSONATE_SEND, WBEM_E_ACCESS_DENIED);
  452. Release();
  453. }
  454. }
  455. else
  456. {
  457. Release();
  458. }
  459. }