diff --git a/src/gpgmm/common/BUILD.gn b/src/gpgmm/common/BUILD.gn index c1ee80ea5..8e439ce5b 100644 --- a/src/gpgmm/common/BUILD.gn +++ b/src/gpgmm/common/BUILD.gn @@ -168,7 +168,11 @@ if (is_win || is_linux || is_chromeos || is_mac || is_fuchsia || is_android) { ] if (is_win) { - sources += [ "WindowsTime.cpp" ] + sources += [ + "WindowsTime.cpp", + "WindowsUtils.cpp", + "WindowsUtils.h", + ] } configs += [ ":gpgmm_common_config" ] diff --git a/src/gpgmm/common/CMakeLists.txt b/src/gpgmm/common/CMakeLists.txt index 0f2d4eb9f..442189a80 100644 --- a/src/gpgmm/common/CMakeLists.txt +++ b/src/gpgmm/common/CMakeLists.txt @@ -41,6 +41,8 @@ target_sources(gpgmm_common PRIVATE if (WIN32) target_sources(gpgmm_common PRIVATE "WindowsTime.cpp" + "WindowsUtils.cpp" + "WindowsUtils.h" ) endif() diff --git a/src/gpgmm/common/WindowsUtils.cpp b/src/gpgmm/common/WindowsUtils.cpp new file mode 100644 index 000000000..798716dd2 --- /dev/null +++ b/src/gpgmm/common/WindowsUtils.cpp @@ -0,0 +1,51 @@ +// Copyright 2021 The GPGMM Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "WindowsUtils.h" + +#include "Assert.h" + +#include +#include + +#include // must include before stringapiset. + +#include + +namespace gpgmm { + + std::wstring TCharToWString(const wchar_t* const str) { + return str; + } + + std::wstring TCharToWString(const char* const str) { + std::string strFrom(str); + int requiredSize = + MultiByteToWideChar(CP_UTF8, 0, &strFrom[0], static_cast(strFrom.size()), NULL, 0); + + std::wstring wstrTo(requiredSize, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast(strFrom.size()), &wstrTo[0], + requiredSize); + return wstrTo; + } + + std::string WCharToUTF8(const wchar_t* str) { + int requiredSize = WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, nullptr, nullptr); + std::string result; + result.resize(requiredSize - 1); + WideCharToMultiByte(CP_UTF8, 0, str, -1, &result[0], requiredSize, nullptr, nullptr); + return result; + } + +} // namespace gpgmm diff --git a/src/gpgmm/common/WindowsUtils.h b/src/gpgmm/common/WindowsUtils.h new file mode 100644 index 000000000..99436dd5a --- /dev/null +++ b/src/gpgmm/common/WindowsUtils.h @@ -0,0 +1,28 @@ +// Copyright 2021 The GPGMM Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GPGMM_COMMON_WINDOWSUTILS_H +#define GPGMM_COMMON_WINDOWSUTILS_H + +#include +namespace gpgmm { + + std::wstring TCharToWString(const wchar_t* const str); + std::wstring TCharToWString(const char* const str); + + std::string WCharToUTF8(const wchar_t* str); + +} // namespace gpgmm + +#endif // GPGMM_COMMON_WINDOWSUTILS_H diff --git a/src/gpgmm/d3d12/ErrorD3D12.cpp b/src/gpgmm/d3d12/ErrorD3D12.cpp index f3b0ade90..0f7a92bed 100644 --- a/src/gpgmm/d3d12/ErrorD3D12.cpp +++ b/src/gpgmm/d3d12/ErrorD3D12.cpp @@ -14,6 +14,8 @@ #include "gpgmm/d3d12/ErrorD3D12.h" +#include "gpgmm/common/WindowsUtils.h" + #include #include #include @@ -21,8 +23,9 @@ namespace gpgmm { namespace d3d12 { std::string GetErrorMessage(HRESULT error) { + std::wstring wstring = TCharToWString(_com_error(error).ErrorMessage()); std::stringstream ss; - ss << _com_error(error).ErrorMessage() << " (0x" << std::hex << std::uppercase + ss << WCharToUTF8(wstring.c_str()) << " (0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << error << ")"; return ss.str(); }