You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScReader.cpp 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // Created by robin on 6/28/15.
  3. //
  4. #include <winscard.h>
  5. #include <vector>
  6. #include <string.h>
  7. #include "libpcsc_cpptools/ScReader.h"
  8. /*thread_local*/ LPSCARDCONTEXT ScReader::_context = nullptr;
  9. /*thread_local*/ LONG ScReader::_lastStaticResult = SCARD_S_SUCCESS;
  10. ScReader::~ScReader()
  11. {
  12. disconnect();
  13. }
  14. bool ScReader::establishContext()
  15. {
  16. if (!freeContext())
  17. return false;
  18. _context = new SCARDCONTEXT[1];
  19. _lastStaticResult = SCardEstablishContext(SCARD_SCOPE_SYSTEM, nullptr, nullptr, _context);
  20. return _lastStaticResult == SCARD_S_SUCCESS;
  21. }
  22. bool ScReader::freeContext()
  23. {
  24. if (!_context)
  25. return true;
  26. _lastStaticResult = SCardReleaseContext(*_context);
  27. delete[] _context;
  28. _context = nullptr;
  29. return _lastStaticResult == SCARD_S_SUCCESS;
  30. }
  31. bool ScReader::connect(DWORD shareMode, DWORD protocols, DWORD disposition)
  32. {
  33. if (!disconnect(disposition))
  34. return false;
  35. _card = new SCARDCONTEXT[1];
  36. _proto = new DWORD[1];
  37. _lastResult = SCardConnect(*_context, _name.c_str(), shareMode, protocols, _card, _proto);
  38. if (*_proto == SCARD_PROTOCOL_T0)
  39. _sendPci = *SCARD_PCI_T0;
  40. if (*_proto == SCARD_PROTOCOL_T1)
  41. _sendPci = *SCARD_PCI_T1;
  42. return _lastResult == SCARD_S_SUCCESS;
  43. }
  44. bool ScReader::disconnect(DWORD disposition)
  45. {
  46. if (!_card)
  47. return true;
  48. _lastResult = SCardDisconnect(*_card, disposition);
  49. delete[] _proto;
  50. _proto = nullptr;
  51. delete[] _card;
  52. _card = nullptr;
  53. return _lastResult == SCARD_S_SUCCESS;
  54. }
  55. std::shared_ptr<ScResult> ScReader::transmit(const ScCommand& command, DWORD size)
  56. {
  57. auto data = command.getData();
  58. auto resBuffer = new BYTE[size];
  59. _lastResult = SCardTransmit(*_card, &_sendPci, (BYTE*)data.data(), data.size(), nullptr, resBuffer, &size);
  60. if (_lastResult == SCARD_S_SUCCESS)
  61. return std::make_shared<ScResult>(std::string((char*)resBuffer, size));
  62. return std::make_shared<ScResult>("");
  63. }
  64. std::vector<std::shared_ptr<ScReader>> ScReader::getReaders()
  65. {
  66. std::vector<std::shared_ptr<ScReader>> readers;
  67. DWORD readerCount = SCARD_AUTOALLOCATE;
  68. LPTSTR readersNames = nullptr;
  69. _lastStaticResult = SCardListReaders(*_context, nullptr, (LPTSTR)&readersNames, &readerCount);
  70. if (_lastStaticResult == SCARD_S_SUCCESS)
  71. {
  72. LPTSTR reader = readersNames;
  73. while (*reader)
  74. {
  75. readers.push_back(std::make_shared<ScReader>(reader));
  76. reader += strlen(reader) + 1;
  77. }
  78. }
  79. SCardFreeMemory(*_context, readersNames);
  80. return readers;
  81. }
  82. std::string ScReader::getAttribute(DWORD attr)
  83. {
  84. DWORD len = SCARD_AUTOALLOCATE;
  85. BYTE* data = nullptr;
  86. _lastResult = SCardGetAttrib(*_card, attr, (BYTE*)&data, &len);
  87. std::string str((char*)data, len);
  88. SCardFreeMemory(*_context, data);
  89. if (_lastResult == SCARD_S_SUCCESS)
  90. return str;
  91. return std::string();
  92. }