Discontinue forward declarations

They are pain to maintain. We'll use them only if really needed (cyclic
dependencies).

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2022-02-04 11:33:08 +01:00
parent e513782854
commit 921aa9f4e9
15 changed files with 1776 additions and 2543 deletions

View File

@ -4,36 +4,15 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinStdCOM COM object management
/// Provides helper templates for Windows COM object manipulation
///
#pragma once
#include "Common.h"
#include <unknwn.h>
#include <string>
namespace winstd
{
class com_runtime_error;
struct CoTaskMemFree_delete;
template <class T> class com_obj;
class bstr;
class variant;
class com_initializer;
}
#pragma once
#include <unknwn.h>
namespace winstd
{
///
/// \defgroup WinStdExceptions Exceptions
/// Additional exceptions
///
/// \addtogroup WinStdExceptions
/// @{
///
@ -54,7 +33,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -67,7 +45,11 @@ namespace winstd
};
/// @}
/// \addtogroup WinStdCOM
///
/// \defgroup WinStdCOM COM object management
/// Provides helper templates for Windows COM object manipulation
///
/// @{
///
@ -111,7 +93,6 @@ namespace winstd
CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (LPVOID*)&m_h);
}
///
/// Queries the object for another interface and creates new class with it
///
@ -124,7 +105,6 @@ namespace winstd
other->QueryInterface(__uuidof(T), (void**)&m_h);
}
///
/// Queries the object for another interface and creates new class with it
///
@ -136,7 +116,6 @@ namespace winstd
other->QueryInterface(__uuidof(T), (void**)&m_h);
}
///
/// Releases object
///
@ -146,7 +125,6 @@ namespace winstd
free_internal();
}
///
/// Creates a new object
///
@ -161,7 +139,6 @@ namespace winstd
return hr;
}
///
/// Queries the object for another interface
///
@ -175,7 +152,6 @@ namespace winstd
return m_h->QueryInterface(__uuidof(_Other), (void**)h);
}
///
/// Queries the object for another interface
///
@ -203,7 +179,6 @@ namespace winstd
m_h->Release();
}
///
/// Duplicates the object by incrementing the reference counter
///
@ -220,7 +195,6 @@ namespace winstd
}
};
///
/// BSTR string wrapper
///
@ -301,7 +275,6 @@ namespace winstd
}
};
///
/// VARIANT struct wrapper
///
@ -680,7 +653,6 @@ namespace winstd
return *this;
}
///
/// Copy from long long value
///
@ -1057,7 +1029,6 @@ namespace winstd
};
#pragma warning(pop)
///
/// Context scope automatic COM (un)initialization
///
@ -1077,7 +1048,6 @@ namespace winstd
m_result = CoInitialize(pvReserved);
}
///
/// Initializes the COM library for use by the calling thread, sets the thread's concurrency model, and creates a new apartment for the thread if one is required.
///
@ -1088,7 +1058,6 @@ namespace winstd
m_result = CoInitializeEx(pvReserved, dwCoInit);
}
///
/// Uninitializes COM.
///
@ -1100,7 +1069,6 @@ namespace winstd
CoUninitialize();
}
///
/// Return result of `CoInitialize()` call.
///

View File

@ -4,41 +4,23 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinStdGeneral General
/// General API
///
/// \defgroup WinStdSysHandles System Handles
/// Simplifies work with object handles of various type
///
/// \defgroup WinStdExceptions Exceptions
/// Additional exceptions
///
/// \defgroup WinStdStrFormat String Formatting
/// Formatted string generation
///
/// \par Example
/// \code
/// // Please note the PCSTR typecasting invokes an operator to return
/// // pointer to formatted buffer rather than class reference itself.
/// cout << (PCSTR)(winstd::string_printf("%i is less than %i.\n", 1, 5));
/// \endcode
///
/// \defgroup WinStdMemSanitize Auto-sanitize Memory Management
/// Sanitizes memory before dismissed
///
#pragma once
#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h.
#include <Windows.h>
#include <assert.h>
#include <stdarg.h>
#include <tchar.h>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
/// \addtogroup WinStdGeneral
///
/// \defgroup WinStdGeneral General
/// General API
///
/// @{
///
@ -81,10 +63,35 @@ private: \
C (_Inout_ C &&h) noexcept; \
C& operator=(_Inout_ C &&h) noexcept;
#ifndef WINSTD_STACK_BUFFER_BYTES
///
/// Size of the stack buffer in bytes used for initial system function call
///
/// Some system functions with variable length output data fail for
/// insufficient buffer sizes, and return an exact buffer length required.
/// The function helpers use a fixed size stack buffer first. If the stack
/// buffer really prooved sufficient, the helper allocates the exact length
/// output on heap and copies the data without calling the system function
/// again. Otherwise it allocates the exact length output on heap and retries.
///
/// \note
/// Decrease this value in case of stack overflow.
///
#define WINSTD_STACK_BUFFER_BYTES 1024
#endif
/// @}
/// \addtogroup WinStdStrFormat
/// \defgroup WinStdStrFormat String Formatting
/// Formatted string generation
///
/// \par Example
/// \code
/// // Please note the PCSTR typecasting invokes an operator to return
/// // pointer to formatted buffer rather than class reference itself.
/// cout << (PCSTR)(winstd::string_printf("%i is less than %i.\n", 1, 5));
/// \endcode
///
/// @{
///
@ -119,8 +126,10 @@ private: \
/// @}
/// \addtogroup WinStdSysHandles
///
/// \defgroup WinStdSysHandles System Handles
/// Simplifies work with object handles of various type
///
/// @{
///
@ -151,166 +160,21 @@ private:
/// @}
#ifndef _FormatMessage_format_string_
#define _FormatMessage_format_string_ _In_z_
#endif
#ifndef _LPCBYTE_DEFINED
#define _LPCBYTE_DEFINED
typedef const BYTE *LPCBYTE;
#endif
namespace winstd
{
/// \addtogroup WinStdStrFormat
/// @{
///
/// Multi-byte / Wide-character string (according to _UNICODE)
///
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
/// @}
template <class _Ty> struct LocalFree_delete;
template <class _Ty> struct LocalFree_delete<_Ty[]>;
template<class _Ty, class _Dx = std::default_delete<_Ty>> class ref_unique_ptr;
template<class _Ty, class _Dx> class ref_unique_ptr<_Ty[], _Dx>;
template <class T, T INVAL> class handle;
template <class T, T INVAL> class dplhandle;
template <class T> class vector_queue;
template <typename _Tn> class num_runtime_error;
class win_runtime_error;
/// \addtogroup WinStdGeneral
/// @{
///
/// Helper function template for returning pointers to std::unique_ptr
///
/// \param[inout] owner Original owner of the pointer
///
/// \returns A helper wrapper class to handle returning a reference to the pointer
///
template<class _Ty, class _Dx> ref_unique_ptr<_Ty, _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty, _Dx> &owner) noexcept;
///
/// Helper function template for returning pointers to std::unique_ptr
/// (specialization for arrays)
///
/// \param[inout] owner Original owner of the pointer
///
/// \returns A helper wrapper class to handle returning a reference to the pointer
///
template<class _Ty, class _Dx> ref_unique_ptr<_Ty[], _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept;
/// @}
/// \addtogroup WinStdStrFormat
/// @{
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem> > class basic_string_printf;
///
/// Single-byte character implementation of a class to support string formatting using `printf()` style templates
///
typedef basic_string_printf<char, std::char_traits<char>, std::allocator<char> > string_printf;
///
/// Wide character implementation of a class to support string formatting using `printf()` style templates
///
typedef basic_string_printf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > wstring_printf;
///
/// Multi-byte / Wide-character formatted string (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_printf tstring_printf;
#else
typedef string_printf tstring_printf;
#endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem> > class basic_string_msg;
///
/// Single-byte character implementation of a class to support string formatting using `FormatMessage()` style templates
///
typedef basic_string_msg<char, std::char_traits<char>, std::allocator<char> > string_msg;
///
/// Wide character implementation of a class to support string formatting using `FormatMessage()` style templates
///
typedef basic_string_msg<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > wstring_msg;
///
/// Multi-byte / Wide-character formatted string (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_msg tstring_msg;
#else
typedef string_msg tstring_msg;
#endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem> > class basic_string_guid;
class string_guid;
class wstring_guid;
///
/// Multi-byte / Wide-character string GUID (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_guid tstring_guid;
#else
typedef string_guid tstring_guid;
#endif
/// @}
/// \addtogroup WinStdMemSanitize
/// @{
template<class _Ty> class sanitizing_allocator;
template<size_t N> class sanitizing_blob;
///
/// A sanitizing variant of std::string
///
/// \note
/// `sanitizing_string` introduces a performance penalty. However, it provides an additional level of security.
/// Use for security sensitive data memory storage only.
///
typedef std::basic_string<char, std::char_traits<char>, sanitizing_allocator<char> > sanitizing_string;
///
/// A sanitizing variant of std::wstring
///
/// \note
/// `sanitizing_wstring` introduces a performance penalty. However, it provides an additional level of security.
/// Use for security sensitive data memory storage only.
///
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, sanitizing_allocator<wchar_t> > sanitizing_wstring;
///
/// Multi-byte / Wide-character sanitizing string (according to _UNICODE)
///
#ifdef _UNICODE
typedef sanitizing_wstring sanitizing_tstring;
#else
typedef sanitizing_string sanitizing_tstring;
#endif
/// @}
}
#pragma warning(push)
// Do not use _vsnprintf_s/_vsnwprintf_s(), since it terminates string by force even when we explicitly want to write unterminated string.
// Threfore turn off compiler warning instead. ;)
#pragma warning(disable: 4995)
#pragma warning(disable: 4996)
#pragma warning(disable: 4505) // Don't warn on unused code
/// \addtogroup WinStdStrFormat
/// @{
@ -326,7 +190,10 @@ namespace winstd
/// \returns Number of characters in result.
///
#if _MSC_VER <= 1600
static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ va_list arg);
static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ va_list arg)
{
return _vsnprintf(str, capacity, format, arg);
}
#endif
///
@ -339,7 +206,10 @@ static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_
///
/// \returns Number of characters in result.
///
static int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const wchar_t *format, _In_ va_list arg) noexcept;
static int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const wchar_t *format, _In_ va_list arg) noexcept
{
return _vsnwprintf(str, capacity, format, arg);
}
///
/// Formats string using `printf()`.
@ -351,7 +221,29 @@ static int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _
/// \returns Number of characters in result.
///
template<class _Elem, class _Traits, class _Ax>
static int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg);
static 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)];
// Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf) - 1, format, arg);
if (count >= 0) {
// Copy from stack.
str.assign(buf, count);
} else {
for (size_t capacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; capacity *= 2) {
// Allocate on heap and retry.
auto buf_dyn = std::make_unique<_Elem[]>(capacity);
count = vsnprintf(buf_dyn.get(), capacity - 1, format, arg);
if (count >= 0) {
str.assign(buf_dyn.get(), count);
break;
}
}
}
return count;
}
///
/// Formats string using `printf()`.
@ -362,7 +254,14 @@ static int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_
/// \returns Number of characters in result.
///
template<class _Elem, class _Traits, class _Ax>
static int sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...);
static 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);
const int res = vsprintf(str, format, arg);
va_end(arg);
return res;
}
///
/// Formats a message string.
@ -370,7 +269,14 @@ static int sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _
/// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx)
///
template<class _Traits, class _Ax>
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<char, _Traits, _Ax> &str, _In_opt_ va_list *Arguments);
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<char, _Traits, _Ax> &str, _In_opt_ va_list *Arguments)
{
std::unique_ptr<CHAR[], winstd::LocalFree_delete<CHAR[]> > lpBuffer;
DWORD dwResult = FormatMessageA(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPSTR>((LPSTR*)get_ptr(lpBuffer)), 0, Arguments);
if (dwResult)
str.assign(lpBuffer.get(), dwResult);
return dwResult;
}
///
/// Formats a message string.
@ -378,47 +284,33 @@ static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ D
/// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx)
///
template<class _Traits, class _Ax>
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &str, _In_opt_ va_list *Arguments);
/// @}
#pragma once
#include <assert.h>
#include <tchar.h>
#include <memory>
#include <vector>
/// \addtogroup WinStdGeneral
/// @{
#ifndef WINSTD_STACK_BUFFER_BYTES
///
/// Size of the stack buffer in bytes used for initial system function call
///
/// Some system functions with variable length output data fail for
/// insufficient buffer sizes, and return an exact buffer length required.
/// The function helpers use a fixed size stack buffer first. If the stack
/// buffer really prooved sufficient, the helper allocates the exact length
/// output on heap and copies the data without calling the system function
/// again. Otherwise it allocates the exact length output on heap and retries.
///
/// \note
/// Decrease this value in case of stack overflow.
///
#define WINSTD_STACK_BUFFER_BYTES 1024
#endif
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &str, _In_opt_ va_list *Arguments)
{
std::unique_ptr<WCHAR[], winstd::LocalFree_delete<WCHAR[]> > lpBuffer;
DWORD dwResult = FormatMessageW(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPWSTR>((LPWSTR*)get_ptr(lpBuffer)), 0, Arguments);
if (dwResult)
str.assign(lpBuffer.get(), dwResult);
return dwResult;
}
/// @}
#pragma warning(pop)
namespace winstd
{
/// \addtogroup WinStdGeneral
/// @{
///
/// Multi-byte / Wide-character string (according to _UNICODE)
///
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
///
/// Deleter for unique_ptr using LocalFree
///
@ -448,7 +340,6 @@ namespace winstd
}
};
///
/// Deleter for unique_ptr to array of unknown size using LocalFree
///
@ -482,7 +373,6 @@ namespace winstd
}
};
///
/// Helper class for returning pointers to std::unique_ptr
///
@ -546,6 +436,32 @@ namespace winstd
_Ty *m_ptr; ///< Pointer
};
///
/// Helper function template for returning pointers to std::unique_ptr
///
/// \param[inout] owner Original owner of the pointer
///
/// \returns A helper wrapper class to handle returning a reference to the pointer
///
template<class _Ty, class _Dx>
ref_unique_ptr<_Ty, _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty, _Dx> &owner) noexcept
{
return ref_unique_ptr<_Ty, _Dx>(owner);
}
///
/// Helper function template for returning pointers to std::unique_ptr
/// (specialization for arrays)
///
/// \param[inout] owner Original owner of the pointer
///
/// \returns A helper wrapper class to handle returning a reference to the pointer
///
template<class _Ty, class _Dx>
ref_unique_ptr<_Ty[], _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept
{
return ref_unique_ptr<_Ty[], _Dx>(owner);
}
///
/// Helper class for returning pointers to std::unique_ptr
@ -649,21 +565,8 @@ namespace winstd
};
#pragma warning(pop)
template<class _Ty, class _Dx>
ref_unique_ptr<_Ty, _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty, _Dx> &owner) noexcept
{
return ref_unique_ptr<_Ty, _Dx>(owner);
}
template<class _Ty, class _Dx>
ref_unique_ptr<_Ty[], _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept
{
return ref_unique_ptr<_Ty[], _Dx>(owner);
}
/// @}
/// \addtogroup WinStdSysHandles
/// @{
@ -930,11 +833,9 @@ namespace winstd
handle_type m_h; ///< Object handle
};
template <class T, const T INVAL>
const T handle<T, INVAL>::invalid = INVAL;
///
/// Base abstract template class to support object handle keeping for objects that support handle duplication
///
@ -1475,7 +1376,10 @@ namespace winstd
/// @}
/// \addtogroup WinStdExceptions
///
/// \defgroup WinStdExceptions Exceptions
/// Additional exceptions
///
/// @{
///
@ -1500,7 +1404,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -1513,7 +1416,6 @@ namespace winstd
{
}
///
/// Returns the Windows error number
///
@ -1526,7 +1428,6 @@ namespace winstd
error_type m_num; ///< Numeric error code
};
///
/// Windows runtime error
///
@ -1543,7 +1444,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -1554,7 +1454,6 @@ namespace winstd
{
}
///
/// Constructs an exception using `GetLastError()`
///
@ -1564,7 +1463,6 @@ namespace winstd
{
}
///
/// Constructs an exception using `GetLastError()`
///
@ -1574,7 +1472,6 @@ namespace winstd
{
}
///
/// Returns a user-readable Windows error message
///
@ -1663,6 +1560,24 @@ namespace winstd
/// }@
};
///
/// Single-byte character implementation of a class to support string formatting using `printf()` style templates
///
typedef basic_string_printf<char, std::char_traits<char>, std::allocator<char> > string_printf;
///
/// Wide character implementation of a class to support string formatting using `printf()` style templates
///
typedef basic_string_printf<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > wstring_printf;
///
/// Multi-byte / Wide-character formatted string (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_printf tstring_printf;
#else
typedef string_printf tstring_printf;
#endif
///
/// Base template class to support string formatting using `FormatMessage()` style templates
@ -1729,7 +1644,6 @@ namespace winstd
/// @}
///
/// Initializes a new string and formats its contents using `FormatMessage()` style.
///
@ -1740,7 +1654,6 @@ namespace winstd
FormatMessage(dwFlags & ~FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, Arguments);
}
///
/// Initializes a new string and formats its contents using `FormatMessage()` style.
///
@ -1751,7 +1664,6 @@ namespace winstd
FormatMessage(dwFlags | FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, (va_list*)Arguments);
}
///
/// Initializes a new string and formats its contents using `FormatMessage()` style.
///
@ -1762,7 +1674,6 @@ namespace winstd
FormatMessage(dwFlags & ~FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, *this, Arguments);
}
///
/// Initializes a new string and formats its contents using `FormatMessage()` style.
///
@ -1774,6 +1685,24 @@ namespace winstd
}
};
///
/// Single-byte character implementation of a class to support string formatting using `FormatMessage()` style templates
///
typedef basic_string_msg<char, std::char_traits<char>, std::allocator<char> > string_msg;
///
/// Wide character implementation of a class to support string formatting using `FormatMessage()` style templates
///
typedef basic_string_msg<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > wstring_msg;
///
/// Multi-byte / Wide-character formatted string (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_msg tstring_msg;
#else
typedef string_msg tstring_msg;
#endif
///
/// Base template class to support converting GUID to string
@ -1804,7 +1733,6 @@ namespace winstd
/// @}
};
///
/// Single-byte character implementation of a class to support converting GUID to string
///
@ -1827,7 +1755,6 @@ namespace winstd
/// @}
};
///
/// Wide character implementation of a class to support converting GUID to string
///
@ -1850,9 +1777,21 @@ namespace winstd
/// @}
};
///
/// Multi-byte / Wide-character string GUID (according to _UNICODE)
///
#ifdef _UNICODE
typedef wstring_guid tstring_guid;
#else
typedef string_guid tstring_guid;
#endif
/// @}
/// \addtogroup WinStdMemSanitize
///
/// \defgroup WinStdMemSanitize Auto-sanitize Memory Management
/// Sanitizes memory before dismissed
///
/// @{
// winstd::sanitizing_allocator::destroy() member generates _Ptr parameter not used warning for primitive datatypes _Ty.
@ -1881,7 +1820,6 @@ namespace winstd
typedef sanitizing_allocator<_Other> other; ///< Other type
};
///
/// Construct default allocator
///
@ -1889,7 +1827,6 @@ namespace winstd
{
}
///
/// Construct by copying
///
@ -1897,7 +1834,6 @@ namespace winstd
{
}
///
/// Construct from a related allocator
///
@ -1906,7 +1842,6 @@ namespace winstd
{
}
///
/// Deallocate object at _Ptr sanitizing its content first
///
@ -1920,6 +1855,33 @@ namespace winstd
#pragma warning(pop)
///
/// A sanitizing variant of std::string
///
/// \note
/// `sanitizing_string` introduces a performance penalty. However, it provides an additional level of security.
/// Use for security sensitive data memory storage only.
///
typedef std::basic_string<char, std::char_traits<char>, sanitizing_allocator<char> > sanitizing_string;
///
/// A sanitizing variant of std::wstring
///
/// \note
/// `sanitizing_wstring` introduces a performance penalty. However, it provides an additional level of security.
/// Use for security sensitive data memory storage only.
///
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, sanitizing_allocator<wchar_t> > sanitizing_wstring;
///
/// Multi-byte / Wide-character sanitizing string (according to _UNICODE)
///
#ifdef _UNICODE
typedef sanitizing_wstring sanitizing_tstring;
#else
typedef sanitizing_string sanitizing_tstring;
#endif
///
/// Sanitizing BLOB
///
@ -1949,87 +1911,3 @@ namespace winstd
/// @}
}
#pragma warning(push)
// Do not use _vsnprintf_s/_vsnwprintf_s(), since it terminates string by force even when we explicitly want to write unterminated string.
// Threfore turn off compiler warning instead. ;)
#pragma warning(disable: 4995)
#pragma warning(disable: 4996)
#pragma warning(disable: 4505) // Don't warn on unused code
#if _MSC_VER <= 1600
static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ va_list arg)
{
return _vsnprintf(str, capacity, format, arg);
}
#endif
static int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const wchar_t *format, _In_ va_list arg) noexcept
{
return _vsnwprintf(str, capacity, format, arg);
}
template<class _Elem, class _Traits, class _Ax>
static 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)];
// Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf) - 1, format, arg);
if (count >= 0) {
// Copy from stack.
str.assign(buf, count);
} else {
for (size_t capacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; capacity *= 2) {
// Allocate on heap and retry.
auto buf_dyn = std::make_unique<_Elem[]>(capacity);
count = vsnprintf(buf_dyn.get(), capacity - 1, format, arg);
if (count >= 0) {
str.assign(buf_dyn.get(), count);
break;
}
}
}
return count;
}
template<class _Elem, class _Traits, class _Ax>
static 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);
const int res = vsprintf(str, format, arg);
va_end(arg);
return res;
}
template<class _Traits, class _Ax>
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<char, _Traits, _Ax> &str, _In_opt_ va_list *Arguments)
{
std::unique_ptr<CHAR[], winstd::LocalFree_delete<CHAR[]> > lpBuffer;
DWORD dwResult = FormatMessageA(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPSTR>((LPSTR*)get_ptr(lpBuffer)), 0, Arguments);
if (dwResult)
str.assign(lpBuffer.get(), dwResult);
return dwResult;
}
template<class _Traits, class _Ax>
static DWORD FormatMessage(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &str, _In_opt_ va_list *Arguments)
{
std::unique_ptr<WCHAR[], winstd::LocalFree_delete<WCHAR[]> > lpBuffer;
DWORD dwResult = FormatMessageW(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPWSTR>((LPWSTR*)get_ptr(lpBuffer)), 0, Arguments);
if (dwResult)
str.assign(lpBuffer.get(), dwResult);
return dwResult;
}
#pragma warning(pop)

View File

@ -4,37 +4,41 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinStdCryptoAPI Cryptography API
/// Integrates WinStd classes with Microsoft Cryptography API
///
#pragma once
#include "Common.h"
#include <wincred.h>
#include <memory>
namespace winstd
{
template <class _Ty> struct CredFree_delete;
template <class _Ty> struct CredFree_delete<_Ty[]>;
}
/// \addtogroup WinStdCryptoAPI
///
/// \defgroup WinStdCredAPI Credentials API
/// Integrates WinStd classes with Microsoft Credentials API
///
/// @{
///
/// Enumerates the credentials from the user's credential set. The credential set used is the one associated with the logon session of the current token. The token must not have the user's SID disabled.
///
/// \sa [CredEnumerate function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794.aspx)
///
static BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Inout_ std::unique_ptr<PCREDENTIAL[], winstd::CredFree_delete<PCREDENTIAL[]> > &cCredentials) noexcept;
/// @copydoc CredProtectW()
template<class _Traits, class _Ax>
static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]);
if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
///
/// Encrypts the specified credentials so that only the current security context can decrypt them.
@ -42,11 +46,51 @@ static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR ps
/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
///
template<class _Traits, class _Ax>
static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
/// @copydoc CredUnprotectW()
template<class _Traits, class _Ax>
static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sCredentials);
static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sCredentials)
{
char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]);
if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
///
/// Decrypts credentials that were previously encrypted by using the CredProtect function.
@ -54,16 +98,33 @@ static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR
/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
///
template<class _Traits, class _Ax>
static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sCredentials);
static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sCredentials)
{
wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
/// @}
#pragma once
namespace winstd
{
/// \addtogroup WinStdCryptoAPI
/// \addtogroup WinStdCredAPI
/// @{
///
@ -94,7 +155,6 @@ namespace winstd
}
};
///
/// Deleter for unique_ptr to array of unknown size using CredFree
///
@ -132,11 +192,15 @@ namespace winstd
/// @}
}
/// \addtogroup WinStdCredAPI
/// @{
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
///
/// Enumerates the credentials from the user's credential set. The credential set used is the one associated with the logon session of the current token. The token must not have the user's SID disabled.
///
/// \sa [CredEnumerate function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794.aspx)
///
#pragma warning(suppress: 4505) // Don't warn on unused code
static BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ DWORD *Count, _Inout_ std::unique_ptr<PCREDENTIAL[], winstd::CredFree_delete<PCREDENTIAL[]> > &cCredentials) noexcept
{
PCREDENTIAL *pCredentials;
@ -148,100 +212,4 @@ static BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ D
return FALSE;
}
template<class _Traits, class _Ax>
static BOOL CredProtectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]);
if (CredProtectA(fAsSelf, const_cast<LPSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
template<class _Traits, class _Ax>
static BOOL CredProtectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
{
wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf, &dwSize, ProtectionType)) {
// Copy from stack.
sProtectedCredentials.assign(buf, dwSize - 1);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
if (CredProtectW(fAsSelf, const_cast<LPWSTR>(pszCredentials), cchCredentials, buf.get(), &dwSize, ProtectionType)) {
sProtectedCredentials.assign(buf.get(), dwSize - 1);
return TRUE;
}
}
return FALSE;
}
template<class _Traits, class _Ax>
static BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<char, _Traits, _Ax> &sCredentials)
{
char buf[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<char[]> buf(new char[dwSize]);
if (CredUnprotectA(fAsSelf, const_cast<LPSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
template<class _Traits, class _Ax>
static BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_count_(cchCredentials) LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sCredentials)
{
wchar_t buf[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
DWORD dwSize = _countof(buf);
// Try with the stack buffer first.
if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf, &dwSize)) {
// Copy from stack.
sCredentials.assign(buf, dwSize);
return TRUE;
} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Allocate on heap and retry.
std::unique_ptr<wchar_t[]> buf(new wchar_t[dwSize]);
if (CredUnprotectW(fAsSelf, const_cast<LPWSTR>(pszProtectedCredentials), cchCredentials, buf.get(), &dwSize)) {
sCredentials.assign(buf.get(), dwSize);
return TRUE;
}
}
return FALSE;
}
#pragma warning(pop)
/// @}

View File

@ -4,35 +4,34 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <assert.h>
#include <WinCrypt.h>
#include <algorithm>
#include <string>
#include <vector>
///
/// \defgroup WinStdCryptoAPI Cryptography API
/// Integrates WinStd classes with Microsoft Cryptography API
///
#include "Common.h"
#include <WinCrypt.h>
#include <string>
#include <vector>
namespace winstd
{
class cert_context;
class cert_chain_context;
class cert_store;
class crypt_prov;
class crypt_hash;
class crypt_key;
class data_blob;
}
/// \addtogroup WinStdCryptoAPI
/// @{
/// @copydoc CertGetNameStringW()
template<class _Traits, class _Ax>
static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<char, _Traits, _Ax> &sNameString);
static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<char, _Traits, _Ax> &sNameString)
{
// Query the final string length first.
DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[dwSize]);
dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
}
///
/// 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.
@ -40,7 +39,17 @@ static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
/// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
///
template<class _Traits, class _Ax>
static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sNameString);
static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sNameString)
{
// Query the final string length first.
DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]);
dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
}
///
/// Retrieves the information contained in an extended property of a certificate context.
@ -48,7 +57,24 @@ static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwT
/// \sa [CertGetCertificateContextProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376079.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData);
static _Success_(return != 0) BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CertGetCertificateContextProperty(pCertContext, dwPropId, buf, &dwSize)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CertGetCertificateContextProperty(pCertContext, dwPropId, (BYTE*)aData.data(), &dwSize))
return TRUE;
}
return FALSE;
}
///
/// Retrieves data that governs the operations of a hash object. The actual hash value can be retrieved by using this function.
@ -56,7 +82,36 @@ static _Success_(return != 0) BOOL WINAPI CertGetCertificateContextProperty(_In_
/// \sa [CryptGetHashParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379947.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags);
static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CryptGetHashParam(hHash, dwParam, buf, &dwSize, dwFlags)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptGetHashParam(hHash, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
return TRUE;
}
return FALSE;
}
///
/// 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<class T>
static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
{
DWORD dwSize = sizeof(T);
return CryptGetHashParam(hHash, dwParam, (BYTE*)&data, &dwSize, dwFlags);
}
///
/// Retrieves data that governs the operations of a key.
@ -64,7 +119,24 @@ static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_
/// \sa [CryptGetKeyParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379949.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags);
static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CryptGetKeyParam(hKey, dwParam, buf, &dwSize, dwFlags)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptGetKeyParam(hKey, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
return TRUE;
}
return FALSE;
}
///
/// Retrieves data that governs the operations of a key.
@ -72,7 +144,11 @@ static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DW
/// \sa [CryptGetKeyParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379949.aspx)
///
template<class T>
static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags);
static BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
{
DWORD dwSize = sizeof(T);
return CryptGetKeyParam(hKey, dwParam, (BYTE*)&data, &dwSize, dwFlags);
}
///
/// Exports a cryptographic key or a key pair from a cryptographic service provider (CSP) in a secure manner.
@ -80,7 +156,18 @@ static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DW
/// \sa [CryptExportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379931.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData);
static _Success_(return != 0) BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData)
{
DWORD dwKeyBLOBSize = 0;
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) {
aData.resize((dwKeyBLOBSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.data(), &dwKeyBLOBSize))
return TRUE;
}
return FALSE;
}
///
/// Encrypts data.
@ -88,7 +175,49 @@ static _Success_(return != 0) BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRY
/// \sa [CryptEncrypt function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379924.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData);
static _Success_(return != 0) BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
{
DWORD
dwDataLen = (DWORD)(aData.size() * sizeof(_Ty)),
dwBufLen = (DWORD)(aData.capacity() * sizeof(_Ty)),
dwEncLen = dwDataLen,
dwResult;
if (dwBufLen) {
aData.resize(dwBufLen);
if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
// Encryption succeeded.
assert(dwEncLen <= dwBufLen);
if (dwEncLen < dwBufLen)
aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else
dwResult = GetLastError();
} else if (CryptEncrypt(hKey, NULL, Final, dwFlags, NULL, &dwEncLen, 0)) {
// CryptEncrypt() always succeeds for output data size queries.
// dwEncLen contains required output data size. Continue as if the buffer was to small. Actually, the output buffer _was_ too small!
dwResult = ERROR_MORE_DATA;
} else
dwResult = GetLastError();
if (dwResult == ERROR_MORE_DATA) {
// Encrypted data will be longer. Reserve more space and retry.
aData.resize(((dwBufLen = dwEncLen) + sizeof(_Ty) - 1) / sizeof(_Ty));
dwEncLen = dwDataLen;
if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
// Encryption succeeded.
assert(dwEncLen <= dwBufLen);
if (dwEncLen < dwBufLen)
aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
}
} else {
// Resize back to data length.
aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
}
return FALSE;
}
///
/// Decrypts data previously encrypted by using the CryptEncrypt function.
@ -96,17 +225,21 @@ static _Success_(return != 0) BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HC
/// \sa [CryptDecrypt function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379913.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptDecrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData);
static _Success_(return != 0) BOOL CryptDecrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
{
DWORD dwDataLen = (DWORD)(aData.size() * sizeof(_Ty));
if (CryptDecrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwDataLen)) {
// Decryption succeeded.
aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
}
return FALSE;
}
/// @}
#pragma once
#include <assert.h>
#include <algorithm>
namespace winstd
{
/// \addtogroup WinStdCryptoAPI
@ -261,7 +394,6 @@ namespace winstd
}
};
///
/// PCCERT_CHAIN_CONTEXT wrapper class
///
@ -326,7 +458,6 @@ namespace winstd
}
};
///
/// HCERTSTORE wrapper class
///
@ -396,7 +527,6 @@ namespace winstd
}
};
///
/// HCRYPTPROV wrapper class
///
@ -447,7 +577,6 @@ namespace winstd
}
};
///
/// HCRYPTHASH wrapper class
///
@ -513,7 +642,6 @@ namespace winstd
}
};
///
/// HCRYPTKEY wrapper class
///
@ -815,186 +943,3 @@ namespace winstd
/// @}
}
template<class _Traits, class _Ax>
static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<char, _Traits, _Ax> &sNameString)
{
// Query the final string length first.
DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<char[]> szBuffer(new char[dwSize]);
dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
}
template<class _Traits, class _Ax>
static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sNameString)
{
// Query the final string length first.
DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
// Allocate buffer on heap to format the string data into and read it.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]);
dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
sNameString.assign(szBuffer.get(), dwSize - 1);
return dwSize;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CertGetCertificateContextProperty(pCertContext, dwPropId, buf, &dwSize)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CertGetCertificateContextProperty(pCertContext, dwPropId, (BYTE*)aData.data(), &dwSize))
return TRUE;
}
return FALSE;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CryptGetHashParam(hHash, dwParam, buf, &dwSize, dwFlags)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptGetHashParam(hHash, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
return TRUE;
}
return FALSE;
}
template<class T>
static BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
{
DWORD dwSize = sizeof(T);
return CryptGetHashParam(hHash, dwParam, (BYTE*)&data, &dwSize, dwFlags);
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
{
BYTE buf[WINSTD_STACK_BUFFER_BYTES];
DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
// Try with the stack buffer first.
if (CryptGetKeyParam(hKey, dwParam, buf, &dwSize, dwFlags)) {
// Copy from stack.
aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) {
aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptGetKeyParam(hKey, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
return TRUE;
}
return FALSE;
}
template<class T>
static BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
{
DWORD dwSize = sizeof(T);
return CryptGetKeyParam(hKey, dwParam, (BYTE*)&data, &dwSize, dwFlags);
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData)
{
DWORD dwKeyBLOBSize = 0;
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) {
aData.resize((dwKeyBLOBSize + sizeof(_Ty) - 1) / sizeof(_Ty));
if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.data(), &dwKeyBLOBSize))
return TRUE;
}
return FALSE;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
{
DWORD
dwDataLen = (DWORD)(aData.size() * sizeof(_Ty)),
dwBufLen = (DWORD)(aData.capacity() * sizeof(_Ty)),
dwEncLen = dwDataLen,
dwResult;
if (dwBufLen) {
aData.resize(dwBufLen);
if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
// Encryption succeeded.
assert(dwEncLen <= dwBufLen);
if (dwEncLen < dwBufLen)
aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
} else
dwResult = GetLastError();
} else if (CryptEncrypt(hKey, NULL, Final, dwFlags, NULL, &dwEncLen, 0)) {
// CryptEncrypt() always succeeds for output data size queries.
// dwEncLen contains required output data size. Continue as if the buffer was to small. Actually, the output buffer _was_ too small!
dwResult = ERROR_MORE_DATA;
} else
dwResult = GetLastError();
if (dwResult == ERROR_MORE_DATA) {
// Encrypted data will be longer. Reserve more space and retry.
aData.resize(((dwBufLen = dwEncLen) + sizeof(_Ty) - 1) / sizeof(_Ty));
dwEncLen = dwDataLen;
if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
// Encryption succeeded.
assert(dwEncLen <= dwBufLen);
if (dwEncLen < dwBufLen)
aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
}
} else {
// Resize back to data length.
aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
}
return FALSE;
}
template<class _Ty, class _Ax>
static _Success_(return != 0) BOOL CryptDecrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
{
DWORD dwDataLen = (DWORD)(aData.size() * sizeof(_Ty));
if (CryptDecrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwDataLen)) {
// Decryption succeeded.
aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE;
}
return FALSE;
}

View File

@ -4,59 +4,27 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <eaphostpeerconfigapis.h>
#include <eaptypes.h>
#include <EapHostPeerTypes.h>
#include <eapmethodtypes.h>
#include <eappapis.h>
#include <WinSock2.h>
#include <memory>
#pragma warning(push)
#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
///
/// \defgroup WinStdEAPAPI Extensible Authentication Protocol API
/// Integrates WinStd classes with Microsoft EAP API
///
#include "Common.h"
#include <eaphostpeerconfigapis.h>
#include <eaptypes.h>
#include <memory>
namespace winstd
{
enum class eap_type_t : unsigned char;
struct EapHostPeerFreeMemory_delete;
struct EapHostPeerFreeRuntimeMemory_delete;
struct EapHostPeerFreeErrorMemory_delete;
struct EapHostPeerFreeEapError_delete;
class eap_attr;
class eap_method_prop;
class eap_packet;
class eap_method_info_array;
class eap_runtime_error;
/// \addtogroup WinStdEAPAPI
/// @{
///
/// EapHost BLOB wrapper class
///
typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
///
/// EapHost BLOB wrapper class
///
typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
///
/// EAP_ERROR wrapper class
///
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
///
/// EAP_ERROR wrapper class
///
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
/// @}
}
/// \addtogroup WinStdEAPAPI
/// @{
///
@ -69,7 +37,14 @@ namespace winstd
/// - Non zero when \p a is equal to \p b;
/// - Zero otherwise.
///
static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept;
static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return
a.eapType.type == b.eapType.type &&
a.eapType.dwVendorId == b.eapType.dwVendorId &&
a.eapType.dwVendorType == b.eapType.dwVendorType &&
a.dwAuthorId == a.dwAuthorId;
}
///
/// Are EAP method types non-equal?
@ -81,19 +56,14 @@ static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE
/// - Non zero when \p a is not equal to \p b;
/// - Zero otherwise.
///
static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept;
static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return !operator==(a, b);
}
/// @}
#pragma once
#include <EapHostPeerTypes.h>
#include <eapmethodtypes.h>
#include <eappapis.h>
#include <WinSock2.h>
#pragma warning(push)
#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
#pragma warning(pop)
namespace winstd
{
@ -131,7 +101,6 @@ namespace winstd
noneap_end = 254, ///< End of non-EAP methods (non-inclusive)
};
///
/// Deleter for unique_ptr using EapHostPeerFreeMemory
///
@ -154,6 +123,10 @@ namespace winstd
}
};
///
/// EapHost BLOB wrapper class
///
typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
///
/// Deleter for unique_ptr using EapHostPeerFreeRuntimeMemory
@ -175,6 +148,10 @@ namespace winstd
}
};
///
/// EapHost BLOB wrapper class
///
typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
///
/// Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeErrorMemory
@ -197,6 +174,10 @@ namespace winstd
}
};
///
/// EAP_ERROR wrapper class
///
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
///
/// Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeEapError
@ -219,6 +200,10 @@ namespace winstd
}
};
///
/// EAP_ERROR wrapper class
///
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
///
/// EAP_ATTRIBUTE wrapper class
@ -371,7 +356,6 @@ namespace winstd
///
static const EAP_ATTRIBUTE blank_eap_attr = {};
///
/// EAP_METHOD_PROPERTY wrapper class
///
@ -392,7 +376,6 @@ namespace winstd
eapMethodPropertyValue.empvBool.value = value;
}
///
/// Constructs a DWORD method property
///
@ -407,7 +390,6 @@ namespace winstd
eapMethodPropertyValue.empvDword.value = value;
}
///
/// Constructs a Unicode string method property
///
@ -423,7 +405,6 @@ namespace winstd
}
};
///
/// EapPacket wrapper class
///
@ -441,7 +422,6 @@ namespace winstd
free_internal();
}
///
/// Create new EAP packet
///
@ -473,7 +453,6 @@ namespace winstd
}
}
///
/// Returns total EAP packet size in bytes.
///
@ -482,7 +461,6 @@ namespace winstd
return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
}
protected:
///
/// Destroys the EAP packet.
@ -508,7 +486,6 @@ namespace winstd
}
};
///
/// EAP_METHOD_INFO_ARRAY wrapper class
///
@ -591,10 +568,7 @@ namespace winstd
/// @}
///
/// \defgroup WinStdExceptions Exceptions
/// Additional exceptions
///
/// \addtogroup WinStdExceptions
/// @{
///
@ -623,7 +597,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -642,7 +615,6 @@ namespace winstd
{
}
///
/// Returns EAP method type
///
@ -651,7 +623,6 @@ namespace winstd
return m_type;
}
///
/// Returns the reason code for error
///
@ -660,7 +631,6 @@ namespace winstd
return m_reason;
}
///
/// Returns root cause ID
///
@ -669,7 +639,6 @@ namespace winstd
return m_root_cause_id;
}
///
/// Returns root cause ID
///
@ -678,7 +647,6 @@ namespace winstd
return m_root_cause_desc.c_str();
}
///
/// Returns repair ID
///
@ -687,7 +655,6 @@ namespace winstd
return m_repair_id;
}
///
/// Returns root cause ID
///
@ -696,7 +663,6 @@ namespace winstd
return m_repair_desc.c_str();
}
///
/// Returns help_link ID
///
@ -722,24 +688,4 @@ namespace winstd
/// @}
}
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return
a.eapType.type == b.eapType.type &&
a.eapType.dwVendorId == b.eapType.dwVendorId &&
a.eapType.dwVendorType == b.eapType.dwVendorType &&
a.dwAuthorId == a.dwAuthorId;
}
static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return !operator==(a, b);
}
#pragma warning(pop)
#pragma warning(pop)

View File

@ -4,64 +4,108 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinStdETWAPI Event Tracing for Windows API
/// Integrates WinStd classes with Event Tracing for Windows API
///
#pragma once
#include "Common.h"
#include <assert.h>
#include <evntprov.h>
#include <evntcons.h>
#include <stdarg.h>
#include <tdh.h>
#include <memory>
#include <string>
#include <vector>
namespace winstd
{
class event_data;
class event_rec;
class event_provider;
class event_session;
class event_trace;
class event_trace_enabler;
class event_fn_auto;
template<class T> class event_fn_auto_ret;
}
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
/// \addtogroup WinStdCryptoAPI
///
/// \defgroup WinStdETWAPI Event Tracing for Windows API
/// Integrates WinStd classes with Event Tracing for Windows API
///
/// @{
///
/// Retrieves metadata about an event.
///
/// \sa [TdhGetEventInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964840.aspx)
///
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr<TRACE_EVENT_INFO> &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)
///
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr<EVENT_MAP_INFO> &info);
///
/// Retrieves a property value from the event data.
///
/// \sa [TdhGetProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964843.aspx)
///
template<class _Ty, class _Ax>
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_reads_(PropertyDataCount) PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData);
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_reads_(PropertyDataCount) PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData)
{
ULONG ulSize, ulResult;
// Query property size.
ulResult = TdhGetPropertySize(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, &ulSize);
if (ulResult == ERROR_SUCCESS) {
if (ulSize) {
// Query property value.
aData.resize((ulSize + sizeof(_Ty) - 1) / sizeof(_Ty));
ulResult = TdhGetProperty(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, ulSize, reinterpret_cast<LPBYTE>(aData.data()));
} else {
// Property value size is zero.
aData.clear();
}
}
return ulResult;
}
///
/// Retrieves metadata about an event.
///
/// \sa [TdhGetEventInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964840.aspx)
///
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr<TRACE_EVENT_INFO> &info)
{
BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
ULONG ulSize = sizeof(szBuffer), ulResult;
// Try with stack buffer first.
ulResult = TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, (PTRACE_EVENT_INFO)szBuffer, &ulSize);
if (ulResult == ERROR_SUCCESS) {
// Copy from stack.
info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
memcpy(info.get(), szBuffer, ulSize);
return ERROR_SUCCESS;
} else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
// Create buffer on heap and retry.
info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
return TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, info.get(), &ulSize);
}
return ulResult;
}
///
/// Retrieves information about the event map contained in the event.
///
/// \sa [TdhGetEventMapInformation function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964841.aspx)
///
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr<EVENT_MAP_INFO> &info)
{
BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
ULONG ulSize = sizeof(szBuffer), ulResult;
// Try with stack buffer first.
ulResult = TdhGetEventMapInformation(pEvent, pMapName, (PEVENT_MAP_INFO)szBuffer, &ulSize);
if (ulResult == ERROR_SUCCESS) {
// Copy from stack.
info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
memcpy(info.get(), szBuffer, ulSize);
return ERROR_SUCCESS;
} else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
// Create buffer on heap and retry.
info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
return TdhGetEventMapInformation(pEvent, pMapName, info.get(), &ulSize);
}
return ulResult;
}
/// @}
#pragma once
#pragma warning(pop)
namespace winstd
{
@ -84,7 +128,6 @@ namespace winstd
Reserved = (ULONG)-1; // Used for varadic argument terminator.
}
///
/// Construct class pointing to an `char`.
///
@ -98,7 +141,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to an `unsigned char`.
///
@ -112,7 +154,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to an `int`.
///
@ -126,7 +167,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to an `unsigned int`.
///
@ -140,7 +180,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to a `long`.
///
@ -154,7 +193,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to an `unsigned long`.
///
@ -168,7 +206,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to a `GUID`.
///
@ -182,7 +219,6 @@ namespace winstd
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
}
///
/// Construct class pointing to a string.
///
@ -202,7 +238,6 @@ namespace winstd
}
}
///
/// Construct class pointing to a wide string.
///
@ -222,7 +257,6 @@ namespace winstd
}
}
///
/// Template to construct pointing to a `std::basic_string<>`.
///
@ -237,7 +271,6 @@ namespace winstd
EventDataDescCreate(this, data.c_str(), (ULONG)((data.length() + 1) * sizeof(_Elem)));
}
///
/// Construct class pointing to binary data.
///
@ -258,7 +291,6 @@ namespace winstd
///
static const event_data blank_event_data;
///
/// EVENT_RECORD wrapper
///
@ -273,7 +305,6 @@ namespace winstd
memset((EVENT_RECORD*)this, 0, sizeof(EVENT_RECORD));
}
///
/// Copies an existing event record.
///
@ -285,7 +316,6 @@ namespace winstd
set_user_data_internal(other.UserDataLength, other.UserData);
}
///
/// Copies an existing event record.
///
@ -297,7 +327,6 @@ namespace winstd
set_user_data_internal(other.UserDataLength, other.UserData);
}
///
/// Moves the event record.
///
@ -308,7 +337,6 @@ namespace winstd
memset((EVENT_RECORD*)&other, 0, sizeof(EVENT_RECORD));
}
///
/// Destroys event record data and frees the allocated memory.
///
@ -321,7 +349,6 @@ namespace winstd
delete reinterpret_cast<unsigned char*>(UserData);
}
///
/// Copies an existing event record.
///
@ -338,7 +365,6 @@ namespace winstd
return *this;
}
///
/// Copies an existing event record.
///
@ -355,7 +381,6 @@ namespace winstd
return *this;
}
///
/// Moves the event record.
///
@ -371,7 +396,6 @@ namespace winstd
return *this;
}
///
/// Sets event record extended data.
///
@ -386,7 +410,6 @@ namespace winstd
set_extended_data_internal(count, data);
}
///
/// Sets event record user data.
///
@ -463,7 +486,6 @@ namespace winstd
}
};
///
/// ETW event provider
///
@ -483,7 +505,6 @@ namespace winstd
free_internal();
}
///
/// Registers the event provider.
///
@ -502,7 +523,6 @@ namespace winstd
return ulRes;
}
///
/// Writes an event with no parameters.
///
@ -518,7 +538,6 @@ namespace winstd
return EventWrite(m_h, EventDescriptor, 0, NULL);
}
///
/// Writes an event with parameters stored in array.
///
@ -534,7 +553,6 @@ namespace winstd
return EventWrite(m_h, EventDescriptor, UserDataCount, UserData);
}
///
/// Writes an event with one or more parameter.
///
@ -589,7 +607,6 @@ namespace winstd
#pragma warning(pop)
}
///
/// Writes an event with variable number of parameters.
///
@ -634,7 +651,6 @@ namespace winstd
#pragma warning(pop)
}
///
/// Writes a string event.
///
@ -671,7 +687,6 @@ namespace winstd
EventUnregister(m_h);
}
///
/// Receive enable or disable notification requests
///
@ -687,7 +702,6 @@ namespace winstd
UNREFERENCED_PARAMETER(FilterData);
}
///
/// Receive enable or disable notification requests
///
@ -702,7 +716,6 @@ namespace winstd
}
};
///
/// ETW session
///
@ -718,7 +731,6 @@ namespace winstd
{
}
///
/// Initializes a new session with an already available object handle.
///
@ -732,7 +744,6 @@ namespace winstd
memcpy(m_prop.get(), prop, prop->Wnode.BufferSize);
}
///
/// Move constructor
///
@ -744,7 +755,6 @@ namespace winstd
{
}
///
/// Closes the session.
///
@ -756,7 +766,6 @@ namespace winstd
free_internal();
}
///
/// Move assignment
///
@ -771,7 +780,6 @@ namespace winstd
return *this;
}
///
/// Auto-typecasting operator
///
@ -782,7 +790,6 @@ namespace winstd
return m_prop.get();
}
///
/// Auto-typecasting operator
///
@ -794,7 +801,6 @@ namespace winstd
return reinterpret_cast<LPCTSTR>(reinterpret_cast<const char*>(prop) + prop->LoggerNameOffset);
}
///
/// Sets a new session handle for the class
///
@ -809,7 +815,6 @@ namespace winstd
m_prop.reset(prop);
}
///
/// Registers and starts an event tracing session.
///
@ -830,7 +835,6 @@ namespace winstd
return ulRes;
}
///
/// Enables the specified event trace provider.
///
@ -855,7 +859,6 @@ namespace winstd
EnableFilterDesc);
}
///
/// Disables the specified event trace provider.
///
@ -880,7 +883,6 @@ namespace winstd
EnableFilterDesc);
}
protected:
///
/// Releases the session.
@ -896,7 +898,6 @@ namespace winstd
std::unique_ptr<EVENT_TRACE_PROPERTIES> m_prop; ///< Session properties
};
///
/// ETW trace
///
@ -916,7 +917,6 @@ namespace winstd
free_internal();
}
///
/// Opens a real-time trace session or log file for consuming.
///
@ -948,7 +948,6 @@ namespace winstd
}
};
///
/// Helper class to enable event provider in constructor and disables it in destructor
///
@ -990,7 +989,6 @@ namespace winstd
m_enable_filter_desc);
}
///
/// Enables event trace
///
@ -1025,7 +1023,6 @@ namespace winstd
m_enable_filter_desc);
}
///
/// Return result of `EnableTraceEx()` call.
///
@ -1036,7 +1033,6 @@ namespace winstd
return m_status;
}
///
/// Disables event trace.
///
@ -1069,7 +1065,6 @@ namespace winstd
PEVENT_FILTER_DESCRIPTOR m_enable_filter_desc; ///< Event filter descriptor
};
///
/// Helper class to write an event on entry/exit of scope.
///
@ -1089,7 +1084,6 @@ namespace winstd
m_ep.write(event_cons, 1, &m_fn_name);
}
///
/// Copies the object
///
@ -1100,7 +1094,6 @@ namespace winstd
{
}
///
/// Moves the object
///
@ -1112,7 +1105,6 @@ namespace winstd
other.m_event_dest = NULL;
}
///
/// Writes the `event_dest` event
///
@ -1122,7 +1114,6 @@ namespace winstd
m_ep.write(m_event_dest, 1, &m_fn_name);
}
///
/// Copies the object
///
@ -1137,7 +1128,6 @@ namespace winstd
return *this;
}
///
/// Moves the object
///
@ -1153,14 +1143,12 @@ namespace winstd
return *this;
}
protected:
event_provider &m_ep; ///< Reference to event provider in use
const EVENT_DESCRIPTOR *m_event_dest; ///< Event descriptor at destruction
EVENT_DATA_DESCRIPTOR m_fn_name; ///< Function name
};
///
/// Helper template to write an event on entry/exit of scope with one parameter (typically result).
///
@ -1182,7 +1170,6 @@ namespace winstd
m_ep.write(event_cons, 1, m_desc);
}
///
/// Copies the object
///
@ -1194,7 +1181,6 @@ namespace winstd
m_desc[0] = other.m_desc[0];
}
///
/// Moves the object
///
@ -1207,7 +1193,6 @@ namespace winstd
other.m_event_dest = NULL;
}
///
/// Writes the `event_dest` event
///
@ -1219,7 +1204,6 @@ namespace winstd
}
}
///
/// Copies the object
///
@ -1235,7 +1219,6 @@ namespace winstd
return *this;
}
///
/// Moves the object
///
@ -1252,7 +1235,6 @@ namespace winstd
return *this;
}
protected:
event_provider &m_ep; ///< Reference to event provider in use
const EVENT_DESCRIPTOR *m_event_dest; ///< Event descriptor at destruction
@ -1262,74 +1244,3 @@ namespace winstd
/// @}
}
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventInformation(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _Out_ std::unique_ptr<TRACE_EVENT_INFO> &info)
{
BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
ULONG ulSize = sizeof(szBuffer), ulResult;
// Try with stack buffer first.
ulResult = TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, (PTRACE_EVENT_INFO)szBuffer, &ulSize);
if (ulResult == ERROR_SUCCESS) {
// Copy from stack.
info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
memcpy(info.get(), szBuffer, ulSize);
return ERROR_SUCCESS;
} else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
// Create buffer on heap and retry.
info.reset(reinterpret_cast<PTRACE_EVENT_INFO>(new char[ulSize]));
return TdhGetEventInformation(pEvent, TdhContextCount, pTdhContext, info.get(), &ulSize);
}
return ulResult;
}
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetEventMapInformation(_In_ PEVENT_RECORD pEvent, _In_ LPWSTR pMapName, _Inout_ std::unique_ptr<EVENT_MAP_INFO> &info)
{
BYTE szBuffer[WINSTD_STACK_BUFFER_BYTES];
ULONG ulSize = sizeof(szBuffer), ulResult;
// Try with stack buffer first.
ulResult = TdhGetEventMapInformation(pEvent, pMapName, (PEVENT_MAP_INFO)szBuffer, &ulSize);
if (ulResult == ERROR_SUCCESS) {
// Copy from stack.
info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
memcpy(info.get(), szBuffer, ulSize);
return ERROR_SUCCESS;
} else if (ulResult == ERROR_INSUFFICIENT_BUFFER) {
// Create buffer on heap and retry.
info.reset(reinterpret_cast<PEVENT_MAP_INFO>(new char[ulSize]));
return TdhGetEventMapInformation(pEvent, pMapName, info.get(), &ulSize);
}
return ulResult;
}
template<class _Ty, class _Ax>
static _Success_(return == ERROR_SUCCESS) ULONG TdhGetProperty(_In_ PEVENT_RECORD pEvent, _In_ ULONG TdhContextCount, _In_reads_opt_(TdhContextCount) PTDH_CONTEXT pTdhContext, _In_ ULONG PropertyDataCount, _In_reads_(PropertyDataCount) PPROPERTY_DATA_DESCRIPTOR pPropertyData, _Inout_ std::vector<_Ty, _Ax> &aData)
{
ULONG ulSize, ulResult;
// Query property size.
ulResult = TdhGetPropertySize(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, &ulSize);
if (ulResult == ERROR_SUCCESS) {
if (ulSize) {
// Query property value.
aData.resize((ulSize + sizeof(_Ty) - 1) / sizeof(_Ty));
ulResult = TdhGetProperty(pEvent, TdhContextCount, pTdhContext, PropertyDataCount, pPropertyData, ulSize, reinterpret_cast<LPBYTE>(aData.data()));
} else {
// Property value size is zero.
aData.clear();
}
}
return ulResult;
}
#pragma warning(pop)

View File

@ -3,28 +3,16 @@
Copyright © 1991-2022 Amebis
*/
///
/// \defgroup WinStdGdiAPI GDI API
/// Integrates WinStd classes with Microsoft Windows GDI
///
#pragma once
#include "Common.h"
namespace winstd
{
template<class T> class gdi_handle;
class dc;
class window_dc;
class dc_selector;
}
#pragma once
namespace winstd
{
/// \addtogroup WinStdGdiAPI
///
/// \defgroup WinStdGdiAPI GDI API
/// Integrates WinStd classes with Microsoft Windows GDI
///
/// @{
///
@ -59,7 +47,6 @@ namespace winstd
}
};
///
/// Device context wrapper class
///
@ -91,7 +78,6 @@ namespace winstd
}
};
///
/// Device context wrapper class
///
@ -148,7 +134,6 @@ namespace winstd
HWND m_hwnd; ///< Window handle
};
///
/// Context scope DC object restorer
///
@ -169,7 +154,6 @@ namespace winstd
{
}
///
/// Restores original object.
///
@ -181,7 +165,6 @@ namespace winstd
SelectObject(m_hdc, m_orig);
}
///
/// Return result of `SelectObject()` call.
///

View File

@ -4,94 +4,21 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <MsiQuery.h>
#include <string>
#include <vector>
///
/// \defgroup WinStdMSIAPI Microsoft Installer API
/// Integrates WinStd classes with Microsoft Installer API
///
#include "Common.h"
#include <MsiQuery.h>
#include <string>
#include <vector>
/// \addtogroup WinStdMSIAPI
/// @{
/// @copydoc MsiGetPropertyW()
template<class _Traits, class _Ax>
static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue);
/// @copydoc MsiRecordGetStringW()
template<class _Traits, class _Ax>
static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue);
/// @copydoc MsiFormatRecordW()
template<class _Traits, class _Ax>
static UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<wchar_t, _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<class _Ty, class _Ax>
static UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData);
/// @copydoc MsiGetTargetPathW()
template<class _Traits, class _Ax>
static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue);
/// @copydoc MsiGetComponentPathW()
template<class _Traits, class _Ax>
static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWSTR szComponent, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue);
/// @}
#pragma once
template<class _Traits, class _Ax>
static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
{
@ -119,7 +46,11 @@ static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inou
}
}
///
/// 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<class _Traits, class _Ax>
static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
@ -145,7 +76,7 @@ static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Ino
}
}
/// @copydoc MsiRecordGetStringW()
template<class _Traits, class _Ax>
static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
{
@ -173,7 +104,11 @@ static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
}
}
///
/// 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<class _Traits, class _Ax>
static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
@ -199,7 +134,7 @@ static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
}
}
/// @copydoc MsiFormatRecordW()
template<class _Traits, class _Ax>
static UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
{
@ -227,7 +162,11 @@ static UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _I
}
}
///
/// 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<class _Traits, class _Ax>
static UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
@ -253,7 +192,11 @@ static UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _I
}
}
///
/// 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<class _Ty, class _Ax>
static UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData)
{
@ -273,7 +216,7 @@ static UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField
}
}
/// @copydoc MsiGetTargetPathW()
template<class _Traits, class _Ax>
static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Out_ std::basic_string<char, _Traits, _Ax> &sValue)
{
@ -301,7 +244,11 @@ static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _
}
}
///
/// 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<class _Traits, class _Ax>
static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
@ -327,7 +274,7 @@ static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder,
}
}
/// @copydoc MsiGetComponentPathW()
template<class _Traits, class _Ax>
static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
{
@ -353,7 +300,11 @@ static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR
}
}
///
/// 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<class _Traits, class _Ax>
static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWSTR szComponent, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
@ -378,3 +329,5 @@ static INSTALLSTATE MsiGetComponentPathW(_In_z_ LPCWSTR szProduct, _In_z_ LPCWST
return state;
}
}
/// @}

View File

@ -4,33 +4,47 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <Security.h>
#include <string>
///
/// \defgroup WinStdSecurityAPI Security API
/// Integrates WinStd classes with Microsoft Security API
///
#include "Common.h"
#include <Security.h>
#include <string>
namespace winstd
{
class sec_credentials;
class sec_context;
class sec_buffer_desc;
class sec_runtime_error;
}
/// @{
#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL)
/// \addtogroup WinStdSecurityAPI
/// @{
/// @copydoc GetUserNameExW()
template<class _Traits, class _Ax>
static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<char, _Traits, _Ax> &sName);
static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<char, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::GetUserNameExA(NameFormat, szStackBuffer, &ulSize)) {
// Copy from stack.
sName.assign(szStackBuffer, ulSize);
return TRUE;
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[ulSize]);
if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;
}
}
}
return FALSE;
}
///
/// Retrieves the name of the user or other security principal associated with the calling thread and stores it in a std::wstring string.
@ -38,15 +52,36 @@ static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std:
/// \sa [GetUserNameEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx)
///
template<class _Traits, class _Ax>
static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName);
static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
// Copy from stack.
sName.assign(szStackBuffer, ulSize);
return TRUE;
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]);
if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;
}
}
}
return FALSE;
}
#endif
/// @}
#pragma once
namespace winstd
{
/// \addtogroup WinStdSecurityAPI
@ -161,7 +196,6 @@ namespace winstd
TimeStamp m_expires; ///< Credentials expiration time
};
///
/// PCtxtHandle wrapper class
///
@ -285,7 +319,6 @@ namespace winstd
TimeStamp m_expires; ///< Context expiration time
};
///
/// SecBufferDesc wrapper class
///
@ -318,10 +351,7 @@ namespace winstd
/// @}
///
/// \defgroup WinStdExceptions Exceptions
/// Additional exceptions
///
/// \addtogroup WinStdExceptions
/// @{
///
@ -342,7 +372,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -353,7 +382,6 @@ namespace winstd
{
}
///
/// Copies an exception
///
@ -366,63 +394,3 @@ namespace winstd
/// @}
}
#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL)
template<class _Traits, class _Ax>
static BOOLEAN GetUserNameExA(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<char, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
char szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(char)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::GetUserNameExA(NameFormat, szStackBuffer, &ulSize)) {
// Copy from stack.
sName.assign(szStackBuffer, ulSize);
return TRUE;
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
std::unique_ptr<char[]> szBuffer(new char[ulSize]);
if (::GetUserNameExA(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;
}
}
}
return FALSE;
}
template<class _Traits, class _Ax>
static BOOLEAN GetUserNameExW(_In_ EXTENDED_NAME_FORMAT NameFormat, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sName)
{
assert(0); // TODO: Test this code.
wchar_t szStackBuffer[WINSTD_STACK_BUFFER_BYTES/sizeof(wchar_t)];
ULONG ulSize = _countof(szStackBuffer);
// Try with stack buffer first.
if (::GetUserNameExW(NameFormat, szStackBuffer, &ulSize)) {
// Copy from stack.
sName.assign(szStackBuffer, ulSize);
return TRUE;
} else {
if (::GetLastError() == ERROR_MORE_DATA) {
// Allocate buffer on heap and retry.
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[ulSize]);
if (::GetUserNameExW(NameFormat, szBuffer.get(), &ulSize)) {
sName.assign(szBuffer.get(), ulSize);
return TRUE;
}
}
}
return FALSE;
}
#endif

View File

@ -4,28 +4,17 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <SetupAPI.h>
namespace winstd
{
///
/// \defgroup SetupAPI Setup API
/// Integrates WinStd classes with Microsoft Setup API
///
#include "Common.h"
namespace winstd
{
class setup_device_info_list;
class setup_driver_info_list_builder;
}
#pragma once
#include <SetupAPI.h>
namespace winstd
{
/// \addtogroup SetupAPI
/// @{
///
@ -108,7 +97,6 @@ namespace winstd
}
};
///
/// Builds a list of drivers in constructor and deletes it in destructor
///
@ -145,7 +133,6 @@ namespace winstd
SetupDiDestroyDriverInfoList(m_DeviceInfoSet, m_DeviceInfoData, m_DriverType);
}
///
/// Return result of `SetupDiBuildDriverInfoList()` call.
///

View File

@ -4,36 +4,19 @@
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <Shlwapi.h>
#include <string>
///
/// \defgroup WinStdShellWAPI Shell API
/// Integrates WinStd classes with Microsoft Shell API
///
#include "Common.h"
#include <Shlwapi.h>
#include <string>
/// \addtogroup WinStdShellWAPI
/// @{
/// @copydoc PathCanonicalizeW()
template<class _Traits, class _Ax>
static BOOL PathCanonicalizeA(_Inout_ std::basic_string<char, _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<class _Traits, class _Ax>
static BOOL PathCanonicalizeW(_Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, _In_ LPCWSTR pszPath);
/// @}
#pragma once
template<class _Traits, class _Ax>
static BOOL PathCanonicalizeA(_Inout_ std::basic_string<char, _Traits, _Ax> &sValue, _In_ LPCSTR pszPath)
{
@ -46,7 +29,11 @@ static BOOL PathCanonicalizeA(_Inout_ std::basic_string<char, _Traits, _Ax> &sVa
return bResult;
}
///
/// 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<class _Traits, class _Ax>
static BOOL PathCanonicalizeW(_Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, _In_ LPCWSTR pszPath)
{
@ -57,3 +44,5 @@ static BOOL PathCanonicalizeW(_Inout_ std::basic_string<wchar_t, _Traits, _Ax> &
sValue.assign(szBuffer, bResult ? MAX_PATH : 0);
return bResult;
}
/// @}

View File

@ -4,28 +4,20 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinStdWLANAPI WLAN API
/// Integrates WinStd classes with Microsoft WLAN API
///
#pragma once
#include "Common.h"
#include <wlanapi.h>
#include <string>
// Must not statically link to Wlanapi.dll as it is not available on Windows
// without a WLAN interface.
extern DWORD (WINAPI *pfnWlanReasonCodeToString)(__in DWORD dwReasonCode, __in DWORD dwBufferSize, __in_ecount(dwBufferSize) PWCHAR pStringBuffer, __reserved PVOID pReserved);
namespace winstd {
template <class _Ty> struct WlanFreeMemory_delete;
template <class _Ty> struct WlanFreeMemory_delete<_Ty[]>;
class wlan_handle;
}
/// \addtogroup WinStdWLANAPI
///
/// \defgroup WinStdWLANAPI WLAN API
/// Integrates WinStd classes with Microsoft WLAN API
///
/// @{
///
@ -38,13 +30,36 @@ namespace winstd {
/// function must be loaded dynamically.
///
template<class _Traits, class _Ax>
static DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, __reserved PVOID pReserved);
static DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, __reserved PVOID pReserved)
{
DWORD dwSize = 0;
if (!::pfnWlanReasonCodeToString)
return ERROR_CALL_NOT_IMPLEMENTED;
for (;;) {
// Increment size and allocate buffer.
dwSize += 1024;
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]);
// Try!
DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, dwSize, szBuffer.get(), pReserved);
if (dwResult == ERROR_SUCCESS) {
DWORD dwLength = (DWORD)wcsnlen(szBuffer.get(), dwSize);
if (dwLength < dwSize - 1) {
// Buffer was long enough.
sValue.assign(szBuffer.get(), dwLength);
return ERROR_SUCCESS;
}
} else {
// Return error code.
return dwResult;
}
}
}
/// @}
#pragma once
namespace winstd
{
/// \addtogroup WinStdWLANAPI
@ -76,7 +91,6 @@ namespace winstd
}
};
///
/// Deleter for unique_ptr to array of unknown size using WlanFreeMemory
///
@ -107,7 +121,6 @@ namespace winstd
}
};
///
/// WLAN handle wrapper
///
@ -163,33 +176,3 @@ namespace winstd
/// @}
}
template<class _Traits, class _Ax>
static DWORD WlanReasonCodeToString(_In_ DWORD dwReasonCode, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, __reserved PVOID pReserved)
{
DWORD dwSize = 0;
if (!::pfnWlanReasonCodeToString)
return ERROR_CALL_NOT_IMPLEMENTED;
for (;;) {
// Increment size and allocate buffer.
dwSize += 1024;
std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]);
// Try!
DWORD dwResult = ::pfnWlanReasonCodeToString(dwReasonCode, dwSize, szBuffer.get(), pReserved);
if (dwResult == ERROR_SUCCESS) {
DWORD dwLength = (DWORD)wcsnlen(szBuffer.get(), dwSize);
if (dwLength < dwSize - 1) {
// Buffer was long enough.
sValue.assign(szBuffer.get(), dwLength);
return ERROR_SUCCESS;
}
} else {
// Return error code.
return dwResult;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,31 +4,19 @@
Copyright © 2016 GÉANT
*/
///
/// \defgroup WinSock2API WinSock2 API
/// Integrates WinStd classes with Microsoft WinSock2 API
///
#include "Common.h"
namespace winstd
{
class ws2_runtime_error;
#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502)
class addrinfo;
#endif
}
#pragma once
#include "Common.h"
#include <WinSock2.h>
#include <ws2def.h>
#include <WS2tcpip.h>
namespace winstd
{
/// \addtogroup WinStdExceptions
///
/// \defgroup WinSock2API WinSock2 API
/// Integrates WinStd classes with Microsoft WinSock2 API
///
/// @{
///
@ -47,7 +35,6 @@ namespace winstd
{
}
///
/// Constructs an exception
///
@ -58,7 +45,6 @@ namespace winstd
{
}
///
/// Constructs an exception using `WSAGetLastError()`
///
@ -68,7 +54,6 @@ namespace winstd
{
}
///
/// Constructs an exception using `WSAGetLastError()`
///
@ -78,7 +63,6 @@ namespace winstd
{
}
///
/// Returns a user-readable Windows error message
///
@ -98,7 +82,6 @@ namespace winstd
/// @}
/// \addtogroup WinSock2API
/// @{
@ -141,7 +124,6 @@ namespace winstd
free_internal();
}
protected:
///
/// Frees address information

View File

@ -6,26 +6,15 @@
#pragma once
///
/// \defgroup WinTrustAPI WinTrust API
/// Integrates WinStd classes with Microsoft WinTrust API
///
#include "Common.h"
#include <WinTrust.h>
namespace winstd
{
class wintrust;
}
#pragma once
namespace winstd
{
/// \addtogroup WinTrustAPI
///
/// \defgroup WinTrustAPI WinTrust API
/// Integrates WinStd classes with Microsoft WinTrust API
///
/// @{
///