|
|
|
@ -10,8 +10,10 @@ |
|
|
|
|
#ifndef PCSC_HXX |
|
|
|
|
#define PCSC_HXX |
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
|
|
#include "WinSCard.h" |
|
|
|
|
#include <WinSCard.h> |
|
|
|
|
#ifndef MAX_ATR_SIZE |
|
|
|
|
#define MAX_ATR_SIZE 33 |
|
|
|
|
#endif |
|
|
|
@ -41,7 +43,6 @@ namespace pcsc { |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <boost/shared_ptr.hpp> |
|
|
|
|
#include <string> |
|
|
|
|
#include <vector> |
|
|
|
|
#include <map> |
|
|
|
|
#include <memory> |
|
|
|
@ -69,8 +70,8 @@ namespace pcsc { |
|
|
|
|
std::string hex(const std::string& data) { |
|
|
|
|
std::stringstream res; |
|
|
|
|
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) |
|
|
|
|
res<<"(0x"<<std::hex<<std::setfill('0')<<std::setw(2) |
|
|
|
|
<<(unsigned int)(unsigned char)*it<<')'; |
|
|
|
|
res<<std::hex<<std::setfill('0')<<std::setw(2) |
|
|
|
|
<<(unsigned int)(unsigned char)*it; |
|
|
|
|
return res.str(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -189,7 +190,7 @@ namespace pcsc { |
|
|
|
|
|
|
|
|
|
//! Disconnects connection.
|
|
|
|
|
~Reader() { |
|
|
|
|
_state = SCardDisconnect(_id, SCARD_LEAVE_CARD); |
|
|
|
|
_state = SCardDisconnect(_id, SCARD_RESET_CARD); |
|
|
|
|
if (!std::uncaught_exception()) |
|
|
|
|
_connection.check("disconnect smartcard"); |
|
|
|
|
} |
|
|
|
@ -210,9 +211,11 @@ namespace pcsc { |
|
|
|
|
DWORD len(1024); // arbitrary
|
|
|
|
|
unsigned char buff[len]; |
|
|
|
|
SCARD_IO_REQUEST rPci; |
|
|
|
|
check(SCardTransmit(_id, pci(), |
|
|
|
|
rPci.dwProtocol = pci()->dwProtocol; |
|
|
|
|
rPci.cbPciLength = sizeof(rPci); |
|
|
|
|
check(SCardTransmit(_id, &rPci, |
|
|
|
|
(unsigned char*)in.c_str(), in.size(), |
|
|
|
|
&rPci, buff, &len), |
|
|
|
|
0, buff, &len), |
|
|
|
|
"smartcard transmit message "+hex(in)); |
|
|
|
|
return std::string((char*)buff, len); |
|
|
|
|
} |
|
|
|
@ -232,8 +235,8 @@ namespace pcsc { |
|
|
|
|
// 11 - Error
|
|
|
|
|
// So everything with Sev=00 is successful
|
|
|
|
|
// theoretically even with Sev=01, but that's still rejected
|
|
|
|
|
return (_state>>30&3)==0; |
|
|
|
|
//RETURN _STATE==SCARD_S_SUCCESS;
|
|
|
|
|
//return (_state>>30&3)==0;
|
|
|
|
|
return _state==SCARD_S_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//...........................................................variables
|
|
|
|
@ -282,11 +285,12 @@ namespace pcsc { |
|
|
|
|
friend class Connection; |
|
|
|
|
|
|
|
|
|
//! Establishes a connection to the given named cardreader
|
|
|
|
|
Reader(const std::string& nm, Connection& c): |
|
|
|
|
Reader(const std::string& nm, Connection& c, |
|
|
|
|
DWORD mode=SCARD_SHARE_SHARED, |
|
|
|
|
DWORD protocol=SCARD_PROTOCOL_T1): |
|
|
|
|
name(nm), _connection(c) { |
|
|
|
|
check(SCardConnect(_connection._id, strconv(name).c_str(), |
|
|
|
|
SCARD_SHARE_SHARED, |
|
|
|
|
SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, |
|
|
|
|
mode, protocol, |
|
|
|
|
&_id, &_protocol), |
|
|
|
|
"connect smartcard \""+name+"\""); |
|
|
|
|
} |
|
|
|
@ -347,7 +351,7 @@ namespace pcsc { |
|
|
|
|
- @c true: class throws exceptions in case of an error |
|
|
|
|
- @c false: no exceptions, check your instance after each |
|
|
|
|
operation */ |
|
|
|
|
Connection(Scope s=SYSTEM, bool exceptions=true): |
|
|
|
|
Connection(Scope s=USER, bool exceptions=true): |
|
|
|
|
_exc(exceptions), _id(0), |
|
|
|
|
_state(SCardEstablishContext(s, 0, 0, &_id)) { |
|
|
|
|
check("establish smartcard context"); |
|
|
|
@ -395,8 +399,8 @@ namespace pcsc { |
|
|
|
|
|
|
|
|
|
//! @c false if last operation was not successful
|
|
|
|
|
operator bool() const { |
|
|
|
|
return (_state>>30&3)==0; |
|
|
|
|
//return _state==SCARD_S_SUCCESS;
|
|
|
|
|
//return (_state>>30&3)==0;
|
|
|
|
|
return _state==SCARD_S_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Get the describing text of the last error
|
|
|
|
|