]>
Commit | Line | Data |
---|---|---|
1b1a35ee XL |
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. | |
7 | ||
8 | #![allow(bad_style)] | |
9 | #![allow(unused)] | |
10 | ||
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; | |
22 | ||
23 | use crate::com::{BStr, ComPtr}; | |
24 | ||
25 | // Bindings to the Setup.Configuration stuff | |
26 | pub type InstanceState = u32; | |
27 | ||
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; | |
33 | ||
34 | RIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)] | |
35 | interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) { | |
36 | fn GetInstanceId( | |
37 | pbstrInstanceId: *mut BSTR, | |
38 | ) -> HRESULT, | |
39 | fn GetInstallDate( | |
40 | pInstallDate: LPFILETIME, | |
41 | ) -> HRESULT, | |
42 | fn GetInstallationName( | |
43 | pbstrInstallationName: *mut BSTR, | |
44 | ) -> HRESULT, | |
45 | fn GetInstallationPath( | |
46 | pbstrInstallationPath: *mut BSTR, | |
47 | ) -> HRESULT, | |
48 | fn GetInstallationVersion( | |
49 | pbstrInstallationVersion: *mut BSTR, | |
50 | ) -> HRESULT, | |
51 | fn GetDisplayName( | |
52 | lcid: LCID, | |
53 | pbstrDisplayName: *mut BSTR, | |
54 | ) -> HRESULT, | |
55 | fn GetDescription( | |
56 | lcid: LCID, | |
57 | pbstrDescription: *mut BSTR, | |
58 | ) -> HRESULT, | |
59 | fn ResolvePath( | |
60 | pwszRelativePath: LPCOLESTR, | |
61 | pbstrAbsolutePath: *mut BSTR, | |
62 | ) -> HRESULT, | |
63 | }} | |
64 | ||
65 | RIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)] | |
66 | interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) { | |
67 | fn GetState( | |
68 | pState: *mut InstanceState, | |
69 | ) -> HRESULT, | |
70 | fn GetPackages( | |
71 | ppsaPackages: *mut LPSAFEARRAY, | |
72 | ) -> HRESULT, | |
73 | fn GetProduct( | |
74 | ppPackage: *mut *mut ISetupPackageReference, | |
75 | ) -> HRESULT, | |
76 | fn GetProductPath( | |
77 | pbstrProductPath: *mut BSTR, | |
78 | ) -> HRESULT, | |
79 | }} | |
80 | ||
81 | RIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)] | |
82 | interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) { | |
83 | fn Next( | |
84 | celt: ULONG, | |
85 | rgelt: *mut *mut ISetupInstance, | |
86 | pceltFetched: *mut ULONG, | |
87 | ) -> HRESULT, | |
88 | fn Skip( | |
89 | celt: ULONG, | |
90 | ) -> HRESULT, | |
91 | fn Reset() -> HRESULT, | |
92 | fn Clone( | |
93 | ppenum: *mut *mut IEnumSetupInstances, | |
94 | ) -> HRESULT, | |
95 | }} | |
96 | ||
97 | RIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)] | |
98 | interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) { | |
99 | fn EnumInstances( | |
100 | ppEnumInstances: *mut *mut IEnumSetupInstances, | |
101 | ) -> HRESULT, | |
102 | fn GetInstanceForCurrentProcess( | |
103 | ppInstance: *mut *mut ISetupInstance, | |
104 | ) -> HRESULT, | |
105 | fn GetInstanceForPath( | |
106 | wzPath: LPCWSTR, | |
107 | ppInstance: *mut *mut ISetupInstance, | |
108 | ) -> HRESULT, | |
109 | }} | |
110 | ||
111 | RIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)] | |
112 | interface ISetupConfiguration2(ISetupConfiguration2Vtbl): | |
113 | ISetupConfiguration(ISetupConfigurationVtbl) { | |
114 | fn EnumAllInstances( | |
115 | ppEnumInstances: *mut *mut IEnumSetupInstances, | |
116 | ) -> HRESULT, | |
117 | }} | |
118 | ||
119 | RIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)] | |
120 | interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) { | |
121 | fn GetId( | |
122 | pbstrId: *mut BSTR, | |
123 | ) -> HRESULT, | |
124 | fn GetVersion( | |
125 | pbstrVersion: *mut BSTR, | |
126 | ) -> HRESULT, | |
127 | fn GetChip( | |
128 | pbstrChip: *mut BSTR, | |
129 | ) -> HRESULT, | |
130 | fn GetLanguage( | |
131 | pbstrLanguage: *mut BSTR, | |
132 | ) -> HRESULT, | |
133 | fn GetBranch( | |
134 | pbstrBranch: *mut BSTR, | |
135 | ) -> HRESULT, | |
136 | fn GetType( | |
137 | pbstrType: *mut BSTR, | |
138 | ) -> HRESULT, | |
139 | fn GetUniqueId( | |
140 | pbstrUniqueId: *mut BSTR, | |
141 | ) -> HRESULT, | |
142 | }} | |
143 | ||
144 | RIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)] | |
145 | interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) { | |
146 | fn ParseVersion( | |
147 | pwszVersion: LPCOLESTR, | |
148 | pullVersion: PULONGLONG, | |
149 | ) -> HRESULT, | |
150 | fn ParseVersionRange( | |
151 | pwszVersionRange: LPCOLESTR, | |
152 | pullMinVersion: PULONGLONG, | |
153 | pullMaxVersion: PULONGLONG, | |
154 | ) -> HRESULT, | |
155 | }} | |
156 | ||
157 | DEFINE_GUID! {CLSID_SetupConfiguration, | |
158 | 0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d} | |
159 | ||
160 | // Safe wrapper around the COM interfaces | |
161 | pub struct SetupConfiguration(ComPtr<ISetupConfiguration>); | |
162 | ||
163 | impl SetupConfiguration { | |
164 | pub fn new() -> Result<SetupConfiguration, i32> { | |
165 | let mut obj = null_mut(); | |
166 | let err = unsafe { | |
167 | CoCreateInstance( | |
168 | &CLSID_SetupConfiguration, | |
169 | null_mut(), | |
170 | CLSCTX_ALL, | |
171 | &ISetupConfiguration::uuidof(), | |
172 | &mut obj, | |
173 | ) | |
174 | }; | |
175 | if err < 0 { | |
176 | return Err(err); | |
177 | } | |
178 | let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) }; | |
179 | Ok(SetupConfiguration(obj)) | |
180 | } | |
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) }; | |
184 | if err < 0 { | |
185 | return Err(err); | |
186 | } | |
187 | Ok(unsafe { SetupInstance::from_raw(obj) }) | |
188 | } | |
189 | pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> { | |
190 | let mut obj = null_mut(); | |
191 | let err = unsafe { self.0.EnumInstances(&mut obj) }; | |
192 | if err < 0 { | |
193 | return Err(err); | |
194 | } | |
195 | Ok(unsafe { EnumSetupInstances::from_raw(obj) }) | |
196 | } | |
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) }; | |
201 | if err < 0 { | |
202 | return Err(err); | |
203 | } | |
204 | Ok(unsafe { EnumSetupInstances::from_raw(obj) }) | |
205 | } | |
206 | } | |
207 | ||
208 | pub struct SetupInstance(ComPtr<ISetupInstance>); | |
209 | ||
210 | impl SetupInstance { | |
211 | pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance { | |
212 | SetupInstance(ComPtr::from_raw(obj)) | |
213 | } | |
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) }; | |
218 | if err < 0 { | |
219 | return Err(err); | |
220 | } | |
221 | Ok(bstr.to_osstring()) | |
222 | } | |
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) }; | |
227 | if err < 0 { | |
228 | return Err(err); | |
229 | } | |
230 | Ok(bstr.to_osstring()) | |
231 | } | |
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) }; | |
236 | if err < 0 { | |
237 | return Err(err); | |
238 | } | |
239 | Ok(bstr.to_osstring()) | |
240 | } | |
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) }; | |
245 | if err < 0 { | |
246 | return Err(err); | |
247 | } | |
248 | Ok(bstr.to_osstring()) | |
249 | } | |
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) }; | |
255 | if err < 0 { | |
256 | return Err(err); | |
257 | } | |
258 | Ok(bstr.to_osstring()) | |
259 | } | |
260 | } | |
261 | ||
262 | pub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>); | |
263 | ||
264 | impl EnumSetupInstances { | |
265 | pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances { | |
266 | EnumSetupInstances(ComPtr::from_raw(obj)) | |
267 | } | |
268 | } | |
269 | ||
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()) }; | |
275 | if err < 0 { | |
276 | return Some(Err(err)); | |
277 | } | |
278 | if err == S_FALSE { | |
279 | return None; | |
280 | } | |
281 | Some(Ok(unsafe { SetupInstance::from_raw(obj) })) | |
282 | } | |
283 | } |