diff --git a/Cargo.toml b/Cargo.toml index 4158cd277..bde2eb225 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ jobserver = { version = "0.1.16", optional = true } libc = "0.2.62" [target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.48.0", features = ["Win32_Foundation", "Win32_System_Pipes", "Win32_Security"] } +windows-sys = { version = "0.48.0", features = ["Win32_Foundation", "Win32_System_Pipes", "Win32_Security", "Win32_System_Com", "Win32_System_Registry"] } [features] parallel = ["jobserver"] diff --git a/src/com.rs b/src/com.rs index 843247e58..623141274 100644 --- a/src/com.rs +++ b/src/com.rs @@ -7,27 +7,31 @@ #![allow(unused)] -use crate::winapi::CoInitializeEx; -use crate::winapi::IUnknown; -use crate::winapi::Interface; -use crate::winapi::BSTR; -use crate::winapi::COINIT_MULTITHREADED; -use crate::winapi::{SysFreeString, SysStringLen}; -use crate::winapi::{HRESULT, S_FALSE, S_OK}; -use std::ffi::{OsStr, OsString}; -use std::mem::forget; -use std::ops::Deref; -use std::os::windows::ffi::{OsStrExt, OsStringExt}; -use std::ptr::null_mut; -use std::slice::from_raw_parts; +use crate::winapi::{IUnknown, Interface}; +use std::{ + ffi::{OsStr, OsString}, + mem::ManuallyDrop, + ops::Deref, + os::windows::ffi::{OsStrExt, OsStringExt}, + ptr::{null, null_mut}, + slice::from_raw_parts, +}; +use windows_sys::{ + core::{BSTR, HRESULT}, + Win32::{ + Foundation::{SysFreeString, SysStringLen, S_FALSE, S_OK}, + System::Com::{CoInitializeEx, COINIT_MULTITHREADED}, + }, +}; pub fn initialize() -> Result<(), HRESULT> { - let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) }; + let err = unsafe { CoInitializeEx(null(), COINIT_MULTITHREADED) }; if err != S_OK && err != S_FALSE { // S_FALSE just means COM is already initialized - return Err(err); + Err(err) + } else { + Ok(()) } - Ok(()) } pub struct ComPtr(*mut T) @@ -55,9 +59,7 @@ where /// Extracts the raw pointer. /// You are now responsible for releasing it yourself. pub fn into_raw(self) -> *mut T { - let p = self.0; - forget(self); - p + ManuallyDrop::new(self).0 } /// For internal use only. fn as_unknown(&self) -> &IUnknown { diff --git a/src/registry.rs b/src/registry.rs index cae32219c..bd5fbb2fa 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -8,63 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::ffi::{OsStr, OsString}; -use std::io; -use std::ops::RangeFrom; -use std::os::raw; -use std::os::windows::prelude::*; +use std::{ + ffi::{OsStr, OsString}, + io, + ops::RangeFrom, + os::windows::prelude::*, + ptr::null_mut, +}; +use windows_sys::Win32::{ + Foundation::{ERROR_NO_MORE_ITEMS, ERROR_SUCCESS}, + System::Registry::{ + RegCloseKey, RegEnumKeyExW, RegOpenKeyExW, RegQueryValueExW, HKEY, HKEY_LOCAL_MACHINE, + KEY_READ, KEY_WOW64_32KEY, REG_SZ, + }, +}; /// Must never be `HKEY_PERFORMANCE_DATA`. pub(crate) struct RegistryKey(Repr); -type HKEY = *mut u8; type DWORD = u32; -type LPDWORD = *mut DWORD; -type LPCWSTR = *const u16; -type LPWSTR = *mut u16; -type LONG = raw::c_long; -type PHKEY = *mut HKEY; -type PFILETIME = *mut u8; -type LPBYTE = *mut u8; -type REGSAM = u32; - -const ERROR_SUCCESS: DWORD = 0; -const ERROR_NO_MORE_ITEMS: DWORD = 259; -// Sign-extend into 64 bits if needed. -const HKEY_LOCAL_MACHINE: HKEY = 0x80000002u32 as i32 as isize as HKEY; -const REG_SZ: DWORD = 1; -const KEY_READ: DWORD = 0x20019; -const KEY_WOW64_32KEY: DWORD = 0x200; - -#[link(name = "advapi32")] -extern "system" { - fn RegOpenKeyExW( - key: HKEY, - lpSubKey: LPCWSTR, - ulOptions: DWORD, - samDesired: REGSAM, - phkResult: PHKEY, - ) -> LONG; - fn RegEnumKeyExW( - key: HKEY, - dwIndex: DWORD, - lpName: LPWSTR, - lpcName: LPDWORD, - lpReserved: LPDWORD, - lpClass: LPWSTR, - lpcClass: LPDWORD, - lpftLastWriteTime: PFILETIME, - ) -> LONG; - fn RegQueryValueExW( - hKey: HKEY, - lpValueName: LPCWSTR, - lpReserved: LPDWORD, - lpType: LPDWORD, - lpData: LPBYTE, - lpcbData: LPDWORD, - ) -> LONG; - fn RegCloseKey(hKey: HKEY) -> LONG; -} struct OwnedKey(HKEY); @@ -97,7 +59,7 @@ impl RegistryKey { /// Open a sub-key of `self`. pub fn open(&self, key: &OsStr) -> io::Result { let key = key.encode_wide().chain(Some(0)).collect::>(); - let mut ret = 0 as *mut _; + let mut ret = 0; let err = unsafe { RegOpenKeyExW( self.raw(), @@ -107,7 +69,7 @@ impl RegistryKey { &mut ret, ) }; - if err == ERROR_SUCCESS as LONG { + if err == ERROR_SUCCESS { Ok(RegistryKey(Repr::Owned(OwnedKey(ret)))) } else { Err(io::Error::from_raw_os_error(err as i32)) @@ -130,12 +92,12 @@ impl RegistryKey { let err = RegQueryValueExW( self.raw(), name.as_ptr(), - 0 as *mut _, + null_mut(), &mut kind, - 0 as *mut _, + null_mut(), &mut len, ); - if err != ERROR_SUCCESS as LONG { + if err != ERROR_SUCCESS { return Err(io::Error::from_raw_os_error(err as i32)); } if kind != REG_SZ { @@ -156,8 +118,8 @@ impl RegistryKey { let err = RegQueryValueExW( self.raw(), name.as_ptr(), - 0 as *mut _, - 0 as *mut _, + null_mut(), + null_mut(), v.as_mut_ptr() as *mut _, &mut len, ); @@ -165,7 +127,7 @@ impl RegistryKey { // grew between the first and second call to `RegQueryValueExW`), // both because it's extremely unlikely, and this is a bit more // defensive more defensive against weird types of registry keys. - if err != ERROR_SUCCESS as LONG { + if err != ERROR_SUCCESS { return Err(io::Error::from_raw_os_error(err as i32)); } // The length is allowed to change, but should still be even, as @@ -213,14 +175,14 @@ impl<'a> Iterator for Iter<'a> { i, v.as_mut_ptr(), &mut len, - 0 as *mut _, - 0 as *mut _, - 0 as *mut _, - 0 as *mut _, + null_mut(), + null_mut(), + null_mut(), + null_mut(), ); - if ret == ERROR_NO_MORE_ITEMS as LONG { + if ret == ERROR_NO_MORE_ITEMS { None - } else if ret != ERROR_SUCCESS as LONG { + } else if ret != ERROR_SUCCESS { Some(Err(io::Error::from_raw_os_error(ret as i32))) } else { v.set_len(len as usize); diff --git a/src/setup_config.rs b/src/setup_config.rs index 030051ca6..a738b9659 100644 --- a/src/setup_config.rs +++ b/src/setup_config.rs @@ -8,19 +8,25 @@ #![allow(bad_style)] #![allow(unused)] -use crate::winapi::Interface; -use crate::winapi::BSTR; -use crate::winapi::LPCOLESTR; -use crate::winapi::LPSAFEARRAY; -use crate::winapi::S_FALSE; -use crate::winapi::{CoCreateInstance, CLSCTX_ALL}; -use crate::winapi::{IUnknown, IUnknownVtbl}; -use crate::winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG}; -use crate::winapi::{LPFILETIME, ULONG}; -use std::ffi::OsString; -use std::ptr::null_mut; +use crate::{ + com::{BStr, ComPtr}, + winapi::{ + IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY, + PULONGLONG, ULONG, + }, +}; -use crate::com::{BStr, ComPtr}; +use std::{ + ffi::OsString, + ptr::{null, null_mut}, +}; +use windows_sys::{ + core::{BSTR, HRESULT}, + Win32::{ + Foundation::S_FALSE, + System::Com::{CoCreateInstance, CLSCTX_ALL}, + }, +}; // Bindings to the Setup.Configuration stuff pub type InstanceState = u32; @@ -212,7 +218,7 @@ impl SetupInstance { SetupInstance(ComPtr::from_raw(obj)) } pub fn instance_id(&self) -> Result { - let mut s = null_mut(); + let mut s = null(); let err = unsafe { self.0.GetInstanceId(&mut s) }; let bstr = unsafe { BStr::from_raw(s) }; if err < 0 { @@ -221,7 +227,7 @@ impl SetupInstance { Ok(bstr.to_osstring()) } pub fn installation_name(&self) -> Result { - let mut s = null_mut(); + let mut s = null(); let err = unsafe { self.0.GetInstallationName(&mut s) }; let bstr = unsafe { BStr::from_raw(s) }; if err < 0 { @@ -230,7 +236,7 @@ impl SetupInstance { Ok(bstr.to_osstring()) } pub fn installation_path(&self) -> Result { - let mut s = null_mut(); + let mut s = null(); let err = unsafe { self.0.GetInstallationPath(&mut s) }; let bstr = unsafe { BStr::from_raw(s) }; if err < 0 { @@ -239,7 +245,7 @@ impl SetupInstance { Ok(bstr.to_osstring()) } pub fn installation_version(&self) -> Result { - let mut s = null_mut(); + let mut s = null(); let err = unsafe { self.0.GetInstallationVersion(&mut s) }; let bstr = unsafe { BStr::from_raw(s) }; if err < 0 { @@ -248,7 +254,7 @@ impl SetupInstance { Ok(bstr.to_osstring()) } pub fn product_path(&self) -> Result { - let mut s = null_mut(); + let mut s = null(); let this = self.0.cast::()?; let err = unsafe { this.GetProductPath(&mut s) }; let bstr = unsafe { BStr::from_raw(s) }; diff --git a/src/winapi.rs b/src/winapi.rs index 8e04ce9cb..93bea3cc4 100644 --- a/src/winapi.rs +++ b/src/winapi.rs @@ -11,20 +11,20 @@ use std::os::raw; pub type wchar_t = u16; -pub type UINT = raw::c_uint; -pub type LPUNKNOWN = *mut IUnknown; +pub use windows_sys::{ + core::GUID, + Win32::{ + Foundation::FILETIME, + System::Com::{SAFEARRAY, SAFEARRAYBOUND}, + }, +}; + pub type REFIID = *const IID; pub type IID = GUID; -pub type REFCLSID = *const IID; -pub type PVOID = *mut raw::c_void; -pub type USHORT = raw::c_ushort; pub type ULONG = raw::c_ulong; -pub type LONG = raw::c_long; pub type DWORD = u32; -pub type LPVOID = *mut raw::c_void; pub type HRESULT = raw::c_long; pub type LPFILETIME = *mut FILETIME; -pub type BSTR = *mut OLECHAR; pub type OLECHAR = WCHAR; pub type WCHAR = wchar_t; pub type LPCOLESTR = *const OLECHAR; @@ -33,75 +33,10 @@ pub type LPCWSTR = *const WCHAR; pub type PULONGLONG = *mut ULONGLONG; pub type ULONGLONG = u64; -pub const S_OK: HRESULT = 0; -pub const S_FALSE: HRESULT = 1; -pub const COINIT_MULTITHREADED: u32 = 0x0; - -pub type CLSCTX = u32; - -pub const CLSCTX_INPROC_SERVER: CLSCTX = 0x1; -pub const CLSCTX_INPROC_HANDLER: CLSCTX = 0x2; -pub const CLSCTX_LOCAL_SERVER: CLSCTX = 0x4; -pub const CLSCTX_REMOTE_SERVER: CLSCTX = 0x10; - -pub const CLSCTX_ALL: CLSCTX = - CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct GUID { - pub Data1: raw::c_ulong, - pub Data2: raw::c_ushort, - pub Data3: raw::c_ushort, - pub Data4: [raw::c_uchar; 8], -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct FILETIME { - pub dwLowDateTime: DWORD, - pub dwHighDateTime: DWORD, -} - pub trait Interface { fn uuidof() -> GUID; } -#[link(name = "ole32")] -#[link(name = "oleaut32")] -extern "C" {} - -extern "system" { - pub fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT; - pub fn CoCreateInstance( - rclsid: REFCLSID, - pUnkOuter: LPUNKNOWN, - dwClsContext: DWORD, - riid: REFIID, - ppv: *mut LPVOID, - ) -> HRESULT; - pub fn SysFreeString(bstrString: BSTR); - pub fn SysStringLen(pbstr: BSTR) -> UINT; -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SAFEARRAYBOUND { - pub cElements: ULONG, - pub lLbound: LONG, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SAFEARRAY { - pub cDims: USHORT, - pub fFeatures: USHORT, - pub cbElements: ULONG, - pub cLocks: ULONG, - pub pvData: PVOID, - pub rgsabound: [SAFEARRAYBOUND; 1], -} - pub type LPSAFEARRAY = *mut SAFEARRAY; macro_rules! DEFINE_GUID { @@ -110,10 +45,10 @@ macro_rules! DEFINE_GUID { $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr ) => { pub const $name: $crate::winapi::GUID = $crate::winapi::GUID { - Data1: $l, - Data2: $w1, - Data3: $w2, - Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], + data1: $l, + data2: $w1, + data3: $w2, + data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], }; }; } @@ -197,10 +132,10 @@ macro_rules! RIDL { #[inline] fn uuidof() -> $crate::winapi::GUID { $crate::winapi::GUID { - Data1: $l, - Data2: $w1, - Data3: $w2, - Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], + data1: $l, + data2: $w1, + data3: $w2, + data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], } } }