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

📄 datalink.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:

        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 + -