// // Created by robin on 6/28/15. // #include #include #include #include "libpcsc_cpptools/ScReader.h" /*thread_local*/ LPSCARDCONTEXT ScReader::_context = nullptr; /*thread_local*/ LONG ScReader::_lastStaticResult = SCARD_S_SUCCESS; ScReader::~ScReader() { disconnect(); } bool ScReader::establishContext() { if (!freeContext()) return false; _context = new SCARDCONTEXT[1]; _lastStaticResult = SCardEstablishContext(SCARD_SCOPE_SYSTEM, nullptr, nullptr, _context); return _lastStaticResult == SCARD_S_SUCCESS; } bool ScReader::freeContext() { if (!_context) return true; _lastStaticResult = SCardReleaseContext(*_context); delete[] _context; _context = nullptr; return _lastStaticResult == SCARD_S_SUCCESS; } bool ScReader::connect(DWORD shareMode, DWORD protocols, DWORD disposition) { if (!disconnect(disposition)) return false; _card = new SCARDCONTEXT[1]; _proto = new DWORD[1]; _lastResult = SCardConnect(*_context, _name.c_str(), shareMode, protocols, _card, _proto); if (*_proto == SCARD_PROTOCOL_T0) _sendPci = *SCARD_PCI_T0; if (*_proto == SCARD_PROTOCOL_T1) _sendPci = *SCARD_PCI_T1; return _lastResult == SCARD_S_SUCCESS; } bool ScReader::disconnect(DWORD disposition) { if (!_card) return true; _lastResult = SCardDisconnect(*_card, disposition); delete[] _proto; _proto = nullptr; delete[] _card; _card = nullptr; return _lastResult == SCARD_S_SUCCESS; } std::shared_ptr ScReader::transmit(const ScCommand& command, DWORD size) { auto data = command.getData(); auto resBuffer = new BYTE[size]; _lastResult = SCardTransmit(*_card, &_sendPci, (BYTE*)data.data(), data.size(), nullptr, resBuffer, &size); if (_lastResult == SCARD_S_SUCCESS) return std::make_shared(std::string((char*)resBuffer, size)); return std::make_shared(""); } std::vector> ScReader::getReaders() { std::vector> readers; DWORD readerCount = SCARD_AUTOALLOCATE; LPTSTR readersNames = nullptr; _lastStaticResult = SCardListReaders(*_context, nullptr, (LPTSTR)&readersNames, &readerCount); if (_lastStaticResult == SCARD_S_SUCCESS) { LPTSTR reader = readersNames; while (*reader) { readers.push_back(std::make_shared(reader)); reader += strlen(reader) + 1; } } SCardFreeMemory(*_context, readersNames); return readers; } std::string ScReader::getAttribute(DWORD attr) { DWORD len = SCARD_AUTOALLOCATE; BYTE* data = nullptr; _lastResult = SCardGetAttrib(*_card, attr, (BYTE*)&data, &len); std::string str((char*)data, len); SCardFreeMemory(*_context, data); if (_lastResult == SCARD_S_SUCCESS) return str; return std::string(); }