PcscCall.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #include "PcscCall.h"
  2. #include "cmb.h"
  3. #define SCARD_SCOPE_SYSTEM 0x0002 /**< Scope in system */
  4. #define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
  5. #define SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */
  6. #define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */
  7. #define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */
  8. #define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */
  9. #define SCARD_STATE_UNAWARE 0x0000 /**< App wants status */
  10. #define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */
  11. #define SCARD_PROTOCOL_UNDEFINED 0x0000 /**< protocol not set */
  12. #define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
  13. #define SCARD_CTL_CODE(code) (0x42000000 + (code))
  14. #define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(1)
  15. PcscCall::PcscCall()
  16. {
  17. m_sErrInfo[0] = 0;
  18. m_sReadName[0] = 0;
  19. m_hContext = NULL;
  20. m_hCurCard = NULL;
  21. SCardEstablishContext = NULL;
  22. }
  23. bool PcscCall::Load()
  24. {
  25. void *hLib = dlopen("libpcsclite.so", RTLD_LAZY); //load so
  26. if(hLib == NULL)
  27. {
  28. strcpy(m_sErrInfo, "load libpcsclite.so error");
  29. return false;
  30. }
  31. SCardEstablishContext = (pSCardEstablishContext)dlsym(hLib, "SCardEstablishContext");
  32. if (SCardEstablishContext == NULL)
  33. {
  34. strcpy(m_sErrInfo, "find function SCardEstablishContext error");
  35. return false;
  36. }
  37. SCardListReaders = (pSCardListReaders)dlsym(hLib, "SCardListReaders");
  38. SCardConnect = (pSCardConnect)dlsym(hLib, "SCardConnect");
  39. SCardDisconnect = (pSCardDisconnect)dlsym(hLib, "SCardDisconnect");
  40. SCardGetStatusChange = (pSCardGetStatusChange)dlsym(hLib, "SCardGetStatusChange");
  41. SCardStatus = (pSCardStatus)dlsym(hLib, "SCardStatus");
  42. SCardTransmit = (pSCardTransmit)dlsym(hLib, "SCardTransmit");
  43. SCardCancel = (pSCardCancel)dlsym(hLib, "SCardCancel");
  44. SCardReleaseContext = (pSCardReleaseContext)dlsym(hLib, "SCardReleaseContext");
  45. SCardIsValidContext = (pSCardIsValidContext)dlsym(hLib, "SCardIsValidContext");
  46. SCardControl = (pSCardControl)dlsym(hLib, "SCardControl");
  47. m_sErrInfo[0] = 0;
  48. return true;
  49. }
  50. bool PcscCall::Open(const char* sNameIn)
  51. {
  52. if (SCardEstablishContext == NULL && Load() == false)
  53. return false;
  54. LONG iRet = SCARD_S_SUCCESS;
  55. if (m_hContext == NULL)
  56. iRet = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &m_hContext);
  57. if (iRet != SCARD_S_SUCCESS || m_hContext == NULL)
  58. {
  59. sprintf(m_sErrInfo, "PCSC SCardEstablishContext %x", iRet);
  60. return false;
  61. }
  62. char sNameList[1024]="";
  63. ULONG dwLeng=1024;
  64. iRet = SCardListReaders(m_hContext, NULL, sNameList , &dwLeng);
  65. if (iRet == SCARD_E_NO_READERS_AVAILABLE)
  66. {
  67. sprintf(m_sErrInfo, "PCSC SCardListReaders NO_READERS %x", iRet);
  68. return false;
  69. }
  70. if (iRet != SCARD_S_SUCCESS || strlen(sNameList) < 16)
  71. {
  72. sprintf(m_sErrInfo, "PCSC SCardListReaders %x", iRet);
  73. return false;
  74. }
  75. if (m_hCurCard)
  76. SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
  77. m_hCurCard = NULL;
  78. int iLen = sNameIn ? strlen(sNameIn) : 0;
  79. char* pEnd = sNameList + dwLeng;
  80. for (char* pName = sNameList; pName < pEnd; pName++)
  81. {
  82. if (memcmp(pName, sNameIn, iLen) == 0)
  83. {
  84. strcpy(m_sReadName, pName);
  85. return true;
  86. }
  87. pName += strlen(pName);
  88. }
  89. sprintf(m_sErrInfo, "PCSC SCardListReaders not fond");
  90. return false;
  91. }
  92. bool PcscCall::Close()
  93. {
  94. if (m_hCurCard)
  95. DicConnect();
  96. if (m_hContext > 0)
  97. {
  98. SCardCancel(m_hContext);
  99. SCardReleaseContext(m_hContext);
  100. m_hContext = 0;
  101. }
  102. m_sReadName[0] = 0;
  103. return false;
  104. }
  105. int PcscCall::GetState()
  106. {
  107. if (m_hContext == 0)
  108. {
  109. strcpy(m_sErrInfo, "PCSC not opened");
  110. return STATE_NO_READER;
  111. }
  112. long iRet = SCARD_S_SUCCESS;
  113. SCARD_READERSTATE ReaderState;
  114. ReaderState.szReader = m_sReadName;
  115. ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
  116. ReaderState.dwEventState = 0;
  117. DWORD Value_timeout = 0;
  118. DWORD ReaderCount = 1;
  119. iRet = SCardGetStatusChange(m_hContext, Value_timeout, &ReaderState, ReaderCount);
  120. if (iRet != SCARD_S_SUCCESS)
  121. {
  122. sprintf(m_sErrInfo, "PCSC SCardGetStatusChange %x", iRet);
  123. return STATE_ERROR;
  124. }
  125. if (ReaderState.cbAtr > 0)
  126. {
  127. return STATE_HAVE_CARD;
  128. }
  129. return STATE_NO_CARD;
  130. }
  131. bool PcscCall::Connect(char* sATR, int& iLen)
  132. {
  133. if (m_hContext == NULL)
  134. {
  135. strcpy(m_sErrInfo, "PCSC not opened");
  136. return STATE_NO_READER;
  137. }
  138. if (m_hCurCard)
  139. SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
  140. m_hCurCard = NULL;
  141. LONG iRet = SCardConnect(m_hContext, m_sReadName, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &m_hCurCard, &m_APrtocol);
  142. if (iRet != 0)
  143. {
  144. sprintf(m_sErrInfo, "PCSC SCardConnect %s %x", m_sReadName, iRet);
  145. return false;
  146. }
  147. ULONG dwState;
  148. char szReader[256] = {0};
  149. BYTE byData[256] = {0};
  150. ULONG iDataLen = 256;
  151. ULONG iReaderLen = 256;
  152. iRet = SCardStatus(m_hCurCard, szReader, &iReaderLen, &dwState, &m_APrtocol, byData, &iDataLen);
  153. if (iRet != SCARD_S_SUCCESS )
  154. {
  155. sprintf(m_sErrInfo, "PCSC SCardStatus %x", iRet);
  156. return false;
  157. }
  158. memcpy(sATR, byData, iDataLen);
  159. iLen = iDataLen;
  160. return true;
  161. }
  162. bool PcscCall::DicConnect()
  163. {
  164. if (m_hCurCard)
  165. SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
  166. m_hCurCard = NULL;
  167. return true;
  168. }
  169. int PcscCall::ChipIO(const char* sIn, char* sOut)
  170. {
  171. if (m_hCurCard == NULL)
  172. {
  173. strcpy(m_sErrInfo, "PCSC not connected");
  174. return STATE_NO_READER;
  175. }
  176. SCARD_IO_REQUEST pioSendRequest;
  177. pioSendRequest.dwProtocol = m_APrtocol;
  178. pioSendRequest.cbPciLength = sizeof(SCARD_IO_REQUEST);
  179. BYTE bSend[512], bRecv[512];
  180. ULONG iLen = ::HexStrToANSI(sIn, bSend);
  181. ULONG iRcv = 512;
  182. LONG iRet = SCardTransmit(m_hCurCard, &pioSendRequest, bSend, iLen, NULL, bRecv, &iRcv);
  183. if (iRet != SCARD_S_SUCCESS)
  184. {
  185. sprintf(m_sErrInfo, "PCSC SCardTransmit %x", iRet);
  186. return STATE_ERROR;
  187. }
  188. ::ANSIToHexStr(bRecv, iRcv, sOut);
  189. return 0;
  190. }
  191. int PcscCall::SendCMD(const char* sIn, char* sOut)
  192. {
  193. if (m_hContext == 0)
  194. {
  195. strcpy(m_sErrInfo, "PCSC not opened");
  196. return STATE_NO_READER;
  197. }
  198. if (m_hCurCard)
  199. SCardDisconnect(m_hCurCard, SCARD_UNPOWER_CARD);
  200. m_hCurCard = NULL;
  201. long iRet = SCARD_S_SUCCESS;
  202. SCARDHANDLE hCurCard = 0;
  203. ULONG dwOutProtocal = 0;
  204. iRet = SCardConnect(m_hContext, m_sReadName, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_UNDEFINED,&hCurCard, &dwOutProtocal);
  205. if (iRet != 0)
  206. {
  207. sprintf(m_sErrInfo, "PCSC SCardConnect %s %x", m_sReadName, iRet);
  208. return STATE_ERROR;
  209. }
  210. BYTE bSend[512], bRecv[512];
  211. ULONG iLen = ::HexStrToANSI(sIn, bSend);
  212. ULONG iRcv = 512;
  213. iRet = SCardControl(hCurCard, IOCTL_CCID_ESCAPE, bSend, iLen, bRecv, 512, &iRcv);
  214. if (iRet != SCARD_S_SUCCESS)
  215. {
  216. sprintf(m_sErrInfo, "PCSC SCardControl %s %x", m_sReadName, iRet);
  217. return STATE_ERROR;
  218. }
  219. ::ANSIToHexStr(bRecv, iRcv, sOut);
  220. iRet = SCardDisconnect(hCurCard, SCARD_LEAVE_CARD);
  221. if (iRet != SCARD_S_SUCCESS)
  222. {
  223. sprintf(m_sErrInfo, "PCSC SCardDisconnect %x", iRet);
  224. return STATE_ERROR;
  225. }
  226. return STATE_NO_CARD;
  227. }