Skip to content

Commit

Permalink
Cleanup mod com, registry, setup_config and winapi (#828)
Browse files Browse the repository at this point in the history
  • Loading branch information
NobodyXu committed Jul 21, 2023
1 parent c83f5ee commit 2d9941b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 184 deletions.
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

0 comments on commit 2d9941b

Please sign in to comment.