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

📄 uscrioctl.c

📁 usblsccid-0.9.2: ED1x Smart Card Reader Driver
💻 C
字号:
/*++

Copyright (c) 2004  QWY MicroSystem Inc.

Module Name:
    uscrioctl.c 

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

Environment:
    kernel mode only

Notes:

Revision History:
    5/21/2005: Adapted from BULKUSB DDK sample.
--*/

#include "uscr.h"
    
NTSTATUS
USCR_ProcessIOCTL(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
    	NTSTATUS status = STATUS_SUCCESS;
    	PIO_STACK_LOCATION irpStack;
    	ULONG	ioControlCode;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "Enter USCR_ProcessIOCTL, PendingIo %d.\n",deviceExtension->PendingIoCount)
		);
    	//In order to not exclusive open by smart card service. yanglq 2005-6-25
    	KeWaitForSingleObject(
                    &deviceExtension->NoPendingIoEvent,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
    	USCR_KdPrint( DBGLVL_MEDIUM, 
    		( "NoPendingIo I can access the device.\n")
    		);
    		
    	USCR_IncrementIoCount(DeviceObject);    // Can't accept a new io request if:
    	//  1) device is removed, 
    	//  2) has never been started, 
	//  3) is stopped,
	//  4) has a remove request pending,
	//  5) has a stop device pending
	if ( !USCR_CanAcceptIoRequests( DeviceObject ) ) {
		status = STATUS_DELETE_PENDING;
	        Irp->IoStatus.Status = status;
	        Irp->IoStatus.Information = 0;
	
	        IoCompleteRequest( Irp, IO_NO_INCREMENT );
	
	        USCR_DecrementIoCount(DeviceObject);                          
	        return status;
	}
	irpStack = IoGetCurrentIrpStackLocation (Irp);
	ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "SmartcardDeviceControl: %x\n",ioControlCode )
		);
#if DBG
	USCR_ShowIoctlCode(Irp);
#endif
	status = SmartcardDeviceControl(
		smartcardExtension,
		Irp
		);
		
    	USCR_DecrementIoCount(DeviceObject);                          
	return status;

}

ULONG
VendorCommand(
	IN PDEVICE_OBJECT 	DeviceObject,
        IN UCHAR 		Request,
	IN USHORT 		Value,
	IN USHORT 		Index,
	PVOID			ioBuffer,
	IN ULONG		ioBufferLength
        )
{

	NTSTATUS ntStatus;
	PURB urb;

	if (ioBufferLength>255) ioBufferLength=255;  //hardware support max 255 block size length
	
	urb = (PURB) USCR_ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
        if (urb) 
        {
	 UsbBuildVendorRequest(urb, 
		 	      URB_FUNCTION_VENDOR_ENDPOINT,
			      sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		   	      (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),  
			      0, 	 // Reserved Bits 		
			      Request,	 // Request 	
			      Value, 	 // Value 	
			      Index, 	 // Index	
			      ioBuffer,	 // Transfer Buffer
			      NULL,	 // TransferBufferMDL OPTIONAL
			      ioBufferLength,	 // Transfer Buffer Lenght	
			      NULL);	 // Link OPTIONAL
        	
	 ntStatus = USCR_CallUSBD(DeviceObject, urb);

	
	 if (NT_SUCCESS(ntStatus))
	  {
	   ULONG ans = urb->UrbControlVendorClassRequest.TransferBufferLength;
           USCR_ExFreePool(urb);
	   return(ans);
	  }
	 else
	  {
           USCR_ExFreePool(urb);
	   return(0);
	  }
        }
  	else
  	{
  		KdPrint(("Error to alocate\n"));
  		 return(0); 
  	}

}

extern int channel;
NTSTATUS
USCR_CCIDIoctl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	PIO_STACK_LOCATION 	irpStack;
	PUCHAR 			ioBuffer;
	ULONG 			inputBufferLength;
	ULONG 			outputBufferLength;
	ULONG 			length;
	NTSTATUS 		ntStatus = STATUS_INVALID_DEVICE_REQUEST;
	PDEVICE_EXTENSION 	deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION 	smartcardExtension = &deviceExtension->SmartcardExtension;
	PREADER_EXTENSION	ReaderExtension = smartcardExtension->ReaderExtension;

	USCR_KdPrint( DBGLVL_DEFAULT,("USCR_CCIDIoctl\n"));
	
	irpStack = IoGetCurrentIrpStackLocation (Irp);
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	// get pointers and lengths of the caller's (user's) IO buffer
	ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
	inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
	outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
	length = outputBufferLength;
	KdPrint(("inputBufferLength = %d , outputBufferLength = %d \n",inputBufferLength,outputBufferLength));

	if (inputBufferLength < 1)
		return	ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	
	switch(ioBuffer[0])
	{
		case PC_to_RDR_IccPowerOn:
			length = MAXIMUM_ATTR_STRING_LENGTH;
			USCR_ASSERT(outputBufferLength >= length);
			ntStatus = CmdPowerOn(
				ReaderExtension,
				&length,
				ioBuffer
				);
			Irp->IoStatus.Information = length;
            		KdPrint(("Length= %d,ioBuffer[0]=%x\n",length,ioBuffer[0]));
			break;
		case PC_to_RDR_IccPowerOff:
			ntStatus = CmdPowerOff(ReaderExtension);
			break;
		case PC_to_RDR_GetSlotStatus:
			ntStatus = CmdGetSlotStatus(
					ReaderExtension,
					ioBuffer,
					&length
					);
			Irp->IoStatus.Information = length;
			break;
		case PC_to_RDR_XfrBlock:
			KdPrint(("Length= %d\n",inputBufferLength));
			HEXDUMP(ioBuffer,inputBufferLength);
			ntStatus = CmdXfrBlockTPDU_T0(
					ReaderExtension,
					inputBufferLength-1,
					ioBuffer+1,
					&length,
					ioBuffer
					);
			Irp->IoStatus.Information = length;
            		KdPrint(("Length= %d,ioBuffer[0]=%x\n",length,ioBuffer[0]));
			break;
		case PC_to_RDR_ResetParameters:
			ntStatus = CmdResetReaderRelatedParameters(
				ReaderExtension
				);
			break;
		case PC_to_RDR_SetParameters:
			ntStatus = CmdSetReaderRelatedParameters(
				ReaderExtension,
				inputBufferLength-1,
				ioBuffer+1
				);
			break;
		case PC_to_RDR_GetParameters:
			ntStatus = CmdGetReaderRelatedParameters(
				ReaderExtension,
				&length,
				ioBuffer
				);
			Irp->IoStatus.Information = length;		
			break;
		case PC_to_RDR_RunBuiltInFunctions:
			ReaderExtension->channel = 1;
			ntStatus = CmdXfrBlockTPDU_T0(
				ReaderExtension,
				inputBufferLength-1,
				ioBuffer+1,
				&length,
				ioBuffer
				);
			Irp->IoStatus.Information = length;
			ReaderExtension->channel = 0;
			break;
		default:
			break;
	}

	return ntStatus;
}

NTSTATUS
USCRVendorIoctl(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
{
	NTSTATUS		NTStatus;
	PIRP			Irp;
	PIO_STACK_LOCATION	IrpStack;
	LONG 			EventState;
	PDEVICE_EXTENSION 	deviceExtension;

	
	SmartcardDebug( 
		DEBUG_TRACE, 
		( "USCRVendorIoctl: Enter\n" )
		);
	deviceExtension = SmartcardExtension->OsData->DeviceObject->DeviceExtension;
	//
	//	get pointer to current IRP stack location
	//
	Irp		= SmartcardExtension->OsData->CurrentIrp;
	IrpStack	= IoGetCurrentIrpStackLocation( Irp );
	//
	// assume error
	//
	NTStatus = STATUS_INVALID_DEVICE_REQUEST;
	Irp->IoStatus.Information = 0;
	//
	//	dispatch IOCTL
	//
	switch( IrpStack->Parameters.DeviceIoControl.IoControlCode )
	{
		case IOCTL_USCR_GET_CONFIG_DESCRIPTOR:
		case IOCTL_USCR_RESET_DEVICE:                                                    
		case IOCTL_USCR_RESET_PIPE:
			NTStatus = USCR_USBIoctl(
				SmartcardExtension->OsData->DeviceObject,
				Irp);
			break;
		case IOCTL_USCR_CCID:
			NTStatus = USCR_CCIDIoctl(
				SmartcardExtension->OsData->DeviceObject,
				Irp);
			break;
		//////////////////////////TEST ONLY//////////////////////////	
		case IOCTL_USCR_DecrementIoCount:
			USCR_DecrementIoCount(SmartcardExtension->OsData->DeviceObject);
			break;
		case IOCTL_USCR_IncrementIoCount:
			USCR_IncrementIoCount(SmartcardExtension->OsData->DeviceObject);
			break;
		case IOCTL_USCR_SetPendingIoEvent:
			KeSetEvent(&deviceExtension->NoPendingIoEvent,
                   		1, //Specifies the priority increment to be applied if setting the event causes a wait to be satisfied.
                   		FALSE);//Specifies whether the call to KeSetEvent is to be followed immediately by a call to a KeWaitXxx. 
			USCR_KdPrint( DBGLVL_DEFAULT,("IOCTL_USCR_SetPendingIoEvent\n"));
			EventState = KeReadStateEvent(&deviceExtension->NoPendingIoEvent);
			USCR_KdPrint( DBGLVL_DEFAULT,("ReadPendingIoEventState:%d\n",EventState));
			break;
		case IOCTL_USCR_ClearPendingIoEvent:
			KeClearEvent(&deviceExtension->NoPendingIoEvent);
			USCR_KdPrint( DBGLVL_DEFAULT,("IOCTL_USCR_ClearPendingIoEvent\n"));
			EventState = KeReadStateEvent(&deviceExtension->NoPendingIoEvent);
			USCR_KdPrint( DBGLVL_DEFAULT,("ReadPendingIoEventState:%d\n",EventState));
			break;
		case IOCTL_USCR_ReadPendingIoEventState: 
			EventState = KeReadStateEvent(&deviceExtension->NoPendingIoEvent);
			USCR_KdPrint( DBGLVL_DEFAULT,("ReadPendingIoEventState:%d\n",EventState));
			break;
		default:
			break;
	}
	//
	//	set status of the packet
	//
	Irp->IoStatus.Status = NTStatus;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "USCRVendorIoctl: Exit\n" )
		);
	
	return( NTStatus );
}

⌨️ 快捷键说明

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