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

📄 uscr.c

📁 usblsccid-0.9.2: ED1x Smart Card Reader Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2004  QWY MicroSystem Inc.

Module Name:
    uscr.c 

Abstract:
    USB SmartCard Reader driver for CCID/lsCCID compatible device.

Environment:
    kernel mode only

Notes:
	
Reference:
	doc:
	USB Chip/Smart Card Interface Devices
	Low Speed USB Chip/Smart Card Interface Devices
		
	code:
	NTDDK\src\smartcrd
	NTDDK\src\wdm\usb
Tools:
	ddk
	debugview
	softice
	sniffusb-0.13

Revision History:
    4/19/2005: Adapted from the bulltlp3 DDK sample.
--*/
#include "uscr.h"

NTSTATUS
USCRPower(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
{
	NTSTATUS		status = STATUS_SUCCESS;
	ULONG			Command;
	PREADER_EXTENSION	ReaderExtension = SmartcardExtension->ReaderExtension;
	PUCHAR 			replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
	PULONG 			replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
	#if DBG || DEBUG
    	static PCHAR request[] = { "PowerDown",  "ColdReset", "WarmReset" };
	#endif

	SmartcardDebug( 
		DEBUG_TRACE,
		( "USCRPower: Enter, Request = %s\n",
        	request[SmartcardExtension->MinorIoControlCode])
		);
		
	Command = SmartcardExtension->MinorIoControlCode;
	switch ( Command )
	{
		case SCARD_WARM_RESET:
		case SCARD_COLD_RESET:
			*replyLength = MAXIMUM_ATTR_STRING_LENGTH;
			status = CmdPowerOn(ReaderExtension,
				replyLength,
				replyBuffer
				);
			HEXDUMP(replyBuffer,*replyLength);
			if(status == STATUS_SUCCESS)
			{
				SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)*replyLength;
				RtlCopyMemory(
					SmartcardExtension->CardCapabilities.ATR.Buffer,
					replyBuffer,
					*replyLength
					);
				SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_OPTIMAL;
				status = SmartcardUpdateCardCapabilities(SmartcardExtension);
				USCR_DumpCardCapabilities(SmartcardExtension);	
			}
			if(status == STATUS_SUCCESS)
			{
				/*
				RtlCopyMemory(
					SmartcardExtension->IoRequest.ReplyBuffer,
					replyBuffer,
					*replyLength
					);
				*/
				//In case of InversConvention,the CardCapabilities.ATR.Buffer is the result. 2005-7-23 yanglq
				RtlCopyMemory(
					SmartcardExtension->IoRequest.ReplyBuffer,
					SmartcardExtension->CardCapabilities.ATR.Buffer,
					SmartcardExtension->CardCapabilities.ATR.Length
					);
				
				*SmartcardExtension->IoRequest.Information = *replyLength;
				if(SmartcardExtension->ReaderCapabilities.CurrentState < SCARD_POWERED)
					SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_POWERED;
			}
			break;
		case SCARD_POWER_DOWN:
			status = CmdPowerOff(
				ReaderExtension
				);
			if (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_PRESENT)
			{
				SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
			}
			break;
	}
	SmartcardDebug( 
		DEBUG_TRACE,
		( "USCRPower: Leave, status = %x\n",
        	status)
		);
	
	return status;	
}	    
NTSTATUS
USCRSetProtocol(
   	PSMARTCARD_EXTENSION SmartcardExtension
    )
{
	NTSTATUS 		status = STATUS_SUCCESS;
	USHORT 			newProtocol;
	PREADER_EXTENSION 	ReaderExtension = SmartcardExtension->ReaderExtension;
	
	SmartcardDebug( 
		DEBUG_TRACE,
		("USCRSetProtocol: Enter\n")
		);
	//only support T0 now.(ylq)
	newProtocol = ( USHORT )( SmartcardExtension->MinorIoControlCode );

    	if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
		    (SmartcardExtension->CardCapabilities.Protocol.Selected & newProtocol)) {
    		SmartcardDebug( 
			DEBUG_TRACE,
			("USCRSetProtocol: SCARD_SPECIFIC\n")
			);
        	return STATUS_SUCCESS;
    	}
	SmartcardDebug( 
			DEBUG_TRACE,
			("newProtocol:%x\n",newProtocol)
			);
    	if (newProtocol & (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1))
    	{
#if 0
		//	do the PTS
		PUCHAR ptsRequest = SmartcardExtension->SmartcardRequest.Buffer;
		PUCHAR ptsReply = SmartcardExtension->SmartcardReply.Buffer;
		PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
		PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
	
		while(TRUE) {
			// set initial character of PTS
		    	ptsRequest[0] = 0xff;
		 	if(newProtocol & SCARD_PROTOCOL_T1)   	
		 		ptsRequest[1] = 0x11;
		 	else if(newProtocol & SCARD_PROTOCOL_T0)
		 		ptsRequest[1] = 0x10;
		 	 // set pts1 which codes Fl and Dl
			ptsRequest[2] = 
				SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
				SmartcardExtension->CardCapabilities.PtsData.Dl;
	
	    		// set pck (check character)
			ptsRequest[3] = ptsRequest[0] ^ ptsRequest[1] ^ ptsRequest[2];   
	    		*requestLength = 4;
	    		*replyLength = 4;
	    		status = CmdXfrBlockTPDU_T0(
					ReaderExtension,
					*requestLength,
					ptsRequest,
					replyLength,
					ptsReply
					);
			if (status != STATUS_SUCCESS) {
				break;
			}
			if (NT_SUCCESS(status) && 
				memcmp(ptsRequest, ptsReply, 4) == 0) {
				// the card replied correctly to our pts-request
				// Set Reader CLK Data Rate parameters
				break;
			}
			if (SmartcardExtension->CardCapabilities.PtsData.Type != PTS_TYPE_DEFAULT) {
	    			SmartcardDebug(
	            		DEBUG_TRACE,
	            		("USCRSetProtocol: PTS failed. Trying default parameters...\n")
	            		);
	            		//
				// The card did either NOT reply or it replied incorrectly
				// so try default values
				//
				//SmartcardExtension->CardCapabilities.PtsData.Type = 
	   			//	PTS_TYPE_DEFAULT;
	
				//SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
	
				//status = USCRPower(SmartcardExtension);
				continue;
	            	}
	
			// the card failed the pts-request
			status = STATUS_DEVICE_PROTOCOL_ERROR;
			break;
		}//TRUE
#endif
    	}else{

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

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

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

	return ( status );
}

NTSTATUS
USCRTransmitT0(
	PSMARTCARD_EXTENSION SmartcardExtension
	)
{
	PUCHAR		requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
	PULONG 		requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
	PUCHAR 		replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
	PULONG 		replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
	NTSTATUS	status = STATUS_SUCCESS;
	ULONG		bytesToRead;
	PREADER_EXTENSION	ReaderExtension = SmartcardExtension->ReaderExtension;

    	SmartcardDebug(
        	DEBUG_TRACE,
        	("USCRTransmitT0: Enter\n")
        	);
        	
        status = SmartcardT0Request(SmartcardExtension);
        ASSERT(status == STATUS_SUCCESS);
        SmartcardDebug(
        	DEBUG_TRACE,
        	("requestLength = %d\n",*requestLength)
        	);
        HEXDUMP(requestBuffer,*requestLength);
        
        bytesToRead = SmartcardExtension->T0.Le;
        *replyLength = bytesToRead+2;
	status = CmdXfrBlockTPDU_T0(
			ReaderExtension,
			*requestLength,
			requestBuffer,
			replyLength,
			replyBuffer
			);
	SmartcardDebug(
        	DEBUG_TRACE,
        	("bytesToRead = %d,replyLength = %d\n",bytesToRead,*replyLength)
        	);
        HEXDUMP(replyBuffer,*replyLength);
	if (status == STATUS_SUCCESS) {
		status = SmartcardT0Reply(SmartcardExtension);
	}else
	        *replyLength = 0;

    	SmartcardDebug(
        	(status == STATUS_SUCCESS ? DEBUG_TRACE : DEBUG_ERROR),
        	("USCRTransmitT0: Exit(%lx)\n",
        	status)
       	 	);

	return status;
}	

NTSTATUS
USCRTransmit(
	PSMARTCARD_EXTENSION SmartcardExtension
	)
{
	NTSTATUS	NTStatus = STATUS_SUCCESS;
	
	SmartcardDebug( 
		DEBUG_TRACE,
		("USCRTransmit: Enter\n")
		);
	//	dispatch on the selected protocol
	//	only support T0 now.(ylq)
	switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
	{
		case SCARD_PROTOCOL_T0:
			NTStatus = USCRTransmitT0( SmartcardExtension );
			break;

		case SCARD_PROTOCOL_T1:
			NTStatus = STATUS_INVALID_DEVICE_REQUEST;
			break;

		case SCARD_PROTOCOL_RAW:
			NTStatus = STATUS_INVALID_DEVICE_REQUEST;
			break;

		default:
			NTStatus = STATUS_INVALID_DEVICE_REQUEST;
			break;
	}

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "USCRTransmit: Exit (%lx)\n", NTStatus )
		);

	return( NTStatus );
}

void
USCRCompleteCardTracking(
	IN PSMARTCARD_EXTENSION SmartcardExtension
	)
{
    	KIRQL	ioIrql, keIrql;
    	PIRP	notificationIrp;

	SmartcardDebug( 
		DEBUG_TRACE,
		( "USCRCompleteCardTracking: Enter.\n" )
		);
    	IoAcquireCancelSpinLock(&ioIrql);
    	KeAcquireSpinLock(
        	&SmartcardExtension->OsData->SpinLock, 
        	&keIrql
        	);

    	notificationIrp = SmartcardExtension->OsData->NotificationIrp;
    	SmartcardExtension->OsData->NotificationIrp = NULL;

    	KeReleaseSpinLock(
        	&SmartcardExtension->OsData->SpinLock,
        	keIrql
        	);

    	if (notificationIrp) {
        	IoSetCancelRoutine(
            		notificationIrp, 
            		NULL
            	);
    	}

    	IoReleaseCancelSpinLock(ioIrql);

    	if (notificationIrp) {
		SmartcardDebug(
			DEBUG_INFO,
			("USCRCompleteCardTracking: Completing NotificationIrp %lxh\n",
            		notificationIrp)
			);

	    	//	finish the request
        	if (notificationIrp->Cancel) {
	        	notificationIrp->IoStatus.Status = STATUS_CANCELLED;
        	} else {
         		notificationIrp->IoStatus.Status = STATUS_SUCCESS;
        	}
	    	notificationIrp->IoStatus.Information = 0;
		IoCompleteRequest(
            		notificationIrp, 
            		IO_NO_INCREMENT 
            	);
    	}
    	SmartcardDebug( 
		DEBUG_TRACE,
		( "USCRCompleteCardTracking: Exit.\n" )
		);
}

static VOID
CardStatusWorkItemRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Context
    )
{
	PDEVICE_EXTENSION 	deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION 	smartcardExtension = &deviceExtension->SmartcardExtension;
	PREADER_EXTENSION	readerExtension = smartcardExtension->ReaderExtension;	
	UCHAR			CardStatus;
	ULONG			len = 1;	
	ULONG    		OldState = smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
	NTSTATUS		status;
	SmartcardDebug( 
			DEBUG_TRACE,
			( "---------------CardStatusWorkItemRoutine----------------\n" )

⌨️ 快捷键说明

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