No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

125 líneas
3.6KB

  1. //*********************************************************
  2. //
  3. // Copyright (c) Microsoft. All rights reserved.
  4. // This code is licensed under the MIT License.
  5. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  6. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  7. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  8. // PARTICULAR PURPOSE AND NONINFRINGEMENT.
  9. //
  10. //*********************************************************
  11. #ifndef __WIL_STL_INCLUDED
  12. #define __WIL_STL_INCLUDED
  13. #include "common.h"
  14. #include "resource.h"
  15. #include <memory>
  16. #include <string>
  17. #if defined(WIL_ENABLE_EXCEPTIONS)
  18. namespace std
  19. {
  20. template<class _Ty, class _Alloc>
  21. class vector;
  22. template<class _Elem>
  23. struct char_traits;
  24. template<class _Elem, class _Traits, class _Alloc>
  25. class basic_string;
  26. } // namespace std
  27. namespace wil
  28. {
  29. /** Secure allocator for STL containers.
  30. The `wil::secure_allocator` allocator calls `SecureZeroMemory` before deallocating
  31. memory. This provides a mechanism for secure STL containers such as `wil::secure_vector`,
  32. `wil::secure_string`, and `wil::secure_wstring`. */
  33. template <typename T>
  34. struct secure_allocator
  35. : public std::allocator<T>
  36. {
  37. template<typename Other>
  38. struct rebind
  39. {
  40. typedef secure_allocator<Other> other;
  41. };
  42. secure_allocator()
  43. : std::allocator<T>()
  44. {
  45. }
  46. ~secure_allocator() = default;
  47. secure_allocator(const secure_allocator& a)
  48. : std::allocator<T>(a)
  49. {
  50. }
  51. template <class U>
  52. secure_allocator(const secure_allocator<U>& a)
  53. : std::allocator<T>(a)
  54. {
  55. }
  56. T* allocate(size_t n)
  57. {
  58. return std::allocator<T>::allocate(n);
  59. }
  60. void deallocate(T* p, size_t n)
  61. {
  62. SecureZeroMemory(p, sizeof(T) * n);
  63. std::allocator<T>::deallocate(p, n);
  64. }
  65. };
  66. //! `wil::secure_vector` will be securely zeroed before deallocation.
  67. template <typename Type>
  68. using secure_vector = std::vector<Type, secure_allocator<Type>>;
  69. //! `wil::secure_wstring` will be securely zeroed before deallocation.
  70. using secure_wstring = std::basic_string<wchar_t, std::char_traits<wchar_t>, wil::secure_allocator<wchar_t>>;
  71. //! `wil::secure_string` will be securely zeroed before deallocation.
  72. using secure_string = std::basic_string<char, std::char_traits<char>, wil::secure_allocator<char>>;
  73. /// @cond
  74. namespace details
  75. {
  76. template<> struct string_maker<std::wstring>
  77. {
  78. HRESULT make(_In_reads_opt_(length) PCWSTR source, size_t length) WI_NOEXCEPT try
  79. {
  80. m_value = source ? std::wstring(source, length) : std::wstring(length, L'\0');
  81. return S_OK;
  82. }
  83. catch (...)
  84. {
  85. return E_OUTOFMEMORY;
  86. }
  87. wchar_t* buffer() { return &m_value[0]; }
  88. std::wstring release() { return std::wstring(std::move(m_value)); }
  89. static PCWSTR get(const std::wstring& value) { return value.c_str(); }
  90. private:
  91. std::wstring m_value;
  92. };
  93. }
  94. /// @endcond
  95. // str_raw_ptr is an overloaded function that retrieves a const pointer to the first character in a string's buffer.
  96. // This is the overload for std::wstring. Other overloads available in resource.h.
  97. inline PCWSTR str_raw_ptr(const std::wstring& str)
  98. {
  99. return str.c_str();
  100. }
  101. } // namespace wil
  102. #endif // WIL_ENABLE_EXCEPTIONS
  103. #endif // __WIL_STL_INCLUDED