826 lines
24 KiB
C
826 lines
24 KiB
C
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vwdebug.c
|
|
|
|
Abstract:
|
|
|
|
Contains debug routines for VWIPXSPX.DLL
|
|
|
|
Contents:
|
|
VwDebugStart
|
|
VwDebugEnd
|
|
VwDebugPrint
|
|
VwDumpData
|
|
VwDumpEcb
|
|
VwDumpFragment
|
|
VwDumpPacketHeader
|
|
VwDumpXecb
|
|
VwDumpSocketInfo
|
|
VwDumpConnectionInfo
|
|
VwDumpConnectionStats
|
|
VwLog
|
|
CheckInterrupts
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 5-Oct-1993
|
|
|
|
Environment:
|
|
|
|
User-mode Win32
|
|
|
|
Revision History:
|
|
|
|
5-Oct-1993 rfirth
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include "vw.h"
|
|
#pragma hdrstop
|
|
|
|
#if DBG
|
|
|
|
//
|
|
// private prototypes
|
|
//
|
|
|
|
int PokeLevelString(LPSTR, DWORD, DWORD, LPSTR);
|
|
LPSTR StripNameFromPath(LPSTR);
|
|
|
|
//
|
|
// private data
|
|
//
|
|
|
|
DWORD VwDebugFlags = 0;
|
|
DWORD VwDebugFunctions = 0;
|
|
DWORD VwShow = SHOW_ECBS | SHOW_HEADERS;
|
|
DWORD VwDebugLevel = IPXDBG_MIN_LEVEL;
|
|
DWORD VwDebugDump = 0;
|
|
BOOL VwDebugInitialized = FALSE;
|
|
FILE* hVwDebugLog = NULL;
|
|
DWORD DebugFlagsEx = 0 ;
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
VOID VwDebugStart() {
|
|
|
|
//
|
|
// a little run-time diagnostication, madam?
|
|
//
|
|
|
|
LPSTR ptr;
|
|
|
|
if (VwDebugInitialized) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// override VwDebugFlags from VWFLAGS environment variable
|
|
//
|
|
|
|
if (ptr = getenv("VWFLAGS")) {
|
|
VwDebugFlags = (DWORD)strtoul(ptr, NULL, 0);
|
|
}
|
|
if (ptr = getenv("VWFUNCS")) {
|
|
VwDebugFunctions = (DWORD)strtoul(ptr, NULL, 0);
|
|
}
|
|
if (ptr = getenv("VWSHOW")) {
|
|
VwShow = (DWORD)strtoul(ptr, NULL, 0);
|
|
}
|
|
if (ptr = getenv("VWLEVEL")) {
|
|
VwDebugLevel = strtoul(ptr, NULL, 0);
|
|
if (VwDebugLevel > IPXDBG_MAX_LEVEL) {
|
|
VwDebugLevel = IPXDBG_MAX_LEVEL;
|
|
}
|
|
}
|
|
if (ptr = getenv("VWDUMP")) {
|
|
VwDebugDump = strtoul(ptr, NULL, 0);
|
|
}
|
|
IF_DEBUG(TO_FILE) {
|
|
if ((hVwDebugLog = fopen(VWDEBUG_FILE, "w+")) == NULL) {
|
|
VwDebugFlags &= ~DEBUG_TO_FILE;
|
|
} else {
|
|
|
|
#if 0
|
|
|
|
char currentDirectory[256];
|
|
int n;
|
|
|
|
currentDirectory[0] = 0;
|
|
if (n = GetCurrentDirectory(sizeof(currentDirectory), currentDirectory)) {
|
|
if (currentDirectory[n-1] == '\\') {
|
|
currentDirectory[n-1] = 0;
|
|
}
|
|
}
|
|
|
|
DbgPrint("VWIPXSPX: Writing debug output to %s\\" VWDEBUG_FILE "\n", currentDirectory);
|
|
#endif
|
|
|
|
}
|
|
}
|
|
VwDebugInitialized = TRUE;
|
|
}
|
|
|
|
VOID VwDebugEnd() {
|
|
IF_DEBUG(TO_FILE) {
|
|
fflush(hVwDebugLog);
|
|
fclose(hVwDebugLog);
|
|
}
|
|
}
|
|
|
|
VOID VwDebugPrint(LPSTR Module, DWORD Line, DWORD Function, DWORD Level, LPSTR Format, ...) {
|
|
|
|
char buf[1024];
|
|
va_list p;
|
|
|
|
IF_DEBUG(NOTHING) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// only log something if we are tracking this Function and Level is above
|
|
// (or equal to) the filter cut-off or Level >= minimum alert level (error)
|
|
//
|
|
|
|
if (((Function & VwDebugFunctions) && (Level >= VwDebugLevel)) || (Level >= IPXDBG_LEVEL_ERROR)) {
|
|
va_start(p, Format);
|
|
vsprintf(buf+PokeLevelString(Module, Line, Level, buf), Format, p);
|
|
VwLog(buf);
|
|
va_end(p);
|
|
}
|
|
}
|
|
|
|
int PokeLevelString(LPSTR Module, DWORD Line, DWORD Level, LPSTR Buffer) {
|
|
|
|
int length;
|
|
static char levelString[4] = " : ";
|
|
char level;
|
|
|
|
switch (Level) {
|
|
case IPXDBG_LEVEL_INFO:
|
|
level = 'I';
|
|
break;
|
|
|
|
case IPXDBG_LEVEL_WARNING:
|
|
level = 'W';
|
|
break;
|
|
|
|
case IPXDBG_LEVEL_ERROR:
|
|
level = 'E';
|
|
break;
|
|
|
|
case IPXDBG_LEVEL_FATAL:
|
|
level = 'F';
|
|
break;
|
|
}
|
|
|
|
levelString[0] = level;
|
|
strcpy(Buffer, levelString);
|
|
length = strlen(levelString);
|
|
|
|
if (Level >= IPXDBG_LEVEL_ERROR) {
|
|
length += sprintf(Buffer + length, "%s [% 5d]: ", StripNameFromPath(Module), Line);
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
LPSTR StripNameFromPath(LPSTR Path) {
|
|
|
|
LPSTR p;
|
|
|
|
p = strrchr(Path, '\\');
|
|
return p ? p+1 : Path;
|
|
}
|
|
|
|
VOID VwDumpData(ULPBYTE Address, WORD Seg, WORD Off, BOOL InVdm, WORD Size) {
|
|
|
|
char buf[128];
|
|
int i, len;
|
|
|
|
IF_NOT_DEBUG(DATA) {
|
|
return;
|
|
}
|
|
|
|
while (Size) {
|
|
len = min(Size, 16);
|
|
if (InVdm) {
|
|
sprintf(buf, "%04x:%04x ", Seg, Off);
|
|
} else {
|
|
sprintf(buf, "%p ", Address);
|
|
}
|
|
for (i = 0; i < len; ++i) {
|
|
sprintf(&buf[10+i*3], "%02.2x ", Address[i] & 0xff);
|
|
}
|
|
for (i = len; i < 17; ++i) {
|
|
strcat(buf, " ");
|
|
}
|
|
for (i = 0; i < len; ++i) {
|
|
|
|
char ch;
|
|
|
|
ch = Address[i];
|
|
buf[61+i] = ((ch < 32) || (ch > 127)) ? '.' : ch;
|
|
}
|
|
buf[61+i++] = '\n';
|
|
buf[61+i] = 0;
|
|
VwLog(buf);
|
|
Address += len;
|
|
Size -= (WORD)len;
|
|
Off += (WORD)len;
|
|
}
|
|
VwLog("\n");
|
|
}
|
|
|
|
VOID VwDumpEcb(LPECB pEcb, WORD Seg, WORD Off, BYTE Type, BOOL Frags, BOOL Data, BOOL Mode) {
|
|
|
|
char buf[512];
|
|
int n;
|
|
char* bufptr;
|
|
|
|
IF_NOT_DEBUG(ECB) {
|
|
return;
|
|
}
|
|
|
|
IF_NOT_SHOW(ECBS) {
|
|
VwDumpData((ULPBYTE)pEcb,
|
|
Seg,
|
|
Off,
|
|
TRUE,
|
|
(WORD)((Type == ECB_TYPE_AES)
|
|
? sizeof(AES_ECB)
|
|
: (sizeof(IPX_ECB) + sizeof(FRAGMENT) * (pEcb->FragmentCount - 1)))
|
|
);
|
|
return;
|
|
}
|
|
|
|
n = sprintf(buf,
|
|
"\n"
|
|
"%s ECB @ %04x:%04x:\n"
|
|
"LinkAddress %04x:%04x\n"
|
|
"EsrAddress %04x:%04x\n"
|
|
"InUse %02x\n",
|
|
(Type == ECB_TYPE_AES)
|
|
? "AES"
|
|
: (Type == ECB_TYPE_IPX)
|
|
? "IPX"
|
|
: "SPX",
|
|
Seg,
|
|
Off,
|
|
GET_SEGMENT(&pEcb->LinkAddress),
|
|
GET_OFFSET(&pEcb->LinkAddress),
|
|
GET_SEGMENT(&pEcb->EsrAddress),
|
|
GET_OFFSET(&pEcb->EsrAddress),
|
|
pEcb->InUse
|
|
);
|
|
bufptr = buf + n;
|
|
if (Type == ECB_TYPE_AES) {
|
|
sprintf(bufptr,
|
|
"AesWorkspace %02x-%02x-%02x-%02x-%02x\n",
|
|
((LPAES_ECB)pEcb)->AesWorkspace[0] & 0xff,
|
|
((LPAES_ECB)pEcb)->AesWorkspace[1] & 0xff,
|
|
((LPAES_ECB)pEcb)->AesWorkspace[2] & 0xff,
|
|
((LPAES_ECB)pEcb)->AesWorkspace[3] & 0xff,
|
|
((LPAES_ECB)pEcb)->AesWorkspace[4] & 0xff
|
|
);
|
|
} else {
|
|
sprintf(bufptr,
|
|
"CompletionCode %02x\n"
|
|
"SocketNumber %04x\n"
|
|
"IpxWorkspace %08x\n"
|
|
"DriverWorkspace %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
|
|
"ImmediateAddress %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"FragmentCount %04x\n",
|
|
pEcb->CompletionCode,
|
|
B2LW(pEcb->SocketNumber),
|
|
pEcb->IpxWorkspace,
|
|
pEcb->DriverWorkspace[0] & 0xff,
|
|
pEcb->DriverWorkspace[1] & 0xff,
|
|
pEcb->DriverWorkspace[2] & 0xff,
|
|
pEcb->DriverWorkspace[3] & 0xff,
|
|
pEcb->DriverWorkspace[4] & 0xff,
|
|
pEcb->DriverWorkspace[5] & 0xff,
|
|
pEcb->DriverWorkspace[6] & 0xff,
|
|
pEcb->DriverWorkspace[7] & 0xff,
|
|
pEcb->DriverWorkspace[8] & 0xff,
|
|
pEcb->DriverWorkspace[9] & 0xff,
|
|
pEcb->DriverWorkspace[10] & 0xff,
|
|
pEcb->DriverWorkspace[11] & 0xff,
|
|
pEcb->ImmediateAddress[0] & 0xff,
|
|
pEcb->ImmediateAddress[1] & 0xff,
|
|
pEcb->ImmediateAddress[2] & 0xff,
|
|
pEcb->ImmediateAddress[3] & 0xff,
|
|
pEcb->ImmediateAddress[4] & 0xff,
|
|
pEcb->ImmediateAddress[5] & 0xff,
|
|
pEcb->FragmentCount
|
|
);
|
|
}
|
|
|
|
VwLog(buf);
|
|
|
|
if ((Type != ECB_TYPE_AES) && Frags) {
|
|
|
|
ASSERT(pEcb->FragmentCount < 10);
|
|
|
|
VwDumpFragment(pEcb->FragmentCount,
|
|
(LPFRAGMENT)(pEcb + 1),
|
|
Type,
|
|
Data,
|
|
Mode
|
|
);
|
|
}
|
|
}
|
|
|
|
VOID VwDumpFragment(WORD Count, LPFRAGMENT pFrag, BYTE Type, BOOL Data, BOOL Mode) {
|
|
|
|
char buf[256];
|
|
int i;
|
|
|
|
IF_NOT_DEBUG(FRAGMENTS) {
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < Count; ++i) {
|
|
sprintf(buf,
|
|
"Fragment %d:\n"
|
|
" Address %04x:%04x\n"
|
|
" Length %04x\n",
|
|
i + 1,
|
|
GET_SEGMENT(&pFrag->Address),
|
|
GET_OFFSET(&pFrag->Address),
|
|
pFrag->Length
|
|
);
|
|
VwLog(buf);
|
|
if (Data) {
|
|
|
|
ULPBYTE ptr;
|
|
WORD size;
|
|
WORD offset;
|
|
|
|
ptr = GET_FAR_POINTER(&pFrag->Address, Mode);
|
|
size = pFrag->Length;
|
|
offset = GET_OFFSET(&pFrag->Address);
|
|
|
|
//
|
|
// this allows us to show headers vs. raw data
|
|
//
|
|
|
|
IF_SHOW(HEADERS) {
|
|
if (i == 0) {
|
|
VwDumpPacketHeader(ptr, Type);
|
|
|
|
if (Type == ECB_TYPE_IPX) {
|
|
ptr += IPX_HEADER_LENGTH;
|
|
size -= IPX_HEADER_LENGTH;
|
|
offset += IPX_HEADER_LENGTH;
|
|
} else {
|
|
ptr += SPX_HEADER_LENGTH;
|
|
size -= SPX_HEADER_LENGTH;
|
|
offset += SPX_HEADER_LENGTH;
|
|
}
|
|
}
|
|
}
|
|
|
|
VwDumpData(ptr,
|
|
GET_SEGMENT(&pFrag->Address),
|
|
offset,
|
|
TRUE,
|
|
size
|
|
);
|
|
}
|
|
++pFrag;
|
|
}
|
|
}
|
|
|
|
VOID VwDumpPacketHeader(ULPBYTE pPacket, BYTE Type) {
|
|
|
|
char buf[512];
|
|
|
|
IF_NOT_DEBUG(HEADERS) {
|
|
return;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"Checksum %04x\n"
|
|
"Length %04x\n"
|
|
"TransportControl %02x\n"
|
|
"PacketType %02x\n"
|
|
"Destination %02x-%02x-%02x-%02x : %02x-%02x-%02x-%02x-%02x-%02x : %04x\n"
|
|
"Source %02x-%02x-%02x-%02x : %02x-%02x-%02x-%02x-%02x-%02x : %04x\n",
|
|
((LPIPX_PACKET)pPacket)->Checksum,
|
|
B2LW(((LPIPX_PACKET)pPacket)->Length),
|
|
((LPIPX_PACKET)pPacket)->TransportControl,
|
|
((LPIPX_PACKET)pPacket)->PacketType,
|
|
((LPIPX_PACKET)pPacket)->Destination.Net[0] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Net[1] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Net[2] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Net[3] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[0] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[1] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[2] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[3] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[4] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Destination.Node[5] & 0xff,
|
|
B2LW(((LPIPX_PACKET)pPacket)->Destination.Socket),
|
|
((LPIPX_PACKET)pPacket)->Source.Net[0] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Net[1] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Net[2] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Net[3] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[0] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[1] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[2] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[3] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[4] & 0xff,
|
|
((LPIPX_PACKET)pPacket)->Source.Node[5] & 0xff,
|
|
B2LW(((LPIPX_PACKET)pPacket)->Source.Socket)
|
|
);
|
|
VwLog(buf);
|
|
if (Type == ECB_TYPE_SPX) {
|
|
sprintf(buf,
|
|
"ConnectControl %02x\n"
|
|
"DataStreamType %02x\n"
|
|
"SourceConnectId %04x\n"
|
|
"DestConnectId %04x\n"
|
|
"SequenceNumber %04x\n"
|
|
"AckNumber %04x\n"
|
|
"AllocationNumber %04x\n",
|
|
((LPSPX_PACKET)pPacket)->ConnectionControl,
|
|
((LPSPX_PACKET)pPacket)->DataStreamType,
|
|
B2LW(((LPSPX_PACKET)pPacket)->SourceConnectId),
|
|
B2LW(((LPSPX_PACKET)pPacket)->DestinationConnectId),
|
|
B2LW(((LPSPX_PACKET)pPacket)->SequenceNumber),
|
|
B2LW(((LPSPX_PACKET)pPacket)->AckNumber),
|
|
B2LW(((LPSPX_PACKET)pPacket)->AllocationNumber)
|
|
);
|
|
VwLog(buf);
|
|
}
|
|
VwLog("\n");
|
|
}
|
|
|
|
VOID VwDumpXecb(LPXECB pXecb) {
|
|
|
|
char buf[512];
|
|
|
|
IF_NOT_DEBUG(XECB) {
|
|
return;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"XECB @ %p:\n"
|
|
"Next %p\n"
|
|
"Ecb %p\n"
|
|
"EcbAddress %08x\n"
|
|
"EsrAddress %08x\n"
|
|
"Buffer %p\n"
|
|
"Data %p\n"
|
|
"FrameLength %04x\n"
|
|
"ActualLength %04x\n"
|
|
"Length %04x\n"
|
|
"Ticks %04x\n"
|
|
"SocketNumber %04x\n"
|
|
"Owner %04x\n"
|
|
"TaskId %08x\n"
|
|
"Flags %08x\n"
|
|
"QueueId %08x\n"
|
|
"OwningObject %p\n"
|
|
"RefCount %08x\n",
|
|
pXecb,
|
|
pXecb->Next,
|
|
pXecb->Ecb,
|
|
pXecb->EcbAddress,
|
|
pXecb->EsrAddress,
|
|
pXecb->Buffer,
|
|
pXecb->Data,
|
|
pXecb->FrameLength,
|
|
pXecb->ActualLength,
|
|
pXecb->Length,
|
|
pXecb->Ticks,
|
|
B2LW(pXecb->SocketNumber),
|
|
pXecb->Owner,
|
|
pXecb->TaskId,
|
|
pXecb->Flags,
|
|
pXecb->QueueId,
|
|
pXecb->OwningObject,
|
|
pXecb->RefCount
|
|
);
|
|
VwLog(buf);
|
|
}
|
|
|
|
VOID VwDumpSocketInfo(LPSOCKET_INFO pSocketInfo) {
|
|
|
|
char buf[512];
|
|
|
|
IF_NOT_DEBUG(SOCKINFO) {
|
|
return;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"SOCKET_INFO @ %p:\n"
|
|
"Next %p\n"
|
|
"SocketNumber %04x\n"
|
|
"Owner %04x\n"
|
|
"TaskId %08x\n"
|
|
"Socket %08x\n"
|
|
"Flags %08x\n"
|
|
"LongLived %d\n"
|
|
"SpxSocket %d\n"
|
|
"PendingSends %08x\n"
|
|
"PendingListens %08x\n"
|
|
"ListenQueue %p, %p\n"
|
|
"SendQueue %p, %p\n"
|
|
"HeaderQueue %p, %p\n"
|
|
"Connections %p\n",
|
|
pSocketInfo,
|
|
pSocketInfo->Next,
|
|
B2LW(pSocketInfo->SocketNumber),
|
|
pSocketInfo->Owner,
|
|
pSocketInfo->TaskId,
|
|
pSocketInfo->Socket,
|
|
pSocketInfo->Flags,
|
|
pSocketInfo->LongLived,
|
|
pSocketInfo->SpxSocket,
|
|
pSocketInfo->PendingSends,
|
|
pSocketInfo->PendingListens,
|
|
pSocketInfo->ListenQueue.Head,
|
|
pSocketInfo->ListenQueue.Tail,
|
|
pSocketInfo->SendQueue.Head,
|
|
pSocketInfo->SendQueue.Tail,
|
|
pSocketInfo->HeaderQueue.Head,
|
|
pSocketInfo->HeaderQueue.Tail,
|
|
pSocketInfo->Connections
|
|
);
|
|
VwLog(buf);
|
|
}
|
|
|
|
VOID VwDumpConnectionInfo(LPCONNECTION_INFO pConnectionInfo) {
|
|
|
|
char buf[512];
|
|
|
|
IF_NOT_DEBUG(CONNINFO) {
|
|
return;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"CONNECTION_INFO @ %p:\n"
|
|
"Next %p\n"
|
|
"List %p\n"
|
|
"OwningSocket %p\n"
|
|
"Socket %08x\n"
|
|
"TaskId %08x\n"
|
|
"ConnectionId %04x\n"
|
|
"Flags %02x\n"
|
|
"State %02x\n"
|
|
"ConnectQueue %p, %p\n"
|
|
"AcceptQueue %p, %p\n"
|
|
"SendQueue %p, %p\n"
|
|
"ListenQueue %p, %p\n",
|
|
pConnectionInfo,
|
|
pConnectionInfo->Next,
|
|
pConnectionInfo->List,
|
|
pConnectionInfo->OwningSocket,
|
|
pConnectionInfo->Socket,
|
|
pConnectionInfo->TaskId,
|
|
pConnectionInfo->ConnectionId,
|
|
pConnectionInfo->Flags,
|
|
pConnectionInfo->State,
|
|
pConnectionInfo->ConnectQueue.Head,
|
|
pConnectionInfo->ConnectQueue.Tail,
|
|
pConnectionInfo->AcceptQueue.Head,
|
|
pConnectionInfo->AcceptQueue.Tail,
|
|
pConnectionInfo->SendQueue.Head,
|
|
pConnectionInfo->SendQueue.Tail,
|
|
pConnectionInfo->ListenQueue.Head,
|
|
pConnectionInfo->ListenQueue.Tail
|
|
);
|
|
VwLog(buf);
|
|
}
|
|
|
|
VOID VwDumpConnectionStats(LPSPX_CONNECTION_STATS pStats) {
|
|
|
|
char buf[1024];
|
|
|
|
IF_NOT_DEBUG(STATS) {
|
|
return;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"State %02x\n"
|
|
"WatchDog %02x\n"
|
|
"LocalConnectionId %04x\n"
|
|
"RemoteConnectionId %04x\n"
|
|
"LocalSequenceNumber %04x\n"
|
|
"LocalAckNumber %04x\n"
|
|
"LocalAllocNumber %04x\n"
|
|
"RemoteAckNumber %04x\n"
|
|
"RemoteAllocNumber %04x\n"
|
|
"LocalSocket %04x\n"
|
|
"ImmediateAddress %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"RemoteNetwork %02x-%02x-%02x-%02x\n"
|
|
"RemoteNode %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"RemoteSocket %04x\n"
|
|
"RetransmissionCount %04x\n"
|
|
"EstimatedRoundTripDelay %04x\n"
|
|
"RetransmittedPackets %04x\n",
|
|
pStats->State,
|
|
pStats->WatchDog,
|
|
B2LW(pStats->LocalConnectionId),
|
|
B2LW(pStats->RemoteConnectionId),
|
|
B2LW(pStats->LocalSequenceNumber),
|
|
B2LW(pStats->LocalAckNumber),
|
|
B2LW(pStats->LocalAllocNumber),
|
|
B2LW(pStats->RemoteAckNumber),
|
|
B2LW(pStats->RemoteAllocNumber),
|
|
B2LW(pStats->LocalSocket),
|
|
pStats->ImmediateAddress[0] & 0xff,
|
|
pStats->ImmediateAddress[1] & 0xff,
|
|
pStats->ImmediateAddress[2] & 0xff,
|
|
pStats->ImmediateAddress[3] & 0xff,
|
|
pStats->ImmediateAddress[4] & 0xff,
|
|
pStats->ImmediateAddress[5] & 0xff,
|
|
pStats->RemoteNetwork[0] & 0xff,
|
|
pStats->RemoteNetwork[1] & 0xff,
|
|
pStats->RemoteNetwork[2] & 0xff,
|
|
pStats->RemoteNetwork[3] & 0xff,
|
|
pStats->RemoteNode[0] & 0xff,
|
|
pStats->RemoteNode[1] & 0xff,
|
|
pStats->RemoteNode[2] & 0xff,
|
|
pStats->RemoteNode[3] & 0xff,
|
|
pStats->RemoteNode[4] & 0xff,
|
|
pStats->RemoteNode[5] & 0xff,
|
|
B2LW(pStats->RemoteSocket),
|
|
B2LW(pStats->RetransmissionCount),
|
|
B2LW(pStats->EstimatedRoundTripDelay),
|
|
B2LW(pStats->RetransmittedPackets)
|
|
);
|
|
|
|
VwLog(buf);
|
|
}
|
|
|
|
VOID VwLog(LPSTR buf) {
|
|
|
|
IF_DEBUG(NOTHING) {
|
|
return;
|
|
}
|
|
|
|
IF_DEBUG(TO_FILE) {
|
|
fputs(buf, hVwDebugLog);
|
|
IF_DEBUG(FLUSH) {
|
|
fflush(hVwDebugLog);
|
|
}
|
|
} else IF_DEBUG(TO_DBG) {
|
|
OutputDebugString(buf);
|
|
}
|
|
}
|
|
|
|
VOID CheckInterrupts(LPSTR name) {
|
|
|
|
IF_DEBUG(CHECK_INT) {
|
|
|
|
LPWORD pDosIntFlag = (LPWORD)GET_POINTER(0x40, 0x314, 2, FALSE);
|
|
|
|
if ((getIF() == 0) || !(*pDosIntFlag & 0x200)) {
|
|
IPXDBGPRINT((__FILE__, __LINE__,
|
|
FUNCTION_ANY,
|
|
IPXDBG_LEVEL_ERROR,
|
|
"*** CheckInterrupts: ints off in %s (IF=%d, 40:314=%04x)\n",
|
|
name,
|
|
getIF(),
|
|
*pDosIntFlag
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
extern LPCONNECTION_INFO ConnectionList ;
|
|
extern LPSOCKET_INFO SocketList ;
|
|
|
|
VOID VwDumpAll(VOID)
|
|
{
|
|
char buf[512];
|
|
LPCONNECTION_INFO pConnectionInfo;
|
|
LPSOCKET_INFO pSocketInfo;
|
|
|
|
if (DebugFlagsEx == 0)
|
|
return ;
|
|
|
|
DebugFlagsEx = 0 ;
|
|
|
|
RequestMutex();
|
|
|
|
|
|
pSocketInfo = SocketList;
|
|
while (pSocketInfo) {
|
|
|
|
LPXECB pXecb ;
|
|
|
|
if (!(pSocketInfo->SpxSocket)) {
|
|
pSocketInfo = pSocketInfo->Next;
|
|
continue ;
|
|
}
|
|
|
|
sprintf(buf,
|
|
"%sSOCKET_INFO @ %p:\n"
|
|
" SocketNumber %04x\n"
|
|
" Owner %04x\n"
|
|
" TaskId %08x\n"
|
|
" Socket %08x\n"
|
|
" Flags %08x\n"
|
|
" LongLived %d\n"
|
|
" PendingSends %08x\n"
|
|
" PendingListens %08x\n"
|
|
" ListenQueue %p, %p\n"
|
|
" SendQueue %p, %p\n"
|
|
" HeaderQueue %p, %p\n"
|
|
" Connections %p\n\n",
|
|
(pSocketInfo->SpxSocket)?"SPX ":"",
|
|
pSocketInfo,
|
|
B2LW(pSocketInfo->SocketNumber),
|
|
pSocketInfo->Owner,
|
|
pSocketInfo->TaskId,
|
|
pSocketInfo->Socket,
|
|
pSocketInfo->Flags,
|
|
pSocketInfo->LongLived,
|
|
pSocketInfo->PendingSends,
|
|
pSocketInfo->PendingListens,
|
|
pSocketInfo->ListenQueue.Head,
|
|
pSocketInfo->ListenQueue.Tail,
|
|
pSocketInfo->SendQueue.Head,
|
|
pSocketInfo->SendQueue.Tail,
|
|
pSocketInfo->HeaderQueue.Head,
|
|
pSocketInfo->HeaderQueue.Tail,
|
|
pSocketInfo->Connections
|
|
);
|
|
OutputDebugString(buf);
|
|
|
|
pConnectionInfo = pSocketInfo->Connections ;
|
|
|
|
while(pConnectionInfo) {
|
|
sprintf(buf,
|
|
"CONNECTION_INFO @ %p:\n"
|
|
" List %p\n"
|
|
" OwningSocket %p\n"
|
|
" Socket %08x\n"
|
|
" TaskId %08x\n"
|
|
" ConnectionId %04x\n"
|
|
" Flags %02x\n"
|
|
" State %02x\n"
|
|
" ConnectQueue %p, %p\n"
|
|
" AcceptQueue %p, %p\n"
|
|
" SendQueue %p, %p\n"
|
|
" ListenQueue %p, %p\n\n",
|
|
pConnectionInfo,
|
|
pConnectionInfo->List,
|
|
pConnectionInfo->OwningSocket,
|
|
pConnectionInfo->Socket,
|
|
pConnectionInfo->TaskId,
|
|
pConnectionInfo->ConnectionId,
|
|
pConnectionInfo->Flags,
|
|
pConnectionInfo->State,
|
|
pConnectionInfo->ConnectQueue.Head,
|
|
pConnectionInfo->ConnectQueue.Tail,
|
|
pConnectionInfo->AcceptQueue.Head,
|
|
pConnectionInfo->AcceptQueue.Tail,
|
|
pConnectionInfo->SendQueue.Head,
|
|
pConnectionInfo->SendQueue.Tail,
|
|
pConnectionInfo->ListenQueue.Head,
|
|
pConnectionInfo->ListenQueue.Tail
|
|
);
|
|
OutputDebugString(buf);
|
|
pConnectionInfo = pConnectionInfo->Next ;
|
|
}
|
|
|
|
pXecb = pSocketInfo->ListenQueue.Head ;
|
|
while(pXecb) {
|
|
sprintf(buf,
|
|
" XECB @ %p: (Ecb %p)\n"
|
|
" EcbAddress/EsrAddress %08x %08x\n"
|
|
" Flags/RefCount %08x %08x\n"
|
|
" Buffer/QueueId %p %08x\n"
|
|
" OwningObject %p\n",
|
|
pXecb,
|
|
pXecb->Ecb,
|
|
pXecb->EcbAddress,
|
|
pXecb->EsrAddress,
|
|
pXecb->Flags,
|
|
pXecb->RefCount,
|
|
pXecb->Buffer,
|
|
pXecb->QueueId,
|
|
pXecb->OwningObject
|
|
);
|
|
OutputDebugString(buf);
|
|
pXecb = pXecb->Next ;
|
|
}
|
|
pSocketInfo = pSocketInfo->Next;
|
|
}
|
|
ReleaseMutex();
|
|
}
|
|
|
|
#endif // DBG
|