📄 uscr.c
字号:
);
//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 + -