📄 datalink.c
字号:
if (DOT3DL) {
ULONG dataChannel;
ULONG pid = 0x285; // pid for dot4
// Only use the first channel.
if( !String2Num(&DOT3DL, ',', &dataChannel) ) {
dataChannel = 77;
DD((PCE)Pdx,DDT,"ParDot3CreateObject - No DataChannel Defined\n");
}
if( DOT3C ) {
if (!String2Num(&DOT3C, ',', &pid)) {
pid = 0x285;
DD((PCE)Pdx,DDT,"ParDot3CreateObject - No CurrentPID Defined\n");
}
DD((PCE)Pdx,DDT,"ParDot3CreateObject - .3 mode is ON\n");
}
Pdx->P12843DL.DataChannel = (UCHAR)dataChannel;
Pdx->P12843DL.CurrentPID = (USHORT)pid;
Pdx->P12843DL.DataLinkMode = P12843DL_DOT3_DL;
DD((PCE)Pdx,DDT,"ParDot3CreateObject - Data [%x] CurrentPID [%x]\n",Pdx->P12843DL.DataChannel, Pdx->P12843DL.CurrentPID);
}
if (Pdx->P12843DL.DataLinkMode == P12843DL_OFF) {
DD((PCE)Pdx,DDT,"ParDot3CreateObject - DANGER: .3 mode is OFF\n");
}
}
VOID
ParDot4CreateObject(
IN PPDO_EXTENSION Pdx,
IN PCHAR DOT4DL
)
{
Pdx->P12843DL.DataLinkMode = P12843DL_OFF;
Pdx->P12843DL.fnReset = NULL;
DD((PCE)Pdx,DDT,"ParDot3CreateObject: DOT4DL [%s]\n",DOT4DL);
if (DOT4DL) {
UCHAR numValues = StringCountValues( (PCHAR)DOT4DL, ',' );
ULONG dataChannel, resetChannel, ResetByteCount;
DD((PCE)Pdx,DDT,"ParDot3CreateObject: numValues [%d]\n",numValues);
if (!String2Num(&DOT4DL, ',', &dataChannel)) {
dataChannel = 77;
DD((PCE)Pdx,DDT,"ParDot4CreateObject: No DataChannel Defined.\r\n");
}
if ((String2Num(&DOT4DL, ',', &resetChannel)) && (numValues > 1)) {
if (resetChannel == -1) {
Pdx->P12843DL.fnReset = ParMLCCompatReset;
} else {
Pdx->P12843DL.fnReset = ParMLCECPReset;
}
DD((PCE)Pdx,DDT,"ParDot4CreateObject: ResetChannel Defined.\r\n");
} else {
Pdx->P12843DL.fnReset = NULL;
DD((PCE)Pdx,DDT,"ParDot4CreateObject: No ResetChannel Defined.\r\n");
}
if ((!String2Num(&DOT4DL, 0, &ResetByteCount)) && (numValues > 2)) {
ResetByteCount = 4;
DD((PCE)Pdx,DDT,"ParDot4CreateObject: No ResetByteCount Defined.\r\n");
}
Pdx->P12843DL.DataChannel = (UCHAR)dataChannel;
Pdx->P12843DL.ResetChannel = (UCHAR)resetChannel;
Pdx->P12843DL.ResetByteCount = (UCHAR)ResetByteCount;
Pdx->P12843DL.DataLinkMode = P12843DL_DOT4_DL;
DD((PCE)Pdx,DDT,"ParDot4CreateObject: .4DL mode is ON.\r\n");
DD((PCE)Pdx,DDT,"ParDot4CreateObject: Data [%x] Reset [%x] Bytes [%x]\r\n",
Pdx->P12843DL.DataChannel,
Pdx->P12843DL.ResetChannel,
Pdx->P12843DL.ResetByteCount);
}
#if DBG
if (Pdx->P12843DL.DataLinkMode == P12843DL_OFF) {
DD((PCE)Pdx,DDT,"ParDot4CreateObject: DANGER: .4DL mode is OFF.\r\n");
}
#endif
}
VOID
ParMLCCreateObject(
IN PPDO_EXTENSION Pdx,
IN PCHAR CMDField
)
{
Pdx->P12843DL.DataLinkMode = P12843DL_OFF;
Pdx->P12843DL.fnReset = NULL;
if (CMDField)
{
Pdx->P12843DL.DataChannel = 77;
Pdx->P12843DL.DataLinkMode = P12843DL_MLC_DL;
DD((PCE)Pdx,DDT,"ParMLCCreateObject: MLC mode is on.\r\n");
}
#if DBG
if (Pdx->P12843DL.DataLinkMode == P12843DL_OFF)
{
DD((PCE)Pdx,DDT,"ParMLCCreateObject: DANGER: MLC mode is OFF.\r\n");
}
#endif
}
VOID
ParDot3DestroyObject(
IN PPDO_EXTENSION Pdx
)
{
Pdx->P12843DL.DataLinkMode = P12843DL_OFF;
}
NTSTATUS
ParDot3Disconnect(
IN PPDO_EXTENSION Pdx
)
{
if (Pdx->P12843DL.DataLinkMode == P12843DL_DOT3_DL) {
Pdx->fnRead = arpReverse[Pdx->IdxReverseProtocol].fnRead;
Pdx->fnWrite = afpForward[Pdx->IdxForwardProtocol].fnWrite;
}
Pdx->P12843DL.bEventActive = FALSE;
Pdx->P12843DL.Event = 0;
return STATUS_SUCCESS;
}
VOID
ParDot3ParseModes(
IN PPDO_EXTENSION Pdx,
IN PCHAR DOT3M
)
{
ULONG fwd = 0;
ULONG rev = 0;
DD((PCE)Pdx,DDT,"ParDot3ParseModes: DOT3M [%s]\n",DOT3M);
if (DOT3M) {
UCHAR numValues = StringCountValues((PCHAR)DOT3M, ',');
if (numValues != 2) {
// The periph gave me bad values. I'm not gonna read
// them. I will set the defaults to the lowest
// common denominator.
DD((PCE)Pdx,DDT,"ParDot3ParseModes: Malformed 1284.3M field.\r\n");
Pdx->P12843DL.FwdSkipMask = (USHORT) PAR_FWD_MODE_SKIP_MASK;
Pdx->P12843DL.RevSkipMask = (USHORT) PAR_REV_MODE_SKIP_MASK;
return;
}
// Only use the first channel.
if (!String2Num(&DOT3M, ',', &fwd)) {
fwd = (USHORT) PAR_FWD_MODE_SKIP_MASK;
DD((PCE)Pdx,DDT,"ParDot3ParseModes: Couldn't read fwd of 1284.3M.\r\n");
}
if (!String2Num(&DOT3M, ',', &rev)) {
rev = (USHORT) PAR_REV_MODE_SKIP_MASK;
DD((PCE)Pdx,DDT,"ParDot3ParseModes: Couldn't read rev of 1284.3M.\r\n");
}
}
Pdx->P12843DL.FwdSkipMask = (USHORT) fwd;
Pdx->P12843DL.RevSkipMask = (USHORT) rev;
}
NTSTATUS
ParDot3Read(
IN PPDO_EXTENSION Pdx,
IN PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG BytesTransferred
)
{
NTSTATUS Status;
UCHAR ucScrap1;
UCHAR ucScrap2[2];
USHORT usScrap1;
ULONG bytesToRead;
ULONG bytesTransferred;
USHORT Dot3CheckSum;
USHORT Dot3DataLen;
// ================================== Read the first byte of SOF
bytesToRead = 1;
bytesTransferred = 0;
do
{
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, &ucScrap1, bytesToRead, &bytesTransferred);
}
while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
// ================================== Check the first byte of SOF
if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_StartOfFrame1)
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
// ================================== Read the second byte of SOF
bytesToRead = 1;
bytesTransferred = 0;
do
{
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, &ucScrap1, bytesToRead, &bytesTransferred);
}
while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
// ================================== Check the second byte of SOF
if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_StartOfFrame2)
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
// ================================== Read the PID (Should be in Big Endian)
bytesToRead = 2;
bytesTransferred = 0;
do
{
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, &usScrap1, bytesToRead, &bytesTransferred);
}
while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
// ================================== Check the PID
if (!NT_SUCCESS(Status) || usScrap1 != Pdx->P12843DL.CurrentPID)
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
// ================================== Read the DataLen
bytesToRead = 2;
bytesTransferred = 0;
do
{
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, &ucScrap2[0], bytesToRead, &bytesTransferred);
}
while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
Dot3DataLen = (USHORT)((USHORT)(ucScrap2[0]<<8 | ucScrap2[1]));
// ================================== Check the DataLen
if (!NT_SUCCESS(Status))
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
// ================================== Read the Checksum
bytesToRead = 2;
bytesTransferred = 0;
do
{
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, &ucScrap2[0], bytesToRead, &bytesTransferred);
}
while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
Dot3CheckSum = (USHORT)(ucScrap2[0]<<8 | ucScrap2[1]);
// ================================== Check the DataLen
if (!NT_SUCCESS(Status))
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
Status = ((PPROTOCOL_READ_ROUTINE) Pdx->P12843DL.fnRead)(Pdx, Buffer, BufferSize, BytesTransferred);
if (!NT_SUCCESS(Status))
{
DD((PCE)Pdx,DDE,"ParDot3Read: Data Read Failed. We're Hosed!\n");
return(Status);
}
// LengthOfData field from the Frame header is really the number of bytes of ClientData - 1
if ( ((ULONG)Dot3DataLen + 1) > BufferSize)
{
// buffer overflow - abort operation
DD((PCE)Pdx,DDE,"ParDot3Read: Bad 1284.3DL Data Len. Buffer overflow. We're Hosed!\n");
return STATUS_BUFFER_OVERFLOW;
}
// Check Checksum
{
USHORT pid = Pdx->P12843DL.CurrentPID;
USHORT checkSum;
// 2's complement sum in 32 bit accumulator
ULONG sum = pid + Dot3DataLen + Dot3CheckSum;
// fold 32 bit sum into 16 bits
while( sum >> 16 ) {
sum = (sum & 0xffff) + (sum >> 16);
}
// take 1's complement of folded sum - this should be Zero if there were no errors
checkSum = (USHORT)(0xffff & ~sum);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -