diff --git a/src/cryptoki.hxx b/src/cryptoki.hxx index 7391c2f..933bf41 100644 --- a/src/cryptoki.hxx +++ b/src/cryptoki.hxx @@ -86,119 +86,6 @@ namespace pcsc { //! @see gcryptoki namespace cryptoki { - //! @todo copy in own library - /*! Inherit from SmartResource, - and overwrite free(). You must call destruct() in your destructor. */ - class SmartResource { - public: - SmartResource(): _cnt(0), _destructed(false) { - incr(); - } - //! must be called in copy constructor of children! - SmartResource(const SmartResource& o): _cnt(o._cnt), _destructed(false) { - incr(); - } - ~SmartResource() { - assert(_destructed); // child must call destruct() in destructor - } - //! must be called in assignment constructor of children! - SmartResource& operator=(const SmartResource& o) { - decr(); - _cnt = o._cnt; - incr(); - return *this; - } - protected: - //! Overwrite to free your resource. - virtual void free() = 0; - //! You must call it in your destructor! - void destruct() { - if (_destructed) return; // only once - decr(); - _destructed = true; - } - //! Seldom needed, mostly automatic. - void incr() { - if (!_cnt) _cnt = new unsigned int(0); - ++*_cnt; - assert(_cnt); - } - //! Seldom needed, mostly automatic. - void decr() { - if (!_cnt || --*_cnt) return; - delete _cnt; _cnt = 0; - free(); - } - //! Seldom needed, mostly automatic. - /*! Used in complete reassign of resource from outside. - Call incr() after assignment. */ - void clear() { - decr(); - _cnt = 0; - } - //! Reads the internal counter (for testing and debugging only); - int cnt() { - assert(_cnt); - return *_cnt; - } - private: - unsigned int *_cnt; - bool _destructed; - }; - - template class SharedPointer: public SmartResource { - public: - SharedPointer(): _p(0) {} - SharedPointer(const SharedPointer& o): SmartResource(o), _p(o._p) {} - SharedPointer(T* p): _p(p) {} - SharedPointer& operator=(const SharedPointer& o) { - return reset(o); - } - SharedPointer& operator=(T* p) { - return reset(p); - } - ~SharedPointer() { - destruct(); - } - T* const operator->() { - return get(); - } - const T* const operator->() const { - return get(); - } - const T& operator*() const { - return *get(); - } - T& operator*() { - return *get(); - } - SharedPointer& reset(const SharedPointer& o) { - SmartResource::operator=(o); - _p = o._p; - return *this; - } - SharedPointer& reset(T* p = 0) { - clear(); - _p = p; - incr(); - return *this; - } - const T* const get() const { - assert(_p); - return _p; - } - T* const get() { - assert(_p); - return _p; - } - protected: - void free() { - delete _p; _p=0; - } - private: - T* _p; - }; - //! @addtogroup cryptokitypes //@{ @@ -1000,7 +887,7 @@ namespace cryptoki { //! Session Management //! Not implemented: CK_RV C_CloseAllSessions(CK_SLOT_ID); - class Session: public SmartResource { + class Session { private: friend class Login; @@ -1015,6 +902,9 @@ namespace cryptoki { CK_RV _res; Session(); // forbidden + Session(const Session& o); // no-copy + Session& operator=(const Session& o); // no-copy + bool check(CK_RV result, const std::string& context="") { CRYPTOKI_LOG("log"); @@ -1026,26 +916,31 @@ namespace cryptoki { throw access_error(error()); return _res==CKR_OK; } - + void free() { CRYPTOKI_LOG("log"); try { //! closes login. - _login.reset(); + logout(); + } catch (...) { // still try to close session //! calls @c C_CloseSession - check(_slot._init->_fn->C_CloseSession(_session), - CRYPTOKI_FN_LOG("C_CloseSession")); - } catch (...) { - if (!std::uncaught_exception()) throw; + try { + check(_slot._init->_fn->C_CloseSession(_session), + CRYPTOKI_FN_LOG("C_CloseSession")); + } catch (...) {} // only report first problem + throw; } + //! calls @c C_CloseSession + check(_slot._init->_fn->C_CloseSession(_session), + CRYPTOKI_FN_LOG("C_CloseSession")); } - + public: //! Opens a new session. /*! @param slot slot to open a session on */ Session(Slot& slot, bool rw=false): - _slot(slot), _session(0), _res(CKR_OK) { + _slot(slot), _session(0), _res(CKR_OK), _login(0) { CRYPTOKI_LOG("log"); //! calls @c C_OpenSession check(_slot._init->_fn->C_OpenSession @@ -1055,25 +950,13 @@ namespace cryptoki { //! @todo pass parameter } - Session(const Session& o): - SmartResource(o), - _slot(o._slot), _session(o._session), _res(o._res) { + ~Session() try { CRYPTOKI_LOG("log"); - } - - ~Session() { - CRYPTOKI_LOG("log"); - destruct(); + free(); + } catch (...) { + if (!std::uncaught_exception()) throw; } - Session& operator=(const Session& o) { - CRYPTOKI_LOG("log"); - SmartResource::operator=(o); - _slot = o._slot; - _session = o._session; - _res = o._res; - } - /*! @name Comfortable Access Use these methods in favour of the Low Level Cryptoki @@ -1310,13 +1193,22 @@ namespace cryptoki { void login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) { CRYPTOKI_LOG("log"); - _login = SharedPointer(new Login(*this, pin, userType)); + delete _login; + _login = new Login(*this, pin, userType); } + void logout() { CRYPTOKI_LOG("log"); - _login.reset(); + try { + delete _login; + _login = 0; + } catch (...) { + _login = 0; + throw; + } } - SharedPointer _login; + + Login* _login; /*! @todo Not implemented: @code @@ -1458,7 +1350,7 @@ namespace cryptoki { friend class Session; CK_OBJECT_HANDLE _object; - Session _session; + Session& _session; CK_RV _res; bool check(CK_RV result, const std::string& context="") { @@ -1472,11 +1364,9 @@ namespace cryptoki { return _res==CKR_OK; } - Object() { - CRYPTOKI_LOG("log"); - } + Object(); // forbidden - Object(const Session& session, CK_OBJECT_HANDLE obj): + Object(Session& session, CK_OBJECT_HANDLE obj): _session(session), _object(obj), _res(CKR_OK) { CRYPTOKI_LOG("log"); } diff --git a/src/pcsc.hxx b/src/pcsc.hxx index d8362d9..4e32906 100644 --- a/src/pcsc.hxx +++ b/src/pcsc.hxx @@ -192,7 +192,7 @@ namespace pcsc { } //! Cancels the transaction if not yet finished. ~Transaction() try { - if (_running) cancel(); + cancel(); } catch (...) { if (!std::uncaught_exception()) throw; }