/*++ Copyright (c) 1993 Microsoft Corporation Module Name: kdexts.c Abstract: This file contains the generic routines and initialization code for the kernel debugger extensions dll. Author: Wesley Witt (wesw) 26-Aug-1993 Environment: User Mode --*/ #include "afdkdp.h" #pragma hdrstop #include #include // // globals // EXT_API_VERSION ApiVersion = { VER_PRODUCTVERSION_W >> 8, VER_PRODUCTVERSION_W & 0xFF, EXT_API_VERSION_NUMBER64, 0 }; WINDBG_EXTENSION_APIS ExtensionApis; ULONG64 STeip; ULONG64 STebp; ULONG64 STesp; USHORT SavedMajorVersion; USHORT SavedMinorVersion; LIST_ENTRY TransportInfoList; BOOL IsCheckedAfd; BOOL IsReferenceDebug; ULONG64 UserProbeAddress; ULONG TicksToMs, TickCount; ULONG AfdBufferOverhead; ULONG AfdStandardAddressLength; ULONG AfdBufferTagSize; LARGE_INTEGER SystemTime, InterruptTime; ULONG DatagramBufferListOffset, DatagramRecvListOffset, DatagramPeekListOffset, RoutingNotifyListOffset, RequestListOffset, EventStatusOffset, ConnectionBufferListOffset, ConnectionSendListOffset, ConnectionRecvListOffset, UnacceptedConnListOffset, ReturnedConnListOffset, ListenConnListOffset, FreeConnListOffset, PreaccConnListOffset, ListenIrpListOffset, PollEndpointInfoOffset, DriverContextOffset, SendIrpArrayOffset, FsContextOffset; ULONG EndpointLinkOffset, ConnectionLinkOffset, BufferLinkOffset, AddressEntryLinkOffset, TransportInfoLinkOffset, AddressEntryAddressOffset; ULONG ConnRefOffset, EndpRefOffset, TPackRefOffset; ULONG RefDebugSize; KDDEBUGGER_DATA64 DebuggerData; ULONG AfdResult, NtResult; BOOLEAN GlobalsRead; DllInit( HANDLE hModule, DWORD dwReason, DWORD dwReserved ) { switch (dwReason) { case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: while (!IsListEmpty (&TransportInfoList)) { PLIST_ENTRY listEntry; PAFDKD_TRANSPORT_INFO transportInfo; listEntry = RemoveHeadList (&TransportInfoList); transportInfo = CONTAINING_RECORD (listEntry, AFDKD_TRANSPORT_INFO, Link); RtlFreeHeap (RtlProcessHeap (), 0, transportInfo); } break; case DLL_PROCESS_ATTACH: InitializeListHead (&TransportInfoList); GlobalsRead = FALSE; NtResult = 0; AfdResult = 0; break; } return TRUE; } ULONG ReadTimeInfo ( VOID ) { ULONG result; if ((result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "TickCountLow", TickCount))!=0 || (result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "TickCountMultiplier", TicksToMs))!=0 || (result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "InterruptTime.High1Time", InterruptTime.HighPart))!=0 || (result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "InterruptTime.LowPart", InterruptTime.LowPart))!=0 || (result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "SystemTime.High1Time", SystemTime.HighPart))!=0 || (result=GetFieldValue(MM_SHARED_USER_DATA_VA, "NT!_KUSER_SHARED_DATA", "SystemTime.LowPart", SystemTime.LowPart))!=0 ) { } return result; } VOID ReadGlobals ( VOID ) { ULONG result; ULONG64 val; INT i; struct { LPSTR Type; LPSTR Field; PULONG pOffset; } MainOffsets[] = { {"AFD!AFD_ENDPOINT", "Common.Datagram.ReceiveBufferListHead",&DatagramBufferListOffset }, {"AFD!AFD_ENDPOINT", "Common.Datagram.ReceiveIrpListHead", &DatagramRecvListOffset }, {"AFD!AFD_ENDPOINT", "Common.Datagram.PeekIrpListHead", &DatagramPeekListOffset }, {"AFD!AFD_ENDPOINT", "RoutingNotifications", &RoutingNotifyListOffset }, {"AFD!AFD_ENDPOINT", "RequestList", &RequestListOffset }, {"AFD!AFD_ENDPOINT", "EventStatus", &EventStatusOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.UnacceptedConnectionListHead", &UnacceptedConnListOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.ReturnedConnectionListHead", &ReturnedConnListOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.ListenConnectionListHead", &ListenConnListOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.FreeConnectionListHead", &FreeConnListOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.PreacceptedConnectionsListHead", &PreaccConnListOffset }, {"AFD!AFD_ENDPOINT", "Common.VirtualCircuit.Listening.ListeningIrpListHead", &ListenIrpListOffset }, {"AFD!AFD_ENDPOINT", "GlobalEndpointListEntry", &EndpointLinkOffset }, {"AFD!AFD_CONNECTION", "Common.NonBufferring.ReceiveBufferListHead", &ConnectionBufferListOffset }, {"AFD!AFD_CONNECTION", "Common.NonBufferring.SendIrpListHead", &ConnectionSendListOffset }, {"AFD!AFD_CONNECTION", "Common.NonBufferring.ReceiveIrpListHead", &ConnectionRecvListOffset }, {"AFD!AFD_CONNECTION", "ListEntry", &ConnectionLinkOffset }, {"AFD!AFD_POLL_INFO_INTERNAL","EndpointInfo", &PollEndpointInfoOffset }, {"AFD!AFD_TPACKETS_INFO_INTERNAL","SendIrp", &SendIrpArrayOffset }, {"AFD!AFD_ADDRESS_ENTRY","Address", &AddressEntryAddressOffset }, {"AFD!AFD_ADDRESS_ENTRY","AddressListLink", &AddressEntryLinkOffset }, {"AFD!AFD_BUFFER_HEADER","BufferListEntry", &BufferLinkOffset }, {"AFD!AFD_TRANSPORT_INFO","TransportInfoListEntry", &TransportInfoLinkOffset }, {"NT!_FILE_OBJECT", "FsContext", &FsContextOffset }, {"NT!_IRP", "Tail.Overlay.DriverContext", &DriverContextOffset } }; struct { LPSTR Type; LPSTR Field; PULONG pOffset; } RefOffsets[] = { {"AFD!AFD_ENDPOINT", "ReferenceDebug", &EndpRefOffset }, {"AFD!AFD_CONNECTION", "ReferenceDebug", &ConnRefOffset }, {"AFD!AFD_TPACKETS_INFO_INTERNAL","ReferenceDebug", &TPackRefOffset } }; // // Try to get a pointer to afd!AfdDebug. If we can, then we know // the target machine is running a checked AFD.SYS. // IsCheckedAfd = ( GetExpression( "AFD!AfdDebug" ) != 0 ); IsReferenceDebug = ( GetExpression( "AFD!AfdReferenceEndpoint" ) != 0 ); if (GetDebuggerData (KDBG_TAG, &DebuggerData, sizeof (DebuggerData))) { result = ReadPtr (DebuggerData.MmUserProbeAddress, &UserProbeAddress); if (result!=0) { if (result!=NtResult) { dprintf ("\nReadGlobals: could not read nt!MmUserProbeAddress, err: %ld\n"); NtResult = result; } } } else { dprintf ("\nReadGlobals: Could not get KDDEBUGGER_DATA64\n"); NtResult = 1; } result = ReadTimeInfo (); if (result!=0) { if (result!=AfdResult) { dprintf("\nReadGlobals: Could not read time info from USER_SHARED_DATA, err: %ld\n", result); AfdResult = result; } } result = GetFieldValue (0, "AFD!AfdBufferOverhead", NULL, val); if (result!=0) { if (result!=AfdResult) { dprintf("\nReadGlobals: Could not read afd!AfdBufferOverhead, err: %ld\n", result); AfdResult = result; } } AfdBufferOverhead = (ULONG)val; result = GetFieldValue (0, "AFD!AfdStandardAddressLength", NULL, val); if (result!=0) { if (result!=AfdResult) { dprintf("\nReadGlobals: Could not read AFD!AfdStandardAddressLength, err: %ld\n", result); AfdResult = result; } } AfdStandardAddressLength = (ULONG)val; AfdBufferTagSize = GetTypeSize ("AFD!AFD_BUFFER_TAG"); if (AfdBufferTagSize==0) { if (result!=AfdResult) { dprintf ("\nReadGlobals: Could not get sizeof (AFD_BUFFER_TAG)\n"); AfdResult = result; } } for (i=0; i