45
45
#include " src/logging.h"
46
46
#include " src/platform/common.h"
47
47
#include " src/utility.h"
48
+ #include " utf_utils.h"
48
49
49
50
// UDP_SEND_MSG_SIZE was added in the Windows 10 20H1 SDK
50
51
#ifndef UDP_SEND_MSG_SIZE
@@ -314,7 +315,7 @@ namespace platf {
314
315
// Parse the environment block and populate env
315
316
for (auto c = (PWCHAR) env_block; *c != UNICODE_NULL; c += wcslen (c) + 1 ) {
316
317
// Environment variable entries end with a null-terminator, so std::wstring() will get an entire entry.
317
- std::string env_tuple = to_utf8 (std::wstring {c});
318
+ std::string env_tuple = utf_utils:: to_utf8 (std::wstring {c});
318
319
std::string env_name = env_tuple.substr (0 , env_tuple.find (' =' ));
319
320
std::string env_val = env_tuple.substr (env_tuple.find (' =' ) + 1 );
320
321
@@ -384,7 +385,7 @@ namespace platf {
384
385
for (const auto &entry : env) {
385
386
auto name = entry.get_name ();
386
387
auto value = entry.to_string ();
387
- size += from_utf8 (name).length () + 1 /* L'=' */ + from_utf8 (value).length () + 1 /* L'\0' */ ;
388
+ size += utf_utils:: from_utf8 (name).length () + 1 /* L'=' */ + utf_utils:: from_utf8 (value).length () + 1 /* L'\0' */ ;
388
389
}
389
390
390
391
size += 1 /* L'\0' */ ;
@@ -396,9 +397,9 @@ namespace platf {
396
397
auto value = entry.to_string ();
397
398
398
399
// Construct the NAME=VAL\0 string
399
- append_string_to_environment_block (env_block, offset, from_utf8 (name));
400
+ append_string_to_environment_block (env_block, offset, utf_utils:: from_utf8 (name));
400
401
env_block[offset++] = L' =' ;
401
- append_string_to_environment_block (env_block, offset, from_utf8 (value));
402
+ append_string_to_environment_block (env_block, offset, utf_utils:: from_utf8 (value));
402
403
env_block[offset++] = L' \0 ' ;
403
404
}
404
405
@@ -676,14 +677,14 @@ namespace platf {
676
677
* @return A command string suitable for use by CreateProcess().
677
678
*/
678
679
std::wstring resolve_command_string (const std::string &raw_cmd, const std::wstring &working_dir, HANDLE token, DWORD &creation_flags) {
679
- std::wstring raw_cmd_w = from_utf8 (raw_cmd);
680
+ std::wstring raw_cmd_w = utf_utils:: from_utf8 (raw_cmd);
680
681
681
682
// First, convert the given command into parts so we can get the executable/file/URL without parameters
682
683
auto raw_cmd_parts = boost::program_options::split_winmain (raw_cmd_w);
683
684
if (raw_cmd_parts.empty ()) {
684
685
// This is highly unexpected, but we'll just return the raw string and hope for the best.
685
686
BOOST_LOG (warning) << " Failed to split command string: " sv << raw_cmd;
686
- return from_utf8 (raw_cmd);
687
+ return utf_utils:: from_utf8 (raw_cmd);
687
688
}
688
689
689
690
auto raw_target = raw_cmd_parts.at (0 );
@@ -697,7 +698,7 @@ namespace platf {
697
698
res = UrlGetPartW (raw_target.c_str (), scheme.data (), &out_len, URL_PART_SCHEME, 0 );
698
699
if (res != S_OK) {
699
700
BOOST_LOG (warning) << " Failed to extract URL scheme from URL: " sv << raw_target << " [" sv << util::hex (res).to_string_view () << ' ]' ;
700
- return from_utf8 (raw_cmd);
701
+ return utf_utils:: from_utf8 (raw_cmd);
701
702
}
702
703
703
704
// If the target is a URL, the class is found using the URL scheme (prior to and not including the ':')
@@ -708,13 +709,13 @@ namespace platf {
708
709
if (extension == nullptr || *extension == 0 ) {
709
710
// If the file has no extension, assume it's a command and allow CreateProcess()
710
711
// to try to find it via PATH
711
- return from_utf8 (raw_cmd);
712
+ return utf_utils:: from_utf8 (raw_cmd);
712
713
} else if (boost::iequals (extension, L" .exe" )) {
713
714
// If the file has an .exe extension, we will bypass the resolution here and
714
715
// directly pass the unmodified command string to CreateProcess(). The argument
715
716
// escaping rules are subtly different between CreateProcess() and ShellExecute(),
716
717
// and we want to preserve backwards compatibility with older configs.
717
- return from_utf8 (raw_cmd);
718
+ return utf_utils:: from_utf8 (raw_cmd);
718
719
}
719
720
720
721
// For regular files, the class is found using the file extension (including the dot)
@@ -731,7 +732,7 @@ namespace platf {
731
732
732
733
// Override HKEY_CLASSES_ROOT and HKEY_CURRENT_USER to ensure we query the correct class info
733
734
if (!override_per_user_predefined_keys (token)) {
734
- return from_utf8 (raw_cmd);
735
+ return utf_utils:: from_utf8 (raw_cmd);
735
736
}
736
737
737
738
// Find the command string for the specified class
@@ -762,7 +763,7 @@ namespace platf {
762
763
763
764
if (res != S_OK) {
764
765
BOOST_LOG (warning) << " Failed to query command string for raw command: " sv << raw_cmd << " [" sv << util::hex (res).to_string_view () << ' ]' ;
765
- return from_utf8 (raw_cmd);
766
+ return utf_utils:: from_utf8 (raw_cmd);
766
767
}
767
768
768
769
// Finally, construct the real command string that will be passed into CreateProcess().
@@ -896,7 +897,7 @@ namespace platf {
896
897
* @return A `bp::child` object representing the new process, or an empty `bp::child` object if the launch fails.
897
898
*/
898
899
bp::child run_command (bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
899
- std::wstring start_dir = from_utf8 (working_dir.string ());
900
+ std::wstring start_dir = utf_utils:: from_utf8 (working_dir.string ());
900
901
HANDLE job = group ? group->native_handle () : nullptr ;
901
902
STARTUPINFOEXW startup_info = create_startup_info (file, job ? &job : nullptr , ec);
902
903
PROCESS_INFORMATION process_info;
@@ -1687,65 +1688,13 @@ namespace platf {
1687
1688
return {};
1688
1689
}
1689
1690
1690
- std::wstring from_utf8 (const std::string &string) {
1691
- // No conversion needed if the string is empty
1692
- if (string.empty ()) {
1693
- return {};
1694
- }
1695
-
1696
- // Get the output size required to store the string
1697
- auto output_size = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, string.data (), string.size (), nullptr , 0 );
1698
- if (output_size == 0 ) {
1699
- auto winerr = GetLastError ();
1700
- BOOST_LOG (error) << " Failed to get UTF-16 buffer size: " sv << winerr;
1701
- return {};
1702
- }
1703
-
1704
- // Perform the conversion
1705
- std::wstring output (output_size, L' \0 ' );
1706
- output_size = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, string.data (), string.size (), output.data (), output.size ());
1707
- if (output_size == 0 ) {
1708
- auto winerr = GetLastError ();
1709
- BOOST_LOG (error) << " Failed to convert string to UTF-16: " sv << winerr;
1710
- return {};
1711
- }
1712
-
1713
- return output;
1714
- }
1715
-
1716
- std::string to_utf8 (const std::wstring &string) {
1717
- // No conversion needed if the string is empty
1718
- if (string.empty ()) {
1719
- return {};
1720
- }
1721
-
1722
- // Get the output size required to store the string
1723
- auto output_size = WideCharToMultiByte (CP_UTF8, WC_ERR_INVALID_CHARS, string.data (), string.size (), nullptr , 0 , nullptr , nullptr );
1724
- if (output_size == 0 ) {
1725
- auto winerr = GetLastError ();
1726
- BOOST_LOG (error) << " Failed to get UTF-8 buffer size: " sv << winerr;
1727
- return {};
1728
- }
1729
-
1730
- // Perform the conversion
1731
- std::string output (output_size, ' \0 ' );
1732
- output_size = WideCharToMultiByte (CP_UTF8, WC_ERR_INVALID_CHARS, string.data (), string.size (), output.data (), output.size (), nullptr , nullptr );
1733
- if (output_size == 0 ) {
1734
- auto winerr = GetLastError ();
1735
- BOOST_LOG (error) << " Failed to convert string to UTF-8: " sv << winerr;
1736
- return {};
1737
- }
1738
-
1739
- return output;
1740
- }
1741
-
1742
1691
std::string get_host_name () {
1743
1692
WCHAR hostname[256 ];
1744
1693
if (GetHostNameW (hostname, ARRAYSIZE (hostname)) == SOCKET_ERROR) {
1745
1694
BOOST_LOG (error) << " GetHostNameW() failed: " sv << WSAGetLastError ();
1746
1695
return " Sunshine" s;
1747
1696
}
1748
- return to_utf8 (hostname);
1697
+ return utf_utils:: to_utf8 (hostname);
1749
1698
}
1750
1699
1751
1700
class win32_high_precision_timer : public high_precision_timer {
0 commit comments