summaryrefslogtreecommitdiffstats
path: root/vendor/opener/src/windows.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/opener/src/windows.rs')
-rw-r--r--vendor/opener/src/windows.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/vendor/opener/src/windows.rs b/vendor/opener/src/windows.rs
new file mode 100644
index 0000000..829bdb0
--- /dev/null
+++ b/vendor/opener/src/windows.rs
@@ -0,0 +1,41 @@
+use crate::OpenError;
+use std::ffi::OsStr;
+use std::os::windows::ffi::OsStrExt;
+use std::{io, ptr};
+use winapi::ctypes::c_int;
+use winapi::um::shellapi::ShellExecuteW;
+
+pub(crate) fn open(path: &OsStr) -> Result<(), OpenError> {
+ const SW_SHOW: c_int = 5;
+
+ let path = convert_path(path).map_err(OpenError::Io)?;
+ let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
+ let result = unsafe {
+ ShellExecuteW(
+ ptr::null_mut(),
+ operation.as_ptr(),
+ path.as_ptr(),
+ ptr::null(),
+ ptr::null(),
+ SW_SHOW,
+ )
+ };
+ if result as c_int > 32 {
+ Ok(())
+ } else {
+ Err(OpenError::Io(io::Error::last_os_error()))
+ }
+}
+
+fn convert_path(path: &OsStr) -> io::Result<Vec<u16>> {
+ let mut maybe_result: Vec<u16> = path.encode_wide().collect();
+ if maybe_result.iter().any(|&u| u == 0) {
+ return Err(io::Error::new(
+ io::ErrorKind::InvalidInput,
+ "path contains NUL byte(s)",
+ ));
+ }
+
+ maybe_result.push(0);
+ Ok(maybe_result)
+}