File indexing completed on 2025-01-18 09:28:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
0013 #define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/asio/detail/config.hpp>
0020
0021 #if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
0022
0023 #include <cstring>
0024 #include <boost/asio/detail/win_iocp_serial_port_service.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031
0032 win_iocp_serial_port_service::win_iocp_serial_port_service(
0033 execution_context& context)
0034 : execution_context_service_base<win_iocp_serial_port_service>(context),
0035 handle_service_(context)
0036 {
0037 }
0038
0039 void win_iocp_serial_port_service::shutdown()
0040 {
0041 }
0042
0043 boost::system::error_code win_iocp_serial_port_service::open(
0044 win_iocp_serial_port_service::implementation_type& impl,
0045 const std::string& device, boost::system::error_code& ec)
0046 {
0047 if (is_open(impl))
0048 {
0049 ec = boost::asio::error::already_open;
0050 BOOST_ASIO_ERROR_LOCATION(ec);
0051 return ec;
0052 }
0053
0054
0055 std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
0056
0057
0058 ::HANDLE handle = ::CreateFileA(name.c_str(),
0059 GENERIC_READ | GENERIC_WRITE, 0, 0,
0060 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
0061 if (handle == INVALID_HANDLE_VALUE)
0062 {
0063 DWORD last_error = ::GetLastError();
0064 ec = boost::system::error_code(last_error,
0065 boost::asio::error::get_system_category());
0066 BOOST_ASIO_ERROR_LOCATION(ec);
0067 return ec;
0068 }
0069
0070
0071 using namespace std;
0072 ::DCB dcb;
0073 memset(&dcb, 0, sizeof(DCB));
0074 dcb.DCBlength = sizeof(DCB);
0075 if (!::GetCommState(handle, &dcb))
0076 {
0077 DWORD last_error = ::GetLastError();
0078 ::CloseHandle(handle);
0079 ec = boost::system::error_code(last_error,
0080 boost::asio::error::get_system_category());
0081 BOOST_ASIO_ERROR_LOCATION(ec);
0082 return ec;
0083 }
0084
0085
0086
0087 dcb.fBinary = TRUE;
0088 dcb.fNull = FALSE;
0089 dcb.fAbortOnError = FALSE;
0090 dcb.BaudRate = CBR_9600;
0091 dcb.ByteSize = 8;
0092 dcb.fOutxCtsFlow = FALSE;
0093 dcb.fOutxDsrFlow = FALSE;
0094 dcb.fDtrControl = DTR_CONTROL_DISABLE;
0095 dcb.fDsrSensitivity = FALSE;
0096 dcb.fOutX = FALSE;
0097 dcb.fInX = FALSE;
0098 dcb.fRtsControl = RTS_CONTROL_DISABLE;
0099 dcb.fParity = FALSE;
0100 dcb.Parity = NOPARITY;
0101 dcb.StopBits = ONESTOPBIT;
0102 if (!::SetCommState(handle, &dcb))
0103 {
0104 DWORD last_error = ::GetLastError();
0105 ::CloseHandle(handle);
0106 ec = boost::system::error_code(last_error,
0107 boost::asio::error::get_system_category());
0108 BOOST_ASIO_ERROR_LOCATION(ec);
0109 return ec;
0110 }
0111
0112
0113
0114
0115 ::COMMTIMEOUTS timeouts;
0116 timeouts.ReadIntervalTimeout = 1;
0117 timeouts.ReadTotalTimeoutMultiplier = 0;
0118 timeouts.ReadTotalTimeoutConstant = 0;
0119 timeouts.WriteTotalTimeoutMultiplier = 0;
0120 timeouts.WriteTotalTimeoutConstant = 0;
0121 if (!::SetCommTimeouts(handle, &timeouts))
0122 {
0123 DWORD last_error = ::GetLastError();
0124 ::CloseHandle(handle);
0125 ec = boost::system::error_code(last_error,
0126 boost::asio::error::get_system_category());
0127 BOOST_ASIO_ERROR_LOCATION(ec);
0128 return ec;
0129 }
0130
0131
0132 if (handle_service_.assign(impl, handle, ec))
0133 ::CloseHandle(handle);
0134 return ec;
0135 }
0136
0137 boost::system::error_code win_iocp_serial_port_service::do_set_option(
0138 win_iocp_serial_port_service::implementation_type& impl,
0139 win_iocp_serial_port_service::store_function_type store,
0140 const void* option, boost::system::error_code& ec)
0141 {
0142 using namespace std;
0143
0144 ::DCB dcb;
0145 memset(&dcb, 0, sizeof(DCB));
0146 dcb.DCBlength = sizeof(DCB);
0147 if (!::GetCommState(handle_service_.native_handle(impl), &dcb))
0148 {
0149 DWORD last_error = ::GetLastError();
0150 ec = boost::system::error_code(last_error,
0151 boost::asio::error::get_system_category());
0152 BOOST_ASIO_ERROR_LOCATION(ec);
0153 return ec;
0154 }
0155
0156 if (store(option, dcb, ec))
0157 return ec;
0158
0159 if (!::SetCommState(handle_service_.native_handle(impl), &dcb))
0160 {
0161 DWORD last_error = ::GetLastError();
0162 ec = boost::system::error_code(last_error,
0163 boost::asio::error::get_system_category());
0164 BOOST_ASIO_ERROR_LOCATION(ec);
0165 return ec;
0166 }
0167
0168 ec = boost::system::error_code();
0169 return ec;
0170 }
0171
0172 boost::system::error_code win_iocp_serial_port_service::do_get_option(
0173 const win_iocp_serial_port_service::implementation_type& impl,
0174 win_iocp_serial_port_service::load_function_type load,
0175 void* option, boost::system::error_code& ec) const
0176 {
0177 using namespace std;
0178
0179 ::DCB dcb;
0180 memset(&dcb, 0, sizeof(DCB));
0181 dcb.DCBlength = sizeof(DCB);
0182 if (!::GetCommState(handle_service_.native_handle(impl), &dcb))
0183 {
0184 DWORD last_error = ::GetLastError();
0185 ec = boost::system::error_code(last_error,
0186 boost::asio::error::get_system_category());
0187 BOOST_ASIO_ERROR_LOCATION(ec);
0188 return ec;
0189 }
0190
0191 return load(option, dcb, ec);
0192 }
0193
0194 }
0195 }
0196 }
0197
0198 #include <boost/asio/detail/pop_options.hpp>
0199
0200 #endif
0201
0202 #endif