📄 tlp3cb.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
Module Name:
tlp3cb.c
Abstract:
Callback functions for smart card library
--*/
#include <stdio.h>
#include <smclib.h>
#include <devload.h>
#include <tchar.h>
#include "TLP3CE.h"
#include "BullTLP3.h"
NTSTATUS StarIccCommand(
UCHAR Command,
UCHAR CardNo,
PSMARTCARD_EXTENSION SmartcardExtension);
NTSTATUS
TLP3ReaderPower(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
The smart card lib requires to have this function. It is called
for certain power requests to the card. We do nothing here, because
this action is performed in the StartIo function.
--*/
{
ULONG step, waitTime, numTry = 0, minWaitTime;
NTSTATUS status = STATUS_SUCCESS;
PREADER_EXTENSION pReaderExtension = SmartcardExtension->ReaderExtension;
LARGE_INTEGER liProcessClock;
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPower: Enter\r\n")));
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3ReaderPower: Enter (%lx)\n"),
szDriverName,
SmartcardExtension->MinorIoControlCode)
);
_try {
//
// Set standard parameters for serial port
//
pReaderExtension->SerialConfigData.SerialControlBlock.DCBlength=sizeof(DCB);
pReaderExtension->SerialConfigData.SerialControlBlock.BaudRate=CBR_9600;
pReaderExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBITS;
// pReaderExtension->SerialConfigData.SerialControlBlock.fParity=1; // Even Pariry check
pReaderExtension->SerialConfigData.SerialControlBlock.Parity=NOPARITY;
// pReaderExtension->SerialConfigData.SerialControlBlock.fBinary=1; // Skip EOF; 8-bit binary data.
pReaderExtension->SerialConfigData.SerialControlBlock.ByteSize=DATABITS_8;
// Time out set.
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=READ_INTERVAL_TIMEOUT_DEFAULT;
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier=
pReaderExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier=0;
status = TLP3ConfigureSerialPort(SmartcardExtension);
ASSERT(status == STATUS_SUCCESS);
if (status != STATUS_SUCCESS) {
leave;
}
// We don't send data to the reader, so set Number of bytes to send = 0
SmartcardExtension->SmartcardRequest.BufferLength = 0;
// Default number of bytes we expect to get back
SmartcardExtension->SmartcardReply.BufferLength = 0;
//
// Since power down triggers the UpdateSerialStatus function, we have
// to inform it that we forced the change of the status and not the user
// (who might have removed and inserted a card)
//
SmartcardExtension->ReaderExtension->PowerRequest = TRUE;
SmartcardExtension->ReaderExtension->ModemStatusChanged=FALSE;
// purge the serial buffer (it can contain the pnp id of the reader)
status=(PurgeComm(pReaderExtension->hSerialPort,
PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
ASSERT(status == STATUS_SUCCESS);
if (status != STATUS_SUCCESS) {
leave;
}
SmartcardExtension->CardCapabilities.ATR.Length = 0;
step=(SmartcardExtension->MinorIoControlCode == SCARD_WARM_RESET)?4:0;
for (; NT_SUCCESS(status); step++) {
switch (step) {
case 0:
// RTS = 0 means reader is in command mode
status=EscapeCommFunction(pReaderExtension->hSerialPort,
CLRRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
//
// This is the minimum wait time we have to wait before
// we can send commands to the microcontroller.
//
waitTime = 1000;
break;
case 1:
SmartcardExtension->SmartcardRequest.BufferLength = 0;
SmartcardExtension->SmartcardReply.BufferLength=0;
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown begin \r\n")));
status=StarIccCommand(0xe2,1,SmartcardExtension);
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown end status = %d\r\n"),status));
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerdown end replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
if(status!=STATUS_SUCCESS)
{
leave;
}
/*
// write power down command to the reader
SmartcardExtension->ReaderExtension->SerialIoControlCode =
SMARTCARD_WRITE;
SmartcardExtension->SmartcardRequest.BufferLength = 1;
SmartcardExtension->SmartcardRequest.Buffer[0] =
READER_CMD_POWER_DOWN;
waitTime = 100;
status=TLP3SerialIo( SmartcardExtension);
*/ break;
case 2:
/*
// Read back the echo of the reader
SmartcardExtension->ReaderExtension->SerialIoControlCode =
SMARTCARD_READ;
SmartcardExtension->SmartcardReply.BufferLength = 1;
// Wait the recovery time for the microcontroller
waitTime = 1000;
status=TLP3SerialIo( SmartcardExtension);
*/
break;
case 3:
// set RTS again so the microcontroller can execute the command
status=EscapeCommFunction(pReaderExtension->hSerialPort,
SETRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
waitTime = 10000;
break;
case 4:
if (SmartcardExtension->MinorIoControlCode == SCARD_POWER_DOWN) {
if (SmartcardExtension->ReaderCapabilities.CurrentState >
SCARD_PRESENT) {
SmartcardExtension->ReaderCapabilities.CurrentState =
SCARD_PRESENT;
}
SmartcardExtension->CardCapabilities.Protocol.Selected =
SCARD_PROTOCOL_UNDEFINED;
SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
status = STATUS_SUCCESS;
leave;
}
// clear RTS to switch to command mode
status=EscapeCommFunction(pReaderExtension->hSerialPort,
CLRRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
// Wait the recovery time for the microcontroller
waitTime = 1000;
break;
case 5:
// write the appropriate reset command to the reader
SmartcardExtension->SmartcardRequest.BufferLength = 0;
// SmartcardExtension->SmartcardReply.BufferLength=0;
status=StarIccCommand(0xe1,1,SmartcardExtension);
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerup end replybuffer = %s\r\n"),SmartcardExtension->SmartcardReply.Buffer));
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3ReaderPowerUp status=%d \r\n"),status));
if(status!=STATUS_SUCCESS)
{
return status;
}
return STATUS_SUCCESS;
// status=TLP3SerialIo( SmartcardExtension);
// waitTime = 100;
break;
case 6:
/*
// Read back the echo of the reader
SmartcardExtension->ReaderExtension->SerialIoControlCode =
SMARTCARD_READ;
SmartcardExtension->SmartcardReply.BufferLength = 1;
//
// This is the time we need to wait for the microcontroller
// to recover before we can set RTS again
//
status=TLP3SerialIo( SmartcardExtension);
waitTime = 1000;
*/ break;
case 7:
/* // set RTS again so the microcontroller can execute the command
status=EscapeCommFunction(pReaderExtension->hSerialPort,
SETRTS)?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
waitTime = 10000;
*/ break;
case 8:
// Here we check the card or reader event is changed or not.
// if it is. it is better to aborted it. Otherwise. It take
// long time to timeout.
if (SmartcardExtension->ReaderExtension->ModemStatusChanged) {
status = STATUS_MEDIA_CHANGED;
leave;
};
//
// We now try to get the ATR as fast as possible.
// Therefor we prev. set a very short read timeout and
// expect that the card delivered its ATR within this
// short time. To verify the correctness of the ATR we call
// SmartcardUpdateCardCapabilities(). If this call returns
// with STATUS_SUCCESS we know that the ATR is complete.
// Otherwise we read again and append the new data to the
// ATR buffer in the CardCapabilities and try again.
//
SmartcardExtension->ReaderExtension->SerialIoControlCode =
SMARTCARD_READ;
SmartcardExtension->SmartcardReply.BufferLength =
MAXIMUM_ATR_LENGTH -
SmartcardExtension->CardCapabilities.ATR.Length;
status=TLP3SerialIo( SmartcardExtension);
waitTime = 0;
break;
case 9:
if (SmartcardExtension->SmartcardReply.BufferLength != 0) {
ASSERT(
SmartcardExtension->CardCapabilities.ATR.Length +
SmartcardExtension->SmartcardReply.BufferLength <
MAXIMUM_ATR_LENGTH
);
if( SmartcardExtension->CardCapabilities.ATR.Length +
SmartcardExtension->SmartcardReply.BufferLength >=
MAXIMUM_ATR_LENGTH) {
status = STATUS_UNRECOGNIZED_MEDIA;
leave;
}
// we got some ATR bytes.
RtlCopyMemory(
SmartcardExtension->CardCapabilities.ATR.Buffer +
SmartcardExtension->CardCapabilities.ATR.Length,
SmartcardExtension->SmartcardReply.Buffer,
SmartcardExtension->SmartcardReply.BufferLength
);
SmartcardExtension->CardCapabilities.ATR.Length +=
(UCHAR) SmartcardExtension->SmartcardReply.BufferLength;
status = SmartcardUpdateCardCapabilities(
SmartcardExtension
);
// Only retry if we got at least some bytes, but not the whole ATR
if (status != STATUS_SUCCESS && numTry < 10/*100*/) {
// ATR is incomplete. Try again to get ATR bytes.
numTry += 1;
// continue with step 8
step = 7;
status = STATUS_TIMEOUT;
continue;
}
}
if (status != STATUS_SUCCESS) {
leave;
}
// No break
case 10:
if (SmartcardExtension->ReaderCapabilities.CurrentState <=
SCARD_ABSENT) {
status = STATUS_MEDIA_CHANGED;
}
if (status != STATUS_SUCCESS) {
leave;
}
// Copy ATR to user space
if (SmartcardExtension->IoRequest.ReplyBuffer) {
RtlCopyMemory(
SmartcardExtension->IoRequest.ReplyBuffer,
SmartcardExtension->CardCapabilities.ATR.Buffer,
SmartcardExtension->CardCapabilities.ATR.Length
);
// Tell user length of ATR
*SmartcardExtension->IoRequest.Information =
SmartcardExtension->CardCapabilities.ATR.Length;
}
//
// If the card uses invers convention we need to switch
// the serial driver to odd paritiy
//
if (SmartcardExtension->CardCapabilities.InversConvention) {
//serialConfigData->LineControl.Parity = ODD_PARITY;
pReaderExtension->SerialConfigData.SerialControlBlock.fParity=1; // Even Pariry check
pReaderExtension->SerialConfigData.SerialControlBlock.Parity=ODDPARITY;
}
//
// If the extra guard time is 255 it means that our
// frame with have to expect from the card has only
// 1 instead of 2 stop bits
// 1start bit + 8data bits + 1parity + 1stop == 11 etu
// see iso 7816-3 6.1.4.4 Extra Guard Time N
//
if (SmartcardExtension->CardCapabilities.PtsData.StopBits == 1) {
//serialConfigData->LineControl.StopBits = STOP_BIT_1;
pReaderExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBIT;
}
// depending on the protocol set the timeout values
if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T1) {
// set timeouts
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
(SmartcardExtension->CardCapabilities.T1.BWT +
MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
(SmartcardExtension->CardCapabilities.T1.CWT +
MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -