/*++ Copyright (c) 1992 Microsoft Corporation Module Name: afdutil.c Abstract: Utility functions for dumping various AFD structures. Author: Keith Moore (keithmo) 19-Apr-1995 Environment: User Mode. Revision History: --*/ #include "afdkdp.h" #pragma hdrstop // // Private constants. // // // Private globals. // PSTR WeekdayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; PSTR MonthNames[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; // // Private prototypes. // PSTR StructureTypeToString( USHORT Type ); PSTR StructureTypeToStringBrief ( USHORT Type ); PSTR BooleanToString( BOOLEAN Flag ); PSTR EndpointStateToString( UCHAR State ); PSTR EndpointStateToStringBrief( UCHAR State ); PSTR EndpointStateFlagsToString( PAFD_ENDPOINT Endpoint ); PSTR EndpointTypeToString( ULONG TypeFlags ); PSTR ConnectionStateToString( USHORT State ); PSTR ConnectionStateToStringBrief( USHORT State ); PSTR ConnectionStateFlagsToString( PAFD_CONNECTION Connection ); PSTR TranfileFlagsToString( ULONG Flags, ULONG StateFlags ); PSTR BufferFlagsToString( PAFD_BUFFER_HEADER AfdBuffer ); PSTR SystemTimeToString( LONGLONG Value ); PSTR GroupTypeToString( AFD_GROUP_TYPE GroupType ); VOID DumpReferenceDebug( PAFD_REFERENCE_DEBUG ReferenceDebug, ULONG CurrentSlot ); BOOL IsTransmitIrpBusy( PIRP Irp ); PSTR ListToString ( ULONG64 ListHead, ULONG64 Flink ); #define LIST_TO_STRING(_h,_f) ListToString(_h,ReadField(_f)) PSTR TdiServiceFlagsToString( ULONG Flags ); // // Public functions. // VOID DumpAfdEndpoint( ULONG64 ActualAddress ) /*++ Routine Description: Dumps the specified AFD_ENDPOINT structure. Arguments: ActualAddress - The actual address where the structure resides on the debugee. Return Value: None. --*/ { AFD_ENDPOINT endpoint; ULONG64 address; ULONG length; UCHAR transportAddress[MAX_TRANSPORT_ADDR]; ULONG64 irp; ULONG result; dprintf( "\nAFD_ENDPOINT @ %p:\n", ActualAddress ); dprintf( " ReferenceCount = %ld\n", (ULONG)ReadField(ReferenceCount) ); endpoint.Type=(USHORT)ReadField (Type); dprintf( " Type = %04X (%s)\n", endpoint.Type, StructureTypeToString( endpoint.Type ) ); endpoint.State=(UCHAR)ReadField (State); dprintf( " State = %02X (%s)\n", endpoint.State, EndpointStateToString(endpoint.State) ); if ((endpoint.StateChangeInProgress=(ULONG)ReadField (StateChangeInProgress))!=0) { dprintf( " State changing to = %02X (%s)\n", endpoint.StateChangeInProgress, EndpointStateToString( (UCHAR)endpoint.StateChangeInProgress ) ); } endpoint.TdiServiceFlags=(ULONG)ReadField (TdiServiceFlags); dprintf( " TdiTransportFlags = %08lx (", endpoint.TdiServiceFlags ); if (IS_TDI_ORDERLY_RELEASE(&endpoint)) dprintf (" OrdRel"); if (IS_TDI_DELAYED_ACCEPTANCE(&endpoint)) dprintf (" DelAcc"); if (IS_TDI_EXPEDITED(&endpoint)) dprintf (" Expd"); if (IS_TDI_BUFFERRING(&endpoint)) dprintf (" Buff"); if (IS_TDI_MESSAGE_MODE(&endpoint)) dprintf (" Msg"); if (IS_TDI_DGRAM_CONNECTION(&endpoint)) dprintf (" DgramCon"); if (IS_TDI_FORCE_ACCESS_CHECK(&endpoint)) dprintf (" AccChk"); dprintf (" )\n"); dprintf( " StateFlags = %08X (", endpoint.EndpointStateFlags = (ULONG)ReadField (EndpointStateFlags) ); if (endpoint.Listening) dprintf (" Listn"); if (endpoint.DelayedAcceptance) dprintf (" DelAcc"); if (endpoint.NonBlocking) dprintf (" NBlock"); if (endpoint.InLine) dprintf (" InLine"); if (endpoint.EndpointCleanedUp) dprintf (" Clnd-up"); if (endpoint.PollCalled) dprintf (" Polled"); if (endpoint.RoutingQueryReferenced) dprintf (" RtQ"); if (endpoint.DisableFastIoSend) dprintf (" -FastSnd"); if (endpoint.EnableSendEvent) dprintf (" +SndEvt"); if (endpoint.DisableFastIoRecv) dprintf (" -FastRcv"); dprintf (" )\n"); dprintf( " TransportInfo = %p\n", address = ReadField (TransportInfo) ); if (address!=0) { PAFDKD_TRANSPORT_INFO transportInfo; PLIST_ENTRY listEntry; listEntry = TransportInfoList.Flink; while (listEntry!=&TransportInfoList) { transportInfo = CONTAINING_RECORD (listEntry, AFDKD_TRANSPORT_INFO, Link); if (transportInfo->ActualAddress==address) break; listEntry = listEntry->Flink; } if (listEntry==&TransportInfoList) { transportInfo = ReadTransportInfo (address); if (transportInfo!=NULL) { InsertHeadList (&TransportInfoList, &transportInfo->Link); } } if (transportInfo!=NULL) { dprintf( " TransportDeviceName = %ls\n", transportInfo->DeviceName ); } } dprintf( " AddressHandle = %p\n", ReadField (AddressHandle) ); dprintf( " AddressFileObject = %p\n", ReadField (AddressFileObject) ); dprintf( " AddressDeviceObject = %p\n", ReadField (AddressDeviceObject) ); dprintf( " AdminAccessGranted = %s\n", BooleanToString( (BOOLEAN)ReadField (AdminAccessGranted)) ); switch( endpoint.Type ) { case AfdBlockTypeVcConnecting : address = ReadField (Common.VirtualCircuit.Connection); dprintf( " Connection = %p\n", address!=0 ? address : (((endpoint.State==AfdEndpointStateClosing || endpoint.State==AfdEndpointStateTransmitClosing) && ((address = ReadField (WorkItem.Context))!=0)) ? address : 0) ); dprintf( " ListenEndpoint = %p\n", ReadField (Common.VirtualCircuit.ListenEndpoint) ); dprintf( " ConnectDataBuffers = %p\n", ReadField (Common.VirtualCircuit.ConnectDataBuffers) ); break; case AfdBlockTypeVcBoth : dprintf( " Connection = %p\n", ReadField (Common.VirtualCircuit.Connection) ); dprintf( " ConnectDataBuffers = %p\n", ReadField (Common.VirtualCircuit.ConnectDataBuffers) ); // Skip through to listening endpoint case AfdBlockTypeVcListening : if (IS_DELAYED_ACCEPTANCE_ENDPOINT(&endpoint)) { dprintf( " ListenConnectionListHead @ %s\n", LIST_TO_STRING( ActualAddress+ListenConnListOffset, Common.VirtualCircuit.Listening.ListenConnectionListHead.Flink ) ); } else { dprintf( " FreeConnectionListHead @ %p(%d)\n", ActualAddress + FreeConnListOffset, (USHORT)ReadField (Common.VirtualCircuit.Listening.FreeConnectionListHead.Depth) ); dprintf( " AcceptExIrpListHead @ %p(%d)\n", ActualAddress + PreaccConnListOffset, (USHORT)ReadField (Common.VirtualCircuit.Listening.PreacceptedConnectionsListHead.Depth) ); } dprintf( " UnacceptedConnectionListHead %s\n", LIST_TO_STRING( ActualAddress + UnacceptedConnListOffset, Common.VirtualCircuit.Listening.UnacceptedConnectionListHead.Flink) ); dprintf( " ReturnedConnectionListHead %s\n", LIST_TO_STRING( ActualAddress + ReturnedConnListOffset, Common.VirtualCircuit.Listening.ReturnedConnectionListHead.Flink) ); dprintf( " ListeningIrpListHead %s\n", LIST_TO_STRING( ActualAddress + ListenIrpListOffset, Common.VirtualCircuit.Listening.ListeningIrpListHead.Flink) ); dprintf( " FailedConnectionAdds = %ld\n", (LONG)ReadField (Common.VirtualCircuit.Listening.FailedConnectionAdds) ); dprintf( " TdiAcceptPendingCount = %ld\n", (LONG)ReadField (Common.VirtualCircuit.Listening.TdiAcceptPendingCount) ); dprintf( " MaxCachedConnections = %ld\n", (USHORT)ReadField (Common.VirtualCircuit.Listening.MaxExtraConnections) ); dprintf( " ConnectionSequenceNumber = %ld\n", (LONG)ReadField (Common.VirtualCircuit.ListeningSequence) ); dprintf( " BacklogReplenishActive = %s\n", BooleanToString ( (BOOLEAN)ReadField (Common.VirtualCircuit.Listening.BacklogReplenishActive)) ); dprintf( " EnableDynamicBacklog = %s\n", BooleanToString ( (BOOLEAN)(LONG)ReadField (Common.VirtualCircuit.Listening.EnableDynamicBacklog)) ); break; case AfdBlockTypeDatagram : dprintf( " RemoteAddress = %p\n", address = ReadField (Common.Datagram.RemoteAddress) ); dprintf( " RemoteAddressLength = %lu\n", length=(ULONG)ReadField (Common.Datagram.RemoteAddressLength) ); if( address!=0 ) { if (ReadMemory (address, transportAddress, lengthActualAddress==trInfoAddr) break; listEntry = listEntry->Flink; } if (listEntry==&TransportInfoList) { transportInfo = ReadTransportInfo (trInfoAddr); if (transportInfo!=NULL) { InsertHeadList (&TransportInfoList, &transportInfo->Link); } } } port = " "; if ((localAddr=ReadField(LocalAddress))!=0) { length = (ULONG)ReadField (LocalAddressLength); if (ReadMemory (localAddr, transportAddress, lengthDeviceName[sizeof("\\Device\\")-1] : L"", port, ctrs, (ULONG)ReadField (EventsActive), (ULONG)pid, DISP_PTR(address) ); } VOID DumpAfdConnection( ULONG64 ActualAddress ) /*++ Routine Description: Dumps the specified AFD_CONNECTION structures. Arguments: Connection - Points to the AFD_CONNECTION structure to dump. ActualAddress - The actual address where the structure resides on the debugee. Return Value: None. --*/ { AFD_CONNECTION connection; ULONG64 address, endpAddr; ULONG length; UCHAR transportAddress[MAX_TRANSPORT_ADDR]; dprintf( "\nAFD_CONNECTION @ %p:\n", ActualAddress ); connection.Type = (USHORT)ReadField (Type); dprintf( " Type = %04X (%s)\n", connection.Type, StructureTypeToString( connection.Type ) ); dprintf( " ReferenceCount = %ld\n", (LONG)ReadField (ReferenceCount) ); connection.State = (USHORT)ReadField (State); dprintf( " State = %08X (%s)\n", connection.State, ConnectionStateToString( connection.State ) ); dprintf( " StateFlags = %08X (", connection.ConnectionStateFlags = (ULONG)ReadField (ConnectionStateFlags) ); if (connection.TdiBufferring) dprintf (" Buf"); if (connection.AbortIndicated) dprintf (" AbortInd"); if (connection.DisconnectIndicated) dprintf (" DscnInd"); if (connection.ConnectedReferenceAdded) dprintf (" +CRef"); if (connection.SpecialCondition) dprintf (" Special"); if (connection.CleanupBegun) dprintf (" ClnBegun"); if (connection.ClosePendedTransmit) dprintf (" ClosingTranFile"); if (connection.OnLRList) dprintf (" LRList"); dprintf (" )\n"); dprintf( " Handle = %p\n", ReadField (Handle) ); dprintf( " FileObject = %p\n", ReadField (FileObject) ); if (connection.State==AfdConnectionStateConnected) { connection.ConnectTime = ReadField (ConnectTime); if (SystemTime.QuadPart!=0) { dprintf( " ConnectTime = %s\n", SystemTimeToString( connection.ConnectTime- InterruptTime.QuadPart+ SystemTime.QuadPart)); dprintf( " (now: %s)\n", SystemTimeToString (SystemTime.QuadPart) ); } else { dprintf( " ConnectTime = %I64x (nsec since boot)\n", connection.ConnectTime ); } } else { dprintf( " Accept/Listen Irp = %p\n", ReadField (AcceptIrp) ); } if( connection.TdiBufferring ) { dprintf( " ReceiveBytesIndicated = %I64d\n", ReadField( Common.Bufferring.ReceiveBytesIndicated.QuadPart ) ); dprintf( " ReceiveBytesTaken = %I64d\n", ReadField ( Common.Bufferring.ReceiveBytesTaken.QuadPart ) ); dprintf( " ReceiveBytesOutstanding = %I64d\n", ReadField( Common.Bufferring.ReceiveBytesOutstanding.QuadPart ) ); dprintf( " ReceiveExpeditedBytesIndicated = %I64d\n", ReadField( Common.Bufferring.ReceiveExpeditedBytesIndicated.QuadPart ) ); dprintf( " ReceiveExpeditedBytesTaken = %I64d\n", ReadField( Common.Bufferring.ReceiveExpeditedBytesTaken.QuadPart ) ); dprintf( " ReceiveExpeditedBytesOutstanding = %I64d\n", ReadField( Common.Bufferring.ReceiveExpeditedBytesOutstanding.QuadPart ) ); dprintf( " NonBlockingSendPossible = %s\n", BooleanToString( (BOOLEAN)ReadField (Common.Bufferring.NonBlockingSendPossible) ) ); dprintf( " ZeroByteReceiveIndicated = %s\n", BooleanToString( (BOOLEAN)ReadField (Common.Bufferring.ZeroByteReceiveIndicated) ) ); } else { dprintf( " ReceiveIrpListHead %s\n", LIST_TO_STRING( ActualAddress + ConnectionRecvListOffset, Common.NonBufferring.ReceiveIrpListHead.Flink) ); dprintf( " ReceiveBufferListHead %s\n", LIST_TO_STRING( ActualAddress + ConnectionBufferListOffset, Common.NonBufferring.ReceiveBufferListHead.Flink) ); dprintf( " SendIrpListHead %s\n", LIST_TO_STRING( ActualAddress + ConnectionSendListOffset, Common.NonBufferring.SendIrpListHead.Flink) ); dprintf( " BufferredReceiveBytes = %lu\n", (ULONG)ReadField (Common.NonBufferring.BufferredReceiveBytes) ); dprintf( " BufferredExpeditedBytes = %lu\n", (ULONG)ReadField (Common.NonBufferring.BufferredExpeditedBytes) ); dprintf( " BufferredReceiveCount = %u\n", (USHORT)ReadField (Common.NonBufferring.BufferredReceiveCount) ); dprintf( " BufferredExpeditedCount = %u\n", (USHORT)ReadField (Common.NonBufferring.BufferredExpeditedCount) ); dprintf( " ReceiveBytesInTransport = %lu\n", (ULONG)ReadField (Common.NonBufferring.ReceiveBytesInTransport) ); dprintf( " BufferredSendBytes = %lu\n", (ULONG)ReadField (Common.NonBufferring.BufferredSendBytes) ); dprintf( " BufferredSendCount = %u\n", (USHORT)ReadField (Common.NonBufferring.BufferredSendCount) ); dprintf( " DisconnectIrp = %p\n", ReadField (Common.NonBufferring.DisconnectIrp) ); if (IsCheckedAfd ) { dprintf( " ReceiveIrpsInTransport = %ld\n", (ULONG)ReadField (Common.NonBufferring.ReceiveIrpsInTransport) ); } } dprintf( " Endpoint = %p\n", endpAddr = ReadField (Endpoint) ); dprintf( " MaxBufferredReceiveBytes = %lu\n", (ULONG)ReadField (MaxBufferredReceiveBytes) ); dprintf( " MaxBufferredSendBytes = %lu\n", (ULONG)ReadField (MaxBufferredSendBytes) ); dprintf( " ConnectDataBuffers = %p\n", ReadField (ConnectDataBuffers) ); dprintf( " OwningProcess = %p\n", ReadField (OwningProcess) ); dprintf( " DeviceObject = %p\n", ReadField (DeviceObject) ); dprintf( " RemoteAddress = %p\n", address = ReadField (RemoteAddress) ); length = (USHORT)ReadField (RemoteAddressLength); dprintf( " RemoteAddressLength = %lu\n", length ); if( address != 0 ) { if (ReadMemory (address, transportAddress, length=(ULONG)(addressOffset+addressLength) && ReadMemory (context+addressOffset, &taAddress->Address[0].AddressType, addressLengthTAAddressCount = 1; taAddress->Address[0].AddressLength = addressLength-sizeof (USHORT); DumpTransportAddress( " ", taAddress, context+addressOffset ); } else { dprintf ("\nDumpAfdConnection: Could not read address info from endpoint context (paged out:%p ?)!\n", context); } } if( IsReferenceDebug ) { dprintf( " ReferenceDebug = %p\n", ActualAddress + ConnRefOffset ); dprintf( " CurrentReferenceSlot = %lu\n", (LONG)ReadField (CurrentReferenceSlot) % MAX_REFERENCE ); } #ifdef _AFD_VERIFY_DATA_ dprintf( " VerifySequenceNumber = %lx\n", (LONG)ReadField (VerifySequenceNumber) ); #endif dprintf( "\n" ); } // DumpAfdConnection VOID DumpAfdConnectionBrief( ULONG64 ActualAddress ) /*++ Routine Description: Dumps the specified AFD_CONNECTION structure in short format. Connectn Stat Flags Remote Address SndB RcvB Pid Endpoint xxxxxxxx xxx xxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxx xxxx xxxxxxxx Connection Stat Flags Remote Address SndB RcvB Pid Endpoint xxxxxxxxxxx xxx xxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxx xxxx xxxxxxxxxxx Arguments: Connection - Points to the AFD_CONNECTION structure to dump. ActualAddress - The actual address where the structure resides on the debugee. Return Value: None. --*/ { AFD_CONNECTION connection; CHAR transportAddress[MAX_TRANSPORT_ADDR]; ULONG64 address, endpAddr, pid; ULONG length; LPSTR raddr; connection.Type = (USHORT)ReadField (Type); connection.State = (USHORT)ReadField (State); connection.ConnectionStateFlags = (ULONG)ReadField (ConnectionStateFlags); endpAddr = ReadField (Endpoint); address = ReadField (RemoteAddress); length = (ULONG)ReadField (RemoteAddressLength); if( address != 0 ) { if (ReadMemory (address, transportAddress, length=(ULONG)(addressOffset+addressLength) && ReadMemory (context+addressOffset, &taAddress->Address[0].AddressType, addressLengthTAAddressCount = 1; taAddress->Address[0].AddressLength = addressLength-sizeof (USHORT); raddr = TransportAddressToString( taAddress, context+addressOffset ); } else { raddr = "Read error (paged-out ?)!"; } } else { raddr = ""; } if (GetFieldValue ( ReadField(OwningProcess), "NT!_EPROCESS", "UniqueProcessId", pid)!=0) { pid = 0xFEFE; } // Connection Sta Flg Rem Addr SndB RcvB Pid Endpoint dprintf ( IsPtr64 () ? "\n%011.011p %3s %7s %-32.32s %5.5x %5.5x %4.4x %011.011p" : "\n%008.008p %3s %7s %-32.32s %5.5x %5.5x %4.4x %008.008p", DISP_PTR(ActualAddress), ConnectionStateToStringBrief (connection.State), ConnectionStateFlagsToString (&connection), raddr, connection.TdiBufferring ? (ULONG)0 : (ULONG)ReadField (Common.NonBufferring.BufferredSendBytes), connection.TdiBufferring ? (ULONG)(ReadField (Common.Bufferring.ReceiveBytesIndicated.QuadPart) - ReadField (Common.Bufferring.ReceiveBytesTaken.QuadPart)) : (ULONG)(ReadField (Common.NonBufferring.BufferredReceiveBytes) + ReadField (Common.NonBufferring.ReceiveBytesInTransport)), (ULONG)pid, DISP_PTR(endpAddr) ); } VOID DumpAfdReferenceDebug( ULONG64 ActualAddress, ULONG Idx ) /*++ Routine Description: Dumps the AFD_REFERENCE_DEBUG structures associated with an AFD_CONNECTION object. Arguments: ReferenceDebug - Points to an array of AFD_REFERENCE_DEBUG structures. There are assumed to be MAX_REFERENCE entries in this array. ActualAddress - The actual address where the array resides on the debugee. Return Value: None. --*/ { ULONG i; ULONG result; CHAR filePath[MAX_PATH]; CHAR message[256]; ULONG64 format; ULONG64 address; AFD_REFERENCE_DEBUG rd[MAX_REFERENCE]; ULONG64 locationTable; if (RefDebugSize==0) { dprintf ("\nDumpAfdReferenceDebug: sizeof(AFD!AFD_REFERENCE_DEBUG) is 0!!!\n"); return; } result = ReadPtr (GetExpression ("AFD!AfdLocationTable"), &locationTable); if (result!=0) { dprintf("\nDumpAfdReferenceDebug: Could not read afd!AfdLocationTable, err: %ld\n", result); return; } dprintf( "AFD_REFERENCE_DEBUG @ %p @ %u %s\n", ActualAddress, (TicksToMs!=0) ? (ULONG)(((ULONGLONG)TickCount*TicksToMs)>>24) : TickCount, (TicksToMs!=0) ? "ms" : "" ); if (!ReadMemory (ActualAddress, rd, sizeof(rd), &result)) { dprintf ("\nDumpAfdReferenceDebug: Could not read AFD_REFERENCE_DEBUG @ %p\n", ActualAddress); return; } Idx=(Idx+1)%MAX_REFERENCE; for( i = 0 ; i < MAX_REFERENCE ; i++, Idx=(Idx+1)%MAX_REFERENCE ) { if( CheckControlC() ) { break; } if( rd[Idx].QuadPart==0) { continue; } if (GetFieldValue (locationTable+RefDebugSize*(rd[Idx].LocationId-1), "AFD!AFD_REFERENCE_LOCATION", "Format", format)==0 && GetFieldValue (locationTable+RefDebugSize*(rd[Idx].LocationId-1), "AFD!AFD_REFERENCE_LOCATION", "Address", address)==0 && (ReadMemory (format, filePath, sizeof (filePath), &result) || (result>0 && filePath[result-1]==0))) { CHAR *fileName; fileName = strrchr (filePath, '\\'); if (fileName!=NULL) { fileName += 1; } else { fileName = filePath; } sprintf (message, fileName, (ULONG)rd[Idx].Param); } else { sprintf (message, "%lx %lx", (ULONG)rd[Idx].LocationId, (ULONG)rd[Idx].Param); } dprintf (" %3lu %s -> %ld @ %u %s\n", Idx, message, (ULONG)rd[Idx].NewCount, (TicksToMs!=0) ? (ULONG)((rd[Idx].TickCount*TicksToMs)>>24) : (ULONG)rd[Idx].TickCount, (TicksToMs!=0) ? "ms" : ""); } } // DumpAfdReferenceDebug #if GLOBAL_REFERENCE_DEBUG BOOL DumpAfdGlobalReferenceDebug( PAFD_GLOBAL_REFERENCE_DEBUG ReferenceDebug, ULONG64 ActualAddress, DWORD CurrentSlot, DWORD StartingSlot, DWORD NumEntries, ULONG64 CompareAddress ) /*++ Routine Description: Dumps the AFD_GLOBAL_REFERENCE_DEBUG structures. Arguments: ReferenceDebug - Points to an array of AFD_GLOBAL_REFERENCE_DEBUG structures. There are assumed to be MAX_GLOBAL_REFERENCE entries in this array. ActualAddress - The actual address where the array resides on the debugee. CurrentSlot - The last slot used. CompareAddress - If zero, then dump all records. Otherwise, only dump those records with a matching connection pointer. Return Value: None. --*/ { ULONG result; LPSTR fileName; CHAR decoration; CHAR filePath[MAX_PATH]; CHAR action[16]; BOOL foundEnd = FALSE; ULONG lowTick; if( StartingSlot == 0 ) { dprintf( "AFD_GLOBAL_REFERENCE_DEBUG @ %p, Current Slot = %lu\n", ActualAddress, CurrentSlot ); } for( ; NumEntries > 0 ; NumEntries--, StartingSlot++, ReferenceDebug++ ) { if( CheckControlC() ) { foundEnd = TRUE; break; } if( ReferenceDebug->Info1 == NULL && ReferenceDebug->Info2 == NULL && ReferenceDebug->Action == 0 && ReferenceDebug->NewCount == 0 && ReferenceDebug->Connection == NULL ) { foundEnd = TRUE; break; } if( CompareAddress != 0 && ReferenceDebug->Connection != (PVOID)CompareAddress ) { continue; } if( ReferenceDebug->Action == 0 || ReferenceDebug->Action == 1 || ReferenceDebug->Action == (ULONG64)-1L ) { sprintf( action, "%ld", PtrToUlong(ReferenceDebug->Action) ); } else { sprintf( action, "%p", ReferenceDebug->Action ); } decoration = ( StartingSlot == CurrentSlot ) ? '>' : ' '; lowTick = ReferenceDebug->TickCounter.LowPart; switch( (ULONG64)ReferenceDebug->Info1 ) { case 0xafdafd02 : dprintf( "%c %3lu: %p (%8lu) Buffered Send, IRP @ %plx [%s] -> %lu\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, (ULONG64)ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafdafd03 : dprintf( "%c %3lu: %p (%8lu) Nonbuffered Send, IRP @ %p [%s] -> %lu\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, (ULONG64)ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11100 : case 0xafd11101 : dprintf( "%c %3lu: %p (%8lu) AfdRestartSend (%p), IRP @ %p [%s] -> %lu\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, (ULONG64)ReferenceDebug->Info1, (ULONG64)ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11102 : case 0xafd11103 : case 0xafd11104 : case 0xafd11105 : dprintf( "%c %3lu: %p (%8lu) AfdRestartBufferSend (%p), IRP @ %p [%s] -> %lu\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, (ULONG64)ReferenceDebug->Info1, (ULONG64)ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0 : if( ReferenceDebug->Info2 == NULL ) { dprintf( "%c %3lu: %p (%8lu) AfdDeleteConnectedReference (%p)\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, (ULONG64)ReferenceDebug->Action ); break; } else { // // Fall through to default case. // } default : if( ReadMemory( (ULONG64)ReferenceDebug->Info1, filePath, sizeof(filePath), &result ) ) { fileName = strrchr( filePath, '\\' ); if( fileName != NULL ) { fileName++; } else { fileName = filePath; } } else { sprintf( filePath, "%p", ReferenceDebug->Info1 ); fileName = filePath; } dprintf( "%c %3lu: %p (%8lu) %s:%lu [%s] -> %lu\n", decoration, StartingSlot, (ULONG64)ReferenceDebug->Connection, lowTick, fileName, PtrToUlong (ReferenceDebug->Info2), action, ReferenceDebug->NewCount ); break; } } return foundEnd; } // DumpAfdGlobalReferenceDebug #endif VOID DumpAfdTransmitInfo( ULONG64 ActualAddress ) { ULONG64 fileAddr, endpAddr, tpInfoAddr, irpSpAddr; ULONG64 i; ULONG Flags, StateFlags, NumSendIrps, RefCount; ULONG result; irpSpAddr = ReadField (Tail.Overlay.CurrentStackLocation); tpInfoAddr = ReadField (AssociatedIrp.SystemBuffer); if ( (result=GetFieldValue (ActualAddress+DriverContextOffset, "AFD!AFD_TPACKETS_IRP_CTX", "StateFlags", StateFlags)) !=0 || (result=GetFieldValue (ActualAddress+DriverContextOffset, "AFD!AFD_TPACKETS_IRP_CTX", "ReferenceCount", RefCount)) !=0 ) { dprintf( "\ntran: Could not read AFD_TPACKETS_IRP_CTX @ %p, err:%d\n", ActualAddress+DriverContextOffset, result ); return; } if ( (result=GetFieldValue (irpSpAddr, "NT!_IO_STACK_LOCATION", "Flags", Flags)) !=0 || (result = GetFieldValue (irpSpAddr, "NT!_IO_STACK_LOCATION", "FileObject", fileAddr)) !=0 ) { dprintf( "\ntran: Could not read IO_STACK_LOCATION @ %p for IRP @ %p, err:%d\n", irpSpAddr, ActualAddress, result ); return; } result = GetFieldValue (fileAddr, "NT!_FILE_OBJECT", "FsContext", endpAddr); if (result!=0) { dprintf( "\ntran: Could not read FsContext of FILE_OBJECT @ %p for IRP @ %p, err:%d\n", fileAddr, ActualAddress, result ); return; } dprintf( "\nAFD_TRANSMIT_FILE_INFO_INTERNAL @ %p\n", tpInfoAddr ); dprintf( " Endpoint = %p\n", endpAddr ); dprintf( " TransmitIrp = %p\n", ActualAddress); dprintf( " ReferenceCount = %ld\n", RefCount ); dprintf( " Flags = %08lx (", Flags ); if (Flags & AFD_TF_WRITE_BEHIND) dprintf ("WrB "); if (Flags & AFD_TF_DISCONNECT) dprintf ("Dsc "); if (Flags & AFD_TF_REUSE_SOCKET) dprintf ("Reu "); if (Flags & AFD_TF_USE_SYSTEM_THREAD) dprintf ("Sys "); if (Flags & AFD_TF_USE_KERNEL_APC) dprintf ("Apc "); dprintf (")\n"); dprintf( " StateFlags = %08lx (", StateFlags = (ULONG)ReadField (StateFlags) ); if (StateFlags & AFD_TP_ABORT_PENDING) dprintf ("Abrt "); if (StateFlags & AFD_TP_WORKER_SCHEDULED) dprintf ("WrkS "); #ifdef TDI_SERVICE_SEND_AND_DISCONNECT if (StateFlags & AFD_TP_SEND_AND_DISCONNECT) dprintf ("S&D "); #endif if (tpInfoAddr==0) { dprintf( "Disconnecting)\n" ); } else if (tpInfoAddr==-1) { dprintf( "Reusing)\n" ); } else { result = (ULONG)InitTypeRead (tpInfoAddr, AFD!AFD_TPACKETS_INFO_INTERNAL); if (result!=0) { dprintf( "\ntran: Could not read AFD_TPACKETS_INFO_INTERNAL @ %p, err:%d\n", tpInfoAddr, result ); return; } if (ReadField(PdNeedsPps)) dprintf ("Pps "); if (ReadField(ArrayAllocated)) dprintf ("Alloc "); dprintf (")\n"); dprintf( " SendPacketLength = %08lx\n", (ULONG)ReadField (SendPacketLength) ); dprintf( " PdLength = %08lx\n", (ULONG)ReadField (PdLength) ); dprintf( " NextElement = %d\n", (ULONG)ReadField (NextElement) ); dprintf( " ElementCount = %d\n", (ULONG)ReadField (ElementCount) ); dprintf( " ElementArray = %p\n", ReadField (ElementArray) ); dprintf( " RemainingPkts = %p\n", ReadField (RemainingPkts) ); dprintf( " HeadPd = %p\n", ReadField (HeadPd) ); dprintf( " TailPd = %p\n", ReadField (TailPd) ); dprintf( " HeadMdl = %p\n", ReadField (HeadMdl) ); dprintf( " TailMdl = %p\n", ReadField (TailMdl) ); dprintf( " TdiFileObject = %p\n", ReadField (TdiFileObject) ); dprintf( " TdiDeviceObject = %p\n", ReadField (TdiDeviceObject) ); dprintf( " NumSendIrps = %08lx\n", NumSendIrps = (LONG)ReadField (NumSendIrps) ); for (i=0; iaddress, "AFD!AFD_POLL_ENDPOINT_INFO", "FileObject", file))==0 && (err=GetFieldValue (pField->address, "AFD!AFD_POLL_ENDPOINT_INFO", "Endpoint", endp))==0 && (err=GetFieldValue (pField->address, "AFD!AFD_POLL_ENDPOINT_INFO", "Handle", hndl))==0 && (err=GetFieldValue (pField->address, "AFD!AFD_POLL_ENDPOINT_INFO", "PollEvents", evts))==0) { dprintf (" %-16p %-16p %-8x %s%s%s%s%s%s%s%s%s%s%s%s%s\n", file, endp, (ULONG)hndl, (evts & AFD_POLL_RECEIVE) ? "rcv " : "", (evts & AFD_POLL_RECEIVE_EXPEDITED) ? "rce " : "", (evts & AFD_POLL_SEND) ? "snd " : "", (evts & AFD_POLL_DISCONNECT) ? "dsc " : "", (evts & AFD_POLL_ABORT) ? "abrt " : "", (evts & AFD_POLL_LOCAL_CLOSE) ? "cls " : "", (evts & AFD_POLL_CONNECT) ? "con " : "", (evts & AFD_POLL_ACCEPT) ? "acc " : "", (evts & AFD_POLL_CONNECT_FAIL) ? "cnf " : "", (evts & AFD_POLL_QOS) ? "qos " : "", (evts & AFD_POLL_GROUP_QOS) ? "gqs " : "", (evts & AFD_POLL_ROUTING_IF_CHANGE) ? "rif " : "", (evts & AFD_POLL_ADDRESS_LIST_CHANGE) ? "adr " : ""); } else { dprintf (" Failed to read endpoint info @ %p, err: %ld\n", pField->address, err); } return err; } VOID DumpAfdPollInfo ( ULONG64 ActualAddress ) { ULONG numEndpoints, err; ULONG64 irp,thread,pid,tid; dprintf ("\nAFD_POLL_INFO_INTERNAL @ %p\n", ActualAddress); dprintf( " NumberOfEndpoints = %08lx\n", numEndpoints=(ULONG)ReadField (NumberOfEndpoints) ); dprintf( " Irp = %p\n", irp=ReadField (Irp) ); if ((err=GetFieldValue (irp, "NT!_IRP", "Tail.Overlay.Thread", thread))==0 && (err=GetFieldValue (thread, "NT!_ETHREAD", "Cid.UniqueProcess", pid))==0 && (err=GetFieldValue (thread, "NT!_ETHREAD", "Cid.UniqueThread", tid))==0 ){ dprintf( " Thread = %p (%lx.%lx)\n", thread, (ULONG)pid, (ULONG)tid); } else { dprintf( " Could not get thread(tid/pid) from irp, err: %ld\n", err); } if (ReadField (TimerStarted)) { if (SystemTime.QuadPart!=0 ) { dprintf( " Expires @ %s (cur %s)\n", SystemTimeToString (ReadField (Timer.DueTime.QuadPart)- InterruptTime.QuadPart+ SystemTime.QuadPart), SystemTimeToString (SystemTime.QuadPart)); } else { dprintf( " Expires @ %I64x\n", ReadField (Timer.DueTime.QuadPart)); } } dprintf( " Flags : %s%s%s\n", ReadField (Unique) ? "Unique " : "", ReadField (TimerStarted) ? "TimerStarted " : "", ReadField (SanPoll) ? "SanPoll " : "" ); if (numEndpoints>0) { FIELD_INFO flds = { NULL, NULL, numEndpoints, 0, 0, DumpAfdPollEndpointInfo}; SYM_DUMP_PARAM sym = { sizeof (SYM_DUMP_PARAM), "AFD!AFD_POLL_ENDPOINT_INFO", DBG_DUMP_NO_PRINT | DBG_DUMP_ARRAY, ActualAddress+PollEndpointInfoOffset, &flds, NULL, NULL, 0, NULL }; dprintf ( " File Object Endpoint Handle Events\n"); Ioctl(IG_DUMP_SYMBOL_INFO, &sym, sym.size); } } VOID DumpAfdPollInfoBrief ( ULONG64 ActualAddress ) { ULONG64 irp, thread=0, pid=0, tid=0; BOOLEAN timerStarted, unique, san; CHAR dueTime[16]; irp = ReadField (Irp); GetFieldValue (irp, "NT!_IRP", "Tail.Overlay.Thread", thread); GetFieldValue (thread, "NT!_ETHREAD", "Cid.UniqueProcess", pid); GetFieldValue (thread, "NT!_ETHREAD", "Cid.UniqueThread", tid); timerStarted = ReadField (TimerStarted)!=0; unique = ReadField (Unique)!=0; san = ReadField (SanPoll)!=0; if (timerStarted) { TIME_FIELDS timeFields; LARGE_INTEGER diff; diff.QuadPart = ReadField (Timer.DueTime.QuadPart)-InterruptTime.QuadPart; RtlTimeToElapsedTimeFields( &diff, &timeFields ); sprintf (dueTime, "%2.2d:%2.2d:%2.2d.%3.3d", timeFields.Day*24+timeFields.Hour, timeFields.Minute, timeFields.Second, timeFields.Milliseconds); } else { sprintf (dueTime, "NEVER "); } dprintf (//PollInfo IRP Thread (pid.tid) Expr Flags Hdls Array IsPtr64 () ? "\n%011.011p %011.011p %011.011p %4.4x.%4.4x %12s %1s%1s%1s %4.4x %011.011p" : "\n%008.008p %008.008p %008.008p %4.4x.%4.4x %12s %1s%1s%1s %4.4x %008.008p", DISP_PTR(ActualAddress), DISP_PTR(irp), DISP_PTR(thread), (ULONG)pid, (ULONG)tid, dueTime, timerStarted ? "T" : " ", unique ? "U" : " ", san ? "S" : " ", (ULONG)ReadField (NumberOfEndpoints), DISP_PTR (ActualAddress+PollEndpointInfoOffset)); } // // Private functions. // PSTR StructureTypeToString( USHORT Type ) /*++ Routine Description: Maps an AFD structure type to a displayable string. Arguments: Type - The AFD structure type to map. Return Value: PSTR - Points to the displayable form of the structure type. --*/ { switch( Type ) { case AfdBlockTypeEndpoint : return "Endpoint"; case AfdBlockTypeVcConnecting : return "VcConnecting"; case AfdBlockTypeVcListening : return "VcListening"; case AfdBlockTypeDatagram : return "Datagram"; case AfdBlockTypeConnection : return "Connection"; case AfdBlockTypeHelper : return "Helper"; case AfdBlockTypeVcBoth: return "Listening Root"; } return "INVALID"; } // StructureTypeToString PSTR StructureTypeToStringBrief ( USHORT Type ) /*++ Routine Description: Maps an AFD structure type to a displayable string. Arguments: Type - The AFD structure type to map. Return Value: PSTR - Points to the displayable form of the structure type. --*/ { switch( Type ) { case AfdBlockTypeEndpoint : return "Enp"; case AfdBlockTypeVcConnecting : return "Vc "; case AfdBlockTypeVcListening : return "Lsn"; case AfdBlockTypeDatagram : return "Dg "; case AfdBlockTypeConnection : return "Con"; case AfdBlockTypeHelper : return "Hlp"; case AfdBlockTypeVcBoth: return "Rot"; } return "???"; } // StructureTypeToString PSTR BooleanToString( BOOLEAN Flag ) /*++ Routine Description: Maps a BOOELEAN to a displayable form. Arguments: Flag - The BOOLEAN to map. Return Value: PSTR - Points to the displayable form of the BOOLEAN. --*/ { return Flag ? "TRUE" : "FALSE"; } // BooleanToString PSTR EndpointStateToString( UCHAR State ) /*++ Routine Description: Maps an AFD endpoint state to a displayable string. Arguments: State - The AFD endpoint state to map. Return Value: PSTR - Points to the displayable form of the AFD endpoint state. --*/ { switch( State ) { case AfdEndpointStateOpen : return "Open"; case AfdEndpointStateBound : return "Bound"; case AfdEndpointStateConnected : return "Connected"; case AfdEndpointStateCleanup : return "Cleanup"; case AfdEndpointStateClosing : return "Closing"; case AfdEndpointStateTransmitClosing : return "Transmit Closing"; case AfdEndpointStateInvalid : return "Invalid"; } return "INVALID"; } // EndpointStateToString PSTR EndpointStateToStringBrief( UCHAR State ) /*++ Routine Description: Maps an AFD endpoint state to a displayable string. Arguments: State - The AFD endpoint state to map. Return Value: PSTR - Points to the displayable form of the AFD endpoint state. --*/ { switch( State ) { case AfdEndpointStateOpen : return "Opn"; case AfdEndpointStateBound : return "Bnd"; case AfdEndpointStateConnected : return "Con"; case AfdEndpointStateCleanup : return "Cln"; case AfdEndpointStateClosing : return "Cls"; case AfdEndpointStateTransmitClosing : return "TrC"; case AfdEndpointStateInvalid : return "Inv"; } return "???"; } // EndpointStateToString PSTR EndpointStateFlagsToString( PAFD_ENDPOINT Endpoint ) /*++ Routine Description: Maps an AFD endpoint state flags to a displayable string. Arguments: Endpoint - The AFD endpoint which state flags to map. Return Value: PSTR - Points to the displayable form of the AFD endpoint state flags. --*/ { static CHAR buffer[13]; buffer[0] = (Endpoint->NonBlocking) ? 'N' : ' '; buffer[1] = (Endpoint->InLine) ? 'I' : ' '; buffer[2] = (Endpoint->EndpointCleanedUp) ? 'E' : ' '; buffer[3] = (Endpoint->PollCalled) ? 'P' : ' '; buffer[4] = (Endpoint->RoutingQueryReferenced) ? 'Q' : ' '; buffer[5] = (Endpoint->DisableFastIoSend) ? 'S' : ' '; buffer[6] = (Endpoint->DisableFastIoRecv) ? 'R' : ' '; buffer[7] = (Endpoint->AdminAccessGranted) ? 'A' : ' '; switch (Endpoint->DisconnectMode) { case 0: buffer[8] = ' '; break; case 1: buffer[8] = 's'; break; case 2: buffer[8] = 'r'; break; case 3: buffer[8] = 'b'; break; default: buffer[8] = '?'; break; } if (Endpoint->Type==AfdBlockTypeDatagram) { buffer[9] = Endpoint->Common.Datagram.CircularQueueing ? 'C' : ' '; buffer[10] = Endpoint->Common.Datagram.HalfConnect ? 'H' : ' '; buffer[11] = '0' + (CHAR) ((Endpoint->Common.Datagram.AddressDrop <<0)+ (Endpoint->Common.Datagram.ResourceDrop<<1)+ (Endpoint->Common.Datagram.BufferDrop <<2)+ (Endpoint->Common.Datagram.ErrorDrop <<3)); } else { buffer[9] = (Endpoint->Listening) ? 'L' : ' '; buffer[10] = ' '; buffer[11] = ' '; } buffer[12] = 0; return buffer; } PSTR EndpointTypeToString( ULONG TypeFlags ) /*++ Routine Description: Maps an AFD_ENDPOINT_TYPE to a displayable string. Arguments: Type - The AFD_ENDPOINT_TYPE to map. Return Value: PSTR - Points to the displayable form of the AFD_ENDPOINT_TYPE. --*/ { switch( TypeFlags ) { case AfdEndpointTypeStream : return "Stream"; case AfdEndpointTypeDatagram : return "Datagram"; case AfdEndpointTypeRaw : return "Raw"; case AfdEndpointTypeSequencedPacket : return "SequencedPacket"; default: if (TypeFlags&(~AFD_ENDPOINT_VALID_FLAGS)) return "INVALID"; else { static CHAR buffer[64]; INT n = 0; buffer[0] = 0; if (TypeFlags & AFD_ENDPOINT_FLAG_CONNECTIONLESS) n += sprintf (&buffer[n], "con-less "); if (TypeFlags & AFD_ENDPOINT_FLAG_MESSAGEMODE) n += sprintf (&buffer[n], "msg "); if (TypeFlags & AFD_ENDPOINT_FLAG_RAW) n += sprintf (&buffer[n], "raw "); if (TypeFlags & AFD_ENDPOINT_FLAG_MULTIPOINT) n += sprintf (&buffer[n], "m-point "); if (TypeFlags & AFD_ENDPOINT_FLAG_CROOT) n += sprintf (&buffer[n], "croot "); if (TypeFlags & AFD_ENDPOINT_FLAG_DROOT) n += sprintf (&buffer[n], "droot "); return buffer; } } } // EndpointTypeToString PSTR ConnectionStateToString( USHORT State ) /*++ Routine Description: Maps an AFD connection state to a displayable string. Arguments: State - The AFD connection state to map. Return Value: PSTR - Points to the displayable form of the AFD connection state. --*/ { switch( State ) { case AfdConnectionStateFree : return "Free"; case AfdConnectionStateUnaccepted : return "Unaccepted"; case AfdConnectionStateReturned : return "Returned"; case AfdConnectionStateConnected : return "Connected"; case AfdConnectionStateClosing : return "Closing"; } return "INVALID"; } // ConnectionStateToString PSTR ConnectionStateToStringBrief( USHORT State ) /*++ Routine Description: Maps an AFD connection state to a displayable string. Arguments: State - The AFD connection state to map. Return Value: PSTR - Points to the displayable form of the AFD connection state. --*/ { switch( State ) { case AfdConnectionStateFree : return "Fre"; case AfdConnectionStateUnaccepted : return "UnA"; case AfdConnectionStateReturned : return "Rtn"; case AfdConnectionStateConnected : return "Con"; case AfdConnectionStateClosing : return "Cls"; } return "???"; } // ConnectionStateToStringBrief PSTR ConnectionStateFlagsToString( PAFD_CONNECTION Connection ) /*++ Routine Description: Maps an AFD connection state flags to a displayable string. Arguments: Connection - The AFD connection which state flags to map. Return Value: PSTR - Points to the displayable form of the AFD connection state flags. --*/ { static CHAR buffer[8]; buffer[0] = (Connection->AbortIndicated) ? 'A' : ' '; buffer[1] = (Connection->DisconnectIndicated) ? 'D' : ' '; buffer[2] = (Connection->ConnectedReferenceAdded) ? 'R' : ' '; buffer[3] = (Connection->SpecialCondition) ? 'S' : ' '; buffer[4] = (Connection->CleanupBegun) ? 'C' : ' '; buffer[5] = (Connection->ClosePendedTransmit) ? 'T' : ' '; buffer[6] = (Connection->OnLRList) ? 'L' : ' '; buffer[7] = 0; return buffer; } PSTR TranfileFlagsToString( ULONG Flags, ULONG StateFlags ) /*++ Routine Description: Maps an AFD transmit file info flags to a displayable string. Arguments: TransmitInfo - The AFD transmit file info which flags to map. Return Value: PSTR - Points to the displayable form of the AFD transmit file info flags. --*/ { static CHAR buffer[18]; buffer[0] = (Flags & AFD_TF_WRITE_BEHIND) ? 'b' : ' '; buffer[1] = (Flags & AFD_TF_DISCONNECT) ? 'd' : ' '; buffer[2] = (Flags & AFD_TF_REUSE_SOCKET) ? 'r' : ' '; buffer[3] = (Flags & AFD_TF_USE_SYSTEM_THREAD) ? 's' : 'a'; buffer[4] = '|'; buffer[5] = (StateFlags & AFD_TP_ABORT_PENDING) ? 'A' : ' '; buffer[6] = (StateFlags & AFD_TP_WORKER_SCHEDULED) ? 'W' : ' '; buffer[7] = (StateFlags & AFD_TP_READ_BUSY) ? '0' : ' '; buffer[8] = (StateFlags & AFD_TP_SEND_BUSY(0)) ? '1' : ' '; buffer[9] = (StateFlags & AFD_TP_SEND_BUSY(1)) ? '2' : ' '; buffer[10] = (StateFlags & AFD_TP_SEND_BUSY(2)) ? '3' : ' '; buffer[11] = (StateFlags & AFD_TP_SEND_BUSY(3)) ? '4' : ' '; buffer[12] = (StateFlags & AFD_TP_SEND_BUSY(4)) ? '5' : ' '; buffer[13] = (StateFlags & AFD_TP_SEND_BUSY(5)) ? '6' : ' '; buffer[14] = (StateFlags & AFD_TP_SEND_BUSY(6)) ? '7' : ' '; buffer[15] = (StateFlags & AFD_TP_SEND_BUSY(7)) ? '8' : ' '; #ifdef TDI_SERVICE_SEND_AND_DISCONNECT buffer[16] = (StateFlags & AFD_TP_SEND_AND_DISCONNECT) ? '&' : ' '; buffer[17] = 0; #else buffer[16] = 0; #endif return buffer; } PSTR BufferFlagsToString( PAFD_BUFFER_HEADER AfdBuffer ) /*++ Routine Description: Maps an AFD buffer flags to a displayable string. Arguments: TransmitInfo - The AFD buffer which flags to map. Return Value: PSTR - Points to the displayable form of the AFD buffer flags. --*/ { static CHAR buffer[7]; buffer[0] = (AfdBuffer->ExpeditedData) ? 'E' : ' '; buffer[1] = (AfdBuffer->PartialMessage) ? 'P' : ' '; buffer[2] = (AfdBuffer->Lookaside) ? 'L' : ' '; buffer[3] = (AfdBuffer->NdisPacket) ? 'N' : ' '; switch (AfdBuffer->Placement) { case AFD_PLACEMENT_HDR: buffer[4] = 'h'; break; case AFD_PLACEMENT_IRP: buffer[4] = 'i'; break; case AFD_PLACEMENT_MDL: buffer[4] = 'm'; break; case AFD_PLACEMENT_BUFFER: buffer[4] = 'b'; break; } buffer[5] = (AfdBuffer->AlignmentAdjusted) ? 'A' : ' '; buffer[6] = 0; return buffer; } PSTR SystemTimeToString( LONGLONG Value ) /*++ Routine Description: Maps a LONGLONG representing system time to a displayable string. Arguments: Value - The LONGLONG time to map. Return Value: PSTR - Points to the displayable form of the system time. Notes: This routine is NOT multithread safe! --*/ { static char buffer[64]; NTSTATUS status; LARGE_INTEGER systemTime; LARGE_INTEGER localTime; TIME_FIELDS timeFields; systemTime.QuadPart = Value; status = RtlSystemTimeToLocalTime( &systemTime, &localTime ); if( !NT_SUCCESS(status) ) { sprintf(buffer, "%I64x", Value); return buffer; } RtlTimeToTimeFields( &localTime, &timeFields ); sprintf( buffer, "%s %s %2d %4d %02d:%02d:%02d.%03d", WeekdayNames[timeFields.Weekday], MonthNames[timeFields.Month], timeFields.Day, timeFields.Year, timeFields.Hour, timeFields.Minute, timeFields.Second, timeFields.Milliseconds ); return buffer; } // SystemTimeToString PSTR GroupTypeToString( AFD_GROUP_TYPE GroupType ) /*++ Routine Description: Maps an AFD_GROUP_TYPE to a displayable string. Arguments: GroupType - The AFD_GROUP_TYPE to map. Return Value: PSTR - Points to the displayable form of the AFD_GROUP_TYPE. --*/ { switch( GroupType ) { case GroupTypeNeither : return "Neither"; case GroupTypeConstrained : return "Constrained"; case GroupTypeUnconstrained : return "Unconstrained"; } return "INVALID"; } // GroupTypeToString PSTR ListToString ( ULONG64 ListHead, ULONG64 Flink ) { static CHAR buffer[32]; if (ListHead==Flink) { sprintf (buffer, "= EMPTY"); } else if (IsPtr64()) { sprintf (buffer, "@ %I64X", ListHead); } else { sprintf (buffer, "@ %X", (ULONG)ListHead); } return buffer; } PAFDKD_TRANSPORT_INFO ReadTransportInfo ( ULONG64 ActualAddress ) { ULONG result, length; PAFDKD_TRANSPORT_INFO transportInfo; ULONG64 buffer; if( GetFieldValue( ActualAddress, "AFD!AFD_TRANSPORT_INFO", "TransportDeviceName.Length", length )!=0 || GetFieldValue( ActualAddress, "AFD!AFD_TRANSPORT_INFO", "TransportDeviceName.Buffer", buffer )!=0) { dprintf( "\nReadTransportInfo: Could not read AFD_TRANSPORT_INFO @ %p\n", ActualAddress ); return NULL; } if (length < sizeof (L"\\Device\\")-2) { dprintf( "\nReadTransportInfo: transport info (@%p) device name length (%ld) is less than sizeof (L'\\Device\\')-2\n", ActualAddress, length ); return NULL; } transportInfo = RtlAllocateHeap (RtlProcessHeap (), 0, FIELD_OFFSET (AFDKD_TRANSPORT_INFO, DeviceName[length/2+1])); if (transportInfo==NULL) { dprintf( "\nReadTransportInfo: Could not allocate space for transport info.\n" ); return NULL; } transportInfo->ActualAddress = ActualAddress; if (GetFieldValue ( ActualAddress, "AFD!AFD_TRANSPORT_INFO", "ReferenceCount", transportInfo->ReferenceCount)!=0 || GetFieldValue ( ActualAddress, "AFD!AFD_TRANSPORT_INFO", "InfoValid", transportInfo->InfoValid)!=0 || GetFieldValue ( ActualAddress, "AFD!AFD_TRANSPORT_INFO", "ProviderInfo", transportInfo->ProviderInfo)!=0 || !ReadMemory( buffer, &transportInfo->DeviceName, length, &result )) { dprintf( "\nReadTransportInfo: Could not read AFD_TRANSPORT_INFO @ %p\n", ActualAddress ); RtlFreeHeap (RtlProcessHeap (), 0, transportInfo); return NULL; } transportInfo->DeviceName[length/2] = 0; return transportInfo; } VOID DumpTransportInfo ( PAFDKD_TRANSPORT_INFO TransportInfo ) { dprintf ("\nTransport Info @ %p\n", TransportInfo->ActualAddress); dprintf (" TransportDeviceName = %ls\n", TransportInfo->DeviceName); dprintf (" ReferenceCount = %ld\n", TransportInfo->ReferenceCount); if (TransportInfo->InfoValid) { dprintf (" ProviderInfo:\n"); dprintf (" Version = %8.8lx\n", TransportInfo->ProviderInfo.Version); dprintf (" MaxSendSize = %ld\n", TransportInfo->ProviderInfo.MaxSendSize); dprintf (" MaxConnectionUserData = %ld\n", TransportInfo->ProviderInfo.MaxConnectionUserData); dprintf (" MaxDatagramSize = %ld\n", TransportInfo->ProviderInfo.MaxDatagramSize); dprintf (" ServiceFlags = %lx (", TransportInfo->ProviderInfo.ServiceFlags); if (TDI_SERVICE_ORDERLY_RELEASE & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" OrdRel"); if (TDI_SERVICE_DELAYED_ACCEPTANCE & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" DelAcc"); if (TDI_SERVICE_EXPEDITED_DATA & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" Expd"); if (TDI_SERVICE_INTERNAL_BUFFERING & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" Buff"); if (TDI_SERVICE_MESSAGE_MODE & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" Msg"); if (TDI_SERVICE_DGRAM_CONNECTION & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" DgramCon"); if (TDI_SERVICE_FORCE_ACCESS_CHECK & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" AccChk"); if (TDI_SERVICE_SEND_AND_DISCONNECT & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" S&D"); if (TDI_SERVICE_DIRECT_ACCEPT & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" DirAcc"); if (TDI_SERVICE_ACCEPT_LOCAL_ADDR & TransportInfo->ProviderInfo.ServiceFlags) dprintf (" AcLoAd"); dprintf (" )\n"); dprintf (" MinimumLookaheadData = %ld\n", TransportInfo->ProviderInfo.MinimumLookaheadData); dprintf (" MaximumLookaheadData = %ld\n", TransportInfo->ProviderInfo.MaximumLookaheadData); dprintf (" NumberOfResources = %ld\n", TransportInfo->ProviderInfo.NumberOfResources); dprintf (" StartTime = %s\n", SystemTimeToString(TransportInfo->ProviderInfo.StartTime.QuadPart)); } } VOID DumpTransportInfoBrief ( PAFDKD_TRANSPORT_INFO TransportInfo ) { dprintf (//PollInfo IRP Thread (pid.tid) Expr Flags Hdls Array IsPtr64 () ? "\n%011.011p %-30.30ls %4.4x %3.3x %8.8x %5.5x %5.5x %s" : "\n%008.008p %-30.30ls %4.4x %3.3x %8.8x %5.5x %5.5x %s", DISP_PTR(TransportInfo->ActualAddress), &TransportInfo->DeviceName[sizeof ("\\device\\")-1], TransportInfo->ReferenceCount, TransportInfo->ProviderInfo.Version, TransportInfo->ProviderInfo.MaxSendSize, TransportInfo->ProviderInfo.MaxDatagramSize, TransportInfo->ProviderInfo.ServiceFlags, TdiServiceFlagsToString (TransportInfo->ProviderInfo.ServiceFlags)); } PSTR TdiServiceFlagsToString( ULONG Flags ) /*++ Routine Description: Maps an TDI service flags to a displayable string. Arguments: Flags - flags to map Return Value: PSTR - Points to the displayable form of the TDI service flags. --*/ { static CHAR buffer[10]; buffer[0] = (TDI_SERVICE_ORDERLY_RELEASE & Flags) ? 'O' : ' ', buffer[1] = (TDI_SERVICE_DELAYED_ACCEPTANCE & Flags) ? 'D' : ' ', buffer[2] = (TDI_SERVICE_EXPEDITED_DATA & Flags) ? 'E' : ' ', buffer[3] = (TDI_SERVICE_INTERNAL_BUFFERING & Flags) ? 'B' : ' ', buffer[4] = (TDI_SERVICE_MESSAGE_MODE & Flags) ? 'M' : ' ', buffer[5] = (TDI_SERVICE_DGRAM_CONNECTION & Flags) ? 'G' : ' ', buffer[6] = (TDI_SERVICE_FORCE_ACCESS_CHECK & Flags) ? 'A' : ' ', buffer[7] = (TDI_SERVICE_SEND_AND_DISCONNECT & Flags) ? '&' : ' ', buffer[8] = (TDI_SERVICE_DIRECT_ACCEPT & Flags) ? 'R' : ' ', buffer[9] = 0; return buffer; }