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.

905 lines
19 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. endp.c
  5. Abstract:
  6. Implements the endp, state, port, and proc commands.
  7. Author:
  8. Keith Moore (keithmo) 19-Apr-1995
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "afdkdp.h"
  14. #pragma hdrstop
  15. //
  16. // Private prototypes.
  17. //
  18. BOOL
  19. DumpEndpointCallback(
  20. ULONG64 ActualAddress,
  21. ULONG64 Context
  22. );
  23. BOOL
  24. FindStateCallback(
  25. ULONG64 ActualAddress,
  26. ULONG64 Context
  27. );
  28. BOOL
  29. FindPortCallback(
  30. ULONG64 ActualAddress,
  31. ULONG64 Context
  32. );
  33. BOOL
  34. FindProcessCallback(
  35. ULONG64 ActualAddress,
  36. ULONG64 Context
  37. );
  38. ULONG64
  39. FindProcessByPid (
  40. ULONG64 Pid
  41. );
  42. ULONG
  43. FindProcessByPidCallback (
  44. PFIELD_INFO pField,
  45. PVOID UserContext
  46. );
  47. //
  48. // Public functions.
  49. //
  50. DECLARE_API( endp )
  51. /*++
  52. Routine Description:
  53. Dumps the AFD_ENDPOINT structure at the specified address, if
  54. given or all endpoints.
  55. Arguments:
  56. None.
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. ULONG result;
  62. INT i;
  63. CHAR expr[MAX_ADDRESS_EXPRESSION];
  64. PCHAR argp;
  65. ULONG64 address;
  66. gClient = pClient;
  67. if (!CheckKmGlobals ()) {
  68. return E_INVALIDARG;
  69. }
  70. argp = ProcessOptions ((PCHAR)args);
  71. if (argp==NULL)
  72. return E_INVALIDARG;
  73. if (Options&AFDKD_BRIEF_DISPLAY) {
  74. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_HEADER);
  75. }
  76. if ((argp[0]==0) || (Options & AFDKD_ENDPOINT_SCAN)) {
  77. EnumEndpoints(
  78. DumpEndpointCallback,
  79. 0
  80. );
  81. dprintf ("\nTotal endpoints: %ld", EntityCount);
  82. }
  83. else {
  84. //
  85. // Snag the address from the command line.
  86. //
  87. while (sscanf( argp, "%s%n", expr, &i )==1) {
  88. if( CheckControlC() ) {
  89. break;
  90. }
  91. argp+=i;
  92. address = GetExpression (expr);
  93. result = (ULONG)InitTypeRead (address, AFD!AFD_ENDPOINT);
  94. if (result!=0) {
  95. dprintf ("\nendp: Could not read AFD_ENDPOINT @ %p, err: %d\n",
  96. address, result);
  97. break;
  98. }
  99. if (Options & AFDKD_BRIEF_DISPLAY) {
  100. DumpAfdEndpointBrief (
  101. address
  102. );
  103. }
  104. else {
  105. DumpAfdEndpoint (
  106. address
  107. );
  108. }
  109. if (Options & AFDKD_FIELD_DISPLAY) {
  110. ProcessFieldOutput (address, "AFD!AFD_ENDPOINT");
  111. }
  112. }
  113. }
  114. if (Options&AFDKD_BRIEF_DISPLAY) {
  115. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_TRAILER);
  116. }
  117. else {
  118. dprintf ("\n");
  119. }
  120. return S_OK;
  121. } // endp
  122. //
  123. // Public functions.
  124. //
  125. DECLARE_API( file )
  126. /*++
  127. Routine Description:
  128. Dumps the AFD_ENDPOINT structure associated with AFD file object.
  129. Arguments:
  130. None.
  131. Return Value:
  132. None.
  133. --*/
  134. {
  135. ULONG result;
  136. INT i;
  137. CHAR expr[MAX_ADDRESS_EXPRESSION];
  138. PCHAR argp;
  139. ULONG64 address, endpAddr;
  140. gClient = pClient;
  141. if (!CheckKmGlobals ()) {
  142. return E_INVALIDARG;
  143. }
  144. argp = ProcessOptions ((PCHAR)args);
  145. if (argp==NULL)
  146. return E_INVALIDARG;
  147. if (Options&AFDKD_BRIEF_DISPLAY) {
  148. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_HEADER);
  149. }
  150. //
  151. // Snag the address from the command line.
  152. //
  153. while (sscanf( argp, "%s%n", expr, &i )==1) {
  154. if( CheckControlC() ) {
  155. break;
  156. }
  157. argp += i;
  158. address = GetExpression (expr);
  159. result = GetFieldValue (address,
  160. "NT!_FILE_OBJECT",
  161. "FsContext",
  162. endpAddr);
  163. if (result!=0) {
  164. dprintf ("\nfile: Could not read FILE_OBJECT @ %p, err: %d\n",
  165. address, result);
  166. break;
  167. }
  168. result = (ULONG)InitTypeRead (endpAddr, AFD!AFD_ENDPOINT);
  169. if (result!=0) {
  170. dprintf ("\nfile: Could not read AFD_ENDPOINT @ %p, err: %d\n",
  171. endpAddr, result);
  172. break;
  173. }
  174. if (Options & AFDKD_BRIEF_DISPLAY) {
  175. DumpAfdEndpointBrief (
  176. endpAddr
  177. );
  178. }
  179. else {
  180. DumpAfdEndpoint (
  181. endpAddr
  182. );
  183. }
  184. if (Options & AFDKD_FIELD_DISPLAY) {
  185. ProcessFieldOutput (endpAddr, "AFD!AFD_ENDPOINT");
  186. }
  187. }
  188. if (Options&AFDKD_BRIEF_DISPLAY) {
  189. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_TRAILER);
  190. }
  191. return S_OK;
  192. } // file
  193. DECLARE_API( state )
  194. /*++
  195. Routine Description:
  196. Dumps all AFD_ENDPOINT structures in the given state.
  197. Arguments:
  198. None.
  199. Return Value:
  200. None.
  201. --*/
  202. {
  203. INT i;
  204. CHAR expr[MAX_ADDRESS_EXPRESSION];
  205. PCHAR argp;
  206. ULONG64 val;
  207. gClient = pClient;
  208. if (!CheckKmGlobals ()) {
  209. return E_INVALIDARG;
  210. }
  211. argp = ProcessOptions ((PCHAR)args);
  212. if (argp==NULL)
  213. return E_INVALIDARG;
  214. if (Options&AFDKD_BRIEF_DISPLAY) {
  215. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_HEADER);
  216. }
  217. //
  218. // Snag the state from the command line.
  219. //
  220. while (sscanf( argp, "%s%n", expr, &i )==1) {
  221. if( CheckControlC() ) {
  222. break;
  223. }
  224. argp+=i;
  225. val = GetExpression (expr);
  226. dprintf ("\nLooking for endpoints in state 0x%I64x ", val);
  227. EnumEndpoints(
  228. FindStateCallback,
  229. val
  230. );
  231. dprintf ("\nTotal endpoints: %ld", EntityCount);
  232. }
  233. if (Options&AFDKD_BRIEF_DISPLAY) {
  234. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_TRAILER);
  235. }
  236. else {
  237. dprintf ("\n");
  238. }
  239. return S_OK;
  240. } // state
  241. DECLARE_API( port )
  242. /*++
  243. Routine Description:
  244. Dumps all AFD_ENDPOINT structures bound to the given port.
  245. Arguments:
  246. None.
  247. Return Value:
  248. None.
  249. --*/
  250. {
  251. INT i;
  252. CHAR expr[MAX_ADDRESS_EXPRESSION];
  253. PCHAR argp;
  254. ULONG64 val;
  255. gClient = pClient;
  256. if (!CheckKmGlobals ()) {
  257. return E_INVALIDARG;
  258. }
  259. argp = ProcessOptions ((PCHAR)args);
  260. if (argp==NULL)
  261. return E_INVALIDARG;
  262. if (Options&AFDKD_BRIEF_DISPLAY) {
  263. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_HEADER);
  264. }
  265. //
  266. // Snag the port from the command line.
  267. //
  268. while (sscanf( argp, "%s%n", expr, &i)==1) {
  269. if( CheckControlC() ) {
  270. break;
  271. }
  272. argp+=i;
  273. val = GetExpression (expr);
  274. dprintf ("\nLooking for endpoints bound to port 0x%I64x (0x%I64d) ", val, val);
  275. EnumEndpoints(
  276. FindPortCallback,
  277. val
  278. );
  279. dprintf ("\nTotal endpoints: %ld", EntityCount);
  280. }
  281. if (Options&AFDKD_BRIEF_DISPLAY) {
  282. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_TRAILER);
  283. }
  284. else {
  285. dprintf ("\n");
  286. }
  287. return S_OK;
  288. } // port
  289. DECLARE_API( proc )
  290. /*++
  291. Routine Description:
  292. Dumps all AFD_ENDPOINT structures owned by the given process.
  293. Arguments:
  294. None.
  295. Return Value:
  296. None.
  297. --*/
  298. {
  299. INT i;
  300. CHAR expr[MAX_ADDRESS_EXPRESSION];
  301. PCHAR argp;
  302. ULONG64 val;
  303. BOOLEAN dumpedSomething = FALSE;
  304. gClient = pClient;
  305. if (!CheckKmGlobals ()) {
  306. return E_INVALIDARG;
  307. }
  308. argp = ProcessOptions ((PCHAR)args);
  309. if (argp==NULL)
  310. return E_INVALIDARG;
  311. if (Options&AFDKD_BRIEF_DISPLAY) {
  312. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_HEADER);
  313. }
  314. //
  315. // Snag the process from the command line.
  316. //
  317. expr[0] = 0;
  318. i = 0;
  319. while (sscanf( argp, "%s%n", expr, &i )==1 ||
  320. !dumpedSomething ) {
  321. dumpedSomething = TRUE;
  322. if( CheckControlC() ) {
  323. break;
  324. }
  325. argp+=i;
  326. val = GetExpression (expr);
  327. if (val<UserProbeAddress) {
  328. if (val!=0) {
  329. dprintf ("\nLooking for process with id %I64x", val);
  330. val = FindProcessByPid (val);
  331. if (val==0) {
  332. dprintf ("\n");
  333. return E_INVALIDARG;
  334. }
  335. }
  336. else {
  337. val = GetExpression ("@$proc");
  338. }
  339. }
  340. dprintf ("\nLooking for endpoints in process %p", val);
  341. EnumEndpoints(
  342. FindProcessCallback,
  343. val
  344. );
  345. dprintf ("\nTotal endpoints: %ld", EntityCount);
  346. }
  347. if (Options&AFDKD_BRIEF_DISPLAY) {
  348. dprintf (AFDKD_BRIEF_ENDPOINT_DISPLAY_TRAILER);
  349. }
  350. else {
  351. dprintf ("\n");
  352. }
  353. return S_OK;
  354. } // proc
  355. //
  356. // Private prototypes.
  357. //
  358. BOOL
  359. DumpEndpointCallback(
  360. ULONG64 ActualAddress,
  361. ULONG64 Context
  362. )
  363. /*++
  364. Routine Description:
  365. EnumEndpoints() callback for dumping AFD_ENDPOINTs.
  366. Arguments:
  367. Endpoint - The current AFD_ENDPOINT.
  368. ActualAddress - The actual address where the structure resides on the
  369. debugee.
  370. Context - The context value passed into EnumEndpoints().
  371. Return Value:
  372. BOOL - TRUE if enumeration should continue, FALSE if it should be
  373. terminated.
  374. --*/
  375. {
  376. if (!(Options & AFDKD_CONDITIONAL) ||
  377. CheckConditional (ActualAddress, "AFD!AFD_ENDPOINT") ) {
  378. if (Options & AFDKD_NO_DISPLAY)
  379. dprintf ("+");
  380. else {
  381. if (Options & AFDKD_BRIEF_DISPLAY) {
  382. DumpAfdEndpointBrief (
  383. ActualAddress
  384. );
  385. }
  386. else {
  387. DumpAfdEndpoint (
  388. ActualAddress
  389. );
  390. }
  391. if (Options & AFDKD_FIELD_DISPLAY) {
  392. ProcessFieldOutput (ActualAddress, "AFD!AFD_ENDPOINT");
  393. }
  394. }
  395. EntityCount += 1;
  396. }
  397. else
  398. dprintf (".");
  399. return TRUE;
  400. } // DumpEndpointCallback
  401. BOOL
  402. FindStateCallback(
  403. ULONG64 ActualAddress,
  404. ULONG64 Context
  405. )
  406. /*++
  407. Routine Description:
  408. EnumEndpoints() callback for finding AFD_ENDPOINTs in a specific state.
  409. Arguments:
  410. Endpoint - The current AFD_ENDPOINT.
  411. ActualAddress - The actual address where the structure resides on the
  412. debugee.
  413. Context - The context value passed into EnumEndpoints().
  414. Return Value:
  415. BOOL - TRUE if enumeration should continue, FALSE if it should be
  416. terminated.
  417. --*/
  418. {
  419. UCHAR state = (UCHAR)Context;
  420. UCHAR State;
  421. if (state==0x10) {
  422. if (ReadField (Listening)) {
  423. if (!(Options & AFDKD_CONDITIONAL) ||
  424. CheckConditional (ActualAddress, "AFD!AFD_ENDPOINT") ) {
  425. if (Options & AFDKD_NO_DISPLAY)
  426. dprintf ("+");
  427. else {
  428. if (Options & AFDKD_BRIEF_DISPLAY) {
  429. DumpAfdEndpointBrief (
  430. ActualAddress
  431. );
  432. }
  433. else {
  434. DumpAfdEndpoint (
  435. ActualAddress
  436. );
  437. }
  438. if (Options & AFDKD_FIELD_DISPLAY) {
  439. ProcessFieldOutput (ActualAddress, "AFD!AFD_ENDPOINT");
  440. }
  441. }
  442. EntityCount += 1;
  443. }
  444. else
  445. dprintf (".");
  446. }
  447. else {
  448. dprintf (".");
  449. }
  450. }
  451. else {
  452. State = (UCHAR)ReadField (State);
  453. if( (State == state) && !ReadField (Listening) ) {
  454. if (!(Options & AFDKD_CONDITIONAL) ||
  455. CheckConditional (ActualAddress, "AFD!AFD_ENDPOINT") ) {
  456. if (Options & AFDKD_NO_DISPLAY)
  457. dprintf ("+");
  458. else {
  459. if (Options & AFDKD_BRIEF_DISPLAY) {
  460. DumpAfdEndpointBrief (
  461. ActualAddress
  462. );
  463. }
  464. else {
  465. DumpAfdEndpoint (
  466. ActualAddress
  467. );
  468. }
  469. if (Options & AFDKD_FIELD_DISPLAY) {
  470. ProcessFieldOutput (ActualAddress, "AFD!AFD_ENDPOINT");
  471. }
  472. }
  473. EntityCount += 1;
  474. }
  475. else
  476. dprintf (".");
  477. }
  478. else {
  479. dprintf (".");
  480. }
  481. }
  482. return TRUE;
  483. } // FindStateCallback
  484. BOOL
  485. FindPortCallback(
  486. ULONG64 ActualAddress,
  487. ULONG64 Context
  488. )
  489. /*++
  490. Routine Description:
  491. EnumEndpoints() callback for finding AFD_ENDPOINT bound to a specific
  492. port.
  493. Arguments:
  494. Endpoint - The current AFD_ENDPOINT.
  495. ActualAddress - The actual address where the structure resides on the
  496. debugee.
  497. Context - The context value passed into EnumEndpoints().
  498. Return Value:
  499. BOOL - TRUE if enumeration should continue, FALSE if it should be
  500. terminated.
  501. --*/
  502. {
  503. TA_IP_ADDRESS ipAddress;
  504. ULONG result;
  505. USHORT endpointPort;
  506. ULONG64 address;
  507. ULONG length;
  508. address = ReadField (LocalAddress);
  509. length = (ULONG)ReadField (LocalAddressLength);
  510. if( ( length != sizeof(ipAddress) ) ||
  511. ( address == 0 ) ) {
  512. dprintf (".");
  513. return TRUE;
  514. }
  515. if( !ReadMemory(
  516. address,
  517. &ipAddress,
  518. sizeof(ipAddress),
  519. &result
  520. ) ) {
  521. dprintf(
  522. "\nFindPortCallback: Could not read localAddress for endpoint @ %p\n",
  523. address
  524. );
  525. return TRUE;
  526. }
  527. if( ( ipAddress.TAAddressCount != 1 ) ||
  528. ( ipAddress.Address[0].AddressLength != sizeof(TDI_ADDRESS_IP) ) ||
  529. ( ipAddress.Address[0].AddressType != TDI_ADDRESS_TYPE_IP ) ) {
  530. dprintf (".");
  531. return TRUE;
  532. }
  533. endpointPort = NTOHS(ipAddress.Address[0].Address[0].sin_port);
  534. if( endpointPort == (USHORT)Context ) {
  535. if (!(Options & AFDKD_CONDITIONAL) ||
  536. CheckConditional (ActualAddress, "AFD!AFD_ENDPOINT") ) {
  537. if (Options & AFDKD_NO_DISPLAY)
  538. dprintf ("+");
  539. else {
  540. if (Options & AFDKD_BRIEF_DISPLAY) {
  541. DumpAfdEndpointBrief (
  542. ActualAddress
  543. );
  544. }
  545. else {
  546. DumpAfdEndpoint (
  547. ActualAddress
  548. );
  549. }
  550. if (Options & AFDKD_FIELD_DISPLAY) {
  551. ProcessFieldOutput (ActualAddress, "AFD!AFD_ENDPOINT");
  552. }
  553. }
  554. EntityCount += 1;
  555. }
  556. else
  557. dprintf (".");
  558. }
  559. else {
  560. dprintf (".");
  561. }
  562. return TRUE;
  563. } // FindPortCallback
  564. BOOL
  565. FindProcessCallback(
  566. ULONG64 ActualAddress,
  567. ULONG64 Context
  568. )
  569. /*++
  570. Routine Description:
  571. EnumEndpoints() callback for finding AFD_ENDPOINTs owned by a specific
  572. process.
  573. Arguments:
  574. Endpoint - The current AFD_ENDPOINT.
  575. ActualAddress - The actual address where the structure resides on the
  576. debugee.
  577. Context - The context value passed into EnumEndpoints().
  578. Return Value:
  579. BOOL - TRUE if enumeration should continue, FALSE if it should be
  580. terminated.
  581. --*/
  582. {
  583. ULONG64 process;
  584. if (SavedMinorVersion>=2419) {
  585. process = ReadField (OwningProcess);
  586. }
  587. else {
  588. process = ReadField (ProcessCharge.Process);
  589. }
  590. if( process == Context ) {
  591. if (!(Options & AFDKD_CONDITIONAL) ||
  592. CheckConditional (ActualAddress, "AFD!AFD_ENDPOINT") ) {
  593. if (Options & AFDKD_NO_DISPLAY)
  594. dprintf ("+");
  595. else {
  596. if (Options & AFDKD_BRIEF_DISPLAY) {
  597. DumpAfdEndpointBrief (
  598. ActualAddress
  599. );
  600. }
  601. else {
  602. DumpAfdEndpoint (
  603. ActualAddress
  604. );
  605. }
  606. if (Options & AFDKD_FIELD_DISPLAY) {
  607. ProcessFieldOutput (ActualAddress, "AFD!AFD_ENDPOINT");
  608. }
  609. }
  610. EntityCount += 1;
  611. }
  612. else
  613. dprintf (".");
  614. }
  615. else {
  616. dprintf (".");
  617. }
  618. return TRUE;
  619. } // FindProcessCallback
  620. ULONG
  621. FindProcessByPidCallback (
  622. PFIELD_INFO pField,
  623. PVOID UserContext
  624. )
  625. {
  626. PULONG64 pProcess = UserContext;
  627. ULONG64 Pid;
  628. ULONG result;
  629. result = GetFieldValue (
  630. pField->address,
  631. "NT!_EPROCESS",
  632. "UniqueProcessId",
  633. Pid
  634. );
  635. if (result==0) {
  636. if (Pid==*pProcess) {
  637. *pProcess = pField->address;
  638. result = 1;
  639. }
  640. else
  641. dprintf (".");
  642. }
  643. else {
  644. dprintf ("\nFindProcessByPidCallback: Could not read process @ %p, err: %ld\n",
  645. pField->address, result);
  646. *pProcess = 0;
  647. }
  648. return result;
  649. }
  650. ULONG64
  651. FindProcessByPid (
  652. ULONG64 Pid
  653. )
  654. {
  655. ULONG64 Process, Start;
  656. if (DebuggerData.PsActiveProcessHead==0) {
  657. dprintf ("\nFindProcessByPid: PsActiveProcessHead is NULL!!!\n");
  658. return 0;
  659. }
  660. if (ReadPtr (DebuggerData.PsActiveProcessHead, &Start)!=0) {
  661. dprintf ("\nFindProcessByPid: Can't read PsActiveProcessHead!!!\n");
  662. return 0;
  663. }
  664. Process = Pid;
  665. ListType (
  666. "NT!_EPROCESS", // Type
  667. Start, // Address
  668. 1, // ListByFieldAddress
  669. "ActiveProcessLinks.Flink", // NextPointer
  670. &Process, // Context
  671. FindProcessByPidCallback
  672. );
  673. if (Process!=Pid)
  674. return Process;
  675. else
  676. return 0;
  677. }