Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

115 linhas
3.4 KiB

  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. #include <vector>
  18. #if defined(WIL_ENABLE_EXCEPTIONS)
  19. namespace wil
  20. {
  21. /** Secure allocator for STL containers.
  22. The `wil::secure_allocator` allocator calls `SecureZeroMemory` before deallocating
  23. memory. This provides a mechanism for secure STL containers such as `wil::secure_vector`,
  24. `wil::secure_string`, and `wil::secure_wstring`. */
  25. template <typename T>
  26. struct secure_allocator
  27. : public std::allocator<T>
  28. {
  29. template<typename Other>
  30. struct rebind
  31. {
  32. typedef secure_allocator<Other> other;
  33. };
  34. secure_allocator()
  35. : std::allocator<T>()
  36. {
  37. }
  38. ~secure_allocator() = default;
  39. secure_allocator(const secure_allocator& a)
  40. : std::allocator<T>(a)
  41. {
  42. }
  43. template <class U>
  44. secure_allocator(const secure_allocator<U>& a)
  45. : std::allocator<T>(a)
  46. {
  47. }
  48. T* allocate(size_t n)
  49. {
  50. return std::allocator<T>::allocate(n);
  51. }
  52. void deallocate(T* p, size_t n)
  53. {
  54. SecureZeroMemory(p, sizeof(T) * n);
  55. std::allocator<T>::deallocate(p, n);
  56. }
  57. };
  58. //! `wil::secure_vector` will be securely zeroed before deallocation.
  59. template <typename Type>
  60. using secure_vector = std::vector<Type, secure_allocator<Type>>;
  61. //! `wil::secure_wstring` will be securely zeroed before deallocation.
  62. using secure_wstring = std::basic_string<wchar_t, std::char_traits<wchar_t>, wil::secure_allocator<wchar_t>>;
  63. //! `wil::secure_string` will be securely zeroed before deallocation.
  64. using secure_string = std::basic_string<char, std::char_traits<char>, wil::secure_allocator<char>>;
  65. /// @cond
  66. namespace details
  67. {
  68. template<> struct string_maker<std::wstring>
  69. {
  70. HRESULT make(_In_reads_opt_(length) PCWSTR source, size_t length) WI_NOEXCEPT try
  71. {
  72. m_value = source ? std::wstring(source, length) : std::wstring(length, L'\0');
  73. return S_OK;
  74. }
  75. catch (...)
  76. {
  77. return E_OUTOFMEMORY;
  78. }
  79. wchar_t* buffer() { return &m_value[0]; }
  80. std::wstring release() { return std::wstring(std::move(m_value)); }
  81. static PCWSTR get(const std::wstring& value) { return value.c_str(); }
  82. private:
  83. std::wstring m_value;
  84. };
  85. }
  86. /// @endcond
  87. // str_raw_ptr is an overloaded function that retrieves a const pointer to the first character in a string's buffer.
  88. // This is the overload for std::wstring. Other overloads available in resource.h.
  89. inline PCWSTR str_raw_ptr(const std::wstring& str)
  90. {
  91. return str.c_str();
  92. }
  93. } // namespace wil
  94. #endif // WIL_ENABLE_EXCEPTIONS
  95. #endif // __WIL_STL_INCLUDED