From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/nw/rdr/kdext/nwrdrkd.c | 2223 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2223 insertions(+) create mode 100644 private/nw/rdr/kdext/nwrdrkd.c (limited to 'private/nw/rdr/kdext/nwrdrkd.c') diff --git a/private/nw/rdr/kdext/nwrdrkd.c b/private/nw/rdr/kdext/nwrdrkd.c new file mode 100644 index 000000000..0b1abeef2 --- /dev/null +++ b/private/nw/rdr/kdext/nwrdrkd.c @@ -0,0 +1,2223 @@ +/*++ + +NwRdr Kernel Debugger Extensions +Copyright (c) 1995 Microsoft Corporation + +Abstract: + + NW Redirector Kernel Debugger extensions. + + This module contains a set of useful kernel debugger + extensions for the NT nw redirector. + +Author: + + Cory West , 09-Jan-1994 + +--*/ + +#include "procs.h" +#include "nodetype.h" + +#include +#include +#include + +// +// Function prototypes. +// + +VOID +DumpScbNp( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ); + +VOID +DumpFcbNp( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ); + +// +// Define some macros for simplicity. +// + +#define GET_DWORD( pDest, addr ) \ + (lpExtensionApis->lpReadVirtualMemRoutine)((LPVOID)(addr), pDest, 4, NULL) +#define GET_WORD( pDest, addr ) \ + (lpExtensionApis->lpReadVirtualMemRoutine)((LPVOID)(addr), pDest, 2, NULL) +#define GET_STRING( pDest, string ) \ + (lpExtensionApis->lpReadVirtualMemRoutine)(string.Buffer, pDest, \ + string.Length, NULL); pDest[ string.Length/2 ] = L'\0' + +#define printf lpExtensionApis->lpOutputRoutine +#define getmem lpExtensionApis->lpReadVirtualMemRoutine +#define getexpr lpExtensionApis->lpGetExpressionRoutine + +#ifdef WINDBG +#define getsymaddr( string ) ((lpExtensionApis->lpGetExpressionRoutine))( "&"##string ) +#else +#define getsymaddr lpExtensionApis->lpGetExpressionRoutine +#endif + +VOID +help( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function prints out usage for the nw debugger extensions. + +--*/ +{ + printf( "---------------------------------------------------------------------------\n"); + printf( "NwRdr Debugger Extensions:\n\n"); + + printf( "Top Level Functions:\n\n"); + + printf( "serverlist(void) - List the servers that the redirector knows.\n"); + printf( "logonlist(void) - List the users that are logged on.\n"); + printf( "trace(void) - Display the trace buffer.\n"); + printf( "nwdump(virtual addr) - Display the object at the given virtual address.\n"); + printf( " (This function knows how to dump all NwRdr data\n"); + printf( " structures.)\n"); + printf( "help(void) - Display this message.\n\n"); + + printf( "List Management Functions:\n\n"); + + printf( "vcblist(scb*, npscb*) - Given a pointer to any of the specified objects,\n"); + printf( " this function dumps the VCB list for that server.\n"); + printf( "irplist(scb*, npscb*) - Given a pointer to any of the specified objects,\n"); + printf( " this function dumps the IRP list for that server.\n"); + printf( "fcblist(vcb*) - Given a pointer to a VCB, this function dumps\n"); + printf( " the FCB/DCB list for that VCB.\n"); + printf( "icblist(scb*, npscb*,\n"); + printf( " fcb*, dcb*,\n"); + printf( " npfcb*) - Given a pointer to any of the specified objects,\n"); + printf( " function dumps the ICB list for that object.\n"); + printf( "---------------------------------------------------------------------------\n"); +} + +VOID +traceflags( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function prints out the trace flag values. + +--*/ +{ + printf( "DEBUG_TRACE_CLEANUP (0x00000001)\n"); + printf( "DEBUG_TRACE_CLOSE (0x00000002)\n"); + printf( "DEBUG_TRACE_CLEANUP (0x00000001)\n"); + printf( "DEBUG_TRACE_CLOSE (0x00000002)\n"); + printf( "DEBUG_TRACE_CREATE (0x00000004)\n"); + printf( "DEBUG_TRACE_FSCTRL (0x00000008)\n"); + printf( "DEBUG_TRACE_IPX (0x00000010)\n"); + printf( "DEBUG_TRACE_LOAD (0x00000020)\n"); + printf( "DEBUG_TRACE_EXCHANGE (0x00000040)\n"); + printf( "DEBUG_TRACE_FILOBSUP (0x00000080)\n"); + printf( "DEBUG_TRACE_STRUCSUP (0x00000100)\n"); + printf( "DEBUG_TRACE_FSP_DISPATCHER (0x00000200)\n"); + printf( "DEBUG_TRACE_FSP_DUMP (0x00000400)\n"); + printf( "DEBUG_TRACE_WORKQUE (0x00000800)\n"); + printf( "DEBUG_TRACE_UNWIND (0x00001000)\n"); + printf( "DEBUG_TRACE_CATCH_EXCEPTIONS (0x00002000)\n"); + printf( "DEBUG_TRACE_FILEINFO (0x00008000)\n"); + printf( "DEBUG_TRACE_DIRCTRL (0x00010000)\n"); + printf( "DEBUG_TRACE_CONVERT (0x00020000)\n"); + printf( "DEBUG_TRACE_WRITE (0x00040000)\n"); + printf( "DEBUG_TRACE_READ (0x00080000)\n"); + printf( "DEBUG_TRACE_VOLINFO (0x00100000)\n"); + printf( "DEBUG_TRACE_LOCKCTRL (0x00200000)\n"); + printf( "DEBUG_TRACE_USERNCP (0x00400000)\n"); + printf( "DEBUG_TRACE_SECURITY (0x00800000)\n"); + printf( "DEBUG_TRACE_CACHE (0x01000000)\n"); + printf( "DEBUG_TRACE_LIP (0x02000000)\n"); + printf( "DEBUG_TRACE_MDL (0x04000000)\n"); + printf( "DEBUG_TRACE_NDS (0x10000000)\n"); + printf( "DEBUG_TRACE_SCAVENGER (0x40000000)\n"); + printf( "DEBUG_TRACE_TIMER (0x80000000)\n"); +} + +// +// Internal helper routines to convert numerical data into symbolic data. +// + +NODE_TYPE_CODE +GetNodeType( + DWORD objAddr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + Given the address of an object, this function will + attempt to get the node type code for that object. + +--*/ +{ + + NODE_TYPE_CODE ntc; + GET_WORD( &ntc, objAddr ); + return ntc; + +} + +LPSTR +RcbStateToString( + DWORD State + ) +/*++ + +Routine Description: + + This helper function converts the RCB state from a + DWORD to a readable text string. + +Arguments: + + DWORD State - The DWORD RCB state. + +Return Value: + + LPSTR containing the readable text string. + +--*/ +{ + switch ( State ) { + + case RCB_STATE_STOPPED: + return("RCB_STATE_STOPPED"); + + + case RCB_STATE_STARTING: + return("RCB_STATE_STARTING"); + + case RCB_STATE_NEED_BIND: + return("RCB_STATE_NEED_BIND"); + + case RCB_STATE_RUNNING: + return("RCB_STATE_RUNNING"); + + case RCB_STATE_SHUTDOWN: + return("RCB_STATE_SHUTDOWN"); + + default: + return("(state unknown)" ); + } +} + +LPSTR +ScbStateToString( + DWORD State + ) +/*++ + +Routine Description: + + This helper function converts the SCB state from a + DWORD to a readable text string. + +Arguments: + + DWORD State - The DWORD SCB state. + +Return Value: + + LPSTR containing the readable text string. + +--*/ +{ + switch ( State ) { + + case SCB_STATE_ATTACHING: + return("SCB_STATE_ATTACHING" ); + + case SCB_STATE_IN_USE: + return("SCB_STATE_IN_USE" ); + + case SCB_STATE_DISCONNECTING: + return("SCB_STATE_DISCONNECTING" ); + + case SCB_STATE_FLAG_SHUTDOWN: + return("SCB_STATE_FLAG_SHUTDOWN" ); + + case SCB_STATE_RECONNECT_REQUIRED: + return("SCB_STATE_RECONNECT_REQD" ); + + case SCB_STATE_LOGIN_REQUIRED: + return("SCB_STATE_LOGIN_REQUIRED" ); + + case SCB_STATE_TREE_SCB: + return("SCB_STATE_TREE_SCB" ); + + default: + return("(state unknown)" ); + } +} + +LPSTR +IcbStateToString( + DWORD State + ) +/*++ + +Routine Description: + + This helper function converts the ICB state from a + DWORD to a readable text string. + +--*/ +{ + switch ( State ) { + + case ICB_STATE_OPEN_PENDING: + return("ICB_STATE_OPEN_PENDING" ); + + case ICB_STATE_OPENED: + return("ICB_STATE_OPENED" ); + + case ICB_STATE_CLEANED_UP: + return("ICB_STATE_CLEANED_UP" ); + + case ICB_STATE_CLOSE_PENDING: + return("ICB_STATE_CLOSE_PENDING" ); + + default: + return("(state unknown)" ); + } +} + +VOID +PrintIrpContextFlags( + ULONG Flags, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + Print out the flags that are set in the IRP_CONTEXT flags. + +--*/ +{ + + if ( Flags & IRP_FLAG_IN_FSD ) + printf( "\tIRP_FLAG_IN_FSD\n" ); + + if ( Flags & IRP_FLAG_ON_SCB_QUEUE ) + printf( "\tIRP_FLAG_ON_SCB_QUEUE\n" ); + + if ( Flags & IRP_FLAG_SEQUENCE_NO_REQUIRED ) + printf( "\tIRP_FLAG_SEQUENCE_NO_REQUIRED\n" ); + + if ( Flags & IRP_FLAG_SIGNAL_EVENT ) + printf( "\tIRP_FLAG_SIGNAL_EVENT\n" ); + + if ( Flags & IRP_FLAG_RETRY_SEND ) + printf( "\tIRP_FLAG_RETRY_SEND\n" ); + + if ( Flags & IRP_FLAG_RECONNECTABLE ) + printf( "\tIRP_FLAG_RECONNECTABLE\n" ); + + if ( Flags & IRP_FLAG_RECONNECT_ATTEMPT ) + printf( "\tIRP_FLAG_RECONNECT_ATTEMPT\n" ); + + if ( Flags & IRP_FLAG_BURST_REQUEST ) + printf( "\tIRP_FLAG_BURST_REQUEST\n" ); + + if ( Flags & IRP_FLAG_BURST_PACKET )\ + printf( "\tIRP_FLAG_BURST_PACKET\n" ); + + if ( Flags & IRP_FLAG_NOT_OK_TO_RECEIVE ) + printf( "\tIRP_FLAG_NOT_OK_TO_RECEIVE\n" ); + + if ( Flags & IRP_FLAG_REROUTE_ATTEMPTED ) + printf( "\tIRP_FLAG_REROUTE_ATTEMPTED\n" ); + + if ( Flags & IRP_FLAG_BURST_WRITE ) + printf( "\tIRP_FLAG_BURST_WRITE\n" ); + + if ( Flags & IRP_FLAG_SEND_ALWAYS ) + printf( "\tIRP_FLAG_SEND_ALWAYS\n" ); + + if ( Flags & IRP_FLAG_FREE_RECEIVE_MDL ) + printf( "\tIRP_FLAG_FREE_RECEIVE_MDL\n" ); + + if ( Flags & IRP_FLAG_NOT_SYSTEM_PACKET ) + printf( "\tIRP_FLAG_NOT_SYSTEM_PACKET\n" ); + + if ( Flags & IRP_FLAG_NOCONNECT ) + printf( "\tIRP_FLAG_NOCONNECT\n" ); + +} + +VOID +PrintNpFcbFlags( + ULONG Flags, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + Print out the flags that are set in the IRP_CONTEXT flags. + +--*/ +{ + + if ( Flags & FCB_FLAGS_DELETE_ON_CLOSE ) + printf( "\tFCB_FLAGS_DELETE_ON_CLOSE\n" ); + + if ( Flags & FCB_FLAGS_TRUNCATE_ON_CLOSE ) + printf( "\tFCB_FLAGS_TRUNCATE_ON_CLOSE\n" ); + + if ( Flags & FCB_FLAGS_PAGING_FILE ) + printf( "\tFCB_FLAGS_PAGING_FILE\n" ); + + if ( Flags & FCB_FLAGS_PREFIX_INSERTED ) + printf( "\tFCB_FLAGS_PREFIX_INSERTED\n" ); + + if ( Flags & FCB_FLAGS_FORCE_MISS_IN_PROGRESS ) + printf( "\tFCB_FLAGS_FORCE_MISS_IN_PROGRESS\n" ); + + if ( Flags & FCB_FLAGS_ATTRIBUTES_ARE_VALID ) + printf( "\tFCB_FLAGS_ATTRIBUTES_ARE_VALID\n" ); + + if ( Flags & FCB_FLAGS_LONG_NAME ) + printf( "\tFCB_FLAGS_LONG_NAME\n" ); +} + +LPSTR +PacketToString( + UINT pt + ) +/*++ + +Routine Description: + + This helper function converts a PACKET_TYPE to + a readable text string. + +--*/ +{ + + switch ( pt ) { + + case SAP_BROADCAST: + return "SAP_BROADCAST"; + case NCP_CONNECT: + return "NCP_CONNECT"; + case NCP_FUNCTION: + return "NCP_FUNCTION"; + case NCP_SUBFUNCTION: + return "NCP_SUBFUNCTION"; + case NCP_DISCONNECT: + return "NCP_DISCONNECT"; + case NCP_BURST: + return "NCP_BURST"; + case NCP_ECHO: + return "NCP_ECHO"; + default: + return "(packet type unknown)"; + } + +} + +// +// The internal object functions for the nwdump() routine. +// These functions must receive good pointers; they are +// neither smart, nor exported. +// + +VOID +DumpScb( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ) +/*++ + + This function takes the address of the pageable portion + of an SCB and a pointer to a debugger extension interface + block. It prints out the information in the SCB and + the corresponding non-pageable SCB. + +--*/ +{ + WCHAR Buffer[64]; + BOOL b; + SCB Scb; + + // Read it. + + b = getmem((PVOID)addr, &Scb, sizeof( Scb ), NULL); + if ( b == 0 ) { + printf("\n"); + return; + } + printf( "-----------------------------SCB at %08lx-------------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_SCB\n" ); + printf( "NodeByteSize : %d\n", Scb.NodeByteSize ); + printf( "pNpScb Addr : %08lx\n", Scb.pNpScb ); + printf( "Version : %d\\%d\n", Scb.MajorVersion, Scb.MinorVersion ); + printf( "VcbList : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( SCB, ScbSpecificVcbQueue )); + printf( "VcbCount : %d\n", Scb.VcbCount ); + printf( "IcbList : %08lx (LIST_ENTRY, ICB)\n", addr + FIELD_OFFSET( SCB, IcbList )); + printf( "IcbCount : %d\n", Scb.IcbCount ); + printf( "OpenNdsStreams : %d\n", Scb.OpenNdsStreams ); + printf( "UserUid : %08lx %08lx\n", Scb.UserUid.HighPart, Scb.UserUid.LowPart ); + printf( "OpenFileCount : %d\n", Scb.OpenFileCount ); + + b = GET_STRING( Buffer, Scb.UidServerName ); + if ( b ) { + printf( "UidServerName : %ws\n", Buffer ); + } else { + printf( "UidServerName : (unreadable)\n"); + } + + b = GET_STRING( Buffer, Scb.NdsTreeName ); + if ( b ) { + printf( "NDS Tree Name : %ws\n", Buffer ); + } else { + printf( "Nds Tree Name : (none)\n"); + } + + b = GET_STRING( Buffer, Scb.UnicodeUid ); + + if ( b ) { + printf( "UnicodeUid : %ws\n", Buffer ); + } else { + printf( "UnicodeUid : (unreadable)\n"); + } + + + b = GET_STRING( Buffer, Scb.UserName ); + + if ( b ) { + printf( "User name : %ws\n", Buffer ); + } else { + printf( "User name : (unreadable)\n" ); + } + + b = GET_STRING( Buffer, Scb.Password ); + + if ( b ) { + printf( "Password : %ws\n", Buffer ); + } else { + printf( "Password : (unreadable)\n" ); + } + + printf( "PreferredServer : %s\n", Scb.PreferredServer ? "TRUE" : "FALSE" ); + printf( "MessageWaiting : %s\n", Scb.MessageWaiting ? "TRUE" : "FALSE" ); + printf( "AttachCount : %d\n", Scb.AttachCount); + + // What about the drive map? + + // Dump both parts. + if ( first ) + DumpScbNp( (DWORD)Scb.pNpScb, lpExtensionApis, FALSE ); + else + printf( "---------------------------------------------------------------------------\n"); + + return; +} + +VOID +DumpScbNp( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ) +/*++ + + This function takes the address of the nonpageable + portion of an SCB and a pointer to a debugger extension + interface block. It prints out the information in the + nonpageable SCB and the corresponding pageable SCB. + +--*/ +{ + WCHAR Buffer[64]; + BOOL b; + NONPAGED_SCB NpScb; + + // Read it. + + b = getmem( (PVOID)addr, &NpScb, sizeof( NpScb ), NULL ); + if ( b == 0 ) { + printf("\n"); + return; + } + + printf( "------------------------Non-Pageable SCB at %08lx-----------------------\n", addr); + printf( "NodeTypeCode : NW_NTC_SCBNP\n" ); + printf( "NodeByteSize : %d\n", NpScb.NodeByteSize ); + + b = GET_STRING( Buffer, NpScb.ServerName ); + if ( b ) { + printf( "ServerName : %ws\n", Buffer ); + } else { + printf( "ServerName : (unreadable)\n" ); + } + + printf( "pScb Addr : %08lx\n", NpScb.pScb ); + printf( "Reference Count : %08lx\n", NpScb.Reference ); + printf( "State : %s\n", ScbStateToString( NpScb.State )); + printf( "Last Used Time : %08lx %08lx\n", NpScb.LastUsedTime.HighPart, NpScb.LastUsedTime.LowPart ); + printf( "Sending : %s\n", NpScb.Sending ? "TRUE" : "FALSE" ); + printf( "Receiving : %s\n", NpScb.Receiving ? "TRUE" : "FALSE" ); + printf( "Ok To Receive : %s\n", NpScb.OkToReceive ? "TRUE" : "FALSE" ); + printf( "PageAlign : %s\n", NpScb.PageAlign ? "TRUE" : "FALSE" ); + printf( "Scblinks : %08lx (LIST_ENTRY, NPSCB)\n", addr + FIELD_OFFSET( NONPAGED_SCB, ScbLinks )); + printf( "Requests : %08lx (LIST_ENTRY, NPSCB)\n", addr + FIELD_OFFSET( NONPAGED_SCB, Requests )); + printf( "------------------------------Transport Info-------------------------------\n" ); + printf( "TickCount : %d\n", NpScb.TickCount ); + printf( "RetryCount : %d\n", NpScb.RetryCount ); + printf( "Timeout : %d\n", NpScb.TimeOut ); + printf( "SequenceNo : %d\n", NpScb.SequenceNo ); + printf( "ConnectionNo : %d\n", NpScb.ConnectionNo ); + printf( "ConnectionNoHi : %d\n", NpScb.ConnectionNoHigh ); + printf( "ConnectionStat : %d\n", NpScb.ConnectionStatus ); + printf( "MaxTimeOut : %d\n", NpScb.MaxTimeOut ); + printf( "BufferSize : %d\n", NpScb.BufferSize ); + printf( "TaskNo : %d\n", NpScb.TaskNo ); + printf( "Spin lock : %s\n", NpScb.NpScbSpinLock == 0 ? "Released" : "Acquired " ); + printf( "LIP Data Speed : %d\n", NpScb.LipDataSpeed ); + printf( "---------------------------Burst Mode Parameters---------------------------\n"); + printf( "SourceConnId : %08lx\n", NpScb.SourceConnectionId ); + printf( "DestConnId : %08lx\n", NpScb.DestinationConnectionId ); + printf( "MaxPacketSize : %d\n", NpScb.MaxPacketSize ); + printf( "MaxSendSize : %ld\n", NpScb.MaxSendSize ); + printf( "MaxReceiveSize : %ld\n", NpScb.MaxReceiveSize ); + printf( "SendBMEnable : %s\n", NpScb.SendBurstModeEnabled ? "TRUE" : "FALSE" ); + printf( "ReceiveBMEnable : %s\n", NpScb.ReceiveBurstModeEnabled ? "TRUE" : "FALSE" ); + printf( "BurstSequenceNo : %d\n", NpScb.BurstSequenceNo ); + printf( "BurstRequestNo : %d\n", NpScb.BurstRequestNo ); + printf( "BurstSendDelay : Good %d,\tCurrent %d,\tBad %d\n", NpScb.NwGoodSendDelay, NpScb.NwSendDelay, NpScb.NwBadSendDelay ); + printf( "BurstReceiveDelay : Good %d,\tCurrent %d,\tBad %d\n", NpScb.NwGoodReceiveDelay, NpScb.NwReceiveDelay, NpScb.NwBadReceiveDelay ); + printf( "BurstSuccessCount : Send %d, Receive %d\n", NpScb.SendBurstSuccessCount, NpScb.ReceiveBurstSuccessCount ); + printf( "--------------------------Send Delays and Timeouts-------------------------\n" ); + printf( "SendTimeout : %d\n", NpScb.SendTimeout ); + printf( "TotalWaitTime : %d\n", NpScb.TotalWaitTime ); + printf( "NwLoopTime : %d\n", NpScb.NwLoopTime ); + printf( "NwSingleBurst : %d\n", NpScb.NwSingleBurstPacketTime ); + printf( "NwMaxSendDelay : %d\n", NpScb.NwMaxSendDelay ); + printf( "NwGoodSendDelay : %d\n", NpScb.NwGoodSendDelay ); + printf( "NwBadSendDelay : %d\n", NpScb.NwBadSendDelay ); + printf( "BurstDataWritten : %d\n", NpScb.BurstDataWritten ); + printf( "NwMaxReceiveDelay : %d\n", NpScb.NwMaxReceiveDelay ); + printf( "NwReceiveDelay : %d\n", NpScb.NwReceiveDelay ); + printf( "NwGoodReceiveDelay : %d\n", NpScb.NwGoodReceiveDelay ); + printf( "NwBadReceiveDelay : %d\n", NpScb.NwBadReceiveDelay ); + printf( "CurrentBurstDelay : %d\n", NpScb.CurrentBurstDelay ); + printf( "NtSendDelay : %08lx %08lx\n", NpScb.NtSendDelay.HighPart, NpScb.NtSendDelay.LowPart ); + printf( "NwNextEventTime : %08lx %08lx\n", NpScb.NwNextEventTime.HighPart, NpScb.NwNextEventTime.LowPart ); + + // Spin locks? Transport and TDI info? + + // Dump Both Parts. + if ( first ) + DumpScb( (DWORD)NpScb.pScb, lpExtensionApis, FALSE ); + else + printf( "---------------------------------------------------------------------------\n" ); + + return; +} + +VOID +DumpFcb( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ) +/*++ + + This function takes the address of an FCB or DCB and a pointer + to a debugger extension interface block. It prints out + the information in the FCB or DCB. + +--*/ +{ + WCHAR Buffer[64]; + BOOL b; + FCB Fcb; + + b = getmem( (PVOID)addr, &Fcb, sizeof( Fcb ), NULL ); + if ( b == 0 ) { + printf("\n"); + return; + } + + if (Fcb.NodeTypeCode == NW_NTC_FCB) { + printf( "----------------------------FCB at %08lx--------------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_FCB\n" ); + } else { + printf( "----------------------------DCB at %08lx--------------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_DCB\n" ); + } + + b = GET_STRING( Buffer, Fcb.FullFileName ); + if ( b ) { + printf( "FullFileName : %ws\n", Buffer ); + } else { + printf( "FullFileName : (unreadable)\n" ); + } + + b = GET_STRING( Buffer, Fcb.RelativeFileName ); + if ( b ) { + printf( "RelativeFileName : %ws\n", Buffer ); + } else { + printf( "RelativeFileName : (unreadable)\n" ); + } + printf( "VCB Addr : %08lx\n", Fcb.Vcb ); + printf( "SCB Addr : %08lx\n", Fcb.Scb ); + printf( "NpFcb Addr : %08lx\n", Fcb.NonPagedFcb ); + printf( "LastModifiedDate : %d\n", Fcb.LastModifiedDate ); + printf( "LastModifiedTime : %d\n", Fcb.LastModifiedTime ); + printf( "CreationDate : %d\n", Fcb.CreationDate ); + printf( "CreationTime : %d\n", Fcb.CreationTime ); + printf( "LastAccessDate : %d\n", Fcb.LastAccessDate ); + printf( "State : %d\n", Fcb.State ); + printf( "Flags : %d\n", Fcb.Flags ); + + // SHARE_ACCESS? + + printf( "FcbListEntry : %08lx (LIST_ENTRY, FCB)\n", addr + FIELD_OFFSET( FCB, FcbListEntry )); + printf( "IcbListEntry : %08lx (LIST_ENTRY, ICB)\n", addr + FIELD_OFFSET( FCB, IcbList )); + printf( "IcbCount : %d\n", Fcb.IcbCount ); + printf( "LastReadOffset : %d\n", Fcb.LastReadOffset ); + printf( "LastReadSize : %d\n", Fcb.LastReadSize ); + + // Dump both parts. + if ( first ) + DumpFcbNp( (DWORD)Fcb.NonPagedFcb, lpExtensionApis, FALSE ); + else + printf( "---------------------------------------------------------------------------\n" ); + +} + +VOID +DumpVcb( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of a VCB and a pointer + to a debugger extension interface block. It prints out + the information in the VCB. + +--*/ +{ + WCHAR Buffer[64]; + BOOL b; + VCB Vcb; + + // Read it. + + b = getmem( (PVOID)addr, &Vcb, sizeof( Vcb ), NULL); + if ( b == 0 ) { + printf("\n"); + return; + } + + printf( "------------------------------VCB at %08lx------------------------------\n", addr); + printf( "NodeTypeCode : NW_NTC_VCB\n" ); + printf( "NodeByteSize : %d\n", Vcb.NodeByteSize ); + printf( "Reference Count : %08lx\n", Vcb.Reference ); + printf( "Last Used Time : %08lx %08lx\n", Vcb.LastUsedTime.HighPart, Vcb.LastUsedTime.LowPart ); + printf( "GlobalVcbListEntry : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( VCB, GlobalVcbListEntry) ); + printf( "SequenceNumber : %d\n", Vcb.SequenceNumber ); + + b = GET_STRING( Buffer, Vcb.Name ); + if ( b ) { + printf( "VolumeName : %ws\n", Buffer ); + } else { + printf( "VolumeName : (unreadable)\n" ); + } + + b = GET_STRING( Buffer, Vcb.ConnectName ); + if ( b ) { + printf( "ConnectName : %ws\n", Buffer ); + } else { + printf( "ConnectName : (unreadable)\n" ); + } + + b = GET_STRING( Buffer, Vcb.ShareName ); + if ( b ) { + printf( "NW ShareName : %ws\n", Buffer ); + } else { + printf( "NW ShareName : (unreadable)\n" ); + } + + if ( !Vcb.Flags & VCB_FLAG_PRINT_QUEUE ) { + printf( "VolumeNumber : %d\n", Vcb.Specific.Disk.VolumeNumber ); + printf( "LongNameSpace : %d\n", Vcb.Specific.Disk.LongNameSpace ); + printf( "Handle : %d\n", Vcb.Specific.Disk.Handle ); + } else { + printf( "QueueId : %d\n", Vcb.Specific.Print.QueueId ); + } + + if ( Vcb.DriveLetter != 0) { + printf( "Drive letter : %wc:\n", Vcb.DriveLetter ); + } else { + printf( "Drive letter : UNC\n" ); + } + + printf( "Scb Addr : %08lx\n", Vcb.Scb ); + printf( "VcbListEntry : %08lx (LIST_ENTRY, VCB)\n", addr + FIELD_OFFSET( VCB, VcbListEntry) ); + printf( "FcbListEntry : %08lx (LIST_ENTRY, FCB)\n", addr + FIELD_OFFSET(VCB, FcbList) ); + printf( "OpenFileCount : %d\n", Vcb.OpenFileCount ); + printf( "Flags : %08lx\n", Vcb.Flags ); + printf( "---------------------------------------------------------------------------\n"); + +} + +VOID +DumpIcb( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of an ICB and a pointer + to a debugger extension interface block. It prints out + the information in the ICB. + +--*/ +{ + WCHAR Buffer[64]; + BOOL b, icbscb; + ICB Icb; + UINT hb; + + b = getmem( (PVOID)addr, &Icb, sizeof( Icb ), NULL); + if ( b == 0 ) { + printf("\n"); + return; + } + + icbscb = (Icb.NodeTypeCode == NW_NTC_ICB_SCB); + + if ( icbscb ) { + printf( "---------------------------ICB_SCB at %08lx-----------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_ICB_SCB\n" ); + } else { + printf( "-----------------------------ICB at %08lx-------------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_ICB\n" ); + } + + printf( "NodeByteSize : %d\n", Icb.NodeByteSize ); + printf( "ListEntry : %08lx\n", Icb.ListEntry ); + + if (icbscb ) { + printf( "SuperType Addr : %08lx (SCB)\n", Icb.SuperType.Scb ); + } else { + printf( "SuperType Addr : %08lx (FCB)\n", Icb.SuperType.Fcb ); + printf( "NpFcb Addr : %08lx\n", Icb.NpFcb ); + } + + printf( "State : %s\n", IcbStateToString(Icb.State) ); + printf( "HasRemoteHandle : %s\n", Icb.HasRemoteHandle ? "TRUE" : "FALSE" ); + + if ( Icb.HasRemoteHandle ) { + printf( "Handle : " ); + for ( hb = 0; hb < 6; hb++ ) { + printf( "%c ", (Icb.Handle)[hb]); + } + printf( "\n"); + } + + // What abou the PFILE_OBJECT? + + b = GET_STRING( Buffer, Icb.NwQueryTemplate ); + if ( b ) { + printf( "NwQueryTemplate : %s\n", Buffer ); + } else { + printf( "NWQueryTemplate : (unreadable)\n" ); + } + + b = GET_STRING( Buffer, Icb.UQueryTemplate ); + if ( b ) { + printf( "UQueryTemplate : %ws\n", Buffer ); + } else { + printf( "UQueryTemplate : (unreadable)\n" ); + } + + printf( "IndexLastIcbRtr : %d\n", Icb.IndexOfLastIcbReturned ); + printf( "Pid : %d\n", Icb.Pid ); + printf( "DotReturned : %s\n", Icb.DotReturned ? "TRUE" : "FALSE" ); + printf( "DotDotReturned : %s\n", Icb.DotDotReturned ? "TRUE" : "FALSE" ); + printf( "ReturnedSmthng : %s\n", Icb.ReturnedSomething ? "TRUE" : "FALSE" ); + printf( "ShortNameSearch : %s\n", Icb.ShortNameSearch ? "TRUE" : "FALSE" ); + printf( "SearchHandle : %d\n", Icb.SearchHandle ); + printf( "SearchVolume : %d\n", Icb.SearchVolume ); + printf( "SearchAttribts : %d\n", Icb.SearchAttributes ); + printf( "SearchIndexHigh : %d\n", Icb.SearchIndexHigh ); + printf( "SearchIndexLow : %d\n", Icb.SearchIndexLow ); + printf( "IsPrintJob : %s\n", Icb.IsPrintJob ? "TRUE" : "FALSE" ); + printf( "JobId : %d\n", Icb.JobId ); + printf( "ActuallyPrinted : %s\n", Icb.ActuallyPrinted ? "TRUE" : "FALSE" ); + printf( "USetLastAccessTime : %s\n", Icb.UserSetLastAccessTime ? "TRUE" : "FALSE" ); + printf( "File Position : %d\n", Icb.FilePosition ); + printf( "File Size : %d\n", Icb.FileSize ); + + printf( "IsTreeHanle : %s\n", Icb.IsTreeHandle ? "TRUE" : "FALSE" ); + + // This needs to be cleaned up! + + printf( "---------------------------------------------------------------------------\n" ); + +} + +VOID +DumpIrpContext( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +{ + BOOL b; + IRP_CONTEXT IrpContext; + + b = getmem( (PVOID)addr, &IrpContext, sizeof( IrpContext ), NULL ); + if ( b == 0 ) { + printf( "\n" ); + return; + } + + printf( "--------------------------IRP CONTEXT at %08lx--------------------------\n", addr ); + printf( "NodeTypeCode : NW_NTC_IRP_CONTEXT\n" ); + + // WORK_QUEUE_ITEM? + + printf( "PacketType : %s\n", PacketToString(IrpContext.PacketType)); + printf( "NpScb Addr : %08lx\n", IrpContext.pNpScb ); + printf( "Scb Addr : %08lx\n", IrpContext.pScb ); + printf( "TdiStruct : %08lx\n", IrpContext.pTdiStruct ); + + // NextRequest? + + printf( "Event : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, Event ) ); + printf( "Original IRP : %08lx\n", IrpContext.pOriginalIrp ); + printf( "Original SB : %08lx\n", IrpContext.pOriginalSystemBuffer ); + printf( "Original UB : %08lx\n", IrpContext.pOriginalUserBuffer ); + printf( "Original MDL : %08lx\n", IrpContext.pOriginalMdlAddress ); + printf( "Receive IRP : %08lx\n", IrpContext.ReceiveIrp ); + printf( "TxMdl : %08lx\n", IrpContext.TxMdl ); + printf( "RxMdl : %08lx\n", IrpContext.RxMdl ); + printf( "RunRoutine : %08lx\n", IrpContext.RunRoutine ); + printf( "pEx : %08lx\n", IrpContext.pEx ); + printf( "PostProcessRtn : %08lx\n", IrpContext.PostProcessRoutine ); + printf( "TimeoutRtn : %08lx\n", IrpContext.TimeoutRoutine ); + printf( "ComplSendRtn : %08lx\n", IrpContext.CompletionSendRoutine ); + printf( "pWorkItem : %08lx\n", IrpContext.pWorkItem ); + printf( "Req Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, req ) ); + printf( "ResponseLength : %08lx\n", IrpContext.ResponseLength ); + printf( "Rsp Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, rsp ) ); + printf( "Icb Addr : %08lx\n", IrpContext.Icb ); + printf( "Specific Data Addr : %08lx\n", addr + FIELD_OFFSET( IRP_CONTEXT, Specific.Create.FullPathName ) ); + printf( "------------------------------IRP Context Flags----------------------------\n"); + PrintIrpContextFlags(IrpContext.Flags, lpExtensionApis); + printf( "---------------------------------------------------------------------------\n" ); + + return; +} + +VOID +DumpFcbNp( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis, + BOOL first + ) +{ + WCHAR Buffer[64]; + BOOL b; + NONPAGED_FCB NpFcb; + + b = getmem( (PVOID)addr, &NpFcb, sizeof( NONPAGED_FCB ), NULL); + if ( !b ) { + printf( "\n" ); + return; + } + + printf( "--------------------Common NP FCB Header at %08lx-----------------------\n"); + printf( "NodeTypeCode : NW_NTC_NONPAGED_FCB\n" ); + printf( "NodeByteSize : %d\n", NpFcb.Header.NodeByteSize ); + printf( "IsFastIoPossible : %d\n", NpFcb.Header.IsFastIoPossible ); + + // Resource? PagingIoResource? + + printf( "AllocationSize : %08lx %08lx\n", NpFcb.Header.AllocationSize.HighPart, NpFcb.Header.AllocationSize.LowPart ); + printf( "FileSize : %08lx %08lx\n", NpFcb.Header.FileSize.HighPart, NpFcb.Header.FileSize.LowPart ); + printf( "ValidDataLength : %08lx %08lx\n", NpFcb.Header.ValidDataLength.HighPart, NpFcb.Header.ValidDataLength.LowPart ); + printf( "pFcb Addr : %08lx\n", NpFcb.Fcb ); + + // SegmentObject? + + printf( "FileLockList : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, FileLockList) ); + printf( "PendLockList : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, PendingLockList) ); + printf( "Resource : %08lx\n", addr + FIELD_OFFSET( NONPAGED_FCB, Resource ) ); + + printf( "Attributes : %d\n", NpFcb.Attributes ); + printf( "CacheType : %d\n", NpFcb.CacheType ); + printf( "CacheBuffer : %08lx\n", NpFcb.CacheBuffer ); + printf( "CacheMdl : %08lx\n", NpFcb.CacheMdl ); + printf( "CacheSize : %d\n", NpFcb.CacheSize ); + printf( "CacheFileOffset : %d\n", NpFcb.CacheFileOffset ); + printf( "CacheDataSize : %d\n", NpFcb.CacheDataSize ); + printf( "----------------------------------FCB Flags--------------------------------\n" ); + PrintNpFcbFlags( NpFcb.Header.Flags, lpExtensionApis ); + + // Dump both parts. + if ( first ) + DumpFcb( (DWORD)NpFcb.Fcb, lpExtensionApis, FALSE ); + else + printf( "---------------------------------------------------------------------------\n" ); + +} + +VOID +DumpRcb( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of an ICB and a pointer + to a debugger extension interface block. It prints out + the information in the ICB. + +--*/ +{ + BOOL b; + RCB Rcb; + + b = getmem( (PVOID)addr, &Rcb, sizeof( RCB ), NULL); + if ( b == 0 ) { + printf("\n"); + return; + } + + printf( "------------------------------------------------------------\n"); + printf( "NodeTypeCode : NW_NTC_RCB\n"); + printf( "State : %s\n", RcbStateToString(Rcb.State)); + printf( "OpenCount : %ul\n", Rcb.OpenCount); + printf( "ResourceAddr : %08lx\n", addr + FIELD_OFFSET( RCB, Resource )); + printf( "ServerListAddr : %08lx\n", addr + FIELD_OFFSET( RCB, + ServerNameTable )); + printf( "VolumeListAddr : %08lx\n", addr + FIELD_OFFSET( RCB, + VolumeNameTable )); + printf( "FileListAddr : %08lx\n", addr + FIELD_OFFSET( RCB, + FileNameTable )); + printf( "------------------------------------------------------------\n"); + +} + +VOID +DumpPid( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of a PID and a pointer + to a debugger extension interface block. It prints out + the information in the PID. + +--*/ +{ + + printf( "------------------------------------------------------------\n"); + printf( "NodeTypeCode : NW_NTC_PID\n" ); + printf( "...Not yet implemented..."); + printf( "------------------------------------------------------------\n"); + +} + +VOID +DumpFileLock( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of a file lock and a pointer + to a debugger extension interface block. It prints out + the information in the file lock. + +--*/ +{ + + printf( "------------------------------------------------------------\n" ); + printf( "NodeTypeCode : NW_NTC_FILE_LOCK\n" ); + printf( "Not yet implemented...\n" ); + printf( "------------------------------------------------------------\n" ); + +} + +VOID +DumpLogon( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of a logon and a pointer + to a debugger extension interface block. It prints out + the information in the logon. + +--*/ +{ + BOOL b; + LOGON Logon; + WCHAR Buffer[64]; + + b = getmem( (PVOID)addr, &Logon, sizeof(LOGON), NULL ); + if (!b ) { + printf( "" ); + return; + } + + printf( "------------------------------------------------------------\n"); + printf( "NodeTypeCode : NW_NTC_LOGON\n" ); + printf( "NodeByteSize : %d\n", Logon.NodeByteSize ); + printf( "NextLogon : %08lx (LOGON LIST_ENTRY)\n", addr + + FIELD_OFFSET( LOGON, Next )); + + b = GET_STRING( Buffer, Logon.UserName ); + if ( b ) { + printf( "UserName : %ws\n", Buffer ); + } else { + printf( "UserName : \n" ); + } + + b = GET_STRING( Buffer, Logon.PassWord ); + if ( b ) { + printf( "Password : %ws\n", Buffer ); + } else { + printf( "Password : \n" ); + } + + b = GET_STRING( Buffer, Logon.ServerName ); + if ( b ) { + printf( "Pref Server : %ws\n", Buffer ); + } else { + printf( "Pref Server : \n" ); + } + + printf( "UserUid : %08lx %08lx\n", Logon.UserUid.HighPart, + Logon.UserUid.LowPart); + + printf( "CredListResource: %08lx\n", addr + + FIELD_OFFSET( LOGON, CredentialListResource )); + + printf( "CredentialList : %08lx (CREDENTIAL LIST_ENTRY)\n", addr + + FIELD_OFFSET( LOGON, NdsCredentialList )); + + printf( "------------------------------------------------------------\n"); + +} + +VOID +DumpCredential( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of an nds credential and a + pointer to a debugger extension interface block. It prints + out the information in the logon. + +--*/ +{ + BOOL b; + NDS_SECURITY_CONTEXT Context; + NDS_CREDENTIAL Credential; + NDS_SIGNATURE Signature; + + WCHAR Buffer[512]; + + CHAR PackBuffer[2048]; + BYTE *packed; + ULONG packedlen; + + b = getmem( (PVOID)addr, &Context, sizeof(NDS_SECURITY_CONTEXT), NULL ); + if (!b ) { + printf( "\n" ); + return; + } + + printf( "-------- NDS Security Context at 0x%08lx ----------------\n", addr); + printf( "NodeTypeCode : NW_NTC_NDS_CREDENTIAL\n" ); + printf( "NodeByteSize : %d\n", Context.nts ); + + printf( "Next : %08lx (NDS_SECURITY_CONTEXT LIST_ENTRY)\n", addr + + FIELD_OFFSET( NDS_SECURITY_CONTEXT, Next )); + + + b = GET_STRING( Buffer, Context.NdsTreeName ); + if ( b ) { + printf( "Nds Tree Name : %ws\n", Buffer ); + } else { + printf( "Nds Tree Name : \n" ); + } + + b = GET_STRING( Buffer, Context.CurrentContext ); + if ( b ) { + printf( "Current Context : %ws\n", Buffer ); + } else { + printf( "Current Context :\n" ); + } + + if ( Context.Credential != NULL ) { + + printf( "--------------------- Credential Data ----------------------\n"); + + b = getmem( (PVOID)Context.Credential, &Credential, sizeof(NDS_CREDENTIAL), NULL ); + if (!b ) { + printf( "\n" ); + goto DO_SIGNATURE; + } + + printf( "Start validity : 0x%08lx\n", Credential.validityBegin ); + printf( "End validity : 0x%08lx\n", Credential.validityEnd ); + printf( "Random : 0x%08lx\n", Credential.random ); + printf( "Opt data Len : %d\n", Credential.optDataSize ); + printf( "UserName Len : %d\n", Credential.userNameLength ); + + // + // Optional data is the first packed data after the struct. + // + + packedlen = Credential.optDataSize + Credential.userNameLength; + packed = ((BYTE *)Context.Credential) + sizeof( NDS_CREDENTIAL ); + + if ( Credential.optDataSize ) { + printf( "Opt data addr : %08lx\n", packed ); + } + + packed += Credential.optDataSize; + + b = getmem( (PVOID)packed, Buffer, Credential.userNameLength, NULL ); + if ( !b ) { + printf( "\n" ); + goto DO_SIGNATURE; + } + printf( "Username : %ws\n", Buffer ); + + } else { + + printf( "-------------------- No Credential Data --------------------\n"); + + } + +DO_SIGNATURE: + + if ( Context.Signature != NULL ) { + + printf( "---------------------- Signature Data ----------------------\n"); + + b = getmem( (PVOID)Context.Signature, &Signature, sizeof(NDS_SIGNATURE), NULL ); + if (!b ) { + printf( "\n" ); + goto DO_END; + } + + printf( "Signature Len : %d\n", Signature.signDataLength ); + + packedlen = Signature.signDataLength; + packed = ((BYTE *)Context.Signature) + sizeof( NDS_SIGNATURE ); + + printf( "Signature addr : %08lx\n", packed ); + + } else { + + printf( "-------------------- No Signature Data ---------------------\n"); + + } + +DO_END: + + if ( Context.PublicNdsKey != NULL ) { + + printf( "------------------------------------------------------------\n"); + + printf( "Public Key Len : %d\n", Context.PublicKeyLen ); + printf( "Public Key : %08lx\n", Context.PublicNdsKey ); + + printf( "------------------------------------------------------------\n"); + + } else { + + printf( "-------------------- No Public Key Data --------------------\n"); + + } + +} + + +VOID +DumpMiniIrpContext( + DWORD addr, + PNTKD_EXTENSION_APIS lpExtensionApis + ) +/*++ + + This function takes the address of a mini irp context + and a pointer to a debugger extension interface block. + It prints out the information in the mini irp context. + +--*/ +{ + BOOL b; + MINI_IRP_CONTEXT mini; + + b = getmem( (PVOID)addr, &mini, sizeof(MINI_IRP_CONTEXT), NULL ); + if (!b ) { + printf( "\n"); + return; + } + + printf( "------------------------------------------------------------\n"); + printf( "NodeTypeCode : NW_NTC_MINI_IRP_CONTEXT\n" ); + printf( "NodeByteSize : %d\n", mini.NodeByteSize ); + printf( "ListEntry : %08lx\n", addr + FIELD_OFFSET( MINI_IRP_CONTEXT, + Next )); + printf( "IrpContext : %08lx\n", mini.IrpContext ); + printf( "Irp : %08lx\n", mini.Irp ); + printf( "Buffer : %08lx\n", mini.Buffer ); + printf( "Mdl1 : %08lx\n", mini.Mdl1 ); + printf( "Mdl2 : %08lx\n", mini.Mdl2 ); + printf( "------------------------------------------------------------\n"); + +} + +VOID +nwdump( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + +Routine Description: + + This function takes the pointer to a structure, + figures out what the structure is, and calls the + appropriate dump routine. + +Arguments: + + CurrentPc - Supplies the current pc at the time + the extension is called. + + lpExtensionApis - Supplies the address of the + functions callable by this extension. + + lpArgumentString - Supplies the address of the structure. + +Return Value: + + None. + +---*/ +{ + + DWORD addr; + + // + // Determine the node type and dispatch. + // + + addr = getexpr( lpArgumentString ); + + switch ( GetNodeType( addr, lpExtensionApis ) ) { + + case NW_NTC_SCB: + + DumpScb(addr, lpExtensionApis, TRUE); + break; + + case NW_NTC_SCBNP: + + DumpScbNp(addr, lpExtensionApis, TRUE); + break; + + case NW_NTC_FCB: + case NW_NTC_DCB: + + DumpFcb(addr, lpExtensionApis, TRUE); + break; + + case NW_NTC_VCB: + + DumpVcb(addr, lpExtensionApis); + break; + + case NW_NTC_ICB: + case NW_NTC_ICB_SCB: + + DumpIcb(addr, lpExtensionApis); + break; + + case NW_NTC_IRP_CONTEXT: + + DumpIrpContext(addr, lpExtensionApis); + break; + + case NW_NTC_NONPAGED_FCB: + + DumpFcbNp(addr, lpExtensionApis, TRUE); + break; + + case NW_NTC_RCB: + + DumpRcb(addr, lpExtensionApis); + break; + + case NW_NTC_PID: + + DumpPid(addr, lpExtensionApis); + break; + + case NW_NTC_FILE_LOCK: + + DumpFileLock(addr, lpExtensionApis); + break; + + case NW_NTC_LOGON: + + DumpLogon(addr, lpExtensionApis); + break; + + case NW_NTC_MINI_IRP_CONTEXT: + + DumpMiniIrpContext(addr, lpExtensionApis); + break; + + case NW_NTC_NDS_CREDENTIAL: + + DumpCredential(addr, lpExtensionApis); + break; + + default: + + printf("(this object does not have a vaid node type)\n"); + break; + } + +} + +// +// Other debugger routines. +// + +VOID +serverlist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + +Routine Description: + + This function displays a list of servers that the redirector + is maintaining connections to. The information is read from + the SCB queue, not from the server list in the RCB. The + argument to this function is ignored. + +--*/ +{ + + DWORD addrScbQueue; + WCHAR ServerName[64]; + BOOL b; + PLIST_ENTRY ScbQueueList; + DWORD addrNpScb, addrScb; + NONPAGED_SCB NpScb; + SCB Scb; + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // + // Get the address of the server list in the rdr. + // + + addrScbQueue = getsymaddr("nwrdr!scbqueue"); + + if ( addrScbQueue == 0 ) { + printf("The server list was not locatable.\n"); + return; + } + + // + // Walk the list of servers. + // + + printf("pNpScb pScb Ref State Name\n"); + printf("---------------------------------------------------------------------------\n"); + + for ( GET_DWORD( &ScbQueueList, addrScbQueue ); + ScbQueueList != (PLIST_ENTRY)addrScbQueue; + GET_DWORD( &ScbQueueList, ScbQueueList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrNpScb = (DWORD)CONTAINING_RECORD( ScbQueueList, NONPAGED_SCB, ScbLinks ); + + printf("%08lx ", addrNpScb ); + + b = (getmem)((LPVOID)addrNpScb, + &NpScb, + sizeof( NpScb ), + NULL); + + if ( b == 0 ) { + printf("\n"); + return; + } + + addrScb = (DWORD)NpScb.pScb; + printf("%08lx ", addrScb ); + + printf("%8lx ", NpScb.Reference); + printf("%-25s", ScbStateToString( NpScb.State ) ); + + if ( addrScb != 0 ) { + b = (getmem)((LPVOID)addrScb, + &Scb, + sizeof( Scb ), + NULL); + + if ( b == 0 ) { + printf("\n"); + continue; + } + + // Get the server name. + + b = GET_STRING( ServerName, Scb.UidServerName ); + + if ( b ) { + printf( "%ws\n", ServerName ); + } else { + printf( "Unreadable\n" ); + } + } else { + printf( "Permanent SCB\n" ); + } + + } + + printf("---------------------------------------------------------------------------\n"); + +} + +VOID +trace( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + +Routine Description: + + This function dumps the nwrdr trace buffer. Arguments to + this function are ignored. + +To Be Done: + + Read trace buffer size out of nwrdrd and dynamically size. + +--*/ + +{ + ULONG addrDBuffer, addrDBufferPtr, DBufferPtr; + ULONG BufferSize; + PCHAR TraceStart, CurrentPtr; + char buffer[80 + 1]; + char *bptr; + char *newptr; + int i; + int readsize; + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + addrDBuffer = getsymaddr( "nwrdr!dbuffer" ); + + if ( !addrDBuffer ) { + printf("(unable to locate the trace buffer address)\n"); + return; + } else { + printf("Address of Dbuffer = %08lx\n", addrDBuffer ); + } + + addrDBufferPtr = getsymaddr( "nwrdr!dbufferptr" ); + + if ( !addrDBuffer ) { + printf("(unable to locate the trace buffer pointer)\n"); + return; + } else { + printf("Address of DbufferPtr = %08lx\n", addrDBufferPtr ); + } + + GET_DWORD( &DBufferPtr, addrDBufferPtr ); + printf("DbufferPtr = %08lx\n", DBufferPtr ); + + // Set up state variables and loop. + + TraceStart = (char *)addrDBuffer; + BufferSize = 100*255+1; + CurrentPtr = (char *)DBufferPtr; + + buffer[80] = '\0'; + newptr = CurrentPtr + 1; + while ( 1 ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + if ( newptr + 80 > TraceStart+BufferSize ) { + readsize = TraceStart+BufferSize - newptr; + } else { + readsize = 80; + } + + getmem( newptr, buffer, readsize, NULL ); + + bptr = buffer; + for (i = 0; i<80 ; i++ ) { + if ( buffer[i] == '\n') { + buffer[i] = 0; + printf( "%s\n", bptr ); + bptr = &buffer[i+1]; + } + } + printf( "%s", bptr ); + + // + // If we're back to where we started, break out of here. + // + + if ( (newptr <= CurrentPtr) && + (newptr + readsize) >= CurrentPtr ) { + break; + } + + // + // Advance the running pointer. + // + + newptr += readsize; + if ( newptr >= TraceStart+BufferSize ) { + newptr = TraceStart; + } + } + printf( "\n"); +} + +VOID +reftrace( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + +Routine Description: + + This function dumps the nwrdr reference trace buffer. + +--*/ +{ + ULONG addrRBuffer, addrRBufferPtr, RBufferPtr; + ULONG BufferSize; + PCHAR TraceStart, CurrentPtr; + char buffer[80 + 1]; + char *bptr; + char *newptr; + int i; + int readsize; + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + addrRBuffer = getsymaddr( "nwrdr!RBuffer" ); + + if ( !addrRBuffer ) { + printf("(unable to locate the trace buffer address)\n"); + return; + } else { + printf("Address of RBuffer = %08lx\n", addrRBuffer ); + } + + addrRBufferPtr = getsymaddr( "nwrdr!RBufferptr" ); + + if ( !addrRBuffer ) { + printf("(unable to locate the trace buffer pointer)\n"); + return; + } else { + printf("Address of RBufferPtr = %08lx\n", addrRBufferPtr ); + } + + GET_DWORD( &RBufferPtr, addrRBufferPtr ); + printf("RBufferPtr = %08lx\n", RBufferPtr ); + + // Set up state variables and loop. + + TraceStart = (char *)addrRBuffer; + BufferSize = 100*255+1; + CurrentPtr = (char *)RBufferPtr; + + buffer[80] = '\0'; + newptr = CurrentPtr + 1; + while ( 1 ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + if ( newptr + 80 > TraceStart+BufferSize ) { + readsize = TraceStart+BufferSize - newptr; + } else { + readsize = 80; + } + + getmem( newptr, buffer, readsize, NULL ); + + bptr = buffer; + for (i = 0; i<80 ; i++ ) { + if ( buffer[i] == '\n') { + buffer[i] = 0; + printf( "%s\n", bptr ); + bptr = &buffer[i+1]; + } + } + printf( "%s", bptr ); + + // + // If we're back to where we started, break out of here. + // + + if ( (newptr <= CurrentPtr) && + (newptr + readsize) >= CurrentPtr ) { + break; + } + + // + // Advance the running pointer. + // + + newptr += readsize; + if ( newptr >= TraceStart+BufferSize ) { + newptr = TraceStart; + } + } + printf( "\n"); +} + +VOID +logonlist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + +Routine Description: + + This routine prints out the logon list for the rdr. Arguments + to this function are ignored. + +--*/ + +{ + DWORD addrLogonList; + WCHAR Data[64]; + BOOL b; + PLIST_ENTRY LogonList; + DWORD addrLogonEntry; + LOGON Logon; + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // Get the address of the logon list. + + addrLogonList = getsymaddr( "nwrdr!logonlist" ); + + if ( addrLogonList == 0 ) { + printf("The logon list could not be located.\n"); + return; + } + + // Walk the list of servers + + printf("pLogon User Name Password Pref Server UID\n" ); + printf("---------------------------------------------------------------------------\n" ); + + for ( GET_DWORD( &LogonList, addrLogonList ); + LogonList != (PLIST_ENTRY)addrLogonList; + GET_DWORD( &LogonList, LogonList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrLogonEntry = (DWORD)CONTAINING_RECORD( LogonList, LOGON, Next ); + + printf("%08lx ", addrLogonEntry ); + + b = (getmem)((LPVOID)addrLogonEntry, + &Logon, + sizeof( Logon ), + NULL); + + if ( b == 0 ) return; + + if ( Logon.NodeTypeCode != NW_NTC_LOGON ) { + printf( "\n" ); + return; + } + + b = GET_STRING( Data, Logon.UserName ); + + if ( b ) { + printf( "%-15ws", Data ); + } else { + printf( "%-15s", "Unreadable" ); + } + + /* + b = GET_STRING( Data, Logon.PassWord ); + + if ( b ) { + printf( "%-15ws", Data ); + } else { + printf( "%-15s", "Unreadable" ); + } + */ + printf( "%-15s", "" ); + + b = GET_STRING( Data, Logon.ServerName ); + + if ( b ) { + printf( "%-15ws", Data ); + } else { + printf( "%-15s", "Unreadable" ); + } + + printf( "%08lx:%08x\n", Logon.UserUid.HighPart, Logon.UserUid.LowPart ); + } + + printf("---------------------------------------------------------------------------\n" ); + +} + +// +// Functions that help mangle lists of objects. +// + +VOID +vcblist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function takes a pointer to the pageable portion + or non-pageable portion of an SCB and dumps the VCB + list for that SCB. + +--*/ +{ + BOOL b; + PVOID objAddr; + + PLIST_ENTRY VcbList; + DWORD addrVcbList; + PVCB addrVcb; + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // Figure out which object we have. + objAddr = (PVOID)getexpr( lpArgumentString ); + + // Invariant: If we leave the switch, objAddr must point to the + // pageable portion of the SCB that we are interested in. + + switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) { + + case NW_NTC_SCB: + + break; + + case NW_NTC_SCBNP: + + GET_DWORD( &objAddr, + ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, pScb ) ) ); + if ( objAddr == 0 ) return; + break; + + default: + + printf( "(invalid node type code: argument must point to an scb or npscb)\n" ); + return; + } + + // Get the head of the vcb list. + addrVcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, ScbSpecificVcbQueue )); + + // Walk the list and print. + for ( GET_DWORD( &VcbList, addrVcbList ) ; + VcbList != (PLIST_ENTRY)addrVcbList ; + GET_DWORD( &VcbList, VcbList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrVcb = (PVCB)CONTAINING_RECORD( VcbList, VCB, VcbListEntry ); + if( GetNodeType( (DWORD)addrVcb, lpExtensionApis ) != NW_NTC_VCB ) + printf( "(invalid entry in vcb list)\n" ); + else + DumpVcb( (DWORD)addrVcb, lpExtensionApis ); + } +} + +VOID +irplist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function takes a pointer to the non-pageable portion + of an SCB and dumps the IRP list for that non-pageable SCB. + +--*/ +{ + PLIST_ENTRY IrpList; + DWORD addrIrpList; + PIRP_CONTEXT addrIrp; + + PVOID objAddr; + BOOL b; + + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + + // Figure out which object we have. + objAddr = (PVOID)getexpr( lpArgumentString ); + + // Invariant: If we leave the switch, objAddr must point to the + // non-pageable portion of the SCB that we are interested in. + + switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) { + + case NW_NTC_SCB: + + GET_DWORD( &objAddr, + ( (PCHAR)objAddr + FIELD_OFFSET( SCB, pNpScb ) ) ); + if ( objAddr == 0 ) return; + break; + + case NW_NTC_SCBNP: + + break; + + default: + + printf( "(invalid node type code: argument must point to an scb or npscb)\n" ); + return; + } + + // Get the head of the request list. + addrIrpList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, Requests )); + + // Walk the list and print. + for ( GET_DWORD( &IrpList, addrIrpList ) ; + IrpList != (PLIST_ENTRY)addrIrpList ; + GET_DWORD( &IrpList, IrpList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrIrp = (PIRP_CONTEXT)CONTAINING_RECORD( IrpList, IRP_CONTEXT, NextRequest ); + if( GetNodeType( (DWORD)addrIrp, lpExtensionApis ) != NW_NTC_IRP_CONTEXT ) + printf( "(invalid entry in the irp context list)\n" ); + else + DumpIrpContext( (DWORD)addrIrp, lpExtensionApis ); + } +} + +VOID +fcblist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function takes a pointer to a VCB and dumps + the FCB list for that VCB. + +--*/ +{ + PLIST_ENTRY FcbList; + DWORD addrFcbList; + PFCB addrFcb; + + NODE_TYPE_CODE ntc; + PVOID objAddr; + BOOL b; + + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // Figure out which object we have. + objAddr = (PVOID)getexpr( lpArgumentString ); + + if ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) != NW_NTC_VCB ) { + + printf( "(invalid node type code: argument must point to a vcb)\n" ); + return; + } + + // Get the head of the fcb list. + addrFcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( VCB, FcbList )); + + for ( GET_DWORD( &FcbList, addrFcbList ) ; + FcbList != (PLIST_ENTRY)addrFcbList ; + GET_DWORD( &FcbList, FcbList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrFcb = (PFCB)CONTAINING_RECORD( FcbList, FCB, FcbListEntry ); + ntc = GetNodeType( (DWORD)addrFcb, lpExtensionApis ); + if( (ntc != NW_NTC_FCB) && (ntc != NW_NTC_DCB) ) + printf( "(invalid entry in the fcb list)\n" ); + else + DumpFcb( (DWORD)addrFcb, lpExtensionApis, TRUE ); + } + +} + +VOID +icblist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function takes a pointer to the pageable portion + of an SCB or FCB and dumps the ICB list for that SCB or FCB. + +--*/ +{ + PVOID objAddr; + BOOL b; + NODE_TYPE_CODE ntc; + + PICB addrIcb; + PLIST_ENTRY IcbList; + DWORD addrIcbList, IcbCount; + + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // Figure out which object we have. + objAddr = (PVOID)getexpr( lpArgumentString ); + + // Invariant: If we leave the switch, addrIcbList must point + // to the head of the ICB list that we are interested in. + + switch ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) ) { + + case NW_NTC_SCB: + + addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, IcbList )); + break; + + case NW_NTC_SCBNP: + + // Look up the pageable portion. + GET_DWORD( &objAddr, + ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_SCB, pScb ) ) ); + if ( objAddr == 0 ) return; + // Now get it. + addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( SCB, IcbList)); + break; + + case NW_NTC_FCB: + case NW_NTC_DCB: + + addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( FCB, IcbList )); + break; + + case NW_NTC_NONPAGED_FCB: + + // Look up the pageable portion. + GET_DWORD( &objAddr, + ( (PCHAR)objAddr + FIELD_OFFSET( NONPAGED_FCB, Fcb ) ) ); + if (objAddr == 0) return; + // Now get it. + addrIcbList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( FCB, IcbList )); + break; + + default: + + printf( "(invalid node type: argument must be: scb, npscb, fcb, dcb, or npfcb)\n" ); + return; + } + + // Walk the list. + for ( GET_DWORD( &IcbList, addrIcbList ) ; + IcbList != (PLIST_ENTRY)addrIcbList ; + GET_DWORD( &IcbList, IcbList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrIcb = (PICB)CONTAINING_RECORD( IcbList, ICB, ListEntry ); + ntc = GetNodeType( (DWORD)addrIcb, lpExtensionApis ); + if( (ntc != NW_NTC_ICB) && (ntc != NW_NTC_ICB_SCB) ) + printf( "(invalid entry in icb list)\n" ); + else + DumpIcb( (DWORD)addrIcb, lpExtensionApis ); + + } + +} + +VOID +credlist( +#ifdef WINDBG + HANDLE hProcess, + HANDLE hThread, +#endif + DWORD dwCurrentPc, + PNTKD_EXTENSION_APIS lpExtensionApis, + LPSTR lpArgumentString + ) +/*++ + + This function takes a pointer to a LOGON and dumps + the NDS credential list for that user. + +--*/ +{ + PLIST_ENTRY CredList; + DWORD addrCredList; + PNDS_SECURITY_CONTEXT addrCred; + + NODE_TYPE_CODE ntc; + PVOID objAddr; + BOOL b; + + PNTKD_CHECK_CONTROL_C lpCheckControlCRoutine; + lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine; + + // Figure out which object we have. + objAddr = (PVOID)getexpr( lpArgumentString ); + + if ( GetNodeType( (DWORD)objAddr, lpExtensionApis ) != NW_NTC_LOGON ) { + + printf( "(invalid node type code: argument must point to a logon)\n" ); + return; + } + + // Get the head of the fcb list. + addrCredList = (DWORD)((PCHAR)objAddr + FIELD_OFFSET( LOGON, NdsCredentialList )); + + for ( GET_DWORD( &CredList, addrCredList ) ; + CredList != (PLIST_ENTRY)addrCredList ; + GET_DWORD( &CredList, CredList ) ) { + + if ( lpCheckControlCRoutine() ) { + printf("<<>>\n"); + break; + } + + addrCred = (PNDS_SECURITY_CONTEXT) + CONTAINING_RECORD( CredList, + NDS_SECURITY_CONTEXT, + Next ); + ntc = GetNodeType( (DWORD)addrCred, lpExtensionApis ); + if( (ntc != NW_NTC_NDS_CREDENTIAL ) ) + printf( "(invalid entry in the credential list)\n" ); + else + DumpCredential( (DWORD)addrCred, lpExtensionApis); + printf("\n"); + } + +} -- cgit v1.2.3