⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datalink.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -