|
|
|
@ -21,10 +21,10 @@ |
|
|
|
|
#endif |
|
|
|
|
namespace pcsc { |
|
|
|
|
//! stupid windows needs std::wstring
|
|
|
|
|
std::wstring strconv(std::string s) { |
|
|
|
|
inline std::wstring strconv(std::string s) { |
|
|
|
|
return std::wstring(s.begin(), s.end()); |
|
|
|
|
} |
|
|
|
|
std::string strconv(std::wstring s) { |
|
|
|
|
inline std::string strconv(std::wstring s) { |
|
|
|
|
return std::string(s.begin(), s.end()); |
|
|
|
|
} |
|
|
|
|
typedef wchar_t char_t; |
|
|
|
@ -35,7 +35,7 @@ |
|
|
|
|
#include <PCSC/wintypes.h> |
|
|
|
|
#include <PCSC/winscard.h> |
|
|
|
|
namespace pcsc { |
|
|
|
|
const std::string& strconv(const std::string& s) { |
|
|
|
|
inline const std::string& strconv(const std::string& s) { |
|
|
|
|
return s; |
|
|
|
|
} |
|
|
|
|
typedef char char_t; |
|
|
|
@ -104,6 +104,12 @@ namespace pcsc { |
|
|
|
|
exception("smardcard access error:\n"+reason) { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
class runtime_error: public exception { |
|
|
|
|
public: |
|
|
|
|
runtime_error(const std::string& reason, const std::string& data) throw(): |
|
|
|
|
exception("runtime error,\n"+reason+":\n"+crypto::hex(data)) {} |
|
|
|
|
}; |
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
//! @addtogroup pcsclib
|
|
|
|
@ -175,22 +181,9 @@ namespace pcsc { |
|
|
|
|
//! State and attribute list of a reader.
|
|
|
|
|
class Status { |
|
|
|
|
public: |
|
|
|
|
Status(unsigned long s, const std::vector<unsigned char>& attrs): |
|
|
|
|
state(s), attr(attrs) { |
|
|
|
|
} |
|
|
|
|
Status(unsigned long s, const std::string& attrs): |
|
|
|
|
state(s), attr(convert(attrs)) { |
|
|
|
|
} |
|
|
|
|
Status(unsigned long s, const std::string& a): state(s), atr(a) {} |
|
|
|
|
const unsigned long state; |
|
|
|
|
const std::vector<unsigned char> attr; |
|
|
|
|
private: |
|
|
|
|
static std::vector<unsigned char> convert(const std::string& a) { |
|
|
|
|
std::vector<unsigned char> res; |
|
|
|
|
for (std::string::const_iterator it(a.begin()); |
|
|
|
|
it!=a.end(); ++it) |
|
|
|
|
res.push_back(*it); |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
const std::string atr; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//.............................................................methods
|
|
|
|
@ -215,6 +208,54 @@ namespace pcsc { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Transmit data to reader.
|
|
|
|
|
/*! @note Take care: Stings may contain embedded @c 0. */ |
|
|
|
|
std::string transmit(char cla, char ins, char p1, char p2, |
|
|
|
|
const std::string& lc = std::string(), |
|
|
|
|
unsigned char le = 253) { |
|
|
|
|
std::string claInsP1P2; |
|
|
|
|
claInsP1P2.push_back(cla); |
|
|
|
|
claInsP1P2.push_back(ins); |
|
|
|
|
claInsP1P2.push_back(p1); |
|
|
|
|
claInsP1P2.push_back(p2); |
|
|
|
|
assert(claInsP1P2.size()==4); |
|
|
|
|
return transmit(claInsP1P2, lc, le); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Transmit data to reader.
|
|
|
|
|
/*! @note Take care: Stings may contain embedded @c 0. */ |
|
|
|
|
std::string transmit(char cla, char ins, char p1, char p2, |
|
|
|
|
const char* lc, int len, |
|
|
|
|
unsigned char le = 253) { |
|
|
|
|
std::string claInsP1P2; |
|
|
|
|
claInsP1P2.push_back(cla); |
|
|
|
|
claInsP1P2.push_back(ins); |
|
|
|
|
claInsP1P2.push_back(p1); |
|
|
|
|
claInsP1P2.push_back(p2); |
|
|
|
|
assert(claInsP1P2.size()==4); |
|
|
|
|
return transmit(claInsP1P2, std::string(lc, len), le); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Transmit data to reader.
|
|
|
|
|
/*! @note Take care: Stings may contain embedded @c 0.
|
|
|
|
|
@note Prefer the transmit methods that passes @c cla, @c |
|
|
|
|
ins, @c p1 and @c p2 separate.*/ |
|
|
|
|
std::string transmit(const std::string& claInsP1P2, |
|
|
|
|
const std::string& lc, |
|
|
|
|
unsigned char le = 253) { |
|
|
|
|
if (claInsP1P2.size()!=4) |
|
|
|
|
throw runtime_error("transmit: claInsP1P2 must be 4 byte", |
|
|
|
|
claInsP1P2); |
|
|
|
|
if (lc.size()>255) throw runtime_error("transmit: lc too long", lc); |
|
|
|
|
std::string msg(claInsP1P2); |
|
|
|
|
if (lc.size()) (msg+=(char)lc.size())+=lc; |
|
|
|
|
msg+=le; |
|
|
|
|
return transmit(msg); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Transmit data to reader.
|
|
|
|
|
/*! @note Take care: Stings may contain embedded @c 0.
|
|
|
|
|
@note Prefer the transmit methods that passes @c cla, @c |
|
|
|
|
ins, @c p1 and @c p2 separate.*/ |
|
|
|
|
std::string transmit(std::string in) { |
|
|
|
|
DWORD len(1024); // arbitrary
|
|
|
|
|
unsigned char buff[len]; |
|
|
|
@ -300,7 +341,7 @@ namespace pcsc { |
|
|
|
|
check(SCardConnect(_connection._id, strconv(name).c_str(), |
|
|
|
|
mode, protocol, |
|
|
|
|
&_id, &_protocol), |
|
|
|
|
"connect smartcard \""+name+"\" ("+crypto::hex(name)+")"); |
|
|
|
|
"connect smartcard \""+name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! forbidden
|
|
|
|
|