1 // Copyright © 2017 winapi-rs developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
4 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
5 // All files in the project carrying such notice may not be copied, modified, or distributed
6 // except according to those terms.
11 use crate::winapi
::Interface
;
12 use crate::winapi
::BSTR
;
13 use crate::winapi
::LPCOLESTR
;
14 use crate::winapi
::LPSAFEARRAY
;
15 use crate::winapi
::S_FALSE
;
16 use crate::winapi
::{CoCreateInstance, CLSCTX_ALL}
;
17 use crate::winapi
::{IUnknown, IUnknownVtbl}
;
18 use crate::winapi
::{HRESULT, LCID, LPCWSTR, PULONGLONG}
;
19 use crate::winapi
::{LPFILETIME, ULONG}
;
20 use std
::ffi
::OsString
;
21 use std
::ptr
::null_mut
;
23 use crate::com
::{BStr, ComPtr}
;
25 // Bindings to the Setup.Configuration stuff
26 pub type InstanceState
= u32;
28 pub const eNone
: InstanceState
= 0;
29 pub const eLocal
: InstanceState
= 1;
30 pub const eRegistered
: InstanceState
= 2;
31 pub const eNoRebootRequired
: InstanceState
= 4;
32 pub const eComplete
: InstanceState
= -1i32 as u32;
34 RIDL
! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)]
35 interface
ISetupInstance(ISetupInstanceVtbl
): IUnknown(IUnknownVtbl
) {
37 pbstrInstanceId
: *mut BSTR
,
40 pInstallDate
: LPFILETIME
,
42 fn GetInstallationName(
43 pbstrInstallationName
: *mut BSTR
,
45 fn GetInstallationPath(
46 pbstrInstallationPath
: *mut BSTR
,
48 fn GetInstallationVersion(
49 pbstrInstallationVersion
: *mut BSTR
,
53 pbstrDisplayName
: *mut BSTR
,
57 pbstrDescription
: *mut BSTR
,
60 pwszRelativePath
: LPCOLESTR
,
61 pbstrAbsolutePath
: *mut BSTR
,
65 RIDL
! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)]
66 interface
ISetupInstance2(ISetupInstance2Vtbl
): ISetupInstance(ISetupInstanceVtbl
) {
68 pState
: *mut InstanceState
,
71 ppsaPackages
: *mut LPSAFEARRAY
,
74 ppPackage
: *mut *mut ISetupPackageReference
,
77 pbstrProductPath
: *mut BSTR
,
81 RIDL
! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)]
82 interface
IEnumSetupInstances(IEnumSetupInstancesVtbl
): IUnknown(IUnknownVtbl
) {
85 rgelt
: *mut *mut ISetupInstance
,
86 pceltFetched
: *mut ULONG
,
91 fn Reset() -> HRESULT
,
93 ppenum
: *mut *mut IEnumSetupInstances
,
97 RIDL
! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)]
98 interface
ISetupConfiguration(ISetupConfigurationVtbl
): IUnknown(IUnknownVtbl
) {
100 ppEnumInstances
: *mut *mut IEnumSetupInstances
,
102 fn GetInstanceForCurrentProcess(
103 ppInstance
: *mut *mut ISetupInstance
,
105 fn GetInstanceForPath(
107 ppInstance
: *mut *mut ISetupInstance
,
111 RIDL
! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)]
112 interface
ISetupConfiguration2(ISetupConfiguration2Vtbl
):
113 ISetupConfiguration(ISetupConfigurationVtbl
) {
115 ppEnumInstances
: *mut *mut IEnumSetupInstances
,
119 RIDL
! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)]
120 interface
ISetupPackageReference(ISetupPackageReferenceVtbl
): IUnknown(IUnknownVtbl
) {
125 pbstrVersion
: *mut BSTR
,
128 pbstrChip
: *mut BSTR
,
131 pbstrLanguage
: *mut BSTR
,
134 pbstrBranch
: *mut BSTR
,
137 pbstrType
: *mut BSTR
,
140 pbstrUniqueId
: *mut BSTR
,
144 RIDL
! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)]
145 interface
ISetupHelper(ISetupHelperVtbl
): IUnknown(IUnknownVtbl
) {
147 pwszVersion
: LPCOLESTR
,
148 pullVersion
: PULONGLONG
,
150 fn ParseVersionRange(
151 pwszVersionRange
: LPCOLESTR
,
152 pullMinVersion
: PULONGLONG
,
153 pullMaxVersion
: PULONGLONG
,
157 DEFINE_GUID
! {CLSID_SetupConfiguration
,
158 0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}
160 // Safe wrapper around the COM interfaces
161 pub struct SetupConfiguration(ComPtr
<ISetupConfiguration
>);
163 impl SetupConfiguration
{
164 pub fn new() -> Result
<SetupConfiguration
, i32> {
165 let mut obj
= null_mut();
168 &CLSID_SetupConfiguration
,
171 &ISetupConfiguration
::uuidof(),
178 let obj
= unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) }
;
179 Ok(SetupConfiguration(obj
))
181 pub fn get_instance_for_current_process(&self) -> Result
<SetupInstance
, i32> {
182 let mut obj
= null_mut();
183 let err
= unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) }
;
187 Ok(unsafe { SetupInstance::from_raw(obj) }
)
189 pub fn enum_instances(&self) -> Result
<EnumSetupInstances
, i32> {
190 let mut obj
= null_mut();
191 let err
= unsafe { self.0.EnumInstances(&mut obj) }
;
195 Ok(unsafe { EnumSetupInstances::from_raw(obj) }
)
197 pub fn enum_all_instances(&self) -> Result
<EnumSetupInstances
, i32> {
198 let mut obj
= null_mut();
199 let this
= self.0.cast
::<ISetupConfiguration2
>()?
;
200 let err
= unsafe { this.EnumAllInstances(&mut obj) }
;
204 Ok(unsafe { EnumSetupInstances::from_raw(obj) }
)
208 pub struct SetupInstance(ComPtr
<ISetupInstance
>);
211 pub unsafe fn from_raw(obj
: *mut ISetupInstance
) -> SetupInstance
{
212 SetupInstance(ComPtr
::from_raw(obj
))
214 pub fn instance_id(&self) -> Result
<OsString
, i32> {
215 let mut s
= null_mut();
216 let err
= unsafe { self.0.GetInstanceId(&mut s) }
;
217 let bstr
= unsafe { BStr::from_raw(s) }
;
221 Ok(bstr
.to_osstring())
223 pub fn installation_name(&self) -> Result
<OsString
, i32> {
224 let mut s
= null_mut();
225 let err
= unsafe { self.0.GetInstallationName(&mut s) }
;
226 let bstr
= unsafe { BStr::from_raw(s) }
;
230 Ok(bstr
.to_osstring())
232 pub fn installation_path(&self) -> Result
<OsString
, i32> {
233 let mut s
= null_mut();
234 let err
= unsafe { self.0.GetInstallationPath(&mut s) }
;
235 let bstr
= unsafe { BStr::from_raw(s) }
;
239 Ok(bstr
.to_osstring())
241 pub fn installation_version(&self) -> Result
<OsString
, i32> {
242 let mut s
= null_mut();
243 let err
= unsafe { self.0.GetInstallationVersion(&mut s) }
;
244 let bstr
= unsafe { BStr::from_raw(s) }
;
248 Ok(bstr
.to_osstring())
250 pub fn product_path(&self) -> Result
<OsString
, i32> {
251 let mut s
= null_mut();
252 let this
= self.0.cast
::<ISetupInstance2
>()?
;
253 let err
= unsafe { this.GetProductPath(&mut s) }
;
254 let bstr
= unsafe { BStr::from_raw(s) }
;
258 Ok(bstr
.to_osstring())
262 pub struct EnumSetupInstances(ComPtr
<IEnumSetupInstances
>);
264 impl EnumSetupInstances
{
265 pub unsafe fn from_raw(obj
: *mut IEnumSetupInstances
) -> EnumSetupInstances
{
266 EnumSetupInstances(ComPtr
::from_raw(obj
))
270 impl Iterator
for EnumSetupInstances
{
271 type Item
= Result
<SetupInstance
, i32>;
272 fn next(&mut self) -> Option
<Result
<SetupInstance
, i32>> {
273 let mut obj
= null_mut();
274 let err
= unsafe { self.0.Next(1, &mut obj, null_mut()) }
;
276 return Some(Err(err
));
281 Some(Ok(unsafe { SetupInstance::from_raw(obj) }
))