Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup mod com, registry, setup_config and winapi #828

Merged
merged 1 commit into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
40 changes: 21 additions & 19 deletions src/com.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(*mut T)
Expand Down Expand Up @@ -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 {
Expand Down
94 changes: 28 additions & 66 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -97,7 +59,7 @@ impl RegistryKey {
/// Open a sub-key of `self`.
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
let mut ret = 0 as *mut _;
let mut ret = 0;
let err = unsafe {
RegOpenKeyExW(
self.raw(),
Expand All @@ -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))
Expand All @@ -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 {
Expand All @@ -156,16 +118,16 @@ 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,
);
// We don't check for `ERROR_MORE_DATA` (which would if the value
// 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
Expand Down Expand Up @@ -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);
Expand Down
40 changes: 23 additions & 17 deletions src/setup_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -212,7 +218,7 @@ impl SetupInstance {
SetupInstance(ComPtr::from_raw(obj))
}
pub fn instance_id(&self) -> Result<OsString, i32> {
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 {
Expand All @@ -221,7 +227,7 @@ impl SetupInstance {
Ok(bstr.to_osstring())
}
pub fn installation_name(&self) -> Result<OsString, i32> {
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 {
Expand All @@ -230,7 +236,7 @@ impl SetupInstance {
Ok(bstr.to_osstring())
}
pub fn installation_path(&self) -> Result<OsString, i32> {
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 {
Expand All @@ -239,7 +245,7 @@ impl SetupInstance {
Ok(bstr.to_osstring())
}
pub fn installation_version(&self) -> Result<OsString, i32> {
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 {
Expand All @@ -248,7 +254,7 @@ impl SetupInstance {
Ok(bstr.to_osstring())
}
pub fn product_path(&self) -> Result<OsString, i32> {
let mut s = null_mut();
let mut s = null();
let this = self.0.cast::<ISetupInstance2>()?;
let err = unsafe { this.GetProductPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
Expand Down
Loading