📄 smartcard.cpp
字号:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "SmartCard.h"
#include <Dialogs.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
SCARDCONTEXT m_hContext =0; //Card Reader Contex
//Construction Method, Set the CardReaderName
TSmartCardReader::TSmartCardReader(AnsiString pCardReaderName)
{
strcpy(CardReaderName, pCardReaderName.c_str());
}
void TSmartCardReader::ShowErrorMsg(long ErrorCode)
{
char Msg[255];
switch(ErrorCode)
{
case SCARD_E_CANCELLED: strcpy(Msg, " The action was canceled by an SCardCancel request. "); break;
case SCARD_E_CANT_DISPOSE: strcpy(Msg, "The system could not dispose of the media in the requested manner. "); break;
case SCARD_E_CARD_UNSUPPORTED: strcpy(Msg, "The smart card does not meet minimal requirements for support. "); break;
case SCARD_E_DUPLICATE_READER: strcpy(Msg, "The reader driver didn't produce a unique reader name. "); break;
case SCARD_E_INSUFFICIENT_BUFFER: strcpy(Msg, "The data buffer for returned data is too small for the returned data. "); break;
case SCARD_E_INVALID_ATR: strcpy(Msg, "An ATR string obtained from the registry is not a valid ATR string. "); break;
case SCARD_E_INVALID_HANDLE: strcpy(Msg, "The supplied handle was invalid. "); break;
case SCARD_E_INVALID_PARAMETER: strcpy(Msg, "One or more of the supplied parameters could not be properly interpreted. "); break;
case SCARD_E_INVALID_TARGET: strcpy(Msg, "Registry startup information is missing or invalid. "); break;
case SCARD_E_INVALID_VALUE: strcpy(Msg, "One or more of the supplied parameter values could not be properly interpreted. "); break;
case SCARD_E_NOT_READY: strcpy(Msg, "The reader or card is not ready to accept commands. "); break;
case SCARD_E_NOT_TRANSACTED: strcpy(Msg, "An attempt was made to end a non-existent transaction. "); break;
case SCARD_E_NO_MEMORY: strcpy(Msg, "Not enough memory available to complete this command. "); break;
case SCARD_E_NO_SERVICE: strcpy(Msg, "The smart card resource manager is not running. "); break;
case SCARD_E_NO_SMARTCARD: strcpy(Msg, "The operation requires a smart card, but no smart card is currently in the device. "); break;
case SCARD_E_PCI_TOO_SMALL: strcpy(Msg, "The PCI receive buffer was too small. "); break;
case SCARD_E_PROTO_MISMATCH: strcpy(Msg, "The requested protocols are incompatible with the protocol currently in use with the card. "); break;
case SCARD_E_READER_UNAVAILABLE: strcpy(Msg, "The specified reader is not currently available for use. "); break;
case SCARD_E_READER_UNSUPPORTED: strcpy(Msg, "The reader driver does not meet minimal requirements for support. "); break;
case SCARD_E_SERVICE_STOPPED: strcpy(Msg, "The smart card resource manager has shut down. "); break;
case SCARD_E_SHARING_VIOLATION: strcpy(Msg, "The smart card cannot be accessed because of other outstanding connections. "); break;
case SCARD_E_SYSTEM_CANCELLED: strcpy(Msg, "The action was canceled by the system, presumably to log off or shut down. "); break;
case SCARD_E_TIMEOUT: strcpy(Msg, "The user-specified timeout value has expired. "); break;
case SCARD_E_UNKNOWN_CARD: strcpy(Msg, "The specified smart card name is not recognized. "); break;
case SCARD_E_UNKNOWN_READER: strcpy(Msg, "The specified reader name is not recognized. "); break;
case SCARD_F_COMM_ERROR: strcpy(Msg, "An internal communications error has been detected. "); break;
case SCARD_F_INTERNAL_ERROR: strcpy(Msg, "An internal consistency check failed. "); break;
case SCARD_F_UNKNOWN_ERROR: strcpy(Msg, "An internal error has been detected, but the source is unknown. "); break;
case SCARD_F_WAITED_TOO_LONG: strcpy(Msg, "An internal consistency timer has expired. "); break;
case SCARD_S_SUCCESS: strcpy(Msg, "No error was encountered. "); break;
case SCARD_W_REMOVED_CARD: strcpy(Msg, "The smart card has been removed, so that further communication is not possible. "); break;
case SCARD_W_RESET_CARD: strcpy(Msg, "The smart card has been reset, so any shared state information is invalid. "); break;
case SCARD_W_UNPOWERED_CARD: strcpy(Msg, "Power has been removed from the smart card, so that further communication is not possible. "); break;
case SCARD_W_UNRESPONSIVE_CARD: strcpy(Msg, "The smart card is not responding to a reset. "); break;
case SCARD_W_UNSUPPORTED_CARD: strcpy(Msg, "The reader cannot communicate with the card, due to ATR string configuration conflicts. "); break;
default: strcpy(Msg, "unknow error");
}
ShowMessage(Msg);
}
//Distruction, Call CardDisconnect to Power off the card.
TSmartCardReader::~TSmartCardReader()
{
CardDisconnect();
}
//Power On Smart card.if Success then reuturn TRUE and store ATR to
// The parameter pATR else return False and not set the pATR
bool TSmartCardReader::CardConnect(AnsiString * pATR)
{
bool bRetval = true;
DWORD dwAP=0;
CardDisconnect();
LONG res;
bool bMuteCardChecked = false;
SCARD_READERSTATE ReaderState;
ReaderState.szReader = CardReaderName;
ReaderState.pvUserData = NULL;
ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
ReaderState.dwEventState = SCARD_STATE_CHANGED;
TRY_RESET_CARD_READER:
res = SCardGetStatusChange(m_hContext,
100,
&ReaderState,
1);
if (SCARD_S_SUCCESS == res)
{
if ((ReaderState.dwEventState & SCARD_STATE_PRESENT)== SCARD_STATE_PRESENT)
{
res = SCardConnect(m_hContext,
CardReaderName,
SCARD_SHARE_DIRECT,
0,
&m_hCard,
&dwAP);
if (SCARD_S_SUCCESS == res)
{
if (ReaderState.cbAtr <=0)
{
if (bMuteCardChecked== false)
{
SCardDisconnect(m_hCard, SCARD_EJECT_CARD);
m_hCard = 0;
bMuteCardChecked = true;
goto TRY_RESET_CARD_READER;
}
else
bRetval = false;
}
}
else
bRetval = false;
}
}
else
bRetval = false;
if (bRetval == true)
{
/*
if ((0xF0 & ReaderState.rgbAtr[1]) == 0x60)
m_ActiveProtocol = SCARD_PROTOCOL_T0;
else if((0xF0 & ReaderState.rgbAtr[1]) == 0xE0)
m_ActiveProtocol = SCARD_PROTOCOL_T1;
else
m_ActiveProtocol = SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0;
*/
res = SCardReconnect(m_hCard,
SCARD_SHARE_EXCLUSIVE ,
SCARD_RESET_CARD | SCARD_UNPOWER_CARD,
SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T0,
&m_ActiveProtocol);
if (SCARD_S_SUCCESS == res)
{
char * cAtr = (char*)malloc(ReaderState.cbAtr * 2 + 1);
memset(cAtr, 0, ReaderState.cbAtr * 2 + 1);
BinToHex(ReaderState.rgbAtr, cAtr, ReaderState.cbAtr);
*pATR = AnsiString(cAtr);
free(cAtr);
}
else
bRetval = false;
}
if (bRetval == false)
{
if (m_hCard != 0)
SCardDisconnect(m_hCard, SCARD_UNPOWER_CARD);
m_hCard = 0;
}
return bRetval;
}
//Power off Card
bool TSmartCardReader::CardDisconnect()
{
if (m_hCard != 0)
{
SCardDisconnect(m_hCard, SCARD_UNPOWER_CARD);
m_hCard = 0;
}
return true;
}
//Execute APDU COMMAND , szCMD' Format is Hex String
bool TSmartCardReader::RunAPDU(AnsiString szCMD, AnsiString * pResponse)
{
if(!m_hCard)
{
return false;
}
DWORD CMDLen = szCMD.Length()/2;
DWORD REPLen;
SCARD_IO_REQUEST * ScardIoRequest = new SCARD_IO_REQUEST();
ScardIoRequest->dwProtocol = this->m_ActiveProtocol;
ScardIoRequest->cbPciLength = sizeof(SCARD_IO_REQUEST);
// BYTE * CMD = (BYTE*)malloc(CMDLen);
BYTE CMD[255];
memset(CMD,0, 255);
HexToBin(szCMD.c_str(), CMD, CMDLen);
char cResponse[255];
//Send Command to card
LONG rc = SCardTransmit(m_hCard, ScardIoRequest , CMD, CMDLen, NULL, cResponse,&REPLen);
if(rc != SCARD_S_SUCCESS)
{
ShowErrorMsg(rc);
return false;
}
else
{
*pResponse = CharToHex(cResponse, REPLen, " ");
return true;
}
delete ScardIoRequest;
}
//Get All Card reader names and store to Parameter pReaders
void TSmartCardReader::GetCardListReaders(TStrings * pReaders)
{
TSmartCardReader::CardReleaseContex();
pReaders->Clear();
LONG res;
//SCARD_E_CANCELLED res: -2146435043
res = SCardEstablishContext(SCARD_SCOPE_SYSTEM ,NULL,NULL,&m_hContext);
if(res != SCARD_S_SUCCESS)
{
ShowErrorMsg(res);
m_hContext = 0;
return ;
}
//Look up all Card Reader and Add it to the Parameter of pReaders
LPTSTR pszReaders = NULL;
LPTSTR pReader = NULL;
DWORD cch = SCARD_AUTOALLOCATE;
DWORD dwAP;
res = SCardListReaders(m_hContext,NULL,(LPTSTR)&pszReaders,&cch);
if(res == SCARD_S_SUCCESS)
{
pReader = pszReaders;
String sReaderName = "";
int i = 0;
while (i < cch)
{
if (*pReader != '\0')
sReaderName += * pReader;
else
{
if (sReaderName != "")
pReaders->Add(sReaderName);
sReaderName = "";
}
pReader++;
i++;
}
}
SCardFreeMemory(m_hContext,pszReaders);
}
//Free Card Context
void TSmartCardReader::CardReleaseContex(void)
{
if (m_hContext != 0)
SCardReleaseContext(m_hContext);
}
//Convert Hex String to Char Buff
AnsiString TSmartCardReader::CharToHex(char * pCharBuff,const DWORD dwCharLen, const AnsiString szSeparator)
{
char * plchar = pCharBuff;
AnsiString lResult = "";
for (int i=0; i< dwCharLen; i++)
{
if (lResult != "")
lResult += szSeparator;
lResult = lResult + IntToHex((BYTE)*plchar,2);
plchar++;
}
return lResult;
}
//Delete the Space of Parameter szSourceStr
AnsiString TSmartCardReader::NoSpace(const AnsiString szSourceStr)
{
AnsiString lResult = "";
for (int i =1; i<= szSourceStr.Length(); i++)
{
if (szSourceStr.SubString(i,1) != " ")
lResult += szSourceStr.SubString(i,1);
}
return lResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -