📄 lsccid.c
字号:
/*++Copyright (c) 2004 QWY MicroSystem Inc.Module Name: lsccid.c Abstract: USB SmartCard Reader driver for CCID/lsCCID compatible device.Environment: kernel mode onlyNotes:Revision History: 9/15/2004: created--*/#include "uscr.h"//#define GET_RESPONSE_FROM_INT0_PIPE NTSTATUS WriteUsb( IN PREADER_EXTENSION ReaderExtension, IN PLSCCID_CONTROLOUT_HEADER Setup, ULONG Length, IN PUCHAR Buffer ){ return UsbDoControlTransfer( ReaderExtension->deviceObject, &Setup->SetupPacket, USBD_TRANSFER_DIRECTION_OUT, Buffer, &Length ); }NTSTATUS ReadUsb( IN PREADER_EXTENSION ReaderExtension, IN PLSCCID_CONTROLOUT_HEADER Setup, ULONG *Length, IN PUCHAR Buffer ){ return UsbDoControlTransfer( ReaderExtension->deviceObject, &Setup->SetupPacket, USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, Buffer, Length );}NTSTATUS ReadUsbInt0( IN PREADER_EXTENSION ReaderExtension, ULONG *Length, IN PUCHAR Buffer ){ PDEVICE_OBJECT deviceObject = ReaderExtension->deviceObject; PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension; PUSBD_INTERFACE_INFORMATION interface = deviceExtension->UsbInterface;; return UsbDoInterruptOrBulkTransfer( deviceObject, interface->Pipes[0].PipeHandle, USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, Buffer, Length);}#define DEFAULT_VOLTAGE 1 /* start with 5 volts */NTSTATUSCmdPowerOn( PREADER_EXTENSION ReaderExtension, ULONG *nlength, PUCHAR buffer ){ LSCCID_CONTROLOUT_HEADER cmd; PLSCCID_CONTROLIN_HEADER response = (PLSCCID_CONTROLIN_HEADER)buffer; NTSTATUS status; ULONG atr_len, length, count = 1; UCHAR voltage; SmartcardDebug( DEBUG_TRACE, ("CmdPowerOn: Enter\n") ); /* store length of buffer[] */ voltage = DEFAULT_VOLTAGE; cmd.MessageHeader.bMessageType = PC_to_RDR_IccPowerOn; cmd.MessageHeader.wLength = 8+MAXIMUM_ATR_LENGTH; cmd.MessageHeader.bSeq = ReaderExtension->bSeq++; cmd.MessageHeader.abMspec[0] = voltage; /*bPowerSelect*/ cmd.MessageHeader.abMspec[1] = cmd.MessageHeader.abMspec[2] = 0; /* RFU */ HEXDUMP((char *)&cmd,8); status = ReadUsb(ReaderExtension, &cmd, &length,buffer); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; if (response->bStatus & PROCESSED_FAILED) { SmartcardDebug( DEBUG_ERROR, ("CmdPowerOn: response->bError:%d\n",response->bError) ); return STATUS_NO_MEDIA; } if(length > 8) { /* extract the ATR */ atr_len = response->wLength-8; /* ATR length */ if (atr_len > *nlength) { return STATUS_BUFFER_TOO_SMALL; } else *nlength = atr_len; RtlMoveMemory(buffer, buffer+8, atr_len); }else{ *nlength = 0; status = STATUS_NO_MEDIA; } SmartcardDebug( DEBUG_TRACE, ("CmdPowerOn: Exit atr_len:%d,status=%x\n",atr_len,status) ); return status;} NTSTATUSCmdPowerOff( PREADER_EXTENSION ReaderExtension ){ LSCCID_CONTROLOUT_HEADER cmd; PLSCCID_CONTROLIN_HEADER response = (PLSCCID_CONTROLIN_HEADER)&cmd; NTSTATUS status; ULONG length; SmartcardDebug( DEBUG_TRACE, ("CmdPowerOff: Enter\n") ); cmd.MessageHeader.bMessageType = PC_to_RDR_IccPowerOff; cmd.MessageHeader.wLength = 8; cmd.MessageHeader.bSeq = ReaderExtension->bSeq++; cmd.MessageHeader.abMspec[0] = cmd.MessageHeader.abMspec[1] = cmd.MessageHeader.abMspec[2] = 0; status = ReadUsb(ReaderExtension, &cmd,&length,(PUCHAR)&cmd); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; if (response->bStatus & PROCESSED_FAILED) { SmartcardDebug( DEBUG_ERROR, ("CmdPowerOff: response->bError:%d\n",response->bError) ); return STATUS_NO_MEDIA; } SmartcardDebug( DEBUG_TRACE, ("CmdPowerOff: Exit\n") ); return status;}NTSTATUSCmdGetSlotStatus( PREADER_EXTENSION ReaderExtension, PUCHAR buffer, ULONG *buf_length ){ LSCCID_CONTROLOUT_HEADER cmd; PLSCCID_CONTROLIN_HEADER response = (PLSCCID_CONTROLIN_HEADER)&cmd; ULONG length; NTSTATUS status; //SmartcardDebug( // DEBUG_TRACE, // ("CmdGetSlotStatus: Enter\n") // ); cmd.MessageHeader.bMessageType = PC_to_RDR_GetSlotStatus; cmd.MessageHeader.wLength = 8; cmd.MessageHeader.bSeq = ReaderExtension->bSeq++; cmd.MessageHeader.abMspec[0] = cmd.MessageHeader.abMspec[1] = cmd.MessageHeader.abMspec[2] = 0; status = ReadUsb(ReaderExtension, &cmd, &length, (PUCHAR)&cmd); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; if (response->bStatus & PROCESSED_FAILED) { SmartcardDebug( DEBUG_ERROR, ("CmdGetSlotStatus: response->bError:%d\n",response->bError) ); return STATUS_NO_MEDIA; } if(*buf_length < 1) return STATUS_INVALID_PARAMETER; buffer[0] = response->bStatus; *buf_length = 1; //SmartcardDebug( // DEBUG_TRACE, // ("CmdGetSlotStatus: Exit\n") // ); return status;} NTSTATUSCCID_Transmit( PREADER_EXTENSION ReaderExtension, ULONG tx_length, PUCHAR tx_buffer, UCHAR bBWI ){ NTSTATUS status; UCHAR buf[8+MIN_BUFFER_SIZE]; PLSCCID_CONTROLOUT_HEADER cmd = (PLSCCID_CONTROLOUT_HEADER)buf; int length; SmartcardDebug( DEBUG_TRACE, ("CCID_Transmit: Enter\n") ); SmartcardDebug( DEBUG_TRACE, ("tx_length=%d\n",tx_length) ); if(tx_length > 255) tx_length = 255; cmd->MessageHeader.bMessageType = PC_to_RDR_XfrBlock; cmd->MessageHeader.wLength = (USHORT)tx_length; cmd->MessageHeader.bSeq = ++ReaderExtension->bSeq; cmd->MessageHeader.abMspec[0] = bBWI; cmd->MessageHeader.abMspec[1] = 0; cmd->MessageHeader.abMspec[2] = ReaderExtension->channel; RtlCopyMemory(buf+8, tx_buffer, tx_length); length = tx_length+8; HEXDUMP(buf,length); status = WriteUsb(ReaderExtension, cmd, length,buf+8); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; SmartcardDebug( DEBUG_TRACE, ("CCID_Transmit: Exit\n") ); return status;} NTSTATUSCCID_Receive( PREADER_EXTENSION ReaderExtension, ULONG *rx_length, UCHAR rx_buffer[]){ NTSTATUS status; ULONG length; UCHAR buf[8+MIN_BUFFER_SIZE]; PLSCCID_CONTROLIN_HEADER response = (PLSCCID_CONTROLIN_HEADER)buf; LSCCID_CONTROLOUT_HEADER cmd; SmartcardDebug( DEBUG_TRACE, ("CCID_Receive: Enter\n") );#ifdef GET_RESPONSE_FROM_INT0_PIPE if(*rx_length > 255) *rx_length = 255;time_request: length = *rx_length+8; status = ReadUsbInt0(ReaderExtension, &length, buf);#else if(*rx_length + 8 > 255) *rx_length = 255-8; cmd.MessageHeader.bMessageType = PC_to_RDR_GetResponse; cmd.MessageHeader.wLength = (USHORT)*rx_length+8; cmd.MessageHeader.bSeq = ++ReaderExtension->bSeq; cmd.MessageHeader.abMspec[0] = 0; cmd.MessageHeader.abMspec[1] = 0; cmd.MessageHeader.abMspec[2] = ReaderExtension->channel; time_request: status = ReadUsb(ReaderExtension, &cmd, &length, buf);#endif if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; if (response->bStatus & PROCESSED_FAILED) { SmartcardDebug( DEBUG_ERROR, ("CCID_Receive: response->bError:%d\n",response->bError) ); return STATUS_NO_MEDIA; } if (response->bStatus & CCID_TIME_EXTENSION) { SmartcardDebug( DEBUG_ERROR, ("Time extension requested\n") ); goto time_request; } length = response->wLength; if (length < *rx_length) *rx_length = length; else length = *rx_length; RtlCopyMemory(rx_buffer,buf+8,length); SmartcardDebug( DEBUG_TRACE, ("CCID_Receive: Exit\n") ); return status;} NTSTATUSCmdXfrBlockTPDU_T0( PREADER_EXTENSION ReaderExtension, ULONG tx_length, UCHAR tx_buffer[], ULONG *rx_length, UCHAR rx_buffer[] ){ NTSTATUS status = STATUS_SUCCESS; SmartcardDebug( DEBUG_TRACE, ("CmdXfrBlockTPDU_T0: Enter\n") ); status = CCID_Transmit(ReaderExtension, tx_length, tx_buffer, 0); if (status != STATUS_SUCCESS) return status; status = CCID_Receive(ReaderExtension, rx_length, rx_buffer); SmartcardDebug( DEBUG_TRACE, ("CmdXfrBlockTPDU_T0: Exit\n") ); return status;} NTSTATUSCmdSetReaderRelatedParameters( PREADER_EXTENSION ReaderExtension, ULONG tx_length, PUCHAR tx_buffer){ NTSTATUS status; UCHAR buf[8+MIN_BUFFER_SIZE]; PLSCCID_CONTROLOUT_HEADER cmd = (PLSCCID_CONTROLOUT_HEADER)buf; int length; SmartcardDebug( DEBUG_TRACE, ("CmdSetReaderRelatedParameter: Enter\n") ); SmartcardDebug( DEBUG_TRACE, ("tx_length=%d\n",tx_length) ); if(tx_length != sizeof(READER_RELATED_PARAMETER)) return STATUS_INVALID_PARAMETER; cmd->MessageHeader.bMessageType = PC_to_RDR_SetParameters; cmd->MessageHeader.wLength = (USHORT)tx_length; cmd->MessageHeader.bSeq = ++ReaderExtension->bSeq; cmd->MessageHeader.abMspec[0] = 0; cmd->MessageHeader.abMspec[1] = cmd->MessageHeader.abMspec[2] = 0; RtlCopyMemory(buf+8, tx_buffer, tx_length); length = tx_length+8; HEXDUMP(buf,length); status = WriteUsb(ReaderExtension, cmd, length,buf+8); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT; SmartcardDebug( DEBUG_TRACE, ("CCID_Transmit: Exit\n") ); return status; } NTSTATUSCmdGetReaderRelatedParameters( PREADER_EXTENSION ReaderExtension, ULONG *rx_length, UCHAR rx_buffer[]){ NTSTATUS status; ULONG length; UCHAR buf[8+MIN_BUFFER_SIZE]; PLSCCID_CONTROLIN_HEADER response = (PLSCCID_CONTROLIN_HEADER)buf; LSCCID_CONTROLOUT_HEADER cmd; SmartcardDebug( DEBUG_TRACE, ("CmdGetReaderRelatedParameter: Enter\n") ); if(*rx_length < sizeof(READER_RELATED_PARAMETER)) return STATUS_INVALID_PARAMETER; cmd.MessageHeader.bMessageType = PC_to_RDR_GetParameters; cmd.MessageHeader.wLength = (USHORT)sizeof(READER_RELATED_PARAMETER)+8; cmd.MessageHeader.bSeq = ++ReaderExtension->bSeq; cmd.MessageHeader.abMspec[0] = 0; cmd.MessageHeader.abMspec[1] = cmd.MessageHeader.abMspec[2] = 0; status = ReadUsb(ReaderExtension, &cmd, &length, buf); if (status != STATUS_SUCCESS) return STATUS_IO_TIMEOUT;// if (response->bStatus & PROCESSED_FAILED)// {// SmartcardDebug(// DEBUG_ERROR,// ("CmdGetReaderRelatedParameter: response->bError:%d\n",response->bError)// );// return STATUS_NO_MEDIA;// } length = response->wLength; if (length < *rx_length) *rx_length = length; else length = *rx_length; RtlCopyMemory(rx_buffer,buf+8,length); SmartcardDebug( DEBUG_TRACE, ("CmdGetReaderRelatedParameter: Exit\n") ); return status;} #define high(a) ((a&0xff00) >> 8)#define low(a) (a&0xff)#define clk 1 //smart card clock:0 for 6M Hz,1 for 3M Hz,3 for 1.5M Hzstatic READER_RELATED_PARAMETER defaultReaderRelatedParameter = { clk, 200, low(60000), high(60000), 2, low(124*(clk+1)), high(124*(clk+1)), low(372*(clk+1)), high(372*(clk+1)), low(744*(clk+1)), high(744*(clk+1))};NTSTATUSCmdResetReaderRelatedParameters( PREADER_EXTENSION ReaderExtension ){ return CmdSetReaderRelatedParameters(ReaderExtension, sizeof(READER_RELATED_PARAMETER), (PUCHAR)&defaultReaderRelatedParameter );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -