home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / dlc / dlcdebug.c next >
C/C++ Source or Header  |  1997-10-05  |  81KB  |  3,195 lines

  1. /*++
  2.  
  3. Copyright (c) 1991-1997  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     dlcdebug.c
  8.  
  9. Abstract:
  10.  
  11.     CCB dump routines for NT-level CCB
  12.  
  13.     Contents:
  14.         GetAcslanDebugFlags
  15.         SetAcslanDebugFlags
  16.         AcslanDebugPrint
  17.         AcslanDebugPrintString
  18.         DumpCcb
  19.         MapCcbRetcode
  20.         DumpData
  21.         (DefaultParameterTableDump)
  22.         (DumpParameterTableHeader)
  23.         (DumpBufferCreateParms)
  24.         (DumpBufferFreeParms)
  25.         (DumpBufferGetParms)
  26.         (DumpDirInitializeParms)
  27.         (DumpDirOpenAdapterParms)
  28.         (MapEthernetType)
  29.         (DumpDirOpenDirectParms)
  30.         (DumpDirReadLogParms)
  31.         (MapLogType)
  32.         (DumpDirSetExceptionFlagsParms)
  33.         (DumpDirSetFunctionalAddressParms)
  34.         (DumpDirSetGroupAddressParms)
  35.         (DumpDirStatusParms)
  36.         (MapAdapterType)
  37.         (DumpDirTimerCancelParms)
  38.         (DumpDirTimerCancelGroupParms)
  39.         (DumpDirTimerSetParms)
  40.         (DumpDlcCloseSapParms)
  41.         (DumpDlcCloseStationParms)
  42.         (DumpDlcConnectStationParms)
  43.         (DumpDlcFlowControlParms)
  44.         (MapFlowControl)
  45.         (DumpDlcModifyParms)
  46.         (DumpDlcOpenSapParms)
  47.         (DumpDlcOpenStationParms)
  48.         (DumpDlcReallocateParms)
  49.         (DumpDlcResetParms)
  50.         (DumpDlcSetThresholdParms)
  51.         (DumpDlcStatisticsParms)
  52.         (DumpReadParms)
  53.         (MapOptionIndicator)
  54.         (MapReadEvent)
  55.         (MapDlcStatus)
  56.         (DumpReadCancelParms)
  57.         (DumpReceiveParms)
  58.         (MapRcvReadOption)
  59.         (MapReceiveOptions)
  60.         (DumpReceiveCancelParms)
  61.         (DumpReceiveModifyParms)
  62.         (DumpTransmitDirFrameParms)
  63.         (DumpTransmitIFrameParms)
  64.         (DumpTransmitTestCmdParms)
  65.         (DumpTransmitUiFrameParms)
  66.         (DumpTransmitXidCmdParms)
  67.         (DumpTransmitXidRespFinalParms)
  68.         (DumpTransmitXidRespNotFinalParms)
  69.         (DumpTransmitFramesParms)
  70.         (DumpTransmitParms)
  71.         (DumpTransmitQueue)
  72.         DumpReceiveDataBuffer
  73.         (MapMessageType)
  74.  
  75. Author:
  76.  
  77.     Richard L Firth (rfirth) 28-May-1992
  78.  
  79. Revision History:
  80.  
  81. --*/
  82.  
  83. #if DBG
  84.  
  85. // #include <nt.h>
  86. // #include <ntrtl.h>      // ASSERT, DbgPrint
  87. // #include <nturtl.h>
  88. #include <windows.h>
  89. #include <stdio.h>
  90. #include <stdlib.h>
  91. #include <stdarg.h>
  92. #include <string.h>
  93. #include <ctype.h>
  94. #include <dlcapi.h>     // Official DLC API definition
  95. #include "dlcdebug.h"
  96.  
  97. //
  98. // defines
  99. //
  100.  
  101. #define DBGDBG  0
  102. #define MyDbgPrint  puts
  103.  
  104. //
  105. // macros
  106. //
  107.  
  108. //
  109. // HEX_TO_NUM - converts an ASCII hex character (0-9A-Fa-f) to corresponding
  110. // number (0-15). Assumes c is hexadecimal digit on input
  111. //
  112.  
  113. #define HEX_TO_NUM(c)   ((c) - ('0' + (((c) <= '9') ? 0 : ((islower(c) ? 'a' : 'A') - ('9' + 1)))))
  114.  
  115. //
  116. // local prototypes
  117. //
  118.  
  119. VOID
  120. AcslanDebugPrintString(
  121.     IN LPSTR String
  122.     );
  123.  
  124. PRIVATE
  125. VOID
  126. DefaultParameterTableDump(
  127.     IN PVOID Parameters
  128.     );
  129.  
  130. PRIVATE
  131. VOID
  132. DumpParameterTableHeader(
  133.     IN LPSTR CommandName,
  134.     IN PVOID Table
  135.     );
  136.  
  137. PRIVATE
  138. VOID
  139. DumpBufferCreateParms(
  140.     IN PVOID Parameters
  141.     );
  142.  
  143. PRIVATE
  144. VOID
  145. DumpBufferFreeParms(
  146.     IN PVOID Parameters
  147.     );
  148.  
  149. PRIVATE
  150. VOID
  151. DumpBufferGetParms(
  152.     IN PVOID Parameters
  153.     );
  154.  
  155. PRIVATE
  156. VOID
  157. DumpDirInitializeParms(
  158.     IN PVOID Parameters
  159.     );
  160.  
  161. PRIVATE
  162. VOID
  163. DumpDirOpenAdapterParms(
  164.     IN PVOID Parameters
  165.     );
  166.  
  167. PRIVATE
  168. LPSTR
  169. MapEthernetType(
  170.     IN LLC_ETHERNET_TYPE EthernetType
  171.     );
  172.  
  173. PRIVATE
  174. VOID
  175. DumpDirOpenDirectParms(
  176.     IN PVOID Parameters
  177.     );
  178.  
  179. PRIVATE
  180. VOID
  181. DumpDirReadLogParms(
  182.     IN PVOID Parameters
  183.     );
  184.  
  185. PRIVATE
  186. LPSTR
  187. MapLogType(
  188.     IN USHORT Type
  189.     );
  190.  
  191. PRIVATE
  192. VOID
  193. DumpDirSetExceptionFlagsParms(
  194.     IN PVOID Parameters
  195.     );
  196.  
  197. PRIVATE
  198. VOID
  199. DumpDirSetFunctionalAddressParms(
  200.     IN PVOID Parameters
  201.     );
  202.  
  203. PRIVATE
  204. VOID
  205. DumpDirSetGroupAddressParms(
  206.     IN PVOID Parameters
  207.     );
  208.  
  209. PRIVATE
  210. VOID
  211. DumpDirStatusParms(
  212.     IN PVOID Parameters
  213.     );
  214.  
  215. PRIVATE
  216. LPSTR
  217. MapAdapterType(
  218.     IN USHORT AdapterType
  219.     );
  220.  
  221. PRIVATE
  222. VOID
  223. DumpDirTimerCancelParms(
  224.     IN PVOID Parameters
  225.     );
  226.  
  227. PRIVATE
  228. VOID
  229. DumpDirTimerCancelGroupParms(
  230.     IN PVOID Parameters
  231.     );
  232.  
  233. PRIVATE
  234. VOID
  235. DumpDirTimerSetParms(
  236.     IN PVOID Parameters
  237.     );
  238.  
  239. PRIVATE
  240. VOID
  241. DumpDlcCloseSapParms(
  242.     IN PVOID Parameters
  243.     );
  244.  
  245. PRIVATE
  246. VOID
  247. DumpDlcCloseStationParms(
  248.     IN PVOID Parameters
  249.     );
  250.  
  251. PRIVATE
  252. VOID
  253. DumpDlcConnectStationParms(
  254.     IN PVOID Parameters
  255.     );
  256.  
  257. PRIVATE
  258. VOID
  259. DumpDlcFlowControlParms(
  260.     IN PVOID Parameters
  261.     );
  262.  
  263. PRIVATE
  264. LPSTR
  265. MapFlowControl(
  266.     IN BYTE FlowControl
  267.     );
  268.  
  269. PRIVATE
  270. VOID
  271. DumpDlcModifyParms(
  272.     IN PVOID Parameters
  273.     );
  274.  
  275. PRIVATE
  276. VOID
  277. DumpDlcOpenSapParms(
  278.     IN PVOID Parameters
  279.     );
  280.  
  281. PRIVATE
  282. VOID
  283. DumpDlcOpenStationParms(
  284.     IN PVOID Parameters
  285.     );
  286.  
  287. PRIVATE
  288. VOID
  289. DumpDlcReallocateParms(
  290.     IN PVOID Parameters
  291.     );
  292.  
  293. PRIVATE
  294. VOID
  295. DumpDlcResetParms(
  296.     IN PVOID Parameters
  297.     );
  298.  
  299. PRIVATE
  300. VOID
  301. DumpDlcSetThresholdParms(
  302.     IN PVOID Parameters
  303.     );
  304.  
  305. PRIVATE
  306. VOID
  307. DumpDlcStatisticsParms(
  308.     IN PVOID Parameters
  309.     );
  310.  
  311. PRIVATE
  312. VOID
  313. DumpReadParms(
  314.     IN PVOID Parameters
  315.     );
  316.  
  317. PRIVATE
  318. LPSTR
  319. MapOptionIndicator(
  320.     IN UCHAR OptionIndicator
  321.     );
  322.  
  323. PRIVATE
  324. LPSTR
  325. MapReadEvent(
  326.     UCHAR Event
  327.     );
  328.  
  329. PRIVATE
  330. LPSTR
  331. MapDlcStatus(
  332.     WORD Status
  333.     );
  334.  
  335. PRIVATE
  336. VOID
  337. DumpReadCancelParms(
  338.     IN PVOID Parameters
  339.     );
  340.  
  341. PRIVATE
  342. VOID
  343. DumpReceiveParms(
  344.     IN PVOID Parameters
  345.     );
  346.  
  347. PRIVATE
  348. LPSTR
  349. MapReceiveOptions(
  350.     IN UCHAR Options
  351.     );
  352.  
  353. PRIVATE
  354. LPSTR
  355. MapRcvReadOption(
  356.     IN UCHAR Option
  357.     );
  358.  
  359. PRIVATE
  360. VOID
  361. DumpReceiveCancelParms(
  362.     IN PVOID Parameters
  363.     );
  364.  
  365. PRIVATE
  366. VOID
  367. DumpReceiveModifyParms(
  368.     IN PVOID Parameters
  369.     );
  370.  
  371. PRIVATE
  372. VOID
  373. DumpTransmitDirFrameParms(
  374.     IN PVOID Parameters
  375.     );
  376.  
  377. PRIVATE
  378. VOID
  379. DumpTransmitIFrameParms(
  380.     IN PVOID Parameters
  381.     );
  382.  
  383. PRIVATE
  384. VOID
  385. DumpTransmitTestCmdParms(
  386.     IN PVOID Parameters
  387.     );
  388.  
  389. PRIVATE
  390. VOID
  391. DumpTransmitUiFrameParms(
  392.     IN PVOID Parameters
  393.     );
  394.  
  395. PRIVATE
  396. VOID
  397. DumpTransmitXidCmdParms(
  398.     IN PVOID Parameters
  399.     );
  400.  
  401. PRIVATE
  402. VOID
  403. DumpTransmitXidRespFinalParms(
  404.     IN PVOID Parameters
  405.     );
  406.  
  407. PRIVATE
  408. VOID
  409. DumpTransmitXidRespNotFinalParms(
  410.     IN PVOID Parameters
  411.     );
  412.  
  413. PRIVATE
  414. VOID
  415. DumpTransmitFramesParms(
  416.     IN PVOID Parameters
  417.     );
  418.  
  419. PRIVATE
  420. VOID
  421. DumpTransmitParms(
  422.     IN PVOID Parameters
  423.     );
  424.  
  425. PRIVATE
  426. VOID
  427. DumpTransmitQueue(
  428.     IN PLLC_XMIT_BUFFER Buffer
  429.     );
  430.  
  431. PRIVATE
  432. LPSTR
  433. MapXmitReadOption(
  434.     IN UCHAR Option
  435.     );
  436.  
  437. VOID
  438. DumpReceiveDataBuffer(
  439.     IN PVOID Buffer
  440.     );
  441.  
  442. PRIVATE
  443. LPSTR
  444. MapMessageType(
  445.     UCHAR MessageType
  446.     );
  447.  
  448. //
  449. // explanations of error codes returned in CCB_RETCODE fields. Explanations
  450. // taken more-or-less verbatim from IBM Local Area Network Technical Reference
  451. // table B-1 ppB-2 to B-5. Includes all errors
  452. //
  453.  
  454. static LPSTR CcbRetcodeExplanations[] = {
  455.     "Success",
  456.     "Invalid command code",
  457.     "Duplicate command, one already outstanding",
  458.     "Adapter open, should be closed",
  459.     "Adapter closed, should be open",
  460.     "Required parameter missing",
  461.     "Invalid/incompatible option",
  462.     "Command cancelled - unrecoverable failure",
  463.     "Unauthorized access priority",
  464.     "Adapter not initialized, should be",
  465.     "Command cancelled by user request",
  466.     "Command cancelled, adapter closed while command in progress",
  467.     "Command completed Ok, adapter not open",
  468.     "Invalid error code 0x0D",
  469.     "Invalid error code 0x0E",
  470.     "Invalid error code 0x0F",
  471.     "Adapter open, NetBIOS not operational",
  472.     "Error in DIR.TIMER.SET or DIR.TIMER.CANCEL",
  473.     "Available work area exceeded",
  474.     "Invalid LOG.ID",
  475.     "Invalid shared RAM segment or size",
  476.     "Lost log data, buffer too small, log reset",
  477.     "Requested buffer size exceeds pool length",
  478.     "Command invalid, NetBIOS operational",
  479.     "Invalid SAP buffer length",
  480.     "Inadequate buffers available for request",
  481.     "USER_LENGTH value too large for buffer length",
  482.     "The CCB_PARM_TAB pointer is invalid",
  483.     "A pointer in the CCB parameter table is invalid",
  484.     "Invalid CCB_ADAPTER value",
  485.     "Invalid functional address",
  486.     "Invalid error code 0x1F",
  487.     "Lost data on receive, no buffers available",
  488.     "Lost data on receive, inadequate buffer space",
  489.     "Error on frame transmission, check TRANSMIT.FS data",
  490.     "Error on frame transmit or strip process",
  491.     "Unauthorized MAC frame",
  492.     "Maximum commands exceeded",
  493.     "Unrecognized command correlator",
  494.     "Link not transmitting I frames, state changed from link opened",
  495.     "Invalid transmit frame length",
  496.     "Invalid error code 0x29",
  497.     "Invalid error code 0x2a",
  498.     "Invalid error code 0x2b",
  499.     "Invalid error code 0x2c",
  500.     "Invalid error code 0x2d",
  501.     "Invalid error code 0x2e",
  502.     "Invalid error code 0x2f",
  503.     "Inadequate receive buffers for adapter to open",
  504.     "Invalid error code 0x31",
  505.     "Invalid NODE_ADDRESS",
  506.     "Invalid adapter receive buffer length defined",
  507.     "Invalid adapter transmit buffer length defined",
  508.     "Invalid error code 0x35",
  509.     "Invalid error code 0x36",
  510.     "Invalid error code 0x37",
  511.     "Invalid error code 0x38",
  512.     "Invalid error code 0x39",
  513.     "Invalid error code 0x3a",
  514.     "Invalid error code 0x3b",
  515.     "Invalid error code 0x3c",
  516.     "Invalid error code 0x3d",
  517.     "Invalid error code 0x3e",
  518.     "Invalid error code 0x3f",
  519.     "Invalid STATION_ID",
  520.     "Protocol error, link in invalid state for command",
  521.     "Parameter exceeded maximum allowed",
  522.     "Invalid SAP value or value already in use",
  523.     "Invalid routing information field",
  524.     "Requested group membership in non-existent group SAP",
  525.     "Resources not available",
  526.     "Sap cannot close unless all link stations are closed",
  527.     "Group SAP cannot close, individual SAPs not closed",
  528.     "Group SAP has reached maximum membership",
  529.     "Sequence error, incompatible command in progress",
  530.     "Station closed without remote acknowledgement",
  531.     "Sequence error, cannot close, DLC commands outstanding",
  532.     "Unsuccessful link station connection attempted",
  533.     "Member SAP not found in group SAP list",
  534.     "Invalid remote address, may not be a group address",
  535.     "Invalid pointer in CCB_POINTER field",
  536.     "Invalid error code 0x51",
  537.     "Invalid application program ID",
  538.     "Invalid application program key code",
  539.     "Invalid system key code",
  540.     "Buffer is smaller than buffer size given in DLC.OPEN.SAP",
  541.     "Adapter's system process is not installed",
  542.     "Inadequate stations available",
  543.     "Invalid CCB_PARAMETER_1 parameter",
  544.     "Inadequate queue elements to satisfy request",
  545.     "Initialization failure, cannot open adapter",
  546.     "Error detected in chained READ command",
  547.     "Direct stations not assigned to application program",
  548.     "Dd interface not installed",
  549.     "Requested adapter is not installed",
  550.     "Chained CCBs must all be for same adapter",
  551.     "Adapter initializing, command not accepted",
  552.     "Number of allowed application programs has been exceeded",
  553.     "Command cancelled by system action",
  554.     "Direct stations not available",
  555.     "Invalid DDNAME parameter",
  556.     "Inadequate GDT selectors to satisfy request",
  557.     "Invalid error code 0x66",
  558.     "Command cancelled, CCB resources purged",
  559.     "Application program ID not valid for interface",
  560.     "Segment associated with request cannot be locked",
  561.     "Invalid error code 0x6a",
  562.     "Invalid error code 0x6b",
  563.     "Invalid error code 0x6c",
  564.     "Invalid error code 0x6d",
  565.     "Invalid error code 0x6e",
  566.     "Invalid error code 0x6f",
  567.     "Invalid error code 0x70",
  568.     "Invalid error code 0x71",
  569.     "Invalid error code 0x72",
  570.     "Invalid error code 0x73",
  571.     "Invalid error code 0x74",
  572.     "Invalid error code 0x75",
  573.     "Invalid error code 0x76",
  574.     "Invalid error code 0x77",
  575.     "Invalid error code 0x78",
  576.     "Invalid error code 0x79",
  577.     "Invalid error code 0x7a",
  578.     "Invalid error code 0x7b",
  579.     "Invalid error code 0x7c",
  580.     "Invalid error code 0x7d",
  581.     "Invalid error code 0x7e",
  582.     "Invalid error code 0x7f",
  583.     "Invalid buffer address",
  584.     "Buffer already released",
  585.     "Invalid error code 0x82",
  586.     "Invalid error code 0x83",
  587.     "Invalid error code 0x84",
  588.     "Invalid error code 0x85",
  589.     "Invalid error code 0x86",
  590.     "Invalid error code 0x87",
  591.     "Invalid error code 0x88",
  592.     "Invalid error code 0x89",
  593.     "Invalid error code 0x8a",
  594.     "Invalid error code 0x8b",
  595.     "Invalid error code 0x8c",
  596.     "Invalid error code 0x8d",
  597.     "Invalid error code 0x8e",
  598.     "Invalid error code 0x8f",
  599.     "Invalid error code 0x90",
  600.     "Invalid error code 0x91",
  601.     "Invalid error code 0x92",
  602.     "Invalid error code 0x93",
  603.     "Invalid error code 0x94",
  604.     "Invalid error code 0x95",
  605.     "Invalid error code 0x96",
  606.     "Invalid error code 0x97",
  607.     "Invalid error code 0x98",
  608.     "Invalid error code 0x99",
  609.     "Invalid error code 0x9a",
  610.     "Invalid error code 0x9b",
  611.     "Invalid error code 0x9c",
  612.     "Invalid error code 0x9d",
  613.     "Invalid error code 0x9e",
  614.     "Invalid error code 0x9f",
  615.     "BIND error",
  616.     "Invalid version",
  617.     "NT Error status"
  618. };
  619.  
  620. #define NUMBER_OF_ERROR_MESSAGES    ARRAY_ELEMENTS(CcbRetcodeExplanations)
  621. #define LAST_DLC_ERROR_CODE         LAST_ELEMENT(CcbRetcodeExplanations)
  622.  
  623. //
  624. // preset the debug flags to nothing, or to whatever is defined at compile-time
  625. //
  626.  
  627. DWORD   AcslanDebugFlags = ACSLAN_DEBUG_FLAGS;
  628. FILE*   hDumpFile = NULL;
  629. BYTE    AcslanDumpCcb[LLC_MAX_DLC_COMMAND];
  630. BOOL    HaveCcbFilter = FALSE;
  631.  
  632. VOID
  633. GetAcslanDebugFlags(
  634.     VOID
  635.     )
  636.  
  637. /*++
  638.  
  639. Routine Description:
  640.  
  641.     This routine is called whenever we have a DLL_PROCESS_ATTACH to the DLL
  642.  
  643.     checks if there is an environment variable called ACSLAN_DEBUG_FLAGS, and
  644.     loads whatever it finds (as a 32-bit hex number) into AcslanDebugFlags
  645.  
  646.     checks if there is an environment variable called ACSLAN_DUMP_FILE. If
  647.     there is, then output which otherwise would have gone to the terminal
  648.     goes to the file. The file is opened in "w" mode by default - open for
  649.     write. Current file is destroyed if it exists
  650.  
  651.     If there is an environment variable called ACSLAN_DUMP_FILTER then this is
  652.     loaded into the AcslanDumpCcb array. This is a string of numbers, the
  653.     position of which corresponds to the CCB command. For each position, 1
  654.     means dump the CCB and 2 means dump the CCB and its parameters. This is an
  655.     additional filter control over that contained in ACSLAN_DEBUG_FLAGS which
  656.     allows control on a per CCB basis. Example:
  657.  
  658.         ACSLAN_DUMP_CCB=1x0221
  659.  
  660.     means:
  661.  
  662.         for CCB 0 (DIR.INTERRUPT) dump the CCB only (no parameter table anyway)
  663.                 1 (???) don't do anything (x==0)
  664.                 2 (???) don't do anything (x==0)
  665.                 3 (DIR.OPEN.ADAPTER) dump the CCB and parameter table
  666.                 4 (DIR.CLOSE.ADAPTER) dump the CCB and parameter table
  667.                     (no parameter table, doesn't matter)
  668.                 5 (DIR.SET.MULTICAST.ADDRESS) dump the CCB
  669.  
  670.     etc. We currently recognize up to CCB command 0x36 (54, PURGE.RESOURCES)
  671.  
  672. Arguments:
  673.  
  674.     None.
  675.  
  676. Return Value:
  677.  
  678.     None.
  679.  
  680. --*/
  681.  
  682. {
  683.     LPSTR envVar;
  684.     SYSTEMTIME systemTime;
  685.  
  686.     if (envVar = getenv(ACSLAN_DEBUG_ENV_VAR)) {
  687.         if (!strnicmp(envVar, "0x", 2)) {
  688.             envVar += 2;
  689.         }
  690.         for (AcslanDebugFlags = 0; isxdigit(*envVar); ++envVar) {
  691.             AcslanDebugFlags = AcslanDebugFlags * 16 + HEX_TO_NUM(*envVar);
  692. //                + (*envVar
  693. //                    - ('0' + ((*envVar <= '9') ? 0
  694. //                        : ((islower(*envVar) ? 'a' : 'A') - ('9' + 1)))));
  695.         }
  696.     }
  697.  
  698.     if (envVar = getenv(ACSLAN_DUMP_FILE_VAR)) {
  699.  
  700.         char* comma;
  701.         static char openMode[3] = "w";
  702.  
  703.         if (comma = strchr(envVar, ',')) {
  704.             strcpy(openMode, comma+1);
  705.             *comma = 0;
  706.         }
  707.         if ((hDumpFile = fopen(envVar, openMode)) == NULL) {
  708.             MyDbgPrint("Error: can't create dump file\n");
  709.         } else {
  710.             AcslanDebugFlags |= DEBUG_TO_FILE;
  711.             AcslanDebugFlags &= ~DEBUG_TO_TERMINAL;
  712.         }
  713.     }
  714.  
  715.  
  716. #if DBGDBG
  717.     IF_DEBUG(DLL_INFO) {
  718.         PUT(("GetAcslanDebugFlags: AcslanDebugFlags = %#x\n", AcslanDebugFlags));
  719.     }
  720. #endif
  721.  
  722.     if (envVar = getenv(ACSLAN_DUMP_FILTER_VAR)) {
  723.  
  724.         int i, len;
  725.         BYTE ch;
  726.  
  727.         if (strlen(envVar) > sizeof(AcslanDumpCcb) - 1) {
  728.  
  729.             //
  730.             // if there's too much info then inform the debugger but set up the
  731.             // string anyway
  732.             //
  733.  
  734.             PUT(("GetAcslanDebugFlags: Error: ACSLAN_DUMP_CCB variable too long: \"%s\"\n", envVar));
  735.             strncpy(AcslanDumpCcb, envVar, sizeof(AcslanDumpCcb) - 1);
  736.             AcslanDumpCcb[sizeof(AcslanDumpCcb) - 1] = 0;
  737.         } else {
  738.             strcpy(AcslanDumpCcb, envVar);
  739.         }
  740.  
  741. #if DBGDBG
  742.         IF_DEBUG(DLL_INFO) {
  743.             PUT(("GetAcslanDebugFlags: AcslanDumpCcb = %s\n", AcslanDumpCcb));
  744.         }
  745. #endif
  746.  
  747.         //
  748.         // if there are less characters in the string than CCB commands then
  749.         // default the rest of the commands
  750.         //
  751.  
  752.         len = strlen(AcslanDumpCcb);
  753.         for (i = len; i < sizeof(AcslanDumpCcb); ++i) {
  754.             AcslanDumpCcb[i] = 0xff;
  755.         }
  756.         AcslanDumpCcb[i] = 0;
  757.  
  758.         //
  759.         // convert the ASCII characters to numbers
  760.         //
  761.  
  762.         for (i = 0; i < len; ++i) {
  763.             ch = AcslanDumpCcb[i];
  764.             if (isxdigit(ch)) {
  765.                 ch = HEX_TO_NUM(ch);
  766.             } else {
  767.                 ch = (BYTE)0xff;
  768.             }
  769.             AcslanDumpCcb[i] = ch;
  770.  
  771. #if DBGDBG
  772.             PUT(("Command %d: filter=%02x\n", i, ch));
  773. #endif
  774.  
  775.         }
  776.  
  777.         HaveCcbFilter = TRUE;
  778.     }
  779.  
  780.     IF_DEBUG(DLL_INFO) {
  781.         GetSystemTime(&systemTime);
  782.         PUT(("PROCESS STARTED @ %02d:%02d:%02d\n",
  783.             systemTime.wHour, systemTime.wMinute, systemTime.wSecond
  784.             ));
  785.     }
  786. }
  787.  
  788. VOID
  789. SetAcslanDebugFlags(
  790.     IN DWORD Flags
  791.     )
  792. {
  793.     AcslanDebugFlags = Flags;
  794. }
  795.  
  796. VOID
  797. AcslanDebugPrint(
  798.     IN LPSTR Format,
  799.     IN ...
  800.     )
  801.  
  802. /*++
  803.  
  804. Routine Description:
  805.  
  806.     Print the debug information to the terminal or debug terminal, depending
  807.     on DEBUG_TO_TERMINAL flag (0x80000000)
  808.  
  809. Arguments:
  810.  
  811.     Format  - printf/DbgPrint style format string (ANSI)
  812.     ...     - optional parameters
  813.  
  814. Return Value:
  815.  
  816.     None.
  817.  
  818. --*/
  819.  
  820. {
  821.     char printBuffer[1024];
  822.     va_list list;
  823.  
  824.     va_start(list, Format);
  825.     vsprintf(printBuffer, Format, list);
  826.  
  827.     IF_DEBUG(TO_FILE) {
  828.         fputs(printBuffer, hDumpFile);
  829.     } else IF_DEBUG(TO_TERMINAL) {
  830.         printf(printBuffer);
  831.     } else {
  832.         MyDbgPrint(printBuffer);
  833.     }
  834. }
  835.  
  836. VOID
  837. AcslanDebugPrintString(
  838.     IN LPSTR String
  839.     )
  840.  
  841. /*++
  842.  
  843. Routine Description:
  844.  
  845.     Print the debug information to the terminal or debug terminal, depending
  846.     on DEBUG_TO_TERMINAL flag (0x80000000)
  847.  
  848. Arguments:
  849.  
  850.     String  - formatted string (ANSI)
  851.  
  852. Return Value:
  853.  
  854.     None.
  855.  
  856. --*/
  857.  
  858. {
  859.     IF_DEBUG(TO_FILE) {
  860.         fputs(String, hDumpFile);
  861.     } else IF_DEBUG(TO_TERMINAL) {
  862.         printf(String);
  863.     } else {
  864.         MyDbgPrint(String);
  865.     }
  866. }
  867.  
  868. VOID
  869. DumpCcb(
  870.     IN PLLC_CCB Ccb,
  871.     IN BOOL DumpAll,
  872.     IN BOOL CcbIsInput
  873.     )
  874.  
  875. /*++
  876.  
  877. Routine Description:
  878.  
  879.     Dumps a CCB and any associated parameter table. Also displays the symbolic
  880.     CCB command and an error code description if the CCB is being returned to
  881.     the caller. Dumps NT format CCBs (flat 32-bit pointers)
  882.  
  883. Arguments:
  884.  
  885.     Ccb         - flat 32-bit pointer to CCB2 to dump
  886.     DumpAll     - if TRUE, dumps parameter tables and buffers, else just CCB
  887.     CcbIsInput  - if TRUE, CCB is from user: don't display error code explanation
  888.  
  889. Return Value:
  890.  
  891.     None.
  892.  
  893. --*/
  894.  
  895. {
  896.     LPSTR   cmdname = "UNKNOWN CCB!";
  897.     BOOL    haveParms = FALSE;
  898.     VOID    (*DumpParms)(PVOID) = DefaultParameterTableDump;
  899.     PVOID   parameterTable = NULL;
  900.     BOOL    parmsInCcb = FALSE;
  901.     BYTE    command;
  902.     DWORD   numberOfTicks;
  903.     BOOL    ccbIsBad = FALSE;
  904.     BOOL    dumpInputParms = TRUE;
  905.     BOOL    dumpOutputParms = TRUE;
  906.  
  907.     static DWORD LastTicks;
  908.     static BOOL FirstTimeFunctionCalled = TRUE;
  909.  
  910.     try {
  911.         command = Ccb->uchDlcCommand;
  912.     } except(1) {
  913.         ccbIsBad = TRUE;
  914.     }
  915.  
  916.     //
  917.     // bomb out if we get a bad CCB address
  918.     //
  919.  
  920.     if (ccbIsBad) {
  921.         PUT(("*** Error: Bad Address for CCB @ %08x ***\n", Ccb));
  922.         return;
  923.     }
  924.  
  925. #if DBGDBG
  926.     PUT(("DumpCcb(%x, %d, %d)\n", Ccb, DumpAll, CcbIsInput));
  927. #endif
  928.  
  929.     IF_DEBUG(DUMP_TIME) {
  930.  
  931.         DWORD ticksNow = GetTickCount();
  932.  
  933.         if (FirstTimeFunctionCalled) {
  934.             numberOfTicks = 0;
  935.             FirstTimeFunctionCalled = FALSE;
  936.         } else {
  937.             numberOfTicks = ticksNow - LastTicks;
  938.         }
  939.         LastTicks = ticksNow;
  940.     }
  941.  
  942.     switch (command) {
  943.     case LLC_BUFFER_CREATE:
  944.         cmdname = "BUFFER.CREATE";
  945.         haveParms = TRUE;
  946.         DumpParms = DumpBufferCreateParms;
  947.         break;
  948.  
  949.     case LLC_BUFFER_FREE:
  950.         cmdname = "BUFFER.FREE";
  951.         haveParms = TRUE;
  952.         DumpParms = DumpBufferFreeParms;
  953.         break;
  954.  
  955.     case LLC_BUFFER_GET:
  956.         cmdname = "BUFFER.GET";
  957.         haveParms = TRUE;
  958.         DumpParms = DumpBufferGetParms;
  959.         break;
  960.  
  961.     case LLC_DIR_CLOSE_ADAPTER:
  962.         cmdname = "DIR.CLOSE.ADAPTER";
  963.         haveParms = FALSE;
  964.         break;
  965.  
  966.     case LLC_DIR_CLOSE_DIRECT:
  967.         cmdname = "DIR.CLOSE.DIRECT";
  968.         haveParms = FALSE;
  969.         break;
  970.  
  971.     case LLC_DIR_INITIALIZE:
  972.         cmdname = "DIR.INITIALIZE";
  973.         haveParms = TRUE;
  974.         DumpParms = DumpDirInitializeParms;
  975.         break;
  976.  
  977.     case LLC_DIR_INTERRUPT:
  978.         cmdname = "DIR.INTERRUPT";
  979.         haveParms = FALSE;
  980.         break;
  981.  
  982.     case LLC_DIR_OPEN_ADAPTER:
  983.         cmdname = "DIR.OPEN.ADAPTER";
  984.         haveParms = TRUE;
  985.         DumpParms = DumpDirOpenAdapterParms;
  986.         break;
  987.  
  988.     case LLC_DIR_OPEN_DIRECT:
  989.         cmdname = "DIR.OPEN.DIRECT";
  990.         haveParms = TRUE;
  991.         DumpParms = DumpDirOpenDirectParms;
  992.         break;
  993.  
  994.     case LLC_DIR_READ_LOG:
  995.         cmdname = "DIR.READ.LOG";
  996.         haveParms = TRUE;
  997.         DumpParms = DumpDirReadLogParms;
  998.         break;
  999.  
  1000.     case LLC_DIR_SET_EXCEPTION_FLAGS:
  1001.         cmdname = "DIR.SET.EXCEPTION.FLAGS";
  1002.         haveParms = TRUE;
  1003.         DumpParms = DumpDirSetExceptionFlagsParms;
  1004.         break;
  1005.  
  1006.     case LLC_DIR_SET_FUNCTIONAL_ADDRESS:
  1007.         cmdname = "DIR.SET.FUNCTIONAL.ADDRESS";
  1008.         haveParms = TRUE;
  1009.         DumpParms = DumpDirSetFunctionalAddressParms;
  1010.         parmsInCcb = TRUE;
  1011.         break;
  1012.  
  1013.     case LLC_DIR_SET_GROUP_ADDRESS:
  1014.         cmdname = "DIR.SET.GROUP.ADDRESS";
  1015.         haveParms = TRUE;
  1016.         DumpParms = DumpDirSetGroupAddressParms;
  1017.         parmsInCcb = TRUE;
  1018.         break;
  1019.  
  1020.     case LLC_DIR_STATUS:
  1021.         cmdname = "DIR.STATUS";
  1022.         haveParms = TRUE;
  1023.         DumpParms = DumpDirStatusParms;
  1024.         break;
  1025.  
  1026.     case LLC_DIR_TIMER_CANCEL:
  1027.         cmdname = "DIR.TIMER.CANCEL";
  1028.         haveParms = TRUE;
  1029.         DumpParms = DumpDirTimerCancelParms;
  1030.         parmsInCcb = TRUE;
  1031.         break;
  1032.  
  1033.     case LLC_DIR_TIMER_CANCEL_GROUP:
  1034.         cmdname = "DIR.TIMER.CANCEL.GROUP";
  1035.         haveParms = TRUE;
  1036.         DumpParms = DumpDirTimerCancelGroupParms;
  1037.         parmsInCcb = TRUE;
  1038.         break;
  1039.  
  1040.     case LLC_DIR_TIMER_SET:
  1041.         cmdname = "DIR.TIMER.SET";
  1042.         haveParms = TRUE;
  1043.         DumpParms = DumpDirTimerSetParms;
  1044.         parmsInCcb = TRUE;
  1045.         break;
  1046.  
  1047.     case LLC_DLC_CLOSE_SAP:
  1048.         cmdname = "DLC.CLOSE.SAP";
  1049.         haveParms = TRUE;
  1050.         DumpParms = DumpDlcCloseSapParms;
  1051.         parmsInCcb = TRUE;
  1052.         break;
  1053.  
  1054.     case LLC_DLC_CLOSE_STATION:
  1055.         cmdname = "DLC.CLOSE.STATION";
  1056.         haveParms = TRUE;
  1057.         DumpParms = DumpDlcCloseStationParms;
  1058.         parmsInCcb = TRUE;
  1059.         break;
  1060.  
  1061.     case LLC_DLC_CONNECT_STATION:
  1062.         cmdname = "DLC.CONNECT.STATION";
  1063.         haveParms = TRUE;
  1064.         DumpParms = DumpDlcConnectStationParms;
  1065.         break;
  1066.  
  1067.     case LLC_DLC_FLOW_CONTROL:
  1068.         cmdname = "DLC.FLOW.CONTROL";
  1069.         haveParms = TRUE;
  1070.         DumpParms = DumpDlcFlowControlParms;
  1071.         parmsInCcb = TRUE;
  1072.         break;
  1073.  
  1074.     case LLC_DLC_MODIFY:
  1075.         cmdname = "DLC.MODIFY";
  1076.         haveParms = TRUE;
  1077.         DumpParms = DumpDlcModifyParms;
  1078.         break;
  1079.  
  1080.     case LLC_DLC_OPEN_SAP:
  1081.         cmdname = "DLC.OPEN.SAP";
  1082.         haveParms = TRUE;
  1083.         DumpParms = DumpDlcOpenSapParms;
  1084.         break;
  1085.  
  1086.     case LLC_DLC_OPEN_STATION:
  1087.         cmdname = "DLC.OPEN.STATION";
  1088.         haveParms = TRUE;
  1089.         DumpParms = DumpDlcOpenStationParms;
  1090.         break;
  1091.  
  1092.     case LLC_DLC_REALLOCATE_STATIONS:
  1093.         cmdname = "DLC.REALLOCATE";
  1094.         haveParms = TRUE;
  1095.         DumpParms = DumpDlcReallocateParms;
  1096.         break;
  1097.  
  1098.     case LLC_DLC_RESET:
  1099.         cmdname = "DLC.RESET";
  1100.         break;
  1101.  
  1102.     case LLC_DLC_SET_THRESHOLD:
  1103.         cmdname = "DLC.SET.THRESHOLD";
  1104.         haveParms = TRUE;
  1105.         break;
  1106.  
  1107.     case LLC_DLC_STATISTICS:
  1108.         cmdname = "DLC.STATISTICS";
  1109.         haveParms = TRUE;
  1110.         DumpParms = DumpDlcStatisticsParms;
  1111.         break;
  1112.  
  1113.     case 0x25:
  1114.  
  1115.         //
  1116.         // not supported !
  1117.         //
  1118.  
  1119.         cmdname = "PDT.TRACE.OFF";
  1120.         break;
  1121.  
  1122.     case 0x24:
  1123.  
  1124.         //
  1125.         // not supported !
  1126.         //
  1127.  
  1128.         cmdname = "PDT.TRACE.ON";
  1129.         break;
  1130.  
  1131.     case LLC_READ:
  1132.         cmdname = "READ";
  1133.         haveParms = !CcbIsInput;
  1134.         DumpParms = DumpReadParms;
  1135.         dumpInputParms = FALSE;
  1136.         dumpOutputParms = !CcbIsInput && Ccb->uchDlcStatus == LLC_STATUS_SUCCESS;
  1137.         break;
  1138.  
  1139.     case LLC_READ_CANCEL:
  1140.         cmdname = "READ.CANCEL";
  1141.         break;
  1142.  
  1143.     case LLC_RECEIVE:
  1144.         cmdname = "RECEIVE";
  1145.         haveParms = TRUE;
  1146.         DumpParms = DumpReceiveParms;
  1147.         break;
  1148.  
  1149.     case LLC_RECEIVE_CANCEL:
  1150.         cmdname = "RECEIVE.CANCEL";
  1151.         haveParms = TRUE;
  1152.         DumpParms = DumpReceiveCancelParms;
  1153.         parmsInCcb = TRUE;
  1154.         break;
  1155.  
  1156.     case LLC_RECEIVE_MODIFY:
  1157.         cmdname = "RECEIVE.MODIFY";
  1158.         haveParms = TRUE;
  1159.         break;
  1160.  
  1161.     case LLC_TRANSMIT_FRAMES:
  1162.         cmdname = "TRANSMIT.FRAMES";
  1163.         haveParms = TRUE;
  1164.         DumpParms = DumpTransmitFramesParms;
  1165.         dumpOutputParms = FALSE;
  1166.         break;
  1167.  
  1168.     case LLC_TRANSMIT_DIR_FRAME:
  1169.         cmdname = "TRANSMIT.DIR.FRAME";
  1170.         haveParms = TRUE;
  1171.         DumpParms = DumpTransmitDirFrameParms;
  1172.         dumpOutputParms = FALSE;
  1173.         break;
  1174.  
  1175.     case LLC_TRANSMIT_I_FRAME:
  1176.         cmdname = "TRANSMIT.I.FRAME";
  1177.         haveParms = TRUE;
  1178.         DumpParms = DumpTransmitIFrameParms;
  1179.         dumpOutputParms = FALSE;
  1180.         break;
  1181.  
  1182.     case LLC_TRANSMIT_TEST_CMD:
  1183.         cmdname = "TRANSMIT.TEST.CMD";
  1184.         haveParms = TRUE;
  1185.         DumpParms = DumpTransmitTestCmdParms;
  1186.         dumpOutputParms = FALSE;
  1187.         break;
  1188.  
  1189.     case LLC_TRANSMIT_UI_FRAME:
  1190.         cmdname = "TRANSMIT.UI.FRAME";
  1191.         haveParms = TRUE;
  1192.         DumpParms = DumpTransmitUiFrameParms;
  1193.         break;
  1194.  
  1195.     case LLC_TRANSMIT_XID_CMD:
  1196.         cmdname = "TRANSMIT.XID.CMD";
  1197.         haveParms = TRUE;
  1198.         DumpParms = DumpTransmitXidCmdParms;
  1199.         dumpOutputParms = FALSE;
  1200.         break;
  1201.  
  1202.     case LLC_TRANSMIT_XID_RESP_FINAL:
  1203.         cmdname = "TRANSMIT.XID.RESP.FINAL";
  1204.         haveParms = TRUE;
  1205.         DumpParms = DumpTransmitXidRespFinalParms;
  1206.         dumpOutputParms = FALSE;
  1207.         break;
  1208.  
  1209.     case LLC_TRANSMIT_XID_RESP_NOT_FINAL:
  1210.         cmdname = "TRANSMIT.XID.RESP.NOT.FINAL";
  1211.         haveParms = TRUE;
  1212.         DumpParms = DumpTransmitXidRespNotFinalParms;
  1213.         dumpOutputParms = FALSE;
  1214.         break;
  1215.  
  1216.     }
  1217.  
  1218.     if (HaveCcbFilter) {
  1219.  
  1220.         BYTE filter = AcslanDumpCcb[command];
  1221.  
  1222. #if DBGDBG
  1223.         PUT(("filter = %02x\n", filter));
  1224. #endif
  1225.  
  1226.         if (filter == 0xff) {
  1227.  
  1228.             //
  1229.             // do nothing - 0xff means use default in ACSLAN_DEBUG_FLAGS
  1230.             //
  1231.  
  1232.         } else {
  1233.             if (CcbIsInput) {
  1234.                 if (!(filter & CF_DUMP_CCB_IN)) {
  1235.  
  1236.                     //
  1237.                     // not interested in this input CCB
  1238.                     //
  1239.  
  1240.                     return;
  1241.                 }
  1242.                 DumpAll = filter & CF_DUMP_PARMS_IN;
  1243.             } else {
  1244.                 if (!(filter & CF_DUMP_CCB_OUT)) {
  1245.  
  1246.                     //
  1247.                     // not interested in this output CCB
  1248.                     //
  1249.  
  1250.                     return;
  1251.                 }
  1252.                 DumpAll = filter & CF_DUMP_PARMS_OUT;
  1253.             }
  1254.         }
  1255.     }
  1256.  
  1257.     PUT(("\n==============================================================================\n"));
  1258.  
  1259.     IF_DEBUG(DUMP_TIME) {
  1260.         PUT(("%sPUT CCB @ 0x%08x +%d mSec\n",
  1261.             CcbIsInput ? "IN" : "OUT",
  1262.             Ccb,
  1263.             numberOfTicks
  1264.             ));
  1265.     } else {
  1266.         PUT(("%sPUT CCB @ 0x%08x\n",
  1267.             CcbIsInput ? "IN" : "OUT",
  1268.             Ccb
  1269.             ));
  1270.     }
  1271.  
  1272.     PUT(("Adapter . . . . %02x\n"
  1273.         "Command . . . . %02x [%s]\n"
  1274.         "Status. . . . . %02x [%s]\n"
  1275.         "Reserved. . . . %02x\n"
  1276.         "Next. . . . . . %08x\n"
  1277.         "CompletionFlag. %08x\n",
  1278.         Ccb->uchAdapterNumber,
  1279.         Ccb->uchDlcCommand,
  1280.         cmdname,
  1281.         Ccb->uchDlcStatus,
  1282.         CcbIsInput ? "" : MapCcbRetcode(Ccb->uchDlcStatus),
  1283.         Ccb->uchReserved1,
  1284.         Ccb->pNext,
  1285.         Ccb->ulCompletionFlag
  1286.         ));
  1287.  
  1288.     if (haveParms) {
  1289.         if (parmsInCcb) {
  1290.             DumpParms(Ccb->u.pParameterTable);
  1291.         } else {
  1292.             parameterTable = Ccb->u.pParameterTable;
  1293.             PUT(("Parameters. . . %08x\n", parameterTable));
  1294.         }
  1295.     } else {
  1296.         PUT(("Parameters. . . %08x\n", Ccb->u.pParameterTable));
  1297.     }
  1298.  
  1299.     PUT(("CompletionEvent %08x\n"
  1300.         "Reserved. . . . %02x\n"
  1301.         "ReadFlag. . . . %02x\n"
  1302.         "Reserved. . . . %04x\n",
  1303.         Ccb->hCompletionEvent,
  1304.         Ccb->uchReserved2,
  1305.         Ccb->uchReadFlag,
  1306.         Ccb->usReserved3
  1307.         ));
  1308.  
  1309.     if (parameterTable && DumpAll) {
  1310.         if ((CcbIsInput && dumpInputParms) || (!CcbIsInput && dumpOutputParms)) {
  1311.             DumpParms(parameterTable);
  1312.         }
  1313.     }
  1314. }
  1315.  
  1316. LPSTR
  1317. MapCcbRetcode(
  1318.     IN  BYTE    Retcode
  1319.     )
  1320.  
  1321. /*++
  1322.  
  1323. Routine Description:
  1324.  
  1325.     Returns string describing error code
  1326.  
  1327. Arguments:
  1328.  
  1329.     Retcode - CCB_RETCODE
  1330.  
  1331. Return Value:
  1332.  
  1333.     LPSTR
  1334.  
  1335. --*/
  1336.  
  1337. {
  1338.     static char errbuf[128];
  1339.  
  1340.     if (Retcode == LLC_STATUS_PENDING) {
  1341.         return "Command in progress";
  1342.     } else if (Retcode > NUMBER_OF_ERROR_MESSAGES) {
  1343.         sprintf(errbuf, "*** Invalid error code 0x%2x ***", Retcode);
  1344.         return errbuf;
  1345.     }
  1346.     return CcbRetcodeExplanations[Retcode];
  1347. }
  1348.  
  1349. VOID
  1350. DumpData(
  1351.     IN LPSTR Title,
  1352.     IN PBYTE Address,
  1353.     IN DWORD Length,
  1354.     IN DWORD Options,
  1355.     IN DWORD Indent
  1356.     )
  1357. {
  1358.     char dumpBuf[80];
  1359.     char* bufptr;
  1360.     int i, n, iterations;
  1361.     char* hexptr;
  1362.  
  1363.     //
  1364.     // the usual dump style: 16 columns of hex bytes, followed by 16 columns
  1365.     // of corresponding ASCII characters, or '.' where the character is < 0x20
  1366.     // (space) or > 0x7f (del?)
  1367.     //
  1368.  
  1369.     if (Options & DD_LINE_BEFORE) {
  1370.         AcslanDebugPrintString("\n");
  1371.     }
  1372.  
  1373.     try {
  1374.         iterations = 0;
  1375.         while (Length) {
  1376.             bufptr = dumpBuf;
  1377.             if (Title && !iterations) {
  1378.                 strcpy(bufptr, Title);
  1379.                 bufptr = strchr(bufptr, 0);
  1380.             }
  1381.  
  1382.             if (Indent && ((Options & DD_INDENT_ALL) || iterations)) {
  1383.  
  1384.                 int indentLen = (!iterations && Title)
  1385.                                     ? (Indent - strlen(Title) < 0)
  1386.                                         ? 1
  1387.                                         : Indent - strlen(Title)
  1388.                                     : Indent;
  1389.  
  1390.                 memset(bufptr, ' ', indentLen);
  1391.                 bufptr += indentLen;
  1392.             }
  1393.  
  1394.             if (!(Options & DD_NO_ADDRESS)) {
  1395.                 bufptr += sprintf(bufptr, "%08x: ", Address);
  1396.             }
  1397.  
  1398.             n = (Length < 16) ? Length : 16;
  1399.             hexptr = bufptr;
  1400.             for (i = 0; i < n; ++i) {
  1401.                 bufptr += sprintf(bufptr, "%02x", Address[i]);
  1402.                 *bufptr++ = (i == 7) ? '-' : ' ';
  1403.             }
  1404.  
  1405.             if (Options & DD_UPPER_CASE) {
  1406.                 strupr(hexptr);
  1407.             }
  1408.  
  1409.             if (!(Options & DD_NO_ASCII)) {
  1410.                 if (n < 16) {
  1411.                     for (i = 0; i < 16-n; ++i) {
  1412.                         bufptr += sprintf(bufptr, Options & DD_DOT_DOT_SPACE ? ".. " : "   ");
  1413.                     }
  1414.                 }
  1415.                 bufptr += sprintf(bufptr, "  ");
  1416.                 for (i = 0; i < n; ++i) {
  1417.                     *bufptr++ = (Address[i] < 0x20 || Address[i] > 0x7f) ? '.' : Address[i];
  1418.                 }
  1419.             }
  1420.  
  1421.             *bufptr++ = '\n';
  1422.             *bufptr = 0;
  1423.             AcslanDebugPrintString(dumpBuf);
  1424.             Length -= n;
  1425.             Address += n;
  1426.             ++iterations;
  1427.         }
  1428.  
  1429.         if (Options & DD_LINE_AFTER) {
  1430.             AcslanDebugPrintString("\n");
  1431.         }
  1432.     } except(1) {
  1433.         PUT(("*** Error: Bad Data @ %x, length %d ***\n", Address, Length));
  1434.     }
  1435. }
  1436.  
  1437. PRIVATE
  1438. VOID
  1439. DefaultParameterTableDump(
  1440.     IN  PVOID   Parameters
  1441.     )
  1442.  
  1443. /*++
  1444.  
  1445. Routine Description:
  1446.  
  1447.     Displays default message for CCBs which have parameter tables that don't
  1448.     have a dump routine yet
  1449.  
  1450. Arguments:
  1451.  
  1452.     Parameters  - pointer to parameter table
  1453.  
  1454. Return Value:
  1455.  
  1456.     None.
  1457.  
  1458. --*/
  1459.  
  1460. {
  1461.     PUT(("Parameter table dump not implemented for this CCB\n"));
  1462. }
  1463.  
  1464. PRIVATE
  1465. VOID
  1466. DumpParameterTableHeader(
  1467.     IN  LPSTR   CommandName,
  1468.     IN  PVOID   Table
  1469.     )
  1470.  
  1471. /*++
  1472.  
  1473. Routine Description:
  1474.  
  1475.     Displays header for parameter table dump
  1476.  
  1477. Arguments:
  1478.  
  1479.     CommandName - name of command which owns parameter table
  1480.     Table       - flat 32-bit address of parameter table
  1481.  
  1482. Return Value:
  1483.  
  1484.     None.
  1485.  
  1486. --*/
  1487.  
  1488. {
  1489.     PUT(("\n%s parameter table @ 0x%08x\n", CommandName, Table));
  1490. }
  1491.  
  1492. PRIVATE
  1493. VOID
  1494. DumpBufferCreateParms(
  1495.     IN PVOID Parameters
  1496.     )
  1497. {
  1498.     PLLC_BUFFER_CREATE_PARMS parms = (PLLC_BUFFER_CREATE_PARMS)Parameters;
  1499.  
  1500.     DumpParameterTableHeader("BUFFER.CREATE", Parameters);
  1501.  
  1502.     PUT(("Buf Pool Handle %08x\n"
  1503.         "Buf Pool Addr . %08x\n"
  1504.         "Buffer Size . . %08x\n"
  1505.         "Minimum Size. . %08x\n",
  1506.         parms->hBufferPool,
  1507.         parms->pBuffer,
  1508.         parms->cbBufferSize,
  1509.         parms->cbMinimumSizeThreshold
  1510.         ));
  1511. }
  1512.  
  1513. PRIVATE
  1514. VOID
  1515. DumpBufferFreeParms(
  1516.     IN  PVOID   Parameters
  1517.     )
  1518. {
  1519.     PLLC_BUFFER_FREE_PARMS parms = (PLLC_BUFFER_FREE_PARMS)Parameters;
  1520.  
  1521.     DumpParameterTableHeader("BUFFER.FREE", Parameters);
  1522.  
  1523.     PUT(("reserved. . . . %04x\n"
  1524.         "buffers left. . %04x\n"
  1525.         "reserved. . . . %02x %02x %02x %02x\n"
  1526.         "first buffer. . %08x\n",
  1527.         parms->usReserved1,
  1528.         parms->cBuffersLeft,
  1529.         ((PBYTE)&(parms->ulReserved))[0],
  1530.         ((PBYTE)&(parms->ulReserved))[1],
  1531.         ((PBYTE)&(parms->ulReserved))[2],
  1532.         ((PBYTE)&(parms->ulReserved))[3],
  1533.         parms->pFirstBuffer
  1534.         ));
  1535. }
  1536.  
  1537. PRIVATE
  1538. VOID
  1539. DumpBufferGetParms(
  1540.     IN  PVOID   Parameters
  1541.     )
  1542. {
  1543.     PLLC_BUFFER_GET_PARMS parms = (PLLC_BUFFER_GET_PARMS)Parameters;
  1544.  
  1545.     DumpParameterTableHeader("BUFFER.GET", Parameters);
  1546.  
  1547.     PUT(("reserved. . . . %04x\n"
  1548.         "buffers left. . %04x\n"
  1549.         "buffers to get. %04x\n"
  1550.         "buffer size . . %04x\n"
  1551.         "first buffer. . %08x\n",
  1552.         parms->usReserved1,
  1553.         parms->cBuffersLeft,
  1554.         parms->cBuffersToGet,
  1555.         parms->cbBufferSize,
  1556.         parms->pFirstBuffer
  1557.         ));
  1558. }
  1559.  
  1560. PRIVATE
  1561. VOID
  1562. DumpDirInitializeParms(
  1563.     IN  PVOID   Parameters
  1564.     )
  1565. {
  1566.     PLLC_DIR_INITIALIZE_PARMS parms = (PLLC_DIR_INITIALIZE_PARMS)Parameters;
  1567.  
  1568.     DumpParameterTableHeader("DIR.INITIALIZE", Parameters);
  1569.  
  1570.     PUT(("Bring Ups . . . %04x\n"
  1571.         "Reserved. . . . %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
  1572.         "                %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
  1573.         "                %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
  1574.         parms->usBringUps,
  1575.         parms->Reserved[ 0],
  1576.         parms->Reserved[ 1],
  1577.         parms->Reserved[ 2],
  1578.         parms->Reserved[ 3],
  1579.         parms->Reserved[ 4],
  1580.         parms->Reserved[ 5],
  1581.         parms->Reserved[ 6],
  1582.         parms->Reserved[ 7],
  1583.         parms->Reserved[ 8],
  1584.         parms->Reserved[ 9],
  1585.         parms->Reserved[10],
  1586.         parms->Reserved[11],
  1587.         parms->Reserved[12],
  1588.         parms->Reserved[13],
  1589.         parms->Reserved[14],
  1590.         parms->Reserved[15],
  1591.         parms->Reserved[16],
  1592.         parms->Reserved[17],
  1593.         parms->Reserved[18],
  1594.         parms->Reserved[19],
  1595.         parms->Reserved[20],
  1596.         parms->Reserved[21],
  1597.         parms->Reserved[22],
  1598.         parms->Reserved[23],
  1599.         parms->Reserved[24],
  1600.         parms->Reserved[25],
  1601.         parms->Reserved[26],
  1602.         parms->Reserved[27],
  1603.         parms->Reserved[28],
  1604.         parms->Reserved[29]
  1605.         ));
  1606. }
  1607.  
  1608. PRIVATE
  1609. VOID
  1610. DumpDirOpenAdapterParms(
  1611.     IN  PVOID   Parameters
  1612.     )
  1613. {
  1614.     PLLC_DIR_OPEN_ADAPTER_PARMS parms = (PLLC_DIR_OPEN_ADAPTER_PARMS)Parameters;
  1615.     PLLC_ADAPTER_OPEN_PARMS pAdapterParms = parms->pAdapterParms;
  1616.     PLLC_EXTENDED_ADAPTER_PARMS pExtendedParms = parms->pExtendedParms;
  1617.     PLLC_DLC_PARMS pDlcParms = parms->pDlcParms;
  1618.  
  1619.     DumpParameterTableHeader("DIR.OPEN.ADAPTER", Parameters);
  1620.  
  1621.     PUT(("adapter parms . %08x\n"
  1622.         "extended parms. %08x\n"
  1623.         "DLC parms . . . %08x\n"
  1624.         "reserved. . . . %08x\n",
  1625.         pAdapterParms,
  1626.         pExtendedParms,
  1627.         pDlcParms,
  1628.         parms->pReserved1
  1629.         ));
  1630.  
  1631.     if (pAdapterParms) {
  1632.         PUT(("\n"
  1633.             "Adapter Parms @ %08x\n"
  1634.             "open error. . . %04x\n"
  1635.             "open options. . %04x\n"
  1636.             "node address. . %02x-%02x-%02x-%02x-%02x-%02x\n"
  1637.             "group address . %08x\n"
  1638.             "func. address . %08x\n"
  1639.             "Reserved 1. . . %04x\n"
  1640.             "Reserved 2. . . %04x\n"
  1641.             "max frame size  %04x\n"
  1642.             "Reserved 3. . . %04x %04x %04x %04x\n"
  1643.             "bring ups . . . %04x\n"
  1644.             "init warnings . %04x\n"
  1645.             "Reserved 4. . . %04x %04x %04x\n",
  1646.             pAdapterParms,
  1647.             pAdapterParms->usOpenErrorCode,
  1648.             pAdapterParms->usOpenOptions,
  1649.             pAdapterParms->auchNodeAddress[0],
  1650.             pAdapterParms->auchNodeAddress[1],
  1651.             pAdapterParms->auchNodeAddress[2],
  1652.             pAdapterParms->auchNodeAddress[3],
  1653.             pAdapterParms->auchNodeAddress[4],
  1654.             pAdapterParms->auchNodeAddress[5],
  1655.             *(LPDWORD)(&pAdapterParms->auchGroupAddress),
  1656.             *(LPDWORD)(&pAdapterParms->auchFunctionalAddress),
  1657.             pAdapterParms->usReserved1,
  1658.             pAdapterParms->usReserved2,
  1659.             pAdapterParms->usMaxFrameSize,
  1660.             pAdapterParms->usReserved3[0],
  1661.             pAdapterParms->usReserved3[1],
  1662.             pAdapterParms->usReserved3[2],
  1663.             pAdapterParms->usReserved3[3],
  1664.             pAdapterParms->usBringUps,  // blooargh
  1665.             pAdapterParms->InitWarnings,
  1666.             pAdapterParms->usReserved4[0],
  1667.             pAdapterParms->usReserved4[1],
  1668.             pAdapterParms->usReserved4[2]
  1669.             ));
  1670.     }
  1671.  
  1672.     if (pExtendedParms) {
  1673.         PUT(("\n"
  1674.             "Extended Parms @ %08x\n"
  1675.             "hBufferPool . . %08x\n"
  1676.             "pSecurityDesc . %08x\n"
  1677.             "EthernetType. . %08x [%s]\n",
  1678.             pExtendedParms,
  1679.             pExtendedParms->hBufferPool,
  1680.             pExtendedParms->pSecurityDescriptor,
  1681.             pExtendedParms->LlcEthernetType,
  1682.             MapEthernetType(pExtendedParms->LlcEthernetType)
  1683.             ));
  1684.     }
  1685.  
  1686.     if (pDlcParms) {
  1687.         PUT(("\n"
  1688.             "DLC Parms @ %08x\n"
  1689.             "max SAPs. . . . %02x\n"
  1690.             "max links . . . %02x\n"
  1691.             "max group SAPs. %02x\n"
  1692.             "max group membs %02x\n"
  1693.             "T1 Tick 1 . . . %02x\n"
  1694.             "T2 Tick 1 . . . %02x\n"
  1695.             "Ti Tick 1 . . . %02x\n"
  1696.             "T1 Tick 2 . . . %02x\n"
  1697.             "T2 Tick 2 . . . %02x\n"
  1698.             "Ti Tick 2 . . . %02x\n",
  1699.             pDlcParms,
  1700.             pDlcParms->uchDlcMaxSaps,
  1701.             pDlcParms->uchDlcMaxStations,
  1702.             pDlcParms->uchDlcMaxGroupSaps,
  1703.             pDlcParms->uchDlcMaxGroupMembers,
  1704.             pDlcParms->uchT1_TickOne,
  1705.             pDlcParms->uchT2_TickOne,
  1706.             pDlcParms->uchTi_TickOne,
  1707.             pDlcParms->uchT1_TickTwo,
  1708.             pDlcParms->uchT2_TickTwo,
  1709.             pDlcParms->uchTi_TickTwo
  1710.             ));
  1711.     }
  1712. }
  1713.  
  1714. PRIVATE
  1715. LPSTR
  1716. MapEthernetType(
  1717.     IN LLC_ETHERNET_TYPE EthernetType
  1718.     )
  1719. {
  1720.     switch (EthernetType) {
  1721.     case LLC_ETHERNET_TYPE_DEFAULT:
  1722.         return "DEFAULT";
  1723.  
  1724.     case LLC_ETHERNET_TYPE_AUTO:
  1725.         return "AUTO";
  1726.  
  1727.     case LLC_ETHERNET_TYPE_802_3:
  1728.         return "802.3";
  1729.  
  1730.     case LLC_ETHERNET_TYPE_DIX:
  1731.         return "DIX";
  1732.     }
  1733.     return "*** Unknown Ethernet Type ***";
  1734. }
  1735.  
  1736. PRIVATE
  1737. VOID
  1738. DumpDirOpenDirectParms(
  1739.     IN PVOID Parameters
  1740.     )
  1741. {
  1742.     PLLC_DIR_OPEN_DIRECT_PARMS parms = (PLLC_DIR_OPEN_DIRECT_PARMS)Parameters;
  1743.  
  1744.     DumpParameterTableHeader("DIR.OPEN.DIRECT", Parameters);
  1745.  
  1746.     PUT(("reserved. . . . %04x %04x %04x %04x\n"
  1747.         "open options. . %04x\n"
  1748.         "ethernet type . %04x\n"
  1749.         "protocol mask . %08x\n"
  1750.         "protocol match. %08x\n"
  1751.         "protocol offset %04x\n",
  1752.         parms->Reserved[0],
  1753.         parms->Reserved[1],
  1754.         parms->Reserved[2],
  1755.         parms->Reserved[3],
  1756.         parms->usOpenOptions,
  1757.         parms->usEthernetType,
  1758.         parms->ulProtocolTypeMask,
  1759.         parms->ulProtocolTypeMatch,
  1760.         parms->usProtocolTypeOffset
  1761.         ));
  1762. }
  1763.  
  1764. PRIVATE
  1765. VOID
  1766. DumpDirReadLogParms(
  1767.     IN PVOID Parameters
  1768.     )
  1769. {
  1770.     PLLC_DIR_READ_LOG_PARMS parms = (PLLC_DIR_READ_LOG_PARMS)Parameters;
  1771.  
  1772.     DumpParameterTableHeader("DIR.READ.LOG", Parameters);
  1773.  
  1774.     PUT(("type id . . . . %04x [%s]\n"
  1775.         "log buf len . . %04x\n"
  1776.         "log buf ptr . . %08x\n"
  1777.         "act. log. len.. %04x\n",
  1778.         parms->usTypeId,
  1779.         MapLogType(parms->usTypeId),
  1780.         parms->cbLogBuffer,
  1781.         parms->pLogBuffer,
  1782.         parms->cbActualLength
  1783.         ));
  1784. }
  1785.  
  1786. PRIVATE
  1787. LPSTR
  1788. MapLogType(
  1789.     IN USHORT Type
  1790.     )
  1791. {
  1792.     switch (Type) {
  1793.     case 0:
  1794.         return "Adapter Error Log";
  1795.  
  1796.     case 1:
  1797.         return "Direct Interface Error Log";
  1798.  
  1799.     case 2:
  1800.         return "Adapter & Direct Interface Error Logs";
  1801.     }
  1802.     return "*** Unknown Log Type ***";
  1803. }
  1804.  
  1805. PRIVATE
  1806. VOID
  1807. DumpDirSetExceptionFlagsParms(
  1808.     IN PVOID Parameters
  1809.     )
  1810. {
  1811.     PLLC_DIR_SET_EFLAG_PARMS parms = (PLLC_DIR_SET_EFLAG_PARMS)Parameters;
  1812.  
  1813.     DumpParameterTableHeader("DIR.SET.EXCEPTION.FLAGS", Parameters);
  1814.  
  1815.     PUT(("Adapter Check Flag. %08x\n"
  1816.         "Network Status Flag %08x\n"
  1817.         "PC Error Flag . . . %08x\n"
  1818.         "System Action Flag. %08x\n",
  1819.         parms->ulAdapterCheckFlag,
  1820.         parms->ulNetworkStatusFlag,
  1821.         parms->ulPcErrorFlag,
  1822.         parms->ulSystemActionFlag
  1823.         ));
  1824. }
  1825.  
  1826. PRIVATE
  1827. VOID
  1828. DumpDirSetFunctionalAddressParms(
  1829.     IN PVOID Parameters
  1830.     )
  1831. {
  1832.     PUT(("Functional addr %08x\n", Parameters));
  1833. }
  1834.  
  1835. PRIVATE
  1836. VOID
  1837. DumpDirSetGroupAddressParms(
  1838.     IN PVOID Parameters
  1839.     )
  1840. {
  1841.     PUT(("Group addr. . . %08x\n", Parameters));
  1842. }
  1843.  
  1844. PRIVATE
  1845. VOID
  1846. DumpDirStatusParms(
  1847.     IN  PVOID   Parameters
  1848.     )
  1849. {
  1850.     PLLC_DIR_STATUS_PARMS parms = (PLLC_DIR_STATUS_PARMS)Parameters;
  1851.  
  1852.     DumpParameterTableHeader("DIR.STATUS", Parameters);
  1853.  
  1854.     PUT(("perm node addr. %02x-%02x-%02x-%02x-%02x-%02x\n"
  1855.         "local node addr %02x-%02x-%02x-%02x-%02x-%02x\n"
  1856.         "group addr. . . %08lx\n"
  1857.         "functional addr %08lx\n"
  1858.         "max SAPs. . . . %02x\n"
  1859.         "open SAPs . . . %02x\n"
  1860.         "max stations. . %02x\n"
  1861.         "open stations . %02x\n"
  1862.         "avail stations. %02x\n"
  1863.         "adapter config. %02x\n"
  1864.         "reserved 1. . . %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n"
  1865.         "reserved 2. . . %08x\n"
  1866.         "reserved 3. . . %08x\n"
  1867.         "max frame len . %08x\n"
  1868.         "last NW status. %04x\n"
  1869.         "adapter type. . %04x [%s]\n",
  1870.         parms->auchPermanentAddress[0],
  1871.         parms->auchPermanentAddress[1],
  1872.         parms->auchPermanentAddress[2],
  1873.         parms->auchPermanentAddress[3],
  1874.         parms->auchPermanentAddress[4],
  1875.         parms->auchPermanentAddress[5],
  1876.         parms->auchNodeAddress[0],
  1877.         parms->auchNodeAddress[1],
  1878.         parms->auchNodeAddress[2],
  1879.         parms->auchNodeAddress[3],
  1880.         parms->auchNodeAddress[4],
  1881.         parms->auchNodeAddress[5],
  1882.         *(LPDWORD)(&parms->auchGroupAddress),
  1883.         *(LPDWORD)(&parms->auchFunctAddr),
  1884.         parms->uchMaxSap,
  1885.         parms->uchOpenSaps,
  1886.         parms->uchMaxStations,
  1887.         parms->uchOpenStation,
  1888.         parms->uchAvailStations,
  1889.         parms->uchAdapterConfig,
  1890.         parms->auchReserved1[0],
  1891.         parms->auchReserved1[1],
  1892.         parms->auchReserved1[2],
  1893.         parms->auchReserved1[3],
  1894.         parms->auchReserved1[4],
  1895.         parms->auchReserved1[5],
  1896.         parms->auchReserved1[6],
  1897.         parms->auchReserved1[7],
  1898.         parms->auchReserved1[8],
  1899.         parms->auchReserved1[9],
  1900.         parms->ulReserved1,
  1901.         parms->ulReserved2,
  1902.         parms->ulMaxFrameLength,
  1903.         parms->usLastNetworkStatus,
  1904.         parms->usAdapterType,
  1905.         MapAdapterType(parms->usAdapterType)
  1906.         ));
  1907. }
  1908.  
  1909. PRIVATE
  1910. LPSTR
  1911. MapAdapterType(
  1912.     IN USHORT AdapterType
  1913.     )
  1914. {
  1915.     switch (AdapterType) {
  1916.     case 0x0001:
  1917.         return "Token Ring Network PC Adapter";
  1918.  
  1919.     case 0x0002:
  1920.         return "Token Ring Network PC Adapter II";
  1921.  
  1922.     case 0x0004:
  1923.         return "Token Ring Network Adapter/A";
  1924.  
  1925.     case 0x0008:
  1926.         return "Token Ring Network PC Adapter II";
  1927.  
  1928.     case 0x0020:
  1929.         return "Token Ring Network 16/4 Adapter";
  1930.  
  1931.     case 0x0040:
  1932.         return "Token Ring Network 16/4 Adapter/A";
  1933.  
  1934.     case 0x0080:
  1935.         return "Token Ring Network Adapter/A";
  1936.  
  1937.     case 0x0100:
  1938.         return "Ethernet Adapter";
  1939.  
  1940.     case 0x4000:
  1941.         return "PC Network Adapter";
  1942.  
  1943.     case 0x8000:
  1944.         return "PC Network Adapter/A";
  1945.     }
  1946.     return "*** Unknown Adapter Type ***";
  1947. }
  1948.  
  1949. PRIVATE
  1950. VOID
  1951. DumpDirTimerCancelParms(
  1952.     IN PVOID Parameters
  1953.     )
  1954. {
  1955.     PUT(("timer addr. . . %08x\n", Parameters));
  1956. }
  1957.  
  1958. PRIVATE
  1959. VOID
  1960. DumpDirTimerCancelGroupParms(
  1961.     IN PVOID Parameters
  1962.     )
  1963. {
  1964.     PUT(("timer cmpl flag %08x\n", Parameters));
  1965. }
  1966.  
  1967. PRIVATE
  1968. VOID
  1969. DumpDirTimerSetParms(
  1970.     IN PVOID Parameters
  1971.     )
  1972. {
  1973.     PUT(("time value. . . %04x\n", HIWORD(Parameters)));
  1974. }
  1975.  
  1976. PRIVATE
  1977. VOID
  1978. DumpDlcCloseSapParms(
  1979.     IN PVOID Parameters
  1980.     )
  1981. {
  1982.     PUT(("station id      %04x\n"
  1983.         "reserved. . . . %02x %02x\n",
  1984.         HIWORD(Parameters),
  1985.         HIBYTE(LOWORD(Parameters)),
  1986.         LOBYTE(LOWORD(Parameters))
  1987.         ));
  1988. }
  1989.  
  1990. PRIVATE
  1991. VOID
  1992. DumpDlcCloseStationParms(
  1993.     IN PVOID Parameters
  1994.     )
  1995. {
  1996.     PUT(("station id. . . %04x\n"
  1997.         "reserved. . . . %02x %02x\n",
  1998.         HIWORD(Parameters),
  1999.         HIBYTE(LOWORD(Parameters)),
  2000.         LOBYTE(LOWORD(Parameters))
  2001.         ));
  2002. }
  2003.  
  2004. PRIVATE
  2005. VOID
  2006. DumpDlcConnectStationParms(
  2007.     IN  PVOID   Parameters
  2008.     )
  2009. {
  2010.     PLLC_DLC_CONNECT_PARMS parms = (PLLC_DLC_CONNECT_PARMS)Parameters;
  2011.     LPBYTE routing = parms->pRoutingInfo;
  2012.     int i, n;
  2013.  
  2014.     DumpParameterTableHeader("DLC.CONNECT.STATION", Parameters);
  2015.  
  2016.     PUT(("station id. . . %04x\n"
  2017.         "reserved. . . . %04x\n"
  2018.         "routing addr. . %08x [",
  2019.         parms->usStationId,
  2020.         parms->usReserved,
  2021.         routing
  2022.         ));
  2023.     if (routing) {
  2024.         n = (int)(routing[0] & 0x1f);
  2025.         for (i=0; i<n-1; ++i) {
  2026.             PUT(("%02x ", routing[i]));
  2027.         }
  2028.         PUT(("%02x", routing[i]));
  2029.     }
  2030.     PUT(("]\n"));
  2031.     if (routing) {
  2032.         char broadcastIndicators = routing[0] & 0xe0;
  2033.         char length = routing[0] & 0x1f;
  2034.         char direction = routing[1] & 0x80;
  2035.         char largestFrame = routing[1] & 0x70;
  2036.         PUT(("Routing Info Description: "));
  2037.         if (broadcastIndicators & 0x80 == 0) {
  2038.             PUT(("Non Broadcast "));
  2039.         } else if (broadcastIndicators & 0xc0 == 0x80) {
  2040.             PUT(("All Routes Broadcast "));
  2041.         } else if (broadcastIndicators & 0xc0 == 0xc0) {
  2042.             PUT(("Single Route Broadcast "));
  2043.         }
  2044.         PUT(("Length = %d ", length));
  2045.         if (direction) {
  2046.             PUT(("interpret right-to-left "));
  2047.         } else {
  2048.             PUT(("interpret left-to-right "));
  2049.         }
  2050.         switch (largestFrame) {
  2051.         case 0x00:
  2052.             PUT(("<= 516 bytes in I-field "));
  2053.             break;
  2054.  
  2055.         case 0x10:
  2056.             PUT(("<= 1500 bytes in I-field "));
  2057.             break;
  2058.  
  2059.         case 0x20:
  2060.             PUT(("<= 2052 bytes in I-field "));
  2061.             break;
  2062.  
  2063.         case 0x30:
  2064.             PUT(("<= 4472 bytes in I-field "));
  2065.             break;
  2066.  
  2067.         case 0x40:
  2068.             PUT(("<= 8144 bytes in I-field "));
  2069.             break;
  2070.  
  2071.         case 0x50:
  2072.             PUT(("<= 11407 bytes in I-field "));
  2073.             break;
  2074.  
  2075.         case 0x60:
  2076.             PUT(("<= 17800 bytes in I-field "));
  2077.             break;
  2078.  
  2079.         case 0x70:
  2080.             PUT(("All-Routes Broadcast Frame "));
  2081.             break;
  2082.  
  2083.         }
  2084.         PUT(("\n"));
  2085.     }
  2086. }
  2087.  
  2088. PRIVATE
  2089. VOID
  2090. DumpDlcFlowControlParms(
  2091.     IN PVOID Parameters
  2092.     )
  2093. {
  2094.     PUT(("station id. . . %04x\n"
  2095.         "flow control. . %02x [%s]\n",
  2096.         HIWORD(Parameters),
  2097.         HIBYTE(LOWORD(Parameters)),
  2098.         MapFlowControl(HIBYTE(LOWORD(Parameters)))
  2099.         ));
  2100. }
  2101.  
  2102. PRIVATE
  2103. LPSTR
  2104. MapFlowControl(
  2105.     IN BYTE FlowControl
  2106.     )
  2107. {
  2108.     if (FlowControl & 0x80) {
  2109.         if (FlowControl & 0x40) {
  2110.             return "RESET LOCAL BUSY - BUFFER";
  2111.         } else {
  2112.             return "RESET LOCAL BUSY - USER";
  2113.         }
  2114.     } else {
  2115.         return "Enter LOCAL BUSY state";
  2116.     }
  2117. }
  2118.  
  2119. PRIVATE
  2120. VOID
  2121. DumpDlcModifyParms(
  2122.     IN PVOID Parameters
  2123.     )
  2124. {
  2125.     PLLC_DLC_MODIFY_PARMS parms = (PLLC_DLC_MODIFY_PARMS)Parameters;
  2126.  
  2127.     DumpParameterTableHeader("DLC.MODIFY", Parameters);
  2128.  
  2129.     PUT(("reserved. . . . %04x\n"
  2130.         "station id. . . %04x\n"
  2131.         "timer T1. . . . %02x\n"
  2132.         "timer T2. . . . %02x\n"
  2133.         "timer Ti. . . . %02x\n"
  2134.         "maxout. . . . . %02x\n"
  2135.         "maxin . . . . . %02x\n"
  2136.         "maxout incr . . %02x\n"
  2137.         "max retry count %02x\n"
  2138.         "reserved. . . . %02x\n"
  2139.         "max info field. %02x\n"
  2140.         "access priority %02x\n"
  2141.         "reserved. . . . %02x %02x %02x %02x\n"
  2142.         "group count . . %02x\n"
  2143.         "group list. . . %08x ",
  2144.         parms->usRes,
  2145.         parms->usStationId,
  2146.         parms->uchT1,
  2147.         parms->uchT2,
  2148.         parms->uchTi,
  2149.         parms->uchMaxOut,
  2150.         parms->uchMaxIn,
  2151.         parms->uchMaxOutIncr,
  2152.         parms->uchMaxRetryCnt,
  2153.         parms->uchReserved1,
  2154.         parms->usMaxInfoFieldLength,
  2155.         parms->uchAccessPriority,
  2156.         parms->auchReserved3[0],
  2157.         parms->auchReserved3[1],
  2158.         parms->auchReserved3[2],
  2159.         parms->auchReserved3[3],
  2160.         parms->cGroupCount,
  2161.         parms->pGroupList
  2162.         ));
  2163.  
  2164.     if (parms->pGroupList) {
  2165.         DumpData(NULL,
  2166.                  parms->pGroupList,
  2167.                  parms->cGroupCount,
  2168.                  DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE,
  2169.                  DEFAULT_FIELD_WIDTH + 8 + 1
  2170.                  );
  2171.     }
  2172.  
  2173.     PUT(("\n"));
  2174. }
  2175.  
  2176. PRIVATE
  2177. VOID
  2178. DumpDlcOpenSapParms(
  2179.     IN  PVOID   Parameters
  2180.     )
  2181. {
  2182.     PLLC_DLC_OPEN_SAP_PARMS parms = (PLLC_DLC_OPEN_SAP_PARMS)Parameters;
  2183.  
  2184.     DumpParameterTableHeader("DLC.OPEN.SAP", Parameters);
  2185.  
  2186.     PUT(("station id. . . %04x\n"
  2187.         "user stat . . . %04x\n"
  2188.         "T1. . . . . . . %02x\n"
  2189.         "T2. . . . . . . %02x\n"
  2190.         "Ti. . . . . . . %02x\n"
  2191.         "max out . . . . %02x\n"
  2192.         "max in  . . . . %02x\n"
  2193.         "max out incr. . %02x\n"
  2194.         "max retry count %02x\n"
  2195.         "max members . . %02x\n"
  2196.         "max I field . . %04x\n"
  2197.         "SAP value . . . %02x\n"
  2198.         "options/pri . . %02x\n"
  2199.         "link count. . . %02x\n"
  2200.         "reserved. . . . %02x %02x\n"
  2201.         "group count . . %02x\n"
  2202.         "group list. . . %08x\n"
  2203.         "status flags. . %08x\n"
  2204.         "reserved. . . . %02x %02x %02x %02x %02x %02x %02x %02x\n"
  2205.         "links available %02x\n",
  2206.         parms->usStationId,
  2207.         parms->usUserStatValue,
  2208.         parms->uchT1,
  2209.         parms->uchT2,
  2210.         parms->uchTi,
  2211.         parms->uchMaxOut,
  2212.         parms->uchMaxIn,
  2213.         parms->uchMaxOutIncr,
  2214.         parms->uchMaxRetryCnt,
  2215.         parms->uchMaxMembers,
  2216.         parms->usMaxI_Field,
  2217.         parms->uchSapValue,
  2218.         parms->uchOptionsPriority,
  2219.         parms->uchcStationCount,
  2220.         parms->uchReserved2[0],
  2221.         parms->uchReserved2[1],
  2222.         parms->cGroupCount,
  2223.         parms->pGroupList,
  2224.         parms->DlcStatusFlags,
  2225.         parms->uchReserved3[0],
  2226.         parms->uchReserved3[1],
  2227.         parms->uchReserved3[2],
  2228.         parms->uchReserved3[3],
  2229.         parms->uchReserved3[4],
  2230.         parms->uchReserved3[5],
  2231.         parms->uchReserved3[6],
  2232.         parms->uchReserved3[7],
  2233.         parms->cLinkStationsAvail
  2234.         ));
  2235. }
  2236.  
  2237. PRIVATE
  2238. VOID
  2239. DumpDlcOpenStationParms(
  2240.     IN  PVOID   Parameters
  2241.     )
  2242. {
  2243.     PLLC_DLC_OPEN_STATION_PARMS parms = (PLLC_DLC_OPEN_STATION_PARMS)Parameters;
  2244.     LPBYTE dest = parms->pRemoteNodeAddress;
  2245.     char destAddr[19];
  2246.  
  2247.     DumpParameterTableHeader("DLC.OPEN.STATION", Parameters);
  2248.  
  2249.     destAddr[0] = 0;
  2250.     if (dest) {
  2251.         sprintf(destAddr, "%02x-%02x-%02x-%02x-%02x-%02x",
  2252.                 dest[0],
  2253.                 dest[1],
  2254.                 dest[2],
  2255.                 dest[3],
  2256.                 dest[4],
  2257.                 dest[5]
  2258.                 );
  2259.     }
  2260.     PUT(("SAP station . . %04x\n"
  2261.         "link station. . %04x\n"
  2262.         "T1. . . . . . . %02x\n"
  2263.         "T2. . . . . . . %02x\n"
  2264.         "Ti. . . . . . . %02x\n"
  2265.         "max out . . . . %02x\n"
  2266.         "max in. . . . . %02x\n"
  2267.         "max out incr. . %02x\n"
  2268.         "max retry count %02x\n"
  2269.         "remote SAP. . . %02x\n"
  2270.         "max I field . . %04x\n"
  2271.         "access priority %02x\n"
  2272.         "remote node . . %08x [%s]\n",
  2273.         parms->usSapStationId,
  2274.         parms->usLinkStationId,
  2275.         parms->uchT1,
  2276.         parms->uchT2,
  2277.         parms->uchTi,
  2278.         parms->uchMaxOut,
  2279.         parms->uchMaxIn,
  2280.         parms->uchMaxOutIncr,
  2281.         parms->uchMaxRetryCnt,
  2282.         parms->uchRemoteSap,
  2283.         parms->usMaxI_Field,
  2284.         parms->uchAccessPriority,
  2285.         dest,
  2286.         destAddr
  2287.         ));
  2288. }
  2289.  
  2290. PRIVATE
  2291. VOID
  2292. DumpDlcReallocateParms(
  2293.     IN PVOID Parameters
  2294.     )
  2295. {
  2296.     PLLC_DLC_REALLOCATE_PARMS parms = (PLLC_DLC_REALLOCATE_PARMS)Parameters;
  2297.  
  2298.     DumpParameterTableHeader("DLC.REALLOCATE", Parameters);
  2299.  
  2300.     PUT(("station id. . . %04x\n"
  2301.         "option. . . . . %02x [%screase link stations]\n"
  2302.         "station count . %02x\n"
  2303.         "adapter stns. . %02x\n"
  2304.         "SAP stations. . %02x\n"
  2305.         "adapter total . %02x\n"
  2306.         "SAP total . . . %02x\n",
  2307.         parms->usStationId,
  2308.         parms->uchOption,
  2309.         parms->uchOption & 0x80 ? "De" : "In",
  2310.         parms->uchStationCount,
  2311.         parms->uchStationsAvailOnAdapter,
  2312.         parms->uchStationsAvailOnSap,
  2313.         parms->uchTotalStationsOnAdapter,
  2314.         parms->uchTotalStationsOnSap
  2315.         ));
  2316. }
  2317.  
  2318. PRIVATE
  2319. VOID
  2320. DumpDlcResetParms(
  2321.     IN PVOID Parameters
  2322.     )
  2323. {
  2324.     PUT(("station id. . . %04x\n", HIWORD(Parameters)));
  2325. }
  2326.  
  2327. PRIVATE
  2328. VOID
  2329. DumpDlcSetThresholdParms(
  2330.     IN PVOID Parameters
  2331.     )
  2332. {
  2333.     PLLC_DLC_SET_THRESHOLD_PARMS parms = (PLLC_DLC_SET_THRESHOLD_PARMS)Parameters;
  2334.  
  2335.     DumpParameterTableHeader("DLC.SET.THRESHOLD", Parameters);
  2336.  
  2337.     PUT(("station id. . . %04x\n"
  2338.         "buf threshold . %04x\n"
  2339.         "event . . . . . %08x\n",
  2340.         parms->usStationId,
  2341.         parms->cBufferThreshold,
  2342.         parms->AlertEvent
  2343.         ));
  2344. }
  2345.  
  2346. PRIVATE
  2347. VOID
  2348. DumpDlcStatisticsParms(
  2349.     IN PVOID Parameters
  2350.     )
  2351. {
  2352.     PLLC_DLC_STATISTICS_PARMS parms = (PLLC_DLC_STATISTICS_PARMS)Parameters;
  2353.  
  2354.     DumpParameterTableHeader("DLC.STATISTICS", Parameters);
  2355.  
  2356.     PUT(("station id. . . %04x\n"
  2357.         "log buf size. . %04x\n"
  2358.         "log buffer. . . %08x\n"
  2359.         "actual log len. %04x\n"
  2360.         "options . . . . %02x [%s]\n",
  2361.         parms->usStationId,
  2362.         parms->cbLogBufSize,
  2363.         parms->pLogBuf,
  2364.         parms->usActLogLength,
  2365.         parms->uchOptions,
  2366.         parms->uchOptions & 0x80 ? "Reset counters" : ""
  2367.         ));
  2368. }
  2369.  
  2370. PRIVATE
  2371. VOID
  2372. DumpReadParms(
  2373.     IN PVOID Parameters
  2374.     )
  2375. {
  2376.     PLLC_READ_PARMS parms = (PLLC_READ_PARMS)Parameters;
  2377.  
  2378.     DumpParameterTableHeader("READ", Parameters);
  2379.  
  2380.     try {
  2381.         PUT(("station id. . . %04x\n"
  2382.             "option ind. . . %02x [%s]\n"
  2383.             "event set . . . %02x\n"
  2384.             "event . . . . . %02x [%s]\n"
  2385.             "crit. subset. . %02x\n"
  2386.             "notify flag . . %08x\n",
  2387.             parms->usStationId,
  2388.             parms->uchOptionIndicator,
  2389.             MapOptionIndicator(parms->uchOptionIndicator),
  2390.             parms->uchEventSet,
  2391.             parms->uchEvent,
  2392.             MapReadEvent(parms->uchEvent),
  2393.             parms->uchCriticalSubset,
  2394.             parms->ulNotificationFlag
  2395.             ));
  2396.  
  2397.         //
  2398.         // rest of table interpreted differently depending on whether status change
  2399.         //
  2400.  
  2401.         if (parms->uchEvent & 0x38) {
  2402.             PUT(("station id. . . %04x\n"
  2403.                 "status code . . %04x [%s]\n"
  2404.                 "FRMR data . . . %02x %02x %02x %02x %02x\n"
  2405.                 "access pri. . . %02x\n"
  2406.                 "remote addr . . %02x-%02x-%02x-%02x-%02x-%02x\n"
  2407.                 "remote SAP. . . %02x\n"
  2408.                 "reserved. . . . %02x\n"
  2409.                 "user stat . . . %04x\n",
  2410.                 parms->Type.Status.usStationId,
  2411.                 parms->Type.Status.usDlcStatusCode,
  2412.                 MapDlcStatus(parms->Type.Status.usDlcStatusCode),
  2413.                 parms->Type.Status.uchFrmrData[0],
  2414.                 parms->Type.Status.uchFrmrData[1],
  2415.                 parms->Type.Status.uchFrmrData[2],
  2416.                 parms->Type.Status.uchFrmrData[3],
  2417.                 parms->Type.Status.uchFrmrData[4],
  2418.                 parms->Type.Status.uchAccessPritority,
  2419.                 parms->Type.Status.uchRemoteNodeAddress[0],
  2420.                 parms->Type.Status.uchRemoteNodeAddress[1],
  2421.                 parms->Type.Status.uchRemoteNodeAddress[2],
  2422.                 parms->Type.Status.uchRemoteNodeAddress[3],
  2423.                 parms->Type.Status.uchRemoteNodeAddress[4],
  2424.                 parms->Type.Status.uchRemoteNodeAddress[5],
  2425.                 parms->Type.Status.uchRemoteSap,
  2426.                 parms->Type.Status.uchReserved,
  2427.                 parms->Type.Status.usUserStatusValue
  2428.                 ));
  2429.         } else {
  2430.             PUT(("CCB count . . . %04x\n"
  2431.                 "CCB list. . . . %08x\n"
  2432.                 "buffer count. . %04x\n"
  2433.                 "buffer list . . %08x\n"
  2434.                 "frame count . . %04x\n"
  2435.                 "frame list. . . %08x\n"
  2436.                 "error code. . . %04x\n"
  2437.                 "error data. . . %04x %04x %04x\n",
  2438.                 parms->Type.Event.usCcbCount,
  2439.                 parms->Type.Event.pCcbCompletionList,
  2440.                 parms->Type.Event.usBufferCount,
  2441.                 parms->Type.Event.pFirstBuffer,
  2442.                 parms->Type.Event.usReceivedFrameCount,
  2443.                 parms->Type.Event.pReceivedFrame,
  2444.                 parms->Type.Event.usEventErrorCode,
  2445.                 parms->Type.Event.usEventErrorData[0],
  2446.                 parms->Type.Event.usEventErrorData[1],
  2447.                 parms->Type.Event.usEventErrorData[2]
  2448.                 ));
  2449.  
  2450.             IF_DEBUG(DUMP_ASYNC_CCBS) {
  2451.                 if (parms->Type.Event.usCcbCount) {
  2452.                     DumpCcb(parms->Type.Event.pCcbCompletionList,
  2453.                             TRUE,   // DumpAll
  2454.                             FALSE   // CcbIsInput
  2455.                             );
  2456.                 }
  2457.             }
  2458.  
  2459.             IF_DEBUG(DUMP_RX_INFO) {
  2460.                 if (parms->Type.Event.usReceivedFrameCount) {
  2461.                     DumpReceiveDataBuffer(parms->Type.Event.pReceivedFrame);
  2462.                 }
  2463.             }
  2464.         }
  2465.     } except(1) {
  2466.         PUT(("*** Error: Bad READ Parameter Table @ %x ***\n", parms));
  2467.     }
  2468. }
  2469.  
  2470. PRIVATE
  2471. LPSTR
  2472. MapOptionIndicator(
  2473.     IN UCHAR OptionIndicator
  2474.     )
  2475. {
  2476.     switch (OptionIndicator) {
  2477.     case 0:
  2478.         return "Match READ command using station id nnss";
  2479.  
  2480.     case 1:
  2481.         return "Match READ command using SAP number nn00";
  2482.  
  2483.     case 2:
  2484.         return "Match READ command using all events";
  2485.     }
  2486.     return "*** Unknown READ Option Indicator ***";
  2487. }
  2488.  
  2489. PRIVATE LPSTR MapReadEvent(UCHAR Event) {
  2490.     switch (Event) {
  2491.     case 0x80:
  2492.         return "Reserved Event!";
  2493.  
  2494.     case 0x40:
  2495.         return "System Action (non-critical)";
  2496.  
  2497.     case 0x20:
  2498.         return "Network Status (non-critical)";
  2499.  
  2500.     case 0x10:
  2501.         return "Critical Exception";
  2502.  
  2503.     case 0x8:
  2504.         return "DLC Status Change";
  2505.  
  2506.     case 0x4:
  2507.         return "Receive Data";
  2508.  
  2509.     case 0x2:
  2510.         return "Transmit Completion";
  2511.  
  2512.     case 0x1:
  2513.         return "Command Completion";
  2514.     }
  2515.     return "*** Unknown READ Event ***";
  2516. }
  2517.  
  2518. PRIVATE LPSTR MapDlcStatus(WORD Status) {
  2519.     if (Status & 0x8000) {
  2520.         return "Link lost";
  2521.     } else if (Status & 0x4000) {
  2522.         return "DM/DISC Received -or- DISC ack'd";
  2523.     } else if (Status & 0x2000) {
  2524.         return "FRMR Received";
  2525.     } else if (Status & 0x1000) {
  2526.         return "FRMR Sent";
  2527.     } else if (Status & 0x0800) {
  2528.         return "SABME Received for open link station";
  2529.     } else if (Status & 0x0400) {
  2530.         return "SABME Received - link station opened";
  2531.     } else if (Status & 0x0200) {
  2532.         return "REMOTE Busy Entered";
  2533.     } else if (Status & 0x0100) {
  2534.         return "REMOTE Busy Left";
  2535.     } else if (Status & 0x0080) {
  2536.         return "Ti EXPIRED";
  2537.     } else if (Status & 0x0040) {
  2538.         return "DLC counter overflow - issue DLC.STATISTICS";
  2539.     } else if (Status & 0x0020) {
  2540.         return "Access Priority lowered";
  2541.     } else if (Status & 0x001e) {
  2542.         return "*** ERROR - INVALID STATUS ***";
  2543.     } else if (Status & 0x0001) {
  2544.         return "Entered LOCAL Busy";
  2545.     }
  2546.     return "*** Unknown DLC Status ***";
  2547. }
  2548.  
  2549. PRIVATE
  2550. VOID
  2551. DumpReadCancelParms(
  2552.     IN PVOID Parameters
  2553.     )
  2554. {
  2555. }
  2556.  
  2557. PRIVATE
  2558. VOID
  2559. DumpReceiveParms(
  2560.     IN  PVOID   Parameters
  2561.     )
  2562. {
  2563.     PLLC_RECEIVE_PARMS parms = (PLLC_RECEIVE_PARMS)Parameters;
  2564.  
  2565.     DumpParameterTableHeader("RECEIVE", Parameters);
  2566.  
  2567.     PUT(("station id. . . %04x\n"
  2568.         "user length . . %04x\n"
  2569.         "receive flag. . %08x\n"
  2570.         "first buffer. . %08x\n"
  2571.         "options . . . . %02x [%s]\n"
  2572.         "reserved. . . . %02x %02x %02x\n"
  2573.         "rcv read optns. %02x [%s]\n",
  2574.         parms->usStationId,
  2575.         parms->usUserLength,
  2576.         parms->ulReceiveFlag,
  2577.         parms->pFirstBuffer,
  2578.         parms->uchOptions,
  2579.         MapReceiveOptions(parms->uchOptions),
  2580.         parms->auchReserved1[0],
  2581.         parms->auchReserved1[1],
  2582.         parms->auchReserved1[2],
  2583.         parms->uchRcvReadOption,
  2584.         MapRcvReadOption(parms->uchRcvReadOption)
  2585.         ));
  2586. }
  2587.  
  2588. PRIVATE
  2589. LPSTR
  2590. MapReceiveOptions(
  2591.     IN UCHAR Options
  2592.     )
  2593. {
  2594.     static char buf[80];
  2595.     BOOL space = FALSE;
  2596.  
  2597.     buf[0] = 0;
  2598.     if (Options & 0x80) {
  2599.         strcat(buf, "Contiguous MAC");
  2600.         Options &= 0x7f;
  2601.         space = TRUE;
  2602.     }
  2603.     if (Options & 0x40) {
  2604.         if (space) {
  2605.             strcat(buf, " ");
  2606.         }
  2607.         strcat(buf, "Contiguous DATA");
  2608.         Options &= 0xbf;
  2609.         space = TRUE;
  2610.     }
  2611.     if (Options & 0x20) {
  2612.         if (space) {
  2613.             strcat(buf, " ");
  2614.         }
  2615.         strcat(buf, "Break");
  2616.         Options &= 0xdf;
  2617.         space = TRUE;
  2618.     }
  2619.     if (Options) {
  2620.         if (space) {
  2621.             strcat(buf, " ");
  2622.         }
  2623.         strcat(buf, "*** Invalid options ***");
  2624.     }
  2625.     return buf;
  2626. }
  2627.  
  2628. PRIVATE
  2629. LPSTR
  2630. MapRcvReadOption(
  2631.     IN UCHAR Option
  2632.     )
  2633. {
  2634.     switch (Option) {
  2635.     case 0:
  2636.         return "Receive frames not chained";
  2637.  
  2638.     case 1:
  2639.         return "Chain receive frames for link station";
  2640.  
  2641.     case 2:
  2642.         return "Chain receive frames for SAP";
  2643.     }
  2644.     return "*** Unknown option ***";
  2645. }
  2646.  
  2647. PRIVATE
  2648. VOID
  2649. DumpReceiveCancelParms(
  2650.     IN PVOID Parameters
  2651.     )
  2652. {
  2653.     PUT(("station id. . . %04x\n", HIWORD(Parameters)));
  2654. }
  2655.  
  2656. PRIVATE
  2657. VOID
  2658. DumpReceiveModifyParms(
  2659.     IN PVOID Parameters
  2660.     )
  2661. {
  2662. }
  2663.  
  2664. PRIVATE
  2665. VOID
  2666. DumpTransmitDirFrameParms(
  2667.     IN  PVOID   Parameters
  2668.     )
  2669. {
  2670.     DumpParameterTableHeader("TRANSMIT.DIR.FRAME", Parameters);
  2671.     DumpTransmitParms(Parameters);
  2672. }
  2673.  
  2674. PRIVATE
  2675. VOID
  2676. DumpTransmitIFrameParms(
  2677.     IN PVOID Parameters
  2678.     )
  2679. {
  2680.     DumpParameterTableHeader("TRANSMIT.I.FRAME", Parameters);
  2681.     DumpTransmitParms(Parameters);
  2682. }
  2683.  
  2684. PRIVATE
  2685. VOID
  2686. DumpTransmitTestCmdParms(
  2687.     IN  PVOID   Parameters
  2688.     )
  2689. {
  2690.     DumpParameterTableHeader("TRANSMIT.TEST.CMD", Parameters);
  2691.     DumpTransmitParms(Parameters);
  2692. }
  2693.  
  2694. PRIVATE
  2695. VOID
  2696. DumpTransmitUiFrameParms(
  2697.     IN  PVOID   Parameters
  2698.     )
  2699. {
  2700.     DumpParameterTableHeader("TRANSMIT.UI.FRAME", Parameters);
  2701.     DumpTransmitParms(Parameters);
  2702. }
  2703.  
  2704. PRIVATE
  2705. VOID
  2706. DumpTransmitXidCmdParms(
  2707.     IN  PVOID   Parameters
  2708.     )
  2709. {
  2710.     DumpParameterTableHeader("TRANSMIT.XID.CMD", Parameters);
  2711.     DumpTransmitParms(Parameters);
  2712. }
  2713.  
  2714. PRIVATE
  2715. VOID
  2716. DumpTransmitXidRespFinalParms(
  2717.     IN  PVOID   Parameters
  2718.     )
  2719. {
  2720.     DumpParameterTableHeader("TRANSMIT.XID.RESP.FINAL", Parameters);
  2721.     DumpTransmitParms(Parameters);
  2722. }
  2723.  
  2724. PRIVATE
  2725. VOID
  2726. DumpTransmitXidRespNotFinalParms(
  2727.     IN  PVOID   Parameters
  2728.     )
  2729. {
  2730.     DumpParameterTableHeader("TRANSMIT.XID.RESP.NOT.FINAL", Parameters);
  2731.     DumpTransmitParms(Parameters);
  2732. }
  2733.  
  2734. PRIVATE
  2735. VOID
  2736. DumpTransmitFramesParms(
  2737.     IN PVOID Parameters
  2738.     )
  2739. {
  2740.     DumpParameterTableHeader("TRANSMIT.FRAMES", Parameters);
  2741. //    DumpTransmitParms(Parameters);
  2742. }
  2743.  
  2744. PRIVATE
  2745. VOID
  2746. DumpTransmitParms(
  2747.     IN PVOID Parameters
  2748.     )
  2749. {
  2750.     PLLC_TRANSMIT_PARMS parms = (PLLC_TRANSMIT_PARMS)Parameters;
  2751.  
  2752.     try {
  2753.         PUT(("StationId . . . %04x\n"
  2754.             "Transmit FS . . %02x\n"
  2755.             "Remote SAP. . . %02x\n"
  2756.             "Xmit Queue 1. . %08x\n"
  2757.             "Xmit Queue 2. . %08x\n"
  2758.             "Buffer Length 1 %02x\n"
  2759.             "Buffer Length 2 %02x\n"
  2760.             "Buffer 1. . . . %08x\n"
  2761.             "Buffer 2. . . . %08x\n"
  2762.             "Xmt Read Option %02x [%s]\n"
  2763.             "\n",
  2764.             parms->usStationId,
  2765.             parms->uchTransmitFs,
  2766.             parms->uchRemoteSap,
  2767.             parms->pXmitQueue1,
  2768.             parms->pXmitQueue2,
  2769.             parms->cbBuffer1,
  2770.             parms->cbBuffer2,
  2771.             parms->pBuffer1,
  2772.             parms->pBuffer2,
  2773.             parms->uchXmitReadOption,
  2774.             MapXmitReadOption(parms->uchXmitReadOption)
  2775.             ));
  2776.  
  2777.         IF_DEBUG(DUMP_TX_INFO) {
  2778.             if (parms->pXmitQueue1) {
  2779.                 PUT(("XMIT_QUEUE_ONE:\n"));
  2780.                 DumpTransmitQueue(parms->pXmitQueue1);
  2781.             }
  2782.  
  2783.             if (parms->pXmitQueue2) {
  2784.                 PUT(("XMIT_QUEUE_TWO:\n"));
  2785.                 DumpTransmitQueue(parms->pXmitQueue2);
  2786.             }
  2787.         }
  2788.  
  2789.         IF_DEBUG(DUMP_TX_DATA) {
  2790.             if (parms->cbBuffer1) {
  2791.                 DumpData("BUFFER_ONE. . . ",
  2792.                         (PBYTE)parms->pBuffer1,
  2793.                         (DWORD)parms->cbBuffer1,
  2794.                         DD_NO_ADDRESS
  2795.                         | DD_LINE_AFTER
  2796.                         | DD_INDENT_ALL
  2797.                         | DD_UPPER_CASE
  2798.                         | DD_DOT_DOT_SPACE,
  2799.                         DEFAULT_FIELD_WIDTH
  2800.                         );
  2801.             }
  2802.  
  2803.             if (parms->cbBuffer2) {
  2804.                 DumpData("BUFFER_TWO. . . ",
  2805.                         (PBYTE)parms->pBuffer2,
  2806.                         (DWORD)parms->cbBuffer2,
  2807.                         DD_NO_ADDRESS
  2808.                         | DD_LINE_AFTER
  2809.                         | DD_INDENT_ALL
  2810.                         | DD_UPPER_CASE
  2811.                         | DD_DOT_DOT_SPACE,
  2812.                         DEFAULT_FIELD_WIDTH
  2813.                         );
  2814.             }
  2815.         }
  2816.     } except(1) {
  2817.         PUT(("*** Error: Bad Transmit Parameter Table @ %x ***\n", parms));
  2818.     }
  2819. }
  2820.  
  2821. PRIVATE
  2822. VOID
  2823. DumpTransmitQueue(
  2824.     IN PLLC_XMIT_BUFFER Buffer
  2825.     )
  2826. {
  2827.     try {
  2828.         while (Buffer) {
  2829.             PUT(("Next. . . . . . %08x\n"
  2830.                 "Reserved. . . . %04x\n"
  2831.                 "Data In Buffer. %04x\n"
  2832.                 "User Data . . . %04x\n"
  2833.                 "User Length . . %04x\n"
  2834.                 "\n",
  2835.                 Buffer->pNext,
  2836.                 Buffer->usReserved1,
  2837.                 Buffer->cbBuffer,
  2838.                 Buffer->usReserved2,
  2839.                 Buffer->cbUserData
  2840.                 ));
  2841.  
  2842.             IF_DEBUG(DUMP_TX_DATA) {
  2843.                 DumpData(NULL,
  2844.                         (PBYTE)Buffer->auchData,
  2845.                         (DWORD)Buffer->cbBuffer + (DWORD)Buffer->cbUserData,
  2846.                         DD_DEFAULT_OPTIONS,
  2847.                         DEFAULT_FIELD_WIDTH
  2848.                         );
  2849.             }
  2850.             Buffer = Buffer->pNext;
  2851.         }
  2852.     } except(1) {
  2853.         PUT(("*** Error: Bad Transmit Queue/Buffer @ %x ***\n", Buffer));
  2854.     }
  2855. }
  2856.  
  2857. PRIVATE
  2858. LPSTR
  2859. MapXmitReadOption(
  2860.     IN UCHAR Option
  2861.     )
  2862. {
  2863.     switch (Option) {
  2864.     case 0:
  2865.         return "Chain this Transmit on Link station basis";
  2866.  
  2867.     case 1:
  2868.         return "Do not chain this Transmit completion";
  2869.  
  2870.     case 2:
  2871.         return "Chain this Transmit on SAP station basis";
  2872.     }
  2873.     return "*** Unknown XMIT_READ_OPTION ***";
  2874. }
  2875.  
  2876. VOID
  2877. DumpReceiveDataBuffer(
  2878.     IN PVOID Buffer
  2879.     )
  2880. {
  2881.     PLLC_BUFFER pBuf = (PLLC_BUFFER)Buffer;
  2882.     BOOL contiguous;
  2883.     WORD userLength;
  2884.     WORD dataLength;
  2885.     WORD userOffset;
  2886.  
  2887.     try {
  2888.         contiguous = pBuf->Contiguous.uchOptions & 0xc0;
  2889.         userLength = pBuf->Next.cbUserData;
  2890.         dataLength = pBuf->Next.cbBuffer;
  2891.         userOffset = pBuf->Next.offUserData;
  2892.     } except(1) {
  2893.         PUT(("*** Error: Bad received data buffer address %x ***\n", pBuf));
  2894.         return;
  2895.     }
  2896.  
  2897.     //
  2898.     // Buffer 1: [not] contiguous MAC/DATA
  2899.     //
  2900.  
  2901.     try {
  2902.         PUT(("\n"
  2903.             "%sContiguous MAC/DATA frame @%08x\n"
  2904.             "next buffer . . %08x\n"
  2905.             "frame length. . %04x\n"
  2906.             "data length . . %04x\n"
  2907.             "user offset . . %04x\n"
  2908.             "user length . . %04x\n"
  2909.             "station id. . . %04x\n"
  2910.             "options . . . . %02x\n"
  2911.             "message type. . %02x [%s]\n"
  2912.             "buffers left. . %04x\n"
  2913.             "rcv FS. . . . . %02x\n"
  2914.             "adapter num . . %02x\n"
  2915.             "next frame. . . %08x\n",
  2916.             contiguous ? "" : "Not",
  2917.             pBuf,
  2918.             pBuf->Contiguous.pNextBuffer,
  2919.             pBuf->Contiguous.cbFrame,
  2920.             pBuf->Contiguous.cbBuffer,
  2921.             pBuf->Contiguous.offUserData,
  2922.             pBuf->Contiguous.cbUserData,
  2923.             pBuf->Contiguous.usStationId,
  2924.             pBuf->Contiguous.uchOptions,
  2925.             pBuf->Contiguous.uchMsgType,
  2926.             MapMessageType(pBuf->Contiguous.uchMsgType),
  2927.             pBuf->Contiguous.cBuffersLeft,
  2928.             pBuf->Contiguous.uchRcvFS,
  2929.             pBuf->Contiguous.uchAdapterNumber,
  2930.             pBuf->Contiguous.pNextFrame
  2931.             ));
  2932.  
  2933.         if (!contiguous) {
  2934.  
  2935.             //
  2936.             // dump NotContiguous header
  2937.             //
  2938.  
  2939.             DWORD cbLanHeader = (DWORD)pBuf->NotContiguous.cbLanHeader;
  2940.             DWORD cbDlcHeader = (DWORD)pBuf->NotContiguous.cbDlcHeader;
  2941.  
  2942.             PUT(("LAN hdr len . . %02x\n"
  2943.                 "DLC hdr len . . %02x\n",
  2944.                 cbLanHeader,
  2945.                 cbDlcHeader
  2946.                 ));
  2947.             DumpData("LAN header. . . ",
  2948.                     pBuf->NotContiguous.auchLanHeader,
  2949.                     cbLanHeader,
  2950.                     DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
  2951.                     DEFAULT_FIELD_WIDTH
  2952.                     );
  2953.             DumpData("DLC header. . . ",
  2954.                     pBuf->NotContiguous.auchDlcHeader,
  2955.                     cbDlcHeader,
  2956.                     DD_NO_ADDRESS | DD_NO_ASCII | DD_UPPER_CASE | DD_INDENT_ALL,
  2957.                     DEFAULT_FIELD_WIDTH
  2958.                     );
  2959.  
  2960.             if (userLength) {
  2961.                 DumpData("user space. . . ",
  2962.                         (PBYTE)pBuf + userOffset,
  2963.                         userLength,
  2964.                         DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL,
  2965.                         DEFAULT_FIELD_WIDTH
  2966.                         );
  2967.             } else {
  2968.                 PUT(("user space. . . \n"));
  2969.             }
  2970.  
  2971.             IF_DEBUG(DUMP_RX_DATA) {
  2972.  
  2973.                 if (dataLength) {
  2974.                     DumpData("rcvd data . . . ",
  2975.                             (PBYTE)pBuf + userOffset + userLength,
  2976.                             dataLength,
  2977.                             DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL | DD_DOT_DOT_SPACE,
  2978.                             DEFAULT_FIELD_WIDTH
  2979.                             );
  2980.                 } else {
  2981.                     PUT(("rcvd data . . . \n"));
  2982.                 }
  2983.             }
  2984.         } else {
  2985.  
  2986.             //
  2987.             // dump Contiguous header
  2988.             //
  2989.             // data length is size of frame in contiguous buffer?
  2990.             //
  2991.  
  2992.             if (userLength) {
  2993.                 DumpData("user space. . . ",
  2994.                         (PBYTE)pBuf + userOffset,
  2995.                         userLength,
  2996.                         DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL | DD_DOT_DOT_SPACE,
  2997.                         DEFAULT_FIELD_WIDTH
  2998.                         );
  2999.             } else {
  3000.                 PUT(("user space. . . \n"));
  3001.             }
  3002.  
  3003.             IF_DEBUG(DUMP_RX_DATA) {
  3004.  
  3005.                 dataLength = pBuf->Contiguous.cbFrame;
  3006.  
  3007.                 if (dataLength) {
  3008.                     DumpData("rcvd data . . . ",
  3009.                             (PBYTE)pBuf + userOffset + userLength,
  3010.                             dataLength,
  3011.                             DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL | DD_DOT_DOT_SPACE,
  3012.                             DEFAULT_FIELD_WIDTH
  3013.                             );
  3014.                 } else {
  3015.                     PUT(("rcvd data . . . \n"));
  3016.                 }
  3017.             }
  3018.         }
  3019.  
  3020.         //
  3021.         // dump second & subsequent buffers
  3022.         //
  3023.  
  3024.         IF_DEBUG(DUMP_DATA_CHAIN) {
  3025.  
  3026.             for (pBuf = pBuf->pNext; pBuf; pBuf = pBuf->pNext) {
  3027.  
  3028.                 userLength = pBuf->Next.cbUserData;
  3029.                 dataLength = pBuf->Next.cbBuffer;
  3030.  
  3031.                 PUT(("\n"
  3032.                     "Buffer 2/Subsequent @%08x\n"
  3033.                     "next buffer . . %08x\n"
  3034.                     "frame length. . %04x\n"
  3035.                     "data length . . %04x\n"
  3036.                     "user offset . . %04x\n"
  3037.                     "user length . . %04x\n",
  3038.                     pBuf,
  3039.                     pBuf->pNext,
  3040.                     pBuf->Next.cbFrame,
  3041.                     dataLength,
  3042.                     pBuf->Next.offUserData,
  3043.                     userLength
  3044.                     ));
  3045.  
  3046.                 if (userLength) {
  3047.                     DumpData("user space. . . ",
  3048.                             (PBYTE)&pBuf + pBuf->Next.offUserData,
  3049.                             userLength,
  3050.                             DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL | DD_DOT_DOT_SPACE,
  3051.                             DEFAULT_FIELD_WIDTH
  3052.                             );
  3053.                 } else {
  3054.                     PUT(("user space. . . \n"));
  3055.                 }
  3056.  
  3057.                 IF_DEBUG(DUMP_RX_DATA) {
  3058.  
  3059.                     //
  3060.                     // there must be received data
  3061.                     //
  3062.  
  3063.                     DumpData("rcvd data . . . ",
  3064.                             (PBYTE)pBuf + pBuf->Next.offUserData + userLength,
  3065.                             dataLength,
  3066.                             DD_NO_ADDRESS | DD_UPPER_CASE | DD_INDENT_ALL | DD_DOT_DOT_SPACE,
  3067.                             DEFAULT_FIELD_WIDTH
  3068.                             );
  3069.                 }
  3070.             }
  3071.         }
  3072.  
  3073.         if (((PLLC_BUFFER)Buffer)->Contiguous.pNextFrame) {
  3074.             DumpReceiveDataBuffer(((PLLC_BUFFER)Buffer)->Contiguous.pNextFrame);
  3075.         }
  3076.  
  3077.     } except(1) {
  3078.         PUT(("*** Error: Bad Receive Data Buffer @ %x ***\n", Buffer));
  3079.     }
  3080. }
  3081.  
  3082. PRIVATE
  3083. LPSTR
  3084. MapMessageType(
  3085.     IN UCHAR MessageType
  3086.     )
  3087. {
  3088.     switch (MessageType) {
  3089.     case 0x00:
  3090.         return "Direct Transmit Frame";
  3091.  
  3092.     case 0x02:
  3093.         return "MAC Frame (Direct Station on Token Ring only)";
  3094.  
  3095.     case 0x04:
  3096.         return "I-Frame";
  3097.  
  3098.     case 0x06:
  3099.         return "UI-Frame";
  3100.  
  3101.     case 0x08:
  3102.         return "XID Command (POLL)";
  3103.  
  3104.     case 0x0a:
  3105.         return "XID Command (not POLL)";
  3106.  
  3107.     case 0x0c:
  3108.         return "XID Response (FINAL)";
  3109.  
  3110.     case 0x0e:
  3111.         return "XID Response (not FINAL)";
  3112.  
  3113.     case 0x10:
  3114.         return "TEST Response (FINAL)";
  3115.  
  3116.     case 0x12:
  3117.         return "TEST Response (not FINAL)";
  3118.  
  3119.     case 0x14:
  3120.         return "Direct 802.2/OTHER - non-MAC frame (Direct Station only)";
  3121.  
  3122.     case 0x16:
  3123.         return "TEST Command (POLL)";
  3124.  
  3125.     case 0x18:
  3126.         return "Direct Ethernet Frame";
  3127.  
  3128.     case 0x1a:
  3129.         return "Last Frame Type";
  3130.  
  3131. //    case 0x5dd:
  3132. //        return "First Ethernet Frame Type";
  3133.  
  3134.     default:
  3135.         return "*** BAD FRAME TYPE ***";
  3136.     }
  3137. }
  3138.  
  3139. //PRIVATE
  3140. //VOID
  3141. //DumpData(
  3142. //    IN PBYTE Address,
  3143. //    IN DWORD Length
  3144. //    )
  3145. //{
  3146. //    char dumpBuf[80];
  3147. //    char* bufptr;
  3148. //    int i, n;
  3149. //
  3150. //    //
  3151. //    // the usual dump style: 16 columns of hex bytes, followed by 16 columns
  3152. //    // of corresponding ASCII characters, or '.' where the character is < 0x20
  3153. //    // (space) or > 0x7f (del?)
  3154. //    //
  3155. //
  3156. //    while (Length) {
  3157. //        bufptr = dumpBuf;
  3158. //        bufptr += sprintf(bufptr, "%08x: ", Address);
  3159. //        if (Length < 16) {
  3160. //            n = Length;
  3161. //        } else {
  3162. //            n = 16;
  3163. //        }
  3164. //        for (i = 0; i < n; ++i) {
  3165. //            bufptr += sprintf(bufptr, "%02x", Address[i]);
  3166. //            if (i == 7) {
  3167. //                *bufptr = '-';
  3168. //            } else {
  3169. //                *bufptr = ' ';
  3170. //            }
  3171. //            ++bufptr;
  3172. //        }
  3173. //        if (n < 16) {
  3174. //            for (i = 0; i < 16-n; ++i) {
  3175. //                bufptr += sprintf(bufptr, "   ");
  3176. //            }
  3177. //        }
  3178. //        bufptr += sprintf(bufptr, "  ");
  3179. //        for (i = 0; i < n; ++i) {
  3180. //            if (Address[i] < 0x20 || Address[i] > 0x7f) {
  3181. //                *bufptr++ = '.';
  3182. //            } else {
  3183. //                *bufptr++ = Address[i];
  3184. //            }
  3185. //        }
  3186. //        *bufptr++ = '\n';
  3187. //        *bufptr = 0;
  3188. //        PUT((dumpBuf));
  3189. //        Length -= n;
  3190. //        Address += n;
  3191. //    }
  3192. //    PUT(("\n"));
  3193. //}
  3194. #endif
  3195.