Source code of Windows XP (NT5)
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.

1348 lines
30 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. nbext.c
  5. Abstract:
  6. This file contains kernel debugger extensions for examining the
  7. NB structure.
  8. Author:
  9. Munil Shah (munils) 18-May-1995
  10. Environment:
  11. User Mode
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "isn.h"
  16. #include "isnnb.h"
  17. #include "zwapi.h"
  18. #include "config.h"
  19. #include "nbitypes.h"
  20. PCHAR HandlerNames[] = { "Connection", "Disconnect", "Error", "Receive", "ReceiveDatagram", "ExpeditedData" };
  21. INT NumArgsRead = 0;
  22. //
  23. // Local function prototypes
  24. //
  25. VOID
  26. DumpAddrFile(
  27. ULONG AddrFileToDump
  28. );
  29. VOID
  30. DumpAddrObj(
  31. ULONG AddrObjToDump
  32. );
  33. VOID
  34. DumpConn(
  35. ULONG ConnToDump,
  36. BOOLEAN Full
  37. );
  38. VOID
  39. Dumpdevice(
  40. ULONG deviceToDump,
  41. BOOLEAN Full
  42. );
  43. VOID
  44. DumpSPacketList(
  45. ULONG _objAddr,
  46. ULONG MaxCount,
  47. BOOLEAN Full
  48. );
  49. ///////////////////////////////////////////////////////////////////////
  50. // ADDRESS_FILE
  51. //////////////////////////////////////////////////////////////////////
  52. #define _obj addrfile
  53. #define _objAddr AddrFileToDump
  54. #define _objType ADDRESS_FILE
  55. //
  56. // Exported functions
  57. //
  58. DECLARE_API( nbaddrfile )
  59. /*++
  60. Routine Description:
  61. Dumps the most important fields of the specified ADDRESS_FILE object
  62. Arguments:
  63. args - Address of args string
  64. Return Value:
  65. None
  66. --*/
  67. {
  68. ULONG addrFileToDump = 0;
  69. if (!*args) {
  70. dprintf("No address_file object specified\n");
  71. }
  72. else {
  73. NumArgsRead = sscanf(args, "%lx", &addrFileToDump);
  74. if (NumArgsRead) {
  75. DumpAddrFile(addrFileToDump);
  76. }
  77. else {
  78. dprintf("Bad argument for address_file object <%s>\n", args);
  79. }
  80. }
  81. return;
  82. }
  83. //
  84. // Local functions
  85. //
  86. VOID
  87. DumpAddrFile(
  88. ULONG AddrFileToDump
  89. )
  90. /*++
  91. Routine Description:
  92. Dumps the fields of the specified ADDRESS_FILE object
  93. Arguments:
  94. AddrFileToDump - The ADDRESS_FILE object to display
  95. Full - Display a partial listing if 0, full listing otherwise.
  96. Return Value:
  97. None
  98. --*/
  99. {
  100. ADDRESS_FILE addrfile;
  101. ULONG result;
  102. UCHAR i;
  103. if (!ReadMemory(
  104. AddrFileToDump,
  105. &addrfile,
  106. sizeof(addrfile),
  107. &result
  108. )
  109. )
  110. {
  111. dprintf("%08lx: Could not read address object\n", AddrFileToDump);
  112. return;
  113. }
  114. if (addrfile.Type != NB_ADDRESSFILE_SIGNATURE) {
  115. dprintf("Signature does not match, probably not an address object\n");
  116. return;
  117. }
  118. dprintf("NBI AddressFile:\n");
  119. PrintStart
  120. PrintXUChar(State);
  121. PrintXULong(ReferenceCount);
  122. PrintPtr(FileObject);
  123. PrintPtr(Address);
  124. PrintPtr(OpenRequest);
  125. PrintPtr(CloseRequest);
  126. PrintLL(Linkage);
  127. PrintLL(ConnectionDatabase);
  128. PrintLL(ReceiveDatagramQueue);
  129. PrintEnd
  130. for ( i= TDI_EVENT_CONNECT; i < TDI_EVENT_SEND_POSSIBLE ; i++ ) {
  131. dprintf(" %sHandler = %lx, Registered = %s, Context = %lx\n",
  132. HandlerNames[i], addrfile.Handlers[i], PRINTBOOL(addrfile.RegisteredHandler[i]),addrfile.HandlerContexts[i] );
  133. }
  134. return;
  135. }
  136. ///////////////////////////////////////////////////////////////////////
  137. // ADDRESS
  138. //////////////////////////////////////////////////////////////////////
  139. #undef _obj
  140. #undef _objAddr
  141. #undef _objType
  142. #define _obj addrobj
  143. #define _objAddr AddrObjToDump
  144. #define _objType ADDRESS
  145. DECLARE_API( nbaddr )
  146. /*++
  147. Routine Description:
  148. Dumps the most important fields of the specified ADDRESS object
  149. Arguments:
  150. args - Address of args string
  151. Return Value:
  152. None
  153. --*/
  154. {
  155. ULONG addrobjToDump = 0;
  156. if (!*args) {
  157. dprintf("No address object specified\n");
  158. }
  159. else {
  160. NumArgsRead = sscanf(args, "%lx", &addrobjToDump);
  161. if (NumArgsRead) {
  162. DumpAddrObj(addrobjToDump);
  163. }
  164. else {
  165. dprintf("Bad argument for address object <%s>\n", args);
  166. }
  167. }
  168. return;
  169. }
  170. //
  171. // Local functions
  172. //
  173. VOID
  174. PrintNetbiosName(
  175. PUCHAR Name
  176. )
  177. /*++
  178. Routine Description:
  179. Prints out a Netbios name.
  180. Arguments:
  181. Name - The array containing the name to print.
  182. Return Value:
  183. None
  184. --*/
  185. {
  186. ULONG i;
  187. for (i=0; i<16; i++) {
  188. dprintf("%c", Name[i]);
  189. }
  190. return;
  191. }
  192. VOID
  193. DumpAddrObj(
  194. ULONG AddrObjToDump
  195. )
  196. /*++
  197. Routine Description:
  198. Dumps the fields of the specified ADDRESS object
  199. Arguments:
  200. AddrObjToDump - The address object to display
  201. Full - Display a partial listing if 0, full listing otherwise.
  202. Return Value:
  203. None
  204. --*/
  205. {
  206. ADDRESS addrobj;
  207. ULONG result;
  208. NBI_NETBIOS_ADDRESS nbaddr;
  209. if (!ReadMemory(
  210. AddrObjToDump,
  211. &addrobj,
  212. sizeof(addrobj),
  213. &result
  214. )
  215. )
  216. {
  217. dprintf("%08lx: Could not read address object\n", AddrObjToDump);
  218. return;
  219. }
  220. if (addrobj.Type != NB_ADDRESS_SIGNATURE) {
  221. dprintf("Signature does not match, probably not an address object\n");
  222. return;
  223. }
  224. dprintf("NB Address:\n");
  225. PrintStart
  226. PrintXULong(State);
  227. PrintXULong(Flags);
  228. PrintULong(ReferenceCount);
  229. PrintLL(Linkage);
  230. PrintEnd
  231. // Print the netbiosname info.
  232. PrintFieldName("NetbiosName");
  233. PrintNetbiosName(addrobj.NetbiosAddress.NetbiosName); dprintf("\n");
  234. dprintf(" %25s = 0x%8x %25s = %10s\n", "NetbiosNameType",addrobj.NetbiosAddress.NetbiosNameType,"Broadcast",PRINTBOOL(addrobj.NetbiosAddress.Broadcast));
  235. PrintStart
  236. PrintLL(AddressFileDatabase);
  237. PrintAddr(RegistrationTimer);
  238. PrintXULong(RegistrationCount);
  239. PrintPtr(SecurityDescriptor);
  240. PrintEnd
  241. return;
  242. }
  243. ///////////////////////////////////////////////////////////////////////
  244. // CONNECTION_FILE
  245. //////////////////////////////////////////////////////////////////////
  246. #undef _obj
  247. #undef _objAddr
  248. #undef _objType
  249. #define _obj conn
  250. #define _objAddr ConnToDump
  251. #define _objType CONNECTION
  252. DECLARE_API( nbconn )
  253. /*++
  254. Routine Description:
  255. Dumps the most important fields of the specified CONNECTION object
  256. Arguments:
  257. args - Address
  258. Return Value:
  259. None
  260. --*/
  261. {
  262. ULONG connToDump = 0;
  263. if (!*args) {
  264. dprintf("No conn specified\n");
  265. }
  266. else {
  267. NumArgsRead = sscanf(args, "%lx", &connToDump);
  268. if (NumArgsRead) {
  269. DumpConn(connToDump, FALSE);
  270. }
  271. else {
  272. dprintf("Bad argument for conn object <%s>\n", args);
  273. }
  274. }
  275. return;
  276. }
  277. DECLARE_API( nbconnfull )
  278. /*++
  279. Routine Description:
  280. Dumps all of the fields of the specified CONNECTION object
  281. Arguments:
  282. args - Address
  283. Return Value:
  284. None
  285. --*/
  286. {
  287. ULONG connToDump = 0;
  288. if (!*args) {
  289. dprintf("No conn specified\n");
  290. }
  291. else {
  292. NumArgsRead = sscanf(args, "%lx", &connToDump);
  293. if (NumArgsRead) {
  294. DumpConn(connToDump, TRUE);
  295. }
  296. else {
  297. dprintf("Bad argument for conn object <%s>\n", args);
  298. }
  299. }
  300. return;
  301. }
  302. //
  303. // Local functions
  304. //
  305. VOID
  306. printSendPtr(
  307. PSEND_POINTER SendPtr,
  308. PSEND_POINTER UnAckedPtr
  309. )
  310. {
  311. dprintf(" CurrentSend UnackedSend\n");
  312. dprintf(" MessageOffset 0x%-8lx 0x%-8lx\n", SendPtr->MessageOffset,UnAckedPtr->MessageOffset);
  313. dprintf(" Request 0x%-8lx 0x%-8lx\n", SendPtr->Request,UnAckedPtr->Request);
  314. dprintf(" Buffer 0x%-8lx 0x%-8lx\n", SendPtr->Buffer,UnAckedPtr->Buffer);
  315. dprintf(" BufferOffset 0x%-8lx 0x%-8lx\n", SendPtr->BufferOffset,UnAckedPtr->BufferOffset);
  316. dprintf(" SendSequence 0x%-8x 0x%-8x\n", SendPtr->SendSequence,UnAckedPtr->SendSequence);
  317. }
  318. VOID
  319. printRcvPtr(
  320. PRECEIVE_POINTER CurrentPtr,
  321. PRECEIVE_POINTER PreviousPtr
  322. )
  323. {
  324. dprintf(" CurrentReceive PreviousReceive\n");
  325. dprintf(" MessageOffset 0x%-8lx 0x%-8lx\n", CurrentPtr->MessageOffset,PreviousPtr->MessageOffset);
  326. dprintf(" Offset 0x%-8lx 0x%-8lx\n", CurrentPtr->Offset,PreviousPtr->Offset);
  327. dprintf(" Buffer 0x%-8lx 0x%-8lx\n", CurrentPtr->Buffer,PreviousPtr->Buffer);
  328. dprintf(" BufferOffset 0x%-8lx 0x%-8lx\n", CurrentPtr->BufferOffset,PreviousPtr->BufferOffset);
  329. }
  330. VOID
  331. DumpConn(
  332. ULONG ConnToDump,
  333. BOOLEAN Full
  334. )
  335. /*++
  336. Routine Description:
  337. Dumps the fields of the specified CONNECTION object
  338. Arguments:
  339. ConnToDump - The conn object to display
  340. Full - Display a partial listing if 0, full listing otherwise.
  341. Return Value:
  342. None
  343. --*/
  344. {
  345. CONNECTION conn;
  346. ULONG result;
  347. if (!ReadMemory(
  348. ConnToDump,
  349. &conn,
  350. sizeof(conn),
  351. &result
  352. )
  353. )
  354. {
  355. dprintf("%08lx: Could not read conn\n", ConnToDump);
  356. return;
  357. }
  358. if (conn.Type != NB_CONNECTION_SIGNATURE) {
  359. dprintf("Signature does not match, probably not a conn\n");
  360. return;
  361. }
  362. dprintf("NBI Connection General:\n");
  363. PrintStart
  364. PrintXULong(State);
  365. PrintXULong(SubState);
  366. PrintXULong(ReceiveState);
  367. PrintXULong(ReferenceCount);
  368. PrintXUShort(LocalConnectionId);
  369. PrintXUShort(RemoteConnectionId);
  370. PrintAddr(LocalTarget);
  371. PrintAddr(RemoteHeader);
  372. PrintPtr(Context);
  373. PrintPtr(AddressFile);
  374. PrintXULong(AddressFileLinked);
  375. PrintPtr(NextConnection);
  376. PrintEnd
  377. dprintf(" RemoteName = ");PrintNetbiosName((PUCHAR)conn.RemoteName);dprintf("\n");
  378. dprintf("\n\nConnection Send Info:\n");
  379. PrintStart
  380. PrintIrpQ(SendQueue);
  381. PrintXUShort(SendWindowSequenceLimit);
  382. PrintXUShort(SendWindowSize);
  383. PrintEnd
  384. printSendPtr( &conn.CurrentSend, &conn.UnAckedSend );
  385. if( Full ) {
  386. PrintStart
  387. PrintXUShort(MaxSendWindowSize);
  388. PrintBool(RetransmitThisWindow);
  389. PrintBool(SendWindowIncrease);
  390. PrintBool(ResponseTimeout);
  391. PrintBool(SendBufferInUse);
  392. PrintPtr(FirstMessageRequest);
  393. PrintPtr(LastMessageRequest);
  394. PrintXULong(MaximumPacketSize);
  395. PrintXULong(CurrentMessageLength);
  396. PrintEnd
  397. }
  398. dprintf("\n\nConnection Receive Info:\n");
  399. PrintStart
  400. PrintIrpQ(ReceiveQueue);
  401. PrintXUShort(ReceiveSequence);
  402. PrintXUShort(ReceiveWindowSize);
  403. PrintXUShort(LocalRcvSequenceMax);
  404. PrintXUShort(RemoteRcvSequenceMax);
  405. PrintPtr(ReceiveRequest);
  406. PrintXULong(ReceiveLength);
  407. PrintEnd
  408. printRcvPtr( &conn.CurrentReceive, &conn.PreviousReceive );
  409. if( Full ) {
  410. PrintStart
  411. PrintXULong(ReceiveUnaccepted);
  412. PrintXULong(CurrentIndicateOffset);
  413. PrintBool(NoPiggybackHeuristic);
  414. PrintBool(PiggybackAckTimeout);
  415. PrintBool(CurrentReceiveNoPiggyback);
  416. PrintBool(DataAckPending);
  417. PrintEnd
  418. }
  419. if( Full ) {
  420. PrintStart
  421. PrintPtr(ListenRequest);
  422. PrintPtr(AcceptRequest);
  423. PrintPtr(ClosePending);
  424. PrintPtr(DisassociatePending);
  425. PrintPtr(DisconnectWaitRequest);
  426. PrintPtr(DisconnectRequest);
  427. PrintPtr(ConnectRequest);
  428. PrintEnd
  429. PrintStart
  430. PrintLL(PacketizeLinkage);
  431. PrintBool(OnPacketizeQueue);
  432. PrintLL(WaitPacketLinkage);
  433. PrintBool(OnWaitPacketQueue);
  434. PrintLL(DataAckLinkage);
  435. PrintBool(OnDataAckQueue);
  436. PrintBool(IgnoreNextDosProbe);
  437. PrintXULong(NdisSendsInProgress);
  438. PrintLL(NdisSendQueue);
  439. PrintPtr(NdisSendReference);
  440. PrintXULong(Retries);
  441. PrintXULong(Status);
  442. PrintBool(FindRouteInProgress);
  443. PrintXULong(CanBeDestroyed);
  444. PrintBool(OnShortList);
  445. PrintLL(ShortList);
  446. PrintLL(LongList);
  447. PrintBool(OnLongList);
  448. PrintXULong(BaseRetransmitTimeout);
  449. PrintXULong(CurrentRetransmitTimeout);
  450. PrintXULong(WatchdogTimeout);
  451. PrintXULong(Retransmit);
  452. PrintXULong(Watchdog);
  453. PrintEnd
  454. PrintStart
  455. PrintAddr(ConnectionInfo);
  456. PrintAddr(Timer);
  457. PrintAddr(FindRouteRequest);
  458. PrintPtr(NextConnection);
  459. PrintAddr(SessionInitAckData);
  460. PrintXULong(SessionInitAckDataLength);
  461. PrintAddr(SendPacket);
  462. PrintAddr(SendPacketHeader);
  463. PrintBool(SendPacketInUse);
  464. PrintAddr(LineInfo);
  465. #ifdef RSRC_TIMEOUT_DBG
  466. PrintXULong(FirstMessageRequestTime.HighPart);
  467. PrintXULong(FirstMessageRequestTime.LowPart);
  468. #endif RSRC_TIMEOUT_DBG
  469. }
  470. return;
  471. }
  472. ///////////////////////////////////////////////////////////////////////
  473. // DEVICE
  474. //////////////////////////////////////////////////////////////////////
  475. #undef _obj
  476. #undef _objAddr
  477. #undef _objType
  478. #define _obj device
  479. #define _objAddr deviceToDump
  480. #define _objType DEVICE
  481. //
  482. // Exported functions
  483. //
  484. DECLARE_API( nbdev )
  485. /*++
  486. Routine Description:
  487. Dumps the most important fields of the specified DEVICE_CONTEXT object
  488. Arguments:
  489. args - Address
  490. Return Value:
  491. None
  492. --*/
  493. {
  494. ULONG deviceToDump = 0;
  495. ULONG pDevice = 0;
  496. ULONG result;
  497. if (!*args) {
  498. pDevice = GetExpression( "nwlnknb!NbiDevice" );
  499. if ( !pDevice ) {
  500. dprintf("Could not get NbiDevice, Try !reload\n");
  501. return;
  502. } else {
  503. if (!ReadMemory(pDevice,
  504. &deviceToDump,
  505. sizeof(deviceToDump),
  506. &result
  507. )
  508. )
  509. {
  510. dprintf("%08lx: Could not read device address\n", pDevice);
  511. return;
  512. }
  513. }
  514. }
  515. else {
  516. NumArgsRead = sscanf(args, "%lx", &deviceToDump);
  517. if (0 == NumArgsRead) {
  518. dprintf("Bad argument for NbiDevice <%s>\n", args);
  519. return;
  520. }
  521. }
  522. Dumpdevice(deviceToDump, FALSE);
  523. return;
  524. }
  525. DECLARE_API( nbdevfull )
  526. /*++
  527. Routine Description:
  528. Dumps all of the fields of the specified DEVICE_CONTEXT object
  529. Arguments:
  530. args - Address
  531. Return Value:
  532. None
  533. --*/
  534. {
  535. ULONG deviceToDump = 0;
  536. ULONG pDevice = 0;
  537. ULONG result;
  538. if (!*args) {
  539. pDevice = GetExpression( "nwlnknb!NbiDevice" );
  540. if ( !pDevice ) {
  541. dprintf("Could not get NbiDevice, Try !reload\n");
  542. return;
  543. } else {
  544. if (!ReadMemory(pDevice,
  545. &deviceToDump,
  546. sizeof(deviceToDump),
  547. &result
  548. )
  549. )
  550. {
  551. dprintf("%08lx: Could not read device address\n", pDevice);
  552. return;
  553. }
  554. }
  555. }
  556. else {
  557. NumArgsRead = sscanf(args, "%lx", &deviceToDump);
  558. if (0 == NumArgsRead) {
  559. dprintf("Bad argument for NbiDevice <%s>\n", args);
  560. return;
  561. }
  562. }
  563. Dumpdevice(deviceToDump, TRUE);
  564. return;
  565. }
  566. //
  567. // Local functions
  568. //
  569. VOID
  570. Dumpdevice(
  571. ULONG deviceToDump,
  572. BOOLEAN Full
  573. )
  574. /*++
  575. Routine Description:
  576. Dumps the fields of the specified DEVICE_CONTEXT structure
  577. Arguments:
  578. deviceToDump - The device context object to display
  579. Full - Display a partial listing if 0, full listing otherwise.
  580. Return Value:
  581. None
  582. --*/
  583. {
  584. DEVICE device;
  585. ULONG result;
  586. if (!ReadMemory(
  587. deviceToDump,
  588. &device,
  589. sizeof(device),
  590. &result
  591. )
  592. )
  593. {
  594. dprintf("%08lx: Could not read device context\n", deviceToDump);
  595. return;
  596. }
  597. if (device.Type != NB_DEVICE_SIGNATURE) {
  598. dprintf("Signature does not match, probably not a device object %lx\n",deviceToDump);
  599. return;
  600. }
  601. dprintf("Device General Info:\n");
  602. PrintStart
  603. PrintXUChar(State);
  604. PrintXULong(ReferenceCount);
  605. PrintXUShort(MaximumNicId);
  606. PrintXULong(MemoryUsage);
  607. PrintXULong(MemoryLimit);
  608. PrintXULong(AddressCount);
  609. PrintXULong(AllocatedSendPackets);
  610. PrintXULong(AllocatedReceivePackets);
  611. PrintXULong(AllocatedReceiveBuffers);
  612. PrintXULong(MaxReceiveBuffers);
  613. PrintLL(AddressDatabase);
  614. PrintL(SendPacketList);
  615. PrintL(ReceivePacketList);
  616. PrintLL(GlobalReceiveBufferList);
  617. PrintLL(GlobalSendPacketList);
  618. PrintLL(GlobalReceivePacketList);
  619. PrintLL(GlobalReceiveBufferList);
  620. PrintLL(SendPoolList);
  621. PrintLL(ReceivePoolList);
  622. PrintLL(ReceiveBufferPoolList);
  623. PrintLL(ReceiveCompletionQueue);
  624. PrintLL(WaitPacketConnections);
  625. PrintLL(PacketizeConnections);
  626. PrintLL(WaitingConnects);
  627. PrintLL(WaitingDatagrams);
  628. PrintLL(WaitingAdapterStatus);
  629. PrintLL(WaitingNetbiosFindName);
  630. PrintLL(ActiveAdapterStatus);
  631. PrintLL(ReceiveDatagrams);
  632. PrintLL(ConnectIndicationInProgress);
  633. PrintLL(ListenQueue);
  634. PrintLL(WaitingFindNames);
  635. if ( Full ) {
  636. PrintStart
  637. PrintBool(UnloadWaiting);
  638. PrintBool(DataAckQueueChanged);
  639. PrintBool(ShortListActive);
  640. PrintBool(DataAckActive);
  641. PrintBool(TimersInitialized);
  642. PrintBool(ProcessingShortTimer);
  643. PrintAddr(ShortTimerStart);
  644. PrintAddr(ShortTimer);
  645. PrintXULong(ShortAbsoluteTime);
  646. PrintAddr(LongTimer);
  647. PrintXULong(LongAbsoluteTime);
  648. PrintLL(ShortList);
  649. PrintLL(LongList);
  650. PrintAddr(TimerLock);
  651. PrintEnd
  652. }
  653. if ( Full ) {
  654. PrintStart
  655. PrintXUShort(FindNameTime);
  656. PrintBool(FindNameTimerActive);
  657. PrintAddr(FindNameTimer);
  658. PrintXULong(FindNameTimeout);
  659. PrintXULong(FindNamePacketCount);
  660. PrintLL(WaitingFindNames);
  661. PrintEnd
  662. PrintStart
  663. PrintXULong(AckDelayTime );
  664. PrintXULong(AckWindow );
  665. PrintXULong(AckWindowThreshold );
  666. PrintXULong(EnablePiggyBackAck );
  667. PrintXULong(Extensions );
  668. PrintXULong(RcvWindowMax );
  669. PrintXULong(BroadcastCount );
  670. PrintXULong(BroadcastTimeout );
  671. PrintXULong(ConnectionCount );
  672. PrintXULong(ConnectionTimeout );
  673. PrintXULong(InitPackets );
  674. PrintXULong(MaxPackets );
  675. PrintXULong(InitialRetransmissionTime);
  676. PrintXULong(Internet );
  677. PrintXULong(KeepAliveCount );
  678. PrintXULong(KeepAliveTimeout );
  679. PrintXULong(RetransmitMax );
  680. PrintXULong(RouterMtu);
  681. PrintEnd
  682. }
  683. PrintPtr(NameCache);
  684. PrintXUShort(CacheTimeStamp);
  685. PrintAddr(Bind);
  686. PrintAddr( ConnectionHash);
  687. PrintAddr( ConnectionlessHeader );
  688. PrintAddr( UnloadEvent );
  689. PrintAddr(Information);
  690. PrintAddr(Statistics);
  691. PrintEnd
  692. return;
  693. }
  694. //////////////Send Packet////////////
  695. #undef _obj
  696. #undef _objAddr
  697. #undef _objType
  698. #define _obj spacket
  699. #define _objAddr spacketToDump
  700. #define _objType NB_SEND_RESERVED
  701. //
  702. // Exported functions
  703. //
  704. DECLARE_API( nbspacketlist )
  705. /*++
  706. Routine Description:
  707. Arguments:
  708. args - Address
  709. Return Value:
  710. None
  711. --*/
  712. {
  713. DEVICE NbiDevice;
  714. DEVICE *pDevice;
  715. PNB_SEND_RESERVED pFirstPacket;
  716. ULONG result;
  717. char szPacketCount[MAX_LIST_VARIABLE_NAME_LENGTH + 1];
  718. ULONG MaxCount = 0; // default value means dump all packets!
  719. if ((!*args) || (*args && *args == '-'))
  720. {
  721. //
  722. // No initial packet has been defined, so set the initial packet
  723. // from the global pool list
  724. //
  725. if (!(pDevice = (DEVICE *) GetExpression("nwlnknb!NbiDevice")))
  726. {
  727. dprintf("Could not get NbiDevice, Try !reload\n");
  728. return;
  729. }
  730. if (!ReadMemory((ULONG) pDevice, &pDevice, sizeof(DEVICE *), &result))
  731. {
  732. dprintf("%08lx: Could not read device address\n", pDevice);
  733. return;
  734. }
  735. if (!ReadMemory((ULONG) pDevice, &NbiDevice, sizeof(DEVICE), &result))
  736. {
  737. dprintf("%08lx: Could not read device information\n", pDevice);
  738. return;
  739. }
  740. //
  741. // Now, compute the address of the first packet from the GlobalSendPacketList field
  742. //
  743. if (NbiDevice.GlobalSendPacketList.Flink == &pDevice->GlobalSendPacketList)
  744. {
  745. dprintf("%08lx: Device GlobalSendPacketList @%08lx is empty\n", &pDevice->GlobalSendPacketList);
  746. return;
  747. }
  748. pFirstPacket = CONTAINING_RECORD (NbiDevice.GlobalSendPacketList.Flink, NB_SEND_RESERVED, GlobalLinkage);
  749. }
  750. else
  751. {
  752. //
  753. // Read in the address for the first packet
  754. //
  755. NumArgsRead = sscanf(args, "%lx", &pFirstPacket);
  756. if (0 == NumArgsRead) {
  757. dprintf("Bad argument for FirstPacket <%s>\n", args);
  758. return;
  759. }
  760. }
  761. if (ReadArgsForTraverse (args, szPacketCount))
  762. {
  763. NumArgsRead = sscanf(szPacketCount, "%lx", &MaxCount);
  764. if (0 == NumArgsRead) {
  765. dprintf("Bad argument for PacketCount <%s>\n", szPacketCount);
  766. return;
  767. }
  768. }
  769. DumpSPacketList((ULONG) pFirstPacket, MaxCount, FALSE);
  770. return;
  771. }
  772. //
  773. // Local functions
  774. //
  775. ULONG
  776. DumpSPacket(
  777. ULONG _objAddr,
  778. BOOLEAN Full
  779. )
  780. {
  781. _objType _obj;
  782. ULONG result;
  783. ULONG next;
  784. if (!ReadMemory(
  785. _objAddr,
  786. &_obj,
  787. sizeof(_obj),
  788. &result
  789. )
  790. )
  791. {
  792. dprintf("%08lx: Could not read spacket\n", spacketToDump);
  793. return 0;
  794. }
  795. dprintf( "%s @ %08lx\n", "Send Packet", _objAddr );
  796. PrintStartStruct();
  797. PrintBool(SendInProgress);
  798. PrintXUChar(Type);
  799. PrintBool(OwnedByConnection);
  800. PrintPtr(Header);
  801. switch(_obj.Type) {
  802. case SEND_TYPE_DATAGRAM:
  803. PrintPtr(u.SR_DG.DatagramRequest);
  804. PrintPtr(u.SR_DG.AddressFile);
  805. PrintPtr(u.SR_DG.Cache);
  806. break;
  807. case SEND_TYPE_NAME_FRAME:
  808. PrintPtr(u.SR_NF.Address);
  809. PrintPtr(u.SR_NF.Request);
  810. PrintPtr(u.SR_NF.AddressFile);
  811. break;
  812. case SEND_TYPE_FIND_NAME:
  813. PrintAddr(u.SR_FN.NetbiosName);
  814. break;
  815. case SEND_TYPE_SESSION_NO_DATA:
  816. PrintPtr(u.SR_CO.Connection);
  817. break;
  818. case SEND_TYPE_SESSION_DATA:
  819. PrintPtr(u.SR_CO.Connection);
  820. PrintPtr(u.SR_CO.Request);
  821. break;
  822. case SEND_TYPE_SESSION_INIT:
  823. break;
  824. case SEND_TYPE_STATUS_QUERY:
  825. case SEND_TYPE_STATUS_RESPONSE:
  826. break;
  827. }
  828. PrintEndStruct();
  829. return( (ULONG) CONTAINING_RECORD( _obj.GlobalLinkage.Flink, _objType, GlobalLinkage));
  830. }
  831. VOID
  832. DumpSPacketList(
  833. ULONG pFirstPacket,
  834. ULONG MaxCount,
  835. BOOLEAN Full
  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. ULONG nextSPacket;
  848. ULONG count = 0;
  849. nextSPacket = pFirstPacket;
  850. do
  851. {
  852. nextSPacket = DumpSPacket( nextSPacket, Full );
  853. if (++count == MaxCount)
  854. {
  855. break;
  856. }
  857. } while( nextSPacket && (nextSPacket != pFirstPacket ));
  858. dprintf("\nDumped %d Packets (%s)\n", count, (MaxCount ? "MaxCount specified" : "all packets"));
  859. return;
  860. }
  861. ///////////////////////////////////////////////////////////////////////
  862. // CACHE
  863. //////////////////////////////////////////////////////////////////////
  864. VOID
  865. DumpLocalAddresses(
  866. PLIST_ENTRY pHead
  867. )
  868. /*++
  869. Routine Description:
  870. Dumps the fields of the specified DEVICE_CONTEXT structure
  871. Arguments:
  872. deviceToDump - The device context object to display
  873. Full - Display a partial listing if 0, full listing otherwise.
  874. Return Value:
  875. None
  876. --*/
  877. {
  878. PLIST_ENTRY pEntry;
  879. ADDRESS *pAddress;
  880. ADDRESS Address;
  881. ULONG Result;
  882. ULONG Count = 0;
  883. dprintf("\nDumping Local Address Names:\n");
  884. dprintf("----------------------------\n");
  885. if (!ReadMemory ((ULONG) pHead, &pEntry, sizeof(PLIST_ENTRY), &Result))
  886. {
  887. dprintf("%p: Could not read pHead info\n", pHead);
  888. return;
  889. }
  890. dprintf("RefC <Address> => <Name > | State |NTFlag| Flags | BCast\n");
  891. dprintf("-------------------------------------------------------------------------------\n");
  892. while (pEntry != pHead)
  893. {
  894. pAddress = CONTAINING_RECORD (pEntry, ADDRESS, Linkage);
  895. if (!ReadMemory((ULONG) pAddress, &Address, sizeof(ADDRESS), &Result))
  896. {
  897. dprintf("%p: Could not read Address information\n", pAddress);
  898. return;
  899. }
  900. Count++;
  901. pEntry = Address.Linkage.Flink;
  902. dprintf("[%d]\t<%p> => ", Address.ReferenceCount, pAddress);
  903. dprintf("<%-15.15s:%2x> | %8x | %2x | %8x | %s\n",
  904. Address.NetbiosAddress.NetbiosName,
  905. Address.NetbiosAddress.NetbiosName[15],
  906. Address.State,
  907. Address.NameTypeFlag,
  908. Address.Flags,
  909. (Address.NetbiosAddress.Broadcast ? "Y" : "N"));
  910. }
  911. dprintf("\nDumped %d Addresses\n", Count);
  912. return;
  913. }
  914. VOID
  915. DumpRemoteCache(
  916. NETBIOS_CACHE_TABLE *pNameCacheTable,
  917. USHORT CacheTimeStamp
  918. )
  919. /*++
  920. Routine Description:
  921. Dumps the fields of the specified DEVICE_CONTEXT structure
  922. Arguments:
  923. deviceToDump - The device context object to display
  924. Full - Display a partial listing if 0, full listing otherwise.
  925. Return Value:
  926. None
  927. --*/
  928. {
  929. NETBIOS_CACHE_TABLE NameCacheTable;
  930. NETBIOS_CACHE CacheEntry;
  931. NETBIOS_CACHE *pCacheEntry;
  932. PLIST_ENTRY pHead, pEntry;
  933. ULONG HashIndex;
  934. ULONG Result;
  935. ULONG Count = 0;
  936. if (!ReadMemory ((ULONG) pNameCacheTable, &NameCacheTable, sizeof(NETBIOS_CACHE_TABLE), &Result))
  937. {
  938. dprintf("%p: Could not read Remote Name Cache\n", pNameCacheTable);
  939. return;
  940. }
  941. dprintf("Dumping Remote Names (%3d entries, %3d buckets), TimeStamp = %4d, AgeLimit = %4d:\n",
  942. NameCacheTable.CurrentEntries, NameCacheTable.MaxHashIndex, CacheTimeStamp, (600000 / LONG_TIMER_DELTA));
  943. dprintf("-----------------------------------------------------------------------------------\n");
  944. dprintf("[Bkt#] <Address> => <Name > | TimeSt | NetsU | NetsA | RefC | U | FailedOnDownWan\n");
  945. dprintf("------------------------------------------------------------------------------------------------\n");
  946. for (HashIndex = 0; HashIndex < NameCacheTable.MaxHashIndex; HashIndex++)
  947. {
  948. pHead = &pNameCacheTable->Bucket[HashIndex];
  949. if (!ReadMemory ((ULONG) pHead, &pEntry, sizeof(PLIST_ENTRY), &Result))
  950. {
  951. dprintf("%p: Could not Entry ptr\n", pHead);
  952. return;
  953. }
  954. while (pEntry != pHead)
  955. {
  956. pCacheEntry = CONTAINING_RECORD (pEntry, NETBIOS_CACHE, Linkage);
  957. if (!ReadMemory((ULONG) pCacheEntry, &CacheEntry, sizeof(NETBIOS_CACHE), &Result))
  958. {
  959. dprintf("%p: Could not read Remote Name information\n", pCacheEntry);
  960. return;
  961. }
  962. Count++;
  963. pEntry = CacheEntry.Linkage.Flink;
  964. dprintf("[%d]\t<%p> => ", HashIndex, pCacheEntry);
  965. dprintf("<%-15.15s:%2x> | %4d | %4d | %4d | %2d | %s | %s\n",
  966. CacheEntry.NetbiosName,
  967. CacheEntry.NetbiosName[15],
  968. CacheEntry.TimeStamp,
  969. CacheEntry.NetworksUsed,
  970. CacheEntry.NetworksAllocated,
  971. CacheEntry.ReferenceCount,
  972. (CacheEntry.Unique ? "U" : "G"),
  973. (CacheEntry.FailedOnDownWan ? "Y" : "N"));
  974. }
  975. }
  976. dprintf("\nDumped %d Remote names\n", Count);
  977. return;
  978. }
  979. //
  980. // Exported function
  981. //
  982. DECLARE_API( nbcache )
  983. /*++
  984. Routine Description:
  985. Dumps the most important fields of the specified ADDRESS_FILE object
  986. Arguments:
  987. args - Address of args string
  988. Return Value:
  989. None
  990. --*/
  991. {
  992. DEVICE *pDevice;
  993. ULONG Result;
  994. NETBIOS_CACHE_TABLE *pNameCache;
  995. USHORT CacheTimeStamp;
  996. if (!*args)
  997. {
  998. //
  999. // No initial packet has been defined, so set the initial packet
  1000. // from the global pool list
  1001. //
  1002. if (!(pDevice = (DEVICE *) GetExpression("nwlnknb!NbiDevice")))
  1003. {
  1004. dprintf("Could not get NbiDevice, Try !reload\n");
  1005. return;
  1006. }
  1007. if (!ReadMemory ((ULONG) pDevice, &pDevice, sizeof(DEVICE *), &Result))
  1008. {
  1009. dprintf("%p: Could not read device address\n", pDevice);
  1010. return;
  1011. }
  1012. }
  1013. else
  1014. {
  1015. NumArgsRead = sscanf(args, "%p", &pDevice);
  1016. if (0 == NumArgsRead) {
  1017. dprintf("Bad argument for NbiDevice <%s>\n", args);
  1018. return;
  1019. }
  1020. }
  1021. DumpLocalAddresses (&pDevice->AddressDatabase);
  1022. dprintf ("\n\n");
  1023. if (!ReadMemory ((ULONG) &pDevice->NameCache, &pNameCache, sizeof(NETBIOS_CACHE_TABLE *), &Result))
  1024. {
  1025. dprintf("%p: Could not read NameCache ptr from Device\n", &pDevice->NameCache);
  1026. return;
  1027. }
  1028. if (!ReadMemory ((ULONG) &pDevice->CacheTimeStamp, &CacheTimeStamp, sizeof(USHORT), &Result))
  1029. {
  1030. dprintf("%p: Could not read CacheTimeStamp value from Device\n", &pDevice->CacheTimeStamp);
  1031. return;
  1032. }
  1033. DumpRemoteCache (pNameCache, CacheTimeStamp);
  1034. return;
  1035. }