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

📄 shuttle.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
                ucProdIdLoByteHiNibble &= 0xF0 ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) );    // bring nStrobe low
                KeStallExecutionProcessor( Delay );        // wait a bit
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                KeStallExecutionProcessor( Delay );        // wait a bit

                ucProdIdLoByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdLoByteLoNibble >>= 4 ;
                ucProdIdLoByte = ucProdIdLoByteHiNibble | ucProdIdLoByteLoNibble ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) );    // bring nStrobe low
                KeStallExecutionProcessor( Delay );        // wait a bit
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                KeStallExecutionProcessor( Delay );        // wait a bit

                ucProdIdHiByteHiNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdHiByteHiNibble &= 0xF0 ;

                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) );    // bring nStrobe low
                KeStallExecutionProcessor( Delay );        // wait a bit
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                KeStallExecutionProcessor( Delay );        // wait a bit

                ucProdIdHiByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
                ucProdIdHiByteLoNibble >>= 4 ;
                ucProdIdHiByte = ucProdIdHiByteHiNibble | ucProdIdHiByteLoNibble ;

                // last strobe
                KeStallExecutionProcessor( Delay );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) );    // bring nStrobe low
                KeStallExecutionProcessor( Delay );        // wait a bit
                P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );    // bring nStrobe high
                KeStallExecutionProcessor( Delay );        // wait a bit

                usProdId = ( ucProdIdHiByte << 8 ) | ucProdIdLoByte ;

                if ( ( SHTL_EPAT_PRODID == usProdId ) ||\
                     ( SHTL_EPST_PRODID == usProdId ) ) {
                    // one of the devices that conform to the earlier
                    // draft is found
                    bReturnValue = TRUE ;
                }

                // last byte
                P5WritePortUchar( CurrentPort, ModeQualifier[6] );

            } // Third status

        } // Second status

    } // First status

    P5WritePortUchar( CurrentControl, value );    // restore everything

    DD(NULL,DDW,"ParStlCheckIfStlProductId - returning %s\n",bReturnValue?"TRUE":"FALSE");

    return bReturnValue ;
} // end  ParStlCheckIfStlProductId()

PCHAR
ParStlQueryStlDeviceId(
    IN  PPDO_EXTENSION   Extension,
    OUT PCHAR               CallerDeviceIdBuffer,
    IN  ULONG               CallerBufferSize,
    OUT PULONG              DeviceIdSize,
    IN BOOLEAN              bReturnRawString
    )
/*++

Routine Description:

    This routine retrieves/constructs the unique device id
    string from the selected shuttle device on the chain
    and updates the caller's buffer with the same.

Arguments:

    IN  Extension               : The device extension
    OUT CallerDeviceIdBuffer    : Caller's buffer
    IN  CallerBufferSize        : Size of caller's buffer
    OUT DeviceIdSize            : Updated device id's size
    IN  bReturnRawString        : Whether to return raw
                                  string with the first two
                                  bytes or not.

Return Value:

    Pointer to the read device ID string, if successful.

    NULL otherwise.

--*/
{
    PUCHAR              Controller = Extension->Controller;
    NTSTATUS            Status;
    UCHAR               idSizeBuffer[2];
    ULONG               bytesToRead;
    ULONG               bytesRead = 0;
    USHORT              deviceIdSize;
    USHORT              deviceIdBufferSize;
    PCHAR               deviceIdBuffer;
    PCHAR               readPtr;

    DD(NULL,DDW,"ParStlQueryStlDeviceId - enter\n");

    *DeviceIdSize = 0;

    // assert idle state, to recover from undefined state,
    // just in case it gets into
    ParStlAssertIdleState ( Extension ) ;

    //
    // If we are currently connected to the peripheral via any 1284 mode
    //   other than Compatibility/Spp mode (which does not require an IEEE
    //   negotiation), we must first terminate the current mode/connection.
    // 
    // dvdf - RMT - what if we are connected in a reverse mode?
    //
    if( (Extension->Connected) && (afpForward[Extension->IdxForwardProtocol].fnDisconnect) ) {
        afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
    }

    //
    // Negotiate the peripheral into nibble device id mode.
    //
    Status = ParEnterNibbleMode(Extension, REQUEST_DEVICE_ID);
    if( !NT_SUCCESS(Status) ) {
        ParTerminateNibbleMode(Extension);
        goto targetContinue;
    }
    
    
    //
    // Read first two bytes to get the total (including the 2 size bytes) size 
    //   of the Device Id string.
    //
    bytesToRead = 2;
    Status = ParNibbleModeRead(Extension, idSizeBuffer, bytesToRead, &bytesRead);
    if( !NT_SUCCESS( Status ) || ( bytesRead != bytesToRead ) ) {
        goto targetContinue;
    }
    
    
    //
    // Compute size of DeviceId string (including the 2 byte size prefix)
    //
    deviceIdSize = (USHORT)( idSizeBuffer[0]*0x100 + idSizeBuffer[1] );
    
    {
        const USHORT minValidDevId    =   14; // 2 size bytes + "MFG:x;" + "MDL:y;"
        const USHORT maxValidDevId    = 2048; // arbitrary, but we've never seen one > 1024
        
        if( (deviceIdSize < minValidDevId) || (deviceIdSize > maxValidDevId) ) {
            //
            // The device is reporting a 1284 ID string length that is probably bogus.
            //   Ignore the device reported ID and skip to the code below that makes
            //   up a VID/PID based 1284 ID based on the specific SCM Micro chip used
            //   by the device.
            //
            goto targetContinue; 
        }
    }
    
    //
    // Allocate a buffer to hold the DeviceId string and read the DeviceId into it.
    //
    if( bReturnRawString ) {
        //
        // Caller wants the raw string including the 2 size bytes
        //
        *DeviceIdSize      = deviceIdSize;
        deviceIdBufferSize = (USHORT)(deviceIdSize + sizeof(CHAR));     // ID size + ID + terminating NULL
    } else {
        //
        // Caller does not want the 2 byte size prefix
        //
        *DeviceIdSize      = deviceIdSize - 2*sizeof(CHAR);
        deviceIdBufferSize = (USHORT)(deviceIdSize - 2*sizeof(CHAR) + sizeof(CHAR)); //           ID + terminating NULL
    }
    
    deviceIdBuffer = (PCHAR)ExAllocatePool(PagedPool, deviceIdBufferSize);
    if( !deviceIdBuffer ) {
        goto targetContinue;
    }


    //
    // NULL out the ID buffer to be safe
    //
    RtlZeroMemory( deviceIdBuffer, deviceIdBufferSize );
    
    
    //
    // Does the caller want the 2 byte size prefix?
    //
    if( bReturnRawString ) {
        //
        // Yes, caller wants the size prefix. Copy prefix to buffer to return.
        //
        *(deviceIdBuffer+0) = idSizeBuffer[0];
        *(deviceIdBuffer+1) = idSizeBuffer[1];
        readPtr = deviceIdBuffer + 2;
    } else {
        //
        // No, discard size prefix
        //
        readPtr = deviceIdBuffer;
    }
    
    
    //
    // Read remainder of DeviceId from device
    //
    bytesToRead = deviceIdSize -  2; // already have the 2 size bytes
    Status = ParNibbleModeRead(Extension, readPtr, bytesToRead, &bytesRead);
    
    
    ParTerminateNibbleMode( Extension );
    
    if( !NT_SUCCESS(Status) || (bytesRead < 1) ) {
        ExFreePool( deviceIdBuffer );
        goto targetContinue;
    }
    
    if ( strstr ( readPtr, "MFG:" ) == 0 ) {
        ExFreePool( deviceIdBuffer ) ;
        goto targetContinue;
    }
    
    deviceIdSize = (USHORT)strlen(deviceIdBuffer);
    *DeviceIdSize = deviceIdSize;
    if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
        // caller supplied buffer is large enough, use it
        RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
        RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
        ExFreePool( deviceIdBuffer );
        return CallerDeviceIdBuffer;
    } 
    return deviceIdBuffer;

 targetContinue:

// Builds later than 2080 fail to terminate in Compatibility mode.
//IEEETerminate1284Mode fails after  Event 23 (Extension->CurrentEvent equals 23)
// with earlier 1284 draft.
//So, we terminate the adapter ourselves, in some cases may be redundant.
    P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
    KeStallExecutionProcessor( 5 );
    P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT | DCR_AUTOFEED);
    KeStallExecutionProcessor( 5 );
    P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
     
    ParStlAssertIdleState ( Extension ) ;

    deviceIdBuffer = ParBuildStlDeviceId(Extension, bReturnRawString);

    if( !deviceIdBuffer ) {
        return NULL;
    }

    deviceIdSize = (USHORT)strlen(deviceIdBuffer);
    *DeviceIdSize = deviceIdSize;
    if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
        // caller supplied buffer is large enough, use it
        RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
        RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
        ExFreePool( deviceIdBuffer );
        return CallerDeviceIdBuffer;
    }
    return deviceIdBuffer;
}

PCHAR
ParBuildStlDeviceId(
    IN  PPDO_EXTENSION   Extension,
    IN  BOOLEAN          bReturnRawString
    )
/*++

Routine Description:

    This function detects the type of shuttle adapter and
    builds an appropriate device id string and returns it
    back.

    It is assumed that the device is already in the 
    selected state.

Arguments:

    Nil. 


Return Value:

    Pointer to the read/built device ID string, if successful.

    NULL otherwise.

--*/
{
    ULONG size = 0x80 ;
    PCHAR id ;
    STL_DEVICE_TYPE dtDeviceType ;
    CHAR szDeviceIdString[0x80] ;
    CHAR szVidPidString[] = "MFG:VID_04E6;CLS:SCSIADAPTER;MDL:PID_" ;
    CHAR szVidPidStringScan[] = "MFG:VID_04E6;CLS:IMAGE;MDL:PID_" ;

    RtlZeroMemory(szDeviceIdString, sizeof(szDeviceIdString));

    // identify the shuttle adapter type by calling
    // Devtype routines here and build an unique id
    // string here.
    dtDeviceType = ParStlGetDeviceType(Extension, DEVICE_TYPE_AUTO_DETECT);

    switch ( dtDeviceType ) {

        case DEVICE_TYPE_NONE :
            return NULL;

        case DEVICE_TYPE_EPP_DEVICE :
            dtDeviceType |= 0x80000000 ;
            sprintf(szDeviceIdString, "%s%08X;", szVidPidStringScan, dtDeviceType);
            break;

        default :
            dtDeviceType |= 0x80000000 ;
            sprintf(szDeviceIdString, "%s%08X;", szVidPidString, dtDeviceType);
            break;

    }

    id = ExAllocatePool(PagedPool, size);
    if( id ) {
        RtlZeroMemory( id, size );
        if( bReturnRawString ) {
            //
            // Yes, caller wants the size prefix. Copy prefix to buffer to return.
            //
            *(id+0) = 0;
            *(id+1) = 0x80-2;
            RtlCopyMemory( id+2, szDeviceIdString, size - sizeof(NULL) - 2 );
        } else {
            RtlCopyMemory( id, szDeviceIdString, size - sizeof(NULL) );
        }
        return id;
    }
    return NULL;
}

STL_DEVICE_TYPE __cdecl 
ParStlGetDeviceType (
    IN PPDO_EXTENSION    Extension,
    IN int                  nPreferredDeviceType
    )
{
    STL_DEVICE_TYPE dtDeviceType    = DEVICE_TYPE_NONE ;
    ATAPIPARAMS atapiParams ;
    int i;

    for ( i=0 ; i<ATAPI_MAX_DRIVES ; i++){
        atapiParams.dsDeviceState[i] = DEVICE_STATE_INVALID ;
    }

    do
    {
        if ( TRUE == ParStlCheckIfScsiDevice(Extension))
        {
// SCSI Device identified.
            dtDeviceType |= DEVICE_TYPE_SCSI_BIT ;
            break ;
        }

        if ( TRUE == NeedToEnableIoPads () )
        {
// in some adapters, the IO pads need to be enabled, before
// doing the device detection
            ParStlWriteReg( Extension, CONFIG_INDEX_REGISTER, EP1284_POWER_CONTROL_REG );
            ParStlWriteReg( Extension, CONFIG_DATA_REGISTER, ENABLE_IOPADS );
        }

        if ( TRUE == IsImpactSPresent() )
        {
// as impact-s has been identified, the device type identification
// can be done through personality configuration info
            dtDeviceType |= ParStlGetImpactSDeviceType( Extension, &atapiParams, nPreferredDeviceType );
            break;
        }

        if ( TRUE == IsImpactPresent() )
        {
// as impact has been identified, the device type identification
// can be done through personality configuration info
            dtDeviceType |= ParStlGetImpactDeviceType( Extension, &atapiParams, nPreferredDeviceType );
            break;
        }

        if (TRUE == ParStlCheckIfEppDevice(Extension))
        {
// epp device identified
            if ( TRUE == ParStlCheckUMAXScannerPresence(Extension) ) {
// umax identified
                dtDeviceType |= DEVICE_TYPE_UMAX_BIT;
                break;
            }
            if ( TRUE == ParStlCheckAvisionScannerPresence(Extension) ) {
// avision identified
                dtDeviceType |= DEVICE_TYPE_AVISION_BIT;
                break;
            }
// generice scanner peripheral detected
            dtDeviceType |= DEVICE_TYPE_EPP_DEVICE_BIT;
            break;
        }

        if (TRUE == ParStlCheckIfSSFDC(Extension))

⌨️ 快捷键说明

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