From dd45eb934db09edcff49e3a0837d21d6133c2f7b Mon Sep 17 00:00:00 2001 From: Shane Guan Date: Fri, 21 Apr 2023 11:22:36 -0700 Subject: [PATCH 1/5] initial template --- windows/devices/uwb/UwbConnector.cxx | 22 ++++++++++++++++++- .../windows/devices/uwb/UwbConnector.hxx | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/windows/devices/uwb/UwbConnector.cxx b/windows/devices/uwb/UwbConnector.cxx index 7387021b..c1a5695e 100644 --- a/windows/devices/uwb/UwbConnector.cxx +++ b/windows/devices/uwb/UwbConnector.cxx @@ -591,6 +591,27 @@ UwbConnector::GetApplicationConfigurationParameters(uint32_t sessionId, std::vec return resultFuture; } +template +void +DeviceIoControlWrapper(std::string m_deviceName,std::promise &resultPromise, HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, std::string strFail, std::string strSuccess, std::function interpret){ + wil::unique_hfile handleDriver; + auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); + if (FAILED(hr)) { + PLOG_ERROR << "failed to obtain driver handle for " << m_deviceName << ", hr=" << std::showbase << std::hex << hr; + resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); + return; + } + + BOOL ioResult = DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, nullptr); + if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + PLOG_ERROR << strFail; + resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); + } else { + PLOG_DEBUG << strSuccess; + interpret(lpOutBuffer); + } +} std::future>> UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vector applicationConfigurationParameters) @@ -621,7 +642,6 @@ UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vec HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); PLOG_ERROR << "error when sending IOCTL_UWB_SET_APP_CONFIG_PARAMS with sessionId " << sessionId << ", hr = " << std::showbase << std::hex << hr; resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - return resultFuture; } else { PLOG_DEBUG << "IOCTL_UWB_SET_APP_CONFIG_PARAMS succeeded"; auto& setApplicationConfigurationParametersStatus = *reinterpret_cast(std::data(statusBuffer)); diff --git a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx index d985e9db..817c2fce 100644 --- a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx +++ b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx @@ -222,6 +222,10 @@ private: bool CallbacksPresent(); + // Internal function that wraps DeviceIoControl, handles errors and insufficient buffer size + void + DeviceIoControlWrapper(); + private: std::string m_deviceName{}; std::jthread m_notificationThread; From ccdc1a0f4f555995e9b00eda5e4aaae902e46753 Mon Sep 17 00:00:00 2001 From: Shane Guan Date: Tue, 25 Apr 2023 10:34:08 -0700 Subject: [PATCH 2/5] format --- windows/devices/uwb/UwbConnector.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/windows/devices/uwb/UwbConnector.cxx b/windows/devices/uwb/UwbConnector.cxx index 99a02279..c487a65e 100644 --- a/windows/devices/uwb/UwbConnector.cxx +++ b/windows/devices/uwb/UwbConnector.cxx @@ -632,7 +632,8 @@ UwbConnector::GetApplicationConfigurationParameters(uint32_t sessionId, std::vec } template void -DeviceIoControlWrapper(std::string m_deviceName,std::promise &resultPromise, HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, std::string strFail, std::string strSuccess, std::function interpret){ +DeviceIoControlWrapper(std::string m_deviceName, std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) +{ wil::unique_hfile handleDriver; auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); if (FAILED(hr)) { @@ -640,7 +641,7 @@ DeviceIoControlWrapper(std::string m_deviceName,std::promise &resultPr resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); return; } - + BOOL ioResult = DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, nullptr); if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); From dd8c306e9bd8b2a2847ba30276110a73e35a209c Mon Sep 17 00:00:00 2001 From: Shane Guan Date: Tue, 25 Apr 2023 10:54:56 -0700 Subject: [PATCH 3/5] first use of device io control wrapper --- windows/devices/uwb/UwbConnector.cxx | 93 +++++++++---------- .../windows/devices/uwb/UwbConnector.hxx | 4 +- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/windows/devices/uwb/UwbConnector.cxx b/windows/devices/uwb/UwbConnector.cxx index c487a65e..a1c63602 100644 --- a/windows/devices/uwb/UwbConnector.cxx +++ b/windows/devices/uwb/UwbConnector.cxx @@ -136,6 +136,29 @@ UwbConnector::DeviceName() const noexcept return m_deviceName; } +template +void +DeviceIoControlWrapper(std::string m_deviceName, std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) +{ + wil::unique_hfile handleDriver; + auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); + if (FAILED(hr)) { + PLOG_ERROR << "failed to obtain driver handle for " << m_deviceName << ", hr=" << std::showbase << std::hex << hr; + resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); + return; + } + + BOOL ioResult = DeviceIoControl(handleDriver.get(), dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, nullptr); + if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + PLOG_ERROR << strFail << ", hr = " << std::showbase << std::hex << hr; + resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); + } else { + PLOG_DEBUG << strSuccess; + interpret(); + } +} + std::future UwbConnector::Reset() { @@ -630,28 +653,6 @@ UwbConnector::GetApplicationConfigurationParameters(uint32_t sessionId, std::vec return resultFuture; } -template -void -DeviceIoControlWrapper(std::string m_deviceName, std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) -{ - wil::unique_hfile handleDriver; - auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); - if (FAILED(hr)) { - PLOG_ERROR << "failed to obtain driver handle for " << m_deviceName << ", hr=" << std::showbase << std::hex << hr; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - return; - } - - BOOL ioResult = DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, nullptr); - if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { - HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - PLOG_ERROR << strFail; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - } else { - PLOG_DEBUG << strSuccess; - interpret(lpOutBuffer); - } -} std::future>> UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vector applicationConfigurationParameters) @@ -659,14 +660,6 @@ UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vec std::promise>> resultPromise; auto resultFuture = resultPromise.get_future(); - wil::shared_hfile handleDriver; - auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); - if (FAILED(hr)) { - PLOG_ERROR << "failed to obtain driver handle for " << m_deviceName << ", hr=" << std::showbase << std::hex << hr; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - return resultFuture; - } - UwbCxDdi::UwbSetApplicationConfigurationParameters uwbSetApplicationConfigurationParameters{ .SessionId = sessionId, .Parameters = std::move(applicationConfigurationParameters), @@ -677,23 +670,29 @@ UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vec auto statusSize = offsetof(UWB_SET_APP_CONFIG_PARAMS_STATUS, appConfigParamsStatus[std::size(uwbSetApplicationConfigurationParameters.Parameters)]); std::vector statusBuffer(statusSize); - BOOL ioResult = DeviceIoControl(handleDriver.get(), IOCTL_UWB_SET_APP_CONFIG_PARAMS, std::data(paramsBuffer), std::size(paramsBuffer), std::data(statusBuffer), statusSize, nullptr, nullptr); - if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { - HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - PLOG_ERROR << "error when sending IOCTL_UWB_SET_APP_CONFIG_PARAMS with sessionId " << sessionId << ", hr = " << std::showbase << std::hex << hr; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - } else { - PLOG_DEBUG << "IOCTL_UWB_SET_APP_CONFIG_PARAMS succeeded"; - auto& setApplicationConfigurationParametersStatus = *reinterpret_cast(std::data(statusBuffer)); - auto uwbStatus = UwbCxDdi::To(setApplicationConfigurationParametersStatus.status); - if (!IsUwbStatusOk(uwbStatus)) { - resultPromise.set_exception(std::make_exception_ptr(UwbException(std::move(uwbStatus)))); - } else { - auto uwbSetApplicationConfigurationParametersStatus = UwbCxDdi::To(setApplicationConfigurationParametersStatus); - auto result = std::make_tuple(uwbSetApplicationConfigurationParametersStatus.Status, std::move(uwbSetApplicationConfigurationParametersStatus.ParameterStatuses)); - resultPromise.set_value(std::move(result)); - } - } + + DeviceIoControlWrapper( + m_deviceName, + resultPromise, + "error when sending IOCTL_UWB_SET_APP_CONFIG_PARAMS with sessionId " + std::to_string(sessionId), + "IOCTL_UWB_SET_APP_CONFIG_PARAMS succeeded", + [&]() { + auto& setApplicationConfigurationParametersStatus = *reinterpret_cast(std::data(statusBuffer)); + auto uwbStatus = UwbCxDdi::To(setApplicationConfigurationParametersStatus.status); + if (!IsUwbStatusOk(uwbStatus)) { + resultPromise.set_exception(std::make_exception_ptr(UwbException(std::move(uwbStatus)))); + } else { + auto uwbSetApplicationConfigurationParametersStatus = UwbCxDdi::To(setApplicationConfigurationParametersStatus); + auto result = std::make_tuple(uwbSetApplicationConfigurationParametersStatus.Status, std::move(uwbSetApplicationConfigurationParametersStatus.ParameterStatuses)); + resultPromise.set_value(std::move(result)); + } + }, + IOCTL_UWB_SET_APP_CONFIG_PARAMS, + std::data(paramsBuffer), + std::size(paramsBuffer), + std::data(statusBuffer), + statusSize, + nullptr); return resultFuture; } diff --git a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx index 29f3c8ce..d17413ff 100644 --- a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx +++ b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx @@ -223,8 +223,8 @@ private: CallbacksPresent(); // Internal function that wraps DeviceIoControl, handles errors and insufficient buffer size - void - DeviceIoControlWrapper(); + // void + // DeviceIoControlWrapper(); private: std::string m_deviceName{}; From 21f62ad676994f2266d0f73134583944082439cd Mon Sep 17 00:00:00 2001 From: Shane Guan Date: Thu, 27 Apr 2023 17:47:11 -0700 Subject: [PATCH 4/5] change the interface to be more concise --- windows/devices/uwb/UwbConnector.cxx | 28 ++++++++++++++++--- .../windows/devices/uwb/UwbConnector.hxx | 16 +++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/windows/devices/uwb/UwbConnector.cxx b/windows/devices/uwb/UwbConnector.cxx index a1c63602..46387cd7 100644 --- a/windows/devices/uwb/UwbConnector.cxx +++ b/windows/devices/uwb/UwbConnector.cxx @@ -136,9 +136,9 @@ UwbConnector::DeviceName() const noexcept return m_deviceName; } -template +template void -DeviceIoControlWrapper(std::string m_deviceName, std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned) +UwbConnector::DeviceIoControlWrapper(std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, ArgTs&&... args) { wil::unique_hfile handleDriver; auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); @@ -148,7 +148,7 @@ DeviceIoControlWrapper(std::string m_deviceName, std::promise& resultP return; } - BOOL ioResult = DeviceIoControl(handleDriver.get(), dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, nullptr); + BOOL ioResult = DeviceIoControl(handleDriver.get(), std::forward(args)...); if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); PLOG_ERROR << strFail << ", hr = " << std::showbase << std::hex << hr; @@ -195,6 +195,26 @@ UwbConnector::Reset() } } + DeviceIoControlWrapper( + resultPromise, + "error when sending IOCTL_UWB_DEVICE_RESET", + "IOCTL_UWB_DEVICE_RESET succeeded", + [&]() { + auto uwbStatus = UwbCxDdi::To(status); + if (!IsUwbStatusOk(uwbStatus)) { + resultPromise.set_exception(std::make_exception_ptr(UwbException(std::move(uwbStatus)))); + } else { + resultPromise.set_value(); + } + }, + IOCTL_UWB_DEVICE_RESET, + const_cast(&deviceReset), + sizeof deviceReset, + &status, + sizeof status, + nullptr, + nullptr); + return resultFuture; } @@ -672,7 +692,6 @@ UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vec std::vector statusBuffer(statusSize); DeviceIoControlWrapper( - m_deviceName, resultPromise, "error when sending IOCTL_UWB_SET_APP_CONFIG_PARAMS with sessionId " + std::to_string(sessionId), "IOCTL_UWB_SET_APP_CONFIG_PARAMS succeeded", @@ -692,6 +711,7 @@ UwbConnector::SetApplicationConfigurationParameters(uint32_t sessionId, std::vec std::size(paramsBuffer), std::data(statusBuffer), statusSize, + nullptr, nullptr); return resultFuture; diff --git a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx index d17413ff..7de97207 100644 --- a/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx +++ b/windows/devices/uwb/include/windows/devices/uwb/UwbConnector.hxx @@ -223,8 +223,20 @@ private: CallbacksPresent(); // Internal function that wraps DeviceIoControl, handles errors and insufficient buffer size - // void - // DeviceIoControlWrapper(); + /** + * @brief + * + * @tparam PromiseT + * @tparam ArgTs is everything that goes into a standard DeviceIOControl() call, aside from the leading handle argument + * @param resultPromise + * @param strFail + * @param strSuccess + * @param interpret + * @param args + */ + template + void + DeviceIoControlWrapper(std::promise& resultPromise, std::string strFail, std::string strSuccess, std::function interpret, ArgTs&&... args); private: std::string m_deviceName{}; From c101297ca065b6b7e7b233632d28a8300b77e73b Mon Sep 17 00:00:00 2001 From: Shane Guan Date: Thu, 27 Apr 2023 17:56:41 -0700 Subject: [PATCH 5/5] reset --- windows/devices/uwb/UwbConnector.cxx | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/windows/devices/uwb/UwbConnector.cxx b/windows/devices/uwb/UwbConnector.cxx index 46387cd7..5660bb6f 100644 --- a/windows/devices/uwb/UwbConnector.cxx +++ b/windows/devices/uwb/UwbConnector.cxx @@ -165,36 +165,12 @@ UwbConnector::Reset() std::promise resultPromise{}; auto resultFuture = resultPromise.get_future(); - wil::unique_hfile handleDriver; - auto hr = OpenDriverHandle(handleDriver, m_deviceName.c_str()); - if (FAILED(hr)) { - PLOG_ERROR << "failed to obtain driver handle for " << m_deviceName << ", hr=" << std::showbase << std::hex << hr; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Rejected))); - return resultFuture; - } - const UWB_DEVICE_RESET deviceReset{ .size = sizeof(UWB_DEVICE_RESET), .resetConfig = UWB_RESET_CONFIG_UWBS_RESET, }; UWB_STATUS status; - BOOL ioResult = DeviceIoControl(handleDriver.get(), IOCTL_UWB_DEVICE_RESET, const_cast(&deviceReset), sizeof deviceReset, &status, sizeof status, nullptr, nullptr); - if (!LOG_IF_WIN32_BOOL_FALSE(ioResult)) { - HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - PLOG_ERROR << "error when sending IOCTL_UWB_DEVICE_RESET, hr=" << std::showbase << std::hex << hr; - resultPromise.set_exception(std::make_exception_ptr(UwbException(UwbStatusGeneric::Failed))); - return resultFuture; - } else { - PLOG_DEBUG << "IOCTL_UWB_DEVICE_RESET succeeded"; - auto uwbStatus = UwbCxDdi::To(status); - if (!IsUwbStatusOk(uwbStatus)) { - resultPromise.set_exception(std::make_exception_ptr(UwbException(std::move(uwbStatus)))); - } else { - resultPromise.set_value(); - } - } - DeviceIoControlWrapper( resultPromise, "error when sending IOCTL_UWB_DEVICE_RESET",