📄 datalink.c
字号:
if( checkSum != 0 ) {
DD((PCE)Pdx,DDE,"ParDot3Read: Bad 1284.3DL Checksum. We're Hosed!\n");
return STATUS_DEVICE_PROTOCOL_ERROR;
}
}
// ================================== Read the first byte of EOF
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 EOF
if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_EndOfFrame1)
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
// ================================== Read the second byte of EOF
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 EOF
if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_EndOfFrame2)
{
DD((PCE)Pdx,DDE,"ParDot3Read: Header Read Failed. We're Hosed!\n");
*BytesTransferred = 0;
return(Status);
}
return Status;
}
NTSTATUS
ParDot3Write(
IN PPDO_EXTENSION Pdx,
IN PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG BytesTransferred
)
{
NTSTATUS Status;
ULONG frameBytesTransferred;
ULONG bytesToWrite;
USHORT scrap1;
USHORT scrap2;
USHORT scrapHigh;
USHORT scrapLow;
PUCHAR p;
// valid range for data payload per Frame is 1..64K
if( (BufferSize < 1) || (BufferSize > 64*1024) ) {
return STATUS_INVALID_PARAMETER;
};
// ========================= Write out first Byte of SOF
bytesToWrite = 1;
frameBytesTransferred = 0;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &Dot3_StartOfFrame1, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check first Byte of SOF
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
// ========================= Write out second Byte of SOF
bytesToWrite = 1;
frameBytesTransferred = 0;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &Dot3_StartOfFrame2, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check second Byte of SOF
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
// ========================= Write out PID (which should be in Big Endian already)
bytesToWrite = 2;
frameBytesTransferred = 0;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &Pdx->P12843DL.CurrentPID, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check PID
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
// ========================= Write out Length of Data
bytesToWrite = 2;
frameBytesTransferred = 0;
scrap1 = (USHORT) (BufferSize - 1);
scrapLow = (UCHAR) (scrap1 & 0xff);
scrapHigh = (UCHAR) (scrap1 >> 8);
p = (PUCHAR)&scrap2;
*p++ = (UCHAR)scrapHigh;
*p = (UCHAR)scrapLow;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &scrap2, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check Length of Data
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
// ========================= Write out Checksum
bytesToWrite = 2;
frameBytesTransferred = 0;
{
USHORT pid = Pdx->P12843DL.CurrentPID;
USHORT dataLengthMinusOne = (USHORT)(BufferSize - 1);
USHORT checkSum;
// 2's complement sum in 32 bit accumulator
ULONG sum = pid + dataLengthMinusOne;
// fold 32 bit sum into 16 bits
while( sum >> 16 ) {
sum = (sum & 0xffff) + (sum >> 16);
}
// final checksum is 1's complement of folded sum
checkSum = (USHORT)(0xffff & ~sum);
scrap1 = checkSum;
}
// send checksum big-endian
scrapLow = (UCHAR)(scrap1 & 0xff);
scrapHigh = (UCHAR)(scrap1 >> 8);
p = (PUCHAR)&scrap2;
*p++ = (UCHAR)scrapHigh;
*p = (UCHAR)scrapLow;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &scrap2, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check Checksum
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, Buffer, BufferSize, BytesTransferred);
if (NT_SUCCESS(Status))
{
// ========================= Write out first Byte of EOF
bytesToWrite = 1;
frameBytesTransferred = 0;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &Dot3_EndOfFrame1, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check first Byte of EOF
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
// ========================= Write out second Byte of EOF
bytesToWrite = 1;
frameBytesTransferred = 0;
do
{
Status = ((PPROTOCOL_WRITE_ROUTINE) Pdx->P12843DL.fnWrite)(Pdx, &Dot3_EndOfFrame2, bytesToWrite, &frameBytesTransferred);
}
while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
// ========================= Check second Byte of EOF
if (!NT_SUCCESS(Status))
{
*BytesTransferred = 0;
return(Status);
}
}
return Status;
}
NTSTATUS
ParMLCCompatReset(
IN PPDO_EXTENSION Pdx
)
{
NTSTATUS Status = STATUS_SUCCESS;
UCHAR Reset[256]; // Reset should not require more than 256 chars
const ULONG ResetLen = Pdx->P12843DL.ResetByteCount;
ULONG BytesWritten;
DD((PCE)Pdx,DDT,"ParMLCCompatReset: Start\n");
if (Pdx->P12843DL.DataLinkMode != P12843DL_MLC_DL &&
Pdx->P12843DL.DataLinkMode != P12843DL_DOT4_DL)
{
DD((PCE)Pdx,DDT,"ParMLCCompatReset: not MLC.\n");
return STATUS_SUCCESS;
}
ParTerminate(Pdx);
// Sending NULLs for reset
DD((PCE)Pdx,DDT,"ParMLCCompatReset: Zeroing Reset Bytes.\n");
RtlFillMemory(Reset, ResetLen, Pdx->P12843DL.ResetByte);
DD((PCE)Pdx,DDT,"ParMLCCompatReset: Sending Reset Bytes.\n");
// Don't use the Dot3Write since we are in MLC Mode.
Status = SppWrite(Pdx, Reset, ResetLen, &BytesWritten);
if (!NT_SUCCESS(Status) || BytesWritten != ResetLen)
{
DD((PCE)Pdx,DDE,"ParMLCCompatReset: FAIL. Write Failed\n");
return Status;
}
DD((PCE)Pdx,DDT,"ParMLCCompatReset: Reset Bytes were sent.\n");
return Status;
}
NTSTATUS
ParMLCECPReset(
IN PPDO_EXTENSION Pdx
)
{
NTSTATUS Status = STATUS_SUCCESS;
UCHAR Reset[256]; // Reset should not require more than 256 chars
const ULONG ResetLen = Pdx->P12843DL.ResetByteCount;
ULONG BytesWritten;
DD((PCE)Pdx,DDT,"ParMLCECPReset: Start\n");
if (Pdx->P12843DL.DataLinkMode != P12843DL_MLC_DL &&
Pdx->P12843DL.DataLinkMode != P12843DL_DOT4_DL)
{
DD((PCE)Pdx,DDT,"ParMLCECPReset: not MLC.\n");
return STATUS_SUCCESS;
}
Status = ParReverseToForward(Pdx);
Pdx->ForwardInterfaceAddress = Pdx->P12843DL.ResetChannel;
Status = ParSetFwdAddress(Pdx);
if (!NT_SUCCESS(Status)) {
DD((PCE)Pdx,DDE,"ParMLCECPReset: FAIL. Couldn't Set Reset Channel\n");
return Status;
}
// Sending NULLs for reset
DD((PCE)Pdx,DDT,"ParMLCECPReset: Zeroing Reset Bytes.\n");
RtlFillMemory(Reset, ResetLen, Pdx->P12843DL.ResetByte);
DD((PCE)Pdx,DDT,"ParMLCECPReset: Sending Reset Bytes.\n");
// Don't use the Dot3Write since we are in MLC Mode.
Status = afpForward[Pdx->IdxForwardProtocol].fnWrite(Pdx, Reset, ResetLen, &BytesWritten);
if (!NT_SUCCESS(Status) || BytesWritten != ResetLen) {
DD((PCE)Pdx,DDE,"ParMLCECPReset: FAIL. Write Failed\n");
return Status;
}
DD((PCE)Pdx,DDT,"ParMLCECPReset: Reset Bytes were sent.\n");
Pdx->ForwardInterfaceAddress = Pdx->P12843DL.DataChannel;
Status = ParSetFwdAddress(Pdx);
if (!NT_SUCCESS(Status)) {
DD((PCE)Pdx,DDE,"ParMLCECPReset: FAIL. Couldn't Set Data Channel\n");
return Status;
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -