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:
parent
e513782854
commit
921aa9f4e9
@ -4,36 +4,15 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \defgroup WinStdCOM COM object management
|
|
||||||
/// Provides helper templates for Windows COM object manipulation
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include <unknwn.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
class com_runtime_error;
|
/// \addtogroup WinStdExceptions
|
||||||
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
|
|
||||||
///
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -54,7 +33,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// 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);
|
CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (LPVOID*)&m_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queries the object for another interface and creates new class with it
|
/// 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);
|
other->QueryInterface(__uuidof(T), (void**)&m_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queries the object for another interface and creates new class with it
|
/// 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);
|
other->QueryInterface(__uuidof(T), (void**)&m_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Releases object
|
/// Releases object
|
||||||
///
|
///
|
||||||
@ -146,7 +125,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Creates a new object
|
/// Creates a new object
|
||||||
///
|
///
|
||||||
@ -161,7 +139,6 @@ namespace winstd
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queries the object for another interface
|
/// Queries the object for another interface
|
||||||
///
|
///
|
||||||
@ -175,7 +152,6 @@ namespace winstd
|
|||||||
return m_h->QueryInterface(__uuidof(_Other), (void**)h);
|
return m_h->QueryInterface(__uuidof(_Other), (void**)h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queries the object for another interface
|
/// Queries the object for another interface
|
||||||
///
|
///
|
||||||
@ -203,7 +179,6 @@ namespace winstd
|
|||||||
m_h->Release();
|
m_h->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Duplicates the object by incrementing the reference counter
|
/// Duplicates the object by incrementing the reference counter
|
||||||
///
|
///
|
||||||
@ -220,7 +195,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// BSTR string wrapper
|
/// BSTR string wrapper
|
||||||
///
|
///
|
||||||
@ -301,7 +275,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// VARIANT struct wrapper
|
/// VARIANT struct wrapper
|
||||||
///
|
///
|
||||||
@ -680,7 +653,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copy from long long value
|
/// Copy from long long value
|
||||||
///
|
///
|
||||||
@ -1057,7 +1029,6 @@ namespace winstd
|
|||||||
};
|
};
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Context scope automatic COM (un)initialization
|
/// Context scope automatic COM (un)initialization
|
||||||
///
|
///
|
||||||
@ -1077,7 +1048,6 @@ namespace winstd
|
|||||||
m_result = CoInitialize(pvReserved);
|
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.
|
/// 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);
|
m_result = CoInitializeEx(pvReserved, dwCoInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Uninitializes COM.
|
/// Uninitializes COM.
|
||||||
///
|
///
|
||||||
@ -1100,7 +1069,6 @@ namespace winstd
|
|||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Return result of `CoInitialize()` call.
|
/// Return result of `CoInitialize()` call.
|
||||||
///
|
///
|
||||||
|
@ -4,41 +4,23 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \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
|
|
||||||
///
|
|
||||||
|
|
||||||
#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h.
|
#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h.
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <tchar.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/// \addtogroup WinStdGeneral
|
///
|
||||||
|
/// \defgroup WinStdGeneral General
|
||||||
|
/// General API
|
||||||
|
///
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -81,10 +63,35 @@ private: \
|
|||||||
C (_Inout_ C &&h) noexcept; \
|
C (_Inout_ C &&h) noexcept; \
|
||||||
C& operator=(_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
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// \defgroup WinStdStrFormat String Formatting
|
||||||
/// \addtogroup WinStdStrFormat
|
/// 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_
|
#ifndef _FormatMessage_format_string_
|
||||||
#define _FormatMessage_format_string_ _In_z_
|
#define _FormatMessage_format_string_ _In_z_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef _LPCBYTE_DEFINED
|
#ifndef _LPCBYTE_DEFINED
|
||||||
#define _LPCBYTE_DEFINED
|
#define _LPCBYTE_DEFINED
|
||||||
typedef const BYTE *LPCBYTE;
|
typedef const BYTE *LPCBYTE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
namespace winstd
|
// 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. ;)
|
||||||
/// \addtogroup WinStdStrFormat
|
#pragma warning(disable: 4995)
|
||||||
/// @{
|
#pragma warning(disable: 4996)
|
||||||
|
#pragma warning(disable: 4505) // Don't warn on unused code
|
||||||
///
|
|
||||||
/// 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
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \addtogroup WinStdStrFormat
|
/// \addtogroup WinStdStrFormat
|
||||||
/// @{
|
/// @{
|
||||||
@ -326,7 +190,10 @@ namespace winstd
|
|||||||
/// \returns Number of characters in result.
|
/// \returns Number of characters in result.
|
||||||
///
|
///
|
||||||
#if _MSC_VER <= 1600
|
#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
|
#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.
|
/// \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()`.
|
/// 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.
|
/// \returns Number of characters in result.
|
||||||
///
|
///
|
||||||
template<class _Elem, class _Traits, class _Ax>
|
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()`.
|
/// 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.
|
/// \returns Number of characters in result.
|
||||||
///
|
///
|
||||||
template<class _Elem, class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [FormatMessage function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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);
|
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);
|
||||||
#pragma once
|
if (dwResult)
|
||||||
|
str.assign(lpBuffer.get(), dwResult);
|
||||||
#include <assert.h>
|
return dwResult;
|
||||||
#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
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdGeneral
|
/// \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
|
/// Deleter for unique_ptr using LocalFree
|
||||||
///
|
///
|
||||||
@ -448,7 +340,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Deleter for unique_ptr to array of unknown size using LocalFree
|
/// 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
|
/// Helper class for returning pointers to std::unique_ptr
|
||||||
///
|
///
|
||||||
@ -546,6 +436,32 @@ namespace winstd
|
|||||||
_Ty *m_ptr; ///< Pointer
|
_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
|
/// Helper class for returning pointers to std::unique_ptr
|
||||||
@ -649,21 +565,8 @@ namespace winstd
|
|||||||
};
|
};
|
||||||
#pragma warning(pop)
|
#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
|
/// \addtogroup WinStdSysHandles
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
@ -930,11 +833,9 @@ namespace winstd
|
|||||||
handle_type m_h; ///< Object handle
|
handle_type m_h; ///< Object handle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class T, const T INVAL>
|
template <class T, const T INVAL>
|
||||||
const T handle<T, INVAL>::invalid = INVAL;
|
const T handle<T, INVAL>::invalid = INVAL;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Base abstract template class to support object handle keeping for objects that support handle duplication
|
/// 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
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
@ -1513,7 +1416,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the Windows error number
|
/// Returns the Windows error number
|
||||||
///
|
///
|
||||||
@ -1526,7 +1428,6 @@ namespace winstd
|
|||||||
error_type m_num; ///< Numeric error code
|
error_type m_num; ///< Numeric error code
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Windows runtime error
|
/// Windows runtime error
|
||||||
///
|
///
|
||||||
@ -1543,7 +1444,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
@ -1554,7 +1454,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception using `GetLastError()`
|
/// Constructs an exception using `GetLastError()`
|
||||||
///
|
///
|
||||||
@ -1564,7 +1463,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception using `GetLastError()`
|
/// Constructs an exception using `GetLastError()`
|
||||||
///
|
///
|
||||||
@ -1574,7 +1472,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a user-readable Windows error message
|
/// 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
|
/// 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.
|
/// 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);
|
FormatMessage(dwFlags & ~FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Initializes a new string and formats its contents using `FormatMessage()` style.
|
/// 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);
|
FormatMessage(dwFlags | FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, (va_list*)Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Initializes a new string and formats its contents using `FormatMessage()` style.
|
/// 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);
|
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.
|
/// 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
|
/// 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
|
/// 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
|
/// 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.
|
// 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
|
typedef sanitizing_allocator<_Other> other; ///< Other type
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct default allocator
|
/// Construct default allocator
|
||||||
///
|
///
|
||||||
@ -1889,7 +1827,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct by copying
|
/// Construct by copying
|
||||||
///
|
///
|
||||||
@ -1897,7 +1834,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct from a related allocator
|
/// Construct from a related allocator
|
||||||
///
|
///
|
||||||
@ -1906,7 +1842,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Deallocate object at _Ptr sanitizing its content first
|
/// Deallocate object at _Ptr sanitizing its content first
|
||||||
///
|
///
|
||||||
@ -1920,6 +1855,33 @@ namespace winstd
|
|||||||
|
|
||||||
#pragma warning(pop)
|
#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
|
/// 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)
|
|
||||||
|
@ -4,37 +4,41 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \defgroup WinStdCryptoAPI Cryptography API
|
|
||||||
/// Integrates WinStd classes with Microsoft Cryptography API
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <wincred.h>
|
#include <wincred.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace winstd
|
///
|
||||||
{
|
/// \defgroup WinStdCredAPI Credentials API
|
||||||
template <class _Ty> struct CredFree_delete;
|
/// Integrates WinStd classes with Microsoft Credentials API
|
||||||
template <class _Ty> struct CredFree_delete<_Ty[]>;
|
///
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// \addtogroup WinStdCryptoAPI
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
|
||||||
/// 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()
|
/// @copydoc CredProtectW()
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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()
|
/// @copydoc CredUnprotectW()
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdCryptoAPI
|
/// \addtogroup WinStdCredAPI
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -94,7 +155,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Deleter for unique_ptr to array of unknown size using CredFree
|
/// 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
|
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;
|
PCREDENTIAL *pCredentials;
|
||||||
@ -148,100 +212,4 @@ static BOOL CredEnumerate(_In_z_ LPCTSTR Filter, _Reserved_ DWORD Flags, _Out_ D
|
|||||||
return FALSE;
|
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)
|
|
||||||
|
@ -4,35 +4,34 @@
|
|||||||
Copyright © 2016 GÉANT
|
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
|
/// \defgroup WinStdCryptoAPI Cryptography API
|
||||||
/// Integrates WinStd classes with Microsoft 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()
|
/// @copydoc CertGetNameStringW()
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CertGetCertificateContextProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376079.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CryptGetHashParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379947.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CryptGetKeyParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379949.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CryptGetKeyParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379949.aspx)
|
||||||
///
|
///
|
||||||
template<class T>
|
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.
|
/// 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)
|
/// \sa [CryptExportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379931.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CryptEncrypt function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379924.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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.
|
/// 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)
|
/// \sa [CryptDecrypt function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379913.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdCryptoAPI
|
/// \addtogroup WinStdCryptoAPI
|
||||||
@ -261,7 +394,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// PCCERT_CHAIN_CONTEXT wrapper class
|
/// PCCERT_CHAIN_CONTEXT wrapper class
|
||||||
///
|
///
|
||||||
@ -326,7 +458,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// HCERTSTORE wrapper class
|
/// HCERTSTORE wrapper class
|
||||||
///
|
///
|
||||||
@ -396,7 +527,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// HCRYPTPROV wrapper class
|
/// HCRYPTPROV wrapper class
|
||||||
///
|
///
|
||||||
@ -447,7 +577,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// HCRYPTHASH wrapper class
|
/// HCRYPTHASH wrapper class
|
||||||
///
|
///
|
||||||
@ -513,7 +642,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// HCRYPTKEY wrapper class
|
/// 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;
|
|
||||||
}
|
|
||||||
|
@ -4,59 +4,27 @@
|
|||||||
Copyright © 2016 GÉANT
|
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
|
/// \defgroup WinStdEAPAPI Extensible Authentication Protocol API
|
||||||
/// Integrates WinStd classes with Microsoft EAP 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;
|
/// - Non zero when \p a is equal to \p b;
|
||||||
/// - Zero otherwise.
|
/// - 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?
|
/// 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;
|
/// - Non zero when \p a is not equal to \p b;
|
||||||
/// - Zero otherwise.
|
/// - 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
|
#pragma warning(pop)
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
@ -131,7 +101,6 @@ namespace winstd
|
|||||||
noneap_end = 254, ///< End of non-EAP methods (non-inclusive)
|
noneap_end = 254, ///< End of non-EAP methods (non-inclusive)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Deleter for unique_ptr using EapHostPeerFreeMemory
|
/// 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
|
/// 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
|
/// 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
|
/// 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
|
/// EAP_ATTRIBUTE wrapper class
|
||||||
@ -371,7 +356,6 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
static const EAP_ATTRIBUTE blank_eap_attr = {};
|
static const EAP_ATTRIBUTE blank_eap_attr = {};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// EAP_METHOD_PROPERTY wrapper class
|
/// EAP_METHOD_PROPERTY wrapper class
|
||||||
///
|
///
|
||||||
@ -392,7 +376,6 @@ namespace winstd
|
|||||||
eapMethodPropertyValue.empvBool.value = value;
|
eapMethodPropertyValue.empvBool.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs a DWORD method property
|
/// Constructs a DWORD method property
|
||||||
///
|
///
|
||||||
@ -407,7 +390,6 @@ namespace winstd
|
|||||||
eapMethodPropertyValue.empvDword.value = value;
|
eapMethodPropertyValue.empvDword.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs a Unicode string method property
|
/// Constructs a Unicode string method property
|
||||||
///
|
///
|
||||||
@ -423,7 +405,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// EapPacket wrapper class
|
/// EapPacket wrapper class
|
||||||
///
|
///
|
||||||
@ -441,7 +422,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Create new EAP packet
|
/// Create new EAP packet
|
||||||
///
|
///
|
||||||
@ -473,7 +453,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns total EAP packet size in bytes.
|
/// Returns total EAP packet size in bytes.
|
||||||
///
|
///
|
||||||
@ -482,7 +461,6 @@ namespace winstd
|
|||||||
return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
|
return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// Destroys the EAP packet.
|
/// Destroys the EAP packet.
|
||||||
@ -508,7 +486,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// EAP_METHOD_INFO_ARRAY wrapper class
|
/// EAP_METHOD_INFO_ARRAY wrapper class
|
||||||
///
|
///
|
||||||
@ -591,10 +568,7 @@ namespace winstd
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
///
|
/// \addtogroup WinStdExceptions
|
||||||
/// \defgroup WinStdExceptions Exceptions
|
|
||||||
/// Additional exceptions
|
|
||||||
///
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -623,7 +597,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
@ -642,7 +615,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns EAP method type
|
/// Returns EAP method type
|
||||||
///
|
///
|
||||||
@ -651,7 +623,6 @@ namespace winstd
|
|||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the reason code for error
|
/// Returns the reason code for error
|
||||||
///
|
///
|
||||||
@ -660,7 +631,6 @@ namespace winstd
|
|||||||
return m_reason;
|
return m_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns root cause ID
|
/// Returns root cause ID
|
||||||
///
|
///
|
||||||
@ -669,7 +639,6 @@ namespace winstd
|
|||||||
return m_root_cause_id;
|
return m_root_cause_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns root cause ID
|
/// Returns root cause ID
|
||||||
///
|
///
|
||||||
@ -678,7 +647,6 @@ namespace winstd
|
|||||||
return m_root_cause_desc.c_str();
|
return m_root_cause_desc.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns repair ID
|
/// Returns repair ID
|
||||||
///
|
///
|
||||||
@ -687,7 +655,6 @@ namespace winstd
|
|||||||
return m_repair_id;
|
return m_repair_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns root cause ID
|
/// Returns root cause ID
|
||||||
///
|
///
|
||||||
@ -696,7 +663,6 @@ namespace winstd
|
|||||||
return m_repair_desc.c_str();
|
return m_repair_desc.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns help_link ID
|
/// 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)
|
#pragma warning(pop)
|
||||||
|
@ -4,64 +4,108 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \defgroup WinStdETWAPI Event Tracing for Windows API
|
|
||||||
/// Integrates WinStd classes with Event Tracing for Windows API
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <evntprov.h>
|
#include <evntprov.h>
|
||||||
#include <evntcons.h>
|
#include <evntcons.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <tdh.h>
|
#include <tdh.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace winstd
|
#pragma warning(push)
|
||||||
{
|
#pragma warning(disable: 4505) // Don't warn on unused code
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \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.
|
/// Retrieves a property value from the event data.
|
||||||
///
|
///
|
||||||
/// \sa [TdhGetProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964843.aspx)
|
/// \sa [TdhGetProperty function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa964843.aspx)
|
||||||
///
|
///
|
||||||
template<class _Ty, class _Ax>
|
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
|
namespace winstd
|
||||||
{
|
{
|
||||||
@ -84,7 +128,6 @@ namespace winstd
|
|||||||
Reserved = (ULONG)-1; // Used for varadic argument terminator.
|
Reserved = (ULONG)-1; // Used for varadic argument terminator.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to an `char`.
|
/// Construct class pointing to an `char`.
|
||||||
///
|
///
|
||||||
@ -98,7 +141,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to an `unsigned char`.
|
/// Construct class pointing to an `unsigned char`.
|
||||||
///
|
///
|
||||||
@ -112,7 +154,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to an `int`.
|
/// Construct class pointing to an `int`.
|
||||||
///
|
///
|
||||||
@ -126,7 +167,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to an `unsigned int`.
|
/// Construct class pointing to an `unsigned int`.
|
||||||
///
|
///
|
||||||
@ -140,7 +180,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to a `long`.
|
/// Construct class pointing to a `long`.
|
||||||
///
|
///
|
||||||
@ -154,7 +193,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to an `unsigned long`.
|
/// Construct class pointing to an `unsigned long`.
|
||||||
///
|
///
|
||||||
@ -168,7 +206,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to a `GUID`.
|
/// Construct class pointing to a `GUID`.
|
||||||
///
|
///
|
||||||
@ -182,7 +219,6 @@ namespace winstd
|
|||||||
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
EventDataDescCreate(this, &data, (ULONG)(sizeof(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to a string.
|
/// Construct class pointing to a string.
|
||||||
///
|
///
|
||||||
@ -202,7 +238,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to a wide string.
|
/// Construct class pointing to a wide string.
|
||||||
///
|
///
|
||||||
@ -222,7 +257,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Template to construct pointing to a `std::basic_string<>`.
|
/// 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)));
|
EventDataDescCreate(this, data.c_str(), (ULONG)((data.length() + 1) * sizeof(_Elem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Construct class pointing to binary data.
|
/// Construct class pointing to binary data.
|
||||||
///
|
///
|
||||||
@ -258,7 +291,6 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
static const event_data blank_event_data;
|
static const event_data blank_event_data;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// EVENT_RECORD wrapper
|
/// EVENT_RECORD wrapper
|
||||||
///
|
///
|
||||||
@ -273,7 +305,6 @@ namespace winstd
|
|||||||
memset((EVENT_RECORD*)this, 0, sizeof(EVENT_RECORD));
|
memset((EVENT_RECORD*)this, 0, sizeof(EVENT_RECORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies an existing event record.
|
/// Copies an existing event record.
|
||||||
///
|
///
|
||||||
@ -285,7 +316,6 @@ namespace winstd
|
|||||||
set_user_data_internal(other.UserDataLength, other.UserData);
|
set_user_data_internal(other.UserDataLength, other.UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies an existing event record.
|
/// Copies an existing event record.
|
||||||
///
|
///
|
||||||
@ -297,7 +327,6 @@ namespace winstd
|
|||||||
set_user_data_internal(other.UserDataLength, other.UserData);
|
set_user_data_internal(other.UserDataLength, other.UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the event record.
|
/// Moves the event record.
|
||||||
///
|
///
|
||||||
@ -308,7 +337,6 @@ namespace winstd
|
|||||||
memset((EVENT_RECORD*)&other, 0, sizeof(EVENT_RECORD));
|
memset((EVENT_RECORD*)&other, 0, sizeof(EVENT_RECORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destroys event record data and frees the allocated memory.
|
/// Destroys event record data and frees the allocated memory.
|
||||||
///
|
///
|
||||||
@ -321,7 +349,6 @@ namespace winstd
|
|||||||
delete reinterpret_cast<unsigned char*>(UserData);
|
delete reinterpret_cast<unsigned char*>(UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies an existing event record.
|
/// Copies an existing event record.
|
||||||
///
|
///
|
||||||
@ -338,7 +365,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies an existing event record.
|
/// Copies an existing event record.
|
||||||
///
|
///
|
||||||
@ -355,7 +381,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the event record.
|
/// Moves the event record.
|
||||||
///
|
///
|
||||||
@ -371,7 +396,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets event record extended data.
|
/// Sets event record extended data.
|
||||||
///
|
///
|
||||||
@ -386,7 +410,6 @@ namespace winstd
|
|||||||
set_extended_data_internal(count, data);
|
set_extended_data_internal(count, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets event record user data.
|
/// Sets event record user data.
|
||||||
///
|
///
|
||||||
@ -463,7 +486,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// ETW event provider
|
/// ETW event provider
|
||||||
///
|
///
|
||||||
@ -483,7 +505,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Registers the event provider.
|
/// Registers the event provider.
|
||||||
///
|
///
|
||||||
@ -502,7 +523,6 @@ namespace winstd
|
|||||||
return ulRes;
|
return ulRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes an event with no parameters.
|
/// Writes an event with no parameters.
|
||||||
///
|
///
|
||||||
@ -518,7 +538,6 @@ namespace winstd
|
|||||||
return EventWrite(m_h, EventDescriptor, 0, NULL);
|
return EventWrite(m_h, EventDescriptor, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes an event with parameters stored in array.
|
/// Writes an event with parameters stored in array.
|
||||||
///
|
///
|
||||||
@ -534,7 +553,6 @@ namespace winstd
|
|||||||
return EventWrite(m_h, EventDescriptor, UserDataCount, UserData);
|
return EventWrite(m_h, EventDescriptor, UserDataCount, UserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes an event with one or more parameter.
|
/// Writes an event with one or more parameter.
|
||||||
///
|
///
|
||||||
@ -589,7 +607,6 @@ namespace winstd
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes an event with variable number of parameters.
|
/// Writes an event with variable number of parameters.
|
||||||
///
|
///
|
||||||
@ -634,7 +651,6 @@ namespace winstd
|
|||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes a string event.
|
/// Writes a string event.
|
||||||
///
|
///
|
||||||
@ -671,7 +687,6 @@ namespace winstd
|
|||||||
EventUnregister(m_h);
|
EventUnregister(m_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Receive enable or disable notification requests
|
/// Receive enable or disable notification requests
|
||||||
///
|
///
|
||||||
@ -687,7 +702,6 @@ namespace winstd
|
|||||||
UNREFERENCED_PARAMETER(FilterData);
|
UNREFERENCED_PARAMETER(FilterData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Receive enable or disable notification requests
|
/// Receive enable or disable notification requests
|
||||||
///
|
///
|
||||||
@ -702,7 +716,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// ETW session
|
/// ETW session
|
||||||
///
|
///
|
||||||
@ -718,7 +731,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Initializes a new session with an already available object handle.
|
/// Initializes a new session with an already available object handle.
|
||||||
///
|
///
|
||||||
@ -732,7 +744,6 @@ namespace winstd
|
|||||||
memcpy(m_prop.get(), prop, prop->Wnode.BufferSize);
|
memcpy(m_prop.get(), prop, prop->Wnode.BufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
///
|
///
|
||||||
@ -744,7 +755,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Closes the session.
|
/// Closes the session.
|
||||||
///
|
///
|
||||||
@ -756,7 +766,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Move assignment
|
/// Move assignment
|
||||||
///
|
///
|
||||||
@ -771,7 +780,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Auto-typecasting operator
|
/// Auto-typecasting operator
|
||||||
///
|
///
|
||||||
@ -782,7 +790,6 @@ namespace winstd
|
|||||||
return m_prop.get();
|
return m_prop.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Auto-typecasting operator
|
/// Auto-typecasting operator
|
||||||
///
|
///
|
||||||
@ -794,7 +801,6 @@ namespace winstd
|
|||||||
return reinterpret_cast<LPCTSTR>(reinterpret_cast<const char*>(prop) + prop->LoggerNameOffset);
|
return reinterpret_cast<LPCTSTR>(reinterpret_cast<const char*>(prop) + prop->LoggerNameOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets a new session handle for the class
|
/// Sets a new session handle for the class
|
||||||
///
|
///
|
||||||
@ -809,7 +815,6 @@ namespace winstd
|
|||||||
m_prop.reset(prop);
|
m_prop.reset(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Registers and starts an event tracing session.
|
/// Registers and starts an event tracing session.
|
||||||
///
|
///
|
||||||
@ -830,7 +835,6 @@ namespace winstd
|
|||||||
return ulRes;
|
return ulRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Enables the specified event trace provider.
|
/// Enables the specified event trace provider.
|
||||||
///
|
///
|
||||||
@ -855,7 +859,6 @@ namespace winstd
|
|||||||
EnableFilterDesc);
|
EnableFilterDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Disables the specified event trace provider.
|
/// Disables the specified event trace provider.
|
||||||
///
|
///
|
||||||
@ -880,7 +883,6 @@ namespace winstd
|
|||||||
EnableFilterDesc);
|
EnableFilterDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// Releases the session.
|
/// Releases the session.
|
||||||
@ -896,7 +898,6 @@ namespace winstd
|
|||||||
std::unique_ptr<EVENT_TRACE_PROPERTIES> m_prop; ///< Session properties
|
std::unique_ptr<EVENT_TRACE_PROPERTIES> m_prop; ///< Session properties
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// ETW trace
|
/// ETW trace
|
||||||
///
|
///
|
||||||
@ -916,7 +917,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Opens a real-time trace session or log file for consuming.
|
/// 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
|
/// Helper class to enable event provider in constructor and disables it in destructor
|
||||||
///
|
///
|
||||||
@ -990,7 +989,6 @@ namespace winstd
|
|||||||
m_enable_filter_desc);
|
m_enable_filter_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Enables event trace
|
/// Enables event trace
|
||||||
///
|
///
|
||||||
@ -1025,7 +1023,6 @@ namespace winstd
|
|||||||
m_enable_filter_desc);
|
m_enable_filter_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Return result of `EnableTraceEx()` call.
|
/// Return result of `EnableTraceEx()` call.
|
||||||
///
|
///
|
||||||
@ -1036,7 +1033,6 @@ namespace winstd
|
|||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Disables event trace.
|
/// Disables event trace.
|
||||||
///
|
///
|
||||||
@ -1069,7 +1065,6 @@ namespace winstd
|
|||||||
PEVENT_FILTER_DESCRIPTOR m_enable_filter_desc; ///< Event filter descriptor
|
PEVENT_FILTER_DESCRIPTOR m_enable_filter_desc; ///< Event filter descriptor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Helper class to write an event on entry/exit of scope.
|
/// 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);
|
m_ep.write(event_cons, 1, &m_fn_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies the object
|
/// Copies the object
|
||||||
///
|
///
|
||||||
@ -1100,7 +1094,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the object
|
/// Moves the object
|
||||||
///
|
///
|
||||||
@ -1112,7 +1105,6 @@ namespace winstd
|
|||||||
other.m_event_dest = NULL;
|
other.m_event_dest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes the `event_dest` event
|
/// Writes the `event_dest` event
|
||||||
///
|
///
|
||||||
@ -1122,7 +1114,6 @@ namespace winstd
|
|||||||
m_ep.write(m_event_dest, 1, &m_fn_name);
|
m_ep.write(m_event_dest, 1, &m_fn_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies the object
|
/// Copies the object
|
||||||
///
|
///
|
||||||
@ -1137,7 +1128,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the object
|
/// Moves the object
|
||||||
///
|
///
|
||||||
@ -1153,14 +1143,12 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
event_provider &m_ep; ///< Reference to event provider in use
|
event_provider &m_ep; ///< Reference to event provider in use
|
||||||
const EVENT_DESCRIPTOR *m_event_dest; ///< Event descriptor at destruction
|
const EVENT_DESCRIPTOR *m_event_dest; ///< Event descriptor at destruction
|
||||||
EVENT_DATA_DESCRIPTOR m_fn_name; ///< Function name
|
EVENT_DATA_DESCRIPTOR m_fn_name; ///< Function name
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Helper template to write an event on entry/exit of scope with one parameter (typically result).
|
/// 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);
|
m_ep.write(event_cons, 1, m_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies the object
|
/// Copies the object
|
||||||
///
|
///
|
||||||
@ -1194,7 +1181,6 @@ namespace winstd
|
|||||||
m_desc[0] = other.m_desc[0];
|
m_desc[0] = other.m_desc[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the object
|
/// Moves the object
|
||||||
///
|
///
|
||||||
@ -1207,7 +1193,6 @@ namespace winstd
|
|||||||
other.m_event_dest = NULL;
|
other.m_event_dest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes the `event_dest` event
|
/// Writes the `event_dest` event
|
||||||
///
|
///
|
||||||
@ -1219,7 +1204,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies the object
|
/// Copies the object
|
||||||
///
|
///
|
||||||
@ -1235,7 +1219,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Moves the object
|
/// Moves the object
|
||||||
///
|
///
|
||||||
@ -1252,7 +1235,6 @@ namespace winstd
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
event_provider &m_ep; ///< Reference to event provider in use
|
event_provider &m_ep; ///< Reference to event provider in use
|
||||||
const EVENT_DESCRIPTOR *m_event_dest; ///< Event descriptor at destruction
|
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)
|
|
||||||
|
@ -3,28 +3,16 @@
|
|||||||
Copyright © 1991-2022 Amebis
|
Copyright © 1991-2022 Amebis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \defgroup WinStdGdiAPI GDI API
|
|
||||||
/// Integrates WinStd classes with Microsoft Windows GDI
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
template<class T> class gdi_handle;
|
///
|
||||||
class dc;
|
/// \defgroup WinStdGdiAPI GDI API
|
||||||
class window_dc;
|
/// Integrates WinStd classes with Microsoft Windows GDI
|
||||||
class dc_selector;
|
///
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
namespace winstd
|
|
||||||
{
|
|
||||||
/// \addtogroup WinStdGdiAPI
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -59,7 +47,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Device context wrapper class
|
/// Device context wrapper class
|
||||||
///
|
///
|
||||||
@ -91,7 +78,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Device context wrapper class
|
/// Device context wrapper class
|
||||||
///
|
///
|
||||||
@ -148,7 +134,6 @@ namespace winstd
|
|||||||
HWND m_hwnd; ///< Window handle
|
HWND m_hwnd; ///< Window handle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Context scope DC object restorer
|
/// Context scope DC object restorer
|
||||||
///
|
///
|
||||||
@ -169,7 +154,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Restores original object.
|
/// Restores original object.
|
||||||
///
|
///
|
||||||
@ -181,7 +165,6 @@ namespace winstd
|
|||||||
SelectObject(m_hdc, m_orig);
|
SelectObject(m_hdc, m_orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Return result of `SelectObject()` call.
|
/// Return result of `SelectObject()` call.
|
||||||
///
|
///
|
||||||
|
@ -4,94 +4,21 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include <MsiQuery.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \defgroup WinStdMSIAPI Microsoft Installer API
|
/// \defgroup WinStdMSIAPI Microsoft Installer API
|
||||||
/// Integrates WinStd classes with Microsoft Installer API
|
/// Integrates WinStd classes with Microsoft Installer API
|
||||||
///
|
///
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <MsiQuery.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/// \addtogroup WinStdMSIAPI
|
/// \addtogroup WinStdMSIAPI
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// @copydoc MsiGetPropertyW()
|
/// @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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiGetPropertyA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szName, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiGetPropertyW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szName, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiRecordGetStringA(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiRecordGetStringW(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiFormatRecordA(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiFormatRecordW(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
|
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>
|
template<class _Ty, class _Ax>
|
||||||
static UINT MsiRecordReadStream(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Inout_ std::vector<_Ty, _Ax> &binData)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiGetTargetPathA(_In_ MSIHANDLE hInstall, _In_z_ LPCSTR szFolder, _Out_ std::basic_string<char, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static UINT MsiGetTargetPathW(_In_ MSIHANDLE hInstall, _In_z_ LPCWSTR szFolder, _Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static INSTALLSTATE MsiGetComponentPathA(_In_z_ LPCSTR szProduct, _In_z_ LPCSTR szComponent, _Inout_ std::basic_string<char, _Traits, _Ax> &sValue)
|
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>
|
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)
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
@ -4,33 +4,47 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include <Security.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \defgroup WinStdSecurityAPI Security API
|
/// \defgroup WinStdSecurityAPI Security API
|
||||||
/// Integrates WinStd classes with Microsoft 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)
|
#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL)
|
||||||
|
|
||||||
/// \addtogroup WinStdSecurityAPI
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/// @copydoc GetUserNameExW()
|
/// @copydoc GetUserNameExW()
|
||||||
template<class _Traits, class _Ax>
|
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.
|
/// 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)
|
/// \sa [GetUserNameEx function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx)
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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
|
#endif
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdSecurityAPI
|
/// \addtogroup WinStdSecurityAPI
|
||||||
@ -161,7 +196,6 @@ namespace winstd
|
|||||||
TimeStamp m_expires; ///< Credentials expiration time
|
TimeStamp m_expires; ///< Credentials expiration time
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// PCtxtHandle wrapper class
|
/// PCtxtHandle wrapper class
|
||||||
///
|
///
|
||||||
@ -285,7 +319,6 @@ namespace winstd
|
|||||||
TimeStamp m_expires; ///< Context expiration time
|
TimeStamp m_expires; ///< Context expiration time
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// SecBufferDesc wrapper class
|
/// SecBufferDesc wrapper class
|
||||||
///
|
///
|
||||||
@ -318,10 +351,7 @@ namespace winstd
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
///
|
/// \addtogroup WinStdExceptions
|
||||||
/// \defgroup WinStdExceptions Exceptions
|
|
||||||
/// Additional exceptions
|
|
||||||
///
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -342,7 +372,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
@ -353,7 +382,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies an exception
|
/// 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
|
|
||||||
|
@ -4,28 +4,17 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
|
||||||
/// \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
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
#include <SetupAPI.h>
|
#include <SetupAPI.h>
|
||||||
|
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup SetupAPI
|
///
|
||||||
|
/// \defgroup SetupAPI Setup API
|
||||||
|
/// Integrates WinStd classes with Microsoft Setup API
|
||||||
|
///
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -108,7 +97,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Builds a list of drivers in constructor and deletes it in destructor
|
/// 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);
|
SetupDiDestroyDriverInfoList(m_DeviceInfoSet, m_DeviceInfoData, m_DriverType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Return result of `SetupDiBuildDriverInfoList()` call.
|
/// Return result of `SetupDiBuildDriverInfoList()` call.
|
||||||
///
|
///
|
||||||
|
@ -4,36 +4,19 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \defgroup WinStdShellWAPI Shell API
|
/// \defgroup WinStdShellWAPI Shell API
|
||||||
/// Integrates WinStd classes with Microsoft Shell API
|
/// Integrates WinStd classes with Microsoft Shell API
|
||||||
///
|
///
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <Shlwapi.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
/// \addtogroup WinStdShellWAPI
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// @copydoc PathCanonicalizeW()
|
/// @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>
|
template<class _Traits, class _Ax>
|
||||||
static BOOL PathCanonicalizeA(_Inout_ std::basic_string<char, _Traits, _Ax> &sValue, _In_ LPCSTR pszPath)
|
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;
|
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>
|
template<class _Traits, class _Ax>
|
||||||
static BOOL PathCanonicalizeW(_Inout_ std::basic_string<wchar_t, _Traits, _Ax> &sValue, _In_ LPCWSTR pszPath)
|
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);
|
sValue.assign(szBuffer, bResult ? MAX_PATH : 0);
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
@ -4,28 +4,20 @@
|
|||||||
Copyright © 2016 GÉANT
|
Copyright © 2016 GÉANT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///
|
#pragma once
|
||||||
/// \defgroup WinStdWLANAPI WLAN API
|
|
||||||
/// Integrates WinStd classes with Microsoft WLAN API
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <wlanapi.h>
|
#include <wlanapi.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Must not statically link to Wlanapi.dll as it is not available on Windows
|
// Must not statically link to Wlanapi.dll as it is not available on Windows
|
||||||
// without a WLAN interface.
|
// without a WLAN interface.
|
||||||
extern DWORD (WINAPI *pfnWlanReasonCodeToString)(__in DWORD dwReasonCode, __in DWORD dwBufferSize, __in_ecount(dwBufferSize) PWCHAR pStringBuffer, __reserved PVOID pReserved);
|
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;
|
/// \defgroup WinStdWLANAPI WLAN API
|
||||||
template <class _Ty> struct WlanFreeMemory_delete<_Ty[]>;
|
/// Integrates WinStd classes with Microsoft WLAN API
|
||||||
class wlan_handle;
|
///
|
||||||
}
|
|
||||||
|
|
||||||
/// \addtogroup WinStdWLANAPI
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -38,13 +30,36 @@ namespace winstd {
|
|||||||
/// function must be loaded dynamically.
|
/// function must be loaded dynamically.
|
||||||
///
|
///
|
||||||
template<class _Traits, class _Ax>
|
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
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdWLANAPI
|
/// \addtogroup WinStdWLANAPI
|
||||||
@ -76,7 +91,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Deleter for unique_ptr to array of unknown size using WlanFreeMemory
|
/// Deleter for unique_ptr to array of unknown size using WlanFreeMemory
|
||||||
///
|
///
|
||||||
@ -107,7 +121,6 @@ namespace winstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// WLAN handle wrapper
|
/// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
2203
include/WinStd/Win.h
2203
include/WinStd/Win.h
File diff suppressed because it is too large
Load Diff
@ -4,31 +4,19 @@
|
|||||||
Copyright © 2016 GÉANT
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#include <ws2def.h>
|
#include <ws2def.h>
|
||||||
#include <WS2tcpip.h>
|
#include <WS2tcpip.h>
|
||||||
|
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
/// \addtogroup WinStdExceptions
|
///
|
||||||
|
/// \defgroup WinSock2API WinSock2 API
|
||||||
|
/// Integrates WinStd classes with Microsoft WinSock2 API
|
||||||
|
///
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -47,7 +35,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
@ -58,7 +45,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception using `WSAGetLastError()`
|
/// Constructs an exception using `WSAGetLastError()`
|
||||||
///
|
///
|
||||||
@ -68,7 +54,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs an exception using `WSAGetLastError()`
|
/// Constructs an exception using `WSAGetLastError()`
|
||||||
///
|
///
|
||||||
@ -78,7 +63,6 @@ namespace winstd
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a user-readable Windows error message
|
/// Returns a user-readable Windows error message
|
||||||
///
|
///
|
||||||
@ -98,7 +82,6 @@ namespace winstd
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
/// \addtogroup WinSock2API
|
/// \addtogroup WinSock2API
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
@ -141,7 +124,6 @@ namespace winstd
|
|||||||
free_internal();
|
free_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// Frees address information
|
/// Frees address information
|
||||||
|
@ -6,26 +6,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
///
|
|
||||||
/// \defgroup WinTrustAPI WinTrust API
|
|
||||||
/// Integrates WinStd classes with Microsoft WinTrust API
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include <WinTrust.h>
|
#include <WinTrust.h>
|
||||||
|
|
||||||
namespace winstd
|
namespace winstd
|
||||||
{
|
{
|
||||||
class wintrust;
|
///
|
||||||
}
|
/// \defgroup WinTrustAPI WinTrust API
|
||||||
|
/// Integrates WinStd classes with Microsoft WinTrust API
|
||||||
#pragma once
|
///
|
||||||
|
|
||||||
|
|
||||||
namespace winstd
|
|
||||||
{
|
|
||||||
/// \addtogroup WinTrustAPI
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user