]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // |
2 | // impl/connect_pipe.ipp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
5 | // Copyright (c) 2003-2022 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 | ||
13 | #ifndef BOOST_ASIO_IMPL_CONNECT_PIPE_IPP | |
14 | #define BOOST_ASIO_IMPL_CONNECT_PIPE_IPP | |
15 | ||
16 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | # pragma once | |
18 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
19 | ||
20 | #include <boost/asio/detail/config.hpp> | |
21 | ||
22 | #if defined(BOOST_ASIO_HAS_PIPE) | |
23 | ||
24 | #include <boost/asio/connect_pipe.hpp> | |
25 | ||
26 | #if defined(BOOST_ASIO_HAS_IOCP) | |
27 | # include <cstdio> | |
28 | # if _WIN32_WINNT >= 0x601 | |
29 | # include <bcrypt.h> | |
30 | # if !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS) | |
31 | # if defined(_MSC_VER) | |
32 | # pragma comment(lib, "bcrypt.lib") | |
33 | # endif // defined(_MSC_VER) | |
34 | # endif // !defined(BOOST_ASIO_NO_DEFAULT_LINKED_LIBS) | |
35 | # endif // _WIN32_WINNT >= 0x601 | |
36 | #else // defined(BOOST_ASIO_HAS_IOCP) | |
37 | # include <boost/asio/detail/descriptor_ops.hpp> | |
38 | #endif // defined(BOOST_ASIO_HAS_IOCP) | |
39 | ||
40 | #include <boost/asio/detail/push_options.hpp> | |
41 | ||
42 | namespace boost { | |
43 | namespace asio { | |
44 | namespace detail { | |
45 | ||
46 | void create_pipe(native_pipe_handle p[2], boost::system::error_code& ec) | |
47 | { | |
48 | #if defined(BOOST_ASIO_HAS_IOCP) | |
49 | using namespace std; // For sprintf and memcmp. | |
50 | ||
51 | static long counter1 = 0; | |
52 | static long counter2 = 0; | |
53 | ||
54 | long n1 = ::InterlockedIncrement(&counter1); | |
55 | long n2 = (static_cast<unsigned long>(n1) % 0x10000000) == 0 | |
56 | ? ::InterlockedIncrement(&counter2) | |
57 | : ::InterlockedExchangeAdd(&counter2, 0); | |
58 | ||
59 | wchar_t pipe_name[128]; | |
60 | #if defined(BOOST_ASIO_HAS_SECURE_RTL) | |
61 | swprintf_s( | |
62 | #else // defined(BOOST_ASIO_HAS_SECURE_RTL) | |
63 | _snwprintf( | |
64 | #endif // defined(BOOST_ASIO_HAS_SECURE_RTL) | |
65 | pipe_name, 128, | |
66 | L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld", | |
67 | static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2); | |
68 | ||
69 | p[0] = ::CreateNamedPipeW(pipe_name, | |
70 | PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, | |
71 | 0, 1, 8192, 8192, 0, 0); | |
72 | ||
73 | if (p[0] == INVALID_HANDLE_VALUE) | |
74 | { | |
75 | DWORD last_error = ::GetLastError(); | |
76 | ec.assign(last_error, boost::asio::error::get_system_category()); | |
77 | return; | |
78 | } | |
79 | ||
80 | p[1] = ::CreateFileW(pipe_name, GENERIC_WRITE, 0, | |
81 | 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); | |
82 | ||
83 | if (p[1] == INVALID_HANDLE_VALUE) | |
84 | { | |
85 | DWORD last_error = ::GetLastError(); | |
86 | ::CloseHandle(p[0]); | |
87 | ec.assign(last_error, boost::asio::error::get_system_category()); | |
88 | return; | |
89 | } | |
90 | ||
91 | # if _WIN32_WINNT >= 0x601 | |
92 | unsigned char nonce[16]; | |
93 | if (::BCryptGenRandom(0, nonce, sizeof(nonce), | |
94 | BCRYPT_USE_SYSTEM_PREFERRED_RNG) != 0) | |
95 | { | |
96 | ec = boost::asio::error::connection_aborted; | |
97 | ::CloseHandle(p[0]); | |
98 | ::CloseHandle(p[1]); | |
99 | return; | |
100 | } | |
101 | ||
102 | DWORD bytes_written = 0; | |
103 | BOOL ok = ::WriteFile(p[1], nonce, sizeof(nonce), &bytes_written, 0); | |
104 | if (!ok || bytes_written != sizeof(nonce)) | |
105 | { | |
106 | ec = boost::asio::error::connection_aborted; | |
107 | ::CloseHandle(p[0]); | |
108 | ::CloseHandle(p[1]); | |
109 | return; | |
110 | } | |
111 | ||
112 | unsigned char nonce_check[sizeof(nonce)]; | |
113 | DWORD bytes_read = 0; | |
114 | ok = ::ReadFile(p[0], nonce_check, sizeof(nonce), &bytes_read, 0); | |
115 | if (!ok || bytes_read != sizeof(nonce) | |
116 | || memcmp(nonce, nonce_check, sizeof(nonce)) != 0) | |
117 | { | |
118 | ec = boost::asio::error::connection_aborted; | |
119 | ::CloseHandle(p[0]); | |
120 | ::CloseHandle(p[1]); | |
121 | return; | |
122 | } | |
123 | #endif // _WIN32_WINNT >= 0x601 | |
124 | ||
125 | ec.assign(0, ec.category()); | |
126 | #else // defined(BOOST_ASIO_HAS_IOCP) | |
127 | int result = ::pipe(p); | |
128 | detail::descriptor_ops::get_last_error(ec, result != 0); | |
129 | #endif // defined(BOOST_ASIO_HAS_IOCP) | |
130 | } | |
131 | ||
132 | void close_pipe(native_pipe_handle p) | |
133 | { | |
134 | #if defined(BOOST_ASIO_HAS_IOCP) | |
135 | ::CloseHandle(p); | |
136 | #else // defined(BOOST_ASIO_HAS_IOCP) | |
137 | boost::system::error_code ignored_ec; | |
138 | detail::descriptor_ops::state_type state = 0; | |
139 | detail::descriptor_ops::close(p, state, ignored_ec); | |
140 | #endif // defined(BOOST_ASIO_HAS_IOCP) | |
141 | } | |
142 | ||
143 | } // namespace detail | |
144 | } // namespace asio | |
145 | } // namespace boost | |
146 | ||
147 | #include <boost/asio/detail/pop_options.hpp> | |
148 | ||
149 | #endif // defined(BOOST_ASIO_HAS_PIPE) | |
150 | ||
151 | #endif // BOOST_ASIO_IMPL_CONNECT_PIPE_IPP |