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

📄 datalink.c

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

Copyright (C) Microsoft Corporation, 1993 - 1999

Module Name:

    p12843dl.c

Abstract:

    This module contains utility code used by 1284.3 Data Link.

Author:

    Robbie Harris (Hewlett-Packard) 10-September-1998

Environment:

    Kernel mode

Revision History :

--*/

#include "pch.h"

UCHAR Dot3_StartOfFrame1 = 0x55;  
UCHAR Dot3_StartOfFrame2 = 0xaa;  
UCHAR Dot3_EndOfFrame1 = 0x00; 
UCHAR Dot3_EndOfFrame2 = 0xff; 


NTSTATUS
ParDot3Connect(
    IN  PPDO_EXTENSION    Pdx
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG ParFwdSkip = 0, ParRevSkip = 0;
    ULONG ParResetChannel = (ULONG)~0, ParResetByteCount = 4, ParResetByte = 0;
    ULONG ParSkipDefault = 0;
    ULONG ParResetChannelDefault = (ULONG)~0;

    // If an MLC device hangs we can sometimes wake it up by wacking it with 
    //   4 Zeros sent to the reset channel (typically 78 or 0x4E). Make this
    //   configurable via registry setting.
    ULONG ParResetByteCountDefault = 4; // from MLC spec
    ULONG ParResetByteDefault      = 0; // from MLC spec

    BOOLEAN bConsiderEppDangerous = FALSE;

    DD((PCE)Pdx,DDT,"ParDot3Connect: enter\n");

    if (P12843DL_OFF == Pdx->P12843DL.DataLinkMode) {
        DD((PCE)Pdx,DDT,"ParDot3Connect: Neither Dot3 or MLC are supported - FAIL request\n");
        return STATUS_UNSUCCESSFUL;
    }

    if (Pdx->P12843DL.bEventActive) {
        DD((PCE)Pdx,DDT,"ParDot3Connect: Already connected - FAIL request\n");
        return STATUS_UNSUCCESSFUL;
    }

    // Let's get a Device Id so we can pull settings for this device
    ParTerminate(Pdx);

    {   // local block

        PCHAR                     buffer                    = NULL;
        ULONG                     bufferLength;
        UCHAR                     resultString[MAX_ID_SIZE];
        ANSI_STRING               AnsiIdString;
        UNICODE_STRING            UnicodeTemp;
        RTL_QUERY_REGISTRY_TABLE  paramTable[6];
        UNICODE_STRING            Dot3Key;
        USHORT                    Dot3NameSize;
        NTSTATUS                  status;

        RtlZeroMemory(resultString, MAX_ID_SIZE);
        // ask the device how large of a buffer is needed to hold it's raw device id
        if ( Pdx->Ieee1284Flags & ( 1 << Pdx->Ieee1284_3DeviceId ) ) {
            buffer = Par3QueryDeviceId(Pdx, NULL, 0, &bufferLength, FALSE, TRUE);
        } else{
            buffer = Par3QueryDeviceId(Pdx, NULL, 0, &bufferLength, FALSE, FALSE);
        }
        if( !buffer ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - Couldn't alloc pool for DevId - FAIL request\n");
            return STATUS_UNSUCCESSFUL;
        }

        DD((PCE)Pdx,DDT,"ParDot3Connect - 1284 ID string = <%s>\n",buffer);

        // extract the part of the ID that we want from the raw string 
        //   returned by the hardware
        Status = ParPnpGetId( buffer, BusQueryDeviceID, (PCHAR)resultString, NULL );
        StringSubst( (PCHAR)resultString, ' ', '_', (USHORT)strlen((const PCHAR)resultString) );

        DD((PCE)Pdx,DDT,"ParDot3Connect: resultString Post StringSubst = <%s>\n",resultString);

        // were we able to extract the info that we want from the raw ID string?
        if( !NT_SUCCESS(Status) ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - Call to ParPnpGetId Failed - FAIL request\n");
            if( buffer ) {
                ExFreePool( buffer );
            }
            return STATUS_UNSUCCESSFUL;
        }

        // Does the ID that we just retrieved from the device match the one 
        //   that we previously saved in the device extension?
        if(0 != strcmp( (const PCHAR)Pdx->DeviceIdString, (const PCHAR)resultString)) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - strcmp shows NO MATCH\n");
            // DVDF - we may want to trigger a reenumeration since we know that the device changed
        }

        // Ok, now we have what we need to look in the registry
        // and pull some prefs.
        RtlZeroMemory(&paramTable[0], sizeof(paramTable));
        paramTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[0].Name          = (PWSTR)L"ParFwdSkip";
        paramTable[0].EntryContext  = &ParFwdSkip;
        paramTable[0].DefaultType   = REG_DWORD;
        paramTable[0].DefaultData   = &ParSkipDefault;
        paramTable[0].DefaultLength = sizeof(ULONG);

        paramTable[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[1].Name          = (PWSTR)L"ParRevSkip";
        paramTable[1].EntryContext  = &ParRevSkip;
        paramTable[1].DefaultType   = REG_DWORD;
        paramTable[1].DefaultData   = &ParSkipDefault;
        paramTable[1].DefaultLength = sizeof(ULONG);

        paramTable[2].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[2].Name          = (PWSTR)L"ParRC";
        paramTable[2].EntryContext  = &ParResetChannel;
        paramTable[2].DefaultType   = REG_DWORD;
        paramTable[2].DefaultData   = &ParResetChannelDefault;
        paramTable[2].DefaultLength = sizeof(ULONG);

        paramTable[3].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[3].Name          = (PWSTR)L"ParRBC";
        paramTable[3].EntryContext  = &ParResetByteCount;
        paramTable[3].DefaultType   = REG_DWORD;
        paramTable[3].DefaultData   = &ParResetByteCountDefault;
        paramTable[3].DefaultLength = sizeof(ULONG);

        paramTable[4].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[4].Name          = (PWSTR)L"ParRBD";
        paramTable[4].EntryContext  = &ParResetByte;
        paramTable[4].DefaultType   = REG_DWORD;
        paramTable[4].DefaultData   = &ParResetByteDefault;
        paramTable[4].DefaultLength = sizeof(ULONG);

        Dot3Key.Buffer = NULL;
        Dot3Key.Length = 0;
        Dot3NameSize = sizeof(L"Dot3\\") + sizeof(UNICODE_NULL);
        Dot3Key.MaximumLength = (USHORT)( Dot3NameSize + (sizeof(resultString) * sizeof(WCHAR)) );
        Dot3Key.Buffer = ExAllocatePool(PagedPool,
                                            Dot3Key.MaximumLength);
        if( !Dot3Key.Buffer ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - ExAllocatePool for Registry Check failed - FAIL request\n");
            if( buffer ) {
                ExFreePool( buffer );
            }
            return STATUS_UNSUCCESSFUL;
        }

        DD((PCE)Pdx,DDT,"ParDot3Connect: ready to Zero buffer, &Dot3Key= %x , MaximumLength=%d\n",&Dot3Key, Dot3Key.MaximumLength);
        RtlZeroMemory(Dot3Key.Buffer, Dot3Key.MaximumLength);

        status = RtlAppendUnicodeToString(&Dot3Key, (PWSTR)L"Dot3\\");
        ASSERT( NT_SUCCESS(status) );

        DD((PCE)Pdx,DDT,"ParDot3Connect:\"UNICODE\" Dot3Key S  = <%S>\n",Dot3Key.Buffer);
        DD((PCE)Pdx,DDT,"ParDot3Connect:\"UNICODE\" Dot3Key wZ = <%wZ>\n",&Dot3Key);
        DD((PCE)Pdx,DDT,"ParDot3Connect:\"RAW\" resultString string = <%s>\n",resultString);

        RtlInitAnsiString(&AnsiIdString,(const PCHAR)resultString);

        status = RtlAnsiStringToUnicodeString(&UnicodeTemp,&AnsiIdString,TRUE);
        if( NT_SUCCESS( status ) ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect:\"UNICODE\" UnicodeTemp = <%S>\n",UnicodeTemp.Buffer);

            Dot3Key.Buffer[(Dot3NameSize / sizeof(WCHAR)) - 1] = UNICODE_NULL;
            DD((PCE)Pdx,DDT,"ParDot3Connect:\"UNICODE\" Dot3Key (preappend)  = <%S>\n",Dot3Key.Buffer);

            status = RtlAppendUnicodeStringToString(&Dot3Key, &UnicodeTemp);
            if( NT_SUCCESS( status ) ) {
                DD((PCE)Pdx,DDT,"ParDot3Connect: ready to call RtlQuery...\n");
                Status = RtlQueryRegistryValues( RTL_REGISTRY_CONTROL, Dot3Key.Buffer, &paramTable[0], NULL, NULL);
                DD((PCE)Pdx,DDT,"ParDot3Connect: RtlQueryRegistryValues Status = %x\n",Status);
            }
            
            RtlFreeUnicodeString(&UnicodeTemp);
        }

        if( Dot3Key.Buffer ) {
            ExFreePool (Dot3Key.Buffer);
        }

        // no longer needed
        ExFreePool(buffer);
        if (!NT_SUCCESS(Status)) {
            // registry read failed
            DD((PCE)Pdx,DDT,"ParDot3Connect: No Periph Defaults in Registry\n");
            DD((PCE)Pdx,DDT,"ParDot3Connect: No Periph Defaults in Registry\n");
            // registry read failed, use defaults and consider EPP to be dangerous
            ParRevSkip = ParFwdSkip = ParSkipDefault;
            bConsiderEppDangerous = TRUE; 
        }

        DD((PCE)Pdx,DDT,"ParDot3Connect: pre IeeeNegotiateBestMode\n");
        // if we don't have registry overrides then use what the
        // peripheral told us otherwise stick with defaults.
        if (ParSkipDefault == ParRevSkip) {
            ParRevSkip = Pdx->P12843DL.RevSkipMask;
        } else {
            Pdx->P12843DL.RevSkipMask = (USHORT)ParRevSkip;
        }

        if (ParSkipDefault == ParFwdSkip) {
            ParFwdSkip = Pdx->P12843DL.FwdSkipMask;
        } else {
            Pdx->P12843DL.FwdSkipMask = (USHORT)ParFwdSkip;
        }

        if( bConsiderEppDangerous ) {
            ParFwdSkip |= EPP_ANY;
            ParRevSkip |= EPP_ANY;
        }

        Status = IeeeNegotiateBestMode(Pdx, (USHORT)ParRevSkip, (USHORT)ParFwdSkip);
        if( !NT_SUCCESS(Status) ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - Peripheral Negotiation Failed - FAIL dataLink connect\n");
            return Status;
        }

        Pdx->ForwardInterfaceAddress = Pdx->P12843DL.DataChannel;
        if (Pdx->P12843DL.DataLinkMode == P12843DL_MLC_DL) {
            if (ParResetChannel != ParResetChannelDefault) {
                Pdx->P12843DL.ResetByte  = (UCHAR) ParResetByte & 0xff;
                Pdx->P12843DL.ResetByteCount = (UCHAR) ParResetByteCount & 0xff;
                if (ParResetChannel == PAR_COMPATIBILITY_RESET) {
                    Pdx->P12843DL.fnReset = ParMLCCompatReset;
                } else {
                    // Max ECP channel is 127 so let's mask off bogus bits.
                    Pdx->P12843DL.ResetChannel = (UCHAR) ParResetChannel & 0x7f;
                    Pdx->P12843DL.fnReset = ParMLCECPReset;
                }
            }
        }

        if (Pdx->P12843DL.fnReset) {
            DD((PCE)Pdx,DDT,"ParDot3Connect: MLCReset is supported on %x\n",Pdx->P12843DL.ResetChannel);
            Status = ((PDOT3_RESET_ROUTINE) (Pdx->P12843DL.fnReset))(Pdx);
        } else {
            DD((PCE)Pdx,DDT,"ParDot3Connect - MLCReset is not supported\n");
            Status = ParSetFwdAddress(Pdx);
        }
        if( !NT_SUCCESS(Status) ) {
            DD((PCE)Pdx,DDT,"ParDot3Connect - Couldn't Set Address - FAIL request\n");
            return Status;
        }

        // Check to make sure we are ECP, BECP, or EPP
        DD((PCE)Pdx,DDT,"ParDot3Connect: pre check of ECP, BECP, EPP\n");

        if (afpForward[Pdx->IdxForwardProtocol].ProtocolFamily != FAMILY_BECP &&
            afpForward[Pdx->IdxForwardProtocol].ProtocolFamily != FAMILY_ECP &&
            afpForward[Pdx->IdxForwardProtocol].ProtocolFamily != FAMILY_EPP) {

            DD((PCE)Pdx,DDT,"ParDot3Connect - We did not reach ECP or EPP - FAIL request\n");
            return STATUS_UNSUCCESSFUL;
        }

    } // end local block

    if (Pdx->P12843DL.DataLinkMode == P12843DL_DOT3_DL) {
        DD((PCE)Pdx,DDT,"ParDot3Connect - P12843DL_DOT3_DL\n");
        Pdx->P12843DL.fnRead  = arpReverse[Pdx->IdxReverseProtocol].fnRead;
        Pdx->P12843DL.fnWrite = afpForward[Pdx->IdxForwardProtocol].fnWrite;
        Pdx->fnRead           = ParDot3Read;
        Pdx->fnWrite          = ParDot3Write;
    }

    DD((PCE)Pdx,DDT,"ParDot3Connect - Exit with status %x\n",Status);

    return Status;
}

VOID
ParDot3CreateObject(
    IN  PPDO_EXTENSION   Pdx,
    IN PCHAR DOT3DL,
    IN PCHAR DOT3C
    )
{
    Pdx->P12843DL.DataLinkMode = P12843DL_OFF;
    Pdx->P12843DL.fnReset = NULL;
    DD((PCE)Pdx,DDT,"ParDot3CreateObject - DOT3DL [%s] DOT3C\n",DOT3DL, DOT3C);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -