📄 tlp3ce.c
字号:
smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = TLP3VendorIoctl;
// setup smartcard extension - vendor attribute
RtlCopyMemory(
smartcardExtension->VendorAttr.VendorName.Buffer,
TLP3_VENDOR_NAME,sizeof( TLP3_VENDOR_NAME ));
smartcardExtension->VendorAttr.VendorName.Length = sizeof( TLP3_VENDOR_NAME );
RtlCopyMemory(
smartcardExtension->VendorAttr.IfdType.Buffer,
TLP3_PRODUCT_NAME,sizeof( TLP3_PRODUCT_NAME ));
smartcardExtension->VendorAttr.IfdType.Length = sizeof(TLP3_PRODUCT_NAME );
smartcardExtension->VendorAttr.UnitNo = 0;
smartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
smartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
//
// Set the reader capabilities
//
// Clk frequency in KHz encoded as little endian integer
smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
smartcardExtension->ReaderCapabilities.DataRate.Default =
smartcardExtension->ReaderCapabilities.DataRate.Max =
dataRatesSupported[0];
// reader could support higher data rates
smartcardExtension->ReaderCapabilities.DataRatesSupported.List =
dataRatesSupported;
smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
smartcardExtension->ReaderCapabilities.MaxIFSD = 254;
// Now setup information in our deviceExtension
smartcardExtension->ReaderCapabilities.CurrentState =
(ULONG) SCARD_UNKNOWN;
// This reader supports T=0 and T=1
smartcardExtension->ReaderCapabilities.SupportedProtocols =
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
smartcardExtension->ReaderCapabilities.MechProperties = 0;
smartcardExtension->ReaderCapabilities.ReaderType =
SCARD_READER_TYPE_PCMCIA;
smartcardExtension->ReaderCapabilities.Channel = 0;
smartcardExtension->ReaderExtension->ReaderPowerState =
PowerReaderOff;
// Copy the ActivePath
_tcsncpy(readerExtension->d_ActivePath,ActiveKey,REG_PATH_LEN);
readerExtension->d_ActivePath[REG_PATH_LEN-1]=0;// terminated if overflow.
readerExtension->d_uReaderState = STATE_CLOSED;
return smartcardExtension;
}
void
TLP3UnloadDevice(PSMARTCARD_EXTENSION SmartcardExtension)
{
PREADER_EXTENSION pReader = SmartcardExtension->ReaderExtension;
WCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
DWORD retry = 0;
// remove device from list of active devices managed by this driver
RemoveDevice(SmartcardExtension);
// At this point no other thread should have a reference to this object
// make sure that's the case
while (SmartcardExtension->ReaderExtension->d_RefCount && retry++ < 3)
{
Sleep(retry * 32);
SmartcardDebug(DEBUG_INIT, (TEXT("%s:UnloadDevice - waiting for refCount %d to drop to zero\r\n"),
szDriverName,SmartcardExtension->ReaderExtension->d_RefCount ));
}
ASSERT(!SmartcardExtension->ReaderExtension->d_RefCount);
// Remove friendly name
MakeFriendlyName(SmartcardExtension, szFriendlyName);
SmartcardDeleteLink(szFriendlyName);
// sign off from SMCLIB
SmartcardExit(SmartcardExtension);
SmartcardDebug(DEBUG_INIT, (TEXT("%s:UnloadDevice - freeing PCMCIA resources\r\n"),szDriverName));
LocalFree(SmartcardExtension);
SmartcardDebug(DEBUG_INIT, (TEXT("%s:UnloadDevice done with 0x%x\r\n"), szDriverName, SmartcardExtension));
}
/* ++
TLP3CreateSerialPort
Open Serial Driver.
return :
FALSE: no serial port available.
*/
BOOL TLP3CreateSerialPort(PSMARTCARD_EXTENSION smartcardExtension)
{
HANDLE hSerial;
if (smartcardExtension->ReaderExtension->hSerialPort)
return TRUE;
hSerial = CreateFile( smartcardExtension->ReaderExtension->d_SerialPort,
GENERIC_READ | GENERIC_WRITE, 0, NULL,OPEN_EXISTING, 0, NULL );
if (hSerial!=INVALID_HANDLE_VALUE) { // successed
smartcardExtension->ReaderExtension->hSerialPort=hSerial;
return TRUE;
}
else {
SmartcardDebug(
DEBUG_TRACE|DEBUG_ERROR,
( TEXT("%s!TLP3CreateSerialPort: Fail to open serial port Exit\n"),
szDriverName)
);
return FALSE;
};
}
/* ++
TLP3CloseSerialDevice
Open Serial Driver, if there is no one.
return :
FALSE: no serial port available.
*/
VOID
TLP3CloseSerialPort(PSMARTCARD_EXTENSION smartcardExtension )
/*++
Routine Description:
This function closes the connection to the serial driver when the reader
has been removed (unplugged).
--*/
{
HANDLE hSerial;
SmartcardDebug(
DEBUG_TRACE|DEBUG_SERIAL,
( TEXT("%s!TLP3CloseSerialPort: Enter\n"),
szDriverName)
);
hSerial=smartcardExtension->ReaderExtension->hSerialPort;
if (hSerial!=NULL) {
smartcardExtension->ReaderExtension->hSerialPort=NULL;
CloseHandle(hSerial);
};
SmartcardDebug(
DEBUG_TRACE|DEBUG_SERIAL,
( TEXT("%s!TLP3CloseSerialPort: Exit\n"),
szDriverName)
);
}
NTSTATUS
TLP3SerialIo(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This routine sends IOCTL's to the serial driver. It waits on for their
completion, and then returns.
Arguments:
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
ULONG currentByte = 0;
BOOL bResult;
DWORD dwCompleted;
// Check if the buffers are large enough
ASSERT(SmartcardExtension->SmartcardReply.BufferLength <=
SmartcardExtension->SmartcardReply.BufferSize);
ASSERT(SmartcardExtension->SmartcardRequest.BufferLength <=
SmartcardExtension->SmartcardRequest.BufferSize);
if (SmartcardExtension->SmartcardReply.BufferLength >
SmartcardExtension->SmartcardReply.BufferSize ||
SmartcardExtension->SmartcardRequest.BufferLength >
SmartcardExtension->SmartcardRequest.BufferSize) {
SmartcardLogError(
SmartcardExtension->OsData->DeviceObject,
TLP3_BUFFER_TOO_SMALL,
NULL,
0
);
return STATUS_BUFFER_TOO_SMALL;
}
do {
PUCHAR requestBuffer = NULL;
PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
ULONG requestBufferLength = SmartcardExtension->SmartcardRequest.BufferLength;
ULONG replyBufferLength = SmartcardExtension->SmartcardReply.BufferLength;
if (READER_EXTENSION(SerialIoControlCode) == SMARTCARD_WRITE) {
requestBuffer =
&SmartcardExtension->SmartcardRequest.Buffer[currentByte];
if (SmartcardExtension->CardCapabilities.GT >= MICROSECONDS_PER_MILLISECOND) {
//
// If the guardtime isn't 0 and we write data to the smart card
// we only write byte by byte, because we have to insert a delay
// between every sent byte
//
requestBufferLength = 1;
currentByte++;
}
else
currentByte+=requestBufferLength;
replyBuffer = NULL;
replyBufferLength = 0;
} else {
requestBuffer =
(requestBufferLength ?
SmartcardExtension->SmartcardRequest.Buffer : NULL);
}
if ( SmartcardExtension->ReaderExtension->hSerialPort== NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
bResult=FALSE;
dwCompleted=0;
switch (SmartcardExtension->ReaderExtension->SerialIoControlCode) {
//
//
case SMARTCARD_WRITE:
ASSERT(replyBuffer == NULL);
SmartcardDebug( DEBUG_TRACE|DEBUG_SERIAL,
( TEXT("%s!TLP3SerialIo: Write(Buffer=%lx,Length=%d)\n"),
szDriverName,requestBuffer,requestBufferLength));
bResult=WriteFile(SmartcardExtension->ReaderExtension->hSerialPort, // handle to file to write to
requestBuffer,requestBufferLength,&dwCompleted,NULL);
ASSERT(requestBufferLength==dwCompleted);
dwCompleted=0;
status=(bResult?STATUS_SUCCESS:STATUS_UNSUCCESSFUL);
break;
case SMARTCARD_READ:
bResult=ReadFile(SmartcardExtension->ReaderExtension->hSerialPort,// handle of file to read
replyBuffer,replyBufferLength,&dwCompleted,NULL);
SmartcardDebug( DEBUG_TRACE|DEBUG_SERIAL,
( TEXT("%s!TLP3SerialIo: Read(Buffer=%lx,Length=%d),Completed=%ld\n"),
szDriverName,replyBuffer,replyBufferLength,dwCompleted));
status=(bResult?(dwCompleted<replyBufferLength?STATUS_TIMEOUT:STATUS_SUCCESS):STATUS_UNSUCCESSFUL);
break;
default:
SmartcardDebug( DEBUG_ERROR|DEBUG_SERIAL,
( TEXT("%s!TLP3SerialIo: Invalid SerialIoControlCode\n"),szDriverName));
ASSERT(0);
status = STATUS_INVALID_DEVICE_STATE;
break;
}
if (bResult) {
// save the number of bytes received
SmartcardExtension->SmartcardReply.BufferLength = dwCompleted;
}
// Check if we have to write more bytes to the reader
if (SmartcardExtension->ReaderExtension->SerialIoControlCode ==
SMARTCARD_WRITE &&
SmartcardExtension->CardCapabilities.GT < MICROSECONDS_PER_MILLISECOND &&
currentByte <
SmartcardExtension->SmartcardRequest.BufferLength &&
status == STATUS_SUCCESS) {
// Now wait the required guard time
Sleep((SmartcardExtension->CardCapabilities.GT+
MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND);
status = STATUS_MORE_PROCESSING_REQUIRED;
}
} while (status == STATUS_MORE_PROCESSING_REQUIRED);
return status;
}
#define MAX_SCARD_DATA_BUFFERSIZE 0x200
NTSTATUS
TLP3ConfigureSerialPort(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This routine will appropriately configure the serial port.
It makes synchronous calls to the serial port.
Arguments:
SmartcardExtension - Pointer to smart card struct
Return Value:
NTSTATUS
--*/
{
PREADER_EXTENSION pReaderExtension = SmartcardExtension->ReaderExtension;
NTSTATUS status = STATUS_SUCCESS;
USHORT i;
PUCHAR request = SmartcardExtension->SmartcardRequest.Buffer;
BOOL bSuccess;
SmartcardExtension->SmartcardRequest.BufferLength = 0;
SmartcardExtension->SmartcardReply.BufferLength =
SmartcardExtension->SmartcardReply.BufferSize;
bSuccess=TRUE;
for (i = 0; bSuccess; i++) {
switch (i)
{
case 0:
// Set up baudrate, line control, control charaters for the TLP3 reader
bSuccess=SetCommState(pReaderExtension->hSerialPort,&(pReaderExtension->SerialConfigData.SerialControlBlock));
break;
case 1:
// Set up timeouts
bSuccess=SetCommTimeouts(pReaderExtension->hSerialPort,&(pReaderExtension->SerialConfigData.Timeouts));
break;
case 2:
// Set break off
// bSuccess=ClearCommBreak(pReaderExtension->hSerialPort);
break;
case 3:
// set DTR for the reader
// bSuccess= EscapeCommFunction(pReaderExtension->hSerialPort, SETDTR);
break;
case 4:
// set RTS for the reader
// bSuccess= EscapeCommFunction(pReaderExtension->hSerialPort, SETRTS);
break;
case 5:
bSuccess= SetupComm(pReaderExtension->hSerialPort,
MAX_SCARD_DATA_BUFFERSIZE,
MAX_SCARD_DATA_BUFFERSIZE);
break;
case 6:
return STATUS_SUCCESS;
}
status = bSuccess?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
if (!bSuccess)
SmartcardDebug(
DEBUG_TRACE|DEBUG_ERROR,
(TEXT("%s!TLP3ConfigSerialPort: Fail,Error Code %d \n"),
szDriverName,GetLastError()));
}
return status;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -