author | Kirk Steuber <ksteuber@mozilla.com> |
Tue, 28 Apr 2020 20:50:51 +0000 | |
changeset 526558 | 8fde1306bba7cf2020fb6b05abc7bee19d0047b8 |
parent 526557 | e78e8f677ca081e8227d304cb994c3d1b5860932 |
child 526559 | 772c8a4a58ae59473746d89ce13846b248d11c16 |
push id | 37358 |
push user | opoprus@mozilla.com |
push date | Wed, 29 Apr 2020 03:05:14 +0000 |
treeherder | mozilla-central@6bb8423186c1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | agashlin |
bugs | 1627805 |
milestone | 77.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
toolkit/components/updateagent/src/update_paths.rs | file | annotate | diff | comparison | revisions | |
toolkit/mozapps/update/common/commonupdatedir.cpp | file | annotate | diff | comparison | revisions |
--- a/toolkit/components/updateagent/src/update_paths.rs +++ b/toolkit/components/updateagent/src/update_paths.rs @@ -1,24 +1,61 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use std::{ffi::OsString, path::PathBuf}; +use std::{env::current_exe, ffi::OsString, path::PathBuf}; +use winapi::shared::{ + minwindef::MAX_PATH, + winerror::{FAILED, HRESULT}, +}; +use wio::wide::{FromWide, ToWide}; pub fn get_download_xml() -> Result<OsString, String> { let mut update_dir = PathBuf::from(get_update_directory()?); update_dir.push("download.xml"); Ok(update_dir.into_os_string()) } pub fn get_install_hash() -> Result<OsString, String> { let update_dir = PathBuf::from(get_update_directory()?); update_dir .file_name() .map(|file_name| OsString::from(file_name)) .ok_or("Couldn't get update directory name".to_string()) } +#[link(name = "updatecommon", kind = "static")] +extern "C" { + fn get_common_update_directory(install_path: *const u16, result: *mut u16) -> HRESULT; +} pub fn get_update_directory() -> Result<OsString, String> { - // TODO: Get the real update directory - Ok(OsString::from("C:\\test\\")) + let mut binary_path = current_exe() + .map_err(|e| format!("Couldn't get executing binary's path: {}", e))? + .parent() + .ok_or("Couldn't get executing binary's parent directory")? + .as_os_str() + .to_wide_null(); + // It looks like Path.as_os_str returns a path without a trailing slash, so this may be + // unnecessary. But the documentation does not appear to guarantee the lack of trailing slash. + // get_common_update_directory, however, must be given the installation path without a trailing + // slash. So remove any trailing path slashes, just to be safe. + strip_trailing_path_separators(&mut binary_path); + + let mut buffer: Vec<u16> = Vec::with_capacity(MAX_PATH + 1); + let hr = unsafe { get_common_update_directory(binary_path.as_ptr(), buffer.as_mut_ptr()) }; + if FAILED(hr) { + return Err(format!("Failed to get update directory: HRESULT={}", hr)); + } + Ok(unsafe { OsString::from_wide_ptr_null(buffer.as_ptr()) }) } + +fn strip_trailing_path_separators(path: &mut Vec<u16>) { + let forward_slash = '/' as u16; + let backslash = '\\' as u16; + for character in path.iter_mut().rev() { + if *character == forward_slash || *character == backslash { + *character = 0; + } else if *character != 0 { + break; + } + } +}
--- a/toolkit/mozapps/update/common/commonupdatedir.cpp +++ b/toolkit/mozapps/update/common/commonupdatedir.cpp @@ -893,16 +893,33 @@ GetUserUpdateDirectory(const wchar_t* in mozilla::UniquePtr<wchar_t[]>& result) { return GetUpdateDirectory( installPath, vendor, appName, WhichUpdateDir::UserAppData, SetPermissionsOf::BaseDirIfNotExists, // Arbitrary value result); } /** + * This is a much more limited version of the GetCommonUpdateDirectory that can + * be called from Rust. + * The result parameter must be a valid pointer to a buffer of length + * MAX_PATH + 1 + */ +extern "C" HRESULT get_common_update_directory(const wchar_t* installPath, + wchar_t* result) { + mozilla::UniquePtr<wchar_t[]> uniqueResult; + HRESULT hr = GetCommonUpdateDirectory( + installPath, SetPermissionsOf::BaseDirIfNotExists, uniqueResult); + if (FAILED(hr)) { + return hr; + } + return StringCchCopyW(result, MAX_PATH + 1, uniqueResult.get()); +} + +/** * This is a helper function that does all of the work for * GetCommonUpdateDirectory and GetUserUpdateDirectory. It partially exists to * prevent callers of GetUserUpdateDirectory from having to pass a useless * SetPermissionsOf argument, which will be ignored if whichDir is UserAppData. * * For information on the parameters and return value, see * GetCommonUpdateDirectory. */