From c2ba38a52460e51055333b68fd36c1ae282826ec Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 23 Sep 2016 14:29:44 +0200 Subject: [PATCH] Clean-up - New macros introduced to simplify dplhandle<> and handle<> inherited classes default/copying/moving constructors and assignment operators - com_obj and bstr are duplicetable now - dplhandle<> children changed to assign a handle from constructor, not duplicate - for compliance with assignment operator --- include/WinStd/COM.h | 90 ++++++++++--------- include/WinStd/Common.h | 97 +++++++++++++++++--- include/WinStd/Crypt.h | 192 +++------------------------------------- include/WinStd/EAP.h | 21 +---- include/WinStd/ETW.h | 10 ++- include/WinStd/Sec.h | 28 +++--- include/WinStd/WLAN.h | 39 +------- include/WinStd/Win.h | 117 ++++++------------------ 8 files changed, 203 insertions(+), 391 deletions(-) diff --git a/include/WinStd/COM.h b/include/WinStd/COM.h index 1d434baa..3654dddc 100644 --- a/include/WinStd/COM.h +++ b/include/WinStd/COM.h @@ -71,27 +71,11 @@ namespace winstd namespace winstd { template - class com_obj : public handle + class com_obj : public dplhandle { + DPLHANDLE_IMPL(com_obj) + public: - /// - /// Constructs a new class instance with the object set to NULL - /// - inline com_obj() : handle() - { - } - - - /// - /// Constructs a new class instance and appends an available object - /// - /// \param[in] h Initial object value - /// - inline com_obj(_In_opt_ handle_type h) : handle(h) - { - } - - /// /// Constructs a new object and creates a new class with it /// @@ -131,7 +115,7 @@ namespace winstd /// /// Queries the object for another interface /// - /// \sa [CoCreateInstance function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686615.aspx) + /// \sa [IUnknown::QueryInterface method](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682521.aspx) /// template HRESULT query_interface(_Out_ _Other **h) const @@ -141,6 +125,23 @@ namespace winstd return m_h->QueryInterface(__uuidof(_Other), (void**)h); } + + /// + /// Queries the object for another interface + /// + /// \sa [IUnknown::QueryInterface method](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682521.aspx) + /// + template + HRESULT query_interface(_Out_ com_obj<_Other> &h) const + { + assert(m_h); + _Other *_h; + HRESULT hr = m_h->QueryInterface(__uuidof(_Other), (void**)&_h); + if (SUCCEEDED(hr)) + h.attach(_h); + return hr; + } + protected: /// /// Releases the object. @@ -149,46 +150,51 @@ namespace winstd { m_h->Release(); } + + + /// + /// Duplicates the object. + /// + /// \param[in] h Object handle of existing object + /// + /// \return Duplicated object handle + /// + virtual handle_type duplicate_internal(_In_ handle_type h) const + { + h->AddRef(); + return h; + } }; - class WINSTD_API bstr : public handle + class WINSTD_API bstr : public dplhandle { + DPLHANDLE_IMPL(bstr) + public: - /// - /// Constructs null BSTR - /// - inline bstr() : handle() - { - } - - /// - /// Constructs BSTR from another - /// - inline bstr(_In_ const BSTR src) : handle(SysAllocStringLen(src, SysStringLen(src))) - { - } - /// /// Constructs BSTR from OLE string /// - inline bstr(_In_ LPCOLESTR src) : handle(SysAllocString(src)) + inline bstr(_In_ LPCOLESTR src) { + m_h = SysAllocString(src); } /// /// Constructs BSTR from OLE string with length /// - inline bstr(_In_ LPCOLESTR src, _In_ UINT len) : handle(SysAllocStringLen(src, len)) + inline bstr(_In_ LPCOLESTR src, _In_ UINT len) { + m_h = SysAllocStringLen(src, len); } /// /// Constructs BSTR from std::basic_string /// template - inline bstr(_In_ const std::basic_string &src) : handle(SysAllocStringLen(src.c_str(), (UINT)src.length())) + inline bstr(_In_ const std::basic_string &src) { + m_h = SysAllocStringLen(src.c_str(), (UINT)src.length()); } /// @@ -217,13 +223,13 @@ namespace winstd virtual void free_internal(); /// - /// Duplicates the certificate context + /// Duplicates the string /// - /// \param[in] h Object handle of existing certificate context + /// \param[in] h Existing string /// - /// \return Duplicated certificate context handle + /// \return Duplicated string /// - /// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx) + /// \sa [SysAllocString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458.aspx) /// virtual handle_type duplicate_internal(_In_ handle_type h) const; }; diff --git a/include/WinStd/Common.h b/include/WinStd/Common.h index ffd91125..ed1cbd44 100644 --- a/include/WinStd/Common.h +++ b/include/WinStd/Common.h @@ -38,6 +38,32 @@ #define _L(x) __L(x) #endif +// Macros for building default constructors and operators to prevent their auto-generation by compiler. +#define WINSTD_NONCOPYABLE(C) \ +private: \ + inline C (_In_ const C &h); \ + inline C& operator=(_In_ const C &h); + +#define HANDLE_IMPL(C) \ +public: \ + inline C ( ) { } \ + inline C (_In_ handle_type h) : handle( h ) { } \ + inline C (_Inout_ C &&h) : handle(std::move(h)) { } \ + inline C& operator=(_In_ handle_type h) { handle::operator=( h ); return *this; } \ + inline C& operator=(_Inout_ C &&h) { handle::operator=(std::move(h)); return *this; } \ +WINSTD_NONCOPYABLE(C) + +#define DPLHANDLE_IMPL(C) \ +public: \ + inline C ( ) { } \ + inline C (_In_ handle_type h) : dplhandle( h ) { } \ + inline C (_In_ const C &h) : dplhandle(duplicate_internal(h.m_h)) { } \ + inline C (_Inout_ C &&h) : dplhandle(std::move (h )) { } \ + inline C& operator=(_In_ handle_type h) { dplhandle::operator=( h ); return *this; } \ + inline C& operator=(_In_ const C &h) { dplhandle::operator=( h ); return *this; } \ + inline C& operator=(_Inout_ C &&h) { dplhandle::operator=(std::move(h)); return *this; } \ +private: + #include #include @@ -466,7 +492,7 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline handle(_Inout_ handle &&h) + inline handle(_Inout_ handle &&h) { // Transfer handle. m_h = h.m_h; @@ -479,6 +505,17 @@ namespace winstd handle& operator=(_In_ const handle &h); public: + /// + /// Attaches already available object handle. + /// + /// \param[in] h Object handle value + /// + inline handle& operator=(_In_ handle_type h) + { + attach(h); + return *this; + } + /// /// Move assignment /// @@ -683,22 +720,47 @@ namespace winstd { public: /// - /// Duplicates the object handle. + /// Initializes a new class instance with the object handle set to NULL. + /// + inline dplhandle() + { + } + + /// + /// Initializes a new class instance with an already available object handle. + /// + /// \param[in] h Initial object handle value + /// + inline dplhandle(_In_ handle_type h) : handle(h) + { + } + + /// + /// Copy constructor + /// + /// \param[inout] h A reference of another object + /// + inline dplhandle(_In_ const dplhandle &h) : handle(internal_duplicate(h.m_h)) + { + } + + /// + /// Move constructor + /// + /// \param[inout] h A rvalue reference of another object + /// + inline dplhandle(_Inout_ dplhandle &&h) : handle(std::move(h)) + { + } + + /// + /// Attaches already available object handle. /// /// \param[in] h Object handle value /// inline dplhandle& operator=(_In_ handle_type h) { - if (m_h != h) { - handle_type h_new = duplicate_internal(h); - if (h_new) { - if (m_h) - free_internal(); - - m_h = h_new; - } else if (h) - assert(0); // Could not duplicate the handle - } + handle::operator=(h); return *this; } @@ -722,6 +784,17 @@ namespace winstd return *this; } + /// + /// Moves the object. + /// + /// \param[inout] h A rvalue reference of another object + /// + inline dplhandle& operator=(_Inout_ dplhandle &&h) + { + handle::operator=(std::move(h)); + return *this; + } + /// /// Duplicates and returns a new object handle. /// diff --git a/include/WinStd/Crypt.h b/include/WinStd/Crypt.h index fb994451..93135e41 100644 --- a/include/WinStd/Crypt.h +++ b/include/WinStd/Crypt.h @@ -335,34 +335,9 @@ namespace winstd { class WINSTD_API cert_context : public dplhandle { + DPLHANDLE_IMPL(cert_context) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline cert_context() - { - } - - /// - /// Initializes a new class instance with the duplicated object handle. - /// - /// \param[in] h Initial object handle value - /// - inline cert_context(_In_ handle_type h) - { - m_h = duplicate_internal(h); - } - - /// - /// Initializes a new class instance as a duplicate of given class. - /// - /// \param[in] h Initial object - /// - inline cert_context(_In_ const cert_context &h) - { - m_h = duplicate_internal(h.m_h); - } - /// /// Destroys the certificate context. /// @@ -494,34 +469,9 @@ namespace winstd class WINSTD_API cert_chain_context : public dplhandle { + DPLHANDLE_IMPL(cert_chain_context) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline cert_chain_context() - { - } - - /// - /// Initializes a new class instance with the duplicated object handle. - /// - /// \param[in] h Initial object handle value - /// - inline cert_chain_context(_In_ handle_type h) - { - m_h = duplicate_internal(h); - } - - /// - /// Initializes a new class instance as a duplicate of given class. - /// - /// \param[in] h Initial object - /// - inline cert_chain_context(_In_ const cert_chain_context &h) - { - m_h = duplicate_internal(h.m_h); - } - /// /// Destroys the certificate chain context. /// @@ -571,26 +521,9 @@ namespace winstd class WINSTD_API cert_store : public handle { + HANDLE_IMPL(cert_store) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline cert_store() : handle() {} - - /// - /// Initializes a new class instance with an already available object handle. - /// - /// \param[in] h Initial object handle value - /// - inline cert_store(_In_opt_ handle_type h) : handle(h) {} - - /// - /// Move constructor - /// - /// \param[inout] h A rvalue reference of another object - /// - inline cert_store(_Inout_ cert_store &&h) : handle(std::move(h)) {} - /// /// Closes the certificate store. /// @@ -598,18 +531,6 @@ namespace winstd /// virtual ~cert_store(); - /// - /// Move assignment - /// - /// \param[inout] h A rvalue reference of another object - /// - cert_store& operator=(_Inout_ cert_store &&h) - { - if (this != std::addressof(h)) - *(handle*)this = std::move(h); - return *this; - } - /// /// Opens the certificate store. /// @@ -648,11 +569,6 @@ namespace winstd return false; } - private: - // This class is noncopyable. - cert_store(_In_ const cert_store &h); - cert_store& operator=(_In_ const cert_store &h); - protected: /// /// Closes the certificate store. @@ -665,26 +581,9 @@ namespace winstd class WINSTD_API crypt_prov : public handle { + HANDLE_IMPL(crypt_prov) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline crypt_prov() : handle() {} - - /// - /// Initializes a new class instance with an already available object handle. - /// - /// \param[in] h Initial object handle value - /// - inline crypt_prov(_In_opt_ handle_type h) : handle(h) {} - - /// - /// Move constructor - /// - /// \param[inout] h A rvalue reference of another object - /// - inline crypt_prov(_Inout_ crypt_prov &&h) : handle(std::move(h)) {} - /// /// Releases the cryptographic context. /// @@ -692,18 +591,6 @@ namespace winstd /// virtual ~crypt_prov(); - /// - /// Move assignment - /// - /// \param[inout] h A rvalue reference of another object - /// - crypt_prov& operator=(_Inout_ crypt_prov &&h) - { - if (this != std::addressof(h)) - *(handle*)this = std::move(h); - return *this; - } - /// /// Acquires the cryptographic context. /// @@ -723,11 +610,6 @@ namespace winstd return false; } - private: - // This class is noncopyable. - crypt_prov(_In_ const crypt_prov &h); - crypt_prov& operator=(_In_ const crypt_prov &h); - protected: /// /// Releases the cryptographic context. @@ -740,34 +622,9 @@ namespace winstd class WINSTD_API crypt_hash : public dplhandle { + DPLHANDLE_IMPL(crypt_hash) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline crypt_hash() - { - } - - /// - /// Initializes a new class instance with the duplicated object handle. - /// - /// \param[in] h Initial object handle value - /// - inline crypt_hash(_In_ handle_type h) - { - m_h = duplicate_internal(h); - } - - /// - /// Initializes a new class instance as a duplicate of given class. - /// - /// \param[in] h Initial object - /// - inline crypt_hash(_In_ const crypt_hash &h) - { - m_h = duplicate_internal(h.m_h); - } - /// /// Destroys the hash context. /// @@ -817,34 +674,9 @@ namespace winstd class WINSTD_API crypt_key : public dplhandle { + DPLHANDLE_IMPL(crypt_key) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline crypt_key() - { - } - - /// - /// Initializes a new class instance with the duplicated object handle. - /// - /// \param[in] h Initial object handle value - /// - inline crypt_key(_In_ handle_type h) - { - m_h = duplicate_internal(h); - } - - /// - /// Initializes a new class instance as a duplicate of given class. - /// - /// \param[in] h Initial object - /// - inline crypt_key(_In_ const crypt_key &h) - { - m_h = duplicate_internal(h.m_h); - } - /// /// Destroys the key. /// diff --git a/include/WinStd/EAP.h b/include/WinStd/EAP.h index cd72193d..6f6aaaa3 100644 --- a/include/WinStd/EAP.h +++ b/include/WinStd/EAP.h @@ -243,26 +243,9 @@ namespace winstd class WINSTD_API eap_packet : public dplhandle { + DPLHANDLE_IMPL(eap_packet) + public: - /// - /// Initializes a new class instance with the EAP packet set to NULL. - /// - inline eap_packet() - { - } - - - /// - /// Initializes a new class instance with the duplicated EAP packet. - /// - /// \param[in] h Initial EAP packet value - /// - inline eap_packet(_In_ handle_type h) - { - m_h = duplicate_internal(h); - } - - /// /// Destroys the EAP packet. /// diff --git a/include/WinStd/ETW.h b/include/WinStd/ETW.h index 3e8e2dfe..a40cb53a 100644 --- a/include/WinStd/ETW.h +++ b/include/WinStd/ETW.h @@ -369,6 +369,8 @@ namespace winstd class WINSTD_API event_provider : public handle { + HANDLE_IMPL(event_provider) + public: /// /// Closes the event provider. @@ -545,6 +547,8 @@ namespace winstd class WINSTD_API event_session : public handle { + WINSTD_NONCOPYABLE(event_session) + public: /// /// Initializes a new empty session. @@ -553,6 +557,7 @@ namespace winstd { } + /// /// Initializes a new session with an already available object handle. /// @@ -566,6 +571,7 @@ namespace winstd memcpy(m_prop.get(), prop, prop->Wnode.BufferSize); } + /// /// Move constructor /// @@ -589,7 +595,7 @@ namespace winstd /// /// Move assignment /// - /// \param[inout] other A rvalue reference of another session + /// \param[inout] other A rvalue reference of another object /// inline event_session& operator=(_Inout_ event_session &&other) { @@ -725,6 +731,8 @@ namespace winstd class WINSTD_API event_trace : public handle { + HANDLE_IMPL(event_trace) + public: /// /// Closes the trace. diff --git a/include/WinStd/Sec.h b/include/WinStd/Sec.h index 08244337..b685c769 100644 --- a/include/WinStd/Sec.h +++ b/include/WinStd/Sec.h @@ -91,15 +91,29 @@ namespace winstd { class WINSTD_API sec_credentials : public handle { + WINSTD_NONCOPYABLE(sec_credentials) + public: /// /// Initializes a new class instance with the object handle set to NULL. /// - inline sec_credentials() : handle() + inline sec_credentials() { m_expires.QuadPart = -1; } + /// + /// Initializes a new class with an already available object handle. + /// + /// \param[in] h Initial class handle value + /// \param[in] prop Credentials expiration + /// + inline sec_credentials(_In_opt_ handle_type h, _In_ const TimeStamp expires) : + m_expires(expires), + handle(h) + { + } + /// /// Move constructor /// @@ -127,7 +141,7 @@ namespace winstd { if (this != std::addressof(h)) { *(handle*)this = std::move(h); - m_expires = std::move(h.m_expires); + m_expires = std::move(h.m_expires); } return *this; } @@ -169,11 +183,6 @@ namespace winstd /// virtual void free_internal(); - private: - // This class is noncopyable. - sec_credentials(_In_ const sec_credentials &h); - sec_credentials& operator=(_In_ const sec_credentials &h); - public: TimeStamp m_expires; ///< Credentials expiration time }; @@ -284,11 +293,6 @@ namespace winstd /// virtual void free_internal(); - private: - // This class is noncopyable. - sec_context(_In_ const sec_context &h); - sec_context& operator=(_In_ const sec_context &h); - public: ULONG m_attrib; ///< Context attributes TimeStamp m_expires; ///< Context expiration time diff --git a/include/WinStd/WLAN.h b/include/WinStd/WLAN.h index 6920323f..92947336 100644 --- a/include/WinStd/WLAN.h +++ b/include/WinStd/WLAN.h @@ -123,26 +123,9 @@ namespace winstd class WINSTD_API wlan_handle : public handle { + HANDLE_IMPL(wlan_handle) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline wlan_handle() : handle() {} - - /// - /// Initializes a new class instance with an already available object handle. - /// - /// \param[in] h Initial object handle value - /// - inline wlan_handle(_In_opt_ handle_type h) : handle(h) {} - - /// - /// Move constructor - /// - /// \param[inout] h A rvalue reference of another object - /// - inline wlan_handle(_Inout_ wlan_handle &&h) : handle(std::move(h)) {} - /// /// Closes a connection to the server. /// @@ -150,18 +133,6 @@ namespace winstd /// virtual ~wlan_handle(); - /// - /// Move assignment - /// - /// \param[inout] h A rvalue reference of another object - /// - wlan_handle& operator=(_Inout_ wlan_handle &&h) - { - if (this != std::addressof(h)) - *(handle*)this = std::move(h); - return *this; - } - /// /// Opens a connection to the server. /// @@ -184,12 +155,6 @@ namespace winstd } } - - private: - // This class is noncopyable. - wlan_handle(_In_ const wlan_handle &h); - wlan_handle& operator=(_In_ const wlan_handle &h); - protected: /// /// Closes a connection to the server. diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index 1ce48c2b..fcf00cce 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -344,26 +344,9 @@ namespace winstd { class WINSTD_API win_handle : public handle { + HANDLE_IMPL(win_handle) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline win_handle() : handle() {} - - /// - /// Initializes a new class instance with an already available object handle. - /// - /// \param[in] h Initial object handle value - /// - inline win_handle(_In_opt_ handle_type h) : handle(h) {} - - /// - /// Move constructor - /// - /// \param[inout] h A rvalue reference of another object - /// - inline win_handle(_Inout_ win_handle &&h) : handle(std::move(h)) {} - /// /// Closes an open object handle. /// @@ -371,23 +354,6 @@ namespace winstd /// virtual ~win_handle(); - /// - /// Move assignment - /// - /// \param[inout] h A rvalue reference of another object - /// - win_handle& operator=(_Inout_ win_handle &&h) - { - if (this != std::addressof(h)) - *(handle*)this = std::move(h); - return *this; - } - - private: - // This class is noncopyable. - win_handle(_In_ const win_handle &h); - win_handle& operator=(_In_ const win_handle &h); - protected: /// /// Closes an open object handle. @@ -400,6 +366,8 @@ namespace winstd class WINSTD_API library : public handle { + HANDLE_IMPL(library) + public: /// /// Frees the module. @@ -463,6 +431,8 @@ namespace winstd class WINSTD_API heap : public handle { + HANDLE_IMPL(heap) + public: /// /// Destroys the heap. @@ -559,13 +529,13 @@ namespace winstd class WINSTD_API vmemory : public handle { + WINSTD_NONCOPYABLE(vmemory) + public: /// /// Initializes a new class instance with the memory handle set to NULL. /// - inline vmemory() : - m_proc(NULL), - handle() + inline vmemory() : m_proc(NULL) { } @@ -575,7 +545,7 @@ namespace winstd /// \param[in] proc Handle of process the memory belongs to /// \param[in] h Initial object handle value /// - inline vmemory(_In_ HANDLE proc, _In_opt_ handle_type h) : + inline vmemory(_In_opt_ handle_type h, _In_ HANDLE proc) : m_proc(proc), handle(h) { @@ -586,14 +556,10 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline vmemory(_Inout_ vmemory &&h) + inline vmemory(_Inout_ vmemory &&h) : + m_proc(std::move(h.m_proc)), + handle(std::move(h)) { - // Transfer process. - m_proc = h.m_proc; - - // Transfer handle. - m_h = h.m_h; - h.m_h = NULL; } /// @@ -603,6 +569,20 @@ namespace winstd /// virtual ~vmemory(); + /// + /// Move assignment + /// + /// \param[inout] other A rvalue reference of another object + /// + inline vmemory& operator=(_Inout_ vmemory &&other) + { + if (this != std::addressof(other)) { + (handle&&)*this = std::move(other); + m_proc = std::move(other.m_proc); + } + return *this; + } + /// /// Sets a new memory handle for the class /// @@ -643,11 +623,6 @@ namespace winstd return false; } - private: - // This class is noncopyable. - vmemory(_In_ const vmemory &h); - vmemory& operator=(_In_ const vmemory &h); - protected: /// /// Frees the memory. @@ -663,26 +638,9 @@ namespace winstd class WINSTD_API reg_key : public handle { + HANDLE_IMPL(reg_key) + public: - /// - /// Initializes a new class instance with the object handle set to NULL. - /// - inline reg_key() : handle() {} - - /// - /// Initializes a new class instance with an already available object handle. - /// - /// \param[in] h Initial object handle value - /// - inline reg_key(_In_opt_ handle_type h) : handle(h) {} - - /// - /// Move constructor - /// - /// \param[inout] h A rvalue reference of another object - /// - inline reg_key(_Inout_ reg_key &&h) : handle(std::move(h)) {} - /// /// Closes a handle to the registry key. /// @@ -690,18 +648,6 @@ namespace winstd /// virtual ~reg_key(); - /// - /// Move assignment - /// - /// \param[inout] h A rvalue reference of another object - /// - reg_key& operator=(_Inout_ reg_key &&h) - { - if (this != std::addressof(h)) - *(handle*)this = std::move(h); - return *this; - } - /// /// Creates the specified registry key. If the key already exists, the function opens it. /// @@ -757,11 +703,6 @@ namespace winstd } } - private: - // This class is noncopyable. - reg_key(_In_ const reg_key &h); - reg_key& operator=(_In_ const reg_key &h); - protected: /// /// Closes a handle to the registry key.