WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
Common.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
7#pragma once
8
9#include <Windows.h>
10#include <assert.h>
11#include <stdarg.h>
12#include <tchar.h>
13#include <iostream>
14#include <memory>
15#include <stdexcept>
16#include <string>
17#include <vector>
18
24
28#ifndef __L
29#define __L(x) L ## x
30#endif
31
35#ifndef _L
36#define _L(x) __L(x)
37#endif
38
42#define WINSTD_STRING_IMPL(x) #x
43
47#define WINSTD_STRING(x) WINSTD_STRING_IMPL(x)
48
52#define WINSTD_NONCOPYABLE(C) \
53private: \
54 C (_In_ const C &h) noexcept; \
55 C& operator=(_In_ const C &h) noexcept;
56
60#define WINSTD_NONMOVABLE(C) \
61private: \
62 C (_Inout_ C &&h) noexcept; \
63 C& operator=(_Inout_ C &&h) noexcept;
64
65#ifndef WINSTD_STACK_BUFFER_BYTES
79#define WINSTD_STACK_BUFFER_BYTES 1024
80#endif
81
83
95
99#ifdef UNICODE
100#define PRINTF_LPTSTR "ls"
101#else
102#define PRINTF_LPTSTR "s"
103#endif
104
108#ifdef OLE2ANSI
109#define PRINTF_LPOLESTR "hs"
110#else
111#define PRINTF_LPOLESTR "ls"
112#endif
113
117#ifdef _UNICODE
118#define _tcin (std::wcin )
119#else
120#define _tcin (std::cin )
121#endif
122
126#ifdef _UNICODE
127#define _tcout (std::wcout)
128#else
129#define _tcout (std::cout)
130#endif
131
135#ifdef _UNICODE
136#define _tcerr (std::wcerr)
137#else
138#define _tcerr (std::cerr)
139#endif
140
144#ifdef _UNICODE
145#define _tclog (std::wclog)
146#else
147#define _tclog (std::clog)
148#endif
149
151
157
161#define WINSTD_HANDLE_IMPL(C, INVAL) \
162public: \
163 C ( ) noexcept { } \
164 C (_In_opt_ handle_type h) noexcept : handle<handle_type, INVAL>( h ) { } \
165 C (_Inout_ C &&h) noexcept : handle<handle_type, INVAL>(std::move(h)) { } \
166 C& operator=(_In_opt_ handle_type h) noexcept { handle<handle_type, INVAL>::operator=( h ); return *this; } \
167 C& operator=(_Inout_ C &&h) noexcept { handle<handle_type, INVAL>::operator=(std::move(h)); return *this; } \
168WINSTD_NONCOPYABLE(C)
169
173#define WINSTD_DPLHANDLE_IMPL(C, INVAL) \
174public: \
175 C ( ) noexcept { } \
176 C (_In_opt_ handle_type h) noexcept : dplhandle<handle_type, INVAL>( h ) { } \
177 C (_In_ const C &h) noexcept : dplhandle<handle_type, INVAL>(duplicate_internal(h.m_h)) { } \
178 C (_Inout_ C &&h) noexcept : dplhandle<handle_type, INVAL>(std::move (h )) { } \
179 C& operator=(_In_opt_ handle_type h) noexcept { dplhandle<handle_type, INVAL>::operator=( h ); return *this; } \
180 C& operator=(_In_ const C &h) noexcept { dplhandle<handle_type, INVAL>::operator=( h ); return *this; } \
181 C& operator=(_Inout_ C &&h) noexcept { dplhandle<handle_type, INVAL>::operator=(std::move(h)); return *this; } \
182private:
183
185
186#ifndef _FormatMessage_format_string_
187#define _FormatMessage_format_string_ _In_z_
188#endif
189
190#ifndef _LPCBYTE_DEFINED
191#define _LPCBYTE_DEFINED
192typedef const BYTE *LPCBYTE;
193#endif
194
195#pragma warning(push)
196// Do not use _vsnprintf_s/_vsnwprintf_s(), since it terminates string by force even when we explicitly want to write unterminated string.
197// Threfore turn off compiler warning instead. ;)
198#pragma warning(disable: 4995)
199#pragma warning(disable: 4996)
200#pragma warning(disable: 4505) // Don't warn on unused code
201
204
215#if _MSC_VER <= 1600
216static int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ va_list arg)
217{
218 return _vsnprintf(str, capacity, format, arg);
219}
220#endif
221
232static 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
233{
234 return _vsnwprintf(str, capacity, format, arg);
235}
236
246template<class _Elem, class _Traits, class _Ax>
247static int vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ va_list arg)
248{
249 _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
250
251 // Try with stack buffer first.
252 int count = vsnprintf(buf, _countof(buf) - 1, format, arg);
253 if (count >= 0) {
254 // Copy from stack.
255 str.assign(buf, count);
256 } else {
257 for (size_t capacity = 2*WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem);; capacity *= 2) {
258 // Allocate on heap and retry.
259 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
260 count = vsnprintf(buf_dyn.get(), capacity - 1, format, arg);
261 if (count >= 0) {
262 str.assign(buf_dyn.get(), count);
263 break;
264 }
265 }
266 }
267
268 return count;
269}
270
279template<class _Elem, class _Traits, class _Ax>
280static int sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, ...)
281{
282 va_list arg;
283 va_start(arg, format);
284 const int res = vsprintf(str, format, arg);
285 va_end(arg);
286 return res;
287}
288
294template<class _Traits, class _Ax>
295static 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)
296{
297 std::unique_ptr<CHAR[], winstd::LocalFree_delete<CHAR[]> > lpBuffer;
298 DWORD dwResult = FormatMessageA(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPSTR>((LPSTR*)get_ptr(lpBuffer)), 0, Arguments);
299 if (dwResult)
300 str.assign(lpBuffer.get(), dwResult);
301 return dwResult;
302}
303
309template<class _Traits, class _Ax>
310static 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)
311{
312 std::unique_ptr<WCHAR[], winstd::LocalFree_delete<WCHAR[]> > lpBuffer;
313 DWORD dwResult = FormatMessageW(dwFlags | FORMAT_MESSAGE_ALLOCATE_BUFFER, lpSource, dwMessageId, dwLanguageId, reinterpret_cast<LPWSTR>((LPWSTR*)get_ptr(lpBuffer)), 0, Arguments);
314 if (dwResult)
315 str.assign(lpBuffer.get(), dwResult);
316 return dwResult;
317}
318
320
321#pragma warning(pop)
322
323namespace winstd
324{
327
331#ifdef _UNICODE
332 typedef std::wstring tstring;
333#else
334 typedef std::string tstring;
335#endif
336
340 template <class _Ty>
342 {
344
349
353 template <class _Ty2> LocalFree_delete(const LocalFree_delete<_Ty2>&) {}
354
360 void operator()(_Ty *_Ptr) const
361 {
362 LocalFree(_Ptr);
363 }
364 };
365
369 template <class _Ty>
370 struct LocalFree_delete<_Ty[]>
371 {
373
377 LocalFree_delete() noexcept {}
378
382 void operator()(_Frees_ptr_opt_ _Ty *_Ptr) const noexcept
383 {
384 LocalFree(_Ptr);
385 }
386
392 template<class _Other>
393 void operator()(_Other *) const
394 {
395 LocalFree(_Ptr);
396 }
397 };
398
402 template<class _Ty, class _Dx>
404 {
405 public:
411 ref_unique_ptr(_Inout_ std::unique_ptr<_Ty, _Dx> &owner) :
412 m_own(owner),
413 m_ptr(owner.release())
414 {}
415
422 m_own(other.m_own),
423 m_ptr(other.m_ptr)
424 {
425 other.m_ptr = nullptr;
426 }
427
432 {
433 if (m_ptr != nullptr)
434 m_own.reset(m_ptr);
435 }
436
442 operator typename _Ty**()
443 {
444 return &m_ptr;
445 }
446
452 operator typename _Ty*&()
453 {
454 return m_ptr;
455 }
456
457 protected:
458 std::unique_ptr<_Ty, _Dx> &m_own;
459 _Ty *m_ptr;
460 };
461
469 template<class _Ty, class _Dx>
470 ref_unique_ptr<_Ty, _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty, _Dx> &owner) noexcept
471 {
472 return ref_unique_ptr<_Ty, _Dx>(owner);
473 }
474
483 template<class _Ty, class _Dx>
484 ref_unique_ptr<_Ty[], _Dx> get_ptr(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept
485 {
486 return ref_unique_ptr<_Ty[], _Dx>(owner);
487 }
488
493 #pragma warning(push)
494 #pragma warning(disable: 26432) // Copy constructor and assignment operator are also present, but not detected by code analysis as they are using base type source object reference.
495 template<class _Ty, class _Dx>
496 class ref_unique_ptr<_Ty[], _Dx>
497 {
498 public:
504 ref_unique_ptr(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept :
505 m_own(owner),
506 m_ptr(owner.release())
507 {}
508
516 ref_unique_ptr& operator=(_Inout_ std::unique_ptr<_Ty[], _Dx> &owner) noexcept
517 {
518 if (this != &other) {
519 m_own = owner;
520 m_ptr = owner.release();
521 }
522
523 return *this;
524 }
525
531 ref_unique_ptr(_Inout_ ref_unique_ptr<_Ty[], _Dx> &&other) :
532 m_own(other.m_own),
533 m_ptr(other.m_ptr)
534 {
535 other.m_ptr = nullptr;
536 }
537
545 ref_unique_ptr& operator=(_Inout_ ref_unique_ptr<_Ty[], _Dx> &&other)
546 {
547 if (this != &other) {
548 m_own = other.m_own;
549 m_ptr = other.m_ptr;
550 other.m_ptr = nullptr;
551 }
552
553 return *this;
554 }
555
560 {
561 if (m_ptr != nullptr)
562 m_own.reset(m_ptr);
563 }
564
570 operator typename _Ty**() noexcept
571 {
572 return &m_ptr;
573 }
574
580 operator typename _Ty*&()
581 {
582 return m_ptr;
583 }
584
585 protected:
586 std::unique_ptr<_Ty[], _Dx> &m_own;
587 _Ty *m_ptr;
588 };
589 #pragma warning(pop)
590
592
595
601 template <class T, const T INVAL>
602 class handle
603 {
604 public:
608 typedef T handle_type;
609
613 static const T invalid;
614
618 handle() noexcept : m_h(invalid)
619 {
620 }
621
627 handle(_In_opt_ handle_type h) noexcept : m_h(h)
628 {
629 }
630
636 handle(_Inout_ handle<handle_type, INVAL> &&h) noexcept
637 {
638 // Transfer handle.
639 m_h = h.m_h;
640 h.m_h = invalid;
641 }
642
643 private:
644 // This class is noncopyable.
645 handle(_In_ const handle<handle_type, INVAL> &h) noexcept {};
646 handle<handle_type, INVAL>& operator=(_In_ const handle<handle_type, INVAL> &h) noexcept {};
647
648 public:
655 {
656 attach(h);
657 return *this;
658 }
659
665 #pragma warning(suppress: 26432) // Move constructor is also present, but not detected by code analysis somehow.
667 {
668 if (this != std::addressof(h)) {
669 // Transfer handle.
670 if (m_h != invalid)
672 m_h = h.m_h;
673 h.m_h = invalid;
674 }
675 return *this;
676 }
677
683 operator handle_type() const
684 {
685 return m_h;
686 }
687
694 {
695 assert(m_h != invalid);
696 return *m_h;
697 }
698
704 {
705 assert(m_h == invalid);
706 return &m_h;
707 }
708
715 {
716 assert(m_h != invalid);
717 return m_h;
718 }
719
727 bool operator!() const
728 {
729 return m_h == invalid;
730 }
731
740 bool operator<(_In_opt_ handle_type h) const
741 {
742 return m_h < h;
743 }
744
753 bool operator<=(_In_opt_ handle_type h) const
754 {
755 return !operator>(h);
756 }
757
766 bool operator>=(_In_opt_ handle_type h) const
767 {
768 return !operator<(h);
769 }
770
779 bool operator>(_In_opt_ handle_type h) const
780 {
781 return h < m_h;
782 }
783
792 bool operator!=(_In_opt_ handle_type h) const
793 {
794 return !operator==(h);
795 }
796
805 bool operator==(_In_opt_ handle_type h) const
806 {
807 return m_h == h;
808 }
809
817 void attach(_In_opt_ handle_type h) noexcept
818 {
819 if (m_h != invalid)
821 m_h = h;
822 }
823
830 {
831 handle_type h = m_h;
832 m_h = invalid;
833 return h;
834 }
835
839 void free()
840 {
841 if (m_h != invalid) {
843 m_h = invalid;
844 }
845 }
846
847 protected:
851 virtual void free_internal() noexcept = 0;
852
853 protected:
855 };
856
857 template <class T, const T INVAL>
858 const T handle<T, INVAL>::invalid = INVAL;
859
863 template <class T, T INVAL>
864 class dplhandle : public handle<T, INVAL>
865 {
866 public:
870 dplhandle() noexcept
871 {
872 }
873
880 {
881 }
882
888 dplhandle<handle_type, INVAL>(_In_ const dplhandle<handle_type, INVAL> &h) noexcept : handle<handle_type, INVAL>(duplicate_internal(h.m_h))
889 {
890 }
891
897 dplhandle<handle_type, INVAL>(_Inout_ dplhandle<handle_type, INVAL> &&h) noexcept : handle<handle_type, INVAL>(std::move(h))
898 {
899 }
900
907 {
909 return *this;
910 }
911
918 {
919 if (this != std::addressof(h)) {
920 if (h.m_h != invalid) {
921 handle_type h_new = duplicate_internal(h.m_h);
922 if (h_new != invalid) {
923 if (m_h != invalid)
925
926 m_h = h_new;
927 } else
928 assert(0); // Could not duplicate the handle
929 } else {
930 if (m_h != invalid)
932
933 m_h = invalid;
934 }
935 }
936 return *this;
937 }
938
944 #pragma warning(disable: 26432) // Move constructor is also present, but not detected by code analysis somehow.
946 {
948 return *this;
949 }
950
957 {
958 return m_h != invalid ? duplicate_internal(m_h) : invalid;
959 }
960
971 {
972 if (m_h != invalid)
974
975 return h != invalid ? (m_h = duplicate_internal(h)) != invalid : (m_h = invalid, true);
976 }
977
978 protected:
986 virtual handle_type duplicate_internal(_In_ handle_type h) const noexcept = 0;
987 };
988
990
996
1000 template <typename _Tn>
1001 class num_runtime_error : public std::runtime_error
1002 {
1003 public:
1004 typedef _Tn error_type;
1005
1006 public:
1013 num_runtime_error(_In_ error_type num, _In_ const std::string& msg) :
1014 m_num(num),
1015 runtime_error(msg)
1016 {
1017 }
1018
1025 num_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) :
1026 m_num(num),
1027 runtime_error(msg)
1028 {
1029 }
1030
1035 {
1036 return m_num;
1037 }
1038
1039 protected:
1041 };
1042
1047 {
1048 public:
1055 win_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<DWORD>(num, msg)
1056 {
1057 }
1058
1065 win_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<DWORD>(num, msg)
1066 {
1067 }
1068
1074 win_runtime_error(_In_ const std::string& msg) : num_runtime_error<DWORD>(GetLastError(), msg)
1075 {
1076 }
1077
1083 win_runtime_error(_In_opt_z_ const char *msg = nullptr) : num_runtime_error<DWORD>(GetLastError(), msg)
1084 {
1085 }
1086
1092 tstring msg(_In_opt_ DWORD dwLanguageId = 0) const
1093 {
1094 tstring str;
1095 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, m_num, dwLanguageId, str, NULL)) {
1096 // Stock Windows error messages contain CRLF. Well... Trim all the trailing white space.
1097 str.erase(str.find_last_not_of(_T(" \t\n\r\f\v")) + 1);
1098 } else
1099 sprintf(str, m_num >= 0x10000 ? _T("Error 0x%X") : _T("Error %u"), m_num);
1100 return str;
1101 }
1102 };
1103
1105
1108
1112 template<class _Elem, class _Traits, class _Ax>
1113 class basic_string_printf : public std::basic_string<_Elem, _Traits, _Ax>
1114 {
1115 public:
1118
1124 basic_string_printf(_In_z_ _Printf_format_string_ const _Elem *format, ...)
1125 {
1126 va_list arg;
1127 va_start(arg, format);
1128 vsprintf(*this, format, arg);
1129 va_end(arg);
1130 }
1131
1133
1136
1143 basic_string_printf(_In_ HINSTANCE hInstance, _In_ UINT nFormatID, ...)
1144 {
1145 _Myt format;
1146 ATLENSURE(format.LoadString(hInstance, nFormatID));
1147
1148 va_list arg;
1149 va_start(arg, nFormatID);
1150 vsprintf(*this, format, arg);
1151 va_end(arg);
1152 }
1153
1161 basic_string_printf(_In_ HINSTANCE hInstance, _In_ WORD wLanguageID, _In_ UINT nFormatID, ...)
1162 {
1163 _Myt format;
1164 ATLENSURE(format.LoadString(hInstance, nFormatID, wLanguageID));
1165
1166 va_list arg;
1167 va_start(arg, nFormatID);
1168 vsprintf(*this, format, arg);
1169 va_end(arg);
1170 }
1171
1173 };
1174
1179
1184
1188#ifdef _UNICODE
1190#else
1192#endif
1193
1197 template<class _Elem, class _Traits, class _Ax>
1198 class basic_string_msg : public std::basic_string<_Elem, _Traits, _Ax>
1199 {
1200 public:
1203
1209 basic_string_msg(_In_z_ _FormatMessage_format_string_ const _Elem *format, ...)
1210 {
1211 va_list arg;
1212 va_start(arg, format);
1213 FormatMessage(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, *this, &arg);
1214 va_end(arg);
1215 }
1216
1218
1221
1228 basic_string_msg(_In_ HINSTANCE hInstance, _In_ UINT nFormatID, ...)
1229 {
1230 _Myt format(GetManager());
1231 ATLENSURE(format.LoadString(hInstance, nFormatID));
1232
1233 va_list arg;
1234 va_start(arg, nFormatID);
1235 FormatMessage(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, *this, &arg);
1236 va_end(arg);
1237 }
1238
1246 basic_string_msg(_In_ HINSTANCE hInstance, _In_ WORD wLanguageID, _In_ UINT nFormatID, ...)
1247 {
1248 _Myt format(GetManager());
1249 ATLENSURE(format.LoadString(hInstance, nFormatID, wLanguageID));
1250
1251 va_list arg;
1252 va_start(arg, nFormatID);
1253 FormatMessage(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, *this, &arg);
1254 va_end(arg);
1255 }
1256
1258
1264 basic_string_msg(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _In_opt_ va_list *Arguments)
1265 {
1266 FormatMessage(dwFlags & ~FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, Arguments);
1267 }
1268
1274 basic_string_msg(_In_ DWORD dwFlags, _In_opt_ LPCVOID lpSource, _In_ DWORD dwMessageId, _In_ DWORD dwLanguageId, _In_opt_ DWORD_PTR *Arguments)
1275 {
1276 FormatMessage(dwFlags | FORMAT_MESSAGE_ARGUMENT_ARRAY, lpSource, dwMessageId, dwLanguageId, *this, (va_list*)Arguments);
1277 }
1278
1284 basic_string_msg(_In_ DWORD dwFlags, _In_z_ LPCTSTR pszFormat, _In_opt_ va_list *Arguments)
1285 {
1286 FormatMessage(dwFlags & ~FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, *this, Arguments);
1287 }
1288
1294 basic_string_msg(_In_ DWORD dwFlags, _In_z_ LPCTSTR pszFormat, _In_opt_ DWORD_PTR *Arguments)
1295 {
1296 FormatMessage(dwFlags | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, *this, (va_list*)Arguments);
1297 }
1298 };
1299
1304
1309
1313#ifdef _UNICODE
1314 typedef wstring_msg tstring_msg;
1315#else
1317#endif
1318
1322 template<class _Elem, class _Traits, class _Ax>
1323 class basic_string_guid : public std::basic_string<_Elem, _Traits, _Ax>
1324 {
1325 public:
1328
1335 basic_string_guid(_In_ const GUID &guid, _In_z_ _Printf_format_string_ const _Elem *format)
1336 {
1337 sprintf<_Elem, _Traits, _Ax>(*this, format,
1338 guid.Data1,
1339 guid.Data2,
1340 guid.Data3,
1341 guid.Data4[0], guid.Data4[1],
1342 guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
1343 }
1344
1346 };
1347
1351 class string_guid : public basic_string_guid<char, std::char_traits<char>, std::allocator<char> >
1352 {
1353 public:
1356
1362 string_guid(_In_ const GUID &guid) :
1363 basic_string_guid<char, std::char_traits<char>, std::allocator<char> >(guid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}")
1364 {
1365 }
1366
1368 };
1369
1373 class wstring_guid : public basic_string_guid<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >
1374 {
1375 public:
1378
1384 wstring_guid(_In_ const GUID &guid) :
1385 basic_string_guid<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >(guid, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}")
1386 {
1387 }
1388
1390 };
1391
1395#ifdef _UNICODE
1396 typedef wstring_guid tstring_guid;
1397#else
1399#endif
1400
1402
1408
1409 // winstd::sanitizing_allocator::destroy() member generates _Ptr parameter not used warning for primitive datatypes _Ty.
1410 #pragma warning(push)
1411 #pragma warning(disable: 4100)
1412
1420 template<class _Ty>
1421 class sanitizing_allocator : public std::allocator<_Ty>
1422 {
1423 public:
1424 typedef std::allocator<_Ty> _Mybase;
1425
1429 template<class _Other>
1430 struct rebind
1431 {
1433 };
1434
1439 {
1440 }
1441
1446 {
1447 }
1448
1452 template<class _Other>
1453 sanitizing_allocator(_In_ const sanitizing_allocator<_Other> &_Othr) noexcept : _Mybase(_Othr)
1454 {
1455 }
1456
1460 void deallocate(_In_ pointer _Ptr, _In_ size_type _Size)
1461 {
1462 // Sanitize then free.
1463 SecureZeroMemory(_Ptr, _Size);
1464 _Mybase::deallocate(_Ptr, _Size);
1465 }
1466 };
1467
1468 #pragma warning(pop)
1469
1477 typedef std::basic_string<char, std::char_traits<char>, sanitizing_allocator<char> > sanitizing_string;
1478
1486 typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, sanitizing_allocator<wchar_t> > sanitizing_wstring;
1487
1491#ifdef _UNICODE
1493#else
1495#endif
1496
1500 template<size_t N>
1502 {
1503 public:
1508 {
1509 ZeroMemory(m_data, N);
1510 }
1511
1516 {
1517 SecureZeroMemory(m_data, N);
1518 }
1519
1520 public:
1521 unsigned char m_data[N];
1522 };
1523
1525}
Base template class to support converting GUID to string.
Definition: Common.h:1324
basic_string_guid(const GUID &guid, const _Elem *format)
Initializes a new string and formats its contents to string representation of given GUID.
Definition: Common.h:1335
Base template class to support string formatting using FormatMessage() style templates.
Definition: Common.h:1199
basic_string_msg(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, DWORD_PTR *Arguments)
Initializes a new string and formats its contents using FormatMessage() style.
Definition: Common.h:1274
basic_string_msg(DWORD dwFlags, LPCTSTR pszFormat, va_list *Arguments)
Initializes a new string and formats its contents using FormatMessage() style.
Definition: Common.h:1284
basic_string_msg(HINSTANCE hInstance, WORD wLanguageID, UINT nFormatID,...)
Initializes a new string and formats its contents using FormatMessage() style template in resources.
Definition: Common.h:1246
basic_string_msg(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, va_list *Arguments)
Initializes a new string and formats its contents using FormatMessage() style.
Definition: Common.h:1264
basic_string_msg(const _Elem *format,...)
Initializes a new string and formats its contents using FormatMessage() style template.
Definition: Common.h:1209
basic_string_msg(HINSTANCE hInstance, UINT nFormatID,...)
Initializes a new string and formats its contents using FormatMessage() style template in resources.
Definition: Common.h:1228
basic_string_msg(DWORD dwFlags, LPCTSTR pszFormat, DWORD_PTR *Arguments)
Initializes a new string and formats its contents using FormatMessage() style.
Definition: Common.h:1294
Base template class to support string formatting using printf() style templates.
Definition: Common.h:1114
basic_string_printf(const _Elem *format,...)
Initializes a new string and formats its contents using printf() style template.
Definition: Common.h:1124
basic_string_printf(HINSTANCE hInstance, WORD wLanguageID, UINT nFormatID,...)
Initializes a new string and formats its contents using printf() style template in resources.
Definition: Common.h:1161
basic_string_printf(HINSTANCE hInstance, UINT nFormatID,...)
Initializes a new string and formats its contents using printf() style template in resources.
Definition: Common.h:1143
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition: Common.h:865
dplhandle< handle_type, INVAL > & operator=(handle_type h) noexcept
Attaches already available object handle.
Definition: Common.h:906
handle_type duplicate() const
Duplicates and returns a new object handle.
Definition: Common.h:956
dplhandle< handle_type, INVAL > & operator=(dplhandle< handle_type, INVAL > &&h) noexcept
Moves the object.
Definition: Common.h:945
bool attach_duplicated(handle_type h)
Duplicates an object handle and sets a new object handle.
Definition: Common.h:970
virtual handle_type duplicate_internal(handle_type h) const noexcept=0
Abstract member function that must be implemented by child classes to do the actual object handle dup...
dplhandle(handle_type h) noexcept
Initializes a new class instance with an already available object handle.
Definition: Common.h:879
dplhandle< handle_type, INVAL > & operator=(const dplhandle< handle_type, INVAL > &h) noexcept
Duplicates the object.
Definition: Common.h:917
dplhandle() noexcept
Initializes a new class instance with the object handle set to INVAL.
Definition: Common.h:870
Base abstract template class to support generic object handle keeping.
Definition: Common.h:603
handle_type *& operator*() const
Returns the object handle value when the object handle is a pointer to a value (class,...
Definition: Common.h:693
virtual void free_internal() noexcept=0
Abstract member function that must be implemented by child classes to do the actual object destructio...
handle() noexcept
Initializes a new class instance with the object handle set to INVAL.
Definition: Common.h:618
bool operator>=(handle_type h) const
Is handle greater than or equal to?
Definition: Common.h:766
handle_type operator->() const
Provides object handle member access when the object handle is a pointer to a class or struct.
Definition: Common.h:714
handle_type * operator&()
Returns the object handle reference.
Definition: Common.h:703
T handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:608
handle(handle_type h) noexcept
Initializes a new class instance with an already available object handle.
Definition: Common.h:627
bool operator<(handle_type h) const
Is handle less than?
Definition: Common.h:740
handle< handle_type, INVAL > & operator=(handle_type h) noexcept
Attaches already available object handle.
Definition: Common.h:654
bool operator!() const
Tests if the object handle is INVAL.
Definition: Common.h:727
handle< handle_type, INVAL > & operator=(handle< handle_type, INVAL > &&h) noexcept
Move assignment.
Definition: Common.h:666
bool operator!=(handle_type h) const
Is handle not equal to?
Definition: Common.h:792
void free()
Destroys the object.
Definition: Common.h:839
handle_type m_h
Object handle.
Definition: Common.h:854
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:817
bool operator==(handle_type h) const
Is handle equal to?
Definition: Common.h:805
handle(handle< handle_type, INVAL > &&h) noexcept
Move constructor.
Definition: Common.h:636
handle_type detach()
Dismisses the object handle from this class.
Definition: Common.h:829
bool operator>(handle_type h) const
Is handle greater than?
Definition: Common.h:779
bool operator<=(handle_type h) const
Is handle less than or equal to?
Definition: Common.h:753
Numerical runtime error.
Definition: Common.h:1002
num_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition: Common.h:1025
num_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition: Common.h:1013
error_type number() const
Returns the Windows error number.
Definition: Common.h:1034
_Tn error_type
Error number type.
Definition: Common.h:1004
error_type m_num
Numeric error code.
Definition: Common.h:1040
Helper class for returning pointers to std::unique_ptr (specialization for arrays)
Definition: Common.h:497
std::unique_ptr< _Ty[], _Dx > & m_own
Original owner of the pointer.
Definition: Common.h:586
ref_unique_ptr(ref_unique_ptr< _Ty[], _Dx > &&other)
Moves object.
Definition: Common.h:531
virtual ~ref_unique_ptr()
Returns ownership of the pointer.
Definition: Common.h:559
ref_unique_ptr & operator=(std::unique_ptr< _Ty[], _Dx > &owner) noexcept
Takes ownership of the pointer.
Definition: Common.h:516
ref_unique_ptr(std::unique_ptr< _Ty[], _Dx > &owner) noexcept
Takes ownership of the pointer.
Definition: Common.h:504
_Ty * m_ptr
Pointer.
Definition: Common.h:587
ref_unique_ptr & operator=(ref_unique_ptr< _Ty[], _Dx > &&other)
Moves object.
Definition: Common.h:545
Helper class for returning pointers to std::unique_ptr.
Definition: Common.h:404
std::unique_ptr< _Ty, _Dx > & m_own
Original owner of the pointer.
Definition: Common.h:458
_Ty * m_ptr
Pointer.
Definition: Common.h:459
ref_unique_ptr(ref_unique_ptr< _Ty, _Dx > &&other)
Moves object.
Definition: Common.h:421
~ref_unique_ptr()
Returns ownership of the pointer.
Definition: Common.h:431
ref_unique_ptr(std::unique_ptr< _Ty, _Dx > &owner)
Takes ownership of the pointer.
Definition: Common.h:411
An allocator template that sanitizes each memory block before it is destroyed or reallocated.
Definition: Common.h:1422
sanitizing_allocator(const sanitizing_allocator< _Ty > &_Othr)
Construct by copying.
Definition: Common.h:1445
void deallocate(pointer _Ptr, size_type _Size)
Deallocate object at _Ptr sanitizing its content first.
Definition: Common.h:1460
sanitizing_allocator(const sanitizing_allocator< _Other > &_Othr) noexcept
Construct from a related allocator.
Definition: Common.h:1453
std::allocator< _Ty > _Mybase
Base type.
Definition: Common.h:1424
sanitizing_allocator() noexcept
Construct default allocator.
Definition: Common.h:1438
Sanitizing BLOB.
Definition: Common.h:1502
sanitizing_blob()
Constructs uninitialized BLOB.
Definition: Common.h:1507
~sanitizing_blob()
Sanitizes BLOB.
Definition: Common.h:1515
Single-byte character implementation of a class to support converting GUID to string.
Definition: Common.h:1352
string_guid(const GUID &guid)
Initializes a new string and formats its contents to string representation of given GUID.
Definition: Common.h:1362
Windows runtime error.
Definition: Common.h:1047
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition: Common.h:1092
win_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition: Common.h:1065
win_runtime_error(const std::string &msg)
Constructs an exception using GetLastError()
Definition: Common.h:1074
win_runtime_error(const char *msg=nullptr)
Constructs an exception using GetLastError()
Definition: Common.h:1083
win_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition: Common.h:1055
Wide character implementation of a class to support converting GUID to string.
Definition: Common.h:1374
wstring_guid(const GUID &guid)
Initializes a new string and formats its contents to string representation of given GUID.
Definition: Common.h:1384
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:79
ref_unique_ptr< _Ty[], _Dx > get_ptr(std::unique_ptr< _Ty[], _Dx > &owner) noexcept
Helper function template for returning pointers to std::unique_ptr (specialization for arrays)
Definition: Common.h:484
std::string tstring
Multi-byte / Wide-character string (according to _UNICODE)
Definition: Common.h:334
std::basic_string< wchar_t, std::char_traits< wchar_t >, sanitizing_allocator< wchar_t > > sanitizing_wstring
A sanitizing variant of std::wstring.
Definition: Common.h:1486
sanitizing_string sanitizing_tstring
Multi-byte / Wide-character sanitizing string (according to _UNICODE)
Definition: Common.h:1494
std::basic_string< char, std::char_traits< char >, sanitizing_allocator< char > > sanitizing_string
A sanitizing variant of std::string.
Definition: Common.h:1477
basic_string_printf< wchar_t, std::char_traits< wchar_t >, std::allocator< wchar_t > > wstring_printf
Wide character implementation of a class to support string formatting using printf() style templates.
Definition: Common.h:1183
string_guid tstring_guid
Multi-byte / Wide-character string GUID (according to _UNICODE)
Definition: Common.h:1398
basic_string_msg< wchar_t, std::char_traits< wchar_t >, std::allocator< wchar_t > > wstring_msg
Wide character implementation of a class to support string formatting using FormatMessage() style tem...
Definition: Common.h:1308
basic_string_printf< char, std::char_traits< char >, std::allocator< char > > string_printf
Single-byte character implementation of a class to support string formatting using printf() style tem...
Definition: Common.h:1178
string_printf tstring_printf
Multi-byte / Wide-character formatted string (according to _UNICODE)
Definition: Common.h:1191
basic_string_msg< char, std::char_traits< char >, std::allocator< char > > string_msg
Single-byte character implementation of a class to support string formatting using FormatMessage() st...
Definition: Common.h:1303
string_msg tstring_msg
Multi-byte / Wide-character formatted string (according to _UNICODE)
Definition: Common.h:1316
static const T invalid
Invalid handle value.
Definition: Common.h:613
LocalFree_delete() noexcept
Default construct.
Definition: Common.h:377
LocalFree_delete< _Ty > _Myt
This type.
Definition: Common.h:372
void operator()(_Other *) const
Delete a pointer of another type.
Definition: Common.h:393
void operator()(_Ty *_Ptr) const noexcept
Delete a pointer.
Definition: Common.h:382
Deleter for unique_ptr using LocalFree.
Definition: Common.h:342
LocalFree_delete< _Ty > _Myt
This type.
Definition: Common.h:343
LocalFree_delete(const LocalFree_delete< _Ty2 > &)
Construct from another LocalFree_delete.
Definition: Common.h:353
void operator()(_Ty *_Ptr) const
Delete a pointer.
Definition: Common.h:360
LocalFree_delete()
Default construct.
Definition: Common.h:348
Convert this type to sanitizing_allocator<_Other>
Definition: Common.h:1431
sanitizing_allocator< _Other > other
Other type.
Definition: Common.h:1432