From f47faea71bd5f0dec9b549a6ebd6f5a711b805c8 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 18 Jan 2019 14:47:33 +0100 Subject: [PATCH] Pull changes from downstream - Drop Visual Studio 2010 support - Update SAL - New and updated classes and templates - Copyright year update Signed-off-by: Simon Rozman --- .gitignore | 4 - WinStd-10.0.sln | 26 -- build/WinStd-10.0.vcxproj | 70 --- build/WinStd-10.0.vcxproj.filters | 92 ---- build/WinStd-15.0.vcxproj.filters | 12 + build/WinStd.props | 4 + include/WinStd/Base64.h | 6 +- include/WinStd/COM.h | 37 +- include/WinStd/Common.h | 242 ++++++++--- include/WinStd/Cred.h | 33 +- include/WinStd/Crypt.h | 67 ++- include/WinStd/EAP.h | 11 +- include/WinStd/ETW.h | 50 +-- include/WinStd/Hex.h | 4 +- include/WinStd/MSI.h | 46 +- include/WinStd/Sec.h | 18 +- include/WinStd/SetupAPI.h | 167 +++++++ include/WinStd/Shell.h | 10 +- include/WinStd/WLAN.h | 10 +- include/WinStd/Win.h | 697 ++++++++++++++++++++++++------ include/WinStd/WinSock2.h | 176 ++++++++ include/WinStd/WinTrust.h | 6 +- src/Base64.cpp | 2 +- src/COM.cpp | 4 +- src/Crypt.cpp | 24 +- src/EAP.cpp | 8 +- src/ETW.cpp | 8 +- src/Sec.cpp | 2 +- src/SetupAPI.cpp | 51 +++ src/StdAfx.cpp | 2 +- src/StdAfx.h | 6 +- src/WLAN.cpp | 6 +- src/Win.cpp | 83 +++- src/WinSock2.cpp | 42 ++ src/WinTrust.cpp | 2 +- 35 files changed, 1452 insertions(+), 576 deletions(-) delete mode 100644 WinStd-10.0.sln delete mode 100644 build/WinStd-10.0.vcxproj delete mode 100644 build/WinStd-10.0.vcxproj.filters create mode 100644 include/WinStd/SetupAPI.h create mode 100644 include/WinStd/WinSock2.h create mode 100644 src/SetupAPI.cpp create mode 100644 src/WinSock2.cpp diff --git a/.gitignore b/.gitignore index e87a9297..8fb1f80b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,2 @@ -/*.sdf -/*.suo -/*.opensdf /doc -/ipch /.vs diff --git a/WinStd-10.0.sln b/WinStd-10.0.sln deleted file mode 100644 index 7959f6f8..00000000 --- a/WinStd-10.0.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStd", "build\WinStd-10.0.vcxproj", "{47399D91-7EB9-41DE-B521-514BA5DB0C43}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|Win32.ActiveCfg = Debug|Win32 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|Win32.Build.0 = Debug|Win32 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|x64.ActiveCfg = Debug|x64 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|x64.Build.0 = Debug|x64 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|Win32.ActiveCfg = Release|Win32 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|Win32.Build.0 = Release|Win32 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|x64.ActiveCfg = Release|x64 - {47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/build/WinStd-10.0.vcxproj b/build/WinStd-10.0.vcxproj deleted file mode 100644 index d1530577..00000000 --- a/build/WinStd-10.0.vcxproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {47399D91-7EB9-41DE-B521-514BA5DB0C43} - WinStd - Win32Proj - WinStd - - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/build/WinStd-10.0.vcxproj.filters b/build/WinStd-10.0.vcxproj.filters deleted file mode 100644 index cbf838d0..00000000 --- a/build/WinStd-10.0.vcxproj.filters +++ /dev/null @@ -1,92 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/build/WinStd-15.0.vcxproj.filters b/build/WinStd-15.0.vcxproj.filters index cbf838d0..3d31fc8b 100644 --- a/build/WinStd-15.0.vcxproj.filters +++ b/build/WinStd-15.0.vcxproj.filters @@ -41,6 +41,12 @@ Source Files + + Source Files + + + Source Files + @@ -88,5 +94,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/build/WinStd.props b/build/WinStd.props index 65fbe029..c32fe0a0 100644 --- a/build/WinStd.props +++ b/build/WinStd.props @@ -27,10 +27,12 @@ + Create + @@ -45,8 +47,10 @@ + + diff --git a/include/WinStd/Base64.h b/include/WinStd/Base64.h index 596578e3..71235c65 100644 --- a/include/WinStd/Base64.h +++ b/include/WinStd/Base64.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -68,7 +68,7 @@ namespace winstd /// \param[in ] is_last Is this the last block of data? /// template - inline void encode(_Out_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true) + inline void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true) { assert(data || !size); @@ -200,7 +200,7 @@ namespace winstd /// \param[in ] size Length of `data` in bytes /// template - inline void decode(_Out_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size) + inline void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size) { is_last = false; diff --git a/include/WinStd/COM.h b/include/WinStd/COM.h index c6b632c4..d7a1e193 100644 --- a/include/WinStd/COM.h +++ b/include/WinStd/COM.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -30,6 +30,7 @@ namespace winstd { class WINSTD_API com_runtime_error; + struct WINSTD_API CoTaskMemFree_delete; template class com_obj; class WINSTD_API bstr; class WINSTD_API variant; @@ -62,7 +63,7 @@ namespace winstd /// \param[in] num COM error code /// \param[in] msg Error message /// - inline com_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg.c_str()) + inline com_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg) { } @@ -92,13 +93,35 @@ namespace winstd /// \addtogroup WinStdCOM /// @{ + /// + /// Deleter for unique_ptr using CoTaskMemFree + /// + struct WINSTD_API CoTaskMemFree_delete + { + /// + /// Default constructor + /// + CoTaskMemFree_delete() {} + + /// + /// Delete a pointer + /// + /// \sa [CoTaskMemFree function](https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cotaskmemfree) + /// + template + void operator()(_T *_Ptr) const + { + CoTaskMemFree(_Ptr); + } + }; + /// /// COM object wrapper template /// template - class com_obj : public dplhandle + class com_obj : public dplhandle { - DPLHANDLE_IMPL(com_obj) + DPLHANDLE_IMPL(com_obj, NULL) public: /// @@ -143,7 +166,7 @@ namespace winstd /// virtual ~com_obj() { - if (m_h) + if (m_h != invalid) m_h->Release(); } @@ -225,9 +248,9 @@ namespace winstd /// /// BSTR string wrapper /// - class WINSTD_API bstr : public dplhandle + class WINSTD_API bstr : public dplhandle { - DPLHANDLE_IMPL(bstr) + DPLHANDLE_IMPL(bstr, NULL) public: /// diff --git a/include/WinStd/Common.h b/include/WinStd/Common.h index 68bb7d85..6152ed4a 100644 --- a/include/WinStd/Common.h +++ b/include/WinStd/Common.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -46,6 +46,7 @@ #include +#include #include #include #include @@ -107,35 +108,80 @@ private: \ inline C (_In_ const C &h); \ inline C& operator=(_In_ const C &h); +/// +/// Declares a class as non-movable +/// +#define WINSTD_NONMOVABLE(C) \ +private: \ + inline C (_Inout_ C &&h); \ + inline C& operator=(_Inout_ C &&h); + /// @} + +/// \addtogroup WinStdStrFormat +/// @{ + +/// +/// LPTSTR printf/scanf format specifier +/// +#ifdef UNICODE +#define PRINTF_LPTSTR "ls" +#else +#define PRINTF_LPTSTR "s" +#endif + +/// +/// LPOLESTR printf/scanf format specifier +/// +#ifdef OLE2ANSI +#define PRINTF_LPOLESTR "hs" +#else +#define PRINTF_LPOLESTR "ls" +#endif + +#ifdef _UNICODE +#define _tcin (std::wcin ) +#define _tcout (std::wcout) +#define _tcerr (std::wcerr) +#define _tclog (std::wclog) +#else +#define _tcin (std::cin ) +#define _tcout (std::cout) +#define _tcerr (std::cerr) +#define _tclog (std::clog) +#endif + +/// @} + + /// \addtogroup WinStdSysHandles /// @{ /// /// Implements default constructors and operators to prevent their auto-generation by compiler. /// -#define HANDLE_IMPL(C) \ +#define HANDLE_IMPL(C, INVAL) \ public: \ - inline C ( ) { } \ - inline C (_In_ handle_type h) : handle( h ) { } \ - inline C (_Inout_ C &&h) noexcept : handle(std::move(h)) { } \ - inline C& operator=(_In_ handle_type h) { handle::operator=( h ); return *this; } \ - inline C& operator=(_Inout_ C &&h) noexcept { handle::operator=(std::move(h)); return *this; } \ + inline C ( ) { } \ + inline C (_In_ handle_type h) : handle( h ) { } \ + inline C (_Inout_ C &&h) noexcept : handle(std::move(h)) { } \ + inline C& operator=(_In_ handle_type h) { handle::operator=( h ); return *this; } \ + inline C& operator=(_Inout_ C &&h) noexcept { handle::operator=(std::move(h)); return *this; } \ WINSTD_NONCOPYABLE(C) /// /// Implements default constructors and operators to prevent their auto-generation by compiler. /// -#define DPLHANDLE_IMPL(C) \ +#define DPLHANDLE_IMPL(C, INVAL) \ 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) noexcept : 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) noexcept { dplhandle::operator=(std::move(h)); return *this; } \ + 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) noexcept : 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) noexcept { dplhandle::operator=(std::move(h)); return *this; } \ private: /// @} @@ -166,8 +212,8 @@ namespace winstd template struct LocalFree_delete<_Ty[]>; template> class ref_unique_ptr; template class ref_unique_ptr<_Ty[], _Dx>; - template class handle; - template class dplhandle; + template class handle; + template class dplhandle; template class vector_queue; template class num_runtime_error; class WINSTD_API win_runtime_error; @@ -262,6 +308,8 @@ namespace winstd /// @{ template class sanitizing_allocator; + template class __declspec(novtable) sanitizing_blob; + /// /// A sanitizing variant of std::string @@ -331,7 +379,7 @@ inline int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _ /// /// \returns Number of characters in result. /// -template inline int vsprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg); +template inline int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg); /// /// Formats string using `printf()`. @@ -341,27 +389,28 @@ template inline int vsprintf(_Out_ std::b /// /// \returns Number of characters in result. /// -template inline int sprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...); +template inline int sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...); /// /// Formats a message string. /// /// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx) /// -template inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Out_ std::basic_string &str, _In_opt_ va_list *Arguments); +template inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string &str, _In_opt_ va_list *Arguments); /// /// Formats a message string. /// /// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx) /// -template inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Out_ std::basic_string &str, _In_opt_ va_list *Arguments); +template inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string &str, _In_opt_ va_list *Arguments); /// @} #pragma once #include +#include #include #include @@ -610,7 +659,7 @@ namespace winstd /// /// It provides basic operators and methods common to all descendands of this class establishing a base to ease the replacement of native object handle type with classes in object-oriented approach. /// - template + template class handle { public: @@ -620,9 +669,14 @@ namespace winstd typedef T handle_type; /// - /// Initializes a new class instance with the object handle set to NULL. + /// Invalid handle value /// - inline handle() : m_h(NULL) + static const T invalid; + + /// + /// Initializes a new class instance with the object handle set to INVAL. + /// + inline handle() : m_h(invalid) { } @@ -640,17 +694,17 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline handle(_Inout_ handle &&h) noexcept + inline handle(_Inout_ handle &&h) noexcept { // Transfer handle. m_h = h.m_h; - h.m_h = NULL; + h.m_h = invalid; } private: // This class is noncopyable. - handle(_In_ const handle &h); - handle& operator=(_In_ const handle &h); + handle(_In_ const handle &h); + handle& operator=(_In_ const handle &h); public: /// @@ -658,7 +712,7 @@ namespace winstd /// /// \param[in] h Object handle value /// - inline handle& operator=(_In_ handle_type h) + inline handle& operator=(_In_ handle_type h) { attach(h); return *this; @@ -669,14 +723,14 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline handle& operator=(_Inout_ handle &&h) noexcept + inline handle& operator=(_Inout_ handle &&h) noexcept { if (this != std::addressof(h)) { // Transfer handle. - if (m_h) + if (m_h != invalid) free_internal(); m_h = h.m_h; - h.m_h = NULL; + h.m_h = invalid; } return *this; } @@ -698,7 +752,7 @@ namespace winstd /// inline handle_type*& operator*() const { - assert(m_h != NULL); + assert(m_h != invalid); return *m_h; } @@ -708,7 +762,7 @@ namespace winstd /// inline handle_type* operator&() { - assert(m_h == NULL); + assert(m_h == invalid); return &m_h; } @@ -719,20 +773,20 @@ namespace winstd /// inline handle_type operator->() const { - assert(m_h != NULL); + assert(m_h != invalid); return m_h; } /// - /// Tests if the object handle is NULL. + /// Tests if the object handle is INVAL. /// /// \return - /// - Non zero when object handle is NULL; + /// - Non zero when object handle is INVAL; /// - Zero otherwise. /// inline bool operator!() const { - return m_h == NULL; + return m_h == invalid; } /// @@ -816,13 +870,13 @@ namespace winstd /// /// Sets a new object handle for the class /// - /// When the current object handle of the class is non-NULL, the object is destroyed first. + /// When the current object handle of the class is non-INVAL, the object is destroyed first. /// /// \param[in] h New object handle /// - inline void attach(_In_ handle_type h) + inline void attach(_In_opt_ handle_type h) { - if (m_h) + if (m_h != invalid) free_internal(); m_h = h; } @@ -835,7 +889,7 @@ namespace winstd inline handle_type detach() { handle_type h = m_h; - m_h = NULL; + m_h = invalid; return h; } @@ -844,9 +898,9 @@ namespace winstd /// inline void free() { - if (m_h) { + if (m_h != invalid) { free_internal(); - m_h = NULL; + m_h = invalid; } } @@ -863,15 +917,19 @@ namespace winstd }; + template + const T handle::invalid = INVAL; + + /// /// Base abstract template class to support object handle keeping for objects that support handle duplication /// - template - class dplhandle : public handle + template + class dplhandle : public handle { public: /// - /// Initializes a new class instance with the object handle set to NULL. + /// Initializes a new class instance with the object handle set to INVAL. /// inline dplhandle() { @@ -882,7 +940,7 @@ namespace winstd /// /// \param[in] h Initial object handle value /// - inline dplhandle(_In_ handle_type h) : handle(h) + inline dplhandle(_In_ handle_type h) : handle(h) { } @@ -891,7 +949,7 @@ namespace winstd /// /// \param[inout] h A reference of another object /// - inline dplhandle(_In_ const dplhandle &h) : handle(internal_duplicate(h.m_h)) + inline dplhandle(_In_ const dplhandle &h) : handle(internal_duplicate(h.m_h)) { } @@ -900,7 +958,7 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline dplhandle(_Inout_ dplhandle &&h) noexcept : handle(std::move(h)) + inline dplhandle(_Inout_ dplhandle &&h) noexcept : handle(std::move(h)) { } @@ -909,9 +967,9 @@ namespace winstd /// /// \param[in] h Object handle value /// - inline dplhandle& operator=(_In_ handle_type h) + inline dplhandle& operator=(_In_ handle_type h) { - handle::operator=(h); + handle::operator=(h); return *this; } @@ -920,23 +978,23 @@ namespace winstd /// /// \param[in] h Object /// - inline dplhandle& operator=(_In_ const dplhandle &h) + inline dplhandle& operator=(_In_ const dplhandle &h) { if (this != std::addressof(h)) { - if (h.m_h) { + if (h.m_h != invalid) { handle_type h_new = duplicate_internal(h.m_h); - if (h_new) { - if (m_h) + if (h_new != invalid) { + if (m_h != invalid) free_internal(); m_h = h_new; } else assert(0); // Could not duplicate the handle } else { - if (m_h) + if (m_h != invalid) free_internal(); - m_h = NULL; + m_h = invalid; } } return *this; @@ -947,9 +1005,9 @@ namespace winstd /// /// \param[inout] h A rvalue reference of another object /// - inline dplhandle& operator=(_Inout_ dplhandle &&h) noexcept + inline dplhandle& operator=(_Inout_ dplhandle &&h) noexcept { - handle::operator=(std::move(h)); + handle::operator=(std::move(h)); return *this; } @@ -960,7 +1018,7 @@ namespace winstd /// inline handle_type duplicate() const { - return m_h ? duplicate_internal(m_h) : NULL; + return m_h != invalid ? duplicate_internal(m_h) : invalid; } /// @@ -974,10 +1032,10 @@ namespace winstd /// inline bool attach_duplicated(_In_ handle_type h) { - if (m_h) + if (m_h != invalid) free_internal(); - return h ? (m_h = duplicate_internal(h)) != NULL : (m_h = NULL, true); + return h != invalid ? (m_h = duplicate_internal(h)) != invalid : (m_h = invalid, true); } protected: @@ -1423,7 +1481,7 @@ namespace winstd /// inline num_runtime_error(_In_ error_type num, _In_ const std::string& msg) : m_num(num), - runtime_error(msg.c_str()) + runtime_error(msg) { } @@ -1494,7 +1552,7 @@ namespace winstd /// \param[in] num Windows error code /// \param[in] msg Error message /// - inline win_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg.c_str()) + inline win_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg) { } @@ -1515,7 +1573,7 @@ namespace winstd /// /// \param[in] msg Error message /// - inline win_runtime_error(_In_ const std::string& msg) : num_runtime_error(GetLastError(), msg.c_str()) + inline win_runtime_error(_In_ const std::string& msg) : num_runtime_error(GetLastError(), msg) { } @@ -1538,6 +1596,23 @@ namespace winstd inline win_runtime_error(const win_runtime_error &other) : num_runtime_error(other) { } + + + /// + /// Returns a user-readable Windows error message + /// + /// \sa [FormatMessage function](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-formatmessage) + /// + inline tstring msg(_In_opt_ DWORD dwLanguageId = 0) const + { + tstring str; + if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, m_num, dwLanguageId, str, NULL)) { + // Stock Windows error messages contain CRLF. Well... Trim all the trailing white space. + str.erase(str.find_last_not_of(_T(" \t\n\r\f\v")) + 1); + } else + sprintf(str, m_num >= 0x10000 ? _T("Error 0x%X") : _T("Error %u"), m_num); + return str; + } }; /// @} @@ -1868,6 +1943,33 @@ namespace winstd #pragma warning(pop) + /// + /// Sanitizing BLOB + /// + template + class __declspec(novtable) sanitizing_blob + { + public: + /// + /// Constructs uninitialized BLOB + /// + inline sanitizing_blob() + { + ZeroMemory(m_data, N); + } + + /// + /// Sanitizes BLOB + /// + inline ~sanitizing_blob() + { + SecureZeroMemory(m_data, N); + } + + public: + unsigned char m_data[N]; ///< BLOB data + }; + /// @} } @@ -1895,7 +1997,7 @@ inline int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _ template -inline int vsprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg) +inline int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg) { _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; @@ -1923,7 +2025,7 @@ inline int vsprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _P template -inline int sprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...) +inline int sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...) { va_list arg; va_start(arg, format); @@ -1934,7 +2036,7 @@ inline int sprintf(_Out_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Pr template -inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Out_ std::basic_string &str, _In_opt_ va_list *Arguments) +inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string &str, _In_opt_ va_list *Arguments) { std::unique_ptr > lpBuffer; DWORD dwResult = FormatMessageA(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast((LPSTR*)get_ptr(lpBuffer)), 0, Arguments); @@ -1945,7 +2047,7 @@ inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ D template -inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Out_ std::basic_string &str, _In_opt_ va_list *Arguments) +inline DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string &str, _In_opt_ va_list *Arguments) { std::unique_ptr > lpBuffer; DWORD dwResult = FormatMessageW(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast((LPWSTR*)get_ptr(lpBuffer)), 0, Arguments); diff --git a/include/WinStd/Cred.h b/include/WinStd/Cred.h index e6658660..6cb6d855 100644 --- a/include/WinStd/Cred.h +++ b/include/WinStd/Cred.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -44,27 +44,27 @@ namespace winstd /// /// \sa [CredEnumerate function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794.aspx) /// -inline BOOL CredEnumerate(_In_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Out_ std::unique_ptr > &cCredentials); +inline BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Inout_ std::unique_ptr > &cCredentials); /// @copydoc CredProtectW() -template inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType); +template inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType); /// /// Encrypts the specified credentials so that only the current security context can decrypt them. /// /// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx) /// -template inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType); +template inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType); /// @copydoc CredUnprotectW() -template inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials); +template inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials); /// /// Decrypts credentials that were previously encrypted by using the CredProtect function. /// /// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx) /// -template inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials); +template inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials); /// @} @@ -143,17 +143,20 @@ namespace winstd } -inline BOOL CredEnumerate(_In_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Out_ std::unique_ptr > &cCredentials) +inline BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Inout_ std::unique_ptr > &cCredentials) { - PCREDENTIAL *pCredentials = NULL; - BOOL bResult = CredEnumerate(Filter, Flags, Count, &pCredentials); - cCredentials.reset(pCredentials); - return bResult; + PCREDENTIAL *pCredentials; + if (CredEnumerate(Filter, Flags, Count, &pCredentials)) { + cCredentials.reset(pCredentials); + return TRUE; + } + + return FALSE; } template -inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType) +inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType) { _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(buf); @@ -177,7 +180,7 @@ inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWO template -inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType) +inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType) { _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(buf); @@ -201,7 +204,7 @@ inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DW template -inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials) +inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials) { _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(buf); @@ -225,7 +228,7 @@ inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredential template -inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials) +inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials) { _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(buf); diff --git a/include/WinStd/Crypt.h b/include/WinStd/Crypt.h index 4860b8c6..61d501ef 100644 --- a/include/WinStd/Crypt.h +++ b/include/WinStd/Crypt.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -45,35 +45,35 @@ namespace winstd /// @{ /// @copydoc CertGetNameStringW() -template inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString); +template inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sNameString); /// /// Obtains the subject or issuer name from a certificate [CERT_CONTEXT](https://msdn.microsoft.com/en-us/library/windows/desktop/aa377189.aspx) structure and stores it in a std::wstring string. /// /// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx) /// -template inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString); +template inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sNameString); /// /// Retrieves the information contained in an extended property of a certificate context. /// /// \sa [CertGetCertificateContextProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376079.aspx) /// -template inline BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData); +template inline BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Inout_ std::vector<_Ty, _Ax> &aData); /// /// Retrieves data that governs the operations of a hash object. The actual hash value can be retrieved by using this function. /// /// \sa [CryptGetHashParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379947.aspx) /// -template inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags); +template inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Inout_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags); /// /// Retrieves data that governs the operations of a key. /// /// \sa [CryptGetKeyParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379949.aspx) /// -template inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags); +template inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Inout_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags); /// /// Retrieves data that governs the operations of a key. @@ -87,7 +87,7 @@ template inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD d /// /// \sa [CryptExportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379931.aspx) /// -template inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData); +template inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData); /// /// Encrypts data. @@ -120,9 +120,9 @@ namespace winstd /// /// PCCERT_CONTEXT wrapper class /// - class WINSTD_API cert_context : public dplhandle + class WINSTD_API cert_context : public dplhandle { - DPLHANDLE_IMPL(cert_context) + DPLHANDLE_IMPL(cert_context, NULL) public: /// @@ -144,7 +144,7 @@ namespace winstd inline bool create(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) { handle_type h = CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -161,6 +161,7 @@ namespace winstd /// inline bool operator==(_In_ const handle_type &other) const { + // TODO: [Crypto] Make constant time. return m_h == other || m_h->cbCertEncoded == other->cbCertEncoded && memcmp(m_h->pbCertEncoded, other->pbCertEncoded, m_h->cbCertEncoded) == 0; @@ -189,6 +190,7 @@ namespace winstd /// inline bool operator<(_In_ const handle_type &other) const { + // TODO: [Crypto] Make constant time. int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min(m_h->cbCertEncoded, other->cbCertEncoded)); return r < 0 || r == 0 && m_h->cbCertEncoded < other->cbCertEncoded; } @@ -203,6 +205,7 @@ namespace winstd /// inline bool operator>(_In_ const handle_type &other) const { + // TODO: [Crypto] Make constant time. int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min(m_h->cbCertEncoded, other->cbCertEncoded)); return r > 0 || r == 0 && m_h->cbCertEncoded > other->cbCertEncoded; } @@ -257,9 +260,9 @@ namespace winstd /// /// PCCERT_CHAIN_CONTEXT wrapper class /// - class WINSTD_API cert_chain_context : public dplhandle + class WINSTD_API cert_chain_context : public dplhandle { - DPLHANDLE_IMPL(cert_chain_context) + DPLHANDLE_IMPL(cert_chain_context, NULL) public: /// @@ -312,9 +315,9 @@ namespace winstd /// /// HCERTSTORE wrapper class /// - class WINSTD_API cert_store : public handle + class WINSTD_API cert_store : public handle { - HANDLE_IMPL(cert_store) + HANDLE_IMPL(cert_store, NULL) public: /// @@ -336,7 +339,7 @@ namespace winstd inline bool create(_In_ LPCSTR lpszStoreProvider, _In_ DWORD dwEncodingType, _In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_ DWORD dwFlags, _In_opt_ const void *pvPara) { handle_type h = CertOpenStore(lpszStoreProvider, dwEncodingType, hCryptProv, dwFlags, pvPara); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -352,10 +355,10 @@ namespace winstd /// /// \sa [CertOpenSystemStore function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376560.aspx) /// - inline bool create(_In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_ LPCTSTR szSubsystemProtocol) + inline bool create(_In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_z_ LPCTSTR szSubsystemProtocol) { handle_type h = CertOpenSystemStore(hCryptProv, szSubsystemProtocol); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -375,9 +378,9 @@ namespace winstd /// /// HCRYPTPROV wrapper class /// - class WINSTD_API crypt_prov : public handle + class WINSTD_API crypt_prov : public handle { - HANDLE_IMPL(crypt_prov) + HANDLE_IMPL(crypt_prov, NULL) public: /// @@ -396,7 +399,7 @@ namespace winstd /// /// \sa [CryptAcquireContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886.aspx) /// - inline bool create(_In_opt_ LPCTSTR szContainer, _In_opt_ LPCTSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags = 0) + inline bool create(_In_opt_z_ LPCTSTR szContainer, _In_opt_z_ LPCTSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags = 0) { handle_type h; if (CryptAcquireContext(&h, szContainer, szProvider, dwProvType, dwFlags)) { @@ -419,9 +422,9 @@ namespace winstd /// /// HCRYPTHASH wrapper class /// - class WINSTD_API crypt_hash : public dplhandle + class WINSTD_API crypt_hash : public dplhandle { - DPLHANDLE_IMPL(crypt_hash) + DPLHANDLE_IMPL(crypt_hash, NULL) public: /// @@ -474,9 +477,9 @@ namespace winstd /// /// HCRYPTKEY wrapper class /// - class WINSTD_API crypt_key : public dplhandle + class WINSTD_API crypt_key : public dplhandle { - DPLHANDLE_IMPL(crypt_key) + DPLHANDLE_IMPL(crypt_key, NULL) public: /// @@ -698,7 +701,7 @@ namespace winstd template -inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString) +inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sNameString) { // Query the final string length first. DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); @@ -712,7 +715,7 @@ inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT template -inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sNameString) +inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sNameString) { // Query the final string length first. DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); @@ -726,7 +729,7 @@ inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT template -inline BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData) +inline BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Inout_ std::vector<_Ty, _Ax> &aData) { BYTE buf[WINSTD_STACK_BUFFER_BYTES]; DWORD dwSize = WINSTD_STACK_BUFFER_BYTES; @@ -742,13 +745,12 @@ inline BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertCo return TRUE; } - aData.clear(); return FALSE; } template -inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags) +inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Inout_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags) { BYTE buf[WINSTD_STACK_BUFFER_BYTES]; DWORD dwSize = WINSTD_STACK_BUFFER_BYTES; @@ -764,7 +766,6 @@ inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ s return TRUE; } - aData.clear(); return FALSE; } @@ -778,7 +779,7 @@ inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ T template -inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags) +inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Inout_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags) { BYTE buf[WINSTD_STACK_BUFFER_BYTES]; DWORD dwSize = WINSTD_STACK_BUFFER_BYTES; @@ -794,7 +795,6 @@ inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std: return TRUE; } - aData.clear(); return FALSE; } @@ -808,7 +808,7 @@ inline BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ T &d template -inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData) +inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData) { DWORD dwKeyBLOBSize = 0; @@ -818,7 +818,6 @@ inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWO return TRUE; } - aData.clear(); return FALSE; } diff --git a/include/WinStd/EAP.h b/include/WinStd/EAP.h index abc28145..e83e0f9d 100644 --- a/include/WinStd/EAP.h +++ b/include/WinStd/EAP.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -105,6 +105,7 @@ inline bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE #include #include #include +#include namespace winstd @@ -394,9 +395,9 @@ namespace winstd /// /// EapPacket wrapper class /// - class WINSTD_API eap_packet : public dplhandle + class WINSTD_API eap_packet : public dplhandle { - DPLHANDLE_IMPL(eap_packet) + DPLHANDLE_IMPL(eap_packet, NULL) public: /// @@ -423,7 +424,7 @@ namespace winstd assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B. handle_type h = (handle_type)HeapAlloc(GetProcessHeap(), 0, size); - if (h) { + if (h != NULL) { h->Code = (BYTE) code ; h->Id = id ; *(WORD*)h->Length = htons(size); @@ -442,7 +443,7 @@ namespace winstd /// inline WORD size() const { - return m_h ? ntohs(*(WORD*)m_h->Length) : 0; + return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0; } diff --git a/include/WinStd/ETW.h b/include/WinStd/ETW.h index 9102093b..090364a9 100644 --- a/include/WinStd/ETW.h +++ b/include/WinStd/ETW.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -55,21 +55,21 @@ namespace winstd /// /// \sa [TdhGetEventInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964840.aspx) /// -inline ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr &info); +inline ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _Inout_ std::unique_ptr &info); /// /// Retrieves information about the event map contained in the event. /// /// \sa [TdhGetEventMapInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964841.aspx) /// -inline ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Out_ std::unique_ptr &info); +inline ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr &info); /// /// Retrieves a property value from the event data. /// /// \sa [TdhGetProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964843.aspx) /// -template inline ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_ PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Out_ std::vector<_Ty, _Ax> &aData); +template inline ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_ PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData); /// @} @@ -381,9 +381,9 @@ namespace winstd /// /// ETW event provider /// - class WINSTD_API event_provider : public handle + class WINSTD_API event_provider : public handle { - HANDLE_IMPL(event_provider) + HANDLE_IMPL(event_provider, NULL) public: /// @@ -424,7 +424,7 @@ namespace winstd /// inline ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor) { - assert(m_h); + assert(m_h != invalid); return EventWrite(m_h, EventDescriptor, 0, NULL); } @@ -440,7 +440,7 @@ namespace winstd /// inline ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ ULONG UserDataCount = 0, _In_opt_count_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData = NULL) { - assert(m_h); + assert(m_h != invalid); return EventWrite(m_h, EventDescriptor, UserDataCount, UserData); } @@ -458,7 +458,7 @@ namespace winstd /// inline ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ const EVENT_DATA_DESCRIPTOR param1, ...) { - assert(m_h); + assert(m_h != invalid); // The first argument (param1) is outside of varadic argument list. if (param1.Ptr == winstd::event_data::blank.Ptr && @@ -513,7 +513,7 @@ namespace winstd /// inline ULONG write(_In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ va_list arg) { - assert(m_h); + assert(m_h != invalid); va_list arg_start = arg; std::vector params; @@ -556,7 +556,7 @@ namespace winstd /// inline ULONG write(_In_ UCHAR Level, _In_ ULONGLONG Keyword, _In_z_ _Printf_format_string_ PCWSTR String, ...) { - assert(m_h); + assert(m_h != invalid); std::wstring msg; va_list arg; @@ -599,7 +599,7 @@ namespace winstd /// /// ETW session /// - class WINSTD_API event_session : public handle + class WINSTD_API event_session : public handle { WINSTD_NONCOPYABLE(event_session) @@ -654,8 +654,8 @@ namespace winstd inline event_session& operator=(_Inout_ event_session &&other) noexcept { if (this != std::addressof(other)) { - (handle&&)*this = std::move(other); - m_prop = std::move(other.m_prop); + (handle&&)*this = std::move(other); + m_prop = std::move(other.m_prop); } return *this; } @@ -694,7 +694,7 @@ namespace winstd /// inline void attach(_In_opt_ handle_type h, _In_ EVENT_TRACE_PROPERTIES *prop) { - handle::attach(h); + handle::attach(h); m_prop.reset(prop); } @@ -708,7 +708,7 @@ namespace winstd /// /// \sa [StartTrace function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364117.aspx) /// - inline ULONG create(_In_ LPCTSTR SessionName, _In_ const EVENT_TRACE_PROPERTIES *Properties) + inline ULONG create(_In_z_ LPCTSTR SessionName, _In_ const EVENT_TRACE_PROPERTIES *Properties) { handle_type h; std::unique_ptr prop(reinterpret_cast(new char[Properties->Wnode.BufferSize])); @@ -731,7 +731,7 @@ namespace winstd /// inline ULONG enable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword = 0, _In_opt_ ULONGLONG MatchAllKeyword = 0, _In_opt_ ULONG EnableProperty = 0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL) { - assert(m_h); + assert(m_h != invalid); return EnableTraceEx( ProviderId, &m_prop->Wnode.Guid, @@ -756,7 +756,7 @@ namespace winstd /// inline ULONG disable_trace(_In_ LPCGUID ProviderId, _In_ UCHAR Level, _In_opt_ ULONGLONG MatchAnyKeyword = 0, _In_opt_ ULONGLONG MatchAllKeyword = 0, _In_opt_ ULONG EnableProperty = 0, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc = NULL) { - assert(m_h); + assert(m_h != invalid); return EnableTraceEx( ProviderId, &m_prop->Wnode.Guid, @@ -786,9 +786,9 @@ namespace winstd /// /// ETW trace /// - class WINSTD_API event_trace : public handle + class WINSTD_API event_trace : public handle { - HANDLE_IMPL(event_trace) + HANDLE_IMPL(event_trace, INVALID_PROCESSTRACE_HANDLE) public: /// @@ -811,7 +811,7 @@ namespace winstd inline bool create(_Inout_ PEVENT_TRACE_LOGFILE Logfile) { handle_type h = OpenTrace(Logfile); - if (h != (TRACEHANDLE)INVALID_HANDLE_VALUE) { + if (h != invalid) { attach(h); return true; } else @@ -1130,7 +1130,7 @@ namespace winstd } -inline ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr &info) +inline ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _Inout_ std::unique_ptr &info) { BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES]; ULONG ulSize = sizeof(szBuffer), ulResult; @@ -1148,12 +1148,11 @@ inline ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhCon return TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, info.get(), &ulSize); } - info.reset(nullptr); return ulResult; } -inline ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Out_ std::unique_ptr &info) +inline ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr &info) { BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES]; ULONG ulSize = sizeof(szBuffer), ulResult; @@ -1171,13 +1170,12 @@ inline ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pM return TdhGetEventMapInformation(pEvent, pMapName, info.get(), &ulSize); } - info.reset(nullptr); return ulResult; } template -inline ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_ PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Out_ std::vector<_Ty, _Ax> &aData) +inline ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_ PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_ PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData) { ULONG ulSize, ulResult; diff --git a/include/WinStd/Hex.h b/include/WinStd/Hex.h index 3805a171..5394f66a 100644 --- a/include/WinStd/Hex.h +++ b/include/WinStd/Hex.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -64,7 +64,7 @@ namespace winstd /// \param[in ] size Length of `data` in bytes /// template - inline void encode(_Out_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size) + inline void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size) { assert(data || !size); diff --git a/include/WinStd/MSI.h b/include/WinStd/MSI.h index 201b6fed..a35910ec 100644 --- a/include/WinStd/MSI.h +++ b/include/WinStd/MSI.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -34,61 +34,61 @@ /// @{ /// @copydoc MsiGetPropertyW() -template inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Gets the value for an installer property and stores it in a std::wstring string. /// /// \sa [MsiGetProperty function](https://msdn.microsoft.com/en-us/library/aa370134.aspx) /// -template inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc MsiRecordGetStringW() -template inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Returns the string value of a record field and stores it in a std::wstring string. /// /// \sa [MsiRecordGetString function](https://msdn.microsoft.com/en-us/library/aa370368.aspx) /// -template inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc MsiFormatRecordW() -template inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Formats record field data and properties using a format string and stores it in a std::wstring string. /// /// \sa [MsiFormatRecord function](https://msdn.microsoft.com/en-us/library/aa370109.aspx) /// -template inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Reads bytes from a record stream field into a std::vector buffer. /// /// \sa [MsiRecordReadStream function](https://msdn.microsoft.com/en-us/library/aa370370.aspx) /// -template inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::vector<_Ty, _Ax> &binData); +template inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData); /// @copydoc MsiGetTargetPathW() -template inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Returns the full target path for a folder in the Directory table and stores it in a std::wstring string. /// /// \sa [MsiGetTargetPath function](https://msdn.microsoft.com/en-us/library/aa370303.aspx) /// -template inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc MsiGetComponentPathW() -template inline INSTALLSTATE MsiGetComponentPathA(_In_ LPCSTR szProduct, _In_ LPCSTR szComponent, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Returns the full path to an installed component. If the key path for the component is a registry key then the registry key is returned. /// /// \sa [MsiGetComponentPath function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa370112.aspx) /// -template inline INSTALLSTATE MsiGetComponentPathW(_In_ LPCWSTR szProduct, _In_ LPCWSTR szComponent, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWSTR szComponent, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @} @@ -96,7 +96,7 @@ template inline INSTALLSTATE MsiGetCompon template -inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -124,7 +124,7 @@ inline UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szName, _Out_ s template -inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); @@ -150,7 +150,7 @@ inline UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szName, _Out_ template -inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -178,7 +178,7 @@ inline UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField template -inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); @@ -204,7 +204,7 @@ inline UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField template -inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -232,7 +232,7 @@ inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_s template -inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); @@ -258,7 +258,7 @@ inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, std::basic_s template -inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ std::vector<_Ty, _Ax> &binData) +inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData) { assert(0); // TODO: Test this code. @@ -278,7 +278,7 @@ inline UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField template -inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -306,7 +306,7 @@ inline UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_ LPCSTR szFolder, _Ou template -inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); @@ -332,7 +332,7 @@ inline UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_ LPCWSTR szFolder, _O template -inline INSTALLSTATE MsiGetComponentPathA(_In_ LPCSTR szProduct, _In_ LPCSTR szComponent, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); @@ -358,7 +358,7 @@ inline INSTALLSTATE MsiGetComponentPathA(_In_ LPCSTR szProduct, _In_ LPCSTR szCo template -inline INSTALLSTATE MsiGetComponentPathW(_In_ LPCWSTR szProduct, _In_ LPCWSTR szComponent, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWSTR szComponent, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; DWORD dwSize = _countof(szStackBuffer); diff --git a/include/WinStd/Sec.h b/include/WinStd/Sec.h index 2729c52a..427d6763 100644 --- a/include/WinStd/Sec.h +++ b/include/WinStd/Sec.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -41,14 +41,14 @@ namespace winstd /// @{ /// @copydoc GetUserNameExW() -template BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName); +template BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sName); /// /// Retrieves the name of the user or other security principal associated with the calling thread and stores it in a std::wstring string. /// /// \sa [GetUserNameEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx) /// -template BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName); +template BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sName); /// @} @@ -223,7 +223,7 @@ namespace winstd /// inline SECURITY_STATUS initialize( _In_opt_ PCredHandle phCredential, - _In_opt_ LPCTSTR pszTargetName, + _In_opt_z_ LPCTSTR pszTargetName, _In_ ULONG fContextReq, _In_ ULONG TargetDataRep, _In_opt_ PSecBufferDesc pInput, @@ -253,7 +253,7 @@ namespace winstd /// inline SECURITY_STATUS process( _In_opt_ PCredHandle phCredential, - _In_opt_ LPCTSTR pszTargetName, + _In_opt_z_ LPCTSTR pszTargetName, _In_ ULONG fContextReq, _In_ ULONG TargetDataRep, _In_opt_ PSecBufferDesc pInput, @@ -322,7 +322,7 @@ namespace winstd /// \param[in] num Security provider error code /// \param[in] msg Error message /// - inline sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg.c_str()) + inline sec_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg) { } @@ -353,7 +353,7 @@ namespace winstd template -BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName) +BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sName) { assert(0); // TODO: Test this code. @@ -376,13 +376,12 @@ BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_st } } - sName.clear(); return FALSE; } template -BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sName) +BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sName) { assert(0); // TODO: Test this code. @@ -405,6 +404,5 @@ BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Out_ std::basic_st } } - sName.clear(); return FALSE; } diff --git a/include/WinStd/SetupAPI.h b/include/WinStd/SetupAPI.h new file mode 100644 index 00000000..f3715d0d --- /dev/null +++ b/include/WinStd/SetupAPI.h @@ -0,0 +1,167 @@ +/* + Copyright 1991-2019 Amebis + Copyright 2016 GÉANT + + This file is part of WinStd. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + + /// + /// \defgroup SetupAPI Setup API + /// Integrates WinStd classes with Microsoft Setup API + /// + +#include "Common.h" + +namespace winstd +{ + class WINSTD_API setup_device_info_list; + class WINSTD_API setup_driver_info_list_builder; +} + + +#pragma once + +#include + + +namespace winstd +{ + /// \addtogroup SetupAPI + /// @{ + + /// + /// HDEVINFO wrapper class + /// + class WINSTD_API setup_device_info_list : public handle + { + HANDLE_IMPL(setup_device_info_list, INVALID_HANDLE_VALUE) + + public: + /// + /// Frees the device information set. + /// + /// \sa [SetupDiDestroyDeviceInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdidestroydeviceinfolist) + /// + virtual ~setup_device_info_list(); + + /// + /// Creates an empty device information set and optionally associates the set with a device setup class and a top-level window. + /// + /// \return + /// - true when creation succeeds; + /// - false when creation fails. For extended error information, call `GetLastError()`. + /// + /// \sa [SetupDiCreateDeviceInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdicreatedeviceinfolist) + /// + inline bool create( + _In_opt_ const GUID * ClassGuid, + _In_opt_ HWND hwndParent) + { + handle_type h = SetupDiCreateDeviceInfoList(ClassGuid, hwndParent); + if (h != invalid) { + attach(h); + return true; + } + else + return false; + } + + /// + /// Creates a device information set that contains requested device information elements for a local or a remote computer. + /// + /// \return + /// - true when creation succeeds; + /// - false when creation fails. For extended error information, call `GetLastError()`. + /// + /// \sa [SetupDiGetClassDevsExW function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdigetclassdevsexw) + /// + inline bool create( + _In_opt_ const GUID * ClassGuid, + _In_opt_ PCTSTR Enumerator, + _In_opt_ HWND hwndParent, + _In_ DWORD Flags, + _In_opt_ HDEVINFO DeviceInfoSet, + _In_opt_ PCTSTR MachineName, + _Reserved_ PVOID Reserved) + { + handle_type h = SetupDiGetClassDevsEx(ClassGuid, Enumerator, hwndParent, Flags, DeviceInfoSet, MachineName, Reserved); + if (h != invalid) { + attach(h); + return true; + } + else + return false; + } + + protected: + /// + /// Frees the device information set. + /// + /// \sa [SetupDiDestroyDeviceInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdidestroydeviceinfolist) + /// + virtual void free_internal(); + }; + + + /// + /// Builds a list of drivers in constructor and deletes it in destructor + /// + class WINSTD_API setup_driver_info_list_builder + { + public: + /// + /// Construct the builder and builds a list of drivers that is associated with a specific device or with the global class driver list for a device information set. + /// + /// \sa [SetupDiBuildDriverInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdibuilddriverinfolist) + /// + inline setup_driver_info_list_builder( + _In_ HDEVINFO DeviceInfoSet, + _Inout_opt_ PSP_DEVINFO_DATA DeviceInfoData, + _In_ DWORD DriverType) : + m_DeviceInfoSet (DeviceInfoSet), + m_DeviceInfoData(DeviceInfoData), + m_DriverType (DriverType) + { + m_result = SetupDiBuildDriverInfoList(m_DeviceInfoSet, m_DeviceInfoData, m_DriverType); + } + + /// + /// Deletes a driver list and destructs the builder. + /// + /// \sa [SetupDiDestroyDriverInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdidestroydriverinfolist) + /// + virtual ~setup_driver_info_list_builder(); + + + /// + /// Return result of `SetupDiBuildDriverInfoList()` call. + /// + /// \sa [SetupDiBuildDriverInfoList function](https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdibuilddriverinfolist) + /// + inline BOOL status() const + { + return m_result; + } + + protected: + HDEVINFO m_DeviceInfoSet; + PSP_DEVINFO_DATA m_DeviceInfoData; + DWORD m_DriverType; + BOOL m_result; ///< Did building succeed? + }; + + /// @} +} diff --git a/include/WinStd/Shell.h b/include/WinStd/Shell.h index 4c9f131d..817ce78a 100644 --- a/include/WinStd/Shell.h +++ b/include/WinStd/Shell.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -32,14 +32,14 @@ /// @{ /// @copydoc PathCanonicalizeW() -template inline BOOL PathCanonicalizeA(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCSTR pszPath); +template inline BOOL PathCanonicalizeA(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, _In_ LPCSTR pszPath); /// /// Simplifies a path by removing navigation elements such as "." and ".." to produce a direct, well-formed path, and stores it in a std::wstring string. /// /// \sa [PathCanonicalize function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773569.aspx) /// -template inline BOOL PathCanonicalizeW(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCWSTR pszPath); +template inline BOOL PathCanonicalizeW(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, _In_ LPCWSTR pszPath); /// @} @@ -47,7 +47,7 @@ template inline BOOL PathCanonicalizeW(__ template -inline BOOL PathCanonicalizeA(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCSTR pszPath) +inline BOOL PathCanonicalizeA(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, _In_ LPCSTR pszPath) { assert(0); // TODO: Test this code. @@ -60,7 +60,7 @@ inline BOOL PathCanonicalizeA(__out std::basic_string<_Elem, _Traits, _Ax> &sVal template -inline BOOL PathCanonicalizeW(__out std::basic_string<_Elem, _Traits, _Ax> &sValue, __in LPCWSTR pszPath) +inline BOOL PathCanonicalizeW(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, _In_ LPCWSTR pszPath) { assert(0); // TODO: Test this code. diff --git a/include/WinStd/WLAN.h b/include/WinStd/WLAN.h index 5ad8eddf..209da773 100644 --- a/include/WinStd/WLAN.h +++ b/include/WinStd/WLAN.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -51,7 +51,7 @@ namespace winstd { /// Since Wlanapi.dll is not always present, the `pfnWlanReasonCodeToString` pointer to `WlanReasonCodeToString()` /// function must be loaded dynamically. /// -template inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue, __reserved PVOID pReserved); +template inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, __reserved PVOID pReserved); /// @} @@ -124,9 +124,9 @@ namespace winstd /// /// WLAN handle wrapper /// - class WINSTD_API wlan_handle : public handle + class WINSTD_API wlan_handle : public handle { - HANDLE_IMPL(wlan_handle) + HANDLE_IMPL(wlan_handle, NULL) public: /// @@ -172,7 +172,7 @@ namespace winstd template -inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue, __reserved PVOID pReserved) +inline DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue, __reserved PVOID pReserved) { DWORD dwSize = 0; diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index 9bfeff30..f2390d80 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -32,17 +32,21 @@ namespace winstd { - class WINSTD_API win_handle; + template class WINSTD_API win_handle; class WINSTD_API library; class WINSTD_API process; class WINSTD_API file; + class WINSTD_API event; + class WINSTD_API critical_section; class WINSTD_API heap; template class heap_allocator; class WINSTD_API actctx_activator; class WINSTD_API user_impersonator; + class WINSTD_API console_ctrl_handler; class WINSTD_API vmemory; class WINSTD_API reg_key; class WINSTD_API security_id; + class WINSTD_API process_information; } @@ -50,47 +54,47 @@ namespace winstd /// @{ /// @copydoc GetModuleFileNameW() -template inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Retrieves the fully qualified path for the file that contains the specified module and stores it in a std::wstring string. /// /// \sa [GetModuleFileName function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197.aspx) /// -template inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc GetWindowTextW() -template inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline int GetWindowTextA(_In_ HWND hWnd, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Copies the text of the specified window's title bar (if it has one) into a std::wstring string. /// /// \sa [GetWindowText function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633520.aspx) /// -template inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline int GetWindowTextW(_In_ HWND hWnd, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc GetFileVersionInfoW() -template inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue); +template inline BOOL GetFileVersionInfoA(_In_z_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Inout_ std::vector<_Ty, _Ax> &aValue); /// /// Retrieves version information for the specified file and stores it in a std::vector buffer. /// /// \sa [GetFileVersionInfo function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003.aspx) /// -template inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue); +template inline BOOL GetFileVersionInfoW(_In_z_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Inout_ std::vector<_Ty, _Ax> &aValue); /// @copydoc ExpandEnvironmentStringsW() -template inline DWORD ExpandEnvironmentStringsA(_In_ LPCSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSrc, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Expands environment-variable strings, replaces them with the values defined for the current user, and stores it in a std::wstring string. /// /// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx) /// -template inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpSrc, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc GuidToStringW() -template inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str); +template inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &str); /// /// Formats GUID and stores it in a std::wstring string. @@ -98,7 +102,7 @@ template inline VOID GuidToStringA(_In_ L /// \param[in ] lpGuid Pointer to GUID /// \param[out] str String to store the result to /// -template inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str); +template inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &str); /// @copydoc GuidToStringW() #ifdef _UNICODE #define GuidToString GuidToStringW @@ -146,7 +150,7 @@ _Success_(return) BOOL WINSTD_API StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ L /// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx) /// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx) /// -template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// /// Queries for a string value in the registry and stores it in a std::wstring string. @@ -166,29 +170,29 @@ template inline LSTATUS RegQueryStringVal /// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx) /// \sa [ExpandEnvironmentStrings function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724265.aspx) /// -template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); +template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue); /// @copydoc RegQueryValueExW() -template inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData); +template inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_z_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Inout_ std::vector<_Ty, _Ax> &aData); /// /// Retrieves the type and data for the specified value name associated with an open registry key and stores the data in a std::vector buffer. /// /// \sa [RegQueryValueEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724911.aspx) /// -template inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData); +template inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Inout_ std::vector<_Ty, _Ax> &aData); #if _WIN32_WINNT >= _WIN32_WINNT_VISTA /// @copydoc RegLoadMUIStringW() -template inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCSTR pszDirectory); +template inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_z_ LPCSTR pszValue, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCSTR pszDirectory); /// /// Loads the specified string from the specified key and subkey, and stores it in a std::wstring string. /// /// \sa [RegLoadMUIString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724890.aspx) /// -template inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCWSTR pszDirectory); +template inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR pszValue, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCWSTR pszDirectory); #endif @@ -197,93 +201,161 @@ template inline LSTATUS RegLoadMUIStringW /// /// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) /// -template inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::basic_string &sMultiByteStr, _In_opt_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); +template inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); + +/// +/// Maps a UTF-16 (wide character) string to a std::vector. The new character vector is not necessarily from a multibyte character set. +/// +/// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) +/// +template inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::vector &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); /// /// Maps a UTF-16 (wide character) string to a std::string. The new character string is not necessarily from a multibyte character set. /// /// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) /// -template inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sWideCharStr, _Out_ std::basic_string &sMultiByteStr, _In_opt_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); +template inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _Inout_ std::basic_string sWideCharStr, _Out_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); + +/// +/// Maps a UTF-16 (wide character) string to a std::string. The new character string is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) +/// +template inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); + +/// +/// Maps a UTF-16 (wide character) string to a std::vector. The new character vector is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) +/// +template inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::vector &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); + +/// +/// Maps a UTF-16 (wide character) string to a std::string. The new character string is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [WideCharToMultiByte function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374130.aspx) +/// +template inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _Inout_ std::basic_string sWideCharStr, _Out_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar); /// /// Maps a character string to a UTF-16 (wide character) std::wstring. The character string is not necessarily from a multibyte character set. /// /// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) /// -template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::basic_string &sWideCharStr); +template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::basic_string &sWideCharStr); + +/// +/// Maps a character string to a UTF-16 (wide character) std::vector. The character vector is not necessarily from a multibyte character set. +/// +/// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) +/// +template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::vector &sWideCharStr); /// /// Maps a character string to a UTF-16 (wide character) std::wstring. The character string is not necessarily from a multibyte character set. /// /// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) /// -template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sMultiByteStr, _Out_ std::basic_string &sWideCharStr); +template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string &sMultiByteStr, _Inout_ std::basic_string &sWideCharStr); + +/// +/// Maps a character string to a UTF-16 (wide character) std::wstring. The character string is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) +/// +template inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::basic_string &sWideCharStr); + +/// +/// Maps a character string to a UTF-16 (wide character) std::vector. The character vector is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) +/// +template inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::vector &sWideCharStr); + +/// +/// Maps a character string to a UTF-16 (wide character) std::wstring. The character string is not necessarily from a multibyte character set. +/// +/// \note This function cleans all internal buffers using SecureZeroMemory() before returning. +/// +/// \sa [MultiByteToWideChar function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072.aspx) +/// +template inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string &sMultiByteStr, _Inout_ std::basic_string &sWideCharStr); /// @copydoc LoadStringW -template inline int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string &sBuffer); +template inline int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Inout_ std::basic_string &sBuffer); /// /// Loads a string resource from the executable file associated with a specified module. /// /// \sa [LoadString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647486.aspx) /// -template inline int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string &sBuffer); +template inline int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Inout_ std::basic_string &sBuffer); /// /// Formats and sends a string to the debugger for display. /// /// \sa [OutputDebugString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx) /// -inline VOID OutputDebugStrV(_In_ LPCSTR lpOutputString, _In_ va_list arg); +inline VOID OutputDebugStrV(_In_z_ LPCSTR lpOutputString, _In_ va_list arg); /// /// Formats and sends a string to the debugger for display. /// /// \sa [OutputDebugString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx) /// -inline VOID OutputDebugStrV(_In_ LPCWSTR lpOutputString, _In_ va_list arg); +inline VOID OutputDebugStrV(_In_z_ LPCWSTR lpOutputString, _In_ va_list arg); /// /// Formats and sends a string to the debugger for display. /// /// \sa [OutputDebugString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx) /// -inline VOID OutputDebugStr(_In_ LPCSTR lpOutputString, ...); +inline VOID OutputDebugStr(_In_z_ LPCSTR lpOutputString, ...); /// /// Formats and sends a string to the debugger for display. /// /// \sa [OutputDebugString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx) /// -inline VOID OutputDebugStr(_In_ LPCWSTR lpOutputString, ...); +inline VOID OutputDebugStr(_In_z_ LPCWSTR lpOutputString, ...); /// @copydoc GetDateFormatW() -template inline int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_ LPCSTR lpFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sDate); +template inline int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCSTR lpFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sDate); /// /// Formats a date as a date string for a locale specified by the locale identifier. The function formats either a specified date or the local system date. /// /// \sa [GetDateFormat function](https://msdn.microsoft.com/en-us/library/windows/desktop/dd318086.aspx) /// -template inline int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_ LPCWSTR lpFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sDate); +template inline int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCWSTR lpFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sDate); /// @copydoc LookupAccountSidW() -template inline BOOL LookupAccountSidA(_In_opt_ LPCSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse); +template inline BOOL LookupAccountSidA(_In_opt_z_ LPCSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse); /// /// Retrieves the name of the account for this SID and the name of the first domain on which this SID is found. /// /// \sa [LookupAccountSid function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379166.aspx) /// -template inline BOOL LookupAccountSidW(_In_opt_ LPCWSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse); +template inline BOOL LookupAccountSidW(_In_opt_z_ LPCWSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse); /// /// Retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information. /// /// \sa [GetTokenInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671.aspx) /// -template inline BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_ std::unique_ptr<_Ty> &TokenInformation); +template inline BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Inout_ std::unique_ptr<_Ty> &TokenInformation); /// @} @@ -298,9 +370,10 @@ namespace winstd /// /// Windows HANDLE wrapper class /// - class WINSTD_API win_handle : public handle + template + class WINSTD_API win_handle : public handle { - HANDLE_IMPL(win_handle) + HANDLE_IMPL(win_handle, INVALID) public: /// @@ -308,7 +381,11 @@ namespace winstd /// /// \sa [CloseHandle function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211.aspx) /// - virtual ~win_handle(); + virtual ~win_handle() + { + if (m_h != invalid) + CloseHandle(m_h); + } protected: /// @@ -316,16 +393,19 @@ namespace winstd /// /// \sa [CloseHandle function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211.aspx) /// - virtual void free_internal(); + virtual void free_internal() + { + CloseHandle(m_h); + } }; /// /// Module handle wrapper /// - class WINSTD_API library : public handle + class WINSTD_API library : public handle { - HANDLE_IMPL(library) + HANDLE_IMPL(library, NULL) public: /// @@ -344,10 +424,10 @@ namespace winstd /// - \c true when succeeds; /// - \c false when fails. Use `GetLastError()` for failure reason. /// - inline bool load(_In_ LPCTSTR lpFileName, __reserved handle_type hFile, _In_ DWORD dwFlags) + inline bool load(_In_z_ LPCTSTR lpFileName, __reserved handle_type hFile, _In_ DWORD dwFlags) { handle_type h = LoadLibraryEx(lpFileName, hFile, dwFlags); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -367,7 +447,7 @@ namespace winstd /// /// Process handle wrapper /// - class WINSTD_API process : public win_handle + class WINSTD_API process : public win_handle { public: /// @@ -382,7 +462,7 @@ namespace winstd inline bool open(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId) { handle_type h = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -394,7 +474,7 @@ namespace winstd /// /// File handle wrapper /// - class WINSTD_API file : public win_handle + class WINSTD_API file : public win_handle { public: /// @@ -406,10 +486,10 @@ namespace winstd /// - \c true when succeeds; /// - \c false when fails. Use `GetLastError()` for failure reason. /// - inline bool create(_In_ LPCTSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_opt_ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL, _In_opt_ HANDLE hTemplateFile = NULL) + inline bool create(_In_z_ LPCTSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_opt_ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL, _In_opt_ HANDLE hTemplateFile = NULL) { handle_type h = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -418,12 +498,140 @@ namespace winstd }; + /// + /// Event handle wrapper + /// + class WINSTD_API event : public win_handle + { + public: + /// + /// Creates or opens a named or unnamed event object. + /// + /// \sa [CreateEventW function](https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-createeventw) + /// + /// \return + /// - \c true when succeeds; + /// - \c false when fails. Use `GetLastError()` for failure reason. + /// + inline bool create(_In_ BOOL bManualReset, _In_ BOOL bInitialState, _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes = NULL, _In_opt_z_ LPCTSTR lpName = NULL) + { + handle_type h = CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName); + if (h != invalid) { + attach(h); + return true; + } else + return false; + } + + /// + /// Opens an existing named event object. + /// + /// \sa [OpenEventW function](https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-openeventw) + /// + /// \return + /// - \c true when succeeds; + /// - \c false when fails. Use `GetLastError()` for failure reason. + /// + inline bool open(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_z_ LPCTSTR lpName) + { + handle_type h = OpenEvent(dwDesiredAccess, bInheritHandle, lpName); + if (h != invalid) { + attach(h); + return true; + } else + return false; + } + }; + + + /// + /// Critical section wrapper + /// + class WINSTD_API critical_section + { + WINSTD_NONCOPYABLE(critical_section) + WINSTD_NONMOVABLE(critical_section) + + public: + /// + /// Construct the object and initializes a critical section object + /// + /// \sa [InitializeCriticalSection function](https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-initializecriticalsection) + /// + critical_section(); + + /// + /// Releases all resources used by an unowned critical section object. + /// + /// \sa [DeleteCriticalSection function](https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-deletecriticalsection) + /// + virtual ~critical_section(); + + /// + /// Auto-typecasting operator + /// + /// \return Pointer to critical section + /// + inline operator LPCRITICAL_SECTION() + { + return &m_data; + } + + protected: + CRITICAL_SECTION m_data; ///< Critical section struct + }; + + + /// + /// Find-file handle wrapper + /// + class WINSTD_API find_file : public handle + { + HANDLE_IMPL(find_file, INVALID_HANDLE_VALUE) + + public: + /// + /// Closes a file search handle. + /// + /// \sa [FindClose function](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findclose) + /// + virtual ~find_file(); + + /// + /// Searches a directory for a file or subdirectory with a name that matches a specific name (or partial name if wildcards are used). + /// + /// \sa [FindFirstFile function](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findfirstfilew) + /// + /// \return + /// - \c true when succeeds; + /// - \c false when fails. Use `GetLastError()` for failure reason. + /// + inline bool find(_In_ LPCTSTR lpFileName, _Out_ LPWIN32_FIND_DATA lpFindFileData) + { + handle_type h = FindFirstFile(lpFileName, lpFindFileData); + if (h != invalid) { + attach(h); + return true; + } else + return false; + } + + protected: + /// + /// Closes a file search handle. + /// + /// \sa [FindClose function](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findclose) + /// + virtual void free_internal(); + }; + + /// /// Heap handle wrapper /// - class WINSTD_API heap : public handle + class WINSTD_API heap : public handle { - HANDLE_IMPL(heap) + HANDLE_IMPL(heap, NULL) public: /// @@ -445,7 +653,7 @@ namespace winstd inline bool create(_In_ DWORD flOptions, _In_ SIZE_T dwInitialSize, _In_ SIZE_T dwMaximumSize) { handle_type h = HeapCreate(flOptions, dwInitialSize, dwMaximumSize); - if (h) { + if (h != invalid) { attach(h); return true; } else @@ -642,16 +850,44 @@ namespace winstd }; + /// + /// Console control handler stack management + /// + class WINSTD_API console_ctrl_handler + { + public: + /// + /// Construct the console control handler object and pushes the given handler to the console control handler stack + /// + /// \param[in] HandlerRoutine A pointer to the application-defined HandlerRoutine function to be added. + /// + /// \sa [SetConsoleCtrlHandler function](https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler) + /// + console_ctrl_handler(_In_opt_ PHANDLER_ROUTINE HandlerRoutine); + + /// + /// Pops console control handler from the console control handler stack + /// + /// \sa [SetConsoleCtrlHandler function](https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler) + /// + virtual ~console_ctrl_handler(); + + protected: + BOOL m_cookie; ///< Did pushing the console control handler succeed? + PHANDLER_ROUTINE m_handler; ///< Pointer to console control handler + }; + + /// /// Memory in virtual address space of a process handle wrapper /// - class WINSTD_API vmemory : public handle + class WINSTD_API vmemory : public handle { WINSTD_NONCOPYABLE(vmemory) public: /// - /// Initializes a new class instance with the memory handle set to NULL. + /// Initializes a new class instance with the memory handle set to INVAL. /// inline vmemory() : m_proc(NULL) { @@ -665,7 +901,7 @@ namespace winstd /// inline vmemory(_In_ handle_type h, _In_ HANDLE proc) : m_proc(proc), - handle(h) + handle(h) { } @@ -676,7 +912,7 @@ namespace winstd /// inline vmemory(_Inout_ vmemory &&h) noexcept : m_proc(std::move(h.m_proc)), - handle(std::move(h)) + handle(std::move(h)) { } @@ -695,8 +931,8 @@ namespace winstd inline vmemory& operator=(_Inout_ vmemory &&other) noexcept { if (this != std::addressof(other)) { - (handle&&)*this = std::move(other); - m_proc = std::move(other.m_proc); + (handle&&)*this = std::move(other); + m_proc = std::move(other.m_proc); } return *this; } @@ -704,7 +940,7 @@ namespace winstd /// /// Sets a new memory handle for the class /// - /// When the current object handle of the class is non-NULL, the object is destroyed first. + /// When the current object handle of the class is non-INVAL, the object is destroyed first. /// /// \param[in] proc Handle of process the memory belongs to /// \param[in] h Initial object handle value @@ -712,7 +948,7 @@ namespace winstd inline void attach(_In_ HANDLE proc, _In_opt_ handle_type h) { m_proc = proc; - if (m_h) + if (m_h != invalid) free_internal(); m_h = h; } @@ -734,7 +970,7 @@ namespace winstd _In_ DWORD flProtect) { handle_type h = VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect); - if (h) { + if (h != invalid) { attach(hProcess, h); return true; } else @@ -757,9 +993,9 @@ namespace winstd /// /// Registry wrapper class /// - class WINSTD_API reg_key : public handle + class WINSTD_API reg_key : public handle { - HANDLE_IMPL(reg_key) + HANDLE_IMPL(reg_key, NULL) public: /// @@ -780,7 +1016,7 @@ namespace winstd /// inline bool create( _In_ HKEY hKey, - _In_ LPCTSTR lpSubKey, + _In_z_ LPCTSTR lpSubKey, _In_opt_ LPTSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, @@ -808,10 +1044,10 @@ namespace winstd /// \sa [RegOpenKeyEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724897.aspx) /// inline bool open( - _In_ HKEY hKey, - _In_opt_ LPCTSTR lpSubKey, - _In_ DWORD ulOptions, - _In_ REGSAM samDesired) + _In_ HKEY hKey, + _In_opt_z_ LPCTSTR lpSubKey, + _In_ DWORD ulOptions, + _In_ REGSAM samDesired) { handle_type h; LONG s = RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &h); @@ -837,9 +1073,9 @@ namespace winstd /// /// SID wrapper class /// - class WINSTD_API security_id : public handle + class WINSTD_API security_id : public handle { - HANDLE_IMPL(security_id) + HANDLE_IMPL(security_id, NULL) public: /// @@ -858,12 +1094,48 @@ namespace winstd virtual void free_internal(); }; + + /// + /// PROCESS_INFORMATION struct wrapper + /// + class WINSTD_API process_information : public PROCESS_INFORMATION + { + public: + /// + /// Constructs blank PROCESS_INFORMATION + /// + inline process_information() + { + hProcess = INVALID_HANDLE_VALUE; + hThread = INVALID_HANDLE_VALUE; + dwProcessId = 0; + dwThreadId = 0; + } + + /// + /// Closes process and thread handles. + /// + inline ~process_information() + { + #pragma warning(push) + #pragma warning(disable: 6001) // Using uninitialized memory '*this'. << ??? + + if (hProcess != INVALID_HANDLE_VALUE) + CloseHandle(hProcess); + + if (hThread != INVALID_HANDLE_VALUE) + CloseHandle(hThread); + + #pragma warning(pop) + } + }; + /// @} } template -inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -890,7 +1162,7 @@ inline DWORD GetModuleFileNameA(_In_opt_ HMODULE hModule, _Out_ std::basic_strin template -inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { _Elem szBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; @@ -915,7 +1187,7 @@ inline DWORD GetModuleFileNameW(_In_opt_ HMODULE hModule, _Out_ std::basic_strin template -inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline int GetWindowTextA(_In_ HWND hWnd, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -944,7 +1216,7 @@ inline int GetWindowTextA(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits template -inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline int GetWindowTextW(_In_ HWND hWnd, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. @@ -973,7 +1245,7 @@ inline int GetWindowTextW(_In_ HWND hWnd, _Out_ std::basic_string<_Elem, _Traits template -inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) +inline BOOL GetFileVersionInfoA(_In_z_ LPCSTR lptstrFilename, __reserved DWORD dwHandle, _Inout_ std::vector<_Ty, _Ax> &aValue) { assert(0); // TODO: Test this code. @@ -989,7 +1261,7 @@ inline BOOL GetFileVersionInfoA(_In_ LPCSTR lptstrFilename, __reserved DWORD dwH template -inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Out_ std::vector<_Ty, _Ax> &aValue) +inline BOOL GetFileVersionInfoW(_In_z_ LPCWSTR lptstrFilename, __reserved DWORD dwHandle, _Inout_ std::vector<_Ty, _Ax> &aValue) { assert(0); // TODO: Test this code. @@ -1005,20 +1277,20 @@ inline BOOL GetFileVersionInfoW(_In_ LPCWSTR lptstrFilename, __reserved DWORD dw template -inline DWORD ExpandEnvironmentStringsA(_In_ LPCSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline DWORD ExpandEnvironmentStringsA(_In_z_ LPCSTR lpSrc, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { assert(0); // TODO: Test this code. for (DWORD dwSizeOut = (DWORD)strlen(lpSrc) + 0x100;;) { DWORD dwSizeIn = dwSizeOut; - std::unique_ptr<_Elem[]> szBuffer(new _Elem[dwSizeIn + 2]); // Note: ANSI version requires one extra char. + std::unique_ptr<_Elem[]> szBuffer(new _Elem[(size_t)dwSizeIn + 2]); // Note: ANSI version requires one extra char. dwSizeOut = ::ExpandEnvironmentStringsA(lpSrc, szBuffer.get(), dwSizeIn); if (dwSizeOut == 0) { - // Error. + // Error or zero-length input. break; } else if (dwSizeOut <= dwSizeIn) { // The buffer was sufficient. - sValue.assign(szBuffer.get(), dwSizeOut); + sValue.assign(szBuffer.get(), dwSizeOut - 1); return dwSizeOut; } } @@ -1029,20 +1301,18 @@ inline DWORD ExpandEnvironmentStringsA(_In_ LPCSTR lpSrc, std::basic_string<_Ele template -inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline DWORD ExpandEnvironmentStringsW(_In_z_ LPCWSTR lpSrc, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { - assert(0); // TODO: Test this code. - for (DWORD dwSizeOut = (DWORD)wcslen(lpSrc) + 0x100;;) { DWORD dwSizeIn = dwSizeOut; - std::unique_ptr<_Elem[]> szBuffer(new _Elem[dwSizeIn + 1]); + std::unique_ptr<_Elem[]> szBuffer(new _Elem[(size_t)dwSizeIn + 1]); dwSizeOut = ::ExpandEnvironmentStringsW(lpSrc, szBuffer.get(), dwSizeIn); if (dwSizeOut == 0) { - // Error. + // Error or zero-length input. break; } else if (dwSizeOut <= dwSizeIn) { // The buffer was sufficient. - sValue.assign(szBuffer.get(), dwSizeOut); + sValue.assign(szBuffer.get(), dwSizeOut - 1); return dwSizeOut; } } @@ -1053,7 +1323,7 @@ inline DWORD ExpandEnvironmentStringsW(_In_ LPCWSTR lpSrc, std::basic_string<_El template -inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str) +inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &str) { assert(0); // TODO: Test this code. @@ -1067,7 +1337,7 @@ inline VOID GuidToStringA(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _T template -inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _Traits, _Ax> &str) +inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &str) { assert(0); // TODO: Test this code. @@ -1081,7 +1351,7 @@ inline VOID GuidToStringW(_In_ LPCGUID lpGuid, _Out_ std::basic_string<_Elem, _T template -inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { LSTATUS lResult; BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES]; @@ -1109,16 +1379,14 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { dwSize /= sizeof(CHAR); sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize); - } else - sValue.clear(); + } } else if (dwType == REG_EXPAND_SZ) { // The value is REG_EXPAND_SZ. Read it and expand environment variables. std::unique_ptr szBuffer(new CHAR[dwSize / sizeof(CHAR)]); if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if (::ExpandEnvironmentStringsA(szBuffer.get(), sValue) == 0) lResult = ::GetLastError(); - } else - sValue.clear(); + } } else { // The value is not a string type. lResult = ERROR_INVALID_DATA; @@ -1130,7 +1398,7 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ template -inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue) +inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sValue) { LSTATUS lResult; BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES]; @@ -1158,16 +1426,14 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { dwSize /= sizeof(WCHAR); sValue.assign(szBuffer.get(), dwSize && szBuffer[dwSize - 1] == 0 ? dwSize - 1 : dwSize); - } else - sValue.clear(); + } } else if (dwType == REG_EXPAND_SZ) { // The value is REG_EXPAND_SZ. Read it and expand environment variables. std::unique_ptr szBuffer(new WCHAR[dwSize / sizeof(WCHAR)]); if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, reinterpret_cast(szBuffer.get()), &dwSize)) == ERROR_SUCCESS) { if (::ExpandEnvironmentStringsW(szBuffer.get(), sValue) == 0) lResult = ::GetLastError(); - } else - sValue.clear(); + } } else { // The value is not a string type. lResult = ERROR_INVALID_DATA; @@ -1179,7 +1445,7 @@ inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ template -inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData) +inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_z_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Inout_ std::vector<_Ty, _Ax> &aData) { LSTATUS lResult; BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES]; @@ -1194,8 +1460,7 @@ inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __r } else if (lResult == ERROR_MORE_DATA) { // Allocate buffer on heap and retry. aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty)); - if ((lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize)) != ERROR_SUCCESS) - aData.clear(); + lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize); } return lResult; @@ -1203,7 +1468,7 @@ inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __r template -inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData) +inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Inout_ std::vector<_Ty, _Ax> &aData) { LSTATUS lResult; BYTE aStackBuffer[WINSTD_STACK_BUFFER_BYTES]; @@ -1218,8 +1483,7 @@ inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __ } else if (lResult == ERROR_MORE_DATA) { // Allocate buffer on heap and retry. aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty)); - if ((lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize)) != ERROR_SUCCESS) - aData.clear(); + lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aData.data(), &dwSize); } return lResult; @@ -1229,7 +1493,7 @@ inline LSTATUS RegQueryValueExW(_In_ HKEY hKey, _In_opt_ LPCWSTR lpValueName, __ #if _WIN32_WINNT >= _WIN32_WINNT_VISTA template -inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCSTR pszDirectory) +inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_z_ LPCSTR pszValue, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCSTR pszDirectory) { // According to "Remarks" section in MSDN documentation of RegLoadMUIString(), // this function is defined but not implemented as ANSI variation. @@ -1239,7 +1503,7 @@ inline LSTATUS RegLoadMUIStringA(_In_ HKEY hKey, _In_opt_ LPCSTR pszValue, _Out_ template -inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_ LPCWSTR pszDirectory) +inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_z_ LPCWSTR pszValue, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sOut, _In_ DWORD Flags, _In_opt_z_ LPCWSTR pszDirectory) { LSTATUS lResult; _Elem szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)]; @@ -1265,7 +1529,7 @@ inline LSTATUS RegLoadMUIStringW(_In_ HKEY hKey, _In_opt_ LPCWSTR pszValue, _Out template -inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Out_ std::basic_string &sMultiByteStr, _In_opt_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) { CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; @@ -1273,13 +1537,34 @@ inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_cou int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar); if (cch) { // Copy from stack. Be careful not to include zero terminator. - sMultiByteStr.assign(szStackBuffer, cchWideChar != -1 ? strnlen(szStackBuffer, cch) : cch - 1); + sMultiByteStr.assign(szStackBuffer, cchWideChar != -1 ? strnlen(szStackBuffer, cch) : (size_t)cch - 1); } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Query the required output size. Allocate buffer. Then convert again. cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); std::unique_ptr szBuffer(new CHAR[cch]); cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); - sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : cch - 1); + sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1); + } + + return cch; +} + + +template +inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::vector &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +{ + CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; + + // Try to convert to stack buffer first. + int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar); + if (cch) { + // Copy from stack. + sMultiByteStr.assign(szStackBuffer, szStackBuffer + cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, sMultiByteStr.data(), cch, lpDefaultChar, lpUsedDefaultChar); } return cch; @@ -1287,7 +1572,7 @@ inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_cou template -inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sWideCharStr, _Out_ std::basic_string &sMultiByteStr, _In_opt_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sWideCharStr, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) { CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; @@ -1309,7 +1594,80 @@ inline int WideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std: template -inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_ std::basic_string &sWideCharStr) +inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +{ + CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; + + // Try to convert to stack buffer first. + int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar); + if (cch) { + // Copy from stack. Be careful not to include zero terminator. + sMultiByteStr.assign(szStackBuffer, cchWideChar != -1 ? strnlen(szStackBuffer, cch) : (size_t)cch - 1); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); + std::unique_ptr szBuffer(new CHAR[cch]); + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.assign(szBuffer.get(), cchWideChar != -1 ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1); + SecureZeroMemory(szBuffer.get(), sizeof(CHAR)*cch); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cchWideChar) LPCWSTR lpWideCharStr, _In_ int cchWideChar, _Inout_ std::vector &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +{ + CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; + + // Try to convert to stack buffer first. + int cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar); + if (cch) { + // Copy from stack. + sMultiByteStr.assign(szStackBuffer, szStackBuffer + cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.resize(cch); + cch = ::WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, sMultiByteStr.data(), cch, lpDefaultChar, lpUsedDefaultChar); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int SecureWideCharToMultiByte(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sWideCharStr, _Inout_ std::basic_string &sMultiByteStr, _In_opt_z_ LPCSTR lpDefaultChar, _Out_opt_ LPBOOL lpUsedDefaultChar) +{ + CHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(CHAR)]; + + // Try to convert to stack buffer first. + int cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, lpUsedDefaultChar); + if (cch) { + // Copy from stack. + sMultiByteStr.assign(szStackBuffer, cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), NULL, 0, lpDefaultChar, lpUsedDefaultChar); + std::unique_ptr szBuffer(new CHAR[cch]); + cch = ::WideCharToMultiByte(CodePage, dwFlags, sWideCharStr.c_str(), (int)sWideCharStr.length(), szBuffer.get(), cch, lpDefaultChar, lpUsedDefaultChar); + sMultiByteStr.assign(szBuffer.get(), cch); + SecureZeroMemory(szBuffer.get(), sizeof(CHAR)*cch); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::basic_string &sWideCharStr) { WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; @@ -1317,20 +1675,42 @@ inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_cou int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer)); if (cch) { // Copy from stack. - sWideCharStr.assign(szStackBuffer, cbMultiByte != -1 ? wcsnlen(szStackBuffer, cch) : cch - 1); + sWideCharStr.assign(szStackBuffer, cbMultiByte != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1); } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Query the required output size. Allocate buffer. Then convert again. cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); std::unique_ptr szBuffer(new WCHAR[cch]); cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch); - sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : cch - 1); + sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1); } return cch; } -template inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ std::basic_string sMultiByteStr, _Out_ std::basic_string &sWideCharStr) +template +inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::vector &sWideCharStr) +{ + WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; + + // Try to convert to stack buffer first. + int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer)); + if (cch) { + // Copy from stack. + sWideCharStr.assign(szStackBuffer, szStackBuffer + cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, sWideCharStr.data(), cch); + } + + return cch; +} + + +template +inline int MultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string &sMultiByteStr, _Out_ std::basic_string &sWideCharStr) { WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; @@ -1352,7 +1732,80 @@ template inline int Mult template -inline int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string &sBuffer) +inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::basic_string &sWideCharStr) +{ + WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; + + // Try to convert to stack buffer first. + int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer)); + if (cch) { + // Copy from stack. + sWideCharStr.assign(szStackBuffer, cbMultiByte != -1 ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); + std::unique_ptr szBuffer(new WCHAR[cch]); + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szBuffer.get(), cch); + sWideCharStr.assign(szBuffer.get(), cbMultiByte != -1 ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1); + SecureZeroMemory(szBuffer.get(), sizeof(WCHAR)*cch); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_z_count_(cbMultiByte) LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Inout_ std::vector &sWideCharStr) +{ + WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; + + // Try to convert to stack buffer first. + int cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, szStackBuffer, _countof(szStackBuffer)); + if (cch) { + // Copy from stack. + sWideCharStr.assign(szStackBuffer, szStackBuffer + cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0); + sWideCharStr.resize(cch); + cch = ::MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, sWideCharStr.data(), cch); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int SecureMultiByteToWideChar(_In_ UINT CodePage, _In_ DWORD dwFlags, _In_ const std::basic_string &sMultiByteStr, _Out_ std::basic_string &sWideCharStr) +{ + WCHAR szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(WCHAR)]; + + // Try to convert to stack buffer first. + int cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szStackBuffer, _countof(szStackBuffer)); + if (cch) { + // Copy from stack. + sWideCharStr.assign(szStackBuffer, cch); + } else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Query the required output size. Allocate buffer. Then convert again. + cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), NULL, 0); + std::unique_ptr szBuffer(new WCHAR[cch]); + cch = ::MultiByteToWideChar(CodePage, dwFlags, sMultiByteStr.c_str(), (int)sMultiByteStr.length(), szBuffer.get(), cch); + sWideCharStr.assign(szBuffer.get(), cch); + SecureZeroMemory(szBuffer.get(), sizeof(WCHAR)*cch); + } + + SecureZeroMemory(szStackBuffer, sizeof(szStackBuffer)); + + return cch; +} + + +template +inline int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Inout_ std::basic_string &sBuffer) { // Get read-only pointer to string resource. LPCSTR pszStr; @@ -1366,7 +1819,7 @@ inline int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ template -inline int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ std::basic_string &sBuffer) +inline int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Inout_ std::basic_string &sBuffer) { // Get read-only pointer to string resource. LPCWSTR pszStr; @@ -1379,7 +1832,7 @@ inline int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_ } -inline VOID OutputDebugStrV(_In_ LPCSTR lpOutputString, _In_ va_list arg) +inline VOID OutputDebugStrV(_In_z_ LPCSTR lpOutputString, _In_ va_list arg) { std::string str; vsprintf(str, lpOutputString, arg); @@ -1387,7 +1840,7 @@ inline VOID OutputDebugStrV(_In_ LPCSTR lpOutputString, _In_ va_list arg) } -inline VOID OutputDebugStrV(_In_ LPCWSTR lpOutputString, _In_ va_list arg) +inline VOID OutputDebugStrV(_In_z_ LPCWSTR lpOutputString, _In_ va_list arg) { std::wstring str; vsprintf(str, lpOutputString, arg); @@ -1395,7 +1848,7 @@ inline VOID OutputDebugStrV(_In_ LPCWSTR lpOutputString, _In_ va_list arg) } -inline VOID OutputDebugStr(_In_ LPCSTR lpOutputString, ...) +inline VOID OutputDebugStr(_In_z_ LPCSTR lpOutputString, ...) { va_list arg; va_start(arg, lpOutputString); @@ -1404,7 +1857,7 @@ inline VOID OutputDebugStr(_In_ LPCSTR lpOutputString, ...) } -inline VOID OutputDebugStr(_In_ LPCWSTR lpOutputString, ...) +inline VOID OutputDebugStr(_In_z_ LPCWSTR lpOutputString, ...) { va_list arg; va_start(arg, lpOutputString); @@ -1413,7 +1866,7 @@ inline VOID OutputDebugStr(_In_ LPCWSTR lpOutputString, ...) } -template inline int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_ LPCSTR lpFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sDate) +template inline int GetDateFormatA(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCSTR lpFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sDate) { int iResult = GetDateFormatA(Locale, dwFlags, lpDate, lpFormat, NULL, 0); if (iResult) { @@ -1428,7 +1881,7 @@ template inline int GetDateFormatA(_In_ L } -template inline int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_ LPCWSTR lpFormat, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sDate) +template inline int GetDateFormatW(_In_ LCID Locale, _In_ DWORD dwFlags, _In_opt_ const SYSTEMTIME *lpDate, _In_opt_z_ LPCWSTR lpFormat, _Inout_ std::basic_string<_Elem, _Traits, _Ax> &sDate) { int iResult = GetDateFormatW(Locale, dwFlags, lpDate, lpFormat, NULL, 0); if (iResult) { @@ -1444,7 +1897,7 @@ template inline int GetDateFormatW(_In_ L template -inline BOOL LookupAccountSidA(_In_opt_ LPCSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) +inline BOOL LookupAccountSidA(_In_opt_z_ LPCSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) { assert(0); // TODO: Test this code. @@ -1479,7 +1932,7 @@ inline BOOL LookupAccountSidA(_In_opt_ LPCSTR lpSystemName, _In_ PSID lpSid, _Ou template -inline BOOL LookupAccountSidW(_In_opt_ LPCWSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) +inline BOOL LookupAccountSidW(_In_opt_z_ LPCWSTR lpSystemName, _In_ PSID lpSid, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sName, _Out_opt_ std::basic_string<_Elem, _Traits, _Ax> *sReferencedDomainName, _Out_ PSID_NAME_USE peUse) { assert(0); // TODO: Test this code. @@ -1514,7 +1967,7 @@ inline BOOL LookupAccountSidW(_In_opt_ LPCWSTR lpSystemName, _In_ PSID lpSid, _O template -inline BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_ std::unique_ptr<_Ty> &TokenInformation) +inline BOOL GetTokenInformation(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Inout_ std::unique_ptr<_Ty> &TokenInformation) { BYTE szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(BYTE)]; DWORD dwSize; diff --git a/include/WinStd/WinSock2.h b/include/WinStd/WinSock2.h new file mode 100644 index 00000000..35685c4e --- /dev/null +++ b/include/WinStd/WinSock2.h @@ -0,0 +1,176 @@ +/* + Copyright 1991-2019 Amebis + Copyright 2016 GÉANT + + This file is part of WinStd. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +/// +/// \defgroup WinSock2API WinSock2 API +/// Integrates WinStd classes with Microsoft WinSock2 API +/// + +#include "Common.h" + +namespace winstd +{ + class WINSTD_API ws2_runtime_error; +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502) + class WINSTD_API addrinfo; +#endif +} + +#pragma once + +#include +#include +#include + + +namespace winstd +{ + /// \addtogroup WinStdExceptions + /// @{ + + /// + /// WinSock2 runtime error + /// + class WINSTD_API ws2_runtime_error : public num_runtime_error + { + public: + /// + /// Constructs an exception + /// + /// \param[in] num WinSock2 error code + /// \param[in] msg Error message + /// + inline ws2_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error(num, msg) + { + } + + + /// + /// Constructs an exception + /// + /// \param[in] num WinSock2 error code + /// \param[in] msg Error message + /// + inline ws2_runtime_error(_In_ error_type num, _In_z_ const char *msg) : num_runtime_error(num, msg) + { + } + + + /// + /// Constructs an exception using `WSAGetLastError()` + /// + /// \param[in] msg Error message + /// + inline ws2_runtime_error(_In_ const std::string& msg) : num_runtime_error(WSAGetLastError(), msg) + { + } + + + /// + /// Constructs an exception using `WSAGetLastError()` + /// + /// \param[in] msg Error message + /// + inline ws2_runtime_error(_In_z_ const char *msg) : num_runtime_error(WSAGetLastError(), msg) + { + } + + + /// + /// Copies an exception + /// + /// \param[in] other Exception to copy from + /// + inline ws2_runtime_error(const ws2_runtime_error &other) : num_runtime_error(other) + { + } + + + /// + /// Returns a user-readable Windows error message + /// + /// \sa [FormatMessage function](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-formatmessage) + /// + inline tstring msg(_In_opt_ DWORD dwLanguageId = 0) const + { + tstring str; + if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, m_num, dwLanguageId, str, NULL)) { + // Stock Windows error messages contain CRLF. Well... Trim all the trailing white space. + str.erase(str.find_last_not_of(_T(" \t\n\r\f\v")) + 1); + } else + sprintf(str, m_num >= 0x10000 ? _T("Error 0x%X") : _T("Error %u"), m_num); + return str; + } + }; + + /// @} + + + /// \addtogroup WinSock2API + /// @{ + +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502) + + /// + /// SID wrapper class + /// + class WINSTD_API addrinfo : public handle + { + HANDLE_IMPL(addrinfo, NULL) + + public: + /// + /// Provides protocol-independent translation from a host name to an address. + /// + /// \sa [GetAddrInfoW function](https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-getaddrinfow) + /// + inline bool get( + _In_opt_ PCTSTR pNodeName, + _In_opt_ PCTSTR pServiceName, + _In_opt_ const ADDRINFOT *pHints) + { + handle_type h; + if (GetAddrInfo(pNodeName, pServiceName, pHints, &h) == 0) { + attach(h); + return true; + } else + return false; + } + + /// + /// Frees address information + /// + /// \sa [FreeAddrInfoW function](https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-freeaddrinfow) + /// + virtual ~addrinfo(); + + protected: + /// + /// Frees address information + /// + /// \sa [FreeAddrInfoW function](https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-freeaddrinfow) + /// + virtual void free_internal(); + }; + +#endif + + /// @} +} diff --git a/include/WinStd/WinTrust.h b/include/WinStd/WinTrust.h index 9f8a6b06..dceb26b9 100644 --- a/include/WinStd/WinTrust.h +++ b/include/WinStd/WinTrust.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -27,6 +27,8 @@ #include "Common.h" +#include + namespace winstd { class WINSTD_API wintrust; @@ -34,8 +36,6 @@ namespace winstd #pragma once -#include - namespace winstd { diff --git a/src/Base64.cpp b/src/Base64.cpp index f466d7e1..c163ab06 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. diff --git a/src/COM.cpp b/src/COM.cpp index 03073201..7b74fa9a 100644 --- a/src/COM.cpp +++ b/src/COM.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -27,7 +27,7 @@ winstd::bstr::~bstr() { - if (m_h) + if (m_h != invalid) SysFreeString(m_h); } diff --git a/src/Crypt.cpp b/src/Crypt.cpp index 15685ea7..a535052f 100644 --- a/src/Crypt.cpp +++ b/src/Crypt.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -29,7 +29,7 @@ winstd::cert_context::~cert_context() { - if (m_h) + if (m_h != invalid) CertFreeCertificateContext(m_h); } @@ -52,7 +52,7 @@ winstd::cert_context::handle_type winstd::cert_context::duplicate_internal(_In_ winstd::cert_chain_context::~cert_chain_context() { - if (m_h) + if (m_h != invalid) CertFreeCertificateChain(m_h); } @@ -75,7 +75,7 @@ winstd::cert_chain_context::handle_type winstd::cert_chain_context::duplicate_in winstd::cert_store::~cert_store() { - if (m_h) + if (m_h != invalid) CertCloseStore(m_h, 0); } @@ -92,7 +92,7 @@ void winstd::cert_store::free_internal() winstd::crypt_prov::~crypt_prov() { - if (m_h) + if (m_h != invalid) CryptReleaseContext(m_h, 0); } @@ -109,7 +109,7 @@ void winstd::crypt_prov::free_internal() winstd::crypt_hash::~crypt_hash() { - if (m_h) + if (m_h != invalid) CryptDestroyHash(m_h); } @@ -122,8 +122,8 @@ void winstd::crypt_hash::free_internal() winstd::crypt_hash::handle_type winstd::crypt_hash::duplicate_internal(_In_ handle_type h) const { - handle_type hNew = NULL; - return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : NULL; + handle_type hNew = invalid; + return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : invalid; } @@ -133,7 +133,7 @@ winstd::crypt_hash::handle_type winstd::crypt_hash::duplicate_internal(_In_ hand winstd::crypt_key::~crypt_key() { - if (m_h) + if (m_h != invalid) CryptDestroyKey(m_h); } @@ -209,8 +209,8 @@ void winstd::crypt_key::free_internal() winstd::crypt_key::handle_type winstd::crypt_key::duplicate_internal(_In_ handle_type h) const { - handle_type hNew = NULL; - return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : NULL; + handle_type hNew = invalid; + return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : invalid; } @@ -220,6 +220,6 @@ winstd::crypt_key::handle_type winstd::crypt_key::duplicate_internal(_In_ handle winstd::data_blob::~data_blob() { - if (pbData) + if (pbData != NULL) LocalFree(pbData); } diff --git a/src/EAP.cpp b/src/EAP.cpp index 013d29d2..b632a8ab 100644 --- a/src/EAP.cpp +++ b/src/EAP.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -80,7 +80,7 @@ const EAP_ATTRIBUTE winstd::eap_attr::blank = {}; winstd::eap_packet::~eap_packet() { - if (m_h) + if (m_h != invalid) HeapFree(GetProcessHeap(), 0, m_h); } @@ -95,9 +95,9 @@ winstd::eap_packet::handle_type winstd::eap_packet::duplicate_internal(_In_ hand { WORD n = ntohs(*(WORD*)h->Length); handle_type h2 = (handle_type)HeapAlloc(GetProcessHeap(), 0, n); - if (!h2) { + if (h2 == invalid) { SetLastError(ERROR_OUTOFMEMORY); - return NULL; + return invalid; } memcpy(h2, h, n); diff --git a/src/ETW.cpp b/src/ETW.cpp index dabb8a09..34123938 100644 --- a/src/ETW.cpp +++ b/src/ETW.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -118,7 +118,7 @@ void winstd::event_rec::set_user_data_internal(_In_ USHORT size, _In_bytecount_( winstd::event_provider::~event_provider() { - if (m_h) + if (m_h != invalid) EventUnregister(m_h); } @@ -155,7 +155,7 @@ VOID NTAPI winstd::event_provider::enable_callback(_In_ LPCGUID SourceId, _In_ U winstd::event_session::~event_session() { - if (m_h) + if (m_h != invalid) ControlTrace(m_h, name(), m_prop.get(), EVENT_TRACE_CONTROL_STOP); } @@ -192,7 +192,7 @@ winstd::event_trace_enabler::~event_trace_enabler() winstd::event_trace::~event_trace() { - if (m_h) + if (m_h != invalid) CloseTrace(m_h); } diff --git a/src/Sec.cpp b/src/Sec.cpp index c63eaf8e..1eb84378 100644 --- a/src/Sec.cpp +++ b/src/Sec.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. diff --git a/src/SetupAPI.cpp b/src/SetupAPI.cpp new file mode 100644 index 00000000..c0a80771 --- /dev/null +++ b/src/SetupAPI.cpp @@ -0,0 +1,51 @@ +/* + Copyright 1991-2019 Amebis + Copyright 2016 GÉANT + + This file is part of WinStd. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#include "StdAfx.h" + +#pragma comment(lib, "Setupapi.lib") + + +////////////////////////////////////////////////////////////////////// +// winstd::setup_device_info_list +////////////////////////////////////////////////////////////////////// + +winstd::setup_device_info_list::~setup_device_info_list() +{ + if (m_h != invalid) + SetupDiDestroyDeviceInfoList(m_h); +} + + +void winstd::setup_device_info_list::free_internal() +{ + SetupDiDestroyDeviceInfoList(m_h); +} + + +////////////////////////////////////////////////////////////////////// +// winstd::setup_device_info_list +////////////////////////////////////////////////////////////////////// + +winstd::setup_driver_info_list_builder::~setup_driver_info_list_builder() +{ + if (m_result) + SetupDiDestroyDriverInfoList(m_DeviceInfoSet, m_DeviceInfoData, m_DriverType); +} diff --git a/src/StdAfx.cpp b/src/StdAfx.cpp index c853b3de..7b3f7dc7 100644 --- a/src/StdAfx.cpp +++ b/src/StdAfx.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. diff --git a/src/StdAfx.h b/src/StdAfx.h index c01fc7bd..71647d0a 100644 --- a/src/StdAfx.h +++ b/src/StdAfx.h @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -20,6 +20,8 @@ #pragma once +#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h. + #include "../include/WinStd/Base64.h" #include "../include/WinStd/COM.h" #include "../include/WinStd/Cred.h" @@ -33,8 +35,10 @@ #if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL) || defined(SECURITY_MAC) #include "../include/WinStd/Sec.h" #endif +#include "../include/WinStd/SetupAPI.h" #include "../include/WinStd/Shell.h" #include "../include/WinStd/Win.h" +#include "../include/WinStd/WinSock2.h" #include "../include/WinStd/WinTrust.h" #include "../include/WinStd/WLAN.h" #include "../include/WinStd/Common.h" diff --git a/src/WLAN.cpp b/src/WLAN.cpp index bb27b634..9e4ae2a3 100644 --- a/src/WLAN.cpp +++ b/src/WLAN.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -27,7 +27,7 @@ winstd::wlan_handle::~wlan_handle() { - if (m_h) + if (m_h != invalid) WlanCloseHandle(m_h, NULL); } @@ -36,5 +36,3 @@ void winstd::wlan_handle::free_internal() { WlanCloseHandle(m_h, NULL); } - - diff --git a/src/Win.cpp b/src/Win.cpp index 665a4075..2bcd3cb1 100644 --- a/src/Win.cpp +++ b/src/Win.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd. @@ -151,30 +151,13 @@ _Success_(return) BOOL WINSTD_API StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ L } -////////////////////////////////////////////////////////////////////// -// winstd::win_handle -////////////////////////////////////////////////////////////////////// - -winstd::win_handle::~win_handle() -{ - if (m_h) - CloseHandle(m_h); -} - - -void winstd::win_handle::free_internal() -{ - CloseHandle(m_h); -} - - ////////////////////////////////////////////////////////////////////// // winstd::library ////////////////////////////////////////////////////////////////////// winstd::library::~library() { - if (m_h) + if (m_h != invalid) FreeLibrary(m_h); } @@ -185,13 +168,47 @@ void winstd::library::free_internal() } +////////////////////////////////////////////////////////////////////// +// winstd::critical_section +////////////////////////////////////////////////////////////////////// + +winstd::critical_section::critical_section() +{ + InitializeCriticalSection(&m_data); +} + + +winstd::critical_section::~critical_section() +{ + DeleteCriticalSection(&m_data); +} + + +////////////////////////////////////////////////////////////////////// +// winstd::find_file +////////////////////////////////////////////////////////////////////// + +winstd::find_file::~find_file() +{ + if (m_h != invalid) { + FindClose(m_h); + } +} + + +void winstd::find_file::free_internal() +{ + FindClose(m_h); +} + + ////////////////////////////////////////////////////////////////////// // winstd::heap ////////////////////////////////////////////////////////////////////// winstd::heap::~heap() { - if (m_h) { + if (m_h != invalid) { enumerate(); HeapDestroy(m_h); } @@ -200,6 +217,8 @@ winstd::heap::~heap() bool winstd::heap::enumerate() { + assert(m_h != invalid); + bool found = false; // Lock the heap for exclusive access. @@ -277,13 +296,31 @@ winstd::user_impersonator::~user_impersonator() } +////////////////////////////////////////////////////////////////////// +// winstd::console_ctrl_handler +////////////////////////////////////////////////////////////////////// + +winstd::console_ctrl_handler::console_ctrl_handler(_In_opt_ PHANDLER_ROUTINE HandlerRoutine) : + m_handler(HandlerRoutine) +{ + m_cookie = SetConsoleCtrlHandler(m_handler, TRUE); +} + + +winstd::console_ctrl_handler::~console_ctrl_handler() +{ + if (m_cookie) + SetConsoleCtrlHandler(m_handler, FALSE); +} + + ////////////////////////////////////////////////////////////////////// // winstd::vmemory ////////////////////////////////////////////////////////////////////// winstd::vmemory::~vmemory() { - if (m_h) + if (m_h != invalid) VirtualFreeEx(m_proc, m_h, 0, MEM_RELEASE); } @@ -300,7 +337,7 @@ void winstd::vmemory::free_internal() winstd::reg_key::~reg_key() { - if (m_h) + if (m_h != invalid) RegCloseKey(m_h); } @@ -317,7 +354,7 @@ void winstd::reg_key::free_internal() winstd::security_id::~security_id() { - if (m_h) + if (m_h != invalid) FreeSid(m_h); } diff --git a/src/WinSock2.cpp b/src/WinSock2.cpp new file mode 100644 index 00000000..6a417e4a --- /dev/null +++ b/src/WinSock2.cpp @@ -0,0 +1,42 @@ +/* + Copyright 1991-2019 Amebis + Copyright 2016 GÉANT + + This file is part of WinStd. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#include "StdAfx.h" + + +#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502) + +////////////////////////////////////////////////////////////////////// +// winstd::addrinfo +////////////////////////////////////////////////////////////////////// + +winstd::addrinfo::~addrinfo() +{ + if (m_h != invalid) + FreeAddrInfo(m_h); +} + + +void winstd::addrinfo::free_internal() +{ + FreeAddrInfo(m_h); +} + +#endif diff --git a/src/WinTrust.cpp b/src/WinTrust.cpp index ca74c56b..53d47507 100644 --- a/src/WinTrust.cpp +++ b/src/WinTrust.cpp @@ -1,5 +1,5 @@ /* - Copyright 1991-2018 Amebis + Copyright 1991-2019 Amebis Copyright 2016 GÉANT This file is part of WinStd.