| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #include "PcscCall.h"
- #include "cmb.h"
- #define SCARD_SCOPE_SYSTEM 0x0002 /**< Scope in system */
- #define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
- #define SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */
- #define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */
- #define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */
- #define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */
- #define SCARD_STATE_UNAWARE 0x0000 /**< App wants status */
- #define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */
- #define SCARD_PROTOCOL_UNDEFINED 0x0000 /**< protocol not set */
- #define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
- #define SCARD_CTL_CODE(code) (0x42000000 + (code))
- #define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(1)
- PcscCall::PcscCall()
- {
- m_sErrInfo[0] = 0;
- m_sReadName[0] = 0;
- m_hContext = NULL;
- m_hCurCard = NULL;
- SCardEstablishContext = NULL;
- }
- bool PcscCall::Load()
- {
- void *hLib = dlopen("libpcsclite.so", RTLD_LAZY); //load so
- if(hLib == NULL)
- {
- strcpy(m_sErrInfo, "load libpcsclite.so error");
- return false;
- }
- SCardEstablishContext = (pSCardEstablishContext)dlsym(hLib, "SCardEstablishContext");
- if (SCardEstablishContext == NULL)
- {
- strcpy(m_sErrInfo, "find function SCardEstablishContext error");
- return false;
- }
- SCardListReaders = (pSCardListReaders)dlsym(hLib, "SCardListReaders");
- SCardConnect = (pSCardConnect)dlsym(hLib, "SCardConnect");
- SCardDisconnect = (pSCardDisconnect)dlsym(hLib, "SCardDisconnect");
- SCardGetStatusChange = (pSCardGetStatusChange)dlsym(hLib, "SCardGetStatusChange");
- SCardStatus = (pSCardStatus)dlsym(hLib, "SCardStatus");
- SCardTransmit = (pSCardTransmit)dlsym(hLib, "SCardTransmit");
- SCardCancel = (pSCardCancel)dlsym(hLib, "SCardCancel");
- SCardReleaseContext = (pSCardReleaseContext)dlsym(hLib, "SCardReleaseContext");
- SCardIsValidContext = (pSCardIsValidContext)dlsym(hLib, "SCardIsValidContext");
- SCardControl = (pSCardControl)dlsym(hLib, "SCardControl");
- m_sErrInfo[0] = 0;
- return true;
- }
- bool PcscCall::Open(const char* sNameIn)
- {
- if (SCardEstablishContext == NULL && Load() == false)
- return false;
- LONG iRet = SCARD_S_SUCCESS;
- if (m_hContext == NULL)
- iRet = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &m_hContext);
- if (iRet != SCARD_S_SUCCESS || m_hContext == NULL)
- {
- sprintf(m_sErrInfo, "PCSC SCardEstablishContext %x", iRet);
- return false;
- }
- char sNameList[1024]="";
- ULONG dwLeng=1024;
- iRet = SCardListReaders(m_hContext, NULL, sNameList , &dwLeng);
- if (iRet == SCARD_E_NO_READERS_AVAILABLE)
- {
- sprintf(m_sErrInfo, "PCSC SCardListReaders NO_READERS %x", iRet);
- return false;
- }
- if (iRet != SCARD_S_SUCCESS || strlen(sNameList) < 16)
- {
- sprintf(m_sErrInfo, "PCSC SCardListReaders %x", iRet);
- return false;
- }
- if (m_hCurCard)
- SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
- m_hCurCard = NULL;
- int iLen = sNameIn ? strlen(sNameIn) : 0;
- char* pEnd = sNameList + dwLeng;
- for (char* pName = sNameList; pName < pEnd; pName++)
- {
- if (memcmp(pName, sNameIn, iLen) == 0)
- {
- strcpy(m_sReadName, pName);
- return true;
- }
- pName += strlen(pName);
- }
- sprintf(m_sErrInfo, "PCSC SCardListReaders not fond");
- return false;
- }
- bool PcscCall::Close()
- {
- if (m_hCurCard)
- DicConnect();
- if (m_hContext > 0)
- {
- SCardCancel(m_hContext);
- SCardReleaseContext(m_hContext);
- m_hContext = 0;
- }
- m_sReadName[0] = 0;
- return false;
- }
- int PcscCall::GetState()
- {
- if (m_hContext == 0)
- {
- strcpy(m_sErrInfo, "PCSC not opened");
- return STATE_NO_READER;
- }
- long iRet = SCARD_S_SUCCESS;
- SCARD_READERSTATE ReaderState;
- ReaderState.szReader = m_sReadName;
- ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
- ReaderState.dwEventState = 0;
- DWORD Value_timeout = 0;
- DWORD ReaderCount = 1;
- iRet = SCardGetStatusChange(m_hContext, Value_timeout, &ReaderState, ReaderCount);
- if (iRet != SCARD_S_SUCCESS)
- {
- sprintf(m_sErrInfo, "PCSC SCardGetStatusChange %x", iRet);
- return STATE_ERROR;
- }
- if (ReaderState.cbAtr > 0)
- {
- return STATE_HAVE_CARD;
- }
- return STATE_NO_CARD;
- }
- bool PcscCall::Connect(char* sATR, int& iLen)
- {
- if (m_hContext == NULL)
- {
- strcpy(m_sErrInfo, "PCSC not opened");
- return STATE_NO_READER;
- }
- if (m_hCurCard)
- SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
- m_hCurCard = NULL;
- LONG iRet = SCardConnect(m_hContext, m_sReadName, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &m_hCurCard, &m_APrtocol);
- if (iRet != 0)
- {
- sprintf(m_sErrInfo, "PCSC SCardConnect %s %x", m_sReadName, iRet);
- return false;
- }
- ULONG dwState;
- char szReader[256] = {0};
- BYTE byData[256] = {0};
- ULONG iDataLen = 256;
- ULONG iReaderLen = 256;
- iRet = SCardStatus(m_hCurCard, szReader, &iReaderLen, &dwState, &m_APrtocol, byData, &iDataLen);
- if (iRet != SCARD_S_SUCCESS )
- {
- sprintf(m_sErrInfo, "PCSC SCardStatus %x", iRet);
- return false;
- }
- memcpy(sATR, byData, iDataLen);
- iLen = iDataLen;
- return true;
- }
- bool PcscCall::DicConnect()
- {
- if (m_hCurCard)
- SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
- m_hCurCard = NULL;
- return true;
- }
- int PcscCall::ChipIO(const char* sIn, char* sOut)
- {
- if (m_hCurCard == NULL)
- {
- strcpy(m_sErrInfo, "PCSC not connected");
- return STATE_NO_READER;
- }
- SCARD_IO_REQUEST pioSendRequest;
- pioSendRequest.dwProtocol = m_APrtocol;
- pioSendRequest.cbPciLength = sizeof(SCARD_IO_REQUEST);
- BYTE bSend[512], bRecv[512];
- ULONG iLen = ::HexStrToANSI(sIn, bSend);
- ULONG iRcv = 512;
- LONG iRet = SCardTransmit(m_hCurCard, &pioSendRequest, bSend, iLen, NULL, bRecv, &iRcv);
- if (iRet != SCARD_S_SUCCESS)
- {
- sprintf(m_sErrInfo, "PCSC SCardTransmit %x", iRet);
- return STATE_ERROR;
- }
- ::ANSIToHexStr(bRecv, iRcv, sOut);
- return 0;
- }
- int PcscCall::SendCMD(const char* sIn, char* sOut)
- {
- if (m_hContext == 0)
- {
- strcpy(m_sErrInfo, "PCSC not opened");
- return STATE_NO_READER;
- }
- if (m_hCurCard)
- SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
- m_hCurCard = NULL;
- long iRet = SCARD_S_SUCCESS;
- SCARDHANDLE hCurCard = 0;
- ULONG dwOutProtocal = 0;
- iRet = SCardConnect(m_hContext, m_sReadName, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_UNDEFINED,&hCurCard, &dwOutProtocal);
- if (iRet != 0)
- {
- sprintf(m_sErrInfo, "PCSC SCardConnect %s %x", m_sReadName, iRet);
- return STATE_ERROR;
- }
- BYTE bSend[512], bRecv[512];
- ULONG iLen = ::HexStrToANSI(sIn, bSend);
- ULONG iRcv = 512;
- iRet = SCardControl(hCurCard, IOCTL_CCID_ESCAPE, bSend, iLen, bRecv, 512, &iRcv);
- if (iRet != SCARD_S_SUCCESS)
- {
- sprintf(m_sErrInfo, "PCSC SCardControl %s %x", m_sReadName, iRet);
- return STATE_ERROR;
- }
- ::ANSIToHexStr(bRecv, iRcv, sOut);
- iRet = SCardDisconnect(hCurCard, SCARD_LEAVE_CARD);
- if (iRet != SCARD_S_SUCCESS)
- {
- sprintf(m_sErrInfo, "PCSC SCardDisconnect %x", iRet);
- return STATE_ERROR;
- }
- return STATE_NO_CARD;
- }
|