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

📄 uscr.c

📁 usblsccid-0.9.2: ED1x Smart Card Reader Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
			);
		//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 ) ) {
	        USCR_DecrementIoCount(DeviceObject);                          
	        return;
	}
	status = CmdGetSlotStatus(
			readerExtension,
			&CardStatus,//ICC_PRESENT 0x1 ICC_ABSENT 0x2 
			&len
			);
	if(status == STATUS_SUCCESS)
	{
		if(smartcardExtension->ReaderCapabilities.CurrentState == SCARD_UNKNOWN)
		{
			smartcardExtension->ReaderCapabilities.CurrentState = (CardStatus == ICC_PRESENT) ? SCARD_PRESENT : SCARD_ABSENT;
			USCRCompleteCardTracking(smartcardExtension);
		}else if((OldState == CardStatus) || (CardStatus == ICC_ABSENT && OldState == 0) )
		{
			//do nothing
		}else{
			smartcardExtension->ReaderCapabilities.CurrentState = (CardStatus == ICC_PRESENT) ? SCARD_PRESENT : SCARD_ABSENT;
			USCRCompleteCardTracking(smartcardExtension);  	
		}	
	}
    	USCR_DecrementIoCount(DeviceObject);    
   	if(readerExtension->CardStatusPollingWorker)
   	{
  	 	IoFreeWorkItem(readerExtension->CardStatusPollingWorker);
  	 	readerExtension->CardStatusPollingWorker = NULL;
   	}   
}

static VOID
CardTrackingTimerRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Context
    )
{
	PDEVICE_EXTENSION 		deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION 	smartcardExtension = &deviceExtension->SmartcardExtension;
	PREADER_EXTENSION			readerExtension = smartcardExtension->ReaderExtension;

//	SmartcardDebug( 
//					DEBUG_TRACE,
//					( "+++++++++++++++++++++CardTrackingTimerRoutine+++++++++++++++\n" )
//					);
  if (readerExtension->CardStatusPollingWorker == NULL) {
  		readerExtension->CardStatusPollingWorker = IoAllocateWorkItem(
  													DeviceObject
  													);
  		if (readerExtension->CardStatusPollingWorker == NULL) {
					SmartcardDebug( 
						DEBUG_TRACE,
						( "USCRStartCardTracking: Insufficient memory for Polling Routine.\n" )
						);
					return ;
		  }		
		  IoQueueWorkItem(
  						readerExtension->CardStatusPollingWorker,
  						CardStatusWorkItemRoutine,
  						DelayedWorkQueue ,
  						NULL
  						);																	
  }			
 
}

static void
UpdateCardCurrentState(
    IN PDEVICE_OBJECT DeviceObject
    )
{
		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;
		SmartcardDebug( 
					DEBUG_TRACE,
					( "---------------USCRUpdateCardCurrentState----------------\n" )
					);
		//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 ) ) {
	        USCR_DecrementIoCount(DeviceObject);                          
	        return;
		}
		CmdGetSlotStatus(
									readerExtension,
									&CardStatus,//ICC_PRESENT 0x1 ICC_ABSENT 0x2 
									&len
									);
		smartcardExtension->ReaderCapabilities.CurrentState = (CardStatus == ICC_PRESENT) ? SCARD_PRESENT : SCARD_ABSENT;
    USCR_DecrementIoCount(DeviceObject);       
}

NTSTATUS
USCRStartCardTracking(
	    IN PDEVICE_OBJECT DeviceObject
	    )
{
	NTSTATUS 							status = STATUS_SUCCESS;

	SmartcardDebug( 
					DEBUG_TRACE,
					( "USCRStartCardTracking.\n" )
					);
	UpdateCardCurrentState(DeviceObject);
	
	status = IoInitializeTimer(
														DeviceObject,
														CardTrackingTimerRoutine,
														NULL
														);
														
	IoStartTimer(DeviceObject);
	
	return status;

}

void
USCRStopCardTracking(
	    IN PDEVICE_OBJECT DeviceObject
	    )
{
	NTSTATUS 							status = STATUS_SUCCESS;
	PDEVICE_EXTENSION 		deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION 	smartcardExtension = &deviceExtension->SmartcardExtension;
	PREADER_EXTENSION			readerExtension = smartcardExtension->ReaderExtension;

	SmartcardDebug( 
					DEBUG_TRACE,
					( "USCRStopCardTracking IRQL=%d.DISPATCH_LEVEL=%d\n",KeGetCurrentIrql(),DISPATCH_LEVEL)
					);
	IoStopTimer(DeviceObject);
	
//  if(readerExtension->CardStatusPollingWorker)
//  {
//  	 IoFreeWorkItem(readerExtension->CardStatusPollingWorker);
//  	 readerExtension->CardStatusPollingWorker = NULL;
//  }
  
}


NTSTATUS
USCRCancel(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
Routine Description:
    This routine is called by the I/O system
    when the irp should be cancelled
Arguments:
    DeviceObject 	- Pointer to device object for this miniport
    Irp 		- IRP involved.
Return Value:
    STATUS_CANCELLED
--*/

{
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;

    	SmartcardDebug(
        	DEBUG_TRACE,
        	("USCRCancel: Enter\n")
        	);

    	ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);

	IoReleaseCancelSpinLock(
        	Irp->CancelIrql
        	);
	USCRCompleteCardTracking(smartcardExtension);

    	SmartcardDebug(
        	DEBUG_TRACE,
        	("USCRCancel: Exit\n")
        	);

    	return STATUS_CANCELLED;
}

NTSTATUS
USCRCardTracking(
	PSMARTCARD_EXTENSION SmartcardExtension
	)
{
	KIRQL CancelIrql;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "USRCardTracking: Enter\n" )
		);

	//set cancel routine
	IoAcquireCancelSpinLock( &CancelIrql );
	IoSetCancelRoutine(
		SmartcardExtension->OsData->NotificationIrp, 
		USCRCancel
		);
	IoReleaseCancelSpinLock( CancelIrql );

	SmartcardDebug( 
		DEBUG_TRACE,
		( "USRCardTracking: Exit \n" )
		);

	return( STATUS_PENDING );
}				

NTSTATUS
USCR_Cleanup(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is called when the calling application terminates.
    We can actually only have the notification irp that we have to cancel.

--*/

{
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
	NTSTATUS status = STATUS_SUCCESS;
	             
	SmartcardDebug(
	       DEBUG_TRACE,
	       ("USCR_Cleanup: Enter\n")
	       );
	
	ASSERT(Irp != smartcardExtension->OsData->NotificationIrp);
	
	// We need to complete the notification irp
	//************************************************************************
	// In order to not exclusive open by smart card service,i comment the next
	// line code,i think USCRCompleteCardTracking should be called in USCRCancel.
	// if other app open the device USCRCompleteCardTracking should not be called.
	// yanglq 2005-6-25
	//USCRCompleteCardTracking(smartcardExtension);
	//************************************************************************
	
	SmartcardDebug(
		DEBUG_DRIVER,
		("USCR_Cleanup: Completing IRP %lx\n",Irp)
		);
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	
	IoCompleteRequest(
		Irp,
		IO_NO_INCREMENT
		);
	
	SmartcardDebug(
	       DEBUG_TRACE,
	       ("USCR_Cleanup: Exit\n")
	       );
	
	return STATUS_SUCCESS;
}


NTSTATUS
InitializeSmartcardExtension(
    IN PDEVICE_OBJECT DeviceObject
    )
{
	static ULONG dataRatesSupported[] = { 9600/*, 19200, 38400, 57600, 115200*/ };
	static ULONG clkFrequenciesSupported[] = {1500, 3000, 6000 };
	UCHAR dataRatesEntries = sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);	
	UCHAR clkFrequenciesEntries = sizeof(clkFrequenciesSupported) / sizeof(clkFrequenciesSupported[0]);
	NTSTATUS ntStatus = STATUS_SUCCESS;
	ULONG			deviceInstance;
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;

	smartcardExtension->ReaderExtension = USCR_ExAllocatePool(
			NonPagedPool,
			sizeof(READER_EXTENSION)
			);
  	if(smartcardExtension->ReaderExtension == NULL)	
		return STATUS_INSUFFICIENT_RESOURCES;
	RtlZeroMemory(smartcardExtension->ReaderExtension, sizeof(READER_EXTENSION));
	smartcardExtension->ReaderExtension->deviceObject = DeviceObject;
        
	smartcardExtension->Version = SMCLIB_VERSION;
	smartcardExtension->SmartcardRequest.BufferSize = 
	smartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
	ntStatus = SmartcardInitialize(smartcardExtension);
	if (ntStatus != STATUS_SUCCESS) {
		return ntStatus;		
	}
	
	smartcardExtension->OsData->DeviceObject = DeviceObject;
	smartcardExtension->ReaderFunction[RDF_TRANSMIT] = USCRTransmit;
	smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = USCRSetProtocol;
	smartcardExtension->ReaderFunction[RDF_CARD_POWER] = USCRPower;
	smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = USCRCardTracking;
	smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = USCRVendorIoctl;

	strcpy(smartcardExtension->VendorAttr.VendorName.Buffer, "QWY");
	smartcardExtension->VendorAttr.VendorName.Length = 
		strlen(smartcardExtension->VendorAttr.VendorName.Buffer);
//	strcpy(smartcardExtension->VendorAttr.IfdType.Buffer, "USCReader");
//	smartcardExtension->VendorAttr.IfdType.Length = 
//		strlen(smartcardExtension->VendorAttr.IfdType.Buffer);
	smartcardExtension->VendorAttr.UnitNo = MAXIMUM_SMARTCARD_READERS;
	for (deviceInstance = 0; deviceInstance < MAXIMUM_SMARTCARD_READERS; deviceInstance++)
	{
		PDEVICE_OBJECT devObj;
		for(devObj = DeviceObject; devObj != NULL; devObj = devObj->NextDevice)
		{
			PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
			PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
			if (deviceInstance == smcExt->VendorAttr.UnitNo) {
				break;
			}
		}
		if (devObj == NULL) {
			smartcardExtension->VendorAttr.UnitNo = deviceInstance;
			break;
		}
	}
	smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3000;
	smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3000;
//	smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List = clkFrequenciesSupported;
//	smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.Entries = clkFrequenciesEntries;
	smartcardExtension->ReaderCapabilities.DataRate.Default = dataRatesSupported[0];
	smartcardExtension->ReaderCapabilities.DataRate.Max = dataRatesSupported[0];
	smartcardExtension->ReaderCapabilities.DataRatesSupported.List = dataRatesSupported;
	smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries = dataRatesEntries;
	smartcardExtension->ReaderCapabilities.MaxIFSD = 254;
	smartcardExtension->ReaderCapabilities.CurrentState = (ULONG) SCARD_UNKNOWN;
	smartcardExtension->ReaderCapabilities.SupportedProtocols = 
			SCARD_PROTOCOL_T0 /*| SCARD_PROTOCOL_T1*/;
	smartcardExtension->ReaderCapabilities.MechProperties = 0;
#ifdef DEBUG	
	SmartcardSetDebugLevel(DEBUG_ALL);
#endif
	
	return ntStatus;	
}

void
DeInitializeSmartcardExtension(
    IN PDEVICE_OBJECT DeviceObject
)
{
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;

	if (smartcardExtension->OsData) {
        	// complete pending card tracking requests (if any)
        	USCRCompleteCardTracking(smartcardExtension);
        	ASSERT(smartcardExtension->OsData->NotificationIrp == NULL);

        	// Wait until we can safely unload the device
        	//SmartcardReleaseRemoveLockAndWait(smartcardExtension);
        	// It's safely unload the device now.
				SmartcardExit(smartcardExtension);
  }
  if (smartcardExtension->ReaderExtension != NULL) {
  			USCR_ExFreePool(smartcardExtension->ReaderExtension);
  }
}

⌨️ 快捷键说明

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