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.

2370 lines
60 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <tdint.h>
  4. #include <tcp.h>
  5. #include <tcpconn.h>
  6. #include <addr.h>
  7. #include <udp.h>
  8. #include <raw.h>
  9. #include <winsock.h>
  10. #include <tcb.h>
  11. //#define CONN_INDEX(c) ((c) & 0xffffff)
  12. //#define CONN_INST(c) ((uchar)((c) >> 24))
  13. FLAG_INFO FlagsTcb[] =
  14. {
  15. { WINDOW_SET, "Window_Set" },
  16. { CLIENT_OPTIONS, "Client_Options" },
  17. { CONN_ACCEPTED, "Connection_Accepted" },
  18. { ACTIVE_OPEN, "Active_Open" },
  19. { DISC_NOTIFIED, "Disc_Notified" },
  20. { IN_DELAY_Q, "In_Delay_Q" },
  21. { RCV_CMPLTING, "Receives_Completing" },
  22. { IN_RCV_IND, "In_Receive_Indication" },
  23. { NEED_RCV_CMPLT, "Need_To_Have_Rcvs_Completed" },
  24. { NEED_ACK, "Need_To_Send_Ack" },
  25. { NEED_OUTPUT, "Need_To_Output" },
  26. { ACK_DELAYED, "Delayed_Ack" },
  27. { PMTU_BH_PROBE, "PMTU_BH_Probe" },
  28. { BSD_URGENT, "BSD_Urgent" },
  29. { IN_DELIV_URG, "In_Deliver_Urgent" },
  30. { URG_VALID, "Urgent_Valid" },
  31. { FIN_NEEDED, "Fin_Needed" },
  32. { NAGLING, "Nagling" },
  33. { IN_TCP_SEND, "In_Tcp_Send" },
  34. { FLOW_CNTLD, "Flow_Controlled" },
  35. { DISC_PENDING, "Disconnect_Pending" },
  36. { TW_PENDING, "Timed_Wait_Pending" },
  37. { FORCE_OUTPUT, "Force_Output" },
  38. { SEND_AFTER_RCV, "Send_After_Receive" },
  39. { GC_PENDING, "Graceful_Close_Pending" },
  40. { KEEPALIVE, "KeepAlive" },
  41. { URG_INLINE, "Urgent_Inline" },
  42. { FIN_OUTSTANDING, "Fin_Outstanding" },
  43. { FIN_SENT, "Fin_Sent" },
  44. { NEED_RST, "Need_Rst" },
  45. { IN_TCB_TABLE, "In_Tcb_Table" },
  46. { IN_TWTCB_TABLE, "IN_TWTCB_TABLE" },
  47. { IN_TWQUEUE, "IN_TWQUEUE" },
  48. { 0, NULL }
  49. };
  50. FLAG_INFO FlagsFastChk[] =
  51. {
  52. { TCP_FLAG_SLOW, "Need_Slow_Path" },
  53. { TCP_FLAG_IN_RCV, "In_Receive_Path" },
  54. { TCP_FLAG_FASTREC, "FastXmit_In_Progress" },
  55. { 0, NULL }
  56. };
  57. FLAG_INFO FlagsAO[] =
  58. {
  59. { AO_RAW_FLAG, "Raw" },
  60. { AO_DHCP_FLAG, "DHCP" },
  61. { AO_VALID_FLAG, "Valid" },
  62. { AO_BUSY_FLAG, "Busy" },
  63. { AO_OOR_FLAG, "Out_of_Resources" },
  64. { AO_QUEUED_FLAG, "On_PendingQ" },
  65. { AO_XSUM_FLAG, "Use_Xsums" },
  66. { AO_SEND_FLAG, "Send_Pending" },
  67. { AO_OPTIONS_FLAG, "Options_Pending" },
  68. { AO_DELETE_FLAG, "Delete_Pending" },
  69. { AO_BROADCAST_FLAG ,"BCast_Enabled" },
  70. { AO_CONNUDP_FLAG, "Connected_UDP" },
  71. { 0, NULL }
  72. };
  73. ENUM_INFO StateTcb[] =
  74. {
  75. { TCB_CLOSED, "Closed" },
  76. { TCB_LISTEN, "Listening" },
  77. { TCB_SYN_SENT, "Syn_Sent" },
  78. { TCB_SYN_RCVD, "Syn_Received" },
  79. { TCB_ESTAB, "Established" },
  80. { TCB_FIN_WAIT1, "Fin_Wait_1" },
  81. { TCB_FIN_WAIT2, "Fin_Wait_2" },
  82. { TCB_CLOSE_WAIT, "Close_Wait" },
  83. { TCB_CLOSING, "Closing" },
  84. { TCB_LAST_ACK, "Last_Ack" },
  85. { TCB_TIME_WAIT, "Time_Wait" },
  86. { 0, NULL }
  87. };
  88. ENUM_INFO CloseReason[] =
  89. {
  90. { TCB_CLOSE_RST, "RST_Received" },
  91. { TCB_CLOSE_ABORTED, "Local_Abort" },
  92. { TCB_CLOSE_TIMEOUT, "Timed_Out" },
  93. { TCB_CLOSE_REFUSED, "Refused" },
  94. { TCB_CLOSE_UNREACH, "Dest_Unreachable" },
  95. { TCB_CLOSE_SUCCESS, "Sucessful_Close" },
  96. { 0, NULL }
  97. };
  98. ENUM_INFO FsContext2[] =
  99. {
  100. { TDI_TRANSPORT_ADDRESS_FILE, "Transport_Address" },
  101. { TDI_CONNECTION_FILE, "Connection" },
  102. { TDI_CONTROL_CHANNEL_FILE, "Control_Channel" },
  103. { 0, NULL }
  104. };
  105. ENUM_INFO Prot[] =
  106. {
  107. { PROTOCOL_UDP, "Udp" },
  108. { PROTOCOL_TCP, "Tcp" },
  109. { PROTOCOL_RAW, "Raw" },
  110. { 0, NULL }
  111. };
  112. VOID
  113. DumpTcpTCB(
  114. ULONG TcbAddr,
  115. VERBOSITY Verbosity
  116. );
  117. VOID
  118. SearchTCB(
  119. ULONG addressToSearch,
  120. VERBOSITY Verbosity
  121. );
  122. VOID
  123. DumpTcpConn(
  124. ULONG TcpConnAddr,
  125. VERBOSITY Verbosity
  126. );
  127. VOID
  128. DumpTcpConnBlock
  129. (
  130. ULONG TcpConnBlockAddr,
  131. VERBOSITY Verbosity
  132. );
  133. VOID
  134. DumpTcpAO(
  135. ULONG TcpAOAddr,
  136. VERBOSITY Verbosity
  137. );
  138. VOID
  139. Tcptcbtable(
  140. VERBOSITY Verbosity
  141. );
  142. VOID
  143. syntcbtable(
  144. VERBOSITY Verbosity
  145. );
  146. VOID
  147. Tcptwtcbtable(
  148. VERBOSITY Verbosity
  149. );
  150. VOID
  151. DumpTcpConnTable
  152. (
  153. VERBOSITY Verbosity
  154. );
  155. VOID
  156. TcpConnTableStats
  157. (
  158. VERBOSITY Verbosity
  159. );
  160. VOID
  161. TcpAOTableStats
  162. (
  163. VERBOSITY Verbosity
  164. );
  165. VOID
  166. TcpTwqStats
  167. (
  168. VERBOSITY Verbosity
  169. );
  170. VOID
  171. DumpIrp(
  172. PVOID IrpToDump,
  173. BOOLEAN FullOutput
  174. );
  175. DECLARE_API( irp )
  176. /*++
  177. Routine Description:
  178. Dumps the specified Irp
  179. Arguments:
  180. args - Address
  181. Return Value:
  182. None
  183. --*/
  184. {
  185. ULONG irpToDump;
  186. char buf[128];
  187. buf[0] = '\0';
  188. if (*args) {
  189. sscanf(args, "%lx %s", &irpToDump, buf);
  190. DumpIrp((PUCHAR)irpToDump, (BOOLEAN) (buf[0] != '\0'));
  191. }
  192. }
  193. VOID
  194. DumpTcpIrp(
  195. ULONG _objAddr
  196. );
  197. DECLARE_API( tcpfile )
  198. /*++
  199. Routine Description:
  200. Dumps the specified Irp
  201. Arguments:
  202. args - Address
  203. Return Value:
  204. None
  205. --*/
  206. {
  207. ULONG irpToDump;
  208. if (*args) {
  209. sscanf(args, "%lx", &irpToDump);
  210. DumpTcpIrp(irpToDump);
  211. }
  212. }
  213. DECLARE_API( tcb )
  214. {
  215. ULONG addressToDump = 0;
  216. ULONG result;
  217. if ( *args ) {
  218. sscanf(args, "%lx", &addressToDump);
  219. }
  220. DumpTcpTCB( addressToDump, VERBOSITY_NORMAL );
  221. }
  222. DECLARE_API( tcbsrch )
  223. {
  224. ULONG addressToSearch = 0;
  225. ULONG result;
  226. if ( *args ) {
  227. sscanf(args, "%lx", &addressToSearch);
  228. }
  229. SearchTCB( addressToSearch, VERBOSITY_NORMAL );
  230. }
  231. DECLARE_API( tcpconntable )
  232. {
  233. if ( *args == '\0' ) {
  234. DumpTcpConnTable( VERBOSITY_NORMAL );
  235. } else {
  236. DumpTcpConnTable( VERBOSITY_FULL );
  237. }
  238. }
  239. DECLARE_API( tcpconnstats )
  240. {
  241. TcpConnTableStats( VERBOSITY_NORMAL );
  242. }
  243. DECLARE_API( tcbtable )
  244. {
  245. if ( *args == '\0' ) {
  246. Tcptcbtable( VERBOSITY_NORMAL );
  247. } else {
  248. Tcptcbtable( VERBOSITY_FULL );
  249. }
  250. }
  251. DECLARE_API( syntable )
  252. {
  253. if ( *args == '\0' ) {
  254. syntcbtable( VERBOSITY_NORMAL );
  255. } else {
  256. syntcbtable( VERBOSITY_FULL );
  257. }
  258. }
  259. DECLARE_API( twtcbtable )
  260. {
  261. if ( *args == '\0' ) {
  262. Tcptwtcbtable( VERBOSITY_NORMAL );
  263. } else {
  264. Tcptwtcbtable( VERBOSITY_FULL );
  265. }
  266. }
  267. DECLARE_API( tcpaostats )
  268. {
  269. TcpAOTableStats( VERBOSITY_NORMAL );
  270. }
  271. DECLARE_API( tcptwqstats )
  272. {
  273. TcpTwqStats( VERBOSITY_NORMAL );
  274. }
  275. DECLARE_API( tcpconn )
  276. {
  277. ULONG addressToDump = 0;
  278. ULONG result;
  279. char buf[128];
  280. buf[0] = '\0';
  281. if ( *args ) {
  282. sscanf(args, "%lx %s", &addressToDump, buf);
  283. }
  284. if (buf[0] == '\0') {
  285. DumpTcpConn( addressToDump, VERBOSITY_NORMAL );
  286. } else {
  287. DumpTcpConn( addressToDump, VERBOSITY_FULL );
  288. }
  289. }
  290. DECLARE_API( tcpconnblock )
  291. {
  292. ULONG addressToDump = 0;
  293. ULONG result;
  294. char buf[128];
  295. buf[0] = '\0';
  296. if ( *args ) {
  297. sscanf(args, "%lx %s", &addressToDump, buf);
  298. }
  299. if (buf[0] == '\0') {
  300. DumpTcpConnBlock( addressToDump, VERBOSITY_NORMAL );
  301. } else {
  302. DumpTcpConnBlock( addressToDump, VERBOSITY_FULL );
  303. }
  304. }
  305. DECLARE_API( ao )
  306. {
  307. ULONG addressToDump = 0;
  308. ULONG result;
  309. if ( *args ) {
  310. sscanf(args, "%lx", &addressToDump);
  311. }
  312. DumpTcpAO( addressToDump, VERBOSITY_NORMAL );
  313. }
  314. #ifdef _obj
  315. # undef _obj
  316. # undef _objAddr
  317. # undef _objType
  318. # undef _objTypeName
  319. #endif
  320. #define _obj Tcb
  321. #define _objAddr TcbToDump
  322. #define _objType TCB
  323. #define _objTypeName "TCB"
  324. VOID
  325. DumpTcpTCB
  326. (
  327. ULONG _objAddr,
  328. VERBOSITY Verbosity
  329. )
  330. /*++
  331. Routine Description:
  332. Dumps the fields of the specified DEVICE_CONTEXT structure
  333. Arguments:
  334. DeviceToDump - The device context object to display
  335. Full - Display a partial listing if 0, full listing otherwise.
  336. Return Value:
  337. None
  338. --*/
  339. {
  340. _objType _obj;
  341. ULONG result;
  342. unsigned int index;
  343. BOOL bActive;
  344. if ( !ReadMemory( _objAddr,
  345. &_obj,
  346. sizeof( _obj ),
  347. &result ))
  348. {
  349. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  350. return;
  351. }
  352. #if DBG
  353. CHECK_SIGNATURE( tcb_sig, tcb_signature );
  354. #endif
  355. if ( Verbosity == VERBOSITY_ONE_LINER )
  356. {
  357. dprintf( "NOT IMPLEMENTED" );
  358. return;
  359. }
  360. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  361. PrintStartStruct();
  362. PrintFieldName( "tcb_next" );
  363. dprint_addr_list( ( ULONG )_obj.tcb_next,
  364. FIELD_OFFSET( TCB, tcb_next ));
  365. PrintLock( tcb_lock );
  366. PrintULong( tcb_senduna );
  367. PrintULong( tcb_sendnext );
  368. PrintULong( tcb_sendmax );
  369. PrintULong( tcb_sendwin );
  370. PrintULong( tcb_unacked );
  371. PrintULong( tcb_maxwin );
  372. PrintULong( tcb_cwin );
  373. PrintULong( tcb_ssthresh );
  374. PrintULong( tcb_phxsum );
  375. PrintPtr( tcb_cursend );
  376. PrintPtr( tcb_sendbuf );
  377. PrintULong( tcb_sendofs );
  378. PrintULong( tcb_sendsize );
  379. PrintLLTcp( tcb_sendq );
  380. PrintULong( tcb_rcvnext );
  381. PrintULong( tcb_rcvwin );
  382. PrintULong( tcb_sendwl1 );
  383. PrintULong( tcb_sendwl2 );
  384. PrintPtr( tcb_currcv );
  385. PrintULong( tcb_indicated );
  386. PrintFlags( tcb_flags, FlagsTcb );
  387. PrintFlags( tcb_fastchk, FlagsFastChk );
  388. PrintSymbolPtr( tcb_rcvhndlr );
  389. PrintIPAddress( tcb_daddr );
  390. PrintIPAddress( tcb_saddr );
  391. PrintHTONUShort( tcb_dport );
  392. PrintHTONUShort( tcb_sport );
  393. #if TRACE_EVENT
  394. PrintPtr( tcb_cpcontext ); // CP HOOK context.
  395. #endif
  396. PrintUShort( tcb_mss );
  397. PrintUShort( tcb_rexmit );
  398. PrintULong( tcb_refcnt );
  399. PrintULong( tcb_rttseq );
  400. PrintUShort( tcb_smrtt );
  401. PrintUShort( tcb_delta );
  402. PrintUShort( tcb_remmss );
  403. PrintUChar( tcb_slowcount );
  404. PrintXEnum( tcb_state, StateTcb );
  405. PrintUChar( tcb_rexmitcnt );
  406. PrintUChar( tcb_pending );
  407. PrintUChar( tcb_kacount );
  408. PrintXULong( tcb_error );
  409. PrintULong( tcb_rtt );
  410. PrintULong( tcb_defaultwin );
  411. PrintPtr( tcb_raq );
  412. PrintPtr( tcb_rcvhead );
  413. PrintPtr( tcb_rcvtail );
  414. PrintULong( tcb_pendingcnt );
  415. PrintPtr( tcb_pendhead );
  416. PrintPtr( tcb_pendtail );
  417. PrintPtr( tcb_connreq );
  418. PrintPtr( tcb_conncontext );
  419. PrintULong( tcb_bcountlow );
  420. PrintULong( tcb_bcounthi );
  421. PrintULong( tcb_totaltime );
  422. PrintPtr( tcb_aonext );
  423. PrintPtr( tcb_conn );
  424. PrintLLTcp( tcb_delayq );
  425. PrintXEnum( tcb_closereason, CloseReason );
  426. PrintUChar( tcb_bhprobecnt );
  427. PrintSymbolPtr( tcb_rcvind );
  428. PrintPtr( tcb_ricontext );
  429. PrintPtr( tcb_opt.ioi_options );
  430. PrintIPAddress( tcb_opt.ioi_addr );
  431. PrintUChar( tcb_opt.ioi_optlength );
  432. PrintUChar( tcb_opt.ioi_ttl );
  433. PrintUChar( tcb_opt.ioi_tos );
  434. PrintUChar( tcb_opt.ioi_flags );
  435. PrintUChar( tcb_opt.ioi_hdrincl );
  436. PrintULong( tcb_opt.ioi_GPCHandle );
  437. PrintULong( tcb_opt.ioi_uni );
  438. PrintULong( tcb_opt.ioi_TcpChksum );
  439. PrintULong( tcb_opt.ioi_UdpChksum );
  440. PrintPtr( tcb_rce );
  441. PrintPtr( tcb_discwait );
  442. PrintPtr( tcb_exprcv );
  443. PrintPtr( tcb_urgpending );
  444. PrintULong( tcb_urgcnt );
  445. PrintULong( tcb_urgind );
  446. PrintULong( tcb_urgstart );
  447. PrintULong( tcb_urgend );
  448. PrintULong( tcb_walkcount );
  449. PrintUShort( tcb_dup ); // For Fast recovery algorithm
  450. PrintUShort( tcb_force ); // Force next send after fast send
  451. PrintULong( tcb_tcpopts ); // rfc 1323 and 2018 options holder
  452. PrintPtr( tcb_SackBlock ); // Sacks which needs to be sent
  453. PrintPtr( tcb_SackRcvd ); // Sacks which needs to be proces
  454. PrintUShort( tcb_sndwinscale ); // send window scale
  455. PrintUShort( tcb_rcvwinscale ); // receive window scale
  456. PrintULong( tcb_tsrecent ); // time stamp recent
  457. PrintULong( tcb_lastack ); // ack number in the last segment sent
  458. PrintULong( tcb_tsupdatetime ); // Time when tsrecent was updated
  459. // used for invalidating TS
  460. PrintPtr( tcb_chainedrcvind ); //for chained receives
  461. PrintPtr( tcb_chainedrcvcontext );
  462. PrintULong( tcb_delackticks );
  463. PrintULong( tcb_GPCCachedIF);
  464. PrintULong( tcb_GPCCachedLink);
  465. PrintPtr( tcb_GPCCachedRTE );
  466. #if DBG
  467. PrintULong( tcb_LargeSend );
  468. #endif
  469. PrintULong( tcb_moreflag );
  470. PrintULong( tcb_partition );
  471. PrintXULong( tcb_connid );
  472. #if ACK_DEBUG
  473. PrintULong( tcb_history_index );
  474. for (index = 0; index < NUM_ACK_HISTORY_ITEMS; index++) {
  475. dprintf("[%2i] seq:%lu unacked:%lu\n",
  476. index,
  477. Tcb.tcb_ack_history[index].sequence,
  478. Tcb.tcb_ack_history[index].unacked);
  479. }
  480. #endif // ACK_DEBUG
  481. #if REFERENCE_DEBUG
  482. PrintULong ( tcb_refhistory_index );
  483. for (index = 0; index < MAX_REFERENCE_HISTORY; index++) {
  484. if (index == _obj.tcb_refhistory_index) {
  485. dprintf( "*");
  486. }
  487. dprintf( "[%2d]\t: Ref %d File ", index, _obj.tcb_refhistory[index].Count );
  488. dprint_ansi_string( _obj.tcb_refhistory[index].File );
  489. dprintf( ",%d Caller ", _obj.tcb_refhistory[index].Line );
  490. dprintSymbolPtr( (_obj.tcb_refhistory[index].Caller), EOL );
  491. }
  492. #endif // REFERENCE_DEBUG
  493. PrintEndStruct();
  494. }
  495. #ifdef _obj
  496. # undef _obj
  497. # undef _objAddr
  498. # undef _objType
  499. # undef _objTypeName
  500. #endif
  501. #define _obj TcpConn
  502. #define _objAddr TcpConnToDump
  503. #define _objType TCPConn
  504. #define _objTypeName "TCPConn"
  505. VOID
  506. DumpTcpConn
  507. (
  508. ULONG _objAddr,
  509. VERBOSITY Verbosity
  510. )
  511. /*++
  512. Routine Description:
  513. Dumps the fields of the specified DEVICE_CONTEXT structure
  514. Arguments:
  515. DeviceToDump - The device context object to display
  516. Full - Display a partial listing if 0, full listing otherwise.
  517. Return Value:
  518. None
  519. --*/
  520. {
  521. _objType _obj;
  522. ULONG result;
  523. unsigned int index;
  524. BOOL bActive;
  525. if ( !ReadMemory( _objAddr,
  526. &_obj,
  527. sizeof( _obj ),
  528. &result ))
  529. {
  530. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  531. return;
  532. }
  533. #if DBG
  534. CHECK_SIGNATURE( tc_sig, tc_signature );
  535. #endif
  536. if ( Verbosity == VERBOSITY_ONE_LINER )
  537. {
  538. dprintf( "NOT IMPLEMENTED" );
  539. return;
  540. }
  541. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  542. PrintStartStruct();
  543. PrintLLTcp( tc_q );
  544. PrintPtr( tc_tcb );
  545. PrintPtr( tc_ao );
  546. PrintUChar( tc_inst );
  547. PrintUChar( tc_flags );
  548. PrintUShort( tc_refcnt );
  549. PrintPtr( tc_context );
  550. PrintSymbolPtr( tc_rtn );
  551. PrintPtr( tc_rtncontext );
  552. PrintSymbolPtr( tc_donertn );
  553. PrintFlags( tc_tcbflags, FlagsTcb );
  554. PrintULong( tc_tcbkatime );
  555. PrintULong( tc_tcbkainterval );
  556. PrintULong( tc_window );
  557. PrintPtr( tc_LastTCB );
  558. PrintPtr( tc_ConnBlock );
  559. PrintXULong( tc_connid );
  560. PrintEndStruct();
  561. if (Verbosity == VERBOSITY_FULL) {
  562. if (_obj.tc_tcb) {
  563. DumpTcpTCB( (ULONG)_obj.tc_tcb, VERBOSITY_NORMAL );
  564. }
  565. if (_obj.tc_ao) {
  566. DumpTcpAO( (ULONG)_obj.tc_ao, VERBOSITY_NORMAL );
  567. }
  568. }
  569. }
  570. #ifdef _obj
  571. # undef _obj
  572. # undef _objAddr
  573. # undef _objType
  574. # undef _objTypeName
  575. #endif
  576. #define _obj AddressObject
  577. #define _objAddr AddrObjToDump
  578. #define _objType AddrObj
  579. #define _objTypeName "AddrObj"
  580. VOID
  581. DumpTcpAO
  582. (
  583. ULONG _objAddr,
  584. VERBOSITY Verbosity
  585. )
  586. /*++
  587. Routine Description:
  588. Dumps the fields of the specified DEVICE_CONTEXT structure
  589. Arguments:
  590. DeviceToDump - The device context object to display
  591. Full - Display a partial listing if 0, full listing otherwise.
  592. Return Value:
  593. None
  594. --*/
  595. {
  596. _objType _obj;
  597. ULONG result;
  598. unsigned int index;
  599. BOOL bActive;
  600. if ( !ReadMemory( _objAddr,
  601. &_obj,
  602. sizeof( _obj ),
  603. &result ))
  604. {
  605. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  606. return;
  607. }
  608. #if DBG
  609. CHECK_SIGNATURE( ao_sig, ao_signature );
  610. #endif
  611. if ( Verbosity == VERBOSITY_ONE_LINER )
  612. {
  613. dprintf( "NOT IMPLEMENTED" );
  614. return;
  615. }
  616. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  617. PrintStartStruct();
  618. PrintPtr( ao_next );
  619. PrintLock( ao_lock );
  620. PrintPtr( ao_request );
  621. PrintLLTcp( ao_sendq );
  622. PrintLLTcp( ao_pendq );
  623. PrintLLTcp( ao_rcvq );
  624. PrintPtr( ao_opt.ioi_options );
  625. PrintIPAddress( ao_opt.ioi_addr );
  626. PrintUChar( ao_opt.ioi_optlength );
  627. PrintUChar( ao_opt.ioi_ttl );
  628. PrintUChar( ao_opt.ioi_tos );
  629. PrintUChar( ao_opt.ioi_flags );
  630. PrintUChar( ao_opt.ioi_hdrincl );
  631. PrintULong( ao_opt.ioi_GPCHandle );
  632. PrintULong( ao_opt.ioi_uni );
  633. PrintULong( ao_opt.ioi_TcpChksum );
  634. PrintULong( ao_opt.ioi_UdpChksum );
  635. PrintIPAddress( ao_addr );
  636. PrintHTONUShort( ao_port );
  637. PrintFlags( ao_flags, FlagsAO );
  638. PrintXEnum( ao_prot, Prot );
  639. PrintULong( ao_listencnt );
  640. PrintUShort( ao_usecnt );
  641. PrintUShort ( ao_mcast_loop );
  642. PrintUShort( ao_rcvall );
  643. PrintUShort( ao_rcvall_mcast );
  644. PrintPtr( ao_mcastopt.ioi_options );
  645. PrintIPAddress( ao_mcastopt.ioi_addr );
  646. PrintUChar( ao_mcastopt.ioi_optlength );
  647. PrintUChar( ao_mcastopt.ioi_ttl );
  648. PrintUChar( ao_mcastopt.ioi_tos );
  649. PrintUChar( ao_mcastopt.ioi_flags );
  650. PrintLLTcp( ao_activeq );
  651. PrintLLTcp( ao_idleq );
  652. PrintLLTcp( ao_listenq );
  653. PrintCTEEvent( ao_event );
  654. PrintSymbolPtr( ao_connect );
  655. PrintPtr( ao_conncontext );
  656. PrintSymbolPtr( ao_disconnect );
  657. PrintPtr( ao_disconncontext );
  658. PrintSymbolPtr( ao_error );
  659. PrintPtr( ao_errcontext );
  660. PrintSymbolPtr( ao_rcv );
  661. PrintPtr( ao_rcvcontext );
  662. PrintSymbolPtr( ao_rcvdg );
  663. PrintPtr( ao_rcvdgcontext );
  664. PrintSymbolPtr( ao_exprcv );
  665. PrintPtr( ao_exprcvcontext );
  666. PrintPtr( ao_mcastlist );
  667. PrintSymbolPtr( ao_dgsend );
  668. PrintUShort( ao_maxdgsize );
  669. PrintSymbolPtr( ao_errorex ); // Error event routine.
  670. PrintPtr( ao_errorexcontext ); // Error event context.
  671. // PrintULong( ConnLimitReached ); //set when there are no connections left
  672. PrintSymbolPtr( ao_chainedrcv ); // Chained Receive event handler
  673. PrintPtr( ao_chainedrcvcontext ); // Chained Receive context.
  674. PrintAddr( ao_udpconn );
  675. PrintULong( ao_udpconn.UserDataLength );
  676. PrintPtr( ao_udpconn.UserData );
  677. PrintULong( ao_udpconn.OptionsLength );
  678. PrintPtr( ao_udpconn.Options );
  679. PrintULong( ao_udpconn.RemoteAddressLength );
  680. PrintPtr (ao_udpconn.RemoteAddress );
  681. PrintPtr ( ao_RemoteAddress );
  682. PrintPtr ( ao_Options );
  683. PrintPtr ( ao_rce );
  684. PrintULong( ao_GPCHandle );
  685. PrintULong( ao_GPCCachedIF );
  686. PrintULong( ao_GPCCachedLink );
  687. PrintPtr ( ao_GPCCachedRTE );
  688. PrintIPAddress( ao_rcesrc );
  689. PrintIPAddress( ao_destaddr );
  690. PrintHTONUShort( ao_destport );
  691. PrintULong( ao_promis_ifindex );
  692. PrintUChar( ao_absorb_rtralert );
  693. PrintULong ( ao_bindindex );
  694. PrintEndStruct();
  695. }
  696. #ifdef _obj
  697. # undef _obj
  698. # undef _objAddr
  699. # undef _objType
  700. # undef _objTypeName
  701. #endif
  702. #define _obj TcpConnBlock
  703. #define _objAddr TcpConnBlockToDump
  704. #define _objType TCPConnBlock
  705. #define _objTypeName "TCPConnBlock"
  706. VOID
  707. DumpTcpConnBlock
  708. (
  709. ULONG _objAddr,
  710. VERBOSITY Verbosity
  711. )
  712. {
  713. _objType _obj;
  714. ULONG result;
  715. unsigned int index;
  716. BOOL bActive;
  717. unsigned int count = 0;
  718. if ( !ReadMemory( _objAddr,
  719. &_obj,
  720. sizeof( _obj ),
  721. &result ))
  722. {
  723. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  724. return;
  725. }
  726. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  727. PrintStartStruct();
  728. PrintULong( cb_freecons );
  729. PrintULong( cb_nextfree );
  730. PrintULong( cb_blockid );
  731. PrintULong( cb_conninst );
  732. PrintAddr( cb_conn );
  733. PrintEndStruct();
  734. for (index=0; index<MAX_CONN_PER_BLOCK; index++) {
  735. if ( _obj.cb_conn[index] != NULL ) {
  736. dprintf(" TCPConn @ %08lx\n", _obj.cb_conn[index] );
  737. if (Verbosity == VERBOSITY_FULL) {
  738. DumpTcpConn( (ULONG)(_obj.cb_conn[index]), VERBOSITY_NORMAL );
  739. }
  740. count++;
  741. }
  742. }
  743. dprintf("\n %d Active TCPConn entries in this block.\n", count);
  744. }
  745. VOID
  746. DumpTcpConnTable
  747. (
  748. VERBOSITY Verbosity
  749. )
  750. {
  751. TCPConnBlock **ConnTableBlock, **PreservedPtr;
  752. ULONG result;
  753. unsigned int index;
  754. unsigned int count = 0;
  755. ULONG TabAddr;
  756. ULONG Tablen;
  757. TabAddr = GetUlongValue( "tcpip!ConnTable" );
  758. Tablen = GetUlongValue( "tcpip!MaxConnBlocks" );
  759. dprintf("Dumping ConnTable @ %08lx - ConnTableSize = %08lx\n",
  760. TabAddr, Tablen );
  761. ConnTableBlock = malloc(sizeof( TCPConn * ) * Tablen);
  762. PreservedPtr = ConnTableBlock;
  763. if (ConnTableBlock == NULL) {
  764. dprintf("malloc failed in DumpTcpConnTable.\n");
  765. return;
  766. }
  767. if ( !ReadMemory( TabAddr,
  768. &ConnTableBlock[0],
  769. (sizeof( TCPConnBlock *) * Tablen),
  770. &result ))
  771. {
  772. dprintf("%08lx: Could not read %s structure.\n", TabAddr, "ConnTable" );
  773. free(ConnTableBlock);
  774. return;
  775. }
  776. for (index=0; index<Tablen && !CheckControlC(); index++) {
  777. if ( *ConnTableBlock != NULL ) {
  778. dprintf(" TCPConnBlock @ %08lx\n", *ConnTableBlock );
  779. DumpTcpConnBlock( (ULONG)*ConnTableBlock, VERBOSITY_NORMAL );
  780. count++;
  781. }
  782. ConnTableBlock++;
  783. }
  784. dprintf("\n %d Active TCPConnBlock entries.\n", count);
  785. //free(ConnTable);
  786. free(PreservedPtr);
  787. }
  788. typedef struct ConnStats {
  789. ULONG associated;
  790. ULONG connected;
  791. } ConnStats;
  792. #ifdef _obj
  793. # undef _obj
  794. # undef _objAddr
  795. # undef _objType
  796. # undef _objTypeName
  797. #endif
  798. #define _obj TcpConn
  799. #define _objAddr TcpConnToDump
  800. #define _objType TCPConn
  801. #define _objTypeName "TCPConn"
  802. ULONG
  803. ReadConnInfo
  804. (
  805. ULONG _objAddr
  806. )
  807. {
  808. _objType _obj;
  809. ULONG result;
  810. unsigned int index;
  811. BOOL bActive;
  812. ULONG num=1;
  813. ULONG start=_objAddr;
  814. while (1) {
  815. if ( !ReadMemory( _objAddr,
  816. &_obj,
  817. sizeof( _obj ),
  818. &result ))
  819. {
  820. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  821. return(num);
  822. }
  823. _objAddr = (ULONG)_obj.tc_q.q_next;
  824. if (_objAddr == start) {
  825. break;
  826. }
  827. num++;
  828. }
  829. return(num);
  830. }
  831. VOID
  832. TcpConnStats
  833. (
  834. ULONG _objAddr,
  835. ConnStats *CS
  836. )
  837. /*++
  838. Routine Description:
  839. Dumps the fields of the specified DEVICE_CONTEXT structure
  840. Arguments:
  841. DeviceToDump - The device context object to display
  842. Full - Display a partial listing if 0, full listing otherwise.
  843. Return Value:
  844. None
  845. --*/
  846. {
  847. _objType _obj;
  848. ULONG result;
  849. unsigned int index;
  850. BOOL bActive;
  851. if ( !ReadMemory( _objAddr,
  852. &_obj,
  853. sizeof( _obj ),
  854. &result ))
  855. {
  856. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  857. return;
  858. }
  859. #if DBG
  860. CHECK_SIGNATURE( tc_sig, tc_signature );
  861. #endif
  862. if (_obj.tc_tcb) {
  863. CS->connected++;
  864. }
  865. if (_obj.tc_ao) {
  866. CS->associated++;
  867. }
  868. }
  869. #ifdef _obj
  870. # undef _obj
  871. # undef _objAddr
  872. # undef _objType
  873. # undef _objTypeName
  874. #endif
  875. #define _obj TcpConnBlock
  876. #define _objAddr TcpConnBlockToDump
  877. #define _objType TCPConnBlock
  878. #define _objTypeName "TCPConnBlock"
  879. VOID
  880. TcpConnTableStats (
  881. VERBOSITY Verbosity
  882. )
  883. {
  884. TCPConn **ConnTableBlock, **PreservedPtr;
  885. ULONG result;
  886. unsigned int index;
  887. unsigned int count = 0;
  888. ULONG TabAddr;
  889. ULONG Tablen;
  890. ConnStats CS = { 0, 0 };
  891. TabAddr = GetUlongValue( "tcpip!ConnTable" );
  892. Tablen = GetUlongValue( "tcpip!MaxConnBlocks" );
  893. dprintf("Statistics for ConnTable @ %08lx - ConnTableSize = %08lx\n",
  894. TabAddr, Tablen );
  895. ConnTableBlock = malloc(sizeof( TCPConn * ) * Tablen);
  896. PreservedPtr = ConnTableBlock;
  897. if (ConnTableBlock == NULL) {
  898. dprintf("malloc failed in DumpTcpConnTable.\n");
  899. return;
  900. }
  901. if ( !ReadMemory( TabAddr,
  902. &ConnTableBlock[0],
  903. (sizeof( TCPConnBlock *) * Tablen),
  904. &result ))
  905. {
  906. dprintf("%08lx: Could not read %s structure.\n", TabAddr, "ConnTable" );
  907. free(PreservedPtr);
  908. return;
  909. }
  910. for (index=0; index<Tablen && !CheckControlC(); index++) {
  911. if ( *ConnTableBlock != NULL ) {
  912. {
  913. ULONG _objAddr;
  914. ULONG result;
  915. unsigned int index;
  916. _objType _obj;
  917. _objAddr = (ULONG) *ConnTableBlock;
  918. if ( !ReadMemory( _objAddr,
  919. &_obj,
  920. sizeof( _obj ),
  921. &result ))
  922. {
  923. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  924. free(PreservedPtr);
  925. return;
  926. }
  927. for (index=0; index<MAX_CONN_PER_BLOCK; index++) {
  928. if ( _obj.cb_conn[index] != NULL ) {
  929. count++;
  930. TcpConnStats( (ULONG)(_obj.cb_conn[index]), &CS );
  931. }
  932. }
  933. }
  934. }
  935. ConnTableBlock++;
  936. }
  937. dprintf("\n %d Active TCPConn entries.\n", count);
  938. dprintf("\n %d TCPConn entries are associated with AOs.\n", CS.associated);
  939. dprintf("\n %d TCPConn entries are connected.\n", CS.connected);
  940. free(PreservedPtr);
  941. }
  942. VOID Tcptcbtable(
  943. VERBOSITY Verbosity
  944. )
  945. {
  946. UINT i,result;
  947. TCB *CurrentTcb, *NextTcb;
  948. TCB **TCBTable;
  949. USHORT *TcbDepths;
  950. ULONG_PTR TableAddr;
  951. ULONG TableSize;
  952. ULONG TotalTcbs = 0;
  953. ULONG AverageDepth;
  954. ULONG Variance;
  955. ULONG Depth;
  956. ULONG MinDepth = ~0;
  957. ULONG MaxDepth = 0;
  958. ULONG NumberWithZeroDepth = 0;
  959. TableAddr = GetUlongValue( "tcpip!TcbTable" );
  960. TableSize = GetUlongValue( "tcpip!MaxHashTableSize" );
  961. if ( TableSize == 0 ) {
  962. dprintf( "MaxHashTableSize is uninitialized(0) - check the symbols!\n" );
  963. return;
  964. }
  965. dprintf("Dumping TcbTable @ %08lx - TableSize = 0x%x (%u)\n",
  966. TableAddr, TableSize, TableSize );
  967. TCBTable = malloc(TableSize * sizeof(TCB *));
  968. if (!TCBTable) {
  969. dprintf("malloc failed in DumpTcbTable.\n");
  970. return;
  971. }
  972. // Array of depths we need in order to go back and calculate the
  973. // variance and standard deviation.
  974. //
  975. TcbDepths = malloc(TableSize * sizeof(USHORT));
  976. if (!TcbDepths) {
  977. free (TCBTable);
  978. dprintf("malloc failed in DumpTcbTable.\n");
  979. return;
  980. }
  981. if ( !ReadMemory(TableAddr,
  982. TCBTable,
  983. (sizeof(TCB *) * TableSize),
  984. &result )) {
  985. free (TcbDepths);
  986. free (TCBTable);
  987. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  988. return;
  989. }
  990. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  991. CurrentTcb = TCBTable[i];
  992. if (!CurrentTcb)
  993. {
  994. NumberWithZeroDepth++;
  995. }
  996. Depth = 0;
  997. while (CurrentTcb != NULL && !CheckControlC()) {
  998. TotalTcbs++;
  999. Depth++;
  1000. if ( !ReadMemory((ULONG)CurrentTcb + FIELD_OFFSET(TCB, tcb_next),
  1001. &NextTcb,
  1002. sizeof(TCB*), &result )) {
  1003. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1004. free (TcbDepths);
  1005. free (TCBTable);
  1006. return;
  1007. }
  1008. if (VERBOSITY_FULL == Verbosity) {
  1009. TCB Tcb;
  1010. if ( !ReadMemory((ULONG)CurrentTcb,
  1011. &Tcb,
  1012. sizeof(TCB),
  1013. &result )) {
  1014. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1015. free (TcbDepths);
  1016. free (TCBTable);
  1017. return;
  1018. }
  1019. dprintf("[%u] tcb %x :: SA: ", i, CurrentTcb);
  1020. dprint_IP_address( (IPAddr) Tcb.tcb_saddr);
  1021. dprintf(" DA: ");
  1022. dprint_IP_address( (IPAddr) Tcb.tcb_daddr);
  1023. dprintf(" SPort: %u Dport: %u ", htons(Tcb.tcb_sport), htons(Tcb.tcb_dport));
  1024. dprint_enum_name( (ULONG) Tcb.tcb_state, StateTcb );
  1025. dprintf("\n");
  1026. }
  1027. CurrentTcb = NextTcb;
  1028. }
  1029. if (Depth)
  1030. {
  1031. if (Depth > MaxDepth)
  1032. {
  1033. MaxDepth = Depth;
  1034. }
  1035. if (Depth < MinDepth)
  1036. {
  1037. MinDepth = Depth;
  1038. }
  1039. }
  1040. TcbDepths[i] = (USHORT)Depth;
  1041. }
  1042. AverageDepth = TotalTcbs / TableSize;
  1043. Variance = 0;
  1044. for (i = 0; i < TableSize; i++) {
  1045. SHORT Diff = (SHORT)(TcbDepths[i] - (USHORT)AverageDepth);
  1046. Variance += (Diff * Diff);
  1047. }
  1048. Variance /= (TableSize-1);
  1049. dprintf(
  1050. "\n"
  1051. "%10u total TCBs\n"
  1052. "%10u total hash buckets\n"
  1053. "%10u should ideally be in each bucket\n"
  1054. "%10u Minimum (non-zero) depth\n"
  1055. "%10u Maximum depth\n"
  1056. "%10u Variance (Standard Deviation = %0.1f)\n"
  1057. "%10u on average in the non-empty buckets\n"
  1058. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1059. TotalTcbs,
  1060. TableSize,
  1061. AverageDepth,
  1062. MinDepth,
  1063. MaxDepth,
  1064. Variance, sqrt(Variance),
  1065. TotalTcbs / (TableSize - NumberWithZeroDepth),
  1066. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableSize
  1067. );
  1068. free (TcbDepths);
  1069. free (TCBTable);
  1070. }
  1071. VOID syntcbtable(
  1072. VERBOSITY Verbosity
  1073. )
  1074. {
  1075. UINT i,result;
  1076. Queue *TCBTable;
  1077. Queue *Scan;
  1078. Queue NextItem;
  1079. SYNTCB *CurrentTcb, *NextTcb;
  1080. USHORT *TcbDepths;
  1081. ULONG_PTR TableAddr;
  1082. ULONG TableSize;
  1083. ULONG TotalTcbs = 0;
  1084. ULONG AverageDepth;
  1085. ULONG Variance;
  1086. ULONG Depth;
  1087. ULONG MinDepth = ~0;
  1088. ULONG MaxDepth = 0;
  1089. ULONG NumberWithZeroDepth = 0;
  1090. ULONG TableBuckets;
  1091. TableAddr = GetUlongValue( "tcpip!SynTcbTable" );
  1092. TableBuckets = GetUlongValue("tcpip!MaxHashTableSize");
  1093. TableSize = TableBuckets * sizeof(Queue);
  1094. dprintf("Dumping synTcbTable @ %08lx - TableSize = 0x%x (%u)\n",
  1095. TableAddr, TableSize, TableSize );
  1096. TCBTable = malloc(TableSize);
  1097. if (!TCBTable) {
  1098. dprintf("malloc failed in DumpsynTcbTable.\n");
  1099. return;
  1100. }
  1101. // Array of depths we need in order to go back and calculate the
  1102. // variance and standard deviation.
  1103. //
  1104. TcbDepths = malloc(TableSize * sizeof(USHORT));
  1105. if (!TcbDepths) {
  1106. free (TCBTable);
  1107. dprintf("malloc failed in DumpTcbTable.\n");
  1108. return;
  1109. }
  1110. if ( !ReadMemory(TableAddr,
  1111. TCBTable,
  1112. TableSize,
  1113. &result )) {
  1114. free (TcbDepths);
  1115. free (TCBTable);
  1116. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  1117. return;
  1118. }
  1119. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  1120. dprintf("\r...%d%%", (i * 100) / TableBuckets);
  1121. if (TCBTable[i].q_next == (Queue*)(TableAddr + (i * sizeof(Queue))))
  1122. {
  1123. NumberWithZeroDepth++;
  1124. }
  1125. Depth = 0;
  1126. for (Scan = TCBTable[i].q_next;
  1127. Scan != (Queue*)(TableAddr + (i * sizeof(Queue)));
  1128. Scan = NextItem.q_next) {
  1129. TotalTcbs++;
  1130. Depth++;
  1131. if (!ReadMemory((ULONG_PTR)Scan, &NextItem, sizeof(Queue), &result)) {
  1132. dprintf("%08lx: %d Could not read %s structure.\n", TCBTable, i,"scansyntcb" );
  1133. free (TcbDepths);
  1134. free (TCBTable);
  1135. return;
  1136. }
  1137. if (VERBOSITY_FULL == Verbosity) {
  1138. SYNTCB Tcb;
  1139. if (!ReadMemory((ULONG_PTR)Scan - FIELD_OFFSET(SYNTCB, syntcb_link),
  1140. &Tcb,
  1141. sizeof(SYNTCB),
  1142. &result )) {
  1143. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1144. free (TcbDepths);
  1145. free (TCBTable);
  1146. return;
  1147. }
  1148. dprintf("[%u] tcb %x :: SA: ", i, Tcb);
  1149. //dprint_IP_address( (IPAddr) Tcb.tcb_saddr);
  1150. dprintf(" DA: ");
  1151. dprint_IP_address( (IPAddr) Tcb.syntcb_daddr);
  1152. dprintf(" SPort: %u Dport: %u ", htons(Tcb.syntcb_sport), htons(Tcb.syntcb_dport));
  1153. dprint_enum_name( (ULONG) Tcb.syntcb_state, StateTcb );
  1154. dprintf("\n");
  1155. }
  1156. }
  1157. if (Depth)
  1158. {
  1159. if (Depth > MaxDepth)
  1160. {
  1161. MaxDepth = Depth;
  1162. }
  1163. if (Depth < MinDepth)
  1164. {
  1165. MinDepth = Depth;
  1166. }
  1167. }
  1168. TcbDepths[i] = (USHORT)Depth;
  1169. }
  1170. AverageDepth = TotalTcbs / TableSize;
  1171. Variance = 0;
  1172. for (i = 0; i < TableSize; i++) {
  1173. SHORT Diff = (SHORT)(TcbDepths[i] - (USHORT)AverageDepth);
  1174. Variance += (Diff * Diff);
  1175. }
  1176. Variance /= (TableSize-1);
  1177. dprintf(
  1178. "\n"
  1179. "%10u total TCBs\n"
  1180. "%10u total hash buckets\n"
  1181. "%10u should ideally be in each bucket\n"
  1182. "%10u Minimum (non-zero) depth\n"
  1183. "%10u Maximum depth\n"
  1184. "%10u Variance (Standard Deviation = %0.1f)\n"
  1185. "%10u on average in the non-empty buckets\n"
  1186. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1187. TotalTcbs,
  1188. TableSize,
  1189. AverageDepth,
  1190. MinDepth,
  1191. MaxDepth,
  1192. Variance, sqrt(Variance),
  1193. TotalTcbs / (TableSize - NumberWithZeroDepth),
  1194. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableSize
  1195. );
  1196. free (TcbDepths);
  1197. free (TCBTable);
  1198. }
  1199. VOID Tcptwtcbtable(
  1200. VERBOSITY Verbosity
  1201. )
  1202. {
  1203. UINT i,result;
  1204. Queue *Table;
  1205. Queue *Scan;
  1206. Queue NextItem;
  1207. USHORT *Depths;
  1208. ULONG_PTR TableAddr;
  1209. ULONG TableBuckets;
  1210. ULONG TableSize;
  1211. ULONG TotalItems = 0;
  1212. ULONG AverageDepth;
  1213. ULONG Variance;
  1214. ULONG Depth;
  1215. ULONG MinDepth = ~0;
  1216. ULONG MaxDepth = 0;
  1217. ULONG NumberWithZeroDepth = 0;
  1218. TableAddr = GetUlongValue("tcpip!TWTCBTable");
  1219. TableBuckets = GetUlongValue("tcpip!MaxHashTableSize");
  1220. // Checking for 1 or smaller to avoid division by zero exceptions at the
  1221. // Variance calculation later and in the final dprintf() in this function.
  1222. if ( TableBuckets <= 1 ) {
  1223. dprintf( "MaxHashTableSize seems uninitialized - check the symbols!\n" );
  1224. return;
  1225. }
  1226. TableSize = TableBuckets * sizeof(Queue);
  1227. dprintf("Dumping TWTCBTable @ %08x - TableBuckets = 0x%x (%u)\n",
  1228. TableAddr, TableBuckets, TableBuckets );
  1229. Table = malloc(TableSize);
  1230. if (!Table) {
  1231. dprintf("malloc failed in DumpTcbTable.\n");
  1232. return;
  1233. }
  1234. // Array of depths we need in order to go back and calculate the
  1235. // variance and standard deviation.
  1236. //
  1237. Depths = malloc(TableBuckets * sizeof(USHORT));
  1238. if (!Depths) {
  1239. free (Table);
  1240. dprintf("malloc failed in DumpTcbTable.\n");
  1241. return;
  1242. }
  1243. if (!ReadMemory(TableAddr, Table, TableSize, &result)) {
  1244. free (Depths);
  1245. free (Table);
  1246. dprintf("%08lx: Could not read TWTCBTable structure.\n", Table);
  1247. return;
  1248. }
  1249. for (i = 0; i < TableBuckets && !CheckControlC(); i++) {
  1250. dprintf("\r...%d%%", (i * 100) / TableBuckets);
  1251. if (Table[i].q_next == (Queue*)(TableAddr + (i * sizeof(Queue))))
  1252. {
  1253. NumberWithZeroDepth++;
  1254. }
  1255. Depth = 0;
  1256. for (Scan = Table[i].q_next;
  1257. Scan != (Queue*)(TableAddr + (i * sizeof(Queue)));
  1258. Scan = NextItem.q_next) {
  1259. TotalItems++;
  1260. Depth++;
  1261. if (!ReadMemory((ULONG_PTR)Scan, &NextItem, sizeof(Queue), &result)) {
  1262. dprintf("%08lx: Could not read Queue structure.\n", Table);
  1263. free (Depths);
  1264. free (Table);
  1265. return;
  1266. }
  1267. if (VERBOSITY_FULL == Verbosity) {
  1268. TWTCB Twtcb;
  1269. if (!ReadMemory((ULONG_PTR)Scan - FIELD_OFFSET(TWTCB, twtcb_link),
  1270. &Twtcb,
  1271. sizeof(TWTCB),
  1272. &result )) {
  1273. dprintf("%08lx: Could not read Twtcb structure.\n", Table);
  1274. free (Depths);
  1275. free (Table);
  1276. return;
  1277. }
  1278. dprintf("[%u] twtcb %x :: SA: ", i, (ULONG_PTR)Scan - FIELD_OFFSET(TWTCB, twtcb_link));
  1279. dprint_IP_address( (IPAddr) Twtcb.twtcb_saddr);
  1280. dprintf(" DA: ");
  1281. dprint_IP_address( (IPAddr) Twtcb.twtcb_daddr);
  1282. dprintf(" SPort: %u Dport: %u\n", htons(Twtcb.twtcb_sport), htons(Twtcb.twtcb_dport));
  1283. }
  1284. }
  1285. if (Depth)
  1286. {
  1287. if (Depth > MaxDepth)
  1288. {
  1289. MaxDepth = Depth;
  1290. }
  1291. if (Depth < MinDepth)
  1292. {
  1293. MinDepth = Depth;
  1294. }
  1295. }
  1296. Depths[i] = (USHORT)Depth;
  1297. }
  1298. dprintf("\r...100%%\n");
  1299. AverageDepth = TotalItems / TableBuckets;
  1300. Variance = 0;
  1301. for (i = 0; i < TableBuckets; i++) {
  1302. SHORT Diff = (SHORT)(Depths[i] - (USHORT)AverageDepth);
  1303. Variance += (Diff * Diff);
  1304. }
  1305. Variance /= (TableBuckets-1);
  1306. if ( TableBuckets == NumberWithZeroDepth ) {
  1307. dprintf( "all buckets seem to be empty - bailing to avoid divide by zero exception!\n" );
  1308. return;
  1309. }
  1310. dprintf(
  1311. "\n"
  1312. "%10u total TWTCBs\n"
  1313. "%10u total hash buckets\n"
  1314. "%10u should ideally be in each bucket\n"
  1315. "%10u Minimum (non-zero) depth\n"
  1316. "%10u Maximum depth\n"
  1317. "%10u Variance (Standard Deviation = %0.1f)\n"
  1318. "%10u on average in the non-empty buckets\n"
  1319. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1320. TotalItems,
  1321. TableBuckets,
  1322. AverageDepth,
  1323. MinDepth,
  1324. MaxDepth,
  1325. Variance, sqrt(Variance),
  1326. TotalItems / (TableBuckets - NumberWithZeroDepth),
  1327. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableBuckets
  1328. );
  1329. free (Depths);
  1330. free (Table);
  1331. }
  1332. VOID SearchTCB(
  1333. ULONG TcbAddr,
  1334. VERBOSITY Verbosity
  1335. )
  1336. {
  1337. unsigned int i,j=0,result; // Index variable.
  1338. TCB *CurrentTcb; // Current AddrObj being examined.
  1339. TCB Tcb; // Current AddrObj being examined.
  1340. TCB **TCBTable, **PreservedPtr;
  1341. ULONG TableAddr;
  1342. ULONG TableSize;
  1343. int found = 0;
  1344. TCB *PrevTcb;
  1345. TableAddr = GetUlongValue( "tcpip!TcbTable" );
  1346. TableSize = GetUlongValue( "tcpip!MaxHashTableSize" );
  1347. dprintf("Dumping TCbTable @ %08lx - TableSize = %08lx\n",
  1348. TableAddr, TableSize );
  1349. TCBTable = malloc(sizeof( TCB * ) * TableSize);
  1350. PreservedPtr = TCBTable;
  1351. if (TCBTable == NULL) {
  1352. dprintf("malloc failed in DumpTcbTable.\n");
  1353. return;
  1354. }
  1355. dprintf("Searching for Tcb @ %08lx \n", TcbAddr);
  1356. if ( !ReadMemory(TableAddr,
  1357. &TCBTable[0],
  1358. (sizeof( TCB *) * TableSize),
  1359. &result ))
  1360. {
  1361. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  1362. return;
  1363. }
  1364. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  1365. CurrentTcb = (TCB *)TCBTable[i];
  1366. j = 0;
  1367. PrevTcb = NULL;
  1368. dprintf("Searching in bucket i %d \n", i+1);
  1369. while (CurrentTcb != NULL && !CheckControlC()) {
  1370. j++;
  1371. if ( !ReadMemory((ULONG)CurrentTcb,
  1372. &Tcb,
  1373. sizeof(TCB),
  1374. &result ))
  1375. {
  1376. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1377. return;
  1378. }
  1379. if (TcbAddr == (ULONG) CurrentTcb) {
  1380. found = 1;
  1381. dprintf("found tcb %x i %d j %d Prev %x\n", CurrentTcb, i+1, j, PrevTcb);
  1382. return;
  1383. }
  1384. dprintf("still searching j %d Prev %x\n", j, PrevTcb);
  1385. PrevTcb = CurrentTcb;
  1386. CurrentTcb = Tcb.tcb_next;
  1387. }
  1388. dprintf("Search completed in bucket i %d \n", i+1);
  1389. dprintf("************************ \n", i);
  1390. }
  1391. if (found == 0)
  1392. dprintf("\n Not found TCB entries.\n");
  1393. free(PreservedPtr);
  1394. }
  1395. #define EMPTY ((q).q_next == (q))
  1396. VOID
  1397. TcpAOTableStats(
  1398. VERBOSITY Verbosity
  1399. )
  1400. {
  1401. UINT i,result;
  1402. ULONG_PTR TdiErrorHandler;
  1403. ULONG valid=0,busy=0,emptylisten=0,emptyactive=0,emptyidle=0;
  1404. ULONG pendingque=0,pendingdel=0,netbtaos=0,tcpaos=0;
  1405. ULONG numidle, numlisten, numactive;
  1406. AddrObj AO;
  1407. USHORT *Depths;
  1408. ULONG_PTR TableAddr;
  1409. ULONG_PTR AOAddress;
  1410. ULONG TableBuckets;
  1411. ULONG TableSize;
  1412. ULONG TotalItems = 0;
  1413. ULONG AverageDepth;
  1414. ULONG Variance;
  1415. ULONG Depth;
  1416. ULONG MinDepth = ~0;
  1417. ULONG MaxDepth = 0;
  1418. ULONG NumberWithZeroDepth = 0;
  1419. TdiErrorHandler = GetExpression("netbt!TdiErrorHandler");
  1420. TableAddr = GetUlongValue("tcpip!AddrObjTable");
  1421. TableBuckets = GetUlongValue("tcpip!AddrObjTableSize");
  1422. if ( TableBuckets == 0 ) {
  1423. dprintf( "AddrObjTableSize is uninitialized(0) - check the symbols!\n" );
  1424. return;
  1425. }
  1426. TableSize = TableBuckets * sizeof(AddrObj*);
  1427. dprintf("Statistics for AddrObjTable @ %08x - TableBuckets = 0x%x (%u)\n",
  1428. TableAddr, TableBuckets, TableBuckets );
  1429. // Array of depths we need in order to go back and calculate the
  1430. // variance and standard deviation.
  1431. //
  1432. Depths = malloc(TableBuckets * sizeof(USHORT));
  1433. if (!Depths) {
  1434. dprintf("malloc failed in TcpAOTableStats.\n");
  1435. return;
  1436. }
  1437. for (i = 0; i < TableBuckets && !CheckControlC(); i++) {
  1438. dprintf("\r...%d%%", (i * 100) / TableSize);
  1439. if (!ReadMemory(TableAddr + (i * 4), &AOAddress, sizeof(AddrObj*), &result)) {
  1440. dprintf("%08lx: Could not read AddrObj address.\n", TableAddr + (i * 4));
  1441. free (Depths);
  1442. return;
  1443. }
  1444. if (!AOAddress) {
  1445. NumberWithZeroDepth++;
  1446. }
  1447. Depth = 0;
  1448. while (AOAddress && !CheckControlC()) {
  1449. TotalItems++;
  1450. Depth++;
  1451. if (!ReadMemory(AOAddress, &AO, sizeof(AO), &result)) {
  1452. dprintf("%08lx: Could not read AddrObj structure.\n", AOAddress);
  1453. free (Depths);
  1454. return;
  1455. }
  1456. if (AO.ao_flags & AO_VALID_FLAG) {
  1457. valid++;
  1458. if (AO.ao_flags & AO_BUSY_FLAG) {
  1459. busy++;
  1460. }
  1461. if (AO.ao_flags & AO_QUEUED_FLAG) {
  1462. pendingque++;
  1463. }
  1464. if (AO.ao_flags & AO_DELETE_FLAG) {
  1465. pendingdel++;
  1466. }
  1467. if ((ULONG_PTR)AO.ao_error == TdiErrorHandler) {
  1468. netbtaos++;
  1469. }
  1470. if (AO.ao_prot == 6) {
  1471. tcpaos++;
  1472. }
  1473. //numidle = numactive = numlisten = 0;
  1474. if ((uint)AO.ao_activeq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_activeq.q_next))) {
  1475. emptyactive++;
  1476. } else {
  1477. //numactive = ReadConnInfo((ULONG )AO.ao_activeq.q_next);
  1478. }
  1479. if ((uint)AO.ao_idleq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_idleq.q_next))) {
  1480. emptyidle++;
  1481. } else {
  1482. //numidle = ReadConnInfo((ULONG )AO.ao_idleq.q_next);
  1483. }
  1484. if ((uint)AO.ao_listenq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_listenq.q_next))) {
  1485. emptylisten++;
  1486. } else {
  1487. //numlisten = ReadConnInfo((ULONG )AO.ao_listenq.q_next);
  1488. }
  1489. //dprintf("%x Connidle %d Conactive %d Connlisten %d loop %d\n",
  1490. // AOAddress, numidle, numactive, numlisten,
  1491. // (ushort)AO.ao_mcast_loop );
  1492. } else {
  1493. dprintf(" %x Invalid\n", AOAddress );
  1494. }
  1495. AOAddress = (ULONG_PTR)AO.ao_next;
  1496. }
  1497. if (Depth)
  1498. {
  1499. if (Depth > MaxDepth)
  1500. {
  1501. MaxDepth = Depth;
  1502. }
  1503. if (Depth < MinDepth)
  1504. {
  1505. MinDepth = Depth;
  1506. }
  1507. }
  1508. Depths[i] = (USHORT)Depth;
  1509. }
  1510. dprintf("\r...100%%\n");
  1511. AverageDepth = TotalItems / TableBuckets;
  1512. Variance = 0;
  1513. for (i = 0; i < TableBuckets; i++) {
  1514. SHORT Diff = (SHORT)(Depths[i] - (USHORT)AverageDepth);
  1515. Variance += (Diff * Diff);
  1516. }
  1517. Variance /= (TableBuckets-1);
  1518. dprintf(
  1519. "\n"
  1520. "%10u total Address objects\n"
  1521. "%10u total hash buckets\n"
  1522. "%10u should ideally be in each bucket\n"
  1523. "%10u Minimum (non-zero) depth\n"
  1524. "%10u Maximum depth\n"
  1525. "%10u Variance (Standard Deviation = %0.1f)\n"
  1526. "%10u on average in the non-empty buckets\n"
  1527. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1528. TotalItems,
  1529. TableBuckets,
  1530. AverageDepth,
  1531. MinDepth,
  1532. MaxDepth,
  1533. Variance, sqrt(Variance),
  1534. TotalItems / (TableBuckets - NumberWithZeroDepth),
  1535. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableBuckets
  1536. );
  1537. free (Depths);
  1538. dprintf("%10u are valid\n", valid);
  1539. dprintf("%10u are busy\n", busy);
  1540. dprintf("%10u with pending queue on\n", pendingque);
  1541. dprintf("%10u with pending delete on\n", pendingdel);
  1542. dprintf("%10u with empty active queue\n", emptyactive);
  1543. dprintf("%10u with empty idle queues\n", emptyidle);
  1544. dprintf("%10u with empty listen queues\n", emptylisten);
  1545. dprintf("%10u NETBT AO's\n", netbtaos);
  1546. dprintf("%10u TCP AO's\n\n", tcpaos);
  1547. }
  1548. VOID
  1549. TcpTwqStats(
  1550. VERBOSITY Verbosity
  1551. )
  1552. {
  1553. int i,j=0,result,sum; // Index variable.
  1554. ULONG_PTR TableAddr, TablePtr;
  1555. ULONG Tcbnext, Tcb;
  1556. TWTCB Tcbstr ;
  1557. ULONG Offset;
  1558. TablePtr = GetExpression( "tcpip!TWQueue" );
  1559. if (!TablePtr) {
  1560. dprintf("Error in tcpip!TWQueue: Please try reload\n");
  1561. return;
  1562. }
  1563. if ( !ReadMemory(TablePtr,
  1564. &TableAddr,
  1565. 4,
  1566. &result ))
  1567. {
  1568. dprintf(" Could not read twqueu \n" );
  1569. return;
  1570. }
  1571. dprintf("Statistics for Twqueue @ %08lx\n",
  1572. TableAddr );
  1573. if ( !ReadMemory(TableAddr,
  1574. &Tcbnext,
  1575. 4,
  1576. &result ))
  1577. {
  1578. dprintf(" Could not read twqueu \n" );
  1579. return;
  1580. }
  1581. sum=i=0;
  1582. // Tcb = Tcbnext - 0x118;
  1583. Tcb = Tcbnext - FIELD_OFFSET(TWTCB, twtcb_TWQueue);
  1584. dprintf(" First tcb::: Tcb %x\n", Tcb );
  1585. while ((Tcbnext != TableAddr) && !CheckControlC()) {
  1586. // Tcb = Tcbnext - 0x118;
  1587. Tcb = Tcbnext - FIELD_OFFSET(TWTCB, twtcb_TWQueue);
  1588. if ( !ReadMemory(Tcb,
  1589. &Tcbstr,
  1590. sizeof(TWTCB),
  1591. &result ))
  1592. {
  1593. dprintf(" Could not read tcb %x \n", Tcb );
  1594. return;
  1595. }
  1596. if (Tcbstr.twtcb_rexmittimer > 0x20) {
  1597. dprintf(" Tcb %x:: delta %u: rexmittimer %u\n ",Tcb,Tcbstr.twtcb_delta,Tcbstr.twtcb_rexmittimer);
  1598. }
  1599. sum += Tcbstr.twtcb_rexmittimer;
  1600. Tcbnext = (ULONG)Tcbstr.twtcb_TWQueue.q_next;
  1601. i++;
  1602. }
  1603. dprintf(" Total %d sum of rexmittimer %d\n ",i, sum);
  1604. }
  1605. #ifdef _obj
  1606. # undef _obj
  1607. # undef _objAddr
  1608. # undef _objType
  1609. # undef _objTypeName
  1610. #endif
  1611. #define _obj TcpConnBlock
  1612. #define _objAddr TcpConnBlockToDump
  1613. #define _objType TCPConnBlock
  1614. #define _objTypeName "TCPConnBlock"
  1615. VOID
  1616. DumpConnection(
  1617. ULONG ConnID
  1618. )
  1619. {
  1620. ULONG ConnIndex = CONN_INDEX(ConnID);
  1621. ULONG ConnBlockId = CONN_BLOCKID(ConnID);
  1622. UCHAR inst = CONN_INST(ConnID);
  1623. ULONG TableAddr;
  1624. ULONG ConnBlockAddr;
  1625. ULONG ConnTableSize;
  1626. ULONG MatchingConn;
  1627. ULONG result;
  1628. ULONG MaxAllocatedConnBlocks;
  1629. TableAddr = GetUlongValue( "tcpip!ConnTable" );
  1630. MaxAllocatedConnBlocks = GetUlongValue( "tcpip!MaxAllocatedConnBlocks" );
  1631. if ((ConnIndex < MAX_CONN_PER_BLOCK) &&
  1632. (ConnBlockId < MaxAllocatedConnBlocks) ){
  1633. // get the ConnBlockId
  1634. TableAddr += (ConnBlockId * sizeof(ULONG));
  1635. if ( !ReadMemory( TableAddr,
  1636. &ConnBlockAddr,
  1637. sizeof( ULONG ),
  1638. &result ))
  1639. {
  1640. dprintf("%08lx: Could not read %s structure.\n", TableAddr, "ConnTableBlock" );
  1641. return;
  1642. }
  1643. if (ConnBlockAddr) {
  1644. _objType _obj;
  1645. ULONG _objAddr;
  1646. _objAddr = ConnBlockAddr;
  1647. if ( !ReadMemory( _objAddr,
  1648. &_obj,
  1649. sizeof( _obj ),
  1650. &result ))
  1651. {
  1652. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1653. return;
  1654. }
  1655. MatchingConn = (ULONG)_obj.cb_conn[ConnIndex];
  1656. if (MatchingConn) {
  1657. DumpTcpConn( MatchingConn, VERBOSITY_FULL );
  1658. } else {
  1659. dprintf( "NULL Conn!!\n");
  1660. }
  1661. } else {
  1662. dprintf( "NULL ConnBlock!!\n");
  1663. }
  1664. } else {
  1665. dprintf( "Invalid ConnIndex!!\n");
  1666. }
  1667. }
  1668. #ifdef _obj
  1669. # undef _obj
  1670. # undef _objAddr
  1671. # undef _objType
  1672. # undef _objTypeName
  1673. #endif
  1674. #define _obj TcpContext
  1675. #define _objAddr TcpContextToDump
  1676. #define _objType TCP_CONTEXT
  1677. #define _objTypeName "Tcp Context"
  1678. VOID
  1679. DumpTcpContext(
  1680. ULONG _objAddr,
  1681. ULONG Type
  1682. )
  1683. {
  1684. _objType _obj;
  1685. ULONG result;
  1686. unsigned int index;
  1687. BOOL bActive;
  1688. if ( !ReadMemory( _objAddr,
  1689. &_obj,
  1690. sizeof( _obj ),
  1691. &result ))
  1692. {
  1693. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1694. return;
  1695. }
  1696. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  1697. PrintStartStruct();
  1698. switch ( Type) {
  1699. case TDI_TRANSPORT_ADDRESS_FILE:
  1700. PrintPtr( Handle.AddressHandle );
  1701. break;
  1702. case TDI_CONNECTION_FILE:
  1703. PrintPtr( Handle.ConnectionContext );
  1704. break;
  1705. case TDI_CONTROL_CHANNEL_FILE:
  1706. PrintPtr( Handle.ControlChannel );
  1707. break;
  1708. default:
  1709. dprintf(" INVALID FsContext2 - Unknown Type \n");
  1710. break;
  1711. }
  1712. PrintULong( ReferenceCount );
  1713. PrintBool( CancelIrps );
  1714. PrintKEvent( CleanupEvent );
  1715. PrintEndStruct();
  1716. switch ( Type) {
  1717. case TDI_TRANSPORT_ADDRESS_FILE:
  1718. break;
  1719. case TDI_CONNECTION_FILE:
  1720. DumpConnection( (ULONG)_obj.Handle.ConnectionContext );
  1721. break;
  1722. case TDI_CONTROL_CHANNEL_FILE:
  1723. break;
  1724. default:
  1725. break;
  1726. }
  1727. }
  1728. #ifdef _obj
  1729. # undef _obj
  1730. # undef _objAddr
  1731. # undef _objType
  1732. # undef _objTypeName
  1733. #endif
  1734. #define _obj FileObj
  1735. #define _objAddr FileObjToDump
  1736. #define _objType FILE_OBJECT
  1737. #define _objTypeName "File Object"
  1738. VOID
  1739. DumpTcpIrp(
  1740. ULONG _objAddr
  1741. )
  1742. {
  1743. _objType _obj;
  1744. ULONG result;
  1745. unsigned int index;
  1746. BOOL bActive;
  1747. if ( !ReadMemory( _objAddr,
  1748. &_obj,
  1749. sizeof( _obj ),
  1750. &result ))
  1751. {
  1752. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1753. return;
  1754. }
  1755. dprintf(" %s @ %08lx\n", _objTypeName, _objAddr );
  1756. PrintPtr( FsContext );
  1757. PrintXEnum( FsContext2, FsContext2 );
  1758. DumpTcpContext( (ULONG)_obj.FsContext, (ULONG)_obj.FsContext2 );
  1759. }
  1760. VOID
  1761. DumpIrp(
  1762. PVOID IrpToDump,
  1763. BOOLEAN FullOutput
  1764. )
  1765. /*++
  1766. Routine Description:
  1767. This routine dumps an Irp. It does not check to see that the address
  1768. supplied actually locates an Irp. This is done to allow for dumping
  1769. Irps post mortem, or after they have been freed or completed.
  1770. Arguments:
  1771. IrpToDump - the address of the irp.
  1772. Return Value:
  1773. None
  1774. --*/
  1775. {
  1776. IO_STACK_LOCATION irpStack;
  1777. PCHAR buffer;
  1778. ULONG irpStackAddress;
  1779. ULONG result;
  1780. IRP irp;
  1781. CCHAR irpStackIndex;
  1782. BOOLEAN TcpIrp = FALSE;
  1783. if ( !ReadMemory( (DWORD) IrpToDump,
  1784. &irp,
  1785. sizeof(irp),
  1786. &result) ) {
  1787. dprintf("%08lx: Could not read Irp\n", IrpToDump);
  1788. return;
  1789. }
  1790. if (irp.Type != IO_TYPE_IRP) {
  1791. dprintf("IRP signature does not match, probably not an IRP\n");
  1792. return;
  1793. }
  1794. dprintf("Irp is Active with %d stacks %d is current\n",
  1795. irp.StackCount,
  1796. irp.CurrentLocation);
  1797. if ((irp.MdlAddress != NULL) && (irp.Type == IO_TYPE_IRP)) {
  1798. dprintf(" Mdl = %08lx ", irp.MdlAddress);
  1799. } else {
  1800. dprintf(" No Mdl ");
  1801. }
  1802. if (irp.AssociatedIrp.MasterIrp != NULL) {
  1803. dprintf("%s = %08lx ",
  1804. (irp.Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
  1805. (irp.Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
  1806. "Irp count",
  1807. irp.AssociatedIrp.MasterIrp);
  1808. }
  1809. dprintf("Thread %08lx: ", irp.Tail.Overlay.Thread);
  1810. if (irp.StackCount > 15) {
  1811. dprintf("Too many Irp stacks to be believed (>15)!!\n");
  1812. return;
  1813. } else {
  1814. if (irp.CurrentLocation > irp.StackCount) {
  1815. dprintf("Irp is completed. ");
  1816. } else {
  1817. dprintf("Irp stack trace. ");
  1818. }
  1819. }
  1820. if (irp.PendingReturned) {
  1821. dprintf("Pending has been returned\n");
  1822. } else {
  1823. dprintf("\n");
  1824. }
  1825. if (FullOutput)
  1826. {
  1827. dprintf("Flags = %08lx\n", irp.Flags);
  1828. dprintf("ThreadListEntry.Flink = %08lx\n", irp.ThreadListEntry.Flink);
  1829. dprintf("ThreadListEntry.Blink = %08lx\n", irp.ThreadListEntry.Blink);
  1830. dprintf("IoStatus.Status = %08lx\n", irp.IoStatus.Status);
  1831. dprintf("IoStatus.Information = %08lx\n", irp.IoStatus.Information);
  1832. dprintf("RequestorMode = %08lx\n", irp.RequestorMode);
  1833. dprintf("Cancel = %02lx\n", irp.Cancel);
  1834. dprintf("CancelIrql = %lx\n", irp.CancelIrql);
  1835. dprintf("ApcEnvironment = %02lx\n", irp.ApcEnvironment);
  1836. dprintf("UserIosb = %08lx\n", irp.UserIosb);
  1837. dprintf("UserEvent = %08lx\n", irp.UserEvent);
  1838. dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08lx\n", irp.Overlay.AsynchronousParameters.UserApcRoutine);
  1839. dprintf("Overlay.AsynchronousParameters.UserApcContext = %08lx\n", irp.Overlay.AsynchronousParameters.UserApcContext);
  1840. dprintf(
  1841. "Overlay.AllocationSize = %08lx - %08lx\n",
  1842. irp.Overlay.AllocationSize.HighPart,
  1843. irp.Overlay.AllocationSize.LowPart);
  1844. dprintf("CancelRoutine = %08lx\n", irp.CancelRoutine);
  1845. dprintf("UserBuffer = %08lx\n", irp.UserBuffer);
  1846. dprintf("&Tail.Overlay.DeviceQueueEntry = %08lx\n", &irp.Tail.Overlay.DeviceQueueEntry);
  1847. dprintf("Tail.Overlay.Thread = %08lx\n", irp.Tail.Overlay.Thread);
  1848. dprintf("Tail.Overlay.AuxiliaryBuffer = %08lx\n", irp.Tail.Overlay.AuxiliaryBuffer);
  1849. dprintf("Tail.Overlay.ListEntry.Flink = %08lx\n", irp.Tail.Overlay.ListEntry.Flink);
  1850. dprintf("Tail.Overlay.ListEntry.Blink = %08lx\n", irp.Tail.Overlay.ListEntry.Blink);
  1851. dprintf("Tail.Overlay.CurrentStackLocation = %08lx\n", irp.Tail.Overlay.CurrentStackLocation);
  1852. dprintf("Tail.Overlay.OriginalFileObject = %08lx\n", irp.Tail.Overlay.OriginalFileObject);
  1853. dprintf("Tail.Apc = %08lx\n", irp.Tail.Apc);
  1854. dprintf("Tail.CompletionKey = %08lx\n", irp.Tail.CompletionKey);
  1855. }
  1856. irpStackAddress = (ULONG)IrpToDump + sizeof(irp);
  1857. buffer = LocalAlloc(LPTR, 256);
  1858. if (buffer == NULL) {
  1859. dprintf("Can't allocate 256 bytes\n");
  1860. return;
  1861. }
  1862. dprintf(" cmd flg cl Device File Completion-Context\n");
  1863. for (irpStackIndex = 1; irpStackIndex <= irp.StackCount; irpStackIndex++) {
  1864. if ( !ReadMemory( (DWORD) irpStackAddress,
  1865. &irpStack,
  1866. sizeof(irpStack),
  1867. &result) ) {
  1868. dprintf("%08lx: Could not read IrpStack\n", irpStackAddress);
  1869. goto exit;
  1870. }
  1871. dprintf("%c%3x %2x %2x %08lx %08lx %08lx-%08lx %s %s %s %s\n",
  1872. irpStackIndex == irp.CurrentLocation ? '>' : ' ',
  1873. irpStack.MajorFunction,
  1874. irpStack.Flags,
  1875. irpStack.Control,
  1876. irpStack.DeviceObject,
  1877. irpStack.FileObject,
  1878. irpStack.CompletionRoutine,
  1879. irpStack.Context,
  1880. (irpStack.Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
  1881. (irpStack.Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
  1882. (irpStack.Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
  1883. (irpStack.Control & SL_PENDING_RETURNED) ? "pending" : "");
  1884. if (irpStack.DeviceObject != NULL) {
  1885. if ((ULONG)irpStack.DeviceObject != GetUlongValue( "tcpip!TCPDeviceObject" )) {
  1886. dprintf("THIS IS NOT A TCP Irp!!!!\n");
  1887. TcpIrp = FALSE;
  1888. } else {
  1889. dprintf("\t \\Driver\\Tcpip");
  1890. TcpIrp = TRUE;
  1891. }
  1892. }
  1893. if (irpStack.CompletionRoutine != NULL) {
  1894. GetSymbol(irpStack.CompletionRoutine, buffer, &result);
  1895. dprintf("\t%s\n", buffer);
  1896. } else {
  1897. dprintf("\n");
  1898. }
  1899. dprintf("\t\t\tArgs: %08lx %08lx %08lx %08lx\n",
  1900. irpStack.Parameters.Others.Argument1,
  1901. irpStack.Parameters.Others.Argument2,
  1902. irpStack.Parameters.Others.Argument3,
  1903. irpStack.Parameters.Others.Argument4);
  1904. irpStackAddress += sizeof(irpStack);
  1905. if (CheckControlC()) {
  1906. goto exit;
  1907. }
  1908. if (TcpIrp) {
  1909. if ( irpStack.FileObject != NULL ) {
  1910. DumpTcpIrp( (ULONG)irpStack.FileObject );
  1911. } else {
  1912. dprintf("FILEOBJECT Ptr is NULL!!!!\n");
  1913. }
  1914. }
  1915. }
  1916. exit:
  1917. LocalFree(buffer);
  1918. }