📄 uscrioctl.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 + -