// Copyright © 2017 winapi-rs developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0 > or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT >, at your option.
// All files in the project carrying such notice may not be copied, modified, or distributed
// except according to those terms.
#! [allow(bad_style)]
#! [allow(unused)]
use crate ::windows::{
com::{BStr, ComPtr},
winapi::{
IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY,
PULONGLONG, ULONG,
},
windows_sys::{CoCreateInstance, BSTR, CLSCTX_ALL, HRESULT, S_FALSE},
};
use std::{
ffi::OsString,
ptr::{null, null_mut},
};
// Bindings to the Setup.Configuration stuff
pub type InstanceState = u32;
pub const eNone: InstanceState =
0 ;
pub const eLocal: InstanceState =
1 ;
pub const eRegistered: InstanceState =
2 ;
pub const eNoRebootRequired: InstanceState =
4 ;
pub const eComplete: InstanceState = -
1 i32
as u32;
RIDL! {
#[ uuid(
0 xb41463c3,
0 x8866,
0 x43b5,
0 xbc,
0 x33,
0 x2b,
0 x06,
0 x76,
0 xf7,
0 xf4,
0 x2e)]
interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) {
fn GetInstanceId(
pbstrInstanceId: *
mut BSTR,
) -> HRESULT,
fn GetInstallDate(
pInstallDate: LPFILETIME,
) -> HRESULT,
fn GetInstallationName(
pbstrInstallationName: *
mut BSTR,
) -> HRESULT,
fn GetInstallationPath(
pbstrInstallationPath: *
mut BSTR,
) -> HRESULT,
fn GetInstallationVersion(
pbstrInstallationVersion: *
mut BSTR,
) -> HRESULT,
fn GetDisplayName(
lcid: LCID,
pbstrDisplayName: *
mut BSTR,
) -> HRESULT,
fn GetDescription(
lcid: LCID,
pbstrDescription: *
mut BSTR,
) -> HRESULT,
fn ResolvePath(
pwszRelativePath: LPCOLESTR,
pbstrAbsolutePath: *
mut BSTR,
) -> HRESULT,
}}
RIDL! {
#[ uuid(
0 x89143c9a,
0 x05af,
0 x49b0,
0 xb7,
0 x17,
0 x72,
0 xe2,
0 x18,
0 xa2,
0 x18,
0 x5c)]
interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl)
{
fn GetState(
pState: *mut InstanceState,
) -> HRESULT,
fn GetPackages(
ppsaPackages: *mut LPSAFEARRAY,
) -> HRESULT,
fn GetProduct(
ppPackage: *mut *mut ISetupPackageReference,
) -> HRESULT,
fn GetProductPath(
pbstrProductPath: *mut BSTR,
) -> HRESULT,
}}
RIDL! {#[ uuid(0 x6380bcff, 0 x41d3, 0 x4b2e, 0 x8b, 0 x2e, 0 xbf, 0 x8a, 0 x68, 0 x10, 0 xc8, 0 x48)]
interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) {
fn Next(
celt: ULONG,
rgelt: *mut *mut ISetupInstance,
pceltFetched: *mut ULONG,
) -> HRESULT,
fn Skip(
celt: ULONG,
) -> HRESULT,
fn Reset() -> HRESULT,
fn Clone(
ppenum: *mut *mut IEnumSetupInstances,
) -> HRESULT,
}}
RIDL! {#[ uuid(0 x42843719, 0 xdb4c, 0 x46c2, 0 x8e, 0 x7c, 0 x64, 0 xf1, 0 x81, 0 x6e, 0 xfd, 0 x5b)]
interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) {
fn EnumInstances(
ppEnumInstances: *mut *mut IEnumSetupInstances,
) -> HRESULT,
fn GetInstanceForCurrentProcess(
ppInstance: *mut *mut ISetupInstance,
) -> HRESULT,
fn GetInstanceForPath(
wzPath: LPCWSTR,
ppInstance: *mut *mut ISetupInstance,
) -> HRESULT,
}}
RIDL! {#[ uuid(0 x26aab78c, 0 x4a60, 0 x49d6, 0 xaf, 0 x3b, 0 x3c, 0 x35, 0 xbc, 0 x93, 0 x36, 0 x5d)]
interface ISetupConfiguration2(ISetupConfiguration2Vtbl):
ISetupConfiguration(ISetupConfigurationVtbl) {
fn EnumAllInstances(
ppEnumInstances: *mut *mut IEnumSetupInstances,
) -> HRESULT,
}}
RIDL! {#[ uuid(0 xda8d8a16, 0 xb2b6, 0 x4487, 0 xa2, 0 xf1, 0 x59, 0 x4c, 0 xcc, 0 xcd, 0 x6b, 0 xf5)]
interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) {
fn GetId(
pbstrId: *mut BSTR,
) -> HRESULT,
fn GetVersion(
pbstrVersion: *mut BSTR,
) -> HRESULT,
fn GetChip(
pbstrChip: *mut BSTR,
) -> HRESULT,
fn GetLanguage(
pbstrLanguage: *mut BSTR,
) -> HRESULT,
fn GetBranch(
pbstrBranch: *mut BSTR,
) -> HRESULT,
fn GetType(
pbstrType: *mut BSTR,
) -> HRESULT,
fn GetUniqueId(
pbstrUniqueId: *mut BSTR,
) -> HRESULT,
}}
RIDL! {#[ uuid(0 x42b21b78, 0 x6192, 0 x463e, 0 x87, 0 xbf, 0 xd5, 0 x77, 0 x83, 0 x8f, 0 x1d, 0 x5c)]
interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) {
fn ParseVersion(
pwszVersion: LPCOLESTR,
pullVersion: PULONGLONG,
) -> HRESULT,
fn ParseVersionRange(
pwszVersionRange: LPCOLESTR,
pullMinVersion: PULONGLONG,
pullMaxVersion: PULONGLONG,
) -> HRESULT,
}}
DEFINE_GUID! {CLSID_SetupConfiguration,
0 x177f0c4a, 0 x1cd3, 0 x4de7, 0 xa3, 0 x2c, 0 x71, 0 xdb, 0 xbb, 0 x9f, 0 xa3, 0 x6d}
// Safe wrapper around the COM interfaces
pub struct SetupConfiguration(ComPtr<ISetupConfiguration>);
impl SetupConfiguration {
pub fn new() -> Result<SetupConfiguration, i32> {
let mut obj = null_mut();
let err = unsafe {
CoCreateInstance(
&CLSID_SetupConfiguration,
null_mut(),
CLSCTX_ALL,
&ISetupConfiguration::uuidof(),
&mut obj,
)
};
if err < 0 {
return Err(err);
}
let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) };
Ok(SetupConfiguration(obj))
}
pub fn get_instance_for_current_process(&self ) -> Result<SetupInstance, i32> {
let mut obj = null_mut();
let err = unsafe { self .0 .GetInstanceForCurrentProcess(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { SetupInstance::from_raw(obj) })
}
pub fn enum_instances(&self ) -> Result<EnumSetupInstances, i32> {
let mut obj = null_mut();
let err = unsafe { self .0 .EnumInstances(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
}
pub fn enum_all_instances(&self ) -> Result<EnumSetupInstances, i32> {
let mut obj = null_mut();
let this = self .0 .cast::<ISetupConfiguration2>()?;
let err = unsafe { this.EnumAllInstances(&mut obj) };
if err < 0 {
return Err(err);
}
Ok(unsafe { EnumSetupInstances::from_raw(obj) })
}
}
pub struct SetupInstance(ComPtr<ISetupInstance>);
impl SetupInstance {
pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance {
SetupInstance(ComPtr::from_raw(obj))
}
pub fn instance_id(&self ) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self .0 .GetInstanceId(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_name(&self ) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self .0 .GetInstallationName(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_path(&self ) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self .0 .GetInstallationPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn installation_version(&self ) -> Result<OsString, i32> {
let mut s = null();
let err = unsafe { self .0 .GetInstallationVersion(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
pub fn product_path(&self ) -> Result<OsString, i32> {
let mut s = null();
let this = self .0 .cast::<ISetupInstance2>()?;
let err = unsafe { this.GetProductPath(&mut s) };
let bstr = unsafe { BStr::from_raw(s) };
if err < 0 {
return Err(err);
}
Ok(bstr.to_osstring())
}
}
pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>);
impl EnumSetupInstances {
pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances {
EnumSetupInstances(ComPtr::from_raw(obj))
}
}
impl Iterator for EnumSetupInstances {
type Item = Result<SetupInstance, i32>;
fn next(&mut self ) -> Option<Result<SetupInstance, i32>> {
let mut obj = null_mut();
let err = unsafe { self .0 .Next(1 , &mut obj, null_mut()) };
if err < 0 {
return Some(Err(err));
}
if err == S_FALSE {
return None;
}
Some(Ok(unsafe { SetupInstance::from_raw(obj) }))
}
}
Messung V0.5 in Prozent C=82 H=93 G=87
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-18)
¤
*© Formatika GbR, Deutschland