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

📄 pscrcb.c

📁 pcmcia智能卡的驱动程序例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1997 - 1999 SCM Microsystems, Inc.

Module Name:

    PscrCB.c

Abstract:

	callback handler for PSCR.xxx driver

Author:

	Andreas Straub

Environment:

	Win 95		Sys... calls are resolved by Pscr95Wrap.asm functions and
				Pscr95Wrap.h macros, resp.

	NT	4.0		Sys... functions resolved by PscrNTWrap.c functions and
				PscrNTWrap.h macros, resp.

Revision History:

	Andreas Straub			8/18/1997	1.00	Initial Version
	Andreas Straub			9/24/1997	1.02	Flush Interface if card tracking
												requested

--*/

#if defined( SMCLIB_VXD )

#include <Pscr95.h>

#else	//	SMCLIB_VXD

#include <PscrNT.h>

#endif	//	SMCLIB_VXD


#include <PscrRdWr.h>
#include <PscrCmd.h>
#include <PscrCB.h>


NTSTATUS
CBCardPower( 
	PSMARTCARD_EXTENSION SmartcardExtension 
	)
/*++

CBCardPower:
	callback handler for SMCLIB RDF_CARD_POWER

Arguments:
	SmartcardExtension	context of call

Return Value:
	STATUS_SUCCESS
	STATUS_NO_MEDIA
	STATUS_TIMEOUT
	STATUS_BUFFER_TOO_SMALL

--*/
{
	NTSTATUS			NTStatus = STATUS_SUCCESS;
	UCHAR				ATRBuffer[ ATR_SIZE ], TLVList[16];
	ULONG				Command,
						ATRLength;
	PREADER_EXTENSION	ReaderExtension;
    BYTE                CardState;
#if DBG || DEBUG
    static PCHAR request[] = { "PowerDown",  "ColdReset", "WarmReset" };
#endif

	SmartcardDebug( 
		DEBUG_TRACE,
		( "PSCR!CBCardPower: Enter, Request = %s\n",
        request[SmartcardExtension->MinorIoControlCode])
		);

	ReaderExtension = SmartcardExtension->ReaderExtension;

	//
	//	update actual power state
	//
	Command = SmartcardExtension->MinorIoControlCode;

	switch ( Command )
	{
		case SCARD_WARM_RESET:

			//	if the card was not powerd, fall thru to cold reset
			if( SmartcardExtension->ReaderCapabilities.CurrentState >
				SCARD_SWALLOWED )
			{
				//	reset the card
				ATRLength = ATR_SIZE;
				NTStatus = CmdReset(
					ReaderExtension,
					ReaderExtension->Device,
					TRUE,				// warm reset
					ATRBuffer,
					&ATRLength
					);

				break;
			}

			//	warm reset not possible because card was not powerd
		case SCARD_COLD_RESET:

			//	reset the card
			ATRLength = ATR_SIZE;
			NTStatus = CmdReset(
				ReaderExtension,
				ReaderExtension->Device,
				FALSE,				// cold reset
				ATRBuffer,
				&ATRLength
				);
			break;

		case SCARD_POWER_DOWN:
			ATRLength = 0;
			NTStatus = CmdDeactivate(	
				ReaderExtension,
				ReaderExtension->Device
				);

			//	discard old card status
            CardState = CBGetCardState(SmartcardExtension);
            CBUpdateCardState(SmartcardExtension, CardState, FALSE);
			break;
	}

    if (NTStatus == STATUS_SUCCESS) {
     	
        //
        // Set the 'restart of work waiting time' counter for T=0
        // This will send a WTX request for n NULL bytes received
        //
        TLVList[0] = TAG_SET_NULL_BYTES;
        TLVList[1] = 1;
        TLVList[2] = 0x05; 

        NTStatus = CmdSetInterfaceParameter(
	        ReaderExtension,
	        DEVICE_READER,
	        TLVList,
	        3
	        );
    }

    ASSERT(NTStatus == STATUS_SUCCESS);

	//	finish the request
	if( NT_SUCCESS( NTStatus ))
	{
		//	update all neccessary data if an ATR was received
		if( ATRLength > 2 )
		{
			//
			//	the lib expects only the ATR, so we skip the 
			//	900x from the reader
			//
			ATRLength -= 2;

			//	copy ATR to user buffer buffer
			if( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength )
			{
				SysCopyMemory(
					SmartcardExtension->IoRequest.ReplyBuffer,
					ATRBuffer,
					ATRLength
					);
				*SmartcardExtension->IoRequest.Information = ATRLength;
			}
			else
			{
				NTStatus = STATUS_BUFFER_TOO_SMALL;
			}

			//	copy ATR to card capability buffer
			if( ATRLength <= MAXIMUM_ATR_LENGTH )
			{
				SysCopyMemory(
					SmartcardExtension->CardCapabilities.ATR.Buffer,
					ATRBuffer,
					ATRLength
					);

				SmartcardExtension->CardCapabilities.ATR.Length = 
					( UCHAR )ATRLength;

				//	let the lib update the card capabilities
				NTStatus = SmartcardUpdateCardCapabilities(
					SmartcardExtension 
					);
			}
			else
			{
				NTStatus = STATUS_BUFFER_TOO_SMALL;
			}
		}
	}

	if( !NT_SUCCESS( NTStatus ))
	{
		switch( NTStatus )
		{
			case STATUS_NO_MEDIA:
			case STATUS_BUFFER_TOO_SMALL:
				break;

			case STATUS_TIMEOUT:
                NTStatus = STATUS_IO_TIMEOUT;
                break;

			default:
				NTStatus = STATUS_UNRECOGNIZED_MEDIA;
                break;
		}
	}

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "PSCR!CBCardPower: Exit (%lx)\n", NTStatus )
		);
	
	return( NTStatus );
}

NTSTATUS
CBSetProtocol( 
	PSMARTCARD_EXTENSION SmartcardExtension 
	)

/*++

CBSetProtocol:
	callback handler for SMCLIB RDF_SET_PROTOCOL

Arguments:
	SmartcardExtension	context of call

Return Value:
	STATUS_SUCCESS
	STATUS_NO_MEDIA
	STATUS_TIMEOUT
	STATUS_BUFFER_TOO_SMALL
	STATUS_INVALID_DEVICE_STATE
	STATUS_INVALID_DEVICE_REQUEST

--*/
{
	NTSTATUS NTStatus = STATUS_PENDING;
	USHORT SCLibProtocol;
	UCHAR TLVList[ TLV_BUFFER_SIZE ];
	PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;

    if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {

        return STATUS_SUCCESS;
    }

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "PSCR!CBSetProtocol: Enter\n" )
		);

	SCLibProtocol = ( USHORT )( SmartcardExtension->MinorIoControlCode );

    if (SCLibProtocol & (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1))
    {
		//
		//	setup the TLV list for the Set Interface Parameter List
		//
		TLVList[ 0 ] = TAG_ICC_PROTOCOLS;
		TLVList[ 1 ] = 0x01;
		TLVList[ 2 ] = 
            (SCLibProtocol & SCARD_PROTOCOL_T1 ? PSCR_PROTOCOL_T1 : PSCR_PROTOCOL_T0);

		//	do the PTS
		NTStatus = CmdSetInterfaceParameter(
			ReaderExtension,
			ReaderExtension->Device,
			TLVList,
			3			// size of list
			);		

    } else {

		//	we don't support other modi
		NTStatus = STATUS_INVALID_DEVICE_REQUEST;
	}

	//	if protocol selection failed, prevent from calling invalid protocols
	if( NT_SUCCESS( NTStatus ))
	{
		SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
		SCLibProtocol = (SCLibProtocol & SCARD_PROTOCOL_T1 &
                         SmartcardExtension->CardCapabilities.Protocol.Supported) ?
						 SCARD_PROTOCOL_T1 :
						 SCARD_PROTOCOL_T0;
	}
	else
	{
		SCLibProtocol = SCARD_PROTOCOL_UNDEFINED;
	}

	//	Return the selected protocol to the caller.
	SmartcardExtension->CardCapabilities.Protocol.Selected = SCLibProtocol;
	*( PULONG )( SmartcardExtension->IoRequest.ReplyBuffer ) = SCLibProtocol;
	*( SmartcardExtension->IoRequest.Information ) = sizeof( ULONG );
	
	SmartcardDebug( 
		DEBUG_TRACE,
		( "PSCR!CBSetProtocol: Exit (%lx)\n", NTStatus )
		);

	return ( NTStatus );
}

NTSTATUS
CBTransmit( 
	PSMARTCARD_EXTENSION SmartcardExtension 
	)
/*++

CBTransmit:
	callback handler for SMCLIB RDF_TRANSMIT

Arguments:
	SmartcardExtension	context of call

Return Value:
	STATUS_SUCCESS
	STATUS_NO_MEDIA
	STATUS_TIMEOUT
	STATUS_INVALID_DEVICE_REQUEST

--*/
{
	NTSTATUS  NTStatus = STATUS_SUCCESS;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "PSCR!CBTransmit: Enter\n" )
		);

	//	dispatch on the selected protocol
	switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
	{
		case SCARD_PROTOCOL_T0:
			NTStatus = CBT0Transmit( SmartcardExtension );
			break;

		case SCARD_PROTOCOL_T1:
			NTStatus = CBT1Transmit( SmartcardExtension );
			break;

		case SCARD_PROTOCOL_RAW:
			NTStatus = CBRawTransmit( SmartcardExtension );
			break;

		default:
			NTStatus = STATUS_INVALID_DEVICE_REQUEST;
			break;
	}

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "PSCR!CBTransmit: Exit (%lx)\n", NTStatus )
		);

	return( NTStatus );
}

NTSTATUS
CBRawTransmit(
	PSMARTCARD_EXTENSION SmartcardExtension 
	)
/*++

CBRawTransmit:
	finishes the callback RDF_TRANSMIT for the RAW protocol

Arguments:
	SmartcardExtension	context of call

Return Value:
	STATUS_SUCCESS
	STATUS_NO_MEDIA
	STATUS_TIMEOUT
	STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS			NTStatus = STATUS_SUCCESS;
	UCHAR				TLVList[ TLV_BUFFER_SIZE ],
						Val,
						Len;
	ULONG				TLVListLen;
	PREADER_EXTENSION	ReaderExtension;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "PSCR!CBRawTransmit: Enter\n" )
		);

	ReaderExtension	= SmartcardExtension->ReaderExtension;
	//
	//	read the status file of ICC1 from the reader
	//
	TLVListLen = TLV_BUFFER_SIZE;
	NTStatus = CmdReadStatusFile(
		ReaderExtension,
		ReaderExtension->Device,
		TLVList,
		&TLVListLen
		);

	//
	//	check the active protocol of the reader
	//
	if( NT_SUCCESS( NTStatus ))
	{
		NTStatus = CmdGetTagValue(
			TAG_ICC_PROTOCOLS,
			TLVList,
			TLVListLen,
			&Len,
			( PVOID ) &Val
			);

		//	execute the active protocol
		if( NT_SUCCESS( NTStatus ))
		{

			//	translate the actual protocol to a value the lib can understand
			switch( Val )
			{
				case PSCR_PROTOCOL_T0:
					NTStatus = CBT0Transmit( SmartcardExtension );
					break;
				case PSCR_PROTOCOL_T1:
					NTStatus = CBT1Transmit( SmartcardExtension );
					break;
				default:
					NTStatus = STATUS_UNSUCCESSFUL;
					break;

⌨️ 快捷键说明

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