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.

2228 lines
64 KiB

  1. /*++
  2. NwRdr Kernel Debugger Extensions
  3. Copyright (c) 1995 Microsoft Corporation
  4. Abstract:
  5. NW Redirector Kernel Debugger extensions.
  6. This module contains a set of useful kernel debugger
  7. extensions for the NT nw redirector.
  8. Author:
  9. Cory West <corywest>, 09-Jan-1994
  10. --*/
  11. #include "procs.h"
  12. #include "nodetype.h"
  13. #include <string.h>
  14. #include <stdlib.h>
  15. //
  16. // Function prototypes.
  17. //
  18. VOID
  19. DumpScbNp(
  20. DWORD addr,
  21. PNTKD_EXTENSION_APIS lpExtensionApis,
  22. BOOL first
  23. );
  24. VOID
  25. DumpFcbNp(
  26. DWORD addr,
  27. PNTKD_EXTENSION_APIS lpExtensionApis,
  28. BOOL first
  29. );
  30. //
  31. // Define some macros for simplicity.
  32. //
  33. #define GET_DWORD( pDest, addr ) \
  34. (lpExtensionApis->lpReadVirtualMemRoutine)((LPVOID)(addr), pDest, 4, NULL)
  35. #define GET_WORD( pDest, addr ) \
  36. (lpExtensionApis->lpReadVirtualMemRoutine)((LPVOID)(addr), pDest, 2, NULL)
  37. #define GET_STRING( pDest, string ) \
  38. (lpExtensionApis->lpReadVirtualMemRoutine)(string.Buffer, pDest, \
  39. string.Length, NULL); pDest[ string.Length/2 ] = L'\0'
  40. #define printf lpExtensionApis->lpOutputRoutine
  41. #define getmem lpExtensionApis->lpReadVirtualMemRoutine
  42. #define getexpr lpExtensionApis->lpGetExpressionRoutine
  43. #ifdef WINDBG
  44. #define getsymaddr( string ) ((lpExtensionApis->lpGetExpressionRoutine))( "&"##string )
  45. #else
  46. #define getsymaddr lpExtensionApis->lpGetExpressionRoutine
  47. #endif
  48. VOID
  49. help(
  50. #ifdef WINDBG
  51. HANDLE hProcess,
  52. HANDLE hThread,
  53. #endif
  54. DWORD dwCurrentPc,
  55. PNTKD_EXTENSION_APIS lpExtensionApis,
  56. LPSTR lpArgumentString
  57. )
  58. /*++
  59. This function prints out usage for the nw debugger extensions.
  60. --*/
  61. {
  62. printf( "---------------------------------------------------------------------------\n");
  63. printf( "NwRdr Debugger Extensions:\n\n");
  64. printf( "Top Level Functions:\n\n");
  65. printf( "serverlist(void) - List the servers that the redirector knows.\n");
  66. printf( "logonlist(void) - List the users that are logged on.\n");
  67. printf( "trace(void) - Display the trace buffer.\n");
  68. printf( "nwdump(virtual addr) - Display the object at the given virtual address.\n");
  69. printf( " (This function knows how to dump all NwRdr data\n");
  70. printf( " structures.)\n");
  71. printf( "help(void) - Display this message.\n\n");
  72. printf( "List Management Functions:\n\n");
  73. printf( "vcblist(scb*, npscb*) - Given a pointer to any of the specified objects,\n");
  74. printf( " this function dumps the VCB list for that server.\n");
  75. printf( "irplist(scb*, npscb*) - Given a pointer to any of the specified objects,\n");
  76. printf( " this function dumps the IRP list for that server.\n");
  77. printf( "fcblist(vcb*) - Given a pointer to a VCB, this function dumps\n");
  78. printf( " the FCB/DCB list for that VCB.\n");
  79. printf( "icblist(scb*, npscb*,\n");
  80. printf( " fcb*, dcb*,\n");
  81. printf( " npfcb*) - Given a pointer to any of the specified objects,\n");
  82. printf( " function dumps the ICB list for that object.\n");
  83. printf( "---------------------------------------------------------------------------\n");
  84. }
  85. VOID
  86. traceflags(
  87. #ifdef WINDBG
  88. HANDLE hProcess,
  89. HANDLE hThread,
  90. #endif
  91. DWORD dwCurrentPc,
  92. PNTKD_EXTENSION_APIS lpExtensionApis,
  93. LPSTR lpArgumentString
  94. )
  95. /*++
  96. This function prints out the trace flag values.
  97. --*/
  98. {
  99. printf( "DEBUG_TRACE_CLEANUP (0x00000001)\n");
  100. printf( "DEBUG_TRACE_CLOSE (0x00000002)\n");
  101. printf( "DEBUG_TRACE_CLEANUP (0x00000001)\n");
  102. printf( "DEBUG_TRACE_CLOSE (0x00000002)\n");
  103. printf( "DEBUG_TRACE_CREATE (0x00000004)\n");
  104. printf( "DEBUG_TRACE_FSCTRL (0x00000008)\n");
  105. printf( "DEBUG_TRACE_IPX (0x00000010)\n");
  106. printf( "DEBUG_TRACE_LOAD (0x00000020)\n");
  107. printf( "DEBUG_TRACE_EXCHANGE (0x00000040)\n");
  108. printf( "DEBUG_TRACE_FILOBSUP (0x00000080)\n");
  109. printf( "DEBUG_TRACE_STRUCSUP (0x00000100)\n");
  110. printf( "DEBUG_TRACE_FSP_DISPATCHER (0x00000200)\n");
  111. printf( "DEBUG_TRACE_FSP_DUMP (0x00000400)\n");
  112. printf( "DEBUG_TRACE_WORKQUE (0x00000800)\n");
  113. printf( "DEBUG_TRACE_UNWIND (0x00001000)\n");
  114. printf( "DEBUG_TRACE_CATCH_EXCEPTIONS (0x00002000)\n");
  115. printf( "DEBUG_TRACE_FILEINFO (0x00008000)\n");
  116. printf( "DEBUG_TRACE_DIRCTRL (0x00010000)\n");
  117. printf( "DEBUG_TRACE_CONVERT (0x00020000)\n");
  118. printf( "DEBUG_TRACE_WRITE (0x00040000)\n");
  119. printf( "DEBUG_TRACE_READ (0x00080000)\n");
  120. printf( "DEBUG_TRACE_VOLINFO (0x00100000)\n");
  121. printf( "DEBUG_TRACE_LOCKCTRL (0x00200000)\n");
  122. printf( "DEBUG_TRACE_USERNCP (0x00400000)\n");
  123. printf( "DEBUG_TRACE_SECURITY (0x00800000)\n");
  124. printf( "DEBUG_TRACE_CACHE (0x01000000)\n");
  125. printf( "DEBUG_TRACE_LIP (0x02000000)\n");
  126. printf( "DEBUG_TRACE_MDL (0x04000000)\n");
  127. printf( "DEBUG_TRACE_NDS (0x10000000)\n");
  128. printf( "DEBUG_TRACE_SCAVENGER (0x40000000)\n");
  129. printf( "DEBUG_TRACE_TIMER (0x80000000)\n");
  130. }
  131. //
  132. // Internal helper routines to convert numerical data into symbolic data.
  133. //
  134. NODE_TYPE_CODE
  135. GetNodeType(
  136. DWORD objAddr,
  137. PNTKD_EXTENSION_APIS lpExtensionApis
  138. )
  139. /*++
  140. Given the address of an object, this function will
  141. attempt to get the node type code for that object.
  142. --*/
  143. {
  144. NODE_TYPE_CODE ntc;
  145. GET_WORD( &ntc, objAddr );
  146. return ntc;
  147. }
  148. LPSTR
  149. RcbStateToString(
  150. DWORD State
  151. )
  152. /*++
  153. Routine Description:
  154. This helper function converts the RCB state from a
  155. DWORD to a readable text string.
  156. Arguments:
  157. DWORD State - The DWORD RCB state.
  158. Return Value:
  159. LPSTR containing the readable text string.
  160. --*/
  161. {
  162. switch ( State ) {
  163. case RCB_STATE_STOPPED:
  164. return("RCB_STATE_STOPPED");
  165. case RCB_STATE_STARTING:
  166. return("RCB_STATE_STARTING");
  167. case RCB_STATE_NEED_BIND:
  168. return("RCB_STATE_NEED_BIND");
  169. case RCB_STATE_RUNNING:
  170. return("RCB_STATE_RUNNING");
  171. case RCB_STATE_SHUTDOWN:
  172. return("RCB_STATE_SHUTDOWN");
  173. default:
  174. return("(state unknown)" );
  175. }
  176. }
  177. LPSTR
  178. ScbStateToString(
  179. DWORD State
  180. )
  181. /*++
  182. Routine Description:
  183. This helper function converts the SCB state from a
  184. DWORD to a readable text string.
  185. Arguments:
  186. DWORD State - The DWORD SCB state.
  187. Return Value:
  188. LPSTR containing the readable text string.
  189. --*/
  190. {
  191. switch ( State ) {
  192. case SCB_STATE_ATTACHING:
  193. return("SCB_STATE_ATTACHING" );
  194. case SCB_STATE_IN_USE:
  195. return("SCB_STATE_IN_USE" );
  196. case SCB_STATE_DISCONNECTING:
  197. return("SCB_STATE_DISCONNECTING" );
  198. case SCB_STATE_FLAG_SHUTDOWN:
  199. return("SCB_STATE_FLAG_SHUTDOWN" );
  200. case SCB_STATE_RECONNECT_REQUIRED:
  201. return("SCB_STATE_RECONNECT_REQD" );
  202. case SCB_STATE_LOGIN_REQUIRED:
  203. return("SCB_STATE_LOGIN_REQUIRED" );
  204. case SCB_STATE_TREE_SCB:
  205. return("SCB_STATE_TREE_SCB" );
  206. default:
  207. return("(state unknown)" );
  208. }
  209. }
  210. LPSTR
  211. IcbStateToString(
  212. DWORD State
  213. )
  214. /*++
  215. Routine Description:
  216. This helper function converts the ICB state from a
  217. DWORD to a readable text string.
  218. --*/
  219. {
  220. switch ( State ) {
  221. case ICB_STATE_OPEN_PENDING:
  222. return("ICB_STATE_OPEN_PENDING" );
  223. case ICB_STATE_OPENED:
  224. return("ICB_STATE_OPENED" );
  225. case ICB_STATE_CLEANED_UP:
  226. return("ICB_STATE_CLEANED_UP" );
  227. case ICB_STATE_CLOSE_PENDING:
  228. return("ICB_STATE_CLOSE_PENDING" );
  229. default:
  230. return("(state unknown)" );
  231. }
  232. }
  233. VOID
  234. PrintIrpContextFlags(
  235. ULONG Flags,
  236. PNTKD_EXTENSION_APIS lpExtensionApis
  237. )
  238. /*++
  239. Print out the flags that are set in the IRP_CONTEXT flags.
  240. --*/
  241. {
  242. if ( Flags & IRP_FLAG_IN_FSD )
  243. printf( "\tIRP_FLAG_IN_FSD\n" );
  244. if ( Flags & IRP_FLAG_ON_SCB_QUEUE )
  245. printf( "\tIRP_FLAG_ON_SCB_QUEUE\n" );
  246. if ( Flags & IRP_FLAG_SEQUENCE_NO_REQUIRED )
  247. printf( "\tIRP_FLAG_SEQUENCE_NO_REQUIRED\n" );
  248. if ( Flags & IRP_FLAG_SIGNAL_EVENT )
  249. printf( "\tIRP_FLAG_SIGNAL_EVENT\n" );
  250. if ( Flags & IRP_FLAG_RETRY_SEND )
  251. printf( "\tIRP_FLAG_RETRY_SEND\n" );
  252. if ( Flags & IRP_FLAG_RECONNECTABLE )
  253. printf( "\tIRP_FLAG_RECONNECTABLE\n" );
  254. if ( Flags & IRP_FLAG_RECONNECT_ATTEMPT )
  255. printf( "\tIRP_FLAG_RECONNECT_ATTEMPT\n" );
  256. if ( Flags & IRP_FLAG_BURST_REQUEST )
  257. printf( "\tIRP_FLAG_BURST_REQUEST\n" );
  258. if ( Flags & IRP_FLAG_BURST_PACKET )\
  259. printf( "\tIRP_FLAG_BURST_PACKET\n" );
  260. if ( Flags & IRP_FLAG_NOT_OK_TO_RECEIVE )
  261. printf( "\tIRP_FLAG_NOT_OK_TO_RECEIVE\n" );
  262. if ( Flags & IRP_FLAG_REROUTE_ATTEMPTED )
  263. printf( "\tIRP_FLAG_REROUTE_ATTEMPTED\n" );
  264. if ( Flags & IRP_FLAG_BURST_WRITE )
  265. printf( "\tIRP_FLAG_BURST_WRITE\n" );
  266. if ( Flags & IRP_FLAG_SEND_ALWAYS )
  267. printf( "\tIRP_FLAG_SEND_ALWAYS\n" );
  268. if ( Flags & IRP_FLAG_FREE_RECEIVE_MDL )
  269. printf( "\tIRP_FLAG_FREE_RECEIVE_MDL\n" );
  270. if ( Flags & IRP_FLAG_NOT_SYSTEM_PACKET )
  271. printf( "\tIRP_FLAG_NOT_SYSTEM_PACKET\n" );
  272. if ( Flags & IRP_FLAG_NOCONNECT )
  273. printf( "\tIRP_FLAG_NOCONNECT\n" );
  274. if ( Flags & IRP_FLAG_HAS_CREDENTIAL_LOCK )
  275. printf( "\tIRP_FLAG_HAS_CREDENTIAL_LOCK\n" );
  276. }
  277. VOID
  278. PrintNpFcbFlags(
  279. ULONG Flags,
  280. PNTKD_EXTENSION_APIS lpExtensionApis
  281. )
  282. /*++
  283. Print out the flags that are set in the IRP_CONTEXT flags.
  284. --*/
  285. {
  286. if ( Flags & FCB_FLAGS_DELETE_ON_CLOSE )
  287. printf( "\tFCB_FLAGS_DELETE_ON_CLOSE\n" );
  288. if ( Flags & FCB_FLAGS_TRUNCATE_ON_CLOSE )
  289. printf( "\tFCB_FLAGS_TRUNCATE_ON_CLOSE\n" );
  290. if ( Flags & FCB_FLAGS_PAGING_FILE )
  291. printf( "\tFCB_FLAGS_PAGING_FILE\n" );
  292. if ( Flags & FCB_FLAGS_PREFIX_INSERTED )
  293. printf( "\tFCB_FLAGS_PREFIX_INSERTED\n" );
  294. if ( Flags & FCB_FLAGS_FORCE_MISS_IN_PROGRESS )
  295. printf( "\tFCB_FLAGS_FORCE_MISS_IN_PROGRESS\n" );
  296. if ( Flags & FCB_FLAGS_ATTRIBUTES_ARE_VALID )
  297. printf( "\tFCB_FLAGS_ATTRIBUTES_ARE_VALID\n" );
  298. if ( Flags & FCB_FLAGS_LONG_NAME )
  299. printf( "\tFCB_FLAGS_LONG_NAME\n" );
  300. }
  301. LPSTR
  302. PacketToString(
  303. UINT pt
  304. )
  305. /*++
  306. Routine Description:
  307. This helper function converts a PACKET_TYPE to
  308. a readable text string.
  309. --*/
  310. {
  311. switch ( pt ) {
  312. case SAP_BROADCAST:
  313. return "SAP_BROADCAST";
  314. case NCP_CONNECT:
  315. return "NCP_CONNECT";
  316. case NCP_FUNCTION:
  317. return "NCP_FUNCTION";
  318. case NCP_SUBFUNCTION:
  319. return "NCP_SUBFUNCTION";
  320. case NCP_DISCONNECT:
  321. return "NCP_DISCONNECT";
  322. case NCP_BURST:
  323. return "NCP_BURST";
  324. case NCP_ECHO:
  325. return "NCP_ECHO";
  326. default:
  327. return "(packet type unknown)";
  328. }
  329. }
  330. //
  331. // The internal object functions for the nwdump() routine.
  332. // These functions must receive good pointers; they are
  333. // neither smart, nor exported.
  334. //
  335. VOID
  336. DumpScb(
  337. DWORD addr,
  338. PNTKD_EXTENSION_APIS lpExtensionApis,
  339. BOOL first
  340. )
  341. /*++
  342. This function takes the address of the pageable portion
  343. of an SCB and a pointer to a debugger extension interface
  344. block. It prints out the information in the SCB and
  345. the corresponding non-pageable SCB.
  346. --*/
  347. {
  348. WCHAR Buffer[64];
  349. BOOL b;
  350. SCB Scb;
  351. // Read it.
  352. b = getmem((PVOID)addr, &Scb, sizeof( Scb ), NULL);
  353. if ( b == 0 ) {
  354. printf("<could not read the pageable scb>\n");
  355. return;
  356. }
  357. printf( "-----------------------------SCB at %08lx-------------------------------\n", addr );
  358. printf( "NodeTypeCode : NW_NTC_SCB\n" );
  359. printf( "NodeByteSize : %d\n", Scb.NodeByteSize );
  360. printf( "pNpScb Addr : %08lx\n", Scb.pNpScb );
  361. printf( "Version : %d\\%d\n", Scb.MajorVersion, Scb.MinorVersion );
  362. printf( "VcbList : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( SCB, ScbSpecificVcbQueue ));
  363. printf( "VcbCount : %d\n", Scb.VcbCount );
  364. printf( "IcbList : %08lx (LIST_ENTRY, ICB)\n", addr + FIELD_OFFSET( SCB, IcbList ));
  365. printf( "IcbCount : %d\n", Scb.IcbCount );
  366. printf( "OpenNdsStreams : %d\n", Scb.OpenNdsStreams );
  367. printf( "UserUid : %08lx %08lx\n", Scb.UserUid.HighPart, Scb.UserUid.LowPart );
  368. printf( "OpenFileCount : %d\n", Scb.OpenFileCount );
  369. b = GET_STRING( Buffer, Scb.UidServerName );
  370. if ( b ) {
  371. printf( "UidServerName : %ws\n", Buffer );
  372. } else {
  373. printf( "UidServerName : (unreadable)\n");
  374. }
  375. b = GET_STRING( Buffer, Scb.NdsTreeName );
  376. if ( b ) {
  377. printf( "NDS Tree Name : %ws\n", Buffer );
  378. } else {
  379. printf( "Nds Tree Name : (none)\n");
  380. }
  381. b = GET_STRING( Buffer, Scb.UnicodeUid );
  382. if ( b ) {
  383. printf( "UnicodeUid : %ws\n", Buffer );
  384. } else {
  385. printf( "UnicodeUid : (unreadable)\n");
  386. }
  387. b = GET_STRING( Buffer, Scb.UserName );
  388. if ( b ) {
  389. printf( "User name : %ws\n", Buffer );
  390. } else {
  391. printf( "User name : (unreadable)\n" );
  392. }
  393. b = GET_STRING( Buffer, Scb.Password );
  394. if ( b ) {
  395. printf( "Password : %ws\n", Buffer );
  396. } else {
  397. printf( "Password : (unreadable)\n" );
  398. }
  399. printf( "PreferredServer : %s\n", Scb.PreferredServer ? "TRUE" : "FALSE" );
  400. printf( "MessageWaiting : %s\n", Scb.MessageWaiting ? "TRUE" : "FALSE" );
  401. printf( "AttachCount : %d\n", Scb.AttachCount);
  402. // What about the drive map?
  403. // Dump both parts.
  404. if ( first )
  405. DumpScbNp( (DWORD)Scb.pNpScb, lpExtensionApis, FALSE );
  406. else
  407. printf( "---------------------------------------------------------------------------\n");
  408. return;
  409. }
  410. VOID
  411. DumpScbNp(
  412. DWORD addr,
  413. PNTKD_EXTENSION_APIS lpExtensionApis,
  414. BOOL first
  415. )
  416. /*++
  417. This function takes the address of the nonpageable
  418. portion of an SCB and a pointer to a debugger extension
  419. interface block. It prints out the information in the
  420. nonpageable SCB and the corresponding pageable SCB.
  421. --*/
  422. {
  423. WCHAR Buffer[64];
  424. BOOL b;
  425. NONPAGED_SCB NpScb;
  426. // Read it.
  427. b = getmem( (PVOID)addr, &NpScb, sizeof( NpScb ), NULL );
  428. if ( b == 0 ) {
  429. printf("<could not read the nonpageable scb>\n");
  430. return;
  431. }
  432. printf( "------------------------Non-Pageable SCB at %08lx-----------------------\n", addr);
  433. printf( "NodeTypeCode : NW_NTC_SCBNP\n" );
  434. printf( "NodeByteSize : %d\n", NpScb.NodeByteSize );
  435. b = GET_STRING( Buffer, NpScb.ServerName );
  436. if ( b ) {
  437. printf( "ServerName : %ws\n", Buffer );
  438. } else {
  439. printf( "ServerName : (unreadable)\n" );
  440. }
  441. printf( "pScb Addr : %08lx\n", NpScb.pScb );
  442. printf( "Reference Count : %08lx\n", NpScb.Reference );
  443. printf( "State : %s\n", ScbStateToString( NpScb.State ));
  444. printf( "Last Used Time : %08lx %08lx\n", NpScb.LastUsedTime.HighPart, NpScb.LastUsedTime.LowPart );
  445. printf( "Sending : %s\n", NpScb.Sending ? "TRUE" : "FALSE" );
  446. printf( "Receiving : %s\n", NpScb.Receiving ? "TRUE" : "FALSE" );
  447. printf( "Ok To Receive : %s\n", NpScb.OkToReceive ? "TRUE" : "FALSE" );
  448. printf( "PageAlign : %s\n", NpScb.PageAlign ? "TRUE" : "FALSE" );
  449. printf( "Scblinks : %08lx (LIST_ENTRY, NPSCB)\n", addr + FIELD_OFFSET( NONPAGED_SCB, ScbLinks ));
  450. printf( "Requests : %08lx (LIST_ENTRY, NPSCB)\n", addr + FIELD_OFFSET( NONPAGED_SCB, Requests ));
  451. printf( "------------------------------Transport Info-------------------------------\n" );
  452. printf( "TickCount : %d\n", NpScb.TickCount );
  453. printf( "RetryCount : %d\n", NpScb.RetryCount );
  454. printf( "Timeout : %d\n", NpScb.TimeOut );
  455. printf( "SequenceNo : %d\n", NpScb.SequenceNo );
  456. printf( "ConnectionNo : %d\n", NpScb.ConnectionNo );
  457. printf( "ConnectionNoHi : %d\n", NpScb.ConnectionNoHigh );
  458. printf( "ConnectionStat : %d\n", NpScb.ConnectionStatus );
  459. printf( "MaxTimeOut : %d\n", NpScb.MaxTimeOut );
  460. printf( "BufferSize : %d\n", NpScb.BufferSize );
  461. printf( "TaskNo : %d\n", NpScb.TaskNo );
  462. printf( "Spin lock : %s\n", NpScb.NpScbSpinLock == 0 ? "Released" : "Acquired " );
  463. printf( "LIP Data Speed : %d\n", NpScb.LipDataSpeed );
  464. printf( "---------------------------Burst Mode Parameters---------------------------\n");
  465. printf( "SourceConnId : %08lx\n", NpScb.SourceConnectionId );
  466. printf( "DestConnId : %08lx\n", NpScb.DestinationConnectionId );
  467. printf( "MaxPacketSize : %d\n", NpScb.MaxPacketSize );
  468. printf( "MaxSendSize : %ld\n", NpScb.MaxSendSize );
  469. printf( "MaxReceiveSize : %ld\n", NpScb.MaxReceiveSize );
  470. printf( "SendBMEnable : %s\n", NpScb.SendBurstModeEnabled ? "TRUE" : "FALSE" );
  471. printf( "ReceiveBMEnable : %s\n", NpScb.ReceiveBurstModeEnabled ? "TRUE" : "FALSE" );
  472. printf( "BurstSequenceNo : %d\n", NpScb.BurstSequenceNo );
  473. printf( "BurstRequestNo : %d\n", NpScb.BurstRequestNo );
  474. printf( "BurstSendDelay : Good %d,\tCurrent %d,\tBad %d\n", NpScb.NwGoodSendDelay, NpScb.NwSendDelay, NpScb.NwBadSendDelay );
  475. printf( "BurstReceiveDelay : Good %d,\tCurrent %d,\tBad %d\n", NpScb.NwGoodReceiveDelay, NpScb.NwReceiveDelay, NpScb.NwBadReceiveDelay );
  476. printf( "BurstSuccessCount : Send %d, Receive %d\n", NpScb.SendBurstSuccessCount, NpScb.ReceiveBurstSuccessCount );
  477. printf( "--------------------------Send Delays and Timeouts-------------------------\n" );
  478. printf( "SendTimeout : %d\n", NpScb.SendTimeout );
  479. printf( "TotalWaitTime : %d\n", NpScb.TotalWaitTime );
  480. printf( "NwLoopTime : %d\n", NpScb.NwLoopTime );
  481. printf( "NwSingleBurst : %d\n", NpScb.NwSingleBurstPacketTime );
  482. printf( "NwMaxSendDelay : %d\n", NpScb.NwMaxSendDelay );
  483. printf( "NwGoodSendDelay : %d\n", NpScb.NwGoodSendDelay );
  484. printf( "NwBadSendDelay : %d\n", NpScb.NwBadSendDelay );
  485. printf( "BurstDataWritten : %d\n", NpScb.BurstDataWritten );
  486. printf( "NwMaxReceiveDelay : %d\n", NpScb.NwMaxReceiveDelay );
  487. printf( "NwReceiveDelay : %d\n", NpScb.NwReceiveDelay );
  488. printf( "NwGoodReceiveDelay : %d\n", NpScb.NwGoodReceiveDelay );
  489. printf( "NwBadReceiveDelay : %d\n", NpScb.NwBadReceiveDelay );
  490. printf( "CurrentBurstDelay : %d\n", NpScb.CurrentBurstDelay );
  491. printf( "NtSendDelay : %08lx %08lx\n", NpScb.NtSendDelay.HighPart, NpScb.NtSendDelay.LowPart );
  492. printf( "NwNextEventTime : %08lx %08lx\n", NpScb.NwNextEventTime.HighPart, NpScb.NwNextEventTime.LowPart );
  493. // Spin locks? Transport and TDI info?
  494. // Dump Both Parts.
  495. if ( first )
  496. DumpScb( (DWORD)NpScb.pScb, lpExtensionApis, FALSE );
  497. else
  498. printf( "---------------------------------------------------------------------------\n" );
  499. return;
  500. }
  501. VOID
  502. DumpFcb(
  503. DWORD addr,
  504. PNTKD_EXTENSION_APIS lpExtensionApis,
  505. BOOL first
  506. )
  507. /*++
  508. This function takes the address of an FCB or DCB and a pointer
  509. to a debugger extension interface block. It prints out
  510. the information in the FCB or DCB.
  511. --*/
  512. {
  513. WCHAR Buffer[64];
  514. BOOL b;
  515. FCB Fcb;
  516. b = getmem( (PVOID)addr, &Fcb, sizeof( Fcb ), NULL );
  517. if ( b == 0 ) {
  518. printf("<could not read the fcb or dcb>\n");
  519. return;
  520. }
  521. if (Fcb.NodeTypeCode == NW_NTC_FCB) {
  522. printf( "----------------------------FCB at %08lx--------------------------------\n", addr );
  523. printf( "NodeTypeCode : NW_NTC_FCB\n" );
  524. } else {
  525. printf( "----------------------------DCB at %08lx--------------------------------\n", addr );
  526. printf( "NodeTypeCode : NW_NTC_DCB\n" );
  527. }
  528. b = GET_STRING( Buffer, Fcb.FullFileName );
  529. if ( b ) {
  530. printf( "FullFileName : %ws\n", Buffer );
  531. } else {
  532. printf( "FullFileName : (unreadable)\n" );
  533. }
  534. b = GET_STRING( Buffer, Fcb.RelativeFileName );
  535. if ( b ) {
  536. printf( "RelativeFileName : %ws\n", Buffer );
  537. } else {
  538. printf( "RelativeFileName : (unreadable)\n" );
  539. }
  540. printf( "VCB Addr : %08lx\n", Fcb.Vcb );
  541. printf( "SCB Addr : %08lx\n", Fcb.Scb );
  542. printf( "NpFcb Addr : %08lx\n", Fcb.NonPagedFcb );
  543. printf( "LastModifiedDate : %d\n", Fcb.LastModifiedDate );
  544. printf( "LastModifiedTime : %d\n", Fcb.LastModifiedTime );
  545. printf( "CreationDate : %d\n", Fcb.CreationDate );
  546. printf( "CreationTime : %d\n", Fcb.CreationTime );
  547. printf( "LastAccessDate : %d\n", Fcb.LastAccessDate );
  548. printf( "State : %d\n", Fcb.State );
  549. printf( "Flags : %d\n", Fcb.Flags );
  550. // SHARE_ACCESS?
  551. printf( "FcbListEntry : %08lx (LIST_ENTRY, FCB)\n", addr + FIELD_OFFSET( FCB, FcbListEntry ));
  552. printf( "IcbListEntry : %08lx (LIST_ENTRY, ICB)\n", addr + FIELD_OFFSET( FCB, IcbList ));
  553. printf( "IcbCount : %d\n", Fcb.IcbCount );
  554. printf( "LastReadOffset : %d\n", Fcb.LastReadOffset );
  555. printf( "LastReadSize : %d\n", Fcb.LastReadSize );
  556. // Dump both parts.
  557. if ( first )
  558. DumpFcbNp( (DWORD)Fcb.NonPagedFcb, lpExtensionApis, FALSE );
  559. else
  560. printf( "---------------------------------------------------------------------------\n" );
  561. }
  562. VOID
  563. DumpVcb(
  564. DWORD addr,
  565. PNTKD_EXTENSION_APIS lpExtensionApis
  566. )
  567. /*++
  568. This function takes the address of a VCB and a pointer
  569. to a debugger extension interface block. It prints out
  570. the information in the VCB.
  571. --*/
  572. {
  573. WCHAR Buffer[64];
  574. BOOL b;
  575. VCB Vcb;
  576. // Read it.
  577. b = getmem( (PVOID)addr, &Vcb, sizeof( Vcb ), NULL);
  578. if ( b == 0 ) {
  579. printf("<could not read the vcb>\n");
  580. return;
  581. }
  582. printf( "------------------------------VCB at %08lx------------------------------\n", addr);
  583. printf( "NodeTypeCode : NW_NTC_VCB\n" );
  584. printf( "NodeByteSize : %d\n", Vcb.NodeByteSize );
  585. printf( "Reference Count : %08lx\n", Vcb.Reference );
  586. printf( "Last Used Time : %08lx %08lx\n", Vcb.LastUsedTime.HighPart, Vcb.LastUsedTime.LowPart );
  587. printf( "GlobalVcbListEntry : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( VCB, GlobalVcbListEntry) );
  588. printf( "SequenceNumber : %d\n", Vcb.SequenceNumber );
  589. b = GET_STRING( Buffer, Vcb.Name );
  590. if ( b ) {
  591. printf( "VolumeName : %ws\n", Buffer );
  592. } else {
  593. printf( "VolumeName : (unreadable)\n" );
  594. }
  595. b = GET_STRING( Buffer, Vcb.ConnectName );
  596. if ( b ) {
  597. printf( "ConnectName : %ws\n", Buffer );
  598. } else {
  599. printf( "ConnectName : (unreadable)\n" );
  600. }
  601. b = GET_STRING( Buffer, Vcb.ShareName );
  602. if ( b ) {
  603. printf( "NW ShareName : %ws\n", Buffer );
  604. } else {
  605. printf( "NW ShareName : (unreadable)\n" );
  606. }
  607. if ( !Vcb.Flags & VCB_FLAG_PRINT_QUEUE ) {
  608. printf( "VolumeNumber : %d\n", Vcb.Specific.Disk.VolumeNumber );
  609. printf( "LongNameSpace : %d\n", Vcb.Specific.Disk.LongNameSpace );
  610. printf( "Handle : %d\n", Vcb.Specific.Disk.Handle );
  611. } else {
  612. printf( "QueueId : %d\n", Vcb.Specific.Print.QueueId );
  613. }
  614. if ( Vcb.DriveLetter != 0) {
  615. printf( "Drive letter : %wc:\n", Vcb.DriveLetter );
  616. } else {
  617. printf( "Drive letter : UNC\n" );
  618. }
  619. printf( "Scb Addr : %08lx\n", Vcb.Scb );
  620. printf( "VcbListEntry : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( VCB, VcbListEntry) );
  621. printf( "FcbListEntry : %08lx (LIST_ENTRY, FCB)\n", addr + FIELD_OFFSET(VCB, FcbList) );
  622. printf( "OpenFileCount : %d\n", Vcb.OpenFileCount );
  623. printf( "Flags : %08lx\n", Vcb.Flags );
  624. printf( "---------------------------------------------------------------------------\n");
  625. }
  626. VOID
  627. DumpIcb(
  628. DWORD addr,
  629. PNTKD_EXTENSION_APIS lpExtensionApis
  630. )
  631. /*++
  632. This function takes the address of an ICB and a pointer
  633. to a debugger extension interface block. It prints out
  634. the information in the ICB.
  635. --*/
  636. {
  637. WCHAR Buffer[64];
  638. BOOL b, icbscb;
  639. ICB Icb;
  640. UINT hb;
  641. b = getmem( (PVOID)addr, &Icb, sizeof( Icb ), NULL);
  642. if ( b == 0 ) {
  643. printf("<could not read the icb>\n");
  644. return;
  645. }
  646. icbscb = (Icb.NodeTypeCode == NW_NTC_ICB_SCB);
  647. if ( icbscb ) {
  648. printf( "---------------------------ICB_SCB at %08lx-----------------------------\n", addr );
  649. printf( "NodeTypeCode : NW_NTC_ICB_SCB\n" );
  650. } else {
  651. printf( "-----------------------------ICB at %08lx-------------------------------\n", addr );
  652. printf( "NodeTypeCode : NW_NTC_ICB\n" );
  653. }
  654. printf( "NodeByteSize : %d\n", Icb.NodeByteSize );
  655. printf( "ListEntry : %08lx\n", Icb.ListEntry );
  656. if (icbscb ) {
  657. printf( "SuperType Addr : %08lx (SCB)\n", Icb.SuperType.Scb );
  658. } else {
  659. printf( "SuperType Addr : %08lx (FCB)\n", Icb.SuperType.Fcb );
  660. printf( "NpFcb Addr : %08lx\n", Icb.NpFcb );
  661. }
  662. printf( "State : %s\n", IcbStateToString(Icb.State) );
  663. printf( "HasRemoteHandle : %s\n", Icb.HasRemoteHandle ? "TRUE" : "FALSE" );
  664. if ( Icb.HasRemoteHandle ) {
  665. printf( "Handle : " );
  666. for ( hb = 0; hb < 6; hb++ ) {
  667. printf( "%c ", (Icb.Handle)[hb]);
  668. }
  669. printf( "\n");
  670. }
  671. // What abou the PFILE_OBJECT?
  672. b = GET_STRING( Buffer, Icb.NwQueryTemplate );
  673. if ( b ) {
  674. printf( "NwQueryTemplate : %s\n", Buffer );
  675. } else {
  676. printf( "NWQueryTemplate : (unreadable)\n" );
  677. }
  678. b = GET_STRING( Buffer, Icb.UQueryTemplate );
  679. if ( b ) {
  680. printf( "UQueryTemplate : %ws\n", Buffer );
  681. } else {
  682. printf( "UQueryTemplate : (unreadable)\n" );
  683. }
  684. printf( "IndexLastIcbRtr : %d\n", Icb.IndexOfLastIcbReturned );
  685. printf( "Pid : %d\n", Icb.Pid );
  686. printf( "DotReturned : %s\n", Icb.DotReturned ? "TRUE" : "FALSE" );
  687. printf( "DotDotReturned : %s\n", Icb.DotDotReturned ? "TRUE" : "FALSE" );
  688. printf( "ReturnedSmthng : %s\n", Icb.ReturnedSomething ? "TRUE" : "FALSE" );
  689. printf( "ShortNameSearch : %s\n", Icb.ShortNameSearch ? "TRUE" : "FALSE" );
  690. printf( "SearchHandle : %d\n", Icb.SearchHandle );
  691. printf( "SearchVolume : %d\n", Icb.SearchVolume );
  692. printf( "SearchAttribts : %d\n", Icb.SearchAttributes );
  693. printf( "SearchIndexHigh : %d\n", Icb.SearchIndexHigh );
  694. printf( "SearchIndexLow : %d\n", Icb.SearchIndexLow );
  695. printf( "IsPrintJob : %s\n", Icb.IsPrintJob ? "TRUE" : "FALSE" );
  696. printf( "JobId : %d\n", Icb.JobId );
  697. printf( "ActuallyPrinted : %s\n", Icb.ActuallyPrinted ? "TRUE" : "FALSE" );
  698. printf( "USetLastAccessTime : %s\n", Icb.UserSetLastAccessTime ? "TRUE" : "FALSE" );
  699. printf( "File Position : %d\n", Icb.FilePosition );
  700. printf( "File Size : %d\n", Icb.FileSize );
  701. printf( "IsTreeHanle : %s\n", Icb.IsTreeHandle ? "TRUE" : "FALSE" );
  702. // This needs to be cleaned up!
  703. printf( "---------------------------------------------------------------------------\n" );
  704. }
  705. VOID
  706. DumpIrpContext(
  707. DWORD addr,
  708. PNTKD_EXTENSION_APIS lpExtensionApis
  709. )
  710. {
  711. BOOL b;
  712. IRP_CONTEXT IrpContext;
  713. b = getmem( (PVOID)addr, &IrpContext, sizeof( IrpContext ), NULL );
  714. if ( b == 0 ) {
  715. printf( "<could not read the irpcontext>\n" );
  716. return;
  717. }
  718. printf( "--------------------------IRP CONTEXT at %08lx--------------------------\n", addr );
  719. printf( "NodeTypeCode : NW_NTC_IRP_CONTEXT\n" );
  720. // WORK_QUEUE_ITEM?
  721. printf( "PacketType : %s\n", PacketToString(IrpContext.PacketType));
  722. printf( "NpScb Addr : %08lx\n", IrpContext.pNpScb );
  723. printf( "Scb Addr : %08lx\n", IrpContext.pScb );
  724. printf( "TdiStruct : %08lx\n", IrpContext.pTdiStruct );
  725. // NextRequest?
  726. printf( "Event : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, Event ) );
  727. printf( "Original IRP : %08lx\n", IrpContext.pOriginalIrp );
  728. printf( "Original SB : %08lx\n", IrpContext.pOriginalSystemBuffer );
  729. printf( "Original UB : %08lx\n", IrpContext.pOriginalUserBuffer );
  730. printf( "Original MDL : %08lx\n", IrpContext.pOriginalMdlAddress );
  731. printf( "Receive IRP : %08lx\n", IrpContext.ReceiveIrp );
  732. printf( "TxMdl : %08lx\n", IrpContext.TxMdl );
  733. printf( "RxMdl : %08lx\n", IrpContext.RxMdl );
  734. printf( "RunRoutine : %08lx\n", IrpContext.RunRoutine );
  735. printf( "pEx : %08lx\n", IrpContext.pEx );
  736. printf( "PostProcessRtn : %08lx\n", IrpContext.PostProcessRoutine );
  737. printf( "TimeoutRtn : %08lx\n", IrpContext.TimeoutRoutine );
  738. printf( "ComplSendRtn : %08lx\n", IrpContext.CompletionSendRoutine );
  739. printf( "pWorkItem : %08lx\n", IrpContext.pWorkItem );
  740. printf( "Req Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, req ) );
  741. printf( "ResponseLength : %08lx\n", IrpContext.ResponseLength );
  742. printf( "Rsp Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, rsp ) );
  743. printf( "Icb Addr : %08lx\n", IrpContext.Icb );
  744. printf( "Specific Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, Specific.Create.FullPathName ) );
  745. printf( "------------------------------IRP Context Flags----------------------------\n");
  746. PrintIrpContextFlags(IrpContext.Flags, lpExtensionApis);
  747. printf( "---------------------------------------------------------------------------\n" );
  748. return;
  749. }
  750. VOID
  751. DumpFcbNp(
  752. DWORD addr,
  753. PNTKD_EXTENSION_APIS lpExtensionApis,
  754. BOOL first
  755. )
  756. {
  757. WCHAR Buffer[64];
  758. BOOL b;
  759. NONPAGED_FCB NpFcb;
  760. b = getmem( (PVOID)addr, &NpFcb, sizeof( NONPAGED_FCB ), NULL);
  761. if ( !b ) {
  762. printf( "<could not read the non-pageable fcb>\n" );
  763. return;
  764. }
  765. printf( "--------------------Common NP FCB Header at %08lx-----------------------\n");
  766. printf( "NodeTypeCode : NW_NTC_NONPAGED_FCB\n" );
  767. printf( "NodeByteSize : %d\n", NpFcb.Header.NodeByteSize );
  768. printf( "IsFastIoPossible : %d\n", NpFcb.Header.IsFastIoPossible );
  769. // Resource? PagingIoResource?
  770. printf( "AllocationSize : %08lx %08lx\n", NpFcb.Header.AllocationSize.HighPart, NpFcb.Header.AllocationSize.LowPart );
  771. printf( "FileSize : %08lx %08lx\n", NpFcb.Header.FileSize.HighPart, NpFcb.Header.FileSize.LowPart );
  772. printf( "ValidDataLength : %08lx %08lx\n", NpFcb.Header.ValidDataLength.HighPart, NpFcb.Header.ValidDataLength.LowPart );
  773. printf( "pFcb Addr : %08lx\n", NpFcb.Fcb );
  774. // SegmentObject?
  775. printf( "FileLockList : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, FileLockList) );
  776. printf( "PendLockList : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, PendingLockList) );
  777. printf( "Resource : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, Resource ) );
  778. printf( "Attributes : %d\n", NpFcb.Attributes );
  779. printf( "CacheType : %d\n", NpFcb.CacheType );
  780. printf( "CacheBuffer : %08lx\n", NpFcb.CacheBuffer );
  781. printf( "CacheMdl : %08lx\n", NpFcb.CacheMdl );
  782. printf( "CacheSize : %d\n", NpFcb.CacheSize );
  783. printf( "CacheFileOffset : %d\n", NpFcb.CacheFileOffset );
  784. printf( "CacheDataSize : %d\n", NpFcb.CacheDataSize );
  785. printf( "----------------------------------FCB Flags--------------------------------\n" );
  786. PrintNpFcbFlags( NpFcb.Header.Flags, lpExtensionApis );
  787. // Dump both parts.
  788. if ( first )
  789. DumpFcb( (DWORD)NpFcb.Fcb, lpExtensionApis, FALSE );
  790. else
  791. printf( "---------------------------------------------------------------------------\n" );
  792. }
  793. VOID
  794. DumpRcb(
  795. DWORD addr,
  796. PNTKD_EXTENSION_APIS lpExtensionApis
  797. )
  798. /*++
  799. This function takes the address of an ICB and a pointer
  800. to a debugger extension interface block. It prints out
  801. the information in the ICB.
  802. --*/
  803. {
  804. BOOL b;
  805. RCB Rcb;
  806. b = getmem( (PVOID)addr, &Rcb, sizeof( RCB ), NULL);
  807. if ( b == 0 ) {
  808. printf("<could not read the rcb>\n");
  809. return;
  810. }
  811. printf( "------------------------------------------------------------\n");
  812. printf( "NodeTypeCode : NW_NTC_RCB\n");
  813. printf( "State : %s\n", RcbStateToString(Rcb.State));
  814. printf( "OpenCount : %ul\n", Rcb.OpenCount);
  815. printf( "ResourceAddr : %08lx\n", addr + FIELD_OFFSET( RCB, Resource ));
  816. printf( "ServerListAddr : %08lx\n", addr + FIELD_OFFSET( RCB,
  817. ServerNameTable ));
  818. printf( "VolumeListAddr : %08lx\n", addr + FIELD_OFFSET( RCB,
  819. VolumeNameTable ));
  820. printf( "FileListAddr : %08lx\n", addr + FIELD_OFFSET( RCB,
  821. FileNameTable ));
  822. printf( "------------------------------------------------------------\n");
  823. }
  824. VOID
  825. DumpPid(
  826. DWORD addr,
  827. PNTKD_EXTENSION_APIS lpExtensionApis
  828. )
  829. /*++
  830. This function takes the address of a PID and a pointer
  831. to a debugger extension interface block. It prints out
  832. the information in the PID.
  833. --*/
  834. {
  835. printf( "------------------------------------------------------------\n");
  836. printf( "NodeTypeCode : NW_NTC_PID\n" );
  837. printf( "...Not yet implemented...");
  838. printf( "------------------------------------------------------------\n");
  839. }
  840. VOID
  841. DumpFileLock(
  842. DWORD addr,
  843. PNTKD_EXTENSION_APIS lpExtensionApis
  844. )
  845. /*++
  846. This function takes the address of a file lock and a pointer
  847. to a debugger extension interface block. It prints out
  848. the information in the file lock.
  849. --*/
  850. {
  851. printf( "------------------------------------------------------------\n" );
  852. printf( "NodeTypeCode : NW_NTC_FILE_LOCK\n" );
  853. printf( "Not yet implemented...\n" );
  854. printf( "------------------------------------------------------------\n" );
  855. }
  856. VOID
  857. DumpLogon(
  858. DWORD addr,
  859. PNTKD_EXTENSION_APIS lpExtensionApis
  860. )
  861. /*++
  862. This function takes the address of a logon and a pointer
  863. to a debugger extension interface block. It prints out
  864. the information in the logon.
  865. --*/
  866. {
  867. BOOL b;
  868. LOGON Logon;
  869. WCHAR Buffer[64];
  870. b = getmem( (PVOID)addr, &Logon, sizeof(LOGON), NULL );
  871. if (!b ) {
  872. printf( "<unable to read logon>" );
  873. return;
  874. }
  875. printf( "------------------------------------------------------------\n");
  876. printf( "NodeTypeCode : NW_NTC_LOGON\n" );
  877. printf( "NodeByteSize : %d\n", Logon.NodeByteSize );
  878. printf( "NextLogon : %08lx (LOGON LIST_ENTRY)\n", addr +
  879. FIELD_OFFSET( LOGON, Next ));
  880. b = GET_STRING( Buffer, Logon.UserName );
  881. if ( b ) {
  882. printf( "UserName : %ws\n", Buffer );
  883. } else {
  884. printf( "UserName : <unreadable>\n" );
  885. }
  886. b = GET_STRING( Buffer, Logon.PassWord );
  887. if ( b ) {
  888. printf( "Password : %ws\n", Buffer );
  889. } else {
  890. printf( "Password : <unreadable>\n" );
  891. }
  892. b = GET_STRING( Buffer, Logon.ServerName );
  893. if ( b ) {
  894. printf( "Pref Server : %ws\n", Buffer );
  895. } else {
  896. printf( "Pref Server : <unreadable>\n" );
  897. }
  898. printf( "UserUid : %08lx %08lx\n", Logon.UserUid.HighPart,
  899. Logon.UserUid.LowPart);
  900. printf( "CredListResource: %08lx\n", addr +
  901. FIELD_OFFSET( LOGON, CredentialListResource ));
  902. printf( "CredentialList : %08lx (CREDENTIAL LIST_ENTRY)\n", addr +
  903. FIELD_OFFSET( LOGON, NdsCredentialList ));
  904. printf( "------------------------------------------------------------\n");
  905. }
  906. VOID
  907. DumpCredential(
  908. DWORD addr,
  909. PNTKD_EXTENSION_APIS lpExtensionApis
  910. )
  911. /*++
  912. This function takes the address of an nds credential and a
  913. pointer to a debugger extension interface block. It prints
  914. out the information in the logon.
  915. --*/
  916. {
  917. BOOL b;
  918. NDS_SECURITY_CONTEXT Context;
  919. NDS_CREDENTIAL Credential;
  920. NDS_SIGNATURE Signature;
  921. WCHAR Buffer[512];
  922. CHAR PackBuffer[2048];
  923. BYTE *packed;
  924. ULONG packedlen;
  925. b = getmem( (PVOID)addr, &Context, sizeof(NDS_SECURITY_CONTEXT), NULL );
  926. if (!b ) {
  927. printf( "<unable to read context>\n" );
  928. return;
  929. }
  930. printf( "-------- NDS Security Context at 0x%08lx ----------------\n", addr);
  931. printf( "NodeTypeCode : NW_NTC_NDS_CREDENTIAL\n" );
  932. printf( "NodeByteSize : %d\n", Context.nts );
  933. printf( "Next : %08lx (NDS_SECURITY_CONTEXT LIST_ENTRY)\n", addr +
  934. FIELD_OFFSET( NDS_SECURITY_CONTEXT, Next ));
  935. b = GET_STRING( Buffer, Context.NdsTreeName );
  936. if ( b ) {
  937. printf( "Nds Tree Name : %ws\n", Buffer );
  938. } else {
  939. printf( "Nds Tree Name : <unreadable>\n" );
  940. }
  941. b = GET_STRING( Buffer, Context.CurrentContext );
  942. if ( b ) {
  943. printf( "Current Context : %ws\n", Buffer );
  944. } else {
  945. printf( "Current Context :<unreadable>\n" );
  946. }
  947. printf( "Owning Logon : %08lx\n", Context.pOwningLogon );
  948. printf( "Handle Count : %d\n", Context.SupplementalHandleCount );
  949. if ( Context.Credential != NULL ) {
  950. printf( "--------------------- Credential Data ----------------------\n");
  951. b = getmem( (PVOID)Context.Credential, &Credential, sizeof(NDS_CREDENTIAL), NULL );
  952. if (!b ) {
  953. printf( "<unable to read credential>\n" );
  954. goto DO_SIGNATURE;
  955. }
  956. printf( "Start validity : 0x%08lx\n", Credential.validityBegin );
  957. printf( "End validity : 0x%08lx\n", Credential.validityEnd );
  958. printf( "Random : 0x%08lx\n", Credential.random );
  959. printf( "Opt data Len : %d\n", Credential.optDataSize );
  960. printf( "UserName Len : %d\n", Credential.userNameLength );
  961. //
  962. // Optional data is the first packed data after the struct.
  963. //
  964. packedlen = Credential.optDataSize + Credential.userNameLength;
  965. packed = ((BYTE *)Context.Credential) + sizeof( NDS_CREDENTIAL );
  966. if ( Credential.optDataSize ) {
  967. printf( "Opt data addr : %08lx\n", packed );
  968. }
  969. packed += Credential.optDataSize;
  970. b = getmem( (PVOID)packed, Buffer, Credential.userNameLength, NULL );
  971. if ( !b ) {
  972. printf( "<unable to read user name>\n" );
  973. goto DO_SIGNATURE;
  974. }
  975. printf( "Username : %ws\n", Buffer );
  976. } else {
  977. printf( "-------------------- No Credential Data --------------------\n");
  978. }
  979. DO_SIGNATURE:
  980. if ( Context.Signature != NULL ) {
  981. printf( "---------------------- Signature Data ----------------------\n");
  982. b = getmem( (PVOID)Context.Signature, &Signature, sizeof(NDS_SIGNATURE), NULL );
  983. if (!b ) {
  984. printf( "<unable to read signature>\n" );
  985. goto DO_END;
  986. }
  987. printf( "Signature Len : %d\n", Signature.signDataLength );
  988. packedlen = Signature.signDataLength;
  989. packed = ((BYTE *)Context.Signature) + sizeof( NDS_SIGNATURE );
  990. printf( "Signature addr : %08lx\n", packed );
  991. } else {
  992. printf( "-------------------- No Signature Data ---------------------\n");
  993. }
  994. DO_END:
  995. if ( Context.PublicNdsKey != NULL ) {
  996. printf( "------------------------------------------------------------\n");
  997. printf( "Public Key Len : %d\n", Context.PublicKeyLen );
  998. printf( "Public Key : %08lx\n", Context.PublicNdsKey );
  999. printf( "------------------------------------------------------------\n");
  1000. } else {
  1001. printf( "-------------------- No Public Key Data --------------------\n");
  1002. }
  1003. }
  1004. VOID
  1005. DumpMiniIrpContext(
  1006. DWORD addr,
  1007. PNTKD_EXTENSION_APIS lpExtensionApis
  1008. )
  1009. /*++
  1010. This function takes the address of a mini irp context
  1011. and a pointer to a debugger extension interface block.
  1012. It prints out the information in the mini irp context.
  1013. --*/
  1014. {
  1015. BOOL b;
  1016. MINI_IRP_CONTEXT mini;
  1017. b = getmem( (PVOID)addr, &mini, sizeof(MINI_IRP_CONTEXT), NULL );
  1018. if (!b ) {
  1019. printf( "<unable to read mini irp context>\n");
  1020. return;
  1021. }
  1022. printf( "------------------------------------------------------------\n");
  1023. printf( "NodeTypeCode : NW_NTC_MINI_IRP_CONTEXT\n" );
  1024. printf( "NodeByteSize : %d\n", mini.NodeByteSize );
  1025. printf( "ListEntry : %08lx\n", addr + FIELD_OFFSET( MINI_IRP_CONTEXT,
  1026. Next ));
  1027. printf( "IrpContext : %08lx\n", mini.IrpContext );
  1028. printf( "Irp : %08lx\n", mini.Irp );
  1029. printf( "Buffer : %08lx\n", mini.Buffer );
  1030. printf( "Mdl1 : %08lx\n", mini.Mdl1 );
  1031. printf( "Mdl2 : %08lx\n", mini.Mdl2 );
  1032. printf( "------------------------------------------------------------\n");
  1033. }
  1034. VOID
  1035. nwdump(
  1036. #ifdef WINDBG
  1037. HANDLE hProcess,
  1038. HANDLE hThread,
  1039. #endif
  1040. DWORD dwCurrentPc,
  1041. PNTKD_EXTENSION_APIS lpExtensionApis,
  1042. LPSTR lpArgumentString
  1043. )
  1044. /*++
  1045. Routine Description:
  1046. This function takes the pointer to a structure,
  1047. figures out what the structure is, and calls the
  1048. appropriate dump routine.
  1049. Arguments:
  1050. CurrentPc - Supplies the current pc at the time
  1051. the extension is called.
  1052. lpExtensionApis - Supplies the address of the
  1053. functions callable by this extension.
  1054. lpArgumentString - Supplies the address of the structure.
  1055. Return Value:
  1056. None.
  1057. ---*/
  1058. {
  1059. DWORD addr;
  1060. //
  1061. // Determine the node type and dispatch.
  1062. //
  1063. addr = getexpr( lpArgumentString );
  1064. switch ( GetNodeType( addr, lpExtensionApis ) ) {
  1065. case NW_NTC_SCB:
  1066. DumpScb(addr, lpExtensionApis, TRUE);
  1067. break;
  1068. case NW_NTC_SCBNP:
  1069. DumpScbNp(addr, lpExtensionApis, TRUE);
  1070. break;
  1071. case NW_NTC_FCB:
  1072. case NW_NTC_DCB:
  1073. DumpFcb(addr, lpExtensionApis, TRUE);
  1074. break;
  1075. case NW_NTC_VCB:
  1076. DumpVcb(addr, lpExtensionApis);
  1077. break;
  1078. case NW_NTC_ICB:
  1079. case NW_NTC_ICB_SCB:
  1080. DumpIcb(addr, lpExtensionApis);
  1081. break;
  1082. case NW_NTC_IRP_CONTEXT:
  1083. DumpIrpContext(addr, lpExtensionApis);
  1084. break;
  1085. case NW_NTC_NONPAGED_FCB:
  1086. DumpFcbNp(addr, lpExtensionApis, TRUE);
  1087. break;
  1088. case NW_NTC_RCB:
  1089. DumpRcb(addr, lpExtensionApis);
  1090. break;
  1091. case NW_NTC_PID:
  1092. DumpPid(addr, lpExtensionApis);
  1093. break;
  1094. case NW_NTC_FILE_LOCK:
  1095. DumpFileLock(addr, lpExtensionApis);
  1096. break;
  1097. case NW_NTC_LOGON:
  1098. DumpLogon(addr, lpExtensionApis);
  1099. break;
  1100. case NW_NTC_MINI_IRP_CONTEXT:
  1101. DumpMiniIrpContext(addr, lpExtensionApis);
  1102. break;
  1103. case NW_NTC_NDS_CREDENTIAL:
  1104. DumpCredential(addr, lpExtensionApis);
  1105. break;
  1106. default:
  1107. printf("(this object does not have a vaid node type)\n");
  1108. break;
  1109. }
  1110. }
  1111. //
  1112. // Other debugger routines.
  1113. //
  1114. VOID
  1115. serverlist(
  1116. #ifdef WINDBG
  1117. HANDLE hProcess,
  1118. HANDLE hThread,
  1119. #endif
  1120. DWORD dwCurrentPc,
  1121. PNTKD_EXTENSION_APIS lpExtensionApis,
  1122. LPSTR lpArgumentString
  1123. )
  1124. /*++
  1125. Routine Description:
  1126. This function displays a list of servers that the redirector
  1127. is maintaining connections to. The information is read from
  1128. the SCB queue, not from the server list in the RCB. The
  1129. argument to this function is ignored.
  1130. --*/
  1131. {
  1132. DWORD addrScbQueue;
  1133. WCHAR ServerName[64];
  1134. BOOL b;
  1135. PLIST_ENTRY ScbQueueList;
  1136. DWORD addrNpScb, addrScb;
  1137. NONPAGED_SCB NpScb;
  1138. SCB Scb;
  1139. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1140. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1141. //
  1142. // Get the address of the server list in the rdr.
  1143. //
  1144. addrScbQueue = getsymaddr("nwrdr!scbqueue");
  1145. if ( addrScbQueue == 0 ) {
  1146. printf("The server list was not locatable.\n");
  1147. return;
  1148. }
  1149. //
  1150. // Walk the list of servers.
  1151. //
  1152. printf("pNpScb pScb Ref State Name\n");
  1153. printf("---------------------------------------------------------------------------\n");
  1154. for ( GET_DWORD( &ScbQueueList, addrScbQueue );
  1155. ScbQueueList != (PLIST_ENTRY)addrScbQueue;
  1156. GET_DWORD( &ScbQueueList, ScbQueueList ) ) {
  1157. if ( lpCheckControlCRoutine() ) {
  1158. printf("<<<User Stop>>>\n");
  1159. break;
  1160. }
  1161. addrNpScb = (DWORD)CONTAINING_RECORD( ScbQueueList, NONPAGED_SCB, ScbLinks );
  1162. printf("%08lx ", addrNpScb );
  1163. b = (getmem)((LPVOID)addrNpScb,
  1164. &NpScb,
  1165. sizeof( NpScb ),
  1166. NULL);
  1167. if ( b == 0 ) {
  1168. printf("<could not continue>\n");
  1169. return;
  1170. }
  1171. addrScb = (DWORD)NpScb.pScb;
  1172. printf("%08lx ", addrScb );
  1173. printf("%8lx ", NpScb.Reference);
  1174. printf("%-25s", ScbStateToString( NpScb.State ) );
  1175. if ( addrScb != 0 ) {
  1176. b = (getmem)((LPVOID)addrScb,
  1177. &Scb,
  1178. sizeof( Scb ),
  1179. NULL);
  1180. if ( b == 0 ) {
  1181. printf("<unreadable>\n");
  1182. continue;
  1183. }
  1184. // Get the server name.
  1185. b = GET_STRING( ServerName, Scb.UidServerName );
  1186. if ( b ) {
  1187. printf( "%ws\n", ServerName );
  1188. } else {
  1189. printf( "Unreadable\n" );
  1190. }
  1191. } else {
  1192. printf( "Permanent SCB\n" );
  1193. }
  1194. }
  1195. printf("---------------------------------------------------------------------------\n");
  1196. }
  1197. VOID
  1198. trace(
  1199. #ifdef WINDBG
  1200. HANDLE hProcess,
  1201. HANDLE hThread,
  1202. #endif
  1203. DWORD dwCurrentPc,
  1204. PNTKD_EXTENSION_APIS lpExtensionApis,
  1205. LPSTR lpArgumentString
  1206. )
  1207. /*++
  1208. Routine Description:
  1209. This function dumps the nwrdr trace buffer. Arguments to
  1210. this function are ignored.
  1211. To Be Done:
  1212. Read trace buffer size out of nwrdrd and dynamically size.
  1213. --*/
  1214. {
  1215. ULONG addrDBuffer, addrDBufferPtr, DBufferPtr;
  1216. ULONG BufferSize;
  1217. PCHAR TraceStart, CurrentPtr;
  1218. char buffer[80 + 1];
  1219. char *bptr;
  1220. char *newptr;
  1221. int i;
  1222. int readsize;
  1223. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1224. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1225. addrDBuffer = getsymaddr( "nwrdr!dbuffer" );
  1226. if ( !addrDBuffer ) {
  1227. printf("(unable to locate the trace buffer address)\n");
  1228. return;
  1229. } else {
  1230. printf("Address of Dbuffer = %08lx\n", addrDBuffer );
  1231. }
  1232. addrDBufferPtr = getsymaddr( "nwrdr!dbufferptr" );
  1233. if ( !addrDBuffer ) {
  1234. printf("(unable to locate the trace buffer pointer)\n");
  1235. return;
  1236. } else {
  1237. printf("Address of DbufferPtr = %08lx\n", addrDBufferPtr );
  1238. }
  1239. GET_DWORD( &DBufferPtr, addrDBufferPtr );
  1240. printf("DbufferPtr = %08lx\n", DBufferPtr );
  1241. // Set up state variables and loop.
  1242. TraceStart = (char *)addrDBuffer;
  1243. BufferSize = 100*255+1;
  1244. CurrentPtr = (char *)DBufferPtr;
  1245. buffer[80] = '\0';
  1246. newptr = CurrentPtr + 1;
  1247. while ( 1 ) {
  1248. if ( lpCheckControlCRoutine() ) {
  1249. printf("<<<User Stop>>>\n");
  1250. break;
  1251. }
  1252. if ( newptr + 80 > TraceStart+BufferSize ) {
  1253. readsize = TraceStart+BufferSize - newptr;
  1254. } else {
  1255. readsize = 80;
  1256. }
  1257. getmem( newptr, buffer, readsize, NULL );
  1258. bptr = buffer;
  1259. for (i = 0; i<80 ; i++ ) {
  1260. if ( buffer[i] == '\n') {
  1261. buffer[i] = 0;
  1262. printf( "%s\n", bptr );
  1263. bptr = &buffer[i+1];
  1264. }
  1265. }
  1266. printf( "%s", bptr );
  1267. //
  1268. // If we're back to where we started, break out of here.
  1269. //
  1270. if ( (newptr <= CurrentPtr) &&
  1271. (newptr + readsize) >= CurrentPtr ) {
  1272. break;
  1273. }
  1274. //
  1275. // Advance the running pointer.
  1276. //
  1277. newptr += readsize;
  1278. if ( newptr >= TraceStart+BufferSize ) {
  1279. newptr = TraceStart;
  1280. }
  1281. }
  1282. printf( "\n");
  1283. }
  1284. VOID
  1285. reftrace(
  1286. #ifdef WINDBG
  1287. HANDLE hProcess,
  1288. HANDLE hThread,
  1289. #endif
  1290. DWORD dwCurrentPc,
  1291. PNTKD_EXTENSION_APIS lpExtensionApis,
  1292. LPSTR lpArgumentString
  1293. )
  1294. /*++
  1295. Routine Description:
  1296. This function dumps the nwrdr reference trace buffer.
  1297. --*/
  1298. {
  1299. ULONG addrRBuffer, addrRBufferPtr, RBufferPtr;
  1300. ULONG BufferSize;
  1301. PCHAR TraceStart, CurrentPtr;
  1302. char buffer[80 + 1];
  1303. char *bptr;
  1304. char *newptr;
  1305. int i;
  1306. int readsize;
  1307. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1308. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1309. addrRBuffer = getsymaddr( "nwrdr!RBuffer" );
  1310. if ( !addrRBuffer ) {
  1311. printf("(unable to locate the trace buffer address)\n");
  1312. return;
  1313. } else {
  1314. printf("Address of RBuffer = %08lx\n", addrRBuffer );
  1315. }
  1316. addrRBufferPtr = getsymaddr( "nwrdr!RBufferptr" );
  1317. if ( !addrRBuffer ) {
  1318. printf("(unable to locate the trace buffer pointer)\n");
  1319. return;
  1320. } else {
  1321. printf("Address of RBufferPtr = %08lx\n", addrRBufferPtr );
  1322. }
  1323. GET_DWORD( &RBufferPtr, addrRBufferPtr );
  1324. printf("RBufferPtr = %08lx\n", RBufferPtr );
  1325. // Set up state variables and loop.
  1326. TraceStart = (char *)addrRBuffer;
  1327. BufferSize = 100*255+1;
  1328. CurrentPtr = (char *)RBufferPtr;
  1329. buffer[80] = '\0';
  1330. newptr = CurrentPtr + 1;
  1331. while ( 1 ) {
  1332. if ( lpCheckControlCRoutine() ) {
  1333. printf("<<<User Stop>>>\n");
  1334. break;
  1335. }
  1336. if ( newptr + 80 > TraceStart+BufferSize ) {
  1337. readsize = TraceStart+BufferSize - newptr;
  1338. } else {
  1339. readsize = 80;
  1340. }
  1341. getmem( newptr, buffer, readsize, NULL );
  1342. bptr = buffer;
  1343. for (i = 0; i<80 ; i++ ) {
  1344. if ( buffer[i] == '\n') {
  1345. buffer[i] = 0;
  1346. printf( "%s\n", bptr );
  1347. bptr = &buffer[i+1];
  1348. }
  1349. }
  1350. printf( "%s", bptr );
  1351. //
  1352. // If we're back to where we started, break out of here.
  1353. //
  1354. if ( (newptr <= CurrentPtr) &&
  1355. (newptr + readsize) >= CurrentPtr ) {
  1356. break;
  1357. }
  1358. //
  1359. // Advance the running pointer.
  1360. //
  1361. newptr += readsize;
  1362. if ( newptr >= TraceStart+BufferSize ) {
  1363. newptr = TraceStart;
  1364. }
  1365. }
  1366. printf( "\n");
  1367. }
  1368. VOID
  1369. logonlist(
  1370. #ifdef WINDBG
  1371. HANDLE hProcess,
  1372. HANDLE hThread,
  1373. #endif
  1374. DWORD dwCurrentPc,
  1375. PNTKD_EXTENSION_APIS lpExtensionApis,
  1376. LPSTR lpArgumentString
  1377. )
  1378. /*++
  1379. Routine Description:
  1380. This routine prints out the logon list for the rdr. Arguments
  1381. to this function are ignored.
  1382. --*/
  1383. {
  1384. DWORD addrLogonList;
  1385. WCHAR Data[64];
  1386. BOOL b;
  1387. PLIST_ENTRY LogonList;
  1388. DWORD addrLogonEntry;
  1389. LOGON Logon;
  1390. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1391. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1392. // Get the address of the logon list.
  1393. addrLogonList = getsymaddr( "nwrdr!logonlist" );
  1394. if ( addrLogonList == 0 ) {
  1395. printf("The logon list could not be located.\n");
  1396. return;
  1397. }
  1398. // Walk the list of servers
  1399. printf("pLogon User Name Password Pref Server UID\n" );
  1400. printf("---------------------------------------------------------------------------\n" );
  1401. for ( GET_DWORD( &LogonList, addrLogonList );
  1402. LogonList != (PLIST_ENTRY)addrLogonList;
  1403. GET_DWORD( &LogonList, LogonList ) ) {
  1404. if ( lpCheckControlCRoutine() ) {
  1405. printf("<<<User Stop>>>\n");
  1406. break;
  1407. }
  1408. addrLogonEntry = (DWORD)CONTAINING_RECORD( LogonList, LOGON, Next );
  1409. printf("%08lx ", addrLogonEntry );
  1410. b = (getmem)((LPVOID)addrLogonEntry,
  1411. &Logon,
  1412. sizeof( Logon ),
  1413. NULL);
  1414. if ( b == 0 ) return;
  1415. if ( Logon.NodeTypeCode != NW_NTC_LOGON ) {
  1416. printf( "<invalid node type>\n" );
  1417. return;
  1418. }
  1419. b = GET_STRING( Data, Logon.UserName );
  1420. if ( b ) {
  1421. printf( "%-15ws", Data );
  1422. } else {
  1423. printf( "%-15s", "Unreadable" );
  1424. }
  1425. /*
  1426. b = GET_STRING( Data, Logon.PassWord );
  1427. if ( b ) {
  1428. printf( "%-15ws", Data );
  1429. } else {
  1430. printf( "%-15s", "Unreadable" );
  1431. }
  1432. */
  1433. printf( "%-15s", "<secret>" );
  1434. b = GET_STRING( Data, Logon.ServerName );
  1435. if ( b ) {
  1436. printf( "%-15ws", Data );
  1437. } else {
  1438. printf( "%-15s", "Unreadable" );
  1439. }
  1440. printf( "%08lx:%08x\n", Logon.UserUid.HighPart, Logon.UserUid.LowPart );
  1441. }
  1442. printf("---------------------------------------------------------------------------\n" );
  1443. }
  1444. //
  1445. // Functions that help mangle lists of objects.
  1446. //
  1447. VOID
  1448. vcblist(
  1449. #ifdef WINDBG
  1450. HANDLE hProcess,
  1451. HANDLE hThread,
  1452. #endif
  1453. DWORD dwCurrentPc,
  1454. PNTKD_EXTENSION_APIS lpExtensionApis,
  1455. LPSTR lpArgumentString
  1456. )
  1457. /*++
  1458. This function takes a pointer to the pageable portion
  1459. or non-pageable portion of an SCB and dumps the VCB
  1460. list for that SCB.
  1461. --*/
  1462. {
  1463. BOOL b;
  1464. PVOID objAddr;
  1465. PLIST_ENTRY VcbList;
  1466. DWORD addrVcbList;
  1467. PVCB addrVcb;
  1468. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1469. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1470. // Figure out which object we have.
  1471. objAddr = (PVOID)getexpr( lpArgumentString );
  1472. // Invariant: If we leave the switch, objAddr must point to the
  1473. // pageable portion of the SCB that we are interested in.
  1474. switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) {
  1475. case NW_NTC_SCB:
  1476. break;
  1477. case NW_NTC_SCBNP:
  1478. GET_DWORD( &objAddr,
  1479. ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, pScb ) ) );
  1480. if ( objAddr == 0 ) return;
  1481. break;
  1482. default:
  1483. printf( "(invalid node type code: argument must point to an scb or npscb)\n" );
  1484. return;
  1485. }
  1486. // Get the head of the vcb list.
  1487. addrVcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, ScbSpecificVcbQueue ));
  1488. // Walk the list and print.
  1489. for ( GET_DWORD( &VcbList, addrVcbList ) ;
  1490. VcbList != (PLIST_ENTRY)addrVcbList ;
  1491. GET_DWORD( &VcbList, VcbList ) ) {
  1492. if ( lpCheckControlCRoutine() ) {
  1493. printf("<<<User Stop>>>\n");
  1494. break;
  1495. }
  1496. addrVcb = (PVCB)CONTAINING_RECORD( VcbList, VCB, VcbListEntry );
  1497. if( GetNodeType( (DWORD)addrVcb, lpExtensionApis ) != NW_NTC_VCB )
  1498. printf( "(invalid entry in vcb list)\n" );
  1499. else
  1500. DumpVcb( (DWORD)addrVcb, lpExtensionApis );
  1501. }
  1502. }
  1503. VOID
  1504. irplist(
  1505. #ifdef WINDBG
  1506. HANDLE hProcess,
  1507. HANDLE hThread,
  1508. #endif
  1509. DWORD dwCurrentPc,
  1510. PNTKD_EXTENSION_APIS lpExtensionApis,
  1511. LPSTR lpArgumentString
  1512. )
  1513. /*++
  1514. This function takes a pointer to the non-pageable portion
  1515. of an SCB and dumps the IRP list for that non-pageable SCB.
  1516. --*/
  1517. {
  1518. PLIST_ENTRY IrpList;
  1519. DWORD addrIrpList;
  1520. PIRP_CONTEXT addrIrp;
  1521. PVOID objAddr;
  1522. BOOL b;
  1523. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1524. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1525. // Figure out which object we have.
  1526. objAddr = (PVOID)getexpr( lpArgumentString );
  1527. // Invariant: If we leave the switch, objAddr must point to the
  1528. // non-pageable portion of the SCB that we are interested in.
  1529. switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) {
  1530. case NW_NTC_SCB:
  1531. GET_DWORD( &objAddr,
  1532. ( (PCHAR)objAddr + FIELD_OFFSET( SCB, pNpScb ) ) );
  1533. if ( objAddr == 0 ) return;
  1534. break;
  1535. case NW_NTC_SCBNP:
  1536. break;
  1537. default:
  1538. printf( "(invalid node type code: argument must point to an scb or npscb)\n" );
  1539. return;
  1540. }
  1541. // Get the head of the request list.
  1542. addrIrpList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, Requests ));
  1543. // Walk the list and print.
  1544. for ( GET_DWORD( &IrpList, addrIrpList ) ;
  1545. IrpList != (PLIST_ENTRY)addrIrpList ;
  1546. GET_DWORD( &IrpList, IrpList ) ) {
  1547. if ( lpCheckControlCRoutine() ) {
  1548. printf("<<<User Stop>>>\n");
  1549. break;
  1550. }
  1551. addrIrp = (PIRP_CONTEXT)CONTAINING_RECORD( IrpList, IRP_CONTEXT, NextRequest );
  1552. if( GetNodeType( (DWORD)addrIrp, lpExtensionApis ) != NW_NTC_IRP_CONTEXT )
  1553. printf( "(invalid entry in the irp context list)\n" );
  1554. else
  1555. DumpIrpContext( (DWORD)addrIrp, lpExtensionApis );
  1556. }
  1557. }
  1558. VOID
  1559. fcblist(
  1560. #ifdef WINDBG
  1561. HANDLE hProcess,
  1562. HANDLE hThread,
  1563. #endif
  1564. DWORD dwCurrentPc,
  1565. PNTKD_EXTENSION_APIS lpExtensionApis,
  1566. LPSTR lpArgumentString
  1567. )
  1568. /*++
  1569. This function takes a pointer to a VCB and dumps
  1570. the FCB list for that VCB.
  1571. --*/
  1572. {
  1573. PLIST_ENTRY FcbList;
  1574. DWORD addrFcbList;
  1575. PFCB addrFcb;
  1576. NODE_TYPE_CODE ntc;
  1577. PVOID objAddr;
  1578. BOOL b;
  1579. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1580. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1581. // Figure out which object we have.
  1582. objAddr = (PVOID)getexpr( lpArgumentString );
  1583. if ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) != NW_NTC_VCB ) {
  1584. printf( "(invalid node type code: argument must point to a vcb)\n" );
  1585. return;
  1586. }
  1587. // Get the head of the fcb list.
  1588. addrFcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( VCB, FcbList ));
  1589. for ( GET_DWORD( &FcbList, addrFcbList ) ;
  1590. FcbList != (PLIST_ENTRY)addrFcbList ;
  1591. GET_DWORD( &FcbList, FcbList ) ) {
  1592. if ( lpCheckControlCRoutine() ) {
  1593. printf("<<<User Stop>>>\n");
  1594. break;
  1595. }
  1596. addrFcb = (PFCB)CONTAINING_RECORD( FcbList, FCB, FcbListEntry );
  1597. ntc = GetNodeType( (DWORD)addrFcb, lpExtensionApis );
  1598. if( (ntc != NW_NTC_FCB) && (ntc != NW_NTC_DCB) )
  1599. printf( "(invalid entry in the fcb list)\n" );
  1600. else
  1601. DumpFcb( (DWORD)addrFcb, lpExtensionApis, TRUE );
  1602. }
  1603. }
  1604. VOID
  1605. icblist(
  1606. #ifdef WINDBG
  1607. HANDLE hProcess,
  1608. HANDLE hThread,
  1609. #endif
  1610. DWORD dwCurrentPc,
  1611. PNTKD_EXTENSION_APIS lpExtensionApis,
  1612. LPSTR lpArgumentString
  1613. )
  1614. /*++
  1615. This function takes a pointer to the pageable portion
  1616. of an SCB or FCB and dumps the ICB list for that SCB or FCB.
  1617. --*/
  1618. {
  1619. PVOID objAddr;
  1620. BOOL b;
  1621. NODE_TYPE_CODE ntc;
  1622. PICB addrIcb;
  1623. PLIST_ENTRY IcbList;
  1624. DWORD addrIcbList, IcbCount;
  1625. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1626. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1627. // Figure out which object we have.
  1628. objAddr = (PVOID)getexpr( lpArgumentString );
  1629. // Invariant: If we leave the switch, addrIcbList must point
  1630. // to the head of the ICB list that we are interested in.
  1631. switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) {
  1632. case NW_NTC_SCB:
  1633. addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, IcbList ));
  1634. break;
  1635. case NW_NTC_SCBNP:
  1636. // Look up the pageable portion.
  1637. GET_DWORD( &objAddr,
  1638. ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, pScb ) ) );
  1639. if ( objAddr == 0 ) return;
  1640. // Now get it.
  1641. addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, IcbList));
  1642. break;
  1643. case NW_NTC_FCB:
  1644. case NW_NTC_DCB:
  1645. addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( FCB, IcbList ));
  1646. break;
  1647. case NW_NTC_NONPAGED_FCB:
  1648. // Look up the pageable portion.
  1649. GET_DWORD( &objAddr,
  1650. ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_FCB, Fcb ) ) );
  1651. if (objAddr == 0) return;
  1652. // Now get it.
  1653. addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( FCB, IcbList ));
  1654. break;
  1655. default:
  1656. printf( "(invalid node type: argument must be: scb, npscb, fcb, dcb, or npfcb)\n" );
  1657. return;
  1658. }
  1659. // Walk the list.
  1660. for ( GET_DWORD( &IcbList, addrIcbList ) ;
  1661. IcbList != (PLIST_ENTRY)addrIcbList ;
  1662. GET_DWORD( &IcbList, IcbList ) ) {
  1663. if ( lpCheckControlCRoutine() ) {
  1664. printf("<<<User Stop>>>\n");
  1665. break;
  1666. }
  1667. addrIcb = (PICB)CONTAINING_RECORD( IcbList, ICB, ListEntry );
  1668. ntc = GetNodeType( (DWORD)addrIcb, lpExtensionApis );
  1669. if( (ntc != NW_NTC_ICB) && (ntc != NW_NTC_ICB_SCB) )
  1670. printf( "(invalid entry in icb list)\n" );
  1671. else
  1672. DumpIcb( (DWORD)addrIcb, lpExtensionApis );
  1673. }
  1674. }
  1675. VOID
  1676. credlist(
  1677. #ifdef WINDBG
  1678. HANDLE hProcess,
  1679. HANDLE hThread,
  1680. #endif
  1681. DWORD dwCurrentPc,
  1682. PNTKD_EXTENSION_APIS lpExtensionApis,
  1683. LPSTR lpArgumentString
  1684. )
  1685. /*++
  1686. This function takes a pointer to a LOGON and dumps
  1687. the NDS credential list for that user.
  1688. --*/
  1689. {
  1690. PLIST_ENTRY CredList;
  1691. DWORD addrCredList;
  1692. PNDS_SECURITY_CONTEXT addrCred;
  1693. NODE_TYPE_CODE ntc;
  1694. PVOID objAddr;
  1695. BOOL b;
  1696. PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1697. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  1698. // Figure out which object we have.
  1699. objAddr = (PVOID)getexpr( lpArgumentString );
  1700. if ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) != NW_NTC_LOGON ) {
  1701. printf( "(invalid node type code: argument must point to a logon)\n" );
  1702. return;
  1703. }
  1704. // Get the head of the fcb list.
  1705. addrCredList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( LOGON, NdsCredentialList ));
  1706. for ( GET_DWORD( &CredList, addrCredList ) ;
  1707. CredList != (PLIST_ENTRY)addrCredList ;
  1708. GET_DWORD( &CredList, CredList ) ) {
  1709. if ( lpCheckControlCRoutine() ) {
  1710. printf("<<<User Stop>>>\n");
  1711. break;
  1712. }
  1713. addrCred = (PNDS_SECURITY_CONTEXT)
  1714. CONTAINING_RECORD( CredList,
  1715. NDS_SECURITY_CONTEXT,
  1716. Next );
  1717. ntc = GetNodeType( (DWORD)addrCred, lpExtensionApis );
  1718. if( (ntc != NW_NTC_NDS_CREDENTIAL ) )
  1719. printf( "(invalid entry in the credential list)\n" );
  1720. else
  1721. DumpCredential( (DWORD)addrCred, lpExtensionApis);
  1722. printf("\n");
  1723. }
  1724. }