windows-nt/Source/XPSP1/NT/net/atm/lane/kdext/kdlane.c
2020-09-26 16:20:57 +08:00

481 lines
11 KiB
C

#include <windows.h>
#include <wtypes.h>
#include <wdbgexts.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ntverp.h>
#include "tracelog.h"
#include "event.h"
void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry);
void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry);
EXT_API_VERSION ApiVersion = { 4, 0, EXT_API_VERSION_NUMBER, 0 };
WINDBG_EXTENSION_APIS ExtensionApis;
USHORT SavedMajorVersion;
USHORT SavedMinorVersion;
// ======================================================================
#define MAXREAD 3500
BOOL ReadMemoryEx(ULONG_PTR From, ULONG_PTR To, ULONG Size, PULONG OutBytesRead)
{
ULONG BytesRead;
ULONG TotalBytesRead = 0;
BOOL success;
// dprintf("ReadMemoryEx: reading %08x bytes from %08x to %08x\n", Size, From, To);
while (Size)
{
if (CheckControlC())
return 0;
if (Size > MAXREAD)
{
// dprintf("(reading %08x bytes from %08x to %08x)\n", MAXREAD, From, To);
success = ReadMemory((ULONG_PTR)From, (PVOID)To, MAXREAD, &BytesRead);
if (!success)
{
dprintf("Problem reading memory at %x for %x bytes\n", From, MAXREAD);
break;
}
TotalBytesRead += BytesRead;
}
else
{
// dprintf("(reading %08x bytes from %08x to %08x)\n", Size, From, To);
success = ReadMemory((ULONG_PTR)From, (PVOID)To, Size, &BytesRead);
if (!success)
{
dprintf("Problem reading memory at %x for %x bytes\n", From, Size);
break;
}
TotalBytesRead += BytesRead;
}
if (Size > MAXREAD)
{
Size -= MAXREAD;
From += MAXREAD;
To += MAXREAD;
}
else
Size = 0;
}
*OutBytesRead = TotalBytesRead;
return success;
}
// ======================================================================
ULONG_PTR GetTraceLogAddress(VOID)
{
ULONG_PTR TargetTraceLog;
PUCHAR symbol = "ATMLANE!TraceLog";
TargetTraceLog = (ULONG_PTR)GetExpression(symbol);
if ( !TargetTraceLog )
{
dprintf("Unable to resolve symbol \"%s\". Try .reload cmd.\n", symbol);
return 0;
}
return TargetTraceLog;
}
// ======================================================================
DllInit(
HANDLE hModule,
DWORD dwReason,
DWORD dwReserved
)
{
switch (dwReason) {
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
// ======================================================================
VOID
WinDbgExtensionDllInit(
PWINDBG_EXTENSION_APIS lpExtensionApis,
USHORT MajorVersion,
USHORT MinorVersion
)
{
ExtensionApis = *lpExtensionApis;
SavedMajorVersion = MajorVersion;
SavedMinorVersion = MinorVersion;
return;
}
// ======================================================================
DECLARE_API( version )
{
#if DBG
PCHAR DebuggerType = "Checked";
#else
PCHAR DebuggerType = "Free";
#endif
dprintf("%s Extension dll for Build %d debugging %s kernel for Build %d\n",
DebuggerType,
VER_PRODUCTBUILD,
SavedMajorVersion == 0x0c ? "Checked" : "Free",
SavedMinorVersion
);
}
// ======================================================================
VOID
CheckVersion(
VOID
)
{
#if DBG
if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
}
#else
if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
}
#endif
}
// ======================================================================
LPEXT_API_VERSION
ExtensionApiVersion(
VOID
)
{
return &ApiVersion;
}
// ======================================================================
DECLARE_API(dumplog)
{
ULONG_PTR TargetTraceLogAddress;
TRACELOG TargetTraceLog;
TRACELOG LocalTraceLog;
PUCHAR LocalLogStorage;
PTRACEENTRY TraceEntry;
PUCHAR CurString, NullPos;
UCHAR SaveChar;
ULONG LogLength;
ULONG bytesread, firstsize;
char * indexstr, *filenamestr;
ULONG index;
FILE * outfile;
filenamestr = strtok((char *)args, " ");
if (filenamestr == NULL)
{
dprintf("usage: dumplog <filename>\n");
return;
}
TargetTraceLogAddress = GetTraceLogAddress();
if (!TargetTraceLogAddress)
return;
// read trace log struct out of target's memory
if (!ReadMemoryEx( (ULONG_PTR)TargetTraceLogAddress, (ULONG_PTR)&TargetTraceLog,
sizeof(TRACELOG), &bytesread))
return;
#if 1
// display trace log vars
dprintf("TraceLog\n");
dprintf("\tStorage = 0x%08x\n", TargetTraceLog.Storage);
dprintf("\tSize = 0x%08x\n", TargetTraceLog.StorageSizeBytes);
dprintf("\tFirst = 0x%08x\n", TargetTraceLog.First);
dprintf("\tLast = 0x%08x\n", TargetTraceLog.Last);
dprintf("\tCurrent = 0x%08x\n", TargetTraceLog.Current);
#endif
// see if logging enabled (i.e. log has storage allocated
if (TargetTraceLog.Storage == NULL)
{
dprintf("Trace Log is disabled\n");
return;
}
// alloc local memory for log
LocalLogStorage = (PUCHAR) malloc(TargetTraceLog.StorageSizeBytes);
if (LocalLogStorage == NULL)
{
dprintf("can't alloc %d bytes for local storage\n",
TargetTraceLog.StorageSizeBytes);
return;
}
// open the output file
outfile = fopen(filenamestr, "wt");
if (outfile == NULL)
{
dprintf("open of file '%s' failed, errno = %d\n", filenamestr, errno);
free(LocalLogStorage);
return;
}
// read the log out of target's memory
dprintf("reading log from target system, please wait...\n");
if (!ReadMemoryEx((ULONG_PTR)TargetTraceLog.Storage, (ULONG_PTR)LocalLogStorage,
TargetTraceLog.StorageSizeBytes, &bytesread))
{
fclose(outfile);
free(LocalLogStorage);
return;
}
// convert addresses to local trace log
LocalTraceLog.Storage = LocalLogStorage;
LocalTraceLog.First = (PTRACEENTRY) LocalTraceLog.Storage;
LocalTraceLog.Last = LocalTraceLog.First +
(TargetTraceLog.Last - TargetTraceLog.First);
LocalTraceLog.Current = LocalTraceLog.First +
(TargetTraceLog.Current - TargetTraceLog.First);
// loop thru the trace log printing out the values
TraceEntry = LocalTraceLog.Current - 1;
dprintf("writing formatted log to file...\n");
for (;;)
{
if (TraceEntry < LocalTraceLog.First)
TraceEntry = LocalTraceLog.Last;
if (TraceEntry->EventId == 0 || TraceEntry == LocalTraceLog.Current)
{
dprintf("done.\n");
break;
}
PrintTraceLogEntry(outfile, TraceEntry);
TraceEntry--;
if (CheckControlC())
{
dprintf("Aborted before end of log.\n");
break;
}
}
// cleanup
fclose(outfile);
free(LocalLogStorage);
}
// ======================================================================
DECLARE_API( help )
{
dprintf("ATMLANE driver kd extensions\n\n");
dprintf("\tdumplog <filename> - dumps & formats tracelog buffer to file\n");
}
// ======================================================================
void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry)
{
ULONG params, i;
switch (TraceEntry->EventId)
{
case TL_MSENDPKTIN:
fprintf(outfile, "[% 10u] MSENDPKTIN: PktCnt %d\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_MSENDPKTBEGIN:
fprintf(outfile, "[% 10u] MSENDPKTBEGIN: Index %d Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1]
);
break;
case TL_MSENDPKTEND:
fprintf(outfile, "[% 10u] MSENDPKTEND: Index %d Pkt %x Status %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2]
);
break;
case TL_MSENDPKTOUT:
fprintf(outfile, "[% 10u] MSENDPKTOUT\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_MSENDCOMPL:
fprintf(outfile, "[% 10u] MSENDCOMPL: Pkt %x Status %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1]
);
break;
case TL_WRAPSEND:
fprintf(outfile, "[% 10u] WRAPSEND: From %x To %x Bcnt %d Len %d\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2],
TraceEntry->Params[3]
);
break;
case TL_UNWRAPSEND:
fprintf(outfile, "[% 10u] UNWRAPSEND: From %x To %x Bcnt %d Len %d\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2],
TraceEntry->Params[3]
);
break;
case TL_WRAPRECV:
fprintf(outfile, "[% 10u] WRAPRECV: From %x To %x Bcnt %d Len %d\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2],
TraceEntry->Params[3]
);
break;
case TL_UNWRAPRECV:
fprintf(outfile, "[% 10u] UNWRAPRECV: From %x To %x Bcnt %d Len %d\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2],
TraceEntry->Params[3]
);
break;
case TL_COSENDPACKET:
fprintf(outfile, "[% 10u] COSENDPKT: Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_COSENDCMPLTIN:
fprintf(outfile, "[% 10u] COSENDCMPLTIN: Pkt %x Status %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1]
);
break;
case TL_COSENDCMPLTOUT:
fprintf(outfile, "[% 10u] COSENDCMPLTOUT: Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_CORECVPACKET:
fprintf(outfile, "[% 10u] CORECVPKT: Pkt %x Vc %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1]
);
break;
case TL_CORETNPACKET:
fprintf(outfile, "[% 10u] CORETNPKT: Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_MINDPACKET:
fprintf(outfile, "[% 10u] MINDPKT: Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_MRETNPACKET:
fprintf(outfile, "[% 10u] MRETNPKT: Pkt %x\n",
TraceEntry->Time,
TraceEntry->Params[0]
);
break;
case TL_NDISPACKET:
fprintf(outfile, "[% 10u] NDISPKT: %x Cnt %d Len %d Bufs %x %x %x %x %x\n",
TraceEntry->Time,
TraceEntry->Params[0],
TraceEntry->Params[1],
TraceEntry->Params[2],
TraceEntry->Params[3],
TraceEntry->Params[4],
TraceEntry->Params[5],
TraceEntry->Params[6],
TraceEntry->Params[7]
);
break;
default:
params = TL_GET_PARAM_COUNT(TraceEntry->EventId);
fprintf(outfile, "****: Unknown Event ID %d with %d Params: ",
TL_GET_EVENT(TraceEntry->EventId), params);
for (i = 0; i < params; i++)
fprintf(outfile, "%x ", TraceEntry->Params[i]);
fprintf(outfile, "\n");
break;
}
}
// ======================================================================