4028 lines
110 KiB
C
4028 lines
110 KiB
C
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vrdlcdbg.c
|
|
|
|
Abstract:
|
|
|
|
Contains functions for dumping CCBs, parameter tables; diagnostic and
|
|
debugging functions for DOS DLC (CCB1)
|
|
|
|
Contents:
|
|
DbgOut
|
|
DbgOutStr
|
|
DumpCcb
|
|
DumpDosDlcBufferPool
|
|
DumpDosDlcBufferChain
|
|
MapCcbRetcode
|
|
(DefaultParameterTableDump)
|
|
(DumpParameterTableHeader)
|
|
(DumpBufferFreeParms)
|
|
(DumpBufferGetParms)
|
|
(DumpDirCloseAdapterParms)
|
|
(DumpDirDefineMifEnvironmentParms)
|
|
(DumpDirInitializeParms)
|
|
(DumpDirModifyOpenParmsParms)
|
|
(DumpDirOpenAdapterParms)
|
|
(DumpDirReadLog)
|
|
(DumpDirRestoreOpenParmsParms)
|
|
(DumpDirSetFunctionalAddressParms)
|
|
(DumpDirSetGroupAddressParms)
|
|
(DumpDirSetUserAppendageParms)
|
|
(DumpDirStatusParms)
|
|
(DumpDirTimerCancelParms)
|
|
(DumpDirTimerCancelGroupParms)
|
|
(DumpDirTimerSetParms)
|
|
(DumpDlcCloseSapParms)
|
|
(DumpDlcCloseStationParms)
|
|
(DumpDlcConnectStationParms)
|
|
(DumpDlcFlowControlParms)
|
|
(MapFlowControl)
|
|
(DumpDlcModifyParms)
|
|
(DumpDlcOpenSapParms)
|
|
(MapOptionsPriority)
|
|
(DumpDlcOpenStationParms)
|
|
(DumpDlcReallocateParms)
|
|
(DumpDlcResetParms)
|
|
(DumpDlcStatisticsParms)
|
|
(DumpPdtTraceOffParms)
|
|
(DumpPdtTraceOnParms)
|
|
(DumpReadParms)
|
|
(MapReadEvent)
|
|
(MapDlcStatus)
|
|
(DumpReadCancelParms)
|
|
(DumpReceiveParms)
|
|
(DumpReceiveCancelParms)
|
|
(DumpReceiveModifyParms)
|
|
(DumpTransmitDirFrameParms)
|
|
(DumpTransmitIFrameParms)
|
|
(DumpTransmitTestCmdParms)
|
|
(DumpTransmitUiFrameParms)
|
|
(DumpTransmitXidCmdParms)
|
|
(DumpTransmitXidRespFinalParms)
|
|
(DumpTransmitXidRespNotFinalParms)
|
|
(DumpTransmitParms)
|
|
(DumpTransmitQueue)
|
|
DumpReceiveDataBuffer
|
|
(MapMessageType)
|
|
DumpData
|
|
IsCcbErrorCodeAllowable
|
|
IsCcbErrorCodeValid
|
|
IsCcbCommandValid
|
|
MapCcbCommandToName
|
|
DumpDosAdapter
|
|
(MapAdapterType)
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 30-Apr-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#if DBG
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <nt.h>
|
|
#include <ntrtl.h> // ASSERT, DbgPrint
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <softpc.h> // x86 virtual machine definitions
|
|
#include <vrdlctab.h>
|
|
#include <vdmredir.h>
|
|
#include <smbgtpt.h>
|
|
#include <dlcapi.h> // Official DLC API definition
|
|
#include <ntdddlc.h> // IOCTL commands
|
|
#include <dlcio.h> // Internal IOCTL API interface structures
|
|
#include "vrdlc.h"
|
|
#include "vrdebug.h"
|
|
#include "vrdlcdbg.h"
|
|
|
|
//
|
|
// defines
|
|
//
|
|
|
|
//
|
|
// standard parameters to each table dump routine
|
|
//
|
|
|
|
#define DUMP_TABLE_PARMS \
|
|
IN PVOID Parameters, \
|
|
IN BOOL IsDos, \
|
|
IN BOOL IsInput, \
|
|
IN WORD Segment, \
|
|
IN WORD Offset
|
|
|
|
//
|
|
// DumpData options
|
|
//
|
|
|
|
#define DD_NO_ADDRESS 0x00000001 // don't display address of data
|
|
#define DD_LINE_BEFORE 0x00000002 // linefeed before first dumped line
|
|
#define DD_LINE_AFTER 0x00000004 // linefeed after last dumped line
|
|
#define DD_INDENT_ALL 0x00000008 // indent all lines
|
|
#define DD_NO_ASCII 0x00000010 // don't dump ASCII respresentation
|
|
#define DD_UPPER_CASE 0x00000020 // upper-case hex dump (F4 instead of f4)
|
|
|
|
//
|
|
// misc.
|
|
//
|
|
|
|
#define DEFAULT_FIELD_WIDTH 13 // amount of description before a number
|
|
|
|
//
|
|
// local prototypes
|
|
//
|
|
|
|
VOID
|
|
DbgOutStr(
|
|
IN LPSTR Str
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DefaultParameterTableDump(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpParameterTableHeader(
|
|
IN LPSTR CommandName,
|
|
IN PVOID Table,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment,
|
|
IN WORD Offset
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpBufferFreeParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpBufferGetParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirCloseAdapterParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirDefineMifEnvironmentParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirInitializeParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirModifyOpenParmsParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirOpenAdapterParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirReadLog(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirRestoreOpenParmsParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetFunctionalAddressParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetGroupAddressParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetUserAppendageParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirStatusParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerCancelGroupParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerSetParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcCloseSapParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcCloseStationParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcConnectStationParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcFlowControlParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapFlowControl(
|
|
BYTE FlowControl
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcModifyParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcOpenSapParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapOptionsPriority(
|
|
UCHAR OptionsPriority
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcOpenStationParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcReallocateParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcResetParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcStatisticsParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpPdtTraceOffParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpPdtTraceOnParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReadParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapReadEvent(
|
|
UCHAR Event
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapDlcStatus(
|
|
WORD Status
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReadCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveModifyParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitDirFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitIFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitTestCmdParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitUiFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidCmdParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidRespFinalParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidRespNotFinalParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitParms(
|
|
DUMP_TABLE_PARMS
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitQueue(
|
|
IN DOS_ADDRESS dpQueue
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapMessageType(
|
|
UCHAR MessageType
|
|
);
|
|
|
|
VOID
|
|
DumpData(
|
|
IN LPSTR Title,
|
|
IN PBYTE Address,
|
|
IN DWORD Length,
|
|
IN DWORD Options,
|
|
IN DWORD Indent,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment,
|
|
IN WORD Offset
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapAdapterType(
|
|
IN ADAPTER_TYPE AdapterType
|
|
);
|
|
|
|
//
|
|
// explanations of error codes returned in CCB_RETCODE fields. Explanations
|
|
// taken more-or-less verbatim from IBM Local Area Network Technical Reference
|
|
// table B-1 ppB-2 to B-5. Includes all errors, even not relevant to CCB1
|
|
//
|
|
|
|
static LPSTR CcbRetcodeExplanations[] = {
|
|
"Success",
|
|
"Invalid command code",
|
|
"Duplicate command, one already outstanding",
|
|
"Adapter open, should be closed",
|
|
"Adapter closed, should be open",
|
|
"Required parameter missing",
|
|
"Invalid/incompatible option",
|
|
"Command cancelled - unrecoverable failure",
|
|
"Unauthorized access priority",
|
|
"Adapter not initialized, should be",
|
|
"Command cancelled by user request",
|
|
"Command cancelled, adapter closed while command in progress",
|
|
"Command completed Ok, adapter not open",
|
|
"Invalid error code 0x0D",
|
|
"Invalid error code 0x0E",
|
|
"Invalid error code 0x0F",
|
|
"Adapter open, NetBIOS not operational",
|
|
"Error in DIR.TIMER.SET or DIR.TIMER.CANCEL",
|
|
"Available work area exceeded",
|
|
"Invalid LOG.ID",
|
|
"Invalid shared RAM segment or size",
|
|
"Lost log data, buffer too small, log reset",
|
|
"Requested buffer size exceeds pool length",
|
|
"Command invalid, NetBIOS operational",
|
|
"Invalid SAP buffer length",
|
|
"Inadequate buffers available for request",
|
|
"USER_LENGTH value too large for buffer length",
|
|
"The CCB_PARM_TAB pointer is invalid",
|
|
"A pointer in the CCB parameter table is invalid",
|
|
"Invalid CCB_ADAPTER value",
|
|
"Invalid functional address",
|
|
"Invalid error code 0x1F",
|
|
"Lost data on receive, no buffers available",
|
|
"Lost data on receive, inadequate buffer space",
|
|
"Error on frame transmission, check TRANSMIT_FS data",
|
|
"Error on frame transmit or strip process",
|
|
"Unauthorized MAC frame",
|
|
"Maximum number of commands exceeded",
|
|
"Unrecognized command correlator",
|
|
"Link not transmitting I frames, state changed from link opened",
|
|
"Invalid transmit frame length",
|
|
"Invalid error code 0x29",
|
|
"Invalid error code 0x2a",
|
|
"Invalid error code 0x2b",
|
|
"Invalid error code 0x2c",
|
|
"Invalid error code 0x2d",
|
|
"Invalid error code 0x2e",
|
|
"Invalid error code 0x2f",
|
|
"Inadequate receive buffers for adapter to open",
|
|
"Invalid error code 0x31",
|
|
"Invalid NODE_ADDRESS",
|
|
"Invalid adapter receive buffer length defined",
|
|
"Invalid adapter transmit buffer length defined",
|
|
"Invalid error code 0x35",
|
|
"Invalid error code 0x36",
|
|
"Invalid error code 0x37",
|
|
"Invalid error code 0x38",
|
|
"Invalid error code 0x39",
|
|
"Invalid error code 0x3a",
|
|
"Invalid error code 0x3b",
|
|
"Invalid error code 0x3c",
|
|
"Invalid error code 0x3d",
|
|
"Invalid error code 0x3e",
|
|
"Invalid error code 0x3f",
|
|
"Invalid STATION_ID",
|
|
"Protocol error, link in invalid state for command",
|
|
"Parameter exceeded maximum allowed",
|
|
"Invalid SAP value or value already in use",
|
|
"Invalid routing information field",
|
|
"Requested group membership in non-existent group SAP",
|
|
"Resources not available",
|
|
"Sap cannot close unless all link stations are closed",
|
|
"Group SAP cannot close, individual SAPs not closed",
|
|
"Group SAP has reached maximum membership",
|
|
"Sequence error, incompatible command in progress",
|
|
"Station closed without remote acknowledgement",
|
|
"Sequence error, cannot close, DLC commands outstanding",
|
|
"Unsuccessful link station connection attempted",
|
|
"Member SAP not found in group SAP list",
|
|
"Invalid remote address, may not be a group address",
|
|
"Invalid pointer in CCB_POINTER field",
|
|
"Invalid error code 0x51",
|
|
"Invalid application program ID",
|
|
"Invalid application program key code",
|
|
"Invalid system key code",
|
|
"Buffer is smaller than buffer size given in DLC.OPEN.SAP",
|
|
"Adapter's system process is not installed",
|
|
"Inadequate stations available",
|
|
"Invalid CCB_PARAMETER_1 parameter",
|
|
"Inadequate queue elements to satisfy request",
|
|
"Initialization failure, cannot open adapter",
|
|
"Error detected in chained READ command",
|
|
"Direct stations not assigned to application program",
|
|
"Dd interface not installed",
|
|
"Requested adapter is not installed",
|
|
"Chained CCBs must all be for same adapter",
|
|
"Adapter initializing, command not accepted",
|
|
"Number of allowed application programs has been exceeded",
|
|
"Command cancelled by system action",
|
|
"Direct stations not available",
|
|
"Invalid DDNAME parameter",
|
|
"Inadequate GDT selectors to satisfy request",
|
|
"Invalid error code 0x66",
|
|
"Command cancelled, CCB resources purged",
|
|
"Application program ID not valid for interface",
|
|
"Segment associated with request cannot be locked"
|
|
};
|
|
|
|
#define NUMBER_OF_ERROR_MESSAGES ARRAY_ELEMENTS(CcbRetcodeExplanations)
|
|
#define LAST_DLC_ERROR_CODE LAST_ELEMENT(CcbRetcodeExplanations)
|
|
|
|
VOID
|
|
DbgOut(
|
|
IN LPSTR Format,
|
|
IN ...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sends formatted debug output to desired output device. If DEBUG_TO_FILE
|
|
was specified in VR environment flags, output goes to VRDEBUG.LOG in
|
|
current directory, else to standard debug output via DbgPrint
|
|
|
|
Arguments:
|
|
|
|
Format - printf-style format string
|
|
... - variable args
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
va_list list;
|
|
char buffer[2048];
|
|
|
|
va_start(list, Format);
|
|
vsprintf(buffer, Format, list);
|
|
va_end(list);
|
|
if (hVrDebugLog) {
|
|
fputs(buffer, hVrDebugLog);
|
|
} else {
|
|
DbgPrint(buffer);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DbgOutStr(
|
|
IN LPSTR Str
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sends formatted debug output to desired output device. If DEBUG_TO_FILE
|
|
was specified in VR environment flags, output goes to VRDEBUG.LOG in
|
|
current directory, else to standard debug output via DbgPrint
|
|
|
|
Arguments:
|
|
|
|
Str - string to print
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (hVrDebugLog) {
|
|
fputs(Str, hVrDebugLog);
|
|
} else {
|
|
DbgPrint(Str);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpCcb(
|
|
IN PVOID Ccb,
|
|
IN BOOL DumpAll,
|
|
IN BOOL CcbIsInput,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment OPTIONAL,
|
|
IN WORD Offset OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps (to debug terminal) a CCB and any associated parameter table. Also
|
|
displays the symbolic CCB command and an error code description if the
|
|
CCB is being returned to the caller. Dumps in either DOS format (segmented
|
|
16-bit pointers) or NT format (flat 32-bit pointers)
|
|
|
|
Arguments:
|
|
|
|
Ccb - flat 32-bit pointer to CCB1 or CCB2 to dump
|
|
DumpAll - if TRUE, dumps parameter tables and buffers, else just CCB
|
|
CcbIsInput - if TRUE, CCB is from user: don't display error code explanation
|
|
IsDos - if TRUE, CCB is DOS format
|
|
Segment - if IsDos is TRUE, segment of CCB in VDM
|
|
Offset - if IsDos is TRUE, offset of CCB in VDM
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PVOID parmtab = NULL;
|
|
LPSTR cmdname = "UNKNOWN CCB!";
|
|
PLLC_CCB NtCcb = (PLLC_CCB)Ccb;
|
|
PLLC_DOS_CCB DosCcb = (PLLC_DOS_CCB)Ccb;
|
|
BOOL haveParms = FALSE;
|
|
VOID (*DumpParms)(PVOID, BOOL, BOOL, WORD, WORD) = DefaultParameterTableDump;
|
|
PVOID parameterTable = NULL;
|
|
WORD seg;
|
|
WORD off;
|
|
BOOL parmsInCcb = FALSE;
|
|
|
|
switch (((PLLC_CCB)Ccb)->uchDlcCommand) {
|
|
case LLC_BUFFER_FREE:
|
|
cmdname = "BUFFER.FREE";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpBufferFreeParms;
|
|
break;
|
|
|
|
case LLC_BUFFER_GET:
|
|
cmdname = "BUFFER.GET";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpBufferGetParms;
|
|
break;
|
|
|
|
case LLC_DIR_CLOSE_ADAPTER:
|
|
cmdname = "DIR.CLOSE.ADAPTER";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirCloseAdapterParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_CLOSE_DIRECT:
|
|
cmdname = "DIR.CLOSE.DIRECT";
|
|
break;
|
|
|
|
case 0x2b:
|
|
|
|
//
|
|
// not supported ! (yet?)
|
|
//
|
|
|
|
cmdname = "DIR.DEFINE.MIF.ENVIRONMENT";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_INITIALIZE:
|
|
cmdname = "DIR.INITIALIZE";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirInitializeParms;
|
|
break;
|
|
|
|
case LLC_DIR_INTERRUPT:
|
|
cmdname = "DIR.INTERRUPT";
|
|
break;
|
|
|
|
case LLC_DIR_MODIFY_OPEN_PARMS:
|
|
cmdname = "DIR.MODIFY.OPEN.PARMS";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_OPEN_ADAPTER:
|
|
cmdname = "DIR.OPEN.ADAPTER";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirOpenAdapterParms;
|
|
break;
|
|
|
|
case LLC_DIR_OPEN_DIRECT:
|
|
|
|
//
|
|
// not supported from DOS!
|
|
//
|
|
|
|
cmdname = "DIR.OPEN.DIRECT";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_READ_LOG:
|
|
cmdname = "DIR.READ.LOG";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_RESTORE_OPEN_PARMS:
|
|
cmdname = "DIR.RESTORE.OPEN.PARMS";
|
|
break;
|
|
|
|
case LLC_DIR_SET_FUNCTIONAL_ADDRESS:
|
|
cmdname = "DIR.SET.FUNCTIONAL.ADDRESS";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirSetFunctionalAddressParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_SET_GROUP_ADDRESS:
|
|
cmdname = "DIR.SET.GROUP.ADDRESS";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirSetGroupAddressParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_SET_USER_APPENDAGE:
|
|
cmdname = "DIR.SET.USER.APPENDAGE";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirSetUserAppendageParms;
|
|
break;
|
|
|
|
case LLC_DIR_STATUS:
|
|
cmdname = "DIR.STATUS";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirStatusParms;
|
|
break;
|
|
|
|
case LLC_DIR_TIMER_CANCEL:
|
|
cmdname = "DIR.TIMER.CANCEL";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirTimerCancelParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_TIMER_CANCEL_GROUP:
|
|
cmdname = "DIR.TIMER.CANCEL.GROUP";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirTimerCancelGroupParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DIR_TIMER_SET:
|
|
cmdname = "DIR.TIMER.SET";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDirTimerSetParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_CLOSE_SAP:
|
|
cmdname = "DLC.CLOSE.SAP";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcCloseSapParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_CLOSE_STATION:
|
|
cmdname = "DLC.CLOSE.STATION";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcCloseStationParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_CONNECT_STATION:
|
|
cmdname = "DLC.CONNECT.STATION";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcConnectStationParms;
|
|
break;
|
|
|
|
case LLC_DLC_FLOW_CONTROL:
|
|
cmdname = "DLC.FLOW.CONTROL";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcFlowControlParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_MODIFY:
|
|
cmdname = "DLC.MODIFY";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_OPEN_SAP:
|
|
cmdname = "DLC.OPEN.SAP";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcOpenSapParms;
|
|
break;
|
|
|
|
case LLC_DLC_OPEN_STATION:
|
|
cmdname = "DLC.OPEN.STATION";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcOpenStationParms;
|
|
break;
|
|
|
|
case LLC_DLC_REALLOCATE_STATIONS:
|
|
cmdname = "DLC.REALLOCATE";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_RESET:
|
|
cmdname = "DLC.RESET";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpDlcResetParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_SET_THRESHOLD:
|
|
cmdname = "DLC.SET.THRESHOLD";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case LLC_DLC_STATISTICS:
|
|
cmdname = "DLC.STATISTICS";
|
|
haveParms = TRUE;
|
|
break;
|
|
|
|
case 0x25:
|
|
|
|
//
|
|
// not supported !
|
|
//
|
|
|
|
cmdname = "PDT.TRACE.OFF";
|
|
break;
|
|
|
|
case 0x24:
|
|
|
|
//
|
|
// not supported !
|
|
//
|
|
|
|
cmdname = "PDT.TRACE.ON";
|
|
break;
|
|
|
|
case LLC_READ:
|
|
cmdname = "READ";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpReadParms;
|
|
break;
|
|
|
|
case LLC_READ_CANCEL:
|
|
cmdname = "READ.CANCEL";
|
|
break;
|
|
|
|
case LLC_RECEIVE:
|
|
cmdname = "RECEIVE";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpReceiveParms;
|
|
break;
|
|
|
|
case LLC_RECEIVE_CANCEL:
|
|
cmdname = "RECEIVE.CANCEL";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpReceiveCancelParms;
|
|
parmsInCcb = TRUE;
|
|
break;
|
|
|
|
case LLC_RECEIVE_MODIFY:
|
|
cmdname = "RECEIVE.MODIFY";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpReceiveModifyParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_DIR_FRAME:
|
|
cmdname = "TRANSMIT.DIR.FRAME";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitDirFrameParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_I_FRAME:
|
|
cmdname = "TRANSMIT.I.FRAME";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitIFrameParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_TEST_CMD:
|
|
cmdname = "TRANSMIT.TEST.CMD";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitTestCmdParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_UI_FRAME:
|
|
cmdname = "TRANSMIT.UI.FRAME";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitUiFrameParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_XID_CMD:
|
|
cmdname = "TRANSMIT.XID.CMD";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitXidCmdParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_XID_RESP_FINAL:
|
|
cmdname = "TRANSMIT.XID.RESP.FINAL";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitXidRespFinalParms;
|
|
break;
|
|
|
|
case LLC_TRANSMIT_XID_RESP_NOT_FINAL:
|
|
cmdname = "TRANSMIT.XID.RESP.NOT.FINAL";
|
|
haveParms = TRUE;
|
|
DumpParms = DumpTransmitXidRespNotFinalParms;
|
|
break;
|
|
|
|
}
|
|
|
|
if (IsDos) {
|
|
seg = GET_SELECTOR(&DosCcb->u.pParms);
|
|
off = GET_OFFSET(&DosCcb->u.pParms);
|
|
parmtab = POINTER_FROM_WORDS(seg, off);
|
|
} else {
|
|
parmtab = NtCcb->u.pParameterTable;
|
|
}
|
|
|
|
if (IsDos) {
|
|
PLLC_DOS_CCB DosCcb = (PLLC_DOS_CCB)Ccb;
|
|
|
|
DBGPRINT( "\n"
|
|
"------------------------------------------------------------------------------"
|
|
"\n"
|
|
);
|
|
|
|
IF_DEBUG(TIME) {
|
|
SYSTEMTIME timestruct;
|
|
|
|
GetLocalTime(×truct);
|
|
DBGPRINT(
|
|
"%02d:%02d:%02d.%03d\n",
|
|
timestruct.wHour,
|
|
timestruct.wMinute,
|
|
timestruct.wSecond,
|
|
timestruct.wMilliseconds
|
|
);
|
|
}
|
|
|
|
DBGPRINT( "%s DOS CCB @%04x:%04x:\n"
|
|
"adapter %02x\n"
|
|
"command %02x [%s]\n"
|
|
"retcode %02x [%s]\n"
|
|
"reserved %02x\n"
|
|
"next %04x:%04x\n"
|
|
"ANR %04x:%04x\n",
|
|
CcbIsInput ? "INPUT" : "OUTPUT",
|
|
Segment,
|
|
Offset,
|
|
DosCcb->uchAdapterNumber,
|
|
DosCcb->uchDlcCommand,
|
|
cmdname,
|
|
DosCcb->uchDlcStatus,
|
|
CcbIsInput ? "" : MapCcbRetcode(DosCcb->uchDlcStatus),
|
|
DosCcb->uchReserved1,
|
|
GET_SEGMENT(&DosCcb->pNext),
|
|
GET_OFFSET(&DosCcb->pNext),
|
|
GET_SEGMENT(&DosCcb->ulCompletionFlag),
|
|
GET_OFFSET(&DosCcb->ulCompletionFlag)
|
|
);
|
|
if (haveParms) {
|
|
if (!parmsInCcb) {
|
|
DBGPRINT(
|
|
"parms %04x:%04x\n",
|
|
GET_SEGMENT(&DosCcb->u.pParms),
|
|
GET_OFFSET(&DosCcb->u.pParms)
|
|
);
|
|
parameterTable = POINTER_FROM_WORDS(GET_SEGMENT(&DosCcb->u.pParms),
|
|
GET_OFFSET(&DosCcb->u.pParms)
|
|
);
|
|
} else {
|
|
parameterTable = (PVOID)READ_DWORD(&DosCcb->u.ulParameter);
|
|
}
|
|
}
|
|
} else {
|
|
PLLC_CCB NtCcb = (PLLC_CCB)Ccb;
|
|
|
|
DBGPRINT( "\n"
|
|
"------------------------------------------------------------------------------"
|
|
"\n"
|
|
);
|
|
|
|
IF_DEBUG(TIME) {
|
|
SYSTEMTIME timestruct;
|
|
|
|
GetLocalTime(×truct);
|
|
DBGPRINT(
|
|
"%02d:%02d:%02d.%03d\n",
|
|
timestruct.wHour,
|
|
timestruct.wMinute,
|
|
timestruct.wSecond,
|
|
timestruct.wMilliseconds
|
|
);
|
|
}
|
|
|
|
DBGPRINT( "%s NT CCB @ %#8x\n"
|
|
"adapter %02x\n"
|
|
"command %02x [%s]\n"
|
|
"retcode %02x [%s]\n"
|
|
"reserved %02x\n"
|
|
"next %08x\n"
|
|
"ANR %08x\n",
|
|
CcbIsInput ? "INPUT" : "OUTPUT",
|
|
Ccb,
|
|
NtCcb->uchAdapterNumber,
|
|
NtCcb->uchDlcCommand,
|
|
cmdname,
|
|
NtCcb->uchDlcStatus,
|
|
CcbIsInput ? "" : MapCcbRetcode(NtCcb->uchDlcStatus),
|
|
NtCcb->uchReserved1,
|
|
NtCcb->pNext,
|
|
NtCcb->ulCompletionFlag
|
|
);
|
|
if (haveParms) {
|
|
if (!parmsInCcb) {
|
|
DBGPRINT(
|
|
"parms %08x\n",
|
|
NtCcb->u.pParameterTable
|
|
);
|
|
}
|
|
parameterTable = NtCcb->u.pParameterTable;
|
|
}
|
|
DBGPRINT(
|
|
"hEvent %08x\n"
|
|
"reserved %02x\n"
|
|
"readflag %02x\n"
|
|
"reserved %04x\n",
|
|
NtCcb->hCompletionEvent,
|
|
NtCcb->uchReserved2,
|
|
NtCcb->uchReadFlag,
|
|
NtCcb->usReserved3
|
|
);
|
|
}
|
|
if ((parameterTable && DumpAll) || parmsInCcb) {
|
|
DumpParms(parameterTable, IsDos, CcbIsInput, seg, off);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpDosDlcBufferPool(
|
|
IN PDOS_DLC_BUFFER_POOL PoolDescriptor
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a DOS DLC buffer pool so we can see that it looks ok
|
|
|
|
Arguments:
|
|
|
|
PoolDescriptor - pointer to DOS_DLC_BUFFER_POOL structure
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
int count = PoolDescriptor->BufferCount;
|
|
|
|
DBGPRINT( "DOS DLC Buffer Pool @%04x:%04x, BufferSize=%d, BufferCount=%d\n",
|
|
HIWORD(PoolDescriptor->dpBuffer),
|
|
LOWORD(PoolDescriptor->dpBuffer),
|
|
PoolDescriptor->BufferSize,
|
|
PoolDescriptor->BufferCount
|
|
);
|
|
|
|
DumpDosDlcBufferChain(PoolDescriptor->dpBuffer, PoolDescriptor->BufferCount);
|
|
}
|
|
|
|
VOID
|
|
DumpDosDlcBufferChain(
|
|
IN DOS_ADDRESS DosAddress,
|
|
IN DWORD BufferCount
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a chain of DOS buffers
|
|
|
|
Arguments:
|
|
|
|
DosAddress - address of buffer in VDM memory in DOS_ADDRESS format (16:16)
|
|
BufferCount - number of buffers to dump
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD seg = HIWORD(DosAddress);
|
|
WORD off = LOWORD(DosAddress);
|
|
LPVOID pointer = DOS_PTR_TO_FLAT(DosAddress);
|
|
int i;
|
|
|
|
for (i = 1; BufferCount; --BufferCount, ++i) {
|
|
DBGPRINT("Buffer % 3d: %04x:%04x, Next Buffer @%04x:%04x\n",
|
|
i,
|
|
seg, off,
|
|
(DWORD)GET_SELECTOR(&((PLLC_DOS_BUFFER)pointer)->pNext),
|
|
(DWORD)GET_OFFSET(&((PLLC_DOS_BUFFER)pointer)->pNext)
|
|
);
|
|
seg = GET_SELECTOR(&((PLLC_DOS_BUFFER)pointer)->pNext);
|
|
off = GET_OFFSET(&((PLLC_DOS_BUFFER)pointer)->pNext);
|
|
|
|
IF_DEBUG(DUMP_FREE_BUF) {
|
|
|
|
PLLC_DOS_BUFFER pBuf = (PLLC_DOS_BUFFER)pointer;
|
|
|
|
DBGPRINT(
|
|
"next buffer %04x:%04x\n"
|
|
"frame length %04x\n"
|
|
"data length %04x\n"
|
|
"user offset %04x\n"
|
|
"user length %04x\n"
|
|
"station id %04x\n"
|
|
"options %02x\n"
|
|
"message type %02x\n"
|
|
"buffers left %04x\n"
|
|
"rcv FS %02x\n"
|
|
"adapter num %02x\n"
|
|
"\n",
|
|
GET_SEGMENT(&pBuf->Contiguous.pNextBuffer),
|
|
GET_OFFSET(&pBuf->Contiguous.pNextBuffer),
|
|
READ_WORD(&pBuf->Contiguous.cbFrame),
|
|
READ_WORD(&pBuf->Contiguous.cbBuffer),
|
|
READ_WORD(&pBuf->Contiguous.offUserData),
|
|
READ_WORD(&pBuf->Contiguous.cbUserData),
|
|
READ_WORD(&pBuf->Contiguous.usStationId),
|
|
pBuf->Contiguous.uchOptions,
|
|
pBuf->Contiguous.uchMsgType,
|
|
READ_WORD(&pBuf->Contiguous.cBuffersLeft),
|
|
pBuf->Contiguous.uchRcvFS,
|
|
pBuf->Contiguous.uchAdapterNumber
|
|
);
|
|
}
|
|
|
|
pointer = READ_FAR_POINTER(&((PLLC_DOS_BUFFER)pointer)->pNext);
|
|
}
|
|
}
|
|
|
|
LPSTR
|
|
MapCcbRetcode(
|
|
IN BYTE Retcode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns string describing error code
|
|
|
|
Arguments:
|
|
|
|
Retcode - CCB_RETCODE
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
static char errbuf[128];
|
|
|
|
if (Retcode == LLC_STATUS_PENDING) {
|
|
return "Command in progress";
|
|
} else if (Retcode > NUMBER_OF_ERROR_MESSAGES) {
|
|
sprintf(errbuf, "*** Invalid error code 0x%2x ***", Retcode);
|
|
return errbuf;
|
|
}
|
|
return CcbRetcodeExplanations[Retcode];
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DefaultParameterTableDump(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Displays default message for CCBs which have parameter tables that don't
|
|
have a dump routine yet
|
|
|
|
Arguments:
|
|
|
|
Parameters - pointer to parameter table
|
|
IsDos - if TRUE parameters in DOS (16:16) format
|
|
Segment - if IsDos is TRUE, segment of CCB in VDM
|
|
Offset - if IsDos is TRUE, offset of CCB in VDM
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DBGPRINT("Parameter table dump not implemented for this CCB\n");
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpParameterTableHeader(
|
|
IN LPSTR CommandName,
|
|
IN PVOID Table,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment,
|
|
IN WORD Offset
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Displays header for parameter table dump. Displays address in DOS or NT
|
|
format (32-bit flat or 16:16)
|
|
|
|
Arguments:
|
|
|
|
CommandName - name of command which owns parameter table
|
|
Table - flat 32-bit address of parameter table
|
|
IsDos - if TRUE, use Segment:Offset in display
|
|
Segment - if IsDos is TRUE, segment of parameter table in VDM
|
|
Offset - if IsDos is TRUE, offset of parameter table in VDM
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DBGPRINT( IsDos ? "\n%s parameter table @%04x:%04x\n"
|
|
: "\n%s parameter table @%08x\n",
|
|
CommandName,
|
|
IsDos ? (DWORD)Segment : (DWORD)Table,
|
|
IsDos ? (DWORD)Offset : 0
|
|
);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpBufferFreeParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_BUFFER_FREE_PARMS parms = (PLLC_BUFFER_FREE_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("BUFFER.FREE", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"buffers left %04x\n"
|
|
"reserved %02x %02x %02x %02x\n",
|
|
READ_WORD(&parms->usReserved1),
|
|
READ_WORD(&parms->cBuffersLeft),
|
|
((PBYTE)&(parms->ulReserved))[0],
|
|
((PBYTE)&(parms->ulReserved))[1],
|
|
((PBYTE)&(parms->ulReserved))[2],
|
|
((PBYTE)&(parms->ulReserved))[3]
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"first buffer %04x:%04x\n",
|
|
GET_SELECTOR(&parms->pFirstBuffer),
|
|
GET_OFFSET(&parms->pFirstBuffer)
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"first buffer %08x\n", parms->pFirstBuffer);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpBufferGetParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
//
|
|
// Antti's definition different from that in manual, so use IBM def.
|
|
//
|
|
|
|
typedef struct {
|
|
WORD StationId;
|
|
WORD BufferLeft;
|
|
BYTE BufferGet;
|
|
BYTE Reserved[3];
|
|
DWORD FirstBuffer;
|
|
} CCB1_BUFFER_GET_PARMS, *PCCB1_BUFFER_GET_PARMS;
|
|
|
|
PCCB1_BUFFER_GET_PARMS parms = (PCCB1_BUFFER_GET_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("BUFFER.GET", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"buffers left %04x\n"
|
|
"buffers get %02x\n"
|
|
"reserved %02x %02x %02x\n",
|
|
READ_WORD(&parms->StationId),
|
|
READ_WORD(&parms->BufferLeft),
|
|
parms->BufferGet,
|
|
parms->Reserved[0],
|
|
parms->Reserved[1],
|
|
parms->Reserved[2]
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"first buffer %04x:%04x\n",
|
|
GET_SELECTOR(&parms->FirstBuffer),
|
|
GET_OFFSET(&parms->FirstBuffer)
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"first buffer %08x\n", parms->FirstBuffer);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirCloseAdapterParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(IsDos);
|
|
UNREFERENCED_PARAMETER(Segment);
|
|
UNREFERENCED_PARAMETER(Offset);
|
|
|
|
DBGPRINT( "lock code %04x\n", LOWORD(Parameters));
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirDefineMifEnvironmentParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirInitializeParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
//
|
|
// once again, invent a structure to reflect the DOS CCB parameter table
|
|
// as defined in the IBM LAN tech ref
|
|
//
|
|
|
|
typedef struct {
|
|
WORD BringUps;
|
|
WORD SharedRam;
|
|
BYTE Reserved[4];
|
|
DWORD AdapterCheckAppendage;
|
|
DWORD NetworkStatusChangeAppendage;
|
|
DWORD IoErrorAppendage;
|
|
} CCB1_DIR_INITIALIZE_PARMS, *PCCB1_DIR_INITIALIZE_PARMS;
|
|
|
|
PCCB1_DIR_INITIALIZE_PARMS parms = (PCCB1_DIR_INITIALIZE_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("DIR.INITIALIZE", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "bring ups %04x\n"
|
|
"shared RAM %04x\n"
|
|
"reserved %02x %02x %02x %02x\n"
|
|
"adap. check %04x:%04x\n"
|
|
"n/w status %04x:%04x\n"
|
|
"pc error %04x:%04x\n",
|
|
READ_WORD(&parms->BringUps),
|
|
READ_WORD(&parms->SharedRam),
|
|
parms->Reserved[0],
|
|
parms->Reserved[1],
|
|
parms->Reserved[2],
|
|
parms->Reserved[3],
|
|
GET_SEGMENT(&parms->AdapterCheckAppendage),
|
|
GET_OFFSET(&parms->AdapterCheckAppendage),
|
|
GET_SEGMENT(&parms->NetworkStatusChangeAppendage),
|
|
GET_OFFSET(&parms->NetworkStatusChangeAppendage),
|
|
GET_SEGMENT(&parms->IoErrorAppendage),
|
|
GET_OFFSET(&parms->IoErrorAppendage)
|
|
);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirModifyOpenParmsParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirOpenAdapterParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_DOS_DIR_OPEN_ADAPTER_PARMS dosParms = (PLLC_DOS_DIR_OPEN_ADAPTER_PARMS)Parameters;
|
|
PLLC_DIR_OPEN_ADAPTER_PARMS ntParms = (PLLC_DIR_OPEN_ADAPTER_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("DIR.OPEN.ADAPTER", Parameters, IsDos, Segment, Offset);
|
|
|
|
if (IsDos) {
|
|
PADAPTER_PARMS pAdapterParms = READ_FAR_POINTER(&dosParms->pAdapterParms);
|
|
PDIRECT_PARMS pDirectParms = READ_FAR_POINTER(&dosParms->pDirectParms);
|
|
PDLC_PARMS pDlcParms = READ_FAR_POINTER(&dosParms->pDlcParms);
|
|
PNCB_PARMS pNcbParms = READ_FAR_POINTER(&dosParms->pNcbParms);
|
|
ULPBYTE pProductId;
|
|
DWORD i;
|
|
|
|
DBGPRINT(
|
|
"adapter parms %04x:%04x\n"
|
|
"direct parms %04x:%04x\n"
|
|
"DLC parms %04x:%04x\n"
|
|
"NCB parms %04x:%04x\n",
|
|
GET_SEGMENT(&dosParms->pAdapterParms),
|
|
GET_OFFSET(&dosParms->pAdapterParms),
|
|
GET_SEGMENT(&dosParms->pDirectParms),
|
|
GET_OFFSET(&dosParms->pDirectParms),
|
|
GET_SEGMENT(&dosParms->pDlcParms),
|
|
GET_OFFSET(&dosParms->pDlcParms),
|
|
GET_SEGMENT(&dosParms->pNcbParms),
|
|
GET_OFFSET(&dosParms->pNcbParms)
|
|
);
|
|
if (pAdapterParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"ADAPTER_PARMS @%04x:%04x\n"
|
|
"open error %04x\n"
|
|
"open options %04x\n"
|
|
"node address %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"group address %08x\n"
|
|
"func. address %08x\n"
|
|
"# rcv buffers %04x\n"
|
|
"rcv buf len %04x\n"
|
|
"DHB len %04x\n"
|
|
"# DHBs %02x\n"
|
|
"Reserved %02x\n"
|
|
"Open Lock %04x\n"
|
|
"Product ID %04x:%04x\n",
|
|
GET_SEGMENT(&dosParms->pAdapterParms),
|
|
GET_OFFSET(&dosParms->pAdapterParms),
|
|
READ_WORD(&pAdapterParms->OpenErrorCode),
|
|
READ_WORD(&pAdapterParms->OpenOptions),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[0]),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[1]),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[2]),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[3]),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[4]),
|
|
READ_BYTE(&pAdapterParms->NodeAddress[5]),
|
|
READ_DWORD(&pAdapterParms->GroupAddress),
|
|
READ_DWORD(&pAdapterParms->FunctionalAddress),
|
|
READ_WORD(&pAdapterParms->NumberReceiveBuffers),
|
|
READ_WORD(&pAdapterParms->ReceiveBufferLength),
|
|
READ_WORD(&pAdapterParms->DataHoldBufferLength),
|
|
READ_BYTE(&pAdapterParms->NumberDataHoldBuffers),
|
|
READ_BYTE(&pAdapterParms->Reserved),
|
|
READ_WORD(&pAdapterParms->OpenLock),
|
|
GET_SEGMENT(&pAdapterParms->ProductId),
|
|
GET_OFFSET(&pAdapterParms->ProductId)
|
|
);
|
|
pProductId = READ_FAR_POINTER(&pAdapterParms->ProductId);
|
|
if (pProductId) {
|
|
DBGPRINT("\nPRODUCT ID:\n");
|
|
for (i=0; i<18; ++i) {
|
|
DBGPRINT("%02x ", *pProductId++);
|
|
}
|
|
DBGPRINT("\n");
|
|
}
|
|
}
|
|
if (pDirectParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"DIRECT_PARMS @%04x:%04x\n"
|
|
"dir buf size %04x\n"
|
|
"dir pool blx %04x\n"
|
|
"dir buf pool %04x:%04x\n"
|
|
"adap chk exit %04x:%04x\n"
|
|
"nw stat exit %04x:%04x\n"
|
|
"pc error exit %04x:%04x\n"
|
|
"adap wrk area %04x:%04x\n"
|
|
"adap wrk req. %04x\n"
|
|
"adap wrk act %04x\n",
|
|
GET_SEGMENT(&dosParms->pDirectParms),
|
|
GET_OFFSET(&dosParms->pDirectParms),
|
|
READ_WORD(&pDirectParms->DirectBufferSize),
|
|
READ_WORD(&pDirectParms->DirectPoolBlocks),
|
|
GET_SEGMENT(&pDirectParms->DirectBufferPool),
|
|
GET_OFFSET(&pDirectParms->DirectBufferPool),
|
|
GET_SEGMENT(&pDirectParms->AdapterCheckExit),
|
|
GET_OFFSET(&pDirectParms->AdapterCheckExit),
|
|
GET_SEGMENT(&pDirectParms->NetworkStatusExit),
|
|
GET_OFFSET(&pDirectParms->NetworkStatusExit),
|
|
GET_SEGMENT(&pDirectParms->PcErrorExit),
|
|
GET_OFFSET(&pDirectParms->PcErrorExit),
|
|
GET_SEGMENT(&pDirectParms->AdapterWorkArea),
|
|
GET_OFFSET(&pDirectParms->AdapterWorkArea),
|
|
READ_WORD(&pDirectParms->AdapterWorkAreaRequested),
|
|
READ_WORD(&pDirectParms->AdapterWorkAreaActual)
|
|
);
|
|
}
|
|
if (pDlcParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"DLC_PARMS @%04x:%04x\n"
|
|
"max SAPs %02x\n"
|
|
"max links %02x\n"
|
|
"max grp SAPs %02x\n"
|
|
"max grp memb %02x\n"
|
|
"T1 tick 1 %02x\n"
|
|
"T2 tick 1 %02x\n"
|
|
"Ti tick 1 %02x\n"
|
|
"T1 tick 2 %02x\n"
|
|
"T2 tick 2 %02x\n"
|
|
"Ti tick 2 %02x\n",
|
|
GET_SEGMENT(&dosParms->pDlcParms),
|
|
GET_OFFSET(&dosParms->pDlcParms),
|
|
READ_BYTE(&pDlcParms->MaxSaps),
|
|
READ_BYTE(&pDlcParms->MaxStations),
|
|
READ_BYTE(&pDlcParms->MaxGroupSaps),
|
|
READ_BYTE(&pDlcParms->MaxGroupMembers),
|
|
READ_BYTE(&pDlcParms->T1Tick1),
|
|
READ_BYTE(&pDlcParms->T2Tick1),
|
|
READ_BYTE(&pDlcParms->TiTick1),
|
|
READ_BYTE(&pDlcParms->T1Tick2),
|
|
READ_BYTE(&pDlcParms->T2Tick2),
|
|
READ_BYTE(&pDlcParms->TiTick2)
|
|
);
|
|
}
|
|
if (pNcbParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"NCB_PARMS @%04x:%04x???\n",
|
|
GET_SEGMENT(&dosParms->pNcbParms),
|
|
GET_OFFSET(&dosParms->pNcbParms)
|
|
|
|
);
|
|
}
|
|
} else {
|
|
PLLC_ADAPTER_OPEN_PARMS pAdapterParms = ntParms->pAdapterParms;
|
|
PLLC_EXTENDED_ADAPTER_PARMS pExtendedParms = ntParms->pExtendedParms;
|
|
PLLC_DLC_PARMS pDlcParms = ntParms->pDlcParms;
|
|
PVOID pNcbParms = ntParms->pReserved1;
|
|
|
|
DBGPRINT(
|
|
"adapter parms %08x\n"
|
|
"direct parms %08x\n"
|
|
"DLC parms %08x\n"
|
|
"NCB parms %08x\n",
|
|
pAdapterParms,
|
|
pExtendedParms,
|
|
pDlcParms,
|
|
pNcbParms
|
|
);
|
|
if (pAdapterParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"ADAPTER_PARMS @%08x\n"
|
|
"open error %04x\n"
|
|
"open options %04x\n"
|
|
"node address %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"group address %08x\n"
|
|
"func. address %08x\n"
|
|
"reserved 1 %04x\n"
|
|
"reserved 2 %04x\n"
|
|
"max frame len %04x\n"
|
|
"reserved 3[0] %04x\n"
|
|
"reserved 3[1] %04x\n"
|
|
"reserved 3[2] %04x\n"
|
|
"reserved 3[3] %04x\n"
|
|
"bring ups %04x\n"
|
|
"init warnings %04x\n"
|
|
"reserved 4[0] %04x\n"
|
|
"reserved 4[1] %04x\n"
|
|
"reserved 4[2] %04x\n",
|
|
pAdapterParms,
|
|
pAdapterParms->usOpenErrorCode,
|
|
pAdapterParms->usOpenOptions,
|
|
pAdapterParms->auchNodeAddress[0],
|
|
pAdapterParms->auchNodeAddress[1],
|
|
pAdapterParms->auchNodeAddress[2],
|
|
pAdapterParms->auchNodeAddress[3],
|
|
pAdapterParms->auchNodeAddress[4],
|
|
pAdapterParms->auchNodeAddress[5],
|
|
*(UNALIGNED DWORD *)&pAdapterParms->auchGroupAddress,
|
|
*(UNALIGNED DWORD *)&pAdapterParms->auchFunctionalAddress,
|
|
pAdapterParms->usReserved1,
|
|
pAdapterParms->usReserved2,
|
|
pAdapterParms->usMaxFrameSize,
|
|
pAdapterParms->usReserved3[0],
|
|
pAdapterParms->usReserved3[1],
|
|
pAdapterParms->usReserved3[2],
|
|
pAdapterParms->usReserved3[3],
|
|
pAdapterParms->usBringUps,
|
|
pAdapterParms->InitWarnings,
|
|
pAdapterParms->usReserved4[0],
|
|
pAdapterParms->usReserved4[1],
|
|
pAdapterParms->usReserved4[2]
|
|
);
|
|
}
|
|
if (pExtendedParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"EXTENDED PARMS @%08x\n"
|
|
"hBufferPool %08x\n"
|
|
"pSecurityDesc %08x\n"
|
|
"Ethernet Type %08x\n",
|
|
pExtendedParms,
|
|
pExtendedParms->hBufferPool,
|
|
pExtendedParms->pSecurityDescriptor,
|
|
pExtendedParms->LlcEthernetType
|
|
);
|
|
}
|
|
if (pDlcParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"DLC_PARMS @%04x:%04x\n"
|
|
"max SAPs %02x\n"
|
|
"max links %02x\n"
|
|
"max grp SAPs %02x\n"
|
|
"max grp memb %02x\n"
|
|
"T1 tick 1 %02x\n"
|
|
"T2 tick 1 %02x\n"
|
|
"Ti tick 1 %02x\n"
|
|
"T1 tick 2 %02x\n"
|
|
"T2 tick 2 %02x\n"
|
|
"Ti tick 2 %02x\n",
|
|
pDlcParms,
|
|
pDlcParms->uchDlcMaxSaps,
|
|
pDlcParms->uchDlcMaxStations,
|
|
pDlcParms->uchDlcMaxGroupSaps,
|
|
pDlcParms->uchDlcMaxGroupMembers,
|
|
pDlcParms->uchT1_TickOne,
|
|
pDlcParms->uchT2_TickOne,
|
|
pDlcParms->uchTi_TickOne,
|
|
pDlcParms->uchT1_TickTwo,
|
|
pDlcParms->uchT2_TickTwo,
|
|
pDlcParms->uchTi_TickTwo
|
|
);
|
|
}
|
|
if (pNcbParms) {
|
|
DBGPRINT(
|
|
"\n"
|
|
"NCB_PARMS @%08x???\n",
|
|
pNcbParms
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirReadLog(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("DIR.READ.LOG", Parameters, IsDos, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirRestoreOpenParmsParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetFunctionalAddressParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DBGPRINT( "funct addr %08lx\n", Parameters);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetGroupAddressParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DBGPRINT( "group addr %08lx\n", Parameters);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirSetUserAppendageParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_DIR_SET_USER_APPENDAGE_PARMS parms = (PLLC_DIR_SET_USER_APPENDAGE_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("DIR.SET.USER.APPENDAGE", Parameters, IsDos, Segment, Offset);
|
|
|
|
if (IsDos) {
|
|
DBGPRINT( "adapt check %04x:%04x\n"
|
|
"n/w status %04x:%04x\n"
|
|
"w/s error %04x:%04x\n",
|
|
GET_SEGMENT(&parms->dpAdapterCheckExit),
|
|
GET_OFFSET(&parms->dpAdapterCheckExit),
|
|
GET_SEGMENT(&parms->dpNetworkStatusExit),
|
|
GET_OFFSET(&parms->dpNetworkStatusExit),
|
|
GET_SEGMENT(&parms->dpPcErrorExit),
|
|
GET_OFFSET(&parms->dpPcErrorExit)
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirStatusParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PDOS_DIR_STATUS_PARMS dosParms = (PDOS_DIR_STATUS_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("DIR.STATUS", Parameters, IsDos, Segment, Offset);
|
|
|
|
if (IsDos) {
|
|
DBGPRINT( "perm addr %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"local addr %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"group addr %08lx\n"
|
|
"func addr %08lx\n"
|
|
"max SAPs %02x\n"
|
|
"open SAPs %02x\n"
|
|
"max links %02x\n"
|
|
"open links %02x\n"
|
|
"avail links %02x\n"
|
|
"adapt config %02x\n"
|
|
"ucode level %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"adap parms %04x:%04x\n"
|
|
"adap MAC %04x:%04x\n"
|
|
"timer tick %04x:%04x\n"
|
|
"last NW stat %04x\n"
|
|
"ext. status %04x:%04x\n",
|
|
dosParms->auchPermanentAddress[0],
|
|
dosParms->auchPermanentAddress[1],
|
|
dosParms->auchPermanentAddress[2],
|
|
dosParms->auchPermanentAddress[3],
|
|
dosParms->auchPermanentAddress[4],
|
|
dosParms->auchPermanentAddress[5],
|
|
dosParms->auchNodeAddress[0],
|
|
dosParms->auchNodeAddress[1],
|
|
dosParms->auchNodeAddress[2],
|
|
dosParms->auchNodeAddress[3],
|
|
dosParms->auchNodeAddress[4],
|
|
dosParms->auchNodeAddress[5],
|
|
READ_DWORD(&dosParms->auchGroupAddress),
|
|
READ_DWORD(&dosParms->auchFunctAddr),
|
|
dosParms->uchMaxSap,
|
|
dosParms->uchOpenSaps,
|
|
dosParms->uchMaxStations,
|
|
dosParms->uchOpenStation,
|
|
dosParms->uchAvailStations,
|
|
dosParms->uchAdapterConfig,
|
|
dosParms->auchMicroCodeLevel[0],
|
|
dosParms->auchMicroCodeLevel[1],
|
|
dosParms->auchMicroCodeLevel[2],
|
|
dosParms->auchMicroCodeLevel[3],
|
|
dosParms->auchMicroCodeLevel[4],
|
|
dosParms->auchMicroCodeLevel[5],
|
|
dosParms->auchMicroCodeLevel[6],
|
|
dosParms->auchMicroCodeLevel[7],
|
|
dosParms->auchMicroCodeLevel[8],
|
|
dosParms->auchMicroCodeLevel[9],
|
|
GET_SEGMENT(&dosParms->dpAdapterParmsAddr),
|
|
GET_OFFSET(&dosParms->dpAdapterParmsAddr),
|
|
GET_SEGMENT(&dosParms->dpAdapterMacAddr),
|
|
GET_OFFSET(&dosParms->dpAdapterMacAddr),
|
|
GET_SEGMENT(&dosParms->dpTimerTick),
|
|
GET_OFFSET(&dosParms->dpTimerTick),
|
|
READ_WORD(&dosParms->usLastNetworkStatus),
|
|
GET_SEGMENT(&dosParms->dpExtendedParms),
|
|
GET_OFFSET(&dosParms->dpExtendedParms)
|
|
);
|
|
} else {
|
|
DBGPRINT("no dump for this table yet\n");
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
DBGPRINT( "cancel timer %04x:%04x\n",
|
|
HIWORD(Parameters),
|
|
LOWORD(Parameters)
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerCancelGroupParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
DBGPRINT( "cancel timer %04x:%04x\n",
|
|
HIWORD(Parameters),
|
|
LOWORD(Parameters)
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDirTimerSetParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
DBGPRINT( "timer value %04x\n",
|
|
LOWORD(Parameters)
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcCloseSapParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
DBGPRINT( "STATION_ID %04x\n"
|
|
"reserved %04x\n",
|
|
LOWORD(Parameters),
|
|
HIWORD(Parameters)
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcCloseStationParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
DBGPRINT( "STATION_ID %04x\n"
|
|
"reserved %02x %02x\n",
|
|
LOWORD(Parameters),
|
|
LOBYTE(HIWORD(Parameters)),
|
|
HIBYTE(HIWORD(Parameters))
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcConnectStationParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
LLC_DLC_CONNECT_PARMS UNALIGNED * parms = (PLLC_DLC_CONNECT_PARMS)Parameters;
|
|
ULPBYTE routing = NULL;
|
|
int i;
|
|
|
|
DumpParameterTableHeader("DLC.CONNECT.STATION", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"reserved %02x %02x\n",
|
|
READ_WORD(&parms->usStationId),
|
|
((ULPBYTE)(&parms->usReserved))[0],
|
|
((ULPBYTE)(&parms->usReserved))[1]
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"routing addr %04x:%04x\n",
|
|
GET_SEGMENT(&parms->pRoutingInfo),
|
|
GET_OFFSET(&parms->pRoutingInfo)
|
|
);
|
|
routing = READ_FAR_POINTER(&parms->pRoutingInfo);
|
|
} else {
|
|
DBGPRINT(
|
|
"routing addr %08x\n",
|
|
parms->pRoutingInfo
|
|
);
|
|
routing = parms->pRoutingInfo;
|
|
}
|
|
if (routing) {
|
|
DBGPRINT("ROUTING INFO: ");
|
|
for (i=0; i<18; ++i) {
|
|
DBGPRINT("%02x ", routing[i]);
|
|
}
|
|
DBGPRINT("\n");
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcFlowControlParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DBGPRINT(
|
|
"STATION_ID %04x\n"
|
|
"flow control %02x [%s]\n"
|
|
"reserved %02x\n",
|
|
LOWORD(Parameters),
|
|
LOBYTE(HIWORD(Parameters)),
|
|
MapFlowControl(LOBYTE(HIWORD(Parameters))),
|
|
HIBYTE(HIWORD(Parameters))
|
|
);
|
|
}
|
|
|
|
PRIVATE LPSTR MapFlowControl(BYTE FlowControl) {
|
|
if (FlowControl & 0x80) {
|
|
if (FlowControl & 0x40) {
|
|
return "reset local_busy(buffer)";
|
|
} else {
|
|
return "reset local_busy(user)";
|
|
}
|
|
} else {
|
|
return "set local_busy(user)";
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcModifyParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcOpenSapParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_DLC_OPEN_SAP_PARMS parms = (PLLC_DLC_OPEN_SAP_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("DLC.OPEN.SAP", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"user stat %04x\n"
|
|
"T1 %02x\n"
|
|
"T2 %02x\n"
|
|
"Ti %02x\n"
|
|
"max out %02x\n"
|
|
"max in %02x\n"
|
|
"max out inc %02x\n"
|
|
"max retry %02x\n"
|
|
"max members %02x\n"
|
|
"max I field %04x\n"
|
|
"SAP value %02x\n"
|
|
"options %02x [%s]\n"
|
|
"link count %02x\n"
|
|
"reserved %02x %02x\n"
|
|
"group count %02x\n",
|
|
READ_WORD(&parms->usStationId),
|
|
READ_WORD(&parms->usUserStatValue),
|
|
parms->uchT1,
|
|
parms->uchT2,
|
|
parms->uchTi,
|
|
parms->uchMaxOut,
|
|
parms->uchMaxIn,
|
|
parms->uchMaxOutIncr,
|
|
parms->uchMaxRetryCnt,
|
|
parms->uchMaxMembers,
|
|
READ_WORD(&parms->usMaxI_Field),
|
|
parms->uchSapValue,
|
|
parms->uchOptionsPriority,
|
|
MapOptionsPriority(parms->uchOptionsPriority),
|
|
parms->uchcStationCount,
|
|
parms->uchReserved2[0],
|
|
parms->uchReserved2[1],
|
|
parms->cGroupCount
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"group list %04x:%04x\n"
|
|
"dlc stat app %04x:%04x\n",
|
|
GET_SEGMENT(&parms->pGroupList),
|
|
GET_OFFSET(&parms->pGroupList),
|
|
GET_SEGMENT(&parms->DlcStatusFlags),
|
|
GET_OFFSET(&parms->DlcStatusFlags)
|
|
);
|
|
|
|
//
|
|
// some code here to dump group list
|
|
//
|
|
|
|
} else {
|
|
DBGPRINT(
|
|
"group list %08x\n"
|
|
"dlc status %08x\n",
|
|
parms->pGroupList,
|
|
parms->DlcStatusFlags
|
|
);
|
|
}
|
|
DBGPRINT( "buffer size %04x\n"
|
|
"pool length %04x\n",
|
|
READ_WORD(&parms->uchReserved3[0]),
|
|
READ_WORD(&parms->uchReserved3[2])
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"buffer pool %04x:%04x\n",
|
|
READ_WORD(&parms->uchReserved3[6]),
|
|
READ_WORD(&parms->uchReserved3[4])
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"buffer pool %08x\n",
|
|
*(LPDWORD)&parms->uchReserved3[4]
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE LPSTR MapOptionsPriority(UCHAR OptionsPriority) {
|
|
static char buf[80];
|
|
char* bufptr = buf;
|
|
|
|
bufptr += sprintf(buf, "Access Priority=%d", (OptionsPriority & 0xe0) >> 5);
|
|
if (OptionsPriority & 8) {
|
|
bufptr += sprintf(bufptr, " XID handled by APP");
|
|
} else {
|
|
bufptr += sprintf(bufptr, " XID handled by DLC");
|
|
}
|
|
if (OptionsPriority & 4) {
|
|
bufptr += sprintf(bufptr, " Individual SAP");
|
|
}
|
|
if (OptionsPriority & 2) {
|
|
bufptr += sprintf(bufptr, " Group SAP");
|
|
}
|
|
if (OptionsPriority & 1) {
|
|
bufptr += sprintf(bufptr, " Group Member SAP");
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcOpenStationParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_DLC_OPEN_STATION_PARMS parms = (PLLC_DLC_OPEN_STATION_PARMS)Parameters;
|
|
ULPBYTE dest = NULL;
|
|
int i;
|
|
|
|
DumpParameterTableHeader("DLC.OPEN.STATION", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "sap station %04x\n"
|
|
"link station %04x\n"
|
|
"T1 %02x\n"
|
|
"T2 %02x\n"
|
|
"Ti %02x\n"
|
|
"max out %02x\n"
|
|
"max in %02x\n"
|
|
"max out inc %02x\n"
|
|
"max retry %02x\n"
|
|
"remote SAP %02x\n"
|
|
"max I field %04x\n"
|
|
"access pri %02x\n",
|
|
READ_WORD(&parms->usSapStationId),
|
|
READ_WORD(&parms->usLinkStationId),
|
|
parms->uchT1,
|
|
parms->uchT2,
|
|
parms->uchTi,
|
|
parms->uchMaxOut,
|
|
parms->uchMaxIn,
|
|
parms->uchMaxOutIncr,
|
|
parms->uchMaxRetryCnt,
|
|
parms->uchRemoteSap,
|
|
READ_WORD(&parms->usMaxI_Field),
|
|
parms->uchAccessPriority
|
|
);
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"destination %04x:%04x\n",
|
|
GET_SEGMENT(&parms->pRemoteNodeAddress),
|
|
GET_OFFSET(&parms->pRemoteNodeAddress)
|
|
);
|
|
dest = READ_FAR_POINTER(&parms->pRemoteNodeAddress);
|
|
} else {
|
|
DBGPRINT(
|
|
"destination %08x\n",
|
|
parms->pRemoteNodeAddress
|
|
);
|
|
dest = parms->pRemoteNodeAddress;
|
|
}
|
|
if (dest) {
|
|
DBGPRINT("DESTINATION ADDRESS: ");
|
|
for (i=0; i<6; ++i) {
|
|
DBGPRINT("%02x ", dest[i]);
|
|
}
|
|
DBGPRINT("\n");
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcReallocateParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcResetParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DBGPRINT( "STATION_ID %04x\n"
|
|
"reserved %02x %02x\n",
|
|
LOWORD(Parameters),
|
|
LOBYTE(HIWORD(Parameters)),
|
|
HIBYTE(HIWORD(Parameters))
|
|
);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpDlcStatisticsParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpPdtTraceOffParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpPdtTraceOnParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReadParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_READ_PARMS parms = (PLLC_READ_PARMS)Parameters;
|
|
|
|
DumpParameterTableHeader("READ", Parameters, IsDos, Segment, Offset);
|
|
|
|
//
|
|
// this parameter table not for DOS
|
|
//
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"option ind. %02x\n"
|
|
"event set %02x\n"
|
|
"event %02x [%s]\n"
|
|
"crit. subset %02x\n"
|
|
"notify flag %08x\n",
|
|
parms->usStationId,
|
|
parms->uchOptionIndicator,
|
|
parms->uchEventSet,
|
|
parms->uchEvent,
|
|
MapReadEvent(parms->uchEvent),
|
|
parms->uchCriticalSubset,
|
|
parms->ulNotificationFlag
|
|
);
|
|
|
|
//
|
|
// rest of table interpreted differently depending on whether status change
|
|
//
|
|
|
|
if (parms->uchEvent & 0x38) {
|
|
DBGPRINT(
|
|
"station id %04x\n"
|
|
"status code %04x [%s]\n"
|
|
"FRMR data %02x %02x %02x %02x %02x\n"
|
|
"access pri. %02x\n"
|
|
"remote addr %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
"remote SAP %02x\n"
|
|
"reserved %02x\n"
|
|
"user stat %04x\n",
|
|
parms->Type.Status.usStationId,
|
|
parms->Type.Status.usDlcStatusCode,
|
|
MapDlcStatus(parms->Type.Status.usDlcStatusCode),
|
|
parms->Type.Status.uchFrmrData[0],
|
|
parms->Type.Status.uchFrmrData[1],
|
|
parms->Type.Status.uchFrmrData[2],
|
|
parms->Type.Status.uchFrmrData[3],
|
|
parms->Type.Status.uchFrmrData[4],
|
|
parms->Type.Status.uchAccessPritority,
|
|
parms->Type.Status.uchRemoteNodeAddress[0],
|
|
parms->Type.Status.uchRemoteNodeAddress[1],
|
|
parms->Type.Status.uchRemoteNodeAddress[2],
|
|
parms->Type.Status.uchRemoteNodeAddress[3],
|
|
parms->Type.Status.uchRemoteNodeAddress[4],
|
|
parms->Type.Status.uchRemoteNodeAddress[5],
|
|
parms->Type.Status.uchRemoteSap,
|
|
parms->Type.Status.uchReserved,
|
|
parms->Type.Status.usUserStatusValue
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"CCB count %04x\n"
|
|
"CCB list %08x\n"
|
|
"buffer count %04x\n"
|
|
"buffer list %08x\n"
|
|
"frame count %04x\n"
|
|
"frame list %08x\n"
|
|
"error code %04x\n"
|
|
"error data %04x %04x %04x\n",
|
|
parms->Type.Event.usCcbCount,
|
|
parms->Type.Event.pCcbCompletionList,
|
|
parms->Type.Event.usBufferCount,
|
|
parms->Type.Event.pFirstBuffer,
|
|
parms->Type.Event.usReceivedFrameCount,
|
|
parms->Type.Event.pReceivedFrame,
|
|
parms->Type.Event.usEventErrorCode,
|
|
parms->Type.Event.usEventErrorData[0],
|
|
parms->Type.Event.usEventErrorData[1],
|
|
parms->Type.Event.usEventErrorData[2]
|
|
);
|
|
|
|
//
|
|
// address of CCB is in DOS memory
|
|
//
|
|
|
|
if (parms->Type.Event.usCcbCount) {
|
|
DumpCcb(DOS_PTR_TO_FLAT(parms->Type.Event.pCcbCompletionList),
|
|
TRUE, // DumpAll
|
|
FALSE, // CcbIsInput
|
|
TRUE, // IsDos
|
|
HIWORD(parms->Type.Event.pCcbCompletionList),
|
|
LOWORD(parms->Type.Event.pCcbCompletionList)
|
|
);
|
|
}
|
|
if (parms->Type.Event.usReceivedFrameCount) {
|
|
DumpReceiveDataBuffer(parms->Type.Event.pReceivedFrame, FALSE, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
PRIVATE LPSTR MapReadEvent(UCHAR Event) {
|
|
switch (Event) {
|
|
case 0x80:
|
|
return "Reserved Event!";
|
|
|
|
case 0x40:
|
|
return "System Action (non-critical)";
|
|
|
|
case 0x20:
|
|
return "Network Status (non-critical)";
|
|
|
|
case 0x10:
|
|
return "Critical Exception";
|
|
|
|
case 0x8:
|
|
return "DLC Status Change";
|
|
|
|
case 0x4:
|
|
return "Receive Data";
|
|
|
|
case 0x2:
|
|
return "Transmit Completion";
|
|
|
|
case 0x1:
|
|
return "Command Completion";
|
|
}
|
|
return "Unknown Read Event";
|
|
}
|
|
|
|
PRIVATE LPSTR MapDlcStatus(WORD Status) {
|
|
if (Status & 0x8000) {
|
|
return "Link lost";
|
|
} else if (Status & 0x4000) {
|
|
return "DM/DISC Received -or- DISC ack'd";
|
|
} else if (Status & 0x2000) {
|
|
return "FRMR Received";
|
|
} else if (Status & 0x1000) {
|
|
return "FRMR Sent";
|
|
} else if (Status & 0x0800) {
|
|
return "SABME Received for open link station";
|
|
} else if (Status & 0x0400) {
|
|
return "SABME Received - link station opened";
|
|
} else if (Status & 0x0200) {
|
|
return "REMOTE Busy Entered";
|
|
} else if (Status & 0x0100) {
|
|
return "REMOTE Busy Left";
|
|
} else if (Status & 0x0080) {
|
|
return "Ti EXPIRED";
|
|
} else if (Status & 0x0040) {
|
|
return "DLC counter overflow - issue DLC.STATISTICS";
|
|
} else if (Status & 0x0020) {
|
|
return "Access Priority lowered";
|
|
} else if (Status & 0x001e) {
|
|
return "*** ERROR - INVALID STATUS ***";
|
|
} else if (Status & 0x0001) {
|
|
return "Entered LOCAL Busy";
|
|
} else {
|
|
return "Unknown DLC Status";
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReadCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
//
|
|
// the format of the recieve parameter table is different depending on
|
|
// whether this is a DOS command (CCB1) or NT (CCB2)
|
|
//
|
|
|
|
PLLC_RECEIVE_PARMS ntParms = (PLLC_RECEIVE_PARMS)Parameters;
|
|
PLLC_DOS_RECEIVE_PARMS dosParms = (PLLC_DOS_RECEIVE_PARMS)Parameters;
|
|
PLLC_DOS_RECEIVE_PARMS_EX dosExParms = (PLLC_DOS_RECEIVE_PARMS_EX)Parameters;
|
|
PVOID Buffer;
|
|
|
|
DumpParameterTableHeader("RECEIVE", Parameters, IsDos, Segment, Offset);
|
|
|
|
//
|
|
// some common bits: use any structure pointer
|
|
//
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"user length %04x\n",
|
|
READ_WORD(&ntParms->usStationId),
|
|
READ_WORD(&ntParms->usUserLength)
|
|
);
|
|
|
|
//
|
|
// dump segmented pointers for DOS, flat for NT
|
|
//
|
|
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"receive exit %04x:%04x\n"
|
|
"first buffer %04x:%04x\n",
|
|
GET_SEGMENT(&dosParms->ulReceiveExit),
|
|
GET_OFFSET(&dosParms->ulReceiveExit),
|
|
GET_SEGMENT(&dosParms->pFirstBuffer),
|
|
GET_OFFSET(&dosParms->pFirstBuffer)
|
|
);
|
|
Buffer = READ_FAR_POINTER(&dosParms->pFirstBuffer);
|
|
|
|
//
|
|
// use Segment & Offset to address received data buffer
|
|
//
|
|
|
|
Segment = GET_SEGMENT(&dosParms->pFirstBuffer);
|
|
Offset = GET_OFFSET(&dosParms->pFirstBuffer);
|
|
} else {
|
|
DBGPRINT(
|
|
"receive flag %08x\n"
|
|
"first buffer %08x\n",
|
|
ntParms->ulReceiveFlag,
|
|
ntParms->pFirstBuffer
|
|
);
|
|
Buffer = ntParms->pFirstBuffer;
|
|
}
|
|
|
|
//
|
|
// more common bits
|
|
//
|
|
|
|
DBGPRINT( "options %02x\n",
|
|
ntParms->uchOptions
|
|
);
|
|
if (!IsDos) {
|
|
DBGPRINT(
|
|
"reserved1 %02x %02x %02x\n"
|
|
"read options %02x\n"
|
|
"reserved2 %02x %02x %02x\n"
|
|
"original CCB %08x\n"
|
|
"orig. exit %08x\n",
|
|
ntParms->auchReserved1[0],
|
|
ntParms->auchReserved1[1],
|
|
ntParms->auchReserved1[2],
|
|
ntParms->uchRcvReadOption,
|
|
((PLLC_DOS_RECEIVE_PARMS_EX)ntParms)->auchReserved2[0],
|
|
((PLLC_DOS_RECEIVE_PARMS_EX)ntParms)->auchReserved2[1],
|
|
((PLLC_DOS_RECEIVE_PARMS_EX)ntParms)->auchReserved2[2],
|
|
((PLLC_DOS_RECEIVE_PARMS_EX)ntParms)->dpOriginalCcbAddress,
|
|
((PLLC_DOS_RECEIVE_PARMS_EX)ntParms)->dpCompletionFlag
|
|
);
|
|
/* } else {
|
|
|
|
//
|
|
// we have no way of knowing from the general purpose parameters if this
|
|
// is the original DOS CCB1 RECEIVE parameter table, or the extended
|
|
// RECEIVE parameter table that we create. Dump the extended bits for
|
|
// DOS anyhow
|
|
//
|
|
|
|
DBGPRINT(
|
|
"\nExtended RECEIVE parameters for table @%08x\n"
|
|
"reserved1 %02x %02x %02x\n"
|
|
"read options %02x\n"
|
|
"reserved2 %02x %02x %02x\n"
|
|
"original CCB %04x:%04x\n"
|
|
"orig. exit %04x:%04x\n",
|
|
Parameters,
|
|
dosExParms->auchReserved1[0],
|
|
dosExParms->auchReserved1[1],
|
|
dosExParms->auchReserved1[2],
|
|
dosExParms->uchRcvReadOption,
|
|
dosExParms->auchReserved2[0],
|
|
dosExParms->auchReserved2[1],
|
|
dosExParms->auchReserved2[2],
|
|
GET_SEGMENT(&dosExParms->dpOriginalCcbAddress),
|
|
GET_OFFSET(&dosExParms->dpOriginalCcbAddress),
|
|
GET_SEGMENT(&dosExParms->dpCompletionFlag),
|
|
GET_OFFSET(&dosExParms->dpCompletionFlag)
|
|
);
|
|
*/
|
|
}
|
|
|
|
//
|
|
// only dump the buffer(s) if this is an output CCB dump
|
|
//
|
|
|
|
if (Buffer && !IsInput) {
|
|
DumpReceiveDataBuffer(Buffer, IsDos, Segment, Offset);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveCancelParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DBGPRINT("STATION_ID %04x\n", LOWORD(Parameters));
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpReceiveModifyParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_DOS_RECEIVE_MODIFY_PARMS parms = (PLLC_DOS_RECEIVE_MODIFY_PARMS)Parameters;
|
|
PVOID Buffer;
|
|
|
|
DumpParameterTableHeader("RECEIVE.MODIFY", Parameters, IsDos, Segment, Offset);
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"user length %04x\n"
|
|
"receive exit %04x:%04x\n"
|
|
"first buffer %04x:%04x\n"
|
|
"subroutine %04x:%04x\n",
|
|
READ_WORD(&parms->StationId),
|
|
READ_WORD(&parms->UserLength),
|
|
GET_SEGMENT(&parms->ReceivedDataExit),
|
|
GET_OFFSET(&parms->ReceivedDataExit),
|
|
GET_SEGMENT(&parms->FirstBuffer),
|
|
GET_OFFSET(&parms->FirstBuffer),
|
|
GET_SEGMENT(&parms->Subroutine),
|
|
GET_OFFSET(&parms->Subroutine)
|
|
);
|
|
Buffer = READ_FAR_POINTER(&parms->FirstBuffer);
|
|
if (Buffer) {
|
|
DumpReceiveDataBuffer(Buffer, IsDos, Segment, Offset);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitDirFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.DIR.FRAME", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitIFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.I.FRAME", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitTestCmdParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.TEST.CMD", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitUiFrameParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.UI.FRAME", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidCmdParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.XID.CMD", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidRespFinalParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.XID.RESP.FINAL", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitXidRespNotFinalParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
DumpParameterTableHeader("TRANSMIT.XID.RESP.NOT.FINAL", Parameters, IsDos, Segment, Offset);
|
|
DumpTransmitParms(Parameters, IsDos, IsInput, Segment, Offset);
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitParms(
|
|
DUMP_TABLE_PARMS
|
|
)
|
|
{
|
|
PLLC_TRANSMIT_PARMS ntParms = (PLLC_TRANSMIT_PARMS)Parameters;
|
|
PLLC_DOS_TRANSMIT_PARMS dosParms = (PLLC_DOS_TRANSMIT_PARMS)Parameters;
|
|
|
|
DBGPRINT( "station id %04x\n"
|
|
"frame status %02x\n"
|
|
"remote SAP %02x\n",
|
|
READ_WORD(&dosParms->usStationId),
|
|
dosParms->uchTransmitFs,
|
|
dosParms->uchRemoteSap
|
|
);
|
|
|
|
if (IsDos) {
|
|
DBGPRINT(
|
|
"xmit q1 %04x:%04x\n"
|
|
"xmit q2 %04x:%04x\n"
|
|
"buf. len. 1 %04x\n"
|
|
"buf. len. 2 %04x\n"
|
|
"buffer 1 %04x:%04x\n"
|
|
"buffer 2 %04x:%04x\n",
|
|
GET_SEGMENT(&dosParms->pXmitQueue1),
|
|
GET_OFFSET(&dosParms->pXmitQueue1),
|
|
GET_SEGMENT(&dosParms->pXmitQueue2),
|
|
GET_OFFSET(&dosParms->pXmitQueue2),
|
|
READ_WORD(&dosParms->cbBuffer1),
|
|
READ_WORD(&dosParms->cbBuffer2),
|
|
GET_SEGMENT(&dosParms->pBuffer1),
|
|
GET_OFFSET(&dosParms->pBuffer1),
|
|
GET_SEGMENT(&dosParms->pBuffer2),
|
|
GET_OFFSET(&dosParms->pBuffer2)
|
|
);
|
|
IF_DEBUG(DLC_TX_DATA) {
|
|
if (READ_DWORD(&dosParms->pXmitQueue1)) {
|
|
DBGPRINT("\nXMIT_QUEUE_ONE:\n");
|
|
DumpTransmitQueue(READ_DWORD(&dosParms->pXmitQueue1));
|
|
}
|
|
if (READ_DWORD(&dosParms->pXmitQueue2)) {
|
|
DBGPRINT("\nXMIT_QUEUE_TWO:\n");
|
|
DumpTransmitQueue(READ_DWORD(&dosParms->pXmitQueue2));
|
|
}
|
|
if (dosParms->cbBuffer1) {
|
|
DBGPRINT("\nBUFFER1:\n");
|
|
DumpData(NULL,
|
|
NULL,
|
|
dosParms->cbBuffer1,
|
|
DD_UPPER_CASE,
|
|
0,
|
|
TRUE,
|
|
GET_SEGMENT(&dosParms->pBuffer1),
|
|
GET_OFFSET(&dosParms->pBuffer1)
|
|
);
|
|
}
|
|
if (dosParms->cbBuffer2) {
|
|
DBGPRINT("\nBUFFER2:\n");
|
|
DumpData(NULL,
|
|
NULL,
|
|
dosParms->cbBuffer2,
|
|
DD_UPPER_CASE,
|
|
0,
|
|
TRUE,
|
|
GET_SEGMENT(&dosParms->pBuffer2),
|
|
GET_OFFSET(&dosParms->pBuffer2)
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
DBGPRINT(
|
|
"xmit q1 %08x\n"
|
|
"xmit q2 %08x\n"
|
|
"buf. len. 1 %02x\n"
|
|
"buf. len. 2 %02x\n"
|
|
"buffer 1 %08x\n"
|
|
"buffer 2 %08x\n"
|
|
"xmt read opt %02x\n",
|
|
ntParms->pXmitQueue1,
|
|
ntParms->pXmitQueue2,
|
|
ntParms->cbBuffer1,
|
|
ntParms->cbBuffer2,
|
|
ntParms->pBuffer1,
|
|
ntParms->pBuffer2,
|
|
ntParms->uchXmitReadOption
|
|
);
|
|
}
|
|
}
|
|
|
|
PRIVATE
|
|
VOID
|
|
DumpTransmitQueue(
|
|
IN DOS_ADDRESS dpQueue
|
|
)
|
|
{
|
|
PLLC_XMIT_BUFFER pTxBuffer;
|
|
WORD userLength;
|
|
WORD dataLength;
|
|
|
|
while (dpQueue) {
|
|
pTxBuffer = (PLLC_XMIT_BUFFER)DOS_PTR_TO_FLAT(dpQueue);
|
|
dataLength = READ_WORD(&pTxBuffer->cbBuffer);
|
|
userLength = READ_WORD(&pTxBuffer->cbUserData);
|
|
DBGPRINT(
|
|
"\n"
|
|
"Transmit Buffer @%04x:%04x\n"
|
|
"next buffer %04x:%04x\n"
|
|
"reserved %02x %02x\n"
|
|
"data length %04x\n"
|
|
"user data %04x\n"
|
|
"user length %04x\n",
|
|
HIWORD(dpQueue),
|
|
LOWORD(dpQueue),
|
|
GET_SEGMENT(&pTxBuffer->pNext),
|
|
GET_OFFSET(&pTxBuffer->pNext),
|
|
((LPBYTE)(&pTxBuffer->usReserved1))[0],
|
|
((LPBYTE)(&pTxBuffer->usReserved1))[1],
|
|
dataLength,
|
|
READ_WORD(&pTxBuffer->usReserved2),
|
|
userLength
|
|
);
|
|
DumpData("user space",
|
|
(PBYTE)(&pTxBuffer->auchData),
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE, // not displaying seg:off, so no need for these 3
|
|
0,
|
|
0
|
|
);
|
|
DumpData("xmit data",
|
|
(PBYTE)(&pTxBuffer->auchData) + userLength,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE, // not displaying seg:off, so no need for these 3
|
|
0,
|
|
0
|
|
);
|
|
dpQueue = READ_DWORD(&pTxBuffer->pNext);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpReceiveDataBuffer(
|
|
IN PVOID Buffer,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment,
|
|
IN WORD Offset
|
|
)
|
|
{
|
|
if (IsDos) {
|
|
|
|
PLLC_DOS_BUFFER pBuf = (PLLC_DOS_BUFFER)Buffer;
|
|
BOOL contiguous = pBuf->Contiguous.uchOptions & 0xc0;
|
|
WORD userLength = READ_WORD(&pBuf->Next.cbUserData);
|
|
WORD dataLength = READ_WORD(&pBuf->Next.cbBuffer);
|
|
WORD userOffset = READ_WORD(&pBuf->Next.offUserData);
|
|
|
|
//
|
|
// Buffer 1: [not] contiguous MAC/DATA
|
|
//
|
|
|
|
DBGPRINT(
|
|
"\n"
|
|
"%sContiguous MAC/DATA frame @%04x:%04x\n"
|
|
"next buffer %04x:%04x\n"
|
|
"frame length %04x\n"
|
|
"data length %04x\n"
|
|
"user offset %04x\n"
|
|
"user length %04x\n"
|
|
"station id %04x\n"
|
|
"options %02x\n"
|
|
"message type %02x [%s]\n"
|
|
"buffers left %04x\n"
|
|
"rcv FS %02x\n"
|
|
"adapter num %02x\n",
|
|
contiguous ? "" : "Not",
|
|
Segment,
|
|
Offset,
|
|
GET_SEGMENT(&pBuf->Contiguous.pNextBuffer),
|
|
GET_OFFSET(&pBuf->Contiguous.pNextBuffer),
|
|
READ_WORD(&pBuf->Contiguous.cbFrame),
|
|
READ_WORD(&pBuf->Contiguous.cbBuffer),
|
|
READ_WORD(&pBuf->Contiguous.offUserData),
|
|
READ_WORD(&pBuf->Contiguous.cbUserData),
|
|
READ_WORD(&pBuf->Contiguous.usStationId),
|
|
pBuf->Contiguous.uchOptions,
|
|
pBuf->Contiguous.uchMsgType,
|
|
MapMessageType(pBuf->Contiguous.uchMsgType),
|
|
READ_WORD(&pBuf->Contiguous.cBuffersLeft),
|
|
pBuf->Contiguous.uchRcvFS,
|
|
pBuf->Contiguous.uchAdapterNumber
|
|
);
|
|
if (!contiguous) {
|
|
|
|
DWORD cbLanHeader = (DWORD)pBuf->NotContiguous.cbLanHeader;
|
|
DWORD cbDlcHeader = (DWORD)pBuf->NotContiguous.cbDlcHeader;
|
|
|
|
DBGPRINT(
|
|
"LAN hdr len %02x\n"
|
|
"DLC hdr len %02x\n",
|
|
cbLanHeader,
|
|
cbDlcHeader
|
|
);
|
|
DumpData("LAN header",
|
|
NULL,
|
|
(DWORD)cbLanHeader,
|
|
DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
(WORD)(Offset + (WORD)&((PLLC_DOS_BUFFER)0)->NotContiguous.auchLanHeader)
|
|
);
|
|
DumpData("DLC header",
|
|
NULL,
|
|
cbDlcHeader,
|
|
DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
(WORD)(Offset + (WORD)&((PLLC_DOS_BUFFER)0)->NotContiguous.auchDlcHeader)
|
|
);
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space",
|
|
NULL,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + userOffset
|
|
userOffset
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
if (dataLength) {
|
|
DumpData("rcvd data",
|
|
NULL,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + userOffset + userLength
|
|
(WORD)(userOffset + userLength)
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"rcvd data\n"
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// data length is size of frame in contiguous buffer?
|
|
//
|
|
|
|
dataLength = READ_WORD(&pBuf->Contiguous.cbBuffer);
|
|
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space",
|
|
NULL,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + userOffset
|
|
userOffset
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
if (dataLength) {
|
|
DumpData("rcvd data",
|
|
NULL,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + userOffset + userLength
|
|
(WORD)(userOffset + userLength)
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"rcvd data\n"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// dump second & subsequent buffers
|
|
//
|
|
|
|
Segment = GET_SEGMENT(&pBuf->pNext);
|
|
Offset = GET_OFFSET(&pBuf->pNext);
|
|
|
|
for (
|
|
pBuf = (PLLC_DOS_BUFFER)READ_FAR_POINTER(&pBuf->pNext);
|
|
pBuf;
|
|
pBuf = (PLLC_DOS_BUFFER)READ_FAR_POINTER(&pBuf->pNext)
|
|
) {
|
|
|
|
userLength = READ_WORD(&pBuf->Next.cbUserData);
|
|
dataLength = READ_WORD(&pBuf->Next.cbBuffer);
|
|
|
|
DBGPRINT(
|
|
"\n"
|
|
"Buffer 2/Subsequent @%04x:%04x\n"
|
|
"next buffer %04x:%04x\n"
|
|
"frame length %04x\n"
|
|
"data length %04x\n"
|
|
"user offset %04x\n"
|
|
"user length %04x\n",
|
|
Segment,
|
|
Offset,
|
|
GET_SEGMENT(&pBuf->pNext),
|
|
GET_OFFSET(&pBuf->pNext),
|
|
READ_WORD(&pBuf->Next.cbFrame),
|
|
dataLength,
|
|
READ_WORD(&pBuf->Next.offUserData),
|
|
userLength
|
|
);
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space",
|
|
NULL,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + READ_WORD(&pBuf->Next.offUserData)
|
|
READ_WORD(&pBuf->Next.offUserData)
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
|
|
//
|
|
// there must be received data
|
|
//
|
|
|
|
DumpData("rcvd data",
|
|
NULL,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
TRUE,
|
|
Segment,
|
|
//Offset + READ_WORD(&pBuf->Next.offUserData) + userLength
|
|
(WORD)(READ_WORD(&pBuf->Next.offUserData) + userLength)
|
|
);
|
|
}
|
|
Segment = GET_SEGMENT(&pBuf->pNext);
|
|
Offset = GET_OFFSET(&pBuf->pNext);
|
|
}
|
|
} else {
|
|
|
|
PLLC_BUFFER pBuf = (PLLC_BUFFER)Buffer;
|
|
BOOL contiguous = pBuf->Contiguous.uchOptions & 0xc0;
|
|
WORD userLength = pBuf->Next.cbUserData;
|
|
WORD dataLength = pBuf->Next.cbBuffer;
|
|
WORD userOffset = pBuf->Next.offUserData;
|
|
|
|
//
|
|
// Buffer 1: [not] contiguous MAC/DATA
|
|
//
|
|
|
|
DBGPRINT(
|
|
"\n"
|
|
"%sContiguous MAC/DATA frame @%08x\n"
|
|
"next buffer %08x\n"
|
|
"frame length %04x\n"
|
|
"data length %04x\n"
|
|
"user offset %04x\n"
|
|
"user length %04x\n"
|
|
"station id %04x\n"
|
|
"options %02x\n"
|
|
"message type %02x [%s]\n"
|
|
"buffers left %04x\n"
|
|
"rcv FS %02x\n"
|
|
"adapter num %02x\n",
|
|
contiguous ? "" : "Not",
|
|
pBuf,
|
|
pBuf->Contiguous.pNextBuffer,
|
|
pBuf->Contiguous.cbFrame,
|
|
pBuf->Contiguous.cbBuffer,
|
|
pBuf->Contiguous.offUserData,
|
|
pBuf->Contiguous.cbUserData,
|
|
pBuf->Contiguous.usStationId,
|
|
pBuf->Contiguous.uchOptions,
|
|
pBuf->Contiguous.uchMsgType,
|
|
MapMessageType(pBuf->Contiguous.uchMsgType),
|
|
pBuf->Contiguous.cBuffersLeft,
|
|
pBuf->Contiguous.uchRcvFS,
|
|
pBuf->Contiguous.uchAdapterNumber
|
|
);
|
|
if (!contiguous) {
|
|
DWORD cbLanHeader = (DWORD)pBuf->NotContiguous.cbLanHeader;
|
|
DWORD cbDlcHeader = (DWORD)pBuf->NotContiguous.cbDlcHeader;
|
|
|
|
DBGPRINT(
|
|
"next frame %08x\n"
|
|
"LAN hdr len %02x\n"
|
|
"DLC hdr len %02x\n",
|
|
pBuf->NotContiguous.pNextFrame,
|
|
cbLanHeader,
|
|
cbDlcHeader
|
|
);
|
|
DumpData("LAN header",
|
|
pBuf->NotContiguous.auchLanHeader,
|
|
cbLanHeader,
|
|
DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
DumpData("DLC header",
|
|
pBuf->NotContiguous.auchDlcHeader,
|
|
cbDlcHeader,
|
|
DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space ",
|
|
(PBYTE)pBuf + userOffset,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
if (dataLength) {
|
|
DumpData("rcvd data",
|
|
(PBYTE)pBuf + userOffset + userLength,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"rcvd data\n"
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// data length is size of frame in contiguous buffer?
|
|
//
|
|
|
|
dataLength = pBuf->Contiguous.cbFrame;
|
|
|
|
DBGPRINT(
|
|
"next frame %08x\n",
|
|
pBuf->NotContiguous.pNextFrame
|
|
);
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space",
|
|
(PBYTE)pBuf + userOffset,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
if (dataLength) {
|
|
DumpData("rcvd data",
|
|
(PBYTE)pBuf + userOffset + userLength,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"rcvd data\n"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// dump second & subsequent buffers
|
|
//
|
|
|
|
for (pBuf = pBuf->pNext; pBuf; pBuf = pBuf->pNext) {
|
|
userLength = pBuf->Next.cbUserData;
|
|
dataLength = pBuf->Next.cbBuffer;
|
|
DBGPRINT(
|
|
"\n"
|
|
"Buffer 2/Subsequent @%08x\n"
|
|
"next buffer %08x\n"
|
|
"frame length %04x\n"
|
|
"data length %04x\n"
|
|
"user offset %04x\n"
|
|
"user length %04x\n",
|
|
pBuf,
|
|
pBuf->pNext,
|
|
pBuf->Next.cbFrame,
|
|
dataLength,
|
|
pBuf->Next.offUserData,
|
|
userLength
|
|
);
|
|
IF_DEBUG(DLC_RX_DATA) {
|
|
if (userLength) {
|
|
DumpData("user space",
|
|
(PBYTE)&pBuf + pBuf->Next.offUserData,
|
|
userLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
} else {
|
|
DBGPRINT(
|
|
"user space\n"
|
|
);
|
|
}
|
|
|
|
//
|
|
// there must be received data
|
|
//
|
|
|
|
DumpData("rcvd data",
|
|
(PBYTE)pBuf + pBuf->Next.offUserData + userLength,
|
|
dataLength,
|
|
DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
|
|
DEFAULT_FIELD_WIDTH,
|
|
FALSE,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
PRIVATE LPSTR MapMessageType(UCHAR MessageType) {
|
|
switch (MessageType) {
|
|
case 0x02:
|
|
return "MAC Frame (Direct Station on Token Ring only)";
|
|
|
|
case 0x04:
|
|
return "I-Frame";
|
|
|
|
case 0x06:
|
|
return "UI-Frame";
|
|
|
|
case 0x08:
|
|
return "XID Command (POLL)";
|
|
|
|
case 0x0a:
|
|
return "XID Command (not POLL)";
|
|
|
|
case 0x0c:
|
|
return "XID Response (FINAL)";
|
|
|
|
case 0x0e:
|
|
return "XID Response (not FINAL)";
|
|
|
|
case 0x10:
|
|
return "TEST Response (FINAL)";
|
|
|
|
case 0x12:
|
|
return "TEST Response (not FINAL)";
|
|
|
|
case 0x14:
|
|
return "OTHER - non-MAC frame (Direct Station only)";
|
|
|
|
default:
|
|
return "*** BAD FRAME TYPE ***";
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpData(
|
|
IN LPSTR Title,
|
|
IN PBYTE Address,
|
|
IN DWORD Length,
|
|
IN DWORD Options,
|
|
IN DWORD Indent,
|
|
IN BOOL IsDos,
|
|
IN WORD Segment,
|
|
IN WORD Offset
|
|
)
|
|
{
|
|
char dumpBuf[128];
|
|
char* bufptr;
|
|
int i, n, iterations;
|
|
char* hexptr;
|
|
|
|
if (IsDos) {
|
|
Address = LPBYTE_FROM_WORDS(Segment, Offset);
|
|
}
|
|
|
|
//
|
|
// the usual dump style: 16 columns of hex bytes, followed by 16 columns
|
|
// of corresponding ASCII characters, or '.' where the character is < 0x20
|
|
// (space) or > 0x7f (del?)
|
|
//
|
|
|
|
if (Options & DD_LINE_BEFORE) {
|
|
DbgOutStr("\n");
|
|
}
|
|
iterations = 0;
|
|
while (Length) {
|
|
bufptr = dumpBuf;
|
|
if (Title && !iterations) {
|
|
strcpy(bufptr, Title);
|
|
bufptr = strchr(bufptr, 0);
|
|
}
|
|
if (Indent && ((Options & DD_INDENT_ALL) || iterations)) {
|
|
|
|
int indentLen = (!iterations && Title)
|
|
? ((int)Indent - (int)strlen(Title) < 0)
|
|
? 1
|
|
: Indent - strlen(Title)
|
|
: Indent;
|
|
|
|
RtlFillMemory(bufptr, indentLen, ' ');
|
|
bufptr += indentLen;
|
|
}
|
|
if (!(Options & DD_NO_ADDRESS)) {
|
|
if (IsDos) {
|
|
bufptr += sprintf(bufptr, "%04x:%04x ", Segment, Offset);
|
|
} else {
|
|
bufptr += sprintf(bufptr, "%08x: ", Address);
|
|
}
|
|
}
|
|
n = (Length < 16) ? Length : 16;
|
|
hexptr = bufptr;
|
|
for (i = 0; i < n; ++i) {
|
|
bufptr += sprintf(bufptr, "%02x", Address[i]);
|
|
*bufptr++ = (i == 7) ? '-' : ' ';
|
|
}
|
|
if (Options & DD_UPPER_CASE) {
|
|
_strupr(hexptr);
|
|
}
|
|
if (!(Options & DD_NO_ASCII)) {
|
|
if (n < 16) {
|
|
for (i = 0; i < 16-n; ++i) {
|
|
bufptr += sprintf(bufptr, " ");
|
|
}
|
|
}
|
|
bufptr += sprintf(bufptr, " ");
|
|
for (i = 0; i < n; ++i) {
|
|
*bufptr++ = (Address[i] < 0x20 || Address[i] > 0x7f) ? '.' : Address[i];
|
|
}
|
|
}
|
|
*bufptr++ = '\n';
|
|
*bufptr = 0;
|
|
DbgOutStr(dumpBuf);
|
|
Length -= n;
|
|
Address += n;
|
|
++iterations;
|
|
|
|
//
|
|
// take care of segment wrap for DOS addresses
|
|
//
|
|
|
|
if (IsDos) {
|
|
|
|
DWORD x = (DWORD)Offset + n;
|
|
|
|
Offset = (WORD)x;
|
|
if (HIWORD(x)) {
|
|
Segment += 0x1000;
|
|
}
|
|
}
|
|
}
|
|
if (Options & DD_LINE_AFTER) {
|
|
DbgOutStr("\n");
|
|
}
|
|
}
|
|
|
|
//
|
|
// CCB1 error checking
|
|
//
|
|
|
|
#define BITS_PER_BYTE 8
|
|
#define CCB1_ERROR_SPREAD ((MAX_CCB1_ERROR + BITS_PER_BYTE) & ~(BITS_PER_BYTE-1))
|
|
|
|
//
|
|
// Ccb1ErrorTable - for each command described in IBM Lan Tech. Ref. (including
|
|
// those not applicable to CCB1), we keep a list of the permissable error codes
|
|
// which are taken from the "Return Codes for CCB1 Commands" table on pp B-5
|
|
// and B-6
|
|
// The error list is an 80-bit bitmap in which an ON bit indicates that the
|
|
// error number corresponding to the bit's position is allowable for the CCB1
|
|
// command corresponding to the list's index in the table
|
|
//
|
|
|
|
typedef struct {
|
|
BOOL ValidForCcb1;
|
|
BYTE ErrorList[CCB1_ERROR_SPREAD/BITS_PER_BYTE];
|
|
char* CommandName;
|
|
} CCB1_ERROR_TABLE;
|
|
|
|
#define MAX_INCLUSIVE_CCB1_COMMAND LLC_MAX_DLC_COMMAND
|
|
|
|
CCB1_ERROR_TABLE Ccb1ErrorTable[MAX_INCLUSIVE_CCB1_COMMAND + 1] = {
|
|
|
|
// DIR.INTERRUPT (0x00)
|
|
{
|
|
TRUE,
|
|
{0x83, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.INTERRUPT"
|
|
},
|
|
|
|
// DIR.MODIFY.OPEN.PARMS (0x01)
|
|
{
|
|
TRUE,
|
|
{0x97, 0x02, 0x40, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.MODIFY.OPEN.PARMS"
|
|
},
|
|
|
|
// DIR.RESTORE.OPEN.PARMS (0x02)
|
|
{
|
|
TRUE,
|
|
{0xd3, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.RESTORE.OPEN.PARMS"
|
|
},
|
|
|
|
// DIR.OPEN.ADAPTER (0x03)
|
|
{
|
|
TRUE,
|
|
{0xaf, 0x02, 0x45, 0x79, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00},
|
|
"DIR.OPEN.ADAPTER"
|
|
},
|
|
|
|
// DIR.CLOSE.ADAPTER (0x04)
|
|
{
|
|
TRUE,
|
|
{0xb3, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.CLOSE.ADAPTER"
|
|
},
|
|
|
|
// non-existent command (0x05)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x05)"
|
|
},
|
|
|
|
// DIR.SET.GROUP.ADDRESS (0x06)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.SET.GROUP.ADDRESS"
|
|
},
|
|
|
|
// DIR.SET.FUNCTIONAL.ADDRESS (0x07)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.SET.FUNCTIONAL.ADDRESS"
|
|
},
|
|
|
|
// DIR.READ.LOG (0x08)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.READ.LOG"
|
|
},
|
|
|
|
// non-existent command (0x09)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x09)"
|
|
},
|
|
|
|
// TRANSMIT.DIR.FRAME (0x0a)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.DIR.FRAME"
|
|
},
|
|
|
|
// TRANSMIT.I.FRAME (0x0b)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.I.FRAME"
|
|
},
|
|
|
|
// non-existent command (0x0c)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x0c)"
|
|
},
|
|
|
|
// TRANSMIT.UI.FRAME (0x0d)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.UI.FRAME"
|
|
},
|
|
|
|
// TRANSMIT.XID.CMD (0x0e)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.XID.CMD"
|
|
},
|
|
|
|
// TRANSMIT.XID.RESP.FINAL (0x0f)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.XID.RESP.FINAL"
|
|
},
|
|
|
|
// TRANSMIT.XID.RESP.NOT.FINAL (0x10)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.XID.RESP.NOT.FINAL"
|
|
},
|
|
|
|
// TRANSMIT.TEST.CMD (0x11)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0f, 0x00, 0x28, 0xbc, 0x01, 0x00, 0x00, 0x13, 0x04},
|
|
"TRANSMIT.TEST.CMD"
|
|
},
|
|
|
|
// non-existent command (0x12)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x12)"
|
|
},
|
|
|
|
// non-existent command (0x13)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x13)"
|
|
},
|
|
|
|
// DLC.RESET (0x14)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"DLC.RESET"
|
|
},
|
|
|
|
// DLC.OPEN.SAP (0x15)
|
|
{
|
|
TRUE,
|
|
{0xd3, 0x0b, 0x40, 0x39, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x02},
|
|
"DLC.OPEN.SAP"
|
|
},
|
|
|
|
// DLC.CLOSE.SAP (0x16)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11},
|
|
"DLC.CLOSE.SAP"
|
|
},
|
|
|
|
// DLC.REALLOCATE (0x17)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"DLC.REALLOCATE"
|
|
},
|
|
|
|
// non-existent command (0x18)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x18)"
|
|
},
|
|
|
|
// DLC.OPEN.STATION (0x19)
|
|
{
|
|
TRUE,
|
|
{0xb3, 0x0b, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x80},
|
|
"DLC.OPEN.STATION"
|
|
},
|
|
|
|
// DLC.CLOSE.STATION (0x1a)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x81, 0x18},
|
|
"DLC.CLOSE.STATION"
|
|
},
|
|
|
|
// DLC.CONNECT.STATION (0x1b)
|
|
{
|
|
TRUE,
|
|
{0x97, 0x0a, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x13, 0x24},
|
|
"DLC.CONNECT.STATION"
|
|
},
|
|
|
|
// DLC.MODIFY (0x1c)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0b, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x25, 0x42},
|
|
"DLC.MODIFY"
|
|
},
|
|
|
|
// DLC.FLOW.CONTROL (0x1d)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"DLC.FLOW.CONTROL"
|
|
},
|
|
|
|
// DLC.STATISTICS (0x1e)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x0a, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"DLC.STATISTICS"
|
|
},
|
|
|
|
// non-existent command (0x1f)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x1f)"
|
|
},
|
|
|
|
// DIR.INITIALIZE (0x20)
|
|
{
|
|
TRUE,
|
|
{0x87, 0x00, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.INITIALIZE"
|
|
},
|
|
|
|
// DIR.STATUS (0x21)
|
|
{
|
|
TRUE,
|
|
{0x03, 0x12, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.STATUS"
|
|
},
|
|
|
|
// DIR.TIMER.SET (0x22)
|
|
{
|
|
TRUE,
|
|
{0x83, 0x0e, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.TIMER.SET"
|
|
},
|
|
|
|
// DIR.TIMER.CANCEL (0x23)
|
|
{
|
|
TRUE,
|
|
{0x03, 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.TIMER.CANCEL"
|
|
},
|
|
|
|
// PDT.TRACE.ON (0x24)
|
|
{
|
|
TRUE,
|
|
{0x45, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"PDT.TRACE.ON"
|
|
},
|
|
|
|
// PDT.TRACE.OFF (0x25)
|
|
{
|
|
TRUE,
|
|
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"PDT.TRACE.OFF"
|
|
},
|
|
|
|
// BUFFER.GET (0x26)
|
|
{
|
|
TRUE,
|
|
{0x13, 0x02, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"BUFFER.GET"
|
|
},
|
|
|
|
// BUFFER.FREE (0x27)
|
|
{
|
|
TRUE,
|
|
{0x13, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"BUFFER.FREE"
|
|
},
|
|
|
|
// RECEIVE (0x28)
|
|
{
|
|
TRUE,
|
|
{0x97, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"RECEIVE"
|
|
},
|
|
|
|
// RECEIVE.CANCEL (0x29)
|
|
{
|
|
TRUE,
|
|
{0x13, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"RECEIVE.CANCEL"
|
|
},
|
|
|
|
// RECEIVE.MODIFY (0x2a)
|
|
{
|
|
TRUE,
|
|
{0x97, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
"RECEIVE.MODIFY"
|
|
},
|
|
|
|
// DIR.DEFINE.MIF.ENVIRONMENT (0x2b)
|
|
{
|
|
TRUE,
|
|
{0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.DEFINE.MIF.ENVIRONMENT"
|
|
},
|
|
|
|
// DIR.TIMER.CANCEL.GROUP (0x2c)
|
|
{
|
|
TRUE,
|
|
{0x03, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.TIMER.CANCEL.GROUP"
|
|
},
|
|
|
|
// DIR.SET.USER.APPENDAGE (0x2d)
|
|
{
|
|
TRUE,
|
|
{0x93, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.SET.USER.APPENDAGE"
|
|
},
|
|
|
|
// non-existent command (0x2e)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x2e)"
|
|
},
|
|
|
|
// non-existent command (0x2f)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x2f)"
|
|
},
|
|
|
|
// non-existent command (0x30)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT COMMAND (0x30)"
|
|
},
|
|
|
|
// READ (0x31)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"READ"
|
|
},
|
|
|
|
// READ.CANCEL (0x32)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"READ.CANCEL"
|
|
},
|
|
|
|
// DLC.SET.THRESHOLD (0x33)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DLC.SET.THRESHOLD"
|
|
},
|
|
|
|
// DIR.CLOSE.DIRECT (0x34)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.CLOSE.DIRECT"
|
|
},
|
|
|
|
// DIR.OPEN.DIRECT (0x35)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"DIR.OPEN.DIRECT"
|
|
},
|
|
|
|
// PURGE.RESOURCES (0x36)
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"PURGE.RESOURCES"
|
|
},
|
|
|
|
// LLC_MAX_DLC_COMMAND (0x37) ?
|
|
{
|
|
FALSE,
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
"NON-EXISTENT-COMMAND (0x37)"
|
|
}
|
|
};
|
|
|
|
BOOL
|
|
IsCcbErrorCodeAllowable(
|
|
IN BYTE CcbCommand,
|
|
IN BYTE CcbErrorCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check whether an error code is allowable for a particular CCB(1) command
|
|
code. Perform range check on the error code before using as index into
|
|
allowable error table
|
|
|
|
Arguments:
|
|
|
|
CcbCommand - Command code
|
|
CcbErrorCode - Return code
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - CcbErrorCode is valid for CcbCommand
|
|
FALSE - CcbErrorCode should not be returned for CcbCommand
|
|
OR CcbErrorCode is invalid (out of range)
|
|
--*/
|
|
|
|
{
|
|
if (CcbErrorCode == CCB_COMMAND_IN_PROGRESS) {
|
|
return TRUE;
|
|
}
|
|
if (CcbErrorCode > MAX_CCB1_ERROR)
|
|
return FALSE;
|
|
return Ccb1ErrorTable[CcbCommand].ErrorList[CcbErrorCode/8] & (1 << (CcbErrorCode % 8));
|
|
}
|
|
|
|
BOOL
|
|
IsCcbErrorCodeValid(
|
|
IN BYTE CcbErrorCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check if a return code from a CCB(1) is an allowable return code,
|
|
irrespective of command type
|
|
|
|
Arguments:
|
|
|
|
CcbErrorCode - return code to check
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - CcbErrorCode is in range
|
|
FALSE - CcbErrorCode is not in range
|
|
|
|
--*/
|
|
|
|
{
|
|
return (CcbErrorCode == CCB_COMMAND_IN_PROGRESS) // 0xff
|
|
|
|
// 0x00 - 0x0c
|
|
|| ((CcbErrorCode >= CCB_SUCCESS) && (CcbErrorCode <= CCB_SUCCESS_ADAPTER_NOT_OPEN))
|
|
|
|
// 0x10 - 0x1e
|
|
|| ((CcbErrorCode >= CCB_NETBIOS_FAILURE) && (CcbErrorCode <= CCB_INVALID_FUNCTION_ADDRESS))
|
|
|
|
// 0x20 - 0x28
|
|
|| ((CcbErrorCode >= CCB_DATA_LOST_NO_BUFFERS) && (CcbErrorCode <= CCB_INVALID_FRAME_LENGTH))
|
|
|
|
// 0x30
|
|
|| (CcbErrorCode == CCB_NOT_ENOUGH_BUFFERS_OPEN)
|
|
|
|
// 0x32 - 0x34
|
|
|| ((CcbErrorCode >= CCB_INVALID_NODE_ADDRESS) && (CcbErrorCode <= CCB_INVALID_TRANSMIT_LENGTH))
|
|
|
|
// 0x40 - 0x4f
|
|
|| ((CcbErrorCode >= CCB_INVALID_STATION_ID) && (CcbErrorCode <= CCB_INVALID_REMOTE_ADDRESS))
|
|
;
|
|
}
|
|
|
|
BOOL
|
|
IsCcbCommandValid(
|
|
IN BYTE CcbCommand
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check if CCB command code is one of the allowable codes for a DOS CCB
|
|
(CCB1)
|
|
|
|
Arguments:
|
|
|
|
CcbCommand - command code to check
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - CcbCommand is recognized
|
|
FALSE - CcbCommand is not recognized
|
|
|
|
--*/
|
|
|
|
{
|
|
return ((CcbCommand >= LLC_DIR_INTERRUPT) && (CcbCommand <= LLC_DIR_CLOSE_ADAPTER))
|
|
|| ((CcbCommand >= LLC_DIR_SET_GROUP_ADDRESS) && (CcbCommand <= LLC_DIR_SET_FUNCTIONAL_ADDRESS))
|
|
|| ((CcbCommand >= LLC_TRANSMIT_DIR_FRAME) && (CcbCommand <= LLC_TRANSMIT_I_FRAME))
|
|
|| ((CcbCommand >= LLC_TRANSMIT_UI_FRAME) && (CcbCommand <= LLC_TRANSMIT_TEST_CMD))
|
|
|| ((CcbCommand >= LLC_DLC_RESET) && (CcbCommand <= LLC_DLC_REALLOCATE_STATIONS))
|
|
|| ((CcbCommand >= LLC_DLC_OPEN_STATION) && (CcbCommand <= LLC_DLC_STATISTICS))
|
|
|| ((CcbCommand >= LLC_DIR_INITIALIZE) && (CcbCommand <= LLC_DIR_SET_USER_APPENDAGE))
|
|
;
|
|
}
|
|
|
|
LPSTR
|
|
MapCcbCommandToName(
|
|
IN BYTE CcbCommand
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return the name of a CCB command, given its value
|
|
|
|
Arguments:
|
|
|
|
CcbCommand - command code to map
|
|
|
|
Return Value:
|
|
|
|
char* pointer to ASCIZ name of command (in IBM format X.Y.Z)
|
|
|
|
--*/
|
|
|
|
{
|
|
return Ccb1ErrorTable[CcbCommand].CommandName;
|
|
}
|
|
|
|
VOID
|
|
DumpDosAdapter(
|
|
IN DOS_ADAPTER* pDosAdapter
|
|
)
|
|
{
|
|
DBGPRINT( "DOS_ADAPTER @ %08x\n"
|
|
"AdapterType. . . . . . . . . %s\n"
|
|
"IsOpen . . . . . . . . . . . %d\n"
|
|
"DirectStationOpen. . . . . . %d\n"
|
|
"DirectReceive. . . . . . . . %d\n"
|
|
"WaitingRestore . . . . . . . %d\n"
|
|
"BufferFree . . . . . . . . . %d\n"
|
|
"BufferPool . . . . . . . . . %08x\n"
|
|
"CurrentExceptionHandlers . . %08x %08x %08x\n"
|
|
"PreviousExceptionHandlers. . %08x %08x %08x\n"
|
|
"DlcStatusChangeAppendage . . \n"
|
|
"LastNetworkStatusChange. . . %04x\n"
|
|
"UserStatusValue. . . . . . . \n"
|
|
"AdapterParms:\n"
|
|
" OpenErrorCode . . . . . . %04x\n"
|
|
" OpenOptions . . . . . . . %04x\n"
|
|
" NodeAddress . . . . . . . %02x-%02x-%02x-%02x-%02x-%02x\n"
|
|
" GroupAddress. . . . . . . %08x\n"
|
|
" FunctionalAddress . . . . %08x\n"
|
|
" NumberReceiveBuffers. . . %04x\n"
|
|
" ReceiveBufferLength . . . %04x\n"
|
|
" DataHoldBufferLength. . . %04x\n"
|
|
" NumberDataHoldBuffers . . %02x\n"
|
|
" Reserved. . . . . . . . . %02x\n"
|
|
" OpenLock. . . . . . . . . %04x\n"
|
|
" ProductId . . . . . . . . %08x\n"
|
|
"DlcSpecified . . . . . . . . %d\n"
|
|
"DlcParms:\n"
|
|
" MaxSaps . . . . . . . . . %02x\n"
|
|
" MaxStations . . . . . . . %02x\n"
|
|
" MaxGroupSaps. . . . . . . %02x\n"
|
|
" MaxGroupMembers . . . . . %02x\n"
|
|
" T1Tick1 . . . . . . . . . %02x\n"
|
|
" T2Tick1 . . . . . . . . . %02x\n"
|
|
" TiTick1 . . . . . . . . . %02x\n"
|
|
" T1Tick2 . . . . . . . . . %02x\n"
|
|
" T2Tick2 . . . . . . . . . %02x\n"
|
|
" TiTick2 . . . . . . . . . %02x\n"
|
|
"AdapterCloseCcb. . . . . . . \n"
|
|
"DirectCloseCcb . . . . . . . \n"
|
|
"ReadCcb. . . . . . . . . . . \n"
|
|
"EventQueueCritSec. . . . . . \n"
|
|
"EventQueueHead . . . . . . . \n"
|
|
"EventQueueTail . . . . . . . \n"
|
|
"QueueElements. . . . . . . . \n"
|
|
"LocalBusyCritSec . . . . . . \n"
|
|
"DeferredReceives . . . . . . \n"
|
|
"FirstIndex . . . . . . . . . \n"
|
|
"LastIndex. . . . . . . . . . \n"
|
|
"LocalBusyInfo. . . . . . . . \n",
|
|
MapAdapterType(pDosAdapter->AdapterType),
|
|
pDosAdapter->IsOpen,
|
|
pDosAdapter->DirectStationOpen,
|
|
pDosAdapter->DirectReceive,
|
|
pDosAdapter->WaitingRestore,
|
|
pDosAdapter->BufferFree,
|
|
pDosAdapter->BufferPool,
|
|
pDosAdapter->CurrentExceptionHandlers[0],
|
|
pDosAdapter->CurrentExceptionHandlers[1],
|
|
pDosAdapter->CurrentExceptionHandlers[2],
|
|
pDosAdapter->PreviousExceptionHandlers[0],
|
|
pDosAdapter->PreviousExceptionHandlers[1],
|
|
pDosAdapter->PreviousExceptionHandlers[2],
|
|
pDosAdapter->LastNetworkStatusChange,
|
|
pDosAdapter->AdapterParms.OpenErrorCode,
|
|
pDosAdapter->AdapterParms.OpenOptions,
|
|
pDosAdapter->AdapterParms.NodeAddress[0],
|
|
pDosAdapter->AdapterParms.NodeAddress[1],
|
|
pDosAdapter->AdapterParms.NodeAddress[2],
|
|
pDosAdapter->AdapterParms.NodeAddress[3],
|
|
pDosAdapter->AdapterParms.NodeAddress[4],
|
|
pDosAdapter->AdapterParms.NodeAddress[5],
|
|
pDosAdapter->AdapterParms.GroupAddress,
|
|
pDosAdapter->AdapterParms.FunctionalAddress,
|
|
pDosAdapter->AdapterParms.NumberReceiveBuffers,
|
|
pDosAdapter->AdapterParms.ReceiveBufferLength,
|
|
pDosAdapter->AdapterParms.DataHoldBufferLength,
|
|
pDosAdapter->AdapterParms.NumberDataHoldBuffers,
|
|
pDosAdapter->AdapterParms.Reserved,
|
|
pDosAdapter->AdapterParms.OpenLock,
|
|
pDosAdapter->AdapterParms.ProductId,
|
|
pDosAdapter->DlcSpecified,
|
|
pDosAdapter->DlcParms.MaxSaps,
|
|
pDosAdapter->DlcParms.MaxStations,
|
|
pDosAdapter->DlcParms.MaxGroupSaps,
|
|
pDosAdapter->DlcParms.MaxGroupMembers,
|
|
pDosAdapter->DlcParms.T1Tick1,
|
|
pDosAdapter->DlcParms.T2Tick1,
|
|
pDosAdapter->DlcParms.TiTick1,
|
|
pDosAdapter->DlcParms.T1Tick2,
|
|
pDosAdapter->DlcParms.T2Tick2,
|
|
pDosAdapter->DlcParms.TiTick2
|
|
);
|
|
}
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
MapAdapterType(
|
|
IN ADAPTER_TYPE AdapterType
|
|
)
|
|
{
|
|
switch (AdapterType) {
|
|
case TokenRing:
|
|
return "Token Ring";
|
|
|
|
case Ethernet:
|
|
return "Ethernet";
|
|
|
|
case PcNetwork:
|
|
return "PC Network";
|
|
|
|
case UnknownAdapter:
|
|
return "Unknown Adapter";
|
|
}
|
|
return "*** REALLY UNKNOWN ADAPTER! ***";
|
|
}
|
|
|
|
#endif
|