1use std::time::Duration;
7
8use crate::{
9 WString,
10 runtime::executor::BoxedCancelToken,
11 sync::{FabricReceiver, fabric_begin_end_proxy},
12 types::{NameEnumerationResult, PropertyMetadataResult, PropertyValueResult, Uri},
13};
14use mssf_com::{
15 FabricClient::{
16 IFabricNameEnumerationResult, IFabricPropertyBatchResult, IFabricPropertyEnumerationResult,
17 IFabricPropertyMetadataResult, IFabricPropertyValueResult,
18 },
19 FabricTypes::{FABRIC_PROPERTY_BATCH_OPERATION, FABRIC_PUT_CUSTOM_PROPERTY_OPERATION},
20};
21
22use mssf_com::FabricClient::IFabricPropertyManagementClient2;
23
24#[derive(Debug, Clone)]
25pub struct PropertyManagementClient {
26 com: IFabricPropertyManagementClient2,
27}
28
29impl From<IFabricPropertyManagementClient2> for PropertyManagementClient {
30 fn from(com: IFabricPropertyManagementClient2) -> Self {
31 Self { com }
32 }
33}
34
35impl From<PropertyManagementClient> for IFabricPropertyManagementClient2 {
36 fn from(value: PropertyManagementClient) -> Self {
37 value.com
38 }
39}
40
41impl PropertyManagementClient {
42 fn create_name_internal(
43 &self,
44 name: &Uri,
45 timeout_milliseconds: u32,
46 cancellation_token: Option<BoxedCancelToken>,
47 ) -> FabricReceiver<crate::WinResult<()>> {
48 let com1 = &self.com;
49 let com2 = self.com.clone();
50 fabric_begin_end_proxy(
51 move |callback| unsafe {
52 com1.BeginCreateName(name.as_raw(), timeout_milliseconds, callback)
53 },
54 move |ctx| unsafe { com2.EndCreateName(ctx) },
55 cancellation_token,
56 )
57 }
58
59 fn delete_name_internal(
60 &self,
61 name: &Uri,
62 timeout_milliseconds: u32,
63 cancellation_token: Option<BoxedCancelToken>,
64 ) -> FabricReceiver<crate::WinResult<()>> {
65 let com1 = &self.com;
66 let com2 = self.com.clone();
67 fabric_begin_end_proxy(
68 move |callback| unsafe {
69 com1.BeginDeleteName(name.as_raw(), timeout_milliseconds, callback)
70 },
71 move |ctx| unsafe { com2.EndDeleteName(ctx) },
72 cancellation_token,
73 )
74 }
75
76 fn name_exists_internal(
77 &self,
78 name: &Uri,
79 timeout_milliseconds: u32,
80 cancellation_token: Option<BoxedCancelToken>,
81 ) -> FabricReceiver<crate::WinResult<u8>> {
82 let com1 = &self.com;
83 let com2 = self.com.clone();
84 fabric_begin_end_proxy(
85 move |callback| unsafe {
86 com1.BeginNameExists(name.as_raw(), timeout_milliseconds, callback)
87 },
88 move |ctx| unsafe { com2.EndNameExists(ctx) },
89 cancellation_token,
90 )
91 }
92
93 fn enumerate_sub_names_internal(
94 &self,
95 name: &Uri,
96 prev: Option<&IFabricNameEnumerationResult>,
97 recursive: bool,
98 timeout_milliseconds: u32,
99 cancellation_token: Option<BoxedCancelToken>,
100 ) -> FabricReceiver<crate::WinResult<IFabricNameEnumerationResult>> {
101 let com1 = &self.com;
102 let com2 = self.com.clone();
103 fabric_begin_end_proxy(
104 move |callback| unsafe {
105 com1.BeginEnumerateSubNames(
106 name.as_raw(),
107 prev,
108 recursive,
109 timeout_milliseconds,
110 callback,
111 )
112 },
113 move |ctx| unsafe { com2.EndEnumerateSubNames(ctx) },
114 cancellation_token,
115 )
116 }
117
118 fn put_property_binary_internal(
119 &self,
120 name: &Uri,
121 property_name: &WString,
122 data: &[u8],
123 timeout_milliseconds: u32,
124 cancellation_token: Option<BoxedCancelToken>,
125 ) -> FabricReceiver<crate::WinResult<()>> {
126 let com1 = &self.com;
127 let com2 = self.com.clone();
128 fabric_begin_end_proxy(
129 move |callback| unsafe {
130 com1.BeginPutPropertyBinary(
131 name.as_raw(),
132 property_name.as_pcwstr(),
133 data,
134 timeout_milliseconds,
135 callback,
136 )
137 },
138 move |ctx| unsafe { com2.EndPutPropertyBinary(ctx) },
139 cancellation_token,
140 )
141 }
142
143 fn put_property_int64_internal(
144 &self,
145 name: &Uri,
146 property_name: &WString,
147 data: i64,
148 timeout_milliseconds: u32,
149 cancellation_token: Option<BoxedCancelToken>,
150 ) -> FabricReceiver<crate::WinResult<()>> {
151 let com1 = &self.com;
152 let com2 = self.com.clone();
153 fabric_begin_end_proxy(
154 move |callback| unsafe {
155 com1.BeginPutPropertyInt64(
156 name.as_raw(),
157 property_name.as_pcwstr(),
158 data,
159 timeout_milliseconds,
160 callback,
161 )
162 },
163 move |ctx| unsafe { com2.EndPutPropertyInt64(ctx) },
164 cancellation_token,
165 )
166 }
167
168 fn put_property_double_internal(
169 &self,
170 name: &Uri,
171 property_name: &WString,
172 data: f64,
173 timeout_milliseconds: u32,
174 cancellation_token: Option<BoxedCancelToken>,
175 ) -> FabricReceiver<crate::WinResult<()>> {
176 let com1 = &self.com;
177 let com2 = self.com.clone();
178 fabric_begin_end_proxy(
179 move |callback| unsafe {
180 com1.BeginPutPropertyDouble(
181 name.as_raw(),
182 property_name.as_pcwstr(),
183 data,
184 timeout_milliseconds,
185 callback,
186 )
187 },
188 move |ctx| unsafe { com2.EndPutPropertyDouble(ctx) },
189 cancellation_token,
190 )
191 }
192
193 fn put_property_wstring_internal(
194 &self,
195 name: &Uri,
196 property_name: &WString,
197 data: &WString,
198 timeout_milliseconds: u32,
199 cancellation_token: Option<BoxedCancelToken>,
200 ) -> FabricReceiver<crate::WinResult<()>> {
201 let com1 = &self.com;
202 let com2 = self.com.clone();
203 fabric_begin_end_proxy(
204 move |callback| unsafe {
205 com1.BeginPutPropertyWString(
206 name.as_raw(),
207 property_name.as_pcwstr(),
208 data.as_pcwstr(),
209 timeout_milliseconds,
210 callback,
211 )
212 },
213 move |ctx| unsafe { com2.EndPutPropertyWString(ctx) },
214 cancellation_token,
215 )
216 }
217
218 fn put_property_guid_internal(
219 &self,
220 name: &Uri,
221 property_name: &WString,
222 data: &windows_core::GUID,
223 timeout_milliseconds: u32,
224 cancellation_token: Option<BoxedCancelToken>,
225 ) -> FabricReceiver<crate::WinResult<()>> {
226 let com1 = &self.com;
227 let com2 = self.com.clone();
228 fabric_begin_end_proxy(
229 move |callback| unsafe {
230 com1.BeginPutPropertyGuid(
231 name.as_raw(),
232 property_name.as_pcwstr(),
233 data,
234 timeout_milliseconds,
235 callback,
236 )
237 },
238 move |ctx| unsafe { com2.EndPutPropertyGuid(ctx) },
239 cancellation_token,
240 )
241 }
242
243 fn delete_property_internal(
244 &self,
245 name: &Uri,
246 property_name: &WString,
247 timeout_milliseconds: u32,
248 cancellation_token: Option<BoxedCancelToken>,
249 ) -> FabricReceiver<crate::WinResult<()>> {
250 let com1 = &self.com;
251 let com2 = self.com.clone();
252 fabric_begin_end_proxy(
253 move |callback| unsafe {
254 com1.BeginDeleteProperty(
255 name.as_raw(),
256 property_name.as_pcwstr(),
257 timeout_milliseconds,
258 callback,
259 )
260 },
261 move |ctx| unsafe { com2.EndDeleteProperty(ctx) },
262 cancellation_token,
263 )
264 }
265
266 fn get_property_metadata_internal(
267 &self,
268 name: &Uri,
269 property_name: &WString,
270 timeout_milliseconds: u32,
271 cancellation_token: Option<BoxedCancelToken>,
272 ) -> FabricReceiver<crate::WinResult<IFabricPropertyMetadataResult>> {
273 let com1 = &self.com;
274 let com2 = self.com.clone();
275 fabric_begin_end_proxy(
276 move |callback| unsafe {
277 com1.BeginGetPropertyMetadata(
278 name.as_raw(),
279 property_name.as_pcwstr(),
280 timeout_milliseconds,
281 callback,
282 )
283 },
284 move |ctx| unsafe { com2.EndGetPropertyMetadata(ctx) },
285 cancellation_token,
286 )
287 }
288
289 fn get_property_internal(
290 &self,
291 name: &Uri,
292 property_name: &WString,
293 timeout_milliseconds: u32,
294 cancellation_token: Option<BoxedCancelToken>,
295 ) -> FabricReceiver<crate::WinResult<IFabricPropertyValueResult>> {
296 let com1 = &self.com;
297 let com2 = self.com.clone();
298 fabric_begin_end_proxy(
299 move |callback| unsafe {
300 com1.BeginGetProperty(
301 name.as_raw(),
302 property_name.as_pcwstr(),
303 timeout_milliseconds,
304 callback,
305 )
306 },
307 move |ctx| unsafe { com2.EndGetProperty(ctx) },
308 cancellation_token,
309 )
310 }
311
312 #[allow(dead_code)]
315 fn submit_property_batch_internal(
316 &self,
317 name: &Uri,
318 batch: &[FABRIC_PROPERTY_BATCH_OPERATION],
319 timeout_milliseconds: u32,
320 cancellation_token: Option<BoxedCancelToken>,
321 ) -> FabricReceiver<crate::WinResult<(u32, IFabricPropertyBatchResult)>> {
322 let com1 = &self.com;
323 let com2 = self.com.clone();
324 fabric_begin_end_proxy(
325 move |callback| unsafe {
326 com1.BeginSubmitPropertyBatch(name.as_raw(), batch, timeout_milliseconds, callback)
327 },
328 move |ctx| unsafe {
329 let mut failed_operation_index_in_request = 0;
330 let result =
331 com2.EndSubmitPropertyBatch(ctx, &mut failed_operation_index_in_request);
332 result.map(|res| (failed_operation_index_in_request, res))
333 },
334 cancellation_token,
335 )
336 }
337
338 #[allow(dead_code)]
340 fn enumerate_properties_internal(
341 &self,
342 name: &Uri,
343 include_values: bool,
344 prev: Option<&IFabricPropertyEnumerationResult>,
345 timeout_milliseconds: u32,
346 cancellation_token: Option<BoxedCancelToken>,
347 ) -> FabricReceiver<crate::WinResult<IFabricPropertyEnumerationResult>> {
348 let com1 = &self.com;
349 let com2 = self.com.clone();
350 fabric_begin_end_proxy(
351 move |callback| unsafe {
352 com1.BeginEnumerateProperties(
353 name.as_raw(),
354 include_values,
355 prev,
356 timeout_milliseconds,
357 callback,
358 )
359 },
360 move |ctx| unsafe { com2.EndEnumerateProperties(ctx) },
361 cancellation_token,
362 )
363 }
364
365 #[allow(dead_code)]
367 fn put_custom_property_operation_internal(
368 &self,
369 name: &Uri,
370 property_operation: &FABRIC_PUT_CUSTOM_PROPERTY_OPERATION,
371 timeout_milliseconds: u32,
372 cancellation_token: Option<BoxedCancelToken>,
373 ) -> FabricReceiver<crate::WinResult<()>> {
374 let com1 = &self.com;
375 let com2 = self.com.clone();
376 fabric_begin_end_proxy(
377 move |callback| unsafe {
378 com1.BeginPutCustomPropertyOperation(
379 name.as_raw(),
380 property_operation,
381 timeout_milliseconds,
382 callback,
383 )
384 },
385 move |ctx| unsafe { com2.EndPutCustomPropertyOperation(ctx) },
386 cancellation_token,
387 )
388 }
389}
390
391impl PropertyManagementClient {
392 pub async fn create_name(
400 &self,
401 name: &Uri,
402 timeout: Duration,
403 cancellation_token: Option<BoxedCancelToken>,
404 ) -> crate::Result<()> {
405 self.create_name_internal(
406 name,
407 timeout.as_millis().try_into().unwrap(),
408 cancellation_token,
409 )
410 .await??;
411 Ok(())
412 }
413
414 pub async fn delete_name(
418 &self,
419 name: &Uri,
420 timeout: Duration,
421 cancellation_token: Option<BoxedCancelToken>,
422 ) -> crate::Result<()> {
423 self.delete_name_internal(
424 name,
425 timeout.as_millis().try_into().unwrap(),
426 cancellation_token,
427 )
428 .await??;
429 Ok(())
430 }
431
432 pub async fn name_exists(
434 &self,
435 name: &Uri,
436 timeout: Duration,
437 cancellation_token: Option<BoxedCancelToken>,
438 ) -> crate::Result<bool> {
439 self.name_exists_internal(
440 name,
441 timeout.as_millis().try_into().unwrap(),
442 cancellation_token,
443 )
444 .await?
445 .map_err(|e| e.into())
446 .map(|exist| exist != 0)
447 }
448
449 pub async fn enumerate_sub_names(
454 &self,
455 name: &Uri,
456 prev: Option<&NameEnumerationResult>,
457 recursive: bool,
458 timeout: Duration,
459 cancellation_token: Option<BoxedCancelToken>,
460 ) -> crate::Result<NameEnumerationResult> {
461 self.enumerate_sub_names_internal(
462 name,
463 prev.map(|x| x.as_com()),
464 recursive,
465 timeout.as_millis().try_into().unwrap(),
466 cancellation_token,
467 )
468 .await?
469 .map_err(|e| e.into())
470 .map(NameEnumerationResult::from_com)
471 }
472
473 pub async fn put_property_binary(
475 &self,
476 name: &Uri,
477 property_name: &WString,
478 data: &[u8],
479 timeout: Duration,
480 cancellation_token: Option<BoxedCancelToken>,
481 ) -> crate::Result<()> {
482 self.put_property_binary_internal(
483 name,
484 property_name,
485 data,
486 timeout.as_millis().try_into().unwrap(),
487 cancellation_token,
488 )
489 .await??;
490 Ok(())
491 }
492
493 pub async fn put_property_double(
495 &self,
496 name: &Uri,
497 property_name: &WString,
498 data: f64,
499 timeout: Duration,
500 cancellation_token: Option<BoxedCancelToken>,
501 ) -> crate::Result<()> {
502 self.put_property_double_internal(
503 name,
504 property_name,
505 data,
506 timeout.as_millis().try_into().unwrap(),
507 cancellation_token,
508 )
509 .await??;
510 Ok(())
511 }
512
513 pub async fn put_property_int64(
515 &self,
516 name: &Uri,
517 property_name: &WString,
518 data: i64,
519 timeout: Duration,
520 cancellation_token: Option<BoxedCancelToken>,
521 ) -> crate::Result<()> {
522 self.put_property_int64_internal(
523 name,
524 property_name,
525 data,
526 timeout.as_millis().try_into().unwrap(),
527 cancellation_token,
528 )
529 .await??;
530 Ok(())
531 }
532
533 pub async fn put_property_wstring(
535 &self,
536 name: &Uri,
537 property_name: &WString,
538 data: &WString,
539 timeout: Duration,
540 cancellation_token: Option<BoxedCancelToken>,
541 ) -> crate::Result<()> {
542 self.put_property_wstring_internal(
543 name,
544 property_name,
545 data,
546 timeout.as_millis().try_into().unwrap(),
547 cancellation_token,
548 )
549 .await??;
550 Ok(())
551 }
552
553 pub async fn put_property_guid(
555 &self,
556 name: &Uri,
557 property_name: &WString,
558 data: &windows_core::GUID,
559 timeout: Duration,
560 cancellation_token: Option<BoxedCancelToken>,
561 ) -> crate::Result<()> {
562 self.put_property_guid_internal(
563 name,
564 property_name,
565 data,
566 timeout.as_millis().try_into().unwrap(),
567 cancellation_token,
568 )
569 .await??;
570 Ok(())
571 }
572
573 pub async fn delete_property(
575 &self,
576 name: &Uri,
577 property_name: &WString,
578 timeout: Duration,
579 cancellation_token: Option<BoxedCancelToken>,
580 ) -> crate::Result<()> {
581 self.delete_property_internal(
582 name,
583 property_name,
584 timeout.as_millis().try_into().unwrap(),
585 cancellation_token,
586 )
587 .await??;
588 Ok(())
589 }
590
591 pub async fn get_property_metadata(
593 &self,
594 name: &Uri,
595 property_name: &WString,
596 timeout: Duration,
597 cancellation_token: Option<BoxedCancelToken>,
598 ) -> crate::Result<PropertyMetadataResult> {
599 self.get_property_metadata_internal(
600 name,
601 property_name,
602 timeout.as_millis().try_into().unwrap(),
603 cancellation_token,
604 )
605 .await?
606 .map_err(|e| e.into())
607 .map(PropertyMetadataResult::from_com)
608 }
609
610 pub async fn get_property(
612 &self,
613 name: &Uri,
614 property_name: &WString,
615 timeout: Duration,
616 cancellation_token: Option<BoxedCancelToken>,
617 ) -> crate::Result<PropertyValueResult> {
618 self.get_property_internal(
619 name,
620 property_name,
621 timeout.as_millis().try_into().unwrap(),
622 cancellation_token,
623 )
624 .await?
625 .map_err(|e| e.into())
626 .map(PropertyValueResult::from_com)
627 }
628}