NT4/private/ntos/afd/afdkd/afdutil.c
2020-09-30 17:12:29 +02:00

2222 lines
46 KiB
C

/*++
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.
//
#define MAX_SYMBOL_LENGTH 128
#define ACTUAL_ADDRESS(a,s,f) \
( (DWORD)(a) + ( (PUCHAR)(&(s)->f) - (PUCHAR)(s) ) )
#define IS_LIST_EMPTY(a,s,f) \
( (DWORD)(s)->f.Flink == ACTUAL_ADDRESS(a,s,f) )
//
// 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
BooleanToString(
BOOLEAN Flag
);
PSTR
EndpointStateToString(
UCHAR State
);
PSTR
EndpointTypeToString(
AFD_ENDPOINT_TYPE Type
);
PSTR
ConnectionStateToString(
USHORT State
);
PSTR
SystemTimeToString(
LONGLONG Value
);
PSTR
GroupTypeToString(
AFD_GROUP_TYPE GroupType
);
VOID
DumpReferenceDebug(
PAFD_REFERENCE_DEBUG ReferenceDebug,
ULONG CurrentSlot
);
BOOL
IsTransmitIrpBusy(
PIRP Irp
);
//
// Public functions.
//
VOID
DumpAfdEndpoint(
PAFD_ENDPOINT Endpoint,
DWORD ActualAddress
)
/*++
Routine Description:
Dumps the specified AFD_ENDPOINT structure.
Arguments:
Endpoint - Points to the AFD_ENDPOINT to dump.
ActualAddress - The actual address where the structure resides on the
debugee.
Return Value:
None.
--*/
{
AFD_TRANSPORT_INFO transportInfo;
UNICODE_STRING unicodeString;
WCHAR buffer[MAX_PATH];
UCHAR address[MAX_TRANSPORT_ADDR];
ULONG result;
dprintf(
"AFD_ENDPOINT @ %08lx:\n",
ActualAddress
);
dprintf(
" Type = %04X (%s)\n",
Endpoint->Type,
StructureTypeToString( Endpoint->Type )
);
dprintf(
" ReferenceCount = %d\n",
Endpoint->ReferenceCount
);
dprintf(
" State = %02X (%s)\n",
Endpoint->State,
EndpointStateToString( Endpoint->State )
);
dprintf(
" NonBlocking = %s\n",
BooleanToString( Endpoint->NonBlocking )
);
dprintf(
" InLine = %s\n",
BooleanToString( Endpoint->InLine )
);
dprintf(
" TdiBufferring = %s\n",
BooleanToString( Endpoint->TdiBufferring )
);
dprintf(
" TransportInfo = %08lx\n",
Endpoint->TransportInfo
);
if( ReadMemory(
(DWORD)Endpoint->TransportInfo,
&transportInfo,
sizeof(transportInfo),
&result
) &&
ReadMemory(
(DWORD)transportInfo.TransportDeviceName.Buffer,
buffer,
sizeof(buffer),
&result
) ) {
unicodeString = transportInfo.TransportDeviceName;
unicodeString.Buffer = buffer;
dprintf(
" TransportDeviceName = %wZ\n",
&unicodeString
);
}
dprintf(
" EndpointType = %08lx (%s)\n",
Endpoint->EndpointType,
EndpointTypeToString( Endpoint->EndpointType )
);
dprintf(
" AddressHandle = %08lx\n",
Endpoint->AddressHandle
);
dprintf(
" AddressFileObject = %08lx\n",
Endpoint->AddressFileObject
);
switch( Endpoint->Type ) {
case AfdBlockTypeVcConnecting :
dprintf(
" Connection = %08lx\n",
Endpoint->Common.VcConnecting.Connection
);
dprintf(
" ConnectStatus = %08lx\n",
Endpoint->Common.VcConnecting.ConnectStatus
);
dprintf(
" ListenEndpoint = %08lx\n",
Endpoint->Common.VcConnecting.ListenEndpoint
);
break;
case AfdBlockTypeVcListening :
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.VcListening.FreeConnectionListHead ) ) {
dprintf(
" FreeConnectionListHead = EMPTY\n"
);
} else {
dprintf(
" FreeConnectionListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.VcListening.FreeConnectionListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.VcListening.UnacceptedConnectionListHead ) ) {
dprintf(
" UnacceptedConnectionListHead = EMPTY\n"
);
} else {
dprintf(
" UnacceptedConnectionListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.VcListening.UnacceptedConnectionListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.VcListening.ReturnedConnectionListHead ) ) {
dprintf(
" ReturnedConnectionListHead = EMPTY\n"
);
} else {
dprintf(
" ReturnedConnectionListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.VcListening.ReturnedConnectionListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.VcListening.ListeningIrpListHead ) ) {
dprintf(
" ListeningIrpListHead = EMPTY\n"
);
} else {
dprintf(
" ListeningIrpListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.VcListening.ListeningIrpListHead
)
);
}
dprintf(
" FailedConnectionAdds = %08lx\n",
Endpoint->Common.VcListening.FailedConnectionAdds
);
break;
case AfdBlockTypeDatagram :
dprintf(
" RemoteAddress = %08lx\n",
Endpoint->Common.Datagram.RemoteAddress
);
dprintf(
" RemoteAddressLength = %08lx\n",
Endpoint->Common.Datagram.RemoteAddressLength
);
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.Datagram.ReceiveIrpListHead ) ) {
dprintf(
" ReceiveIrpListHead = EMPTY\n"
);
} else {
dprintf(
" ReceiveIrpListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.Datagram.ReceiveIrpListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.Datagram.PeekIrpListHead ) ) {
dprintf(
" PeekIrpListHead = EMPTY\n"
);
} else {
dprintf(
" PeekIrpListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.Datagram.PeekIrpListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Endpoint,
Common.Datagram.ReceiveBufferListHead ) ) {
dprintf(
" ReceiveBufferListHead = EMPTY\n"
);
} else {
dprintf(
" ReceiveBufferListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Endpoint,
Common.Datagram.ReceiveBufferListHead
)
);
}
dprintf(
" BufferredDatagramBytes = %08lx\n",
Endpoint->BufferredDatagramBytes
);
dprintf(
" BufferredDatagramCount = %04X\n",
Endpoint->BufferredDatagramCount
);
dprintf(
" MaxBufferredReceiveBytes = %08lx\n",
Endpoint->Common.Datagram.MaxBufferredReceiveBytes
);
dprintf(
" MaxBufferredSendBytes = %08lx\n",
Endpoint->Common.Datagram.MaxBufferredSendBytes
);
dprintf(
" MaxBufferredReceiveCount = %04X\n",
Endpoint->Common.Datagram.MaxBufferredReceiveCount
);
dprintf(
" MaxBufferredSendCount = %04X\n",
Endpoint->Common.Datagram.MaxBufferredSendCount
);
dprintf(
" CircularQueueing = %s\n",
BooleanToString( Endpoint->Common.Datagram.CircularQueueing )
);
break;
}
dprintf(
" DisconnectMode = %08lx\n",
Endpoint->DisconnectMode
);
dprintf(
" OutstandingIrpCount = %08lx\n",
Endpoint->OutstandingIrpCount
);
dprintf(
" LocalAddress = %08lx\n",
Endpoint->LocalAddress
);
dprintf(
" LocalAddressLength = %08lx\n",
Endpoint->LocalAddressLength
);
if( Endpoint->LocalAddressLength <= sizeof(address) &&
Endpoint->LocalAddress != NULL ) {
if( ReadMemory(
(DWORD)Endpoint->LocalAddress,
address,
sizeof(address),
&result
) ) {
DumpTransportAddress(
" ",
(PTRANSPORT_ADDRESS)address,
(DWORD)Endpoint->LocalAddress
);
}
}
dprintf(
" Context = %08lx\n",
Endpoint->Context
);
dprintf(
" ContextLength = %08lx\n",
Endpoint->ContextLength
);
dprintf(
" OwningProcess = %08lx\n",
Endpoint->OwningProcess
);
dprintf(
" ConnectDataBuffers = %08lx\n",
Endpoint->ConnectDataBuffers
);
dprintf(
" TransmitIrp = %08lx\n",
Endpoint->TransmitIrp
);
dprintf(
" TransmitInfo = %08lx\n",
Endpoint->TransmitInfo
);
dprintf(
" AddressDeviceObject = %08lx\n",
Endpoint->AddressDeviceObject
);
dprintf(
" ConnectOutstanding = %s\n",
BooleanToString( Endpoint->ConnectOutstanding )
);
dprintf(
" SendDisconnected = %s\n",
BooleanToString( Endpoint->SendDisconnected )
);
dprintf(
" EndpointCleanedUp = %s\n",
BooleanToString( Endpoint->EndpointCleanedUp )
);
dprintf(
" TdiMessageMode = %s\n",
BooleanToString( Endpoint->TdiMessageMode )
);
#if !defined(NT351)
dprintf(
" EventObject = %08lx\n",
Endpoint->EventObject
);
dprintf(
" EventsEnabled = %08lx\n",
Endpoint->EventsEnabled
);
dprintf(
" EventsDisabled = %08lx\n",
Endpoint->EventsDisabled
);
dprintf(
" EventsActive = %08lx\n",
Endpoint->EventsActive
);
dprintf(
" EventStatus = %08lx\n",
ACTUAL_ADDRESS( ActualAddress, Endpoint, EventStatus[0] )
);
dprintf(
" GroupID = %08lx\n",
Endpoint->GroupID
);
dprintf(
" GroupType = %s\n",
GroupTypeToString( Endpoint->GroupType )
);
#endif
if( IsCheckedAfd ) {
dprintf(
" ReferenceDebug = %08lx\n",
Endpoint->ReferenceDebug
);
dprintf(
" CurrentReferenceSlot = %lu\n",
Endpoint->CurrentReferenceSlot % MAX_REFERENCE
);
}
dprintf( "\n" );
} // DumpAfdEndpoint
VOID
DumpAfdConnection(
PAFD_CONNECTION Connection,
DWORD 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.
--*/
{
UCHAR address[MAX_TRANSPORT_ADDR];
ULONG result;
dprintf(
"AFD_CONNECTION @ %08lx:\n",
ActualAddress
);
dprintf(
" Type = %04X (%s)\n",
Connection->Type,
StructureTypeToString( Connection->Type )
);
dprintf(
" ReferenceCount = %d\n",
Connection->ReferenceCount
);
dprintf(
" State = %08X (%s)\n",
Connection->State,
ConnectionStateToString( Connection->State )
);
dprintf(
" Handle = %08lx\n",
Connection->Handle
);
dprintf(
" FileObject = %08lx\n",
Connection->FileObject
);
dprintf(
" ConnectTime = %s\n",
SystemTimeToString( Connection->ConnectTime )
);
if( Connection->TdiBufferring )
{
dprintf(
" ReceiveBytesIndicated = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveBytesIndicated.QuadPart )
);
dprintf(
" ReceiveBytesTaken = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveBytesTaken.QuadPart )
);
dprintf(
" ReceiveBytesOutstanding = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveBytesOutstanding.QuadPart )
);
dprintf(
" ReceiveExpeditedBytesIndicated = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveExpeditedBytesIndicated.QuadPart )
);
dprintf(
" ReceiveExpeditedBytesTaken = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveExpeditedBytesTaken.QuadPart )
);
dprintf(
" ReceiveExpeditedBytesOutstanding = %s\n",
LongLongToString( Connection->Common.Bufferring.ReceiveExpeditedBytesOutstanding.QuadPart )
);
dprintf(
" NonBlockingSendPossible = %s\n",
BooleanToString( Connection->Common.Bufferring.NonBlockingSendPossible )
);
dprintf(
" ZeroByteReceiveIndicated = %s\n",
BooleanToString( Connection->Common.Bufferring.ZeroByteReceiveIndicated )
);
}
else
{
if( IS_LIST_EMPTY(
ActualAddress,
Connection,
Common.NonBufferring.ReceiveIrpListHead ) ) {
dprintf(
" ReceiveIrpListHead = EMPTY\n"
);
} else {
dprintf(
" ReceiveIrpListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Connection,
Common.NonBufferring.ReceiveIrpListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Connection,
Common.NonBufferring.ReceiveBufferListHead ) ) {
dprintf(
" ReceiveBufferListHead = EMPTY\n"
);
} else {
dprintf(
" ReceiveBufferListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Connection,
Common.NonBufferring.ReceiveBufferListHead
)
);
}
if( IS_LIST_EMPTY(
ActualAddress,
Connection,
Common.NonBufferring.SendIrpListHead ) ) {
dprintf(
" SendIrpListHead = EMPTY\n"
);
} else {
dprintf(
" SendIrpListHead @ %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Connection,
Common.NonBufferring.SendIrpListHead
)
);
}
dprintf(
" BufferredReceiveBytes = %lu\n",
Connection->Common.NonBufferring.BufferredReceiveBytes
);
dprintf(
" BufferredExpeditedBytes = %lu\n",
Connection->Common.NonBufferring.BufferredExpeditedBytes
);
dprintf(
" BufferredReceiveCount = %u\n",
Connection->Common.NonBufferring.BufferredReceiveCount
);
dprintf(
" BufferredExpeditedCount = %u\n",
Connection->Common.NonBufferring.BufferredExpeditedCount
);
dprintf(
" ReceiveBytesInTransport = %lu\n",
Connection->Common.NonBufferring.ReceiveBytesInTransport
);
dprintf(
" BufferredSendBytes = %lu\n",
Connection->Common.NonBufferring.BufferredSendBytes
);
dprintf(
" ReceiveCountInTransport = %u\n",
Connection->Common.NonBufferring.ReceiveCountInTransport
);
dprintf(
" BufferredSendCount = %u\n",
Connection->Common.NonBufferring.BufferredSendCount
);
dprintf(
" DisconnectIrp = %08lx\n",
Connection->Common.NonBufferring.DisconnectIrp
);
}
dprintf(
" Endpoint = %08lx\n",
Connection->Endpoint
);
dprintf(
" MaxBufferredReceiveBytes = %lu\n",
Connection->MaxBufferredReceiveBytes
);
dprintf(
" MaxBufferredSendBytes = %lu\n",
Connection->MaxBufferredSendBytes
);
dprintf(
" MaxBufferredReceiveCount = %u\n",
Connection->MaxBufferredReceiveCount
);
dprintf(
" MaxBufferredSendCount = %u\n",
Connection->MaxBufferredSendCount
);
dprintf(
" ConnectDataBuffers = %08lx\n",
Connection->ConnectDataBuffers
);
dprintf(
" OwningProcess = %08lx\n",
Connection->OwningProcess
);
dprintf(
" DeviceObject = %08lx\n",
Connection->DeviceObject
);
dprintf(
" RemoteAddress = %08lx\n",
Connection->RemoteAddress
);
dprintf(
" RemoteAddressLength = %lu\n",
Connection->RemoteAddressLength
);
if( Connection->RemoteAddressLength <= sizeof(address) &&
Connection->RemoteAddress != NULL ) {
if( ReadMemory(
(DWORD)Connection->RemoteAddress,
address,
sizeof(address),
&result
) ) {
DumpTransportAddress(
" ",
(PTRANSPORT_ADDRESS)address,
(DWORD)Connection->RemoteAddress
);
}
}
dprintf(
" DisconnectIndicated = %s\n",
BooleanToString( Connection->DisconnectIndicated )
);
dprintf(
" AbortIndicated = %s\n",
BooleanToString( Connection->AbortIndicated )
);
dprintf(
" TdiBufferring = %s\n",
BooleanToString( Connection->TdiBufferring )
);
dprintf(
" ConnectedReferenceAdded = %s\n",
BooleanToString( Connection->ConnectedReferenceAdded )
);
dprintf(
" SpecialCondition = %s\n",
BooleanToString( Connection->SpecialCondition )
);
dprintf(
" CleanupBegun = %s\n",
BooleanToString( Connection->CleanupBegun )
);
dprintf(
" ClosePendedTransmit = %s\n",
BooleanToString( Connection->ClosePendedTransmit )
);
if( IsCheckedAfd ) {
dprintf(
" CurrentReferenceSlot = %lu\n",
Connection->CurrentReferenceSlot % MAX_REFERENCE
);
dprintf(
" ReferenceDebug = %08lx\n",
ACTUAL_ADDRESS(
ActualAddress,
Connection,
ReferenceDebug
)
);
}
dprintf( "\n" );
} // DumpAfdConnection
VOID
DumpAfdConnectionReferenceDebug(
PAFD_REFERENCE_DEBUG ReferenceDebug,
DWORD ActualAddress
)
/*++
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;
LPSTR fileName;
CHAR filePath[MAX_PATH];
CHAR action[16];
dprintf(
"AFD_REFERENCE_DEBUG @ %08lx\n",
ActualAddress
);
for( i = 0 ; i < MAX_REFERENCE ; i++, ReferenceDebug++ ) {
if( CheckControlC() ) {
break;
}
if( ReferenceDebug->Info1 == NULL &&
ReferenceDebug->Info2 == NULL &&
ReferenceDebug->Action == 0 &&
ReferenceDebug->NewCount == 0 ) {
break;
}
if( ReferenceDebug->Action == 0 ||
ReferenceDebug->Action == 1 ||
ReferenceDebug->Action == (ULONG)-1L ) {
sprintf(
action,
"%ld",
ReferenceDebug->Action
);
} else {
sprintf(
action,
"%08lx",
ReferenceDebug->Action
);
}
switch( (DWORD)ReferenceDebug->Info1 ) {
case 0xafdafd02 :
dprintf(
" %3lu: Buffered Send, IRP @ %08lx [%s] -> %lu\n",
i,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafdafd03 :
dprintf(
" %3lu: Nonbuffered Send, IRP @ %08lx [%s] -> %lu\n",
i,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafd11100 :
case 0xafd11101 :
dprintf(
" %3lu: AfdRestartSend (%08lx), IRP @ %08lx [%s] -> %lu\n",
i,
ReferenceDebug->Info1,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafd11102 :
case 0xafd11103 :
case 0xafd11104 :
case 0xafd11105 :
dprintf(
" %3lu: AfdRestartBufferSend (%08lx), IRP @ %08lx [%s] -> %lu\n",
i,
ReferenceDebug->Info1,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0 :
if( ReferenceDebug->Info2 == NULL ) {
dprintf(
" %3lu: AfdDeleteConnectedReference (%08lx)\n",
i,
ReferenceDebug->Action
);
break;
} else {
//
// Fall through to default case.
//
}
default :
if( ReadMemory(
(DWORD)ReferenceDebug->Info1,
filePath,
sizeof(filePath),
&result
) ) {
fileName = strrchr( filePath, '\\' );
if( fileName != NULL ) {
fileName++;
} else {
fileName = filePath;
}
} else {
sprintf(
filePath,
"%08lx",
ReferenceDebug->Info1
);
fileName = filePath;
}
dprintf(
" %3lu: %s:%lu [%s] -> %lu\n",
i,
fileName,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
}
}
} // DumpAfdConnectionReferenceDebug
VOID
DumpAfdEndpointReferenceDebug(
PAFD_REFERENCE_DEBUG ReferenceDebug,
DWORD ActualAddress
)
/*++
Routine Description:
Dumps the AFD_REFERENCE_DEBUG structures associated with an
AFD_ENDPOINT 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;
LPSTR fileName;
CHAR filePath[MAX_PATH];
CHAR action[16];
dprintf(
"AFD_REFERENCE_DEBUG @ %08lx\n",
ActualAddress
);
for( i = 0 ; i < MAX_REFERENCE ; i++, ReferenceDebug++ ) {
if( CheckControlC() ) {
break;
}
if( ReferenceDebug->Info1 == NULL &&
ReferenceDebug->Info2 == NULL &&
ReferenceDebug->Action == 0 &&
ReferenceDebug->NewCount == 0 ) {
break;
}
if( ReferenceDebug->Action == 0 ||
ReferenceDebug->Action == 1 ||
ReferenceDebug->Action == (ULONG)-1L ) {
sprintf(
action,
"%ld",
ReferenceDebug->Action
);
} else {
sprintf(
action,
"%08lx",
ReferenceDebug->Action
);
}
if( ReadMemory(
(DWORD)ReferenceDebug->Info1,
filePath,
sizeof(filePath),
&result
) ) {
fileName = strrchr( filePath, '\\' );
if( fileName != NULL ) {
fileName++;
} else {
fileName = filePath;
}
} else {
sprintf(
filePath,
"%08lx",
ReferenceDebug->Info1
);
fileName = filePath;
}
dprintf(
" %3lu: %s:%lu [%s] -> %ld\n",
i,
fileName,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
}
} // DumpAfdEndpointReferenceDebug
#if GLOBAL_REFERENCE_DEBUG
BOOL
DumpAfdGlobalReferenceDebug(
PAFD_GLOBAL_REFERENCE_DEBUG ReferenceDebug,
DWORD ActualAddress,
DWORD CurrentSlot,
DWORD StartingSlot,
DWORD NumEntries,
DWORD 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 @ %08lx, 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 == (ULONG)-1L ) {
sprintf(
action,
"%ld",
ReferenceDebug->Action
);
} else {
sprintf(
action,
"%08lx",
ReferenceDebug->Action
);
}
decoration = ( StartingSlot == CurrentSlot ) ? '>' : ' ';
lowTick = ReferenceDebug->TickCounter.LowPart;
switch( (DWORD)ReferenceDebug->Info1 ) {
case 0xafdafd02 :
dprintf(
"%c %3lu: %08lx (%8lu) Buffered Send, IRP @ %08lx [%s] -> %lu\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafdafd03 :
dprintf(
"%c %3lu: %08lx (%8lu) Nonbuffered Send, IRP @ %08lx [%s] -> %lu\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafd11100 :
case 0xafd11101 :
dprintf(
"%c %3lu: %08lx (%8lu) AfdRestartSend (%08lx), IRP @ %08lx [%s] -> %lu\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
ReferenceDebug->Info1,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0xafd11102 :
case 0xafd11103 :
case 0xafd11104 :
case 0xafd11105 :
dprintf(
"%c %3lu: %08lx (%8lu) AfdRestartBufferSend (%08lx), IRP @ %08lx [%s] -> %lu\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
ReferenceDebug->Info1,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
case 0 :
if( ReferenceDebug->Info2 == NULL ) {
dprintf(
"%c %3lu: %08lx (%8lu) AfdDeleteConnectedReference (%08lx)\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
ReferenceDebug->Action
);
break;
} else {
//
// Fall through to default case.
//
}
default :
if( ReadMemory(
(DWORD)ReferenceDebug->Info1,
filePath,
sizeof(filePath),
&result
) ) {
fileName = strrchr( filePath, '\\' );
if( fileName != NULL ) {
fileName++;
} else {
fileName = filePath;
}
} else {
sprintf(
filePath,
"%08lx",
ReferenceDebug->Info1
);
fileName = filePath;
}
dprintf(
"%c %3lu: %08lx (%8lu) %s:%lu [%s] -> %lu\n",
decoration,
StartingSlot,
ReferenceDebug->Connection,
lowTick,
fileName,
ReferenceDebug->Info2,
action,
ReferenceDebug->NewCount
);
break;
}
}
return foundEnd;
} // DumpAfdGlobalReferenceDebug
#endif
VOID
DumpAfdTransmitInfo(
PAFD_TRANSMIT_FILE_INFO_INTERNAL TransmitInfo,
DWORD ActualAddress
)
{
dprintf(
"AFD_TRANSMIT_FILE_INFO_INTERNAL @ %08lx\n",
ActualAddress
);
dprintf(
" Offset = %s\n",
LongLongToString( TransmitInfo->Offset )
);
dprintf(
" FileWriteLength = %s\n",
LongLongToString( TransmitInfo->FileWriteLength )
);
dprintf(
" SendPacketLength = %08lx\n",
TransmitInfo->SendPacketLength
);
dprintf(
" FileHandle = %08lx\n",
TransmitInfo->FileHandle
);
dprintf(
" Head = %08lx\n",
TransmitInfo->Head
);
dprintf(
" HeadLength = %08lx\n",
TransmitInfo->HeadLength
);
dprintf(
" Tail = %08lx\n",
TransmitInfo->Tail
);
dprintf(
" TailLength = %08lx\n",
TransmitInfo->TailLength
);
dprintf(
" Flags = %08lx\n",
TransmitInfo->Flags
);
dprintf(
" _Dummy = %08lx\n",
TransmitInfo->_Dummy
);
dprintf(
" TotalBytesToSend = %s\n",
LongLongToString( TransmitInfo->TotalBytesToSend )
);
dprintf(
" BytesRead = %s\n",
LongLongToString( TransmitInfo->BytesRead )
);
dprintf(
" BytesSent = %s\n",
LongLongToString( TransmitInfo->BytesSent )
);
dprintf(
" FileObject = %08lx\n",
TransmitInfo->FileObject
);
dprintf(
" DeviceObject = %08lx\n",
TransmitInfo->DeviceObject
);
dprintf(
" TdiFileObject = %08lx\n",
TransmitInfo->TdiFileObject
);
dprintf(
" TdiDeviceObject = %08lx\n",
TransmitInfo->TdiDeviceObject
);
dprintf(
" TransmitIrp = %08lx\n",
TransmitInfo->TransmitIrp
);
dprintf(
" Endpoint = %08lx\n",
TransmitInfo->Endpoint
);
dprintf(
" FileMdl = %08lx\n",
TransmitInfo->FileMdl
);
dprintf(
" HeadMdl = %08lx\n",
TransmitInfo->HeadMdl
);
dprintf(
" TailMdl = %08lx\n",
TransmitInfo->TailMdl
);
dprintf(
" FirstFileMdlAfterHead = %08lx\n",
TransmitInfo->FirstFileMdlAfterHead
);
dprintf(
" LastFileMdlBeforeTail = %08lx\n",
TransmitInfo->LastFileMdlBeforeTail
);
dprintf(
" IrpUsedTOSendTail = %08lx\n",
TransmitInfo->IrpUsedToSendTail
);
dprintf(
" FileMdlLength = %08lx\n",
TransmitInfo->FileMdlLength
);
dprintf(
" ReadPending = %s\n",
BooleanToString( TransmitInfo->ReadPending )
);
dprintf(
" CompletionPending = %s\n",
BooleanToString( TransmitInfo->CompletionPending )
);
dprintf(
" NeedToSendHead = %s\n",
BooleanToString( TransmitInfo->NeedToSendHead )
);
dprintf(
" Queued = %s\n",
BooleanToString( TransmitInfo->Queued )
);
dprintf(
" Read.Irp = %08lx%s\n",
TransmitInfo->Read.Irp,
IsTransmitIrpBusy( TransmitInfo->Read.Irp )
? " (BUSY)"
: ""
);
dprintf(
" Read.AfdBuffer = %08lx\n",
TransmitInfo->Read.AfdBuffer
);
dprintf(
" Read.Length = %08lx\n",
TransmitInfo->Read.Length
);
dprintf(
" Send1.Irp = %08lx%s\n",
TransmitInfo->Send1.Irp,
IsTransmitIrpBusy( TransmitInfo->Send1.Irp )
? " (BUSY)"
: ""
);
dprintf(
" Send1.AfdBuffer = %08lx\n",
TransmitInfo->Send1.AfdBuffer
);
dprintf(
" Send1.Length = %08lx\n",
TransmitInfo->Send1.Length
);
dprintf(
" Send2.Irp = %08lx%s\n",
TransmitInfo->Send2.Irp,
IsTransmitIrpBusy( TransmitInfo->Send2.Irp )
? " (BUSY)"
: ""
);
dprintf(
" Send2.AfdBuffer = %08lx\n",
TransmitInfo->Send2.AfdBuffer
);
dprintf(
" Send2.Length = %08lx\n",
TransmitInfo->Send2.Length
);
dprintf( "\n" );
} // DumpAfdTransmitInfo
VOID
DumpAfdBuffer(
PAFD_BUFFER Buffer,
DWORD ActualAddress
)
{
dprintf(
"AFD_BUFFER @ %08lx\n",
ActualAddress
);
dprintf(
" BufferListHead = %08lx\n",
Buffer->BufferListHead
);
dprintf(
" NextBuffer = %08lx\n",
Buffer->NextBuffer
);
dprintf(
" Buffer = %08lx\n",
Buffer->Buffer
);
dprintf(
" BufferLength = %08lx\n",
Buffer->BufferLength
);
dprintf(
" DataLength = %08lx\n",
Buffer->DataLength
);
dprintf(
" DataOffset = %08lx\n",
Buffer->DataOffset
);
dprintf(
" Irp = %08lx\n",
Buffer->Irp
);
dprintf(
" Mdl = %08lx\n",
Buffer->Mdl
);
dprintf(
" Context = %08lx\n",
Buffer->Context
);
dprintf(
" SourceAddress = %08lx\n",
Buffer->SourceAddress
);
dprintf(
" SourceAddressLength = %08lx\n",
Buffer->SourceAddressLength
);
dprintf(
" FileObject = %08lx\n",
Buffer->FileObject
);
dprintf(
" AllocatedAddressLength = %04X\n",
Buffer->AllocatedAddressLength
);
dprintf(
" ExpeditedData = %s\n",
BooleanToString( Buffer->ExpeditedData )
);
dprintf(
" PartialMessage = %s\n",
BooleanToString( Buffer->PartialMessage )
);
#if DBG
if( IsCheckedAfd ) {
dprintf(
" TotalChainLength = %08lx\n",
Buffer->TotalChainLength
);
}
#endif
dprintf( "\n" );
} // DumpAfdBuffer
//
// 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";
#if !defined(NT351)
case AfdBlockTypeHelper :
return "Helper";
#endif
}
return "INVALID";
} // 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 AfdEndpointStateListening :
return "Listening";
case AfdEndpointStateConnected :
return "Connected";
case AfdEndpointStateCleanup :
return "Cleanup";
case AfdEndpointStateClosing :
return "Closing";
case AfdEndpointStateTransmitClosing :
return "Transmit Closing";
#if !defined(NT351)
case AfdEndpointStateInvalid :
return "Invalid";
#endif
}
return "INVALID";
} // EndpointStateToString
PSTR
EndpointTypeToString(
AFD_ENDPOINT_TYPE Type
)
/*++
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( Type ) {
case AfdEndpointTypeStream :
return "Stream";
case AfdEndpointTypeDatagram :
return "Datagram";
case AfdEndpointTypeRaw :
return "Raw";
case AfdEndpointTypeSequencedPacket :
return "SequencedPacket";
case AfdEndpointTypeReliableMessage :
return "ReliableMessage";
case AfdEndpointTypeUnknown :
return "Unknown";
}
return "INVALID";
} // 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
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) ) {
return LongLongToString( Value );
}
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
BOOL
IsTransmitIrpBusy(
PIRP Irp
)
{
IRP localIrp;
ULONG result;
if( Irp == NULL ) {
return FALSE;
}
if( !ReadMemory(
(DWORD)Irp,
&localIrp,
sizeof(localIrp),
&result
) ) {
return FALSE;
}
return localIrp.UserIosb != 0;
} // IsTransmitIrpBusy
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