summaryrefslogtreecommitdiffstats
path: root/private/mvdm/vdmredir/vrdlcdbg.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/vdmredir/vrdlcdbg.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/mvdm/vdmredir/vrdlcdbg.c')
-rw-r--r--private/mvdm/vdmredir/vrdlcdbg.c4024
1 files changed, 4024 insertions, 0 deletions
diff --git a/private/mvdm/vdmredir/vrdlcdbg.c b/private/mvdm/vdmredir/vrdlcdbg.c
new file mode 100644
index 000000000..fa824c04b
--- /dev/null
+++ b/private/mvdm/vdmredir/vrdlcdbg.c
@@ -0,0 +1,4024 @@
+/*++
+
+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(&timestruct);
+ 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(&timestruct);
+ 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
+
+--*/
+
+{
+ 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";
+ }
+}
+
+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";
+ }
+}
+
+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,
+ 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,
+ 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
+ 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
+ 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
+ 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)
+ ? (Indent - 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