- 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
This commit is contained in:
Simon Rozman 2016-09-23 14:29:44 +02:00
parent 8a77220475
commit c2ba38a524
8 changed files with 203 additions and 391 deletions

View File

@ -71,27 +71,11 @@ namespace winstd
namespace winstd
{
template <class T>
class com_obj : public handle<T*>
class com_obj : public dplhandle<T*>
{
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 <class _Other>
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 <class _Other>
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<BSTR>
class WINSTD_API bstr : public dplhandle<BSTR>
{
DPLHANDLE_IMPL(bstr)
public:
///
/// Constructs null BSTR
///
inline bstr() : handle<BSTR>()
{
}
///
/// Constructs BSTR from another
///
inline bstr(_In_ const BSTR src) : handle<BSTR>(SysAllocStringLen(src, SysStringLen(src)))
{
}
///
/// Constructs BSTR from OLE string
///
inline bstr(_In_ LPCOLESTR src) : handle<BSTR>(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<BSTR>(SysAllocStringLen(src, len))
inline bstr(_In_ LPCOLESTR src, _In_ UINT len)
{
m_h = SysAllocStringLen(src, len);
}
///
/// Constructs BSTR from std::basic_string
///
template<class _Traits, class _Ax>
inline bstr(_In_ const std::basic_string<wchar_t, _Traits, _Ax> &src) : handle<BSTR>(SysAllocStringLen(src.c_str(), (UINT)src.length()))
inline bstr(_In_ const std::basic_string<wchar_t, _Traits, _Ax> &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;
};

View File

@ -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<handle_type>( h ) { } \
inline C (_Inout_ C &&h) : handle<handle_type>(std::move(h)) { } \
inline C& operator=(_In_ handle_type h) { handle<handle_type>::operator=( h ); return *this; } \
inline C& operator=(_Inout_ C &&h) { handle<handle_type>::operator=(std::move(h)); return *this; } \
WINSTD_NONCOPYABLE(C)
#define DPLHANDLE_IMPL(C) \
public: \
inline C ( ) { } \
inline C (_In_ handle_type h) : dplhandle<handle_type>( h ) { } \
inline C (_In_ const C &h) : dplhandle<handle_type>(duplicate_internal(h.m_h)) { } \
inline C (_Inout_ C &&h) : dplhandle<handle_type>(std::move (h )) { } \
inline C& operator=(_In_ handle_type h) { dplhandle<handle_type>::operator=( h ); return *this; } \
inline C& operator=(_In_ const C &h) { dplhandle<handle_type>::operator=( h ); return *this; } \
inline C& operator=(_Inout_ C &&h) { dplhandle<handle_type>::operator=(std::move(h)); return *this; } \
private:
#include <Windows.h>
#include <stdarg.h>
@ -466,7 +492,7 @@ namespace winstd
///
/// \param[inout] h A rvalue reference of another object
///
inline handle<handle_type>(_Inout_ handle<handle_type> &&h)
inline handle(_Inout_ handle<handle_type> &&h)
{
// Transfer handle.
m_h = h.m_h;
@ -479,6 +505,17 @@ namespace winstd
handle<handle_type>& operator=(_In_ const handle<handle_type> &h);
public:
///
/// Attaches already available object handle.
///
/// \param[in] h Object handle value
///
inline handle<handle_type>& 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<handle_type>(h)
{
}
///
/// Copy constructor
///
/// \param[inout] h A reference of another object
///
inline dplhandle<handle_type>(_In_ const dplhandle<handle_type> &h) : handle<handle_type>(internal_duplicate(h.m_h))
{
}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline dplhandle<handle_type>(_Inout_ dplhandle<handle_type> &&h) : handle<handle_type>(std::move(h))
{
}
///
/// Attaches already available object handle.
///
/// \param[in] h Object handle value
///
inline dplhandle<handle_type>& 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<handle_type>::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<handle_type>& operator=(_Inout_ dplhandle<handle_type> &&h)
{
handle<handle_type>::operator=(std::move(h));
return *this;
}
///
/// Duplicates and returns a new object handle.
///

View File

@ -335,34 +335,9 @@ namespace winstd
{
class WINSTD_API cert_context : public dplhandle<PCCERT_CONTEXT>
{
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<PCCERT_CHAIN_CONTEXT>
{
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<HCERTSTORE>
{
HANDLE_IMPL(cert_store)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline cert_store() : handle<HCERTSTORE>() {}
///
/// 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<HCERTSTORE>(h) {}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline cert_store(_Inout_ cert_store &&h) : handle<HCERTSTORE>(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<handle_type>*)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<HCRYPTPROV>
{
HANDLE_IMPL(crypt_prov)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline crypt_prov() : handle<HCRYPTPROV>() {}
///
/// 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<HCRYPTPROV>(h) {}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline crypt_prov(_Inout_ crypt_prov &&h) : handle<HCRYPTPROV>(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<handle_type>*)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<HCRYPTHASH>
{
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<HCRYPTKEY>
{
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.
///

View File

@ -243,26 +243,9 @@ namespace winstd
class WINSTD_API eap_packet : public dplhandle<EapPacket*>
{
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.
///

View File

@ -369,6 +369,8 @@ namespace winstd
class WINSTD_API event_provider : public handle<REGHANDLE>
{
HANDLE_IMPL(event_provider)
public:
///
/// Closes the event provider.
@ -545,6 +547,8 @@ namespace winstd
class WINSTD_API event_session : public handle<TRACEHANDLE>
{
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<TRACEHANDLE>
{
HANDLE_IMPL(event_trace)
public:
///
/// Closes the trace.

View File

@ -91,15 +91,29 @@ namespace winstd
{
class WINSTD_API sec_credentials : public handle<PCredHandle>
{
WINSTD_NONCOPYABLE(sec_credentials)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline sec_credentials() : handle<PCredHandle>()
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<handle_type>*)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

View File

@ -123,26 +123,9 @@ namespace winstd
class WINSTD_API wlan_handle : public handle<HANDLE>
{
HANDLE_IMPL(wlan_handle)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline wlan_handle() : 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<HANDLE>(h) {}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline wlan_handle(_Inout_ wlan_handle &&h) : handle<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<handle_type>*)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.

View File

@ -344,26 +344,9 @@ namespace winstd
{
class WINSTD_API win_handle : public handle<HANDLE>
{
HANDLE_IMPL(win_handle)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline win_handle() : 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<HANDLE>(h) {}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline win_handle(_Inout_ win_handle &&h) : handle<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<handle_type>*)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<HMODULE>
{
HANDLE_IMPL(library)
public:
///
/// Frees the module.
@ -463,6 +431,8 @@ namespace winstd
class WINSTD_API heap : public handle<HANDLE>
{
HANDLE_IMPL(heap)
public:
///
/// Destroys the heap.
@ -559,13 +529,13 @@ namespace winstd
class WINSTD_API vmemory : public handle<LPVOID>
{
WINSTD_NONCOPYABLE(vmemory)
public:
///
/// Initializes a new class instance with the memory handle set to NULL.
///
inline vmemory() :
m_proc(NULL),
handle<LPVOID>()
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<LPVOID>(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<LPVOID>(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<handle_type>&&)*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<HKEY>
{
HANDLE_IMPL(reg_key)
public:
///
/// Initializes a new class instance with the object handle set to NULL.
///
inline reg_key() : handle<HKEY>() {}
///
/// 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<HKEY>(h) {}
///
/// Move constructor
///
/// \param[inout] h A rvalue reference of another object
///
inline reg_key(_Inout_ reg_key &&h) : handle<HKEY>(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<handle_type>*)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.