connect_pipe.ipp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // impl/connect_pipe.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Copyright (c) 2021 Klemens D. Morgenstern
  7. // (klemens dot morgenstern at gmx dot net)
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  10. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. #ifndef BOOST_ASIO_IMPL_CONNECT_PIPE_IPP
  13. #define BOOST_ASIO_IMPL_CONNECT_PIPE_IPP
  14. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. # pragma once
  16. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  17. #include <boost/asio/detail/config.hpp>
  18. #if defined(BOOST_ASIO_HAS_PIPE)
  19. #include <boost/asio/connect_pipe.hpp>
  20. #if defined(BOOST_ASIO_HAS_IOCP)
  21. # include <cstdio>
  22. # if _WIN32_WINNT >= 0x601
  23. # include <bcrypt.h>
  24. # if !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS)
  25. # if defined(_MSC_VER)
  26. # pragma comment(lib, "bcrypt.lib")
  27. # endif // defined(_MSC_VER)
  28. # endif // !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS)
  29. # endif // _WIN32_WINNT >= 0x601
  30. #else // defined(BOOST_ASIO_HAS_IOCP)
  31. # include <boost/asio/detail/descriptor_ops.hpp>
  32. #endif // defined(BOOST_ASIO_HAS_IOCP)
  33. #include <boost/asio/detail/push_options.hpp>
  34. namespace boost {
  35. namespace asio {
  36. namespace detail {
  37. void create_pipe(native_pipe_handle p[2], boost::system::error_code& ec)
  38. {
  39. #if defined(BOOST_ASIO_HAS_IOCP)
  40. using namespace std; // For sprintf and memcmp.
  41. static long counter1 = 0;
  42. static long counter2 = 0;
  43. long n1 = ::InterlockedIncrement(&counter1);
  44. long n2 = (static_cast<unsigned long>(n1) % 0x10000000) == 0
  45. ? ::InterlockedIncrement(&counter2)
  46. : ::InterlockedExchangeAdd(&counter2, 0);
  47. wchar_t pipe_name[128];
  48. #if defined(BOOST_ASIO_HAS_SECURE_RTL)
  49. swprintf_s(
  50. #else // defined(BOOST_ASIO_HAS_SECURE_RTL)
  51. _snwprintf(
  52. #endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
  53. pipe_name, 128,
  54. L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld",
  55. static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2);
  56. p[0] = ::CreateNamedPipeW(pipe_name,
  57. PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
  58. 0, 1, 8192, 8192, 0, 0);
  59. if (p[0] == INVALID_HANDLE_VALUE)
  60. {
  61. DWORD last_error = ::GetLastError();
  62. ec.assign(last_error, boost::asio::error::get_system_category());
  63. return;
  64. }
  65. p[1] = ::CreateFileW(pipe_name, GENERIC_WRITE, 0,
  66. 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
  67. if (p[1] == INVALID_HANDLE_VALUE)
  68. {
  69. DWORD last_error = ::GetLastError();
  70. ::CloseHandle(p[0]);
  71. ec.assign(last_error, boost::asio::error::get_system_category());
  72. return;
  73. }
  74. # if _WIN32_WINNT >= 0x601
  75. unsigned char nonce[16];
  76. if (::BCryptGenRandom(0, nonce, sizeof(nonce),
  77. BCRYPT_USE_SYSTEM_PREFERRED_RNG) != 0)
  78. {
  79. ec = boost::asio::error::connection_aborted;
  80. ::CloseHandle(p[0]);
  81. ::CloseHandle(p[1]);
  82. return;
  83. }
  84. DWORD bytes_written = 0;
  85. BOOL ok = ::WriteFile(p[1], nonce, sizeof(nonce), &bytes_written, 0);
  86. if (!ok || bytes_written != sizeof(nonce))
  87. {
  88. ec = boost::asio::error::connection_aborted;
  89. ::CloseHandle(p[0]);
  90. ::CloseHandle(p[1]);
  91. return;
  92. }
  93. unsigned char nonce_check[sizeof(nonce)];
  94. DWORD bytes_read = 0;
  95. ok = ::ReadFile(p[0], nonce_check, sizeof(nonce), &bytes_read, 0);
  96. if (!ok || bytes_read != sizeof(nonce)
  97. || memcmp(nonce, nonce_check, sizeof(nonce)) != 0)
  98. {
  99. ec = boost::asio::error::connection_aborted;
  100. ::CloseHandle(p[0]);
  101. ::CloseHandle(p[1]);
  102. return;
  103. }
  104. #endif // _WIN32_WINNT >= 0x601
  105. boost::asio::error::clear(ec);
  106. #else // defined(BOOST_ASIO_HAS_IOCP)
  107. int result = ::pipe(p);
  108. detail::descriptor_ops::get_last_error(ec, result != 0);
  109. #endif // defined(BOOST_ASIO_HAS_IOCP)
  110. }
  111. void close_pipe(native_pipe_handle p)
  112. {
  113. #if defined(BOOST_ASIO_HAS_IOCP)
  114. ::CloseHandle(p);
  115. #else // defined(BOOST_ASIO_HAS_IOCP)
  116. boost::system::error_code ignored_ec;
  117. detail::descriptor_ops::state_type state = 0;
  118. detail::descriptor_ops::close(p, state, ignored_ec);
  119. #endif // defined(BOOST_ASIO_HAS_IOCP)
  120. }
  121. } // namespace detail
  122. } // namespace asio
  123. } // namespace boost
  124. #include <boost/asio/detail/pop_options.hpp>
  125. #endif // defined(BOOST_ASIO_HAS_PIPE)
  126. #endif // BOOST_ASIO_IMPL_CONNECT_PIPE_IPP