From b3b686ed532b760fa3e23aceddabe832ce5ae71d Mon Sep 17 00:00:00 2001 From: liushuyu Date: Sat, 29 Jun 2019 08:53:28 -0600 Subject: [PATCH] native: further improve Unicode support on Windows --- src/native/interop.cpp | 38 ++++++++++++++++++-------------------- src/native/mod.rs | 25 ++++++++++++------------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/native/interop.cpp b/src/native/interop.cpp index d57ff09..18be048 100644 --- a/src/native/interop.cpp +++ b/src/native/interop.cpp @@ -2,6 +2,15 @@ * Misc interop helpers. **/ +// Explicitly use the Unicode version of the APIs +#ifndef UNICODE +#define UNICODE +#endif + +#ifndef _UNICODE +#define _UNICODE +#endif + #include "windows.h" #include "winnls.h" #include "shobjidl.h" @@ -30,25 +39,17 @@ extern "C" int isDarkThemeActive() } extern "C" int saveShortcut( - const char *shortcutPath, - const char *description, - const char *path, - const char *args, - const char *workingDir) + const wchar_t *shortcutPath, + const wchar_t *description, + const wchar_t *path, + const wchar_t *args, + const wchar_t *workingDir) { char *errStr = NULL; HRESULT h; IShellLink *shellLink = NULL; IPersistFile *persistFile = NULL; -#ifdef _WIN64 - wchar_t wName[MAX_PATH + 1]; -#else - WORD wName[MAX_PATH + 1]; -#endif - - int id; - // Initialize the COM library h = CoInitialize(NULL); if (FAILED(h)) @@ -72,12 +73,9 @@ extern "C" int saveShortcut( goto err; } - //Append the shortcut name to the folder - MultiByteToWideChar(CP_UTF8, 0, shortcutPath, -1, wName, MAX_PATH); - // Load the file if it exists, to get the values for anything // that we do not set. Ignore errors, such as if it does not exist. - h = persistFile->Load(wName, 0); + h = persistFile->Load(shortcutPath, 0); // Set the fields for which the application has set a value if (description != NULL) @@ -90,7 +88,7 @@ extern "C" int saveShortcut( shellLink->SetWorkingDirectory(workingDir); //Save the shortcut to disk - h = persistFile->Save(wName, TRUE); + h = persistFile->Save(shortcutPath, TRUE); if (FAILED(h)) { errStr = "Failed to save shortcut"; @@ -118,8 +116,8 @@ extern "C" int spawnDetached(const wchar_t *app, const wchar_t *cmdline) PROCESS_INFORMATION pi; // make non-constant copy of the parameters // this is allowed per https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw#security-remarks - wchar_t *app_copy = wcsdup(app); - wchar_t *cmdline_copy = wcsdup(cmdline); + wchar_t *app_copy = _wcsdup(app); + wchar_t *cmdline_copy = _wcsdup(cmdline); if (app_copy == NULL || cmdline_copy == NULL) { diff --git a/src/native/mod.rs b/src/native/mod.rs index 0e0cd41..b138870 100644 --- a/src/native/mod.rs +++ b/src/native/mod.rs @@ -15,8 +15,6 @@ mod natives { const PROCESS_LEN: usize = 10192; - use std::ffi::CString; - use logging::LoggingErrors; use std::env; @@ -36,11 +34,11 @@ mod natives { extern "C" { pub fn saveShortcut( - shortcutPath: *const ::std::os::raw::c_char, - description: *const ::std::os::raw::c_char, - path: *const ::std::os::raw::c_char, - args: *const ::std::os::raw::c_char, - workingDir: *const ::std::os::raw::c_char, + shortcutPath: *const winapi::ctypes::wchar_t, + description: *const winapi::ctypes::wchar_t, + path: *const winapi::ctypes::wchar_t, + args: *const winapi::ctypes::wchar_t, + workingDir: *const winapi::ctypes::wchar_t, ) -> ::std::os::raw::c_int; pub fn isDarkThemeActive() -> ::std::os::raw::c_uint; @@ -70,15 +68,16 @@ mod natives { info!("Generating shortcut @ {:?}", source_file); - let native_target_dir = CString::new(source_file.clone()) - .log_expect("Error while converting to C-style string"); + let native_target_dir = U16CString::from_str(source_file.clone()) + .log_expect("Error while converting to wchar_t"); let native_description = - CString::new(description).log_expect("Error while converting to C-style string"); + U16CString::from_str(description).log_expect("Error while converting to wchar_t"); let native_target = - CString::new(target).log_expect("Error while converting to C-style string"); - let native_args = CString::new(args).log_expect("Error while converting to C-style string"); + U16CString::from_str(target).log_expect("Error while converting to wchar_t"); + let native_args = + U16CString::from_str(args).log_expect("Error while converting to wchar_t"); let native_working_dir = - CString::new(working_dir).log_expect("Error while converting to C-style string"); + U16CString::from_str(working_dir).log_expect("Error while converting to wchar_t"); let shortcutResult = unsafe { saveShortcut(