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.

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