summaryrefslogtreecommitdiffstats
path: root/third_party/rust/windows-core
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/windows-core
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/windows-core')
-rw-r--r--third_party/rust/windows-core/.cargo-checksum.json1
-rw-r--r--third_party/rust/windows-core/Cargo.toml33
-rw-r--r--third_party/rust/windows-core/license-apache-2.0201
-rw-r--r--third_party/rust/windows-core/license-mit21
-rw-r--r--third_party/rust/windows-core/readme.md88
-rw-r--r--third_party/rust/windows-core/src/agile_reference.rs28
-rw-r--r--third_party/rust/windows-core/src/array.rs177
-rw-r--r--third_party/rust/windows-core/src/as_impl.rs10
-rw-r--r--third_party/rust/windows-core/src/com_interface.rs50
-rw-r--r--third_party/rust/windows-core/src/error.rs159
-rw-r--r--third_party/rust/windows-core/src/event.rs264
-rw-r--r--third_party/rust/windows-core/src/guid.rs136
-rw-r--r--third_party/rust/windows-core/src/hresult.rs140
-rw-r--r--third_party/rust/windows-core/src/imp/bindings.rs53
-rw-r--r--third_party/rust/windows-core/src/imp/com_bindings.rs1370
-rw-r--r--third_party/rust/windows-core/src/imp/delay_load.rs25
-rw-r--r--third_party/rust/windows-core/src/imp/factory_cache.rs161
-rw-r--r--third_party/rust/windows-core/src/imp/generic_factory.rs30
-rw-r--r--third_party/rust/windows-core/src/imp/heap.rs35
-rw-r--r--third_party/rust/windows-core/src/imp/mod.rs55
-rw-r--r--third_party/rust/windows-core/src/imp/ref_count.rs34
-rw-r--r--third_party/rust/windows-core/src/imp/sha1.rs333
-rw-r--r--third_party/rust/windows-core/src/imp/waiter.rs39
-rw-r--r--third_party/rust/windows-core/src/imp/weak_ref_count.rs240
-rw-r--r--third_party/rust/windows-core/src/inspectable.rs148
-rw-r--r--third_party/rust/windows-core/src/interface.rs72
-rw-r--r--third_party/rust/windows-core/src/lib.rs59
-rw-r--r--third_party/rust/windows-core/src/param.rs133
-rw-r--r--third_party/rust/windows-core/src/runtime_name.rs5
-rw-r--r--third_party/rust/windows-core/src/runtime_type.rs30
-rw-r--r--third_party/rust/windows-core/src/scoped_interface.rs36
-rw-r--r--third_party/rust/windows-core/src/strings/bstr.rs162
-rw-r--r--third_party/rust/windows-core/src/strings/hstring.rs458
-rw-r--r--third_party/rust/windows-core/src/strings/literals.rs156
-rw-r--r--third_party/rust/windows-core/src/strings/mod.rs83
-rw-r--r--third_party/rust/windows-core/src/strings/pcstr.rs73
-rw-r--r--third_party/rust/windows-core/src/strings/pcwstr.rs69
-rw-r--r--third_party/rust/windows-core/src/strings/pstr.rs60
-rw-r--r--third_party/rust/windows-core/src/strings/pwstr.rs69
-rw-r--r--third_party/rust/windows-core/src/type.rs110
-rw-r--r--third_party/rust/windows-core/src/unknown.rs103
-rw-r--r--third_party/rust/windows-core/src/weak.rs23
-rw-r--r--third_party/rust/windows-core/windows.natvis84
43 files changed, 5616 insertions, 0 deletions
diff --git a/third_party/rust/windows-core/.cargo-checksum.json b/third_party/rust/windows-core/.cargo-checksum.json
new file mode 100644
index 0000000000..32089fef79
--- /dev/null
+++ b/third_party/rust/windows-core/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"483877d1a465dc6a4c190fdc206eb83293e6102d548dcf0f2e2093fa075694f5","license-apache-2.0":"c16f8dcf1a368b83be78d826ea23de4079fe1b4469a0ab9ee20563f37ff3d44b","license-mit":"c2cfccb812fe482101a8f04597dfc5a9991a6b2748266c47ac91b6a5aae15383","readme.md":"3bcfa95b17c7748ff6139e7482ebad2d24645ac3606e4b4f88318c72122d1386","src/agile_reference.rs":"801b3bbe3674e2665bdcb12a08f06f7782be60a14c3a033289f32aa35db1fce1","src/array.rs":"c9975db941876ce329ed851b5e6ad989a660f9da0f91e8dece7333fda2274e01","src/as_impl.rs":"018954b44fe4c16d62a959f5578c5a26b968d0f9a3f156f1bac10492b934d949","src/com_interface.rs":"afc47510e80e829b5ebb2a801840104725dfcea3c5920a424b089948a14f8d15","src/error.rs":"c9115facaaa7369e91e3d959e9278770d727e52bb0108df099ae5c90feb52fdf","src/event.rs":"cc3502add9db70efb2627ddc5c709853a56ccbfee37923d67b56ed338b9d8f44","src/guid.rs":"dd82af578fef2519173614600a15ada073d5e7c973fd2e951eb5abef9b1553d0","src/hresult.rs":"00155798c154614c4c9a0a2da20814dddb537a1e21c88bc3dff65598fdf7ee03","src/imp/bindings.rs":"805fe0012f5bbf639f6d66cfdbe21f4f855c4ec3eee2610f457dbf3b80defad7","src/imp/com_bindings.rs":"3f88e91dd17daf657c9e29e82628fc84fa02b942bca1ae5ca682e4a2a89ccb6e","src/imp/delay_load.rs":"26492b2ef34f4a3ac35f41050a9088ee15603caf0a59c6e74fdf423bfcb96829","src/imp/factory_cache.rs":"fcec72750d06a262878720a13f82b7365075c6b038b28426532b233aae8baa84","src/imp/generic_factory.rs":"cbf8b251e2758d98bf6bbd7c73b20a2e31e60e0d006b2febc51e247c039fab85","src/imp/heap.rs":"646e31462f37f96a9d6928997c2bbacc333eabb3989e9999e89ff95e9565e4ba","src/imp/mod.rs":"503ab66c7911e5ad6dfd2311f81674798c84e41d3c023b4868f80ad3a3593b8f","src/imp/ref_count.rs":"ded51b50923eb1d542432d216b56604b6cef564f664740a3ad8290ad8d88b8e6","src/imp/sha1.rs":"0ff2ba4d1f77b5ec3859567fec1a3d75175a844914c5f7ec068c8581dc2b7f4a","src/imp/waiter.rs":"575cfdbe9befc22b1e8fa91e15f303d830b23673d07a5361992229e0440081b2","src/imp/weak_ref_count.rs":"5d58f4bdcb4b6fbb55be672b7bd885307c9cac17ee4f212c899a54e76a039ded","src/inspectable.rs":"32c4881d567d90254556a4185cd0dd5b984c932183db7c8b4c51bcbac53e41ac","src/interface.rs":"4a4588085d5401585aabc62a131d2601134f4fb80ba2199fe066e6df6c84ead3","src/lib.rs":"9673f8d82af0325a5924b9afe07af39e7ea82731c3caca126e39cd9596dd4e63","src/param.rs":"cb62f173048e84f6355662223d34be482449393fc049fc45980d1bf087dc8e77","src/runtime_name.rs":"b330db95b0ce32c963d6b43a0b152cd96e136e5b38b92c02223fb53b30f83ecf","src/runtime_type.rs":"cf3697b442b2bc77e1a8981128eb5f4c282603a01f7081399f1e11587670d0bc","src/scoped_interface.rs":"c11be14a0c95c3c9b055741e4b9c353d6bb6efe88075ceb05fd606b6ac34a2a6","src/strings/bstr.rs":"569ff0cf6157cb869ec14f773261fe95ee1d065cade7b04d3ee44f0dfbdec149","src/strings/hstring.rs":"ea3913393e655b6c48270df04fbb82eb9fc4b1d3f1d673bd04872a33d160f38d","src/strings/literals.rs":"5b998ebd3a750a7f42c2013b354a58f6c289f5f433f154a9ac34b47e23ec9429","src/strings/mod.rs":"4aaf6d2efe2396e541bd5d9ddff859d3374bfda4914b67daf645ee3b48cc3852","src/strings/pcstr.rs":"3c29064d22e632dc9f30c8d6933e41d5c755d2c82462c6570318bebe12a5c1a3","src/strings/pcwstr.rs":"86a36da73bdcd12af9a6e1be09470443b42017a0613c432ac3e559cfdc7f3ff2","src/strings/pstr.rs":"151d29125932d874aefcda01975913f87e8561b3d240e84c9db39e891b78a484","src/strings/pwstr.rs":"de99eb08f1f3c351854d1ed1f978460669b53ae39dc118e788a9f66a562d2c7c","src/type.rs":"fc263c265f799c7d5b326cebbbc20a8f96ee438b1cc444d9925caab22db8e488","src/unknown.rs":"5a1888c35ad9db383216bbe1c15dde3ea316d40ba2783392067060706f7ec812","src/weak.rs":"b1d1740d65ad0b9f296342afbac0c6994eb2fa0ea7dba4882b64b246e309d9da","windows.natvis":"f9bd327a207011f85debdd3d67828668f71b56e7e429a7172dab1286738ca238"},"package":"33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"} \ No newline at end of file
diff --git a/third_party/rust/windows-core/Cargo.toml b/third_party/rust/windows-core/Cargo.toml
new file mode 100644
index 0000000000..9b30523911
--- /dev/null
+++ b/third_party/rust/windows-core/Cargo.toml
@@ -0,0 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.56"
+name = "windows-core"
+version = "0.52.0"
+authors = ["Microsoft"]
+description = "Rust for Windows"
+readme = "readme.md"
+categories = ["os::windows-apis"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/microsoft/windows-rs"
+
+[package.metadata.docs.rs]
+default-target = "x86_64-pc-windows-msvc"
+targets = []
+
+[dependencies.windows-targets]
+version = "0.52.0"
+
+[features]
+default = []
+implement = []
diff --git a/third_party/rust/windows-core/license-apache-2.0 b/third_party/rust/windows-core/license-apache-2.0
new file mode 100644
index 0000000000..b5ed4ecec2
--- /dev/null
+++ b/third_party/rust/windows-core/license-apache-2.0
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright (c) Microsoft Corporation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/rust/windows-core/license-mit b/third_party/rust/windows-core/license-mit
new file mode 100644
index 0000000000..9e841e7a26
--- /dev/null
+++ b/third_party/rust/windows-core/license-mit
@@ -0,0 +1,21 @@
+ MIT License
+
+ Copyright (c) Microsoft Corporation.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE
diff --git a/third_party/rust/windows-core/readme.md b/third_party/rust/windows-core/readme.md
new file mode 100644
index 0000000000..ee076f40ca
--- /dev/null
+++ b/third_party/rust/windows-core/readme.md
@@ -0,0 +1,88 @@
+## Rust for Windows
+
+The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
+
+* [Getting started](https://kennykerr.ca/rust-getting-started/)
+* [Samples](https://github.com/microsoft/windows-rs/tree/0.52.0/crates/samples) <!-- link to samples for upcoming release -->
+* [Releases](https://github.com/microsoft/windows-rs/releases)
+
+Start by adding the following to your Cargo.toml file:
+
+```toml
+[dependencies.windows]
+version = "0.52"
+features = [
+ "Data_Xml_Dom",
+ "Win32_Foundation",
+ "Win32_Security",
+ "Win32_System_Threading",
+ "Win32_UI_WindowsAndMessaging",
+]
+```
+
+Make use of any Windows APIs as needed:
+
+```rust,no_run
+use windows::{
+ core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*,
+ Win32::UI::WindowsAndMessaging::*,
+};
+
+fn main() -> Result<()> {
+ let doc = XmlDocument::new()?;
+ doc.LoadXml(h!("<html>hello world</html>"))?;
+
+ let root = doc.DocumentElement()?;
+ assert!(root.NodeName()? == "html");
+ assert!(root.InnerText()? == "hello world");
+
+ unsafe {
+ let event = CreateEventW(None, true, false, None)?;
+ SetEvent(event)?;
+ WaitForSingleObject(event, 0);
+ CloseHandle(event)?;
+
+ MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
+ MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
+ }
+
+ Ok(())
+}
+```
+
+## windows-sys
+
+The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided.
+
+Start by adding the following to your Cargo.toml file:
+
+```toml
+[dependencies.windows-sys]
+version = "0.52"
+features = [
+ "Win32_Foundation",
+ "Win32_Security",
+ "Win32_System_Threading",
+ "Win32_UI_WindowsAndMessaging",
+]
+```
+
+Make use of any Windows APIs as needed:
+
+```rust,no_run
+use windows_sys::{
+ core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*,
+};
+
+fn main() {
+ unsafe {
+ let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null());
+ SetEvent(event);
+ WaitForSingleObject(event, 0);
+ CloseHandle(event);
+
+ MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
+ MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
+ }
+}
+```
diff --git a/third_party/rust/windows-core/src/agile_reference.rs b/third_party/rust/windows-core/src/agile_reference.rs
new file mode 100644
index 0000000000..91dcd1593d
--- /dev/null
+++ b/third_party/rust/windows-core/src/agile_reference.rs
@@ -0,0 +1,28 @@
+use super::*;
+use std::marker::PhantomData;
+
+/// A type representing an agile reference to a COM/WinRT object.
+#[repr(transparent)]
+#[derive(Clone, PartialEq, Eq)]
+pub struct AgileReference<T>(crate::imp::IAgileReference, PhantomData<T>);
+
+impl<T: ComInterface> AgileReference<T> {
+ /// Creates an agile reference to the object.
+ pub fn new(object: &T) -> Result<Self> {
+ unsafe { crate::imp::RoGetAgileReference(crate::imp::AGILEREFERENCE_DEFAULT, &T::IID, object.as_unknown()).map(|reference| Self(reference, Default::default())) }
+ }
+
+ /// Retrieves a proxy to the target of the `AgileReference` object that may safely be used within any thread context in which get is called.
+ pub fn resolve(&self) -> Result<T> {
+ unsafe { self.0.Resolve() }
+ }
+}
+
+unsafe impl<T: ComInterface> Send for AgileReference<T> {}
+unsafe impl<T: ComInterface> Sync for AgileReference<T> {}
+
+impl<T> std::fmt::Debug for AgileReference<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "AgileReference({:?})", &self.0)
+ }
+}
diff --git a/third_party/rust/windows-core/src/array.rs b/third_party/rust/windows-core/src/array.rs
new file mode 100644
index 0000000000..92de007192
--- /dev/null
+++ b/third_party/rust/windows-core/src/array.rs
@@ -0,0 +1,177 @@
+use super::*;
+
+/// A WinRT array stores elements contiguously in a heap-allocated buffer.
+pub struct Array<T: Type<T>> {
+ data: *mut T::Default,
+ len: u32,
+}
+
+impl<T: Type<T>> Default for Array<T> {
+ fn default() -> Self {
+ Array { data: std::ptr::null_mut(), len: 0 }
+ }
+}
+
+impl<T: Type<T>> Array<T> {
+ /// Creates an empty array.
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Creates an array of the given length with default values.
+ pub fn with_len(len: usize) -> Self {
+ assert!(len < std::u32::MAX as usize);
+ let bytes_amount = len.checked_mul(std::mem::size_of::<T>()).expect("Attempted to allocate too large an Array");
+
+ // WinRT arrays must be allocated with CoTaskMemAlloc.
+ // SAFETY: the call to CoTaskMemAlloc is safe to perform
+ // if len is zero and overflow was checked above.
+ // We ensured we alloc enough space by multiplying len * size_of::<T>
+ let data = unsafe { crate::imp::CoTaskMemAlloc(bytes_amount) as *mut T::Default };
+
+ assert!(!data.is_null(), "Could not successfully allocate for Array");
+
+ // SAFETY: It is by definition safe to zero-initialize WinRT types.
+ // `write_bytes` will write 0 to (len * size_of::<T>())
+ // bytes making the entire array zero initialized. We have assured
+ // above that the data ptr is not null.
+ unsafe {
+ std::ptr::write_bytes(data, 0, len);
+ }
+
+ let len = len as u32;
+ Self { data, len }
+ }
+
+ /// Creates an array by copying the elements from the slice.
+ pub fn from_slice(values: &[T::Default]) -> Self
+ where
+ T::Default: Clone,
+ {
+ let mut array = Self::with_len(values.len());
+ array.clone_from_slice(values);
+ array
+ }
+
+ /// Creates an array from a pointer and length. The `len` argument is the number of elements, not the number of bytes.
+ /// # Safety
+ /// The `data` argument must have been allocated with `CoTaskMemAlloc`.
+ pub unsafe fn from_raw_parts(data: *mut T::Default, len: u32) -> Self {
+ Self { data, len }
+ }
+
+ /// Returns a slice containing the entire array.
+ pub fn as_slice(&self) -> &[T::Default] {
+ self
+ }
+
+ /// Returns `true` if the array is empty.
+ pub fn is_empty(&self) -> bool {
+ self.len == 0
+ }
+
+ /// Returns the length of the array.
+ pub fn len(&self) -> usize {
+ self.len as usize
+ }
+
+ /// Clears the contents of the array.
+ pub fn clear(&mut self) {
+ if self.is_empty() {
+ return;
+ }
+
+ let mut data = std::ptr::null_mut();
+ let mut len = 0;
+
+ std::mem::swap(&mut data, &mut self.data);
+ std::mem::swap(&mut len, &mut self.len);
+
+ // SAFETY: At this point, self has been reset to zero so any panics in T's destructor would
+ // only leak data not leave the array in bad state.
+ unsafe {
+ // Call the destructors of all the elements of the old array
+ // SAFETY: the slice cannot be used after the call to `drop_in_place`
+ std::ptr::drop_in_place(std::slice::from_raw_parts_mut(data, len as usize));
+ // Free the data memory where the elements were
+ // SAFETY: we have unique access to the data pointer at this point
+ // so freeing it is the right thing to do
+ crate::imp::CoTaskMemFree(data as _);
+ }
+ }
+
+ #[doc(hidden)]
+ /// Get a mutable pointer to the array's length
+ ///
+ /// # Safety
+ ///
+ /// This function is safe but writing to the pointer is not. Calling this without
+ /// a subsequent call to `set_abi` is likely to either leak memory or cause UB
+ pub unsafe fn set_abi_len(&mut self) -> *mut u32 {
+ &mut self.len
+ }
+
+ #[doc(hidden)]
+ /// Turn the array into a pointer to its data and its length
+ pub fn into_abi(self) -> (*mut T::Abi, u32) {
+ let abi = (self.data as *mut _, self.len);
+ std::mem::forget(self);
+ abi
+ }
+}
+
+impl<T: Type<T>> std::ops::Deref for Array<T> {
+ type Target = [T::Default];
+
+ fn deref(&self) -> &[T::Default] {
+ if self.is_empty() {
+ return &[];
+ }
+
+ // SAFETY: data must not be null if the array is not empty
+ unsafe { std::slice::from_raw_parts(self.data, self.len as usize) }
+ }
+}
+
+impl<T: Type<T>> std::ops::DerefMut for Array<T> {
+ fn deref_mut(&mut self) -> &mut [T::Default] {
+ if self.is_empty() {
+ return &mut [];
+ }
+
+ // SAFETY: data must not be null if the array is not empty
+ unsafe { std::slice::from_raw_parts_mut(self.data, self.len as usize) }
+ }
+}
+
+impl<T: Type<T>> Drop for Array<T> {
+ fn drop(&mut self) {
+ self.clear();
+ }
+}
+
+#[doc(hidden)]
+pub struct ArrayProxy<T: Type<T>> {
+ data: *mut *mut T::Default,
+ len: *mut u32,
+ temp: std::mem::ManuallyDrop<Array<T>>,
+}
+
+impl<T: Type<T>> ArrayProxy<T> {
+ pub fn from_raw_parts(data: *mut *mut T::Default, len: *mut u32) -> Self {
+ Self { data, len, temp: std::mem::ManuallyDrop::new(Array::new()) }
+ }
+
+ pub fn as_array(&mut self) -> &mut Array<T> {
+ &mut self.temp
+ }
+}
+
+impl<T: Type<T>> Drop for ArrayProxy<T> {
+ fn drop(&mut self) {
+ unsafe {
+ *self.data = self.temp.data;
+ *self.len = self.temp.len;
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/as_impl.rs b/third_party/rust/windows-core/src/as_impl.rs
new file mode 100644
index 0000000000..9bcae8ebc3
--- /dev/null
+++ b/third_party/rust/windows-core/src/as_impl.rs
@@ -0,0 +1,10 @@
+/// A trait for retrieving the implementation behind a COM or WinRT interface.
+///
+/// This trait is automatically implemented when using the `implement` macro.
+pub trait AsImpl<T> {
+ /// # Safety
+ ///
+ /// The caller needs to ensure that `self` is actually implemented by the
+ /// implementation `T`.
+ unsafe fn as_impl(&self) -> &T;
+}
diff --git a/third_party/rust/windows-core/src/com_interface.rs b/third_party/rust/windows-core/src/com_interface.rs
new file mode 100644
index 0000000000..5259238b9e
--- /dev/null
+++ b/third_party/rust/windows-core/src/com_interface.rs
@@ -0,0 +1,50 @@
+use super::*;
+
+/// Provides low-level access to a COM interface.
+///
+/// This trait is automatically implemented by the generated bindings and should not be
+/// implemented manually.
+///
+/// # Safety
+///
+/// It is only safe to implement this trait if the implementing type is a valid COM interface pointer meaning
+/// the following criteria are met:
+/// * its in-memory representation is equal to `NonNull<NonNull<Self::VTable>>`
+/// * the vtable is correctly structured beginning with the `IUnknown` function pointers
+/// * the vtable must be the correct vtable for the supplied IID
+pub unsafe trait ComInterface: Interface + Clone {
+ /// A unique identifier representing this interface.
+ const IID: GUID;
+
+ // Casts the `ComInterface` to a `IUnknown`.
+ fn as_unknown(&self) -> &IUnknown {
+ // SAFETY: it is always safe to treat a `ComInterface` as an `IUnknown`.
+ unsafe { std::mem::transmute(self) }
+ }
+
+ /// Attempts to cast the current interface to another interface using `QueryInterface`.
+ ///
+ /// The name `cast` is preferred to `query` because there is a WinRT method named query but not one
+ /// named cast.
+ fn cast<T: ComInterface>(&self) -> Result<T> {
+ let mut result = None;
+ // SAFETY: `result` is valid for writing an interface pointer and it is safe
+ // to cast the `result` pointer as `T` on success because we are using the `IID` tied
+ // to `T` which the implementor of `ComInterface` has guaranteed is correct
+ unsafe { self.query(&T::IID, &mut result as *mut _ as _).and_some(result) }
+ }
+
+ /// Attempts to create a [`Weak`] reference to this object.
+ fn downgrade(&self) -> Result<Weak<Self>> {
+ self.cast::<crate::imp::IWeakReferenceSource>().and_then(|source| Weak::downgrade(&source))
+ }
+
+ /// Call `QueryInterface` on this interface
+ ///
+ /// # Safety
+ ///
+ /// `interface` must be a non-null, valid pointer for writing an interface pointer.
+ unsafe fn query(&self, iid: *const GUID, interface: *mut *mut std::ffi::c_void) -> HRESULT {
+ (self.assume_vtable::<IUnknown>().QueryInterface)(self.as_raw(), iid, interface)
+ }
+}
diff --git a/third_party/rust/windows-core/src/error.rs b/third_party/rust/windows-core/src/error.rs
new file mode 100644
index 0000000000..b851a21311
--- /dev/null
+++ b/third_party/rust/windows-core/src/error.rs
@@ -0,0 +1,159 @@
+use super::*;
+
+/// An error object consists of both an error code as well as detailed error information for debugging.
+#[derive(Clone, PartialEq, Eq)]
+pub struct Error {
+ pub(crate) code: HRESULT,
+ pub(crate) info: Option<crate::imp::IRestrictedErrorInfo>,
+}
+
+impl Error {
+ /// An error object without any failure information.
+ pub const OK: Self = Self { code: HRESULT(0), info: None };
+
+ /// This creates a new WinRT error object, capturing the stack and other information about the
+ /// point of failure.
+ pub fn new(code: HRESULT, message: HSTRING) -> Self {
+ unsafe {
+ if let Some(function) = crate::imp::delay_load::<RoOriginateError>(s!("combase.dll"), s!("RoOriginateError")) {
+ function(code, std::mem::transmute_copy(&message));
+ }
+ let info = GetErrorInfo().and_then(|e| e.cast()).ok();
+ Self { code, info }
+ }
+ }
+
+ pub fn from_win32() -> Self {
+ unsafe { Self { code: HRESULT::from_win32(crate::imp::GetLastError()), info: None } }
+ }
+
+ /// The error code describing the error.
+ pub const fn code(&self) -> HRESULT {
+ self.code
+ }
+
+ /// The error information describing the error.
+ pub const fn info(&self) -> &Option<crate::imp::IRestrictedErrorInfo> {
+ &self.info
+ }
+
+ /// The error message describing the error.
+ pub fn message(&self) -> HSTRING {
+ // First attempt to retrieve the restricted error information.
+ if let Some(info) = &self.info {
+ let mut fallback = BSTR::default();
+ let mut message = BSTR::default();
+ let mut code = HRESULT(0);
+
+ unsafe {
+ let _ = info.GetErrorDetails(&mut fallback, &mut code, &mut message, &mut BSTR::default());
+ }
+
+ if self.code == code {
+ let message = if !message.is_empty() { message } else { fallback };
+ return HSTRING::from_wide(crate::imp::wide_trim_end(message.as_wide())).unwrap_or_default();
+ }
+ }
+
+ self.code.message()
+ }
+}
+
+impl std::convert::From<Error> for HRESULT {
+ fn from(error: Error) -> Self {
+ let code = error.code;
+ let info: Option<crate::imp::IErrorInfo> = error.info.and_then(|info| info.cast().ok());
+
+ unsafe {
+ let _ = crate::imp::SetErrorInfo(0, info.as_ref());
+ }
+
+ code
+ }
+}
+
+impl std::convert::From<Error> for std::io::Error {
+ fn from(from: Error) -> Self {
+ Self::from_raw_os_error(from.code.0)
+ }
+}
+
+impl std::convert::From<std::string::FromUtf16Error> for Error {
+ fn from(_: std::string::FromUtf16Error) -> Self {
+ Self { code: HRESULT::from_win32(crate::imp::ERROR_NO_UNICODE_TRANSLATION), info: None }
+ }
+}
+
+impl std::convert::From<std::string::FromUtf8Error> for Error {
+ fn from(_: std::string::FromUtf8Error) -> Self {
+ Self { code: HRESULT::from_win32(crate::imp::ERROR_NO_UNICODE_TRANSLATION), info: None }
+ }
+}
+
+impl std::convert::From<std::num::TryFromIntError> for Error {
+ fn from(_: std::num::TryFromIntError) -> Self {
+ Self { code: HRESULT(crate::imp::E_INVALIDARG), info: None }
+ }
+}
+
+// Unfortunately this is needed to make types line up. The Rust type system does
+// not know the `Infallible` can never be constructed. This code needs to be here
+// to satesify the type checker but it will never be run. Once `!` is stabilizied
+// this can be removed.
+impl std::convert::From<std::convert::Infallible> for Error {
+ fn from(_: std::convert::Infallible) -> Self {
+ unreachable!()
+ }
+}
+
+impl std::convert::From<HRESULT> for Error {
+ fn from(code: HRESULT) -> Self {
+ let info: Option<crate::imp::IRestrictedErrorInfo> = GetErrorInfo().and_then(|e| e.cast()).ok();
+
+ if let Some(info) = info {
+ // If it does (and therefore running on a recent version of Windows)
+ // then capture_propagation_context adds a breadcrumb to the error
+ // info to make debugging easier.
+ if let Ok(capture) = info.cast::<crate::imp::ILanguageExceptionErrorInfo2>() {
+ unsafe {
+ let _ = capture.CapturePropagationContext(None);
+ }
+ }
+
+ return Self { code, info: Some(info) };
+ }
+
+ if let Ok(info) = GetErrorInfo() {
+ let message = unsafe { info.GetDescription().unwrap_or_default() };
+ Self::new(code, HSTRING::from_wide(message.as_wide()).unwrap_or_default())
+ } else {
+ Self { code, info: None }
+ }
+ }
+}
+
+impl std::fmt::Debug for Error {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let mut debug = fmt.debug_struct("Error");
+ debug.field("code", &self.code).field("message", &self.message()).finish()
+ }
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let message = self.message();
+ if message.is_empty() {
+ std::write!(fmt, "{}", self.code())
+ } else {
+ std::write!(fmt, "{} ({})", self.message(), self.code())
+ }
+ }
+}
+
+impl std::error::Error for Error {}
+
+type RoOriginateError = extern "system" fn(code: HRESULT, message: *mut std::ffi::c_void) -> i32;
+
+fn GetErrorInfo() -> Result<crate::imp::IErrorInfo> {
+ unsafe { crate::imp::GetErrorInfo(0) }
+}
diff --git a/third_party/rust/windows-core/src/event.rs b/third_party/rust/windows-core/src/event.rs
new file mode 100644
index 0000000000..eea0683dfc
--- /dev/null
+++ b/third_party/rust/windows-core/src/event.rs
@@ -0,0 +1,264 @@
+use super::*;
+use std::sync::*;
+
+/// A type that you can use to declare and implement an event of a specified delegate type.
+///
+/// The implementation is thread-safe and designed to avoid contention between events being
+/// raised and delegates being added or removed.
+pub struct Event<T: ComInterface> {
+ swap: Mutex<()>,
+ change: Mutex<()>,
+ delegates: Array<T>,
+}
+
+impl<T: ComInterface> Default for Event<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<T: ComInterface> Event<T> {
+ /// Creates a new, empty `Event<T>`.
+ pub fn new() -> Self {
+ Self { delegates: Array::new(), swap: Mutex::default(), change: Mutex::default() }
+ }
+
+ /// Registers a delegate with the event object.
+ pub fn add(&mut self, delegate: &T) -> Result<i64> {
+ let mut _lock_free_drop = Array::new();
+ Ok({
+ let _change_lock = self.change.lock().unwrap();
+ let mut new_delegates = Array::with_capacity(self.delegates.len() + 1)?;
+ for delegate in self.delegates.as_slice() {
+ new_delegates.push(delegate.clone());
+ }
+ let delegate = Delegate::new(delegate)?;
+ let token = delegate.to_token();
+ new_delegates.push(delegate);
+
+ let _swap_lock = self.swap.lock().unwrap();
+ _lock_free_drop = self.delegates.swap(new_delegates);
+ token
+ })
+ }
+
+ /// Revokes a delegate's registration from the event object.
+ pub fn remove(&mut self, token: i64) -> Result<()> {
+ let mut _lock_free_drop = Array::new();
+ {
+ let _change_lock = self.change.lock().unwrap();
+ if self.delegates.is_empty() {
+ return Ok(());
+ }
+ let mut capacity = self.delegates.len() - 1;
+ let mut new_delegates = Array::new();
+ let mut removed = false;
+ if capacity == 0 {
+ removed = self.delegates.as_slice()[0].to_token() == token;
+ } else {
+ new_delegates = Array::with_capacity(capacity)?;
+ for delegate in self.delegates.as_slice() {
+ if !removed && delegate.to_token() == token {
+ removed = true;
+ continue;
+ }
+ if capacity == 0 {
+ break;
+ }
+ new_delegates.push(delegate.clone());
+ capacity -= 1;
+ }
+ }
+ if removed {
+ let _swap_lock = self.swap.lock().unwrap();
+ _lock_free_drop = self.delegates.swap(new_delegates);
+ }
+ }
+ Ok(())
+ }
+
+ /// Clears the event, removing all delegates.
+ pub fn clear(&mut self) {
+ let mut _lock_free_drop = Array::new();
+ {
+ let _change_lock = self.change.lock().unwrap();
+ if self.delegates.is_empty() {
+ return;
+ }
+ let _swap_lock = self.swap.lock().unwrap();
+ _lock_free_drop = self.delegates.swap(Array::new());
+ }
+ }
+
+ /// Invokes all of the event object's registered delegates with the provided callback.
+ pub fn call<F: FnMut(&T) -> Result<()>>(&mut self, mut callback: F) -> Result<()> {
+ let lock_free_calls = {
+ let _swap_lock = self.swap.lock().unwrap();
+ self.delegates.clone()
+ };
+ for delegate in lock_free_calls.as_slice() {
+ if let Err(error) = delegate.call(&mut callback) {
+ const RPC_E_SERVER_UNAVAILABLE: HRESULT = HRESULT(-2147023174); // HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)
+ if matches!(error.code(), crate::imp::RPC_E_DISCONNECTED | crate::imp::JSCRIPT_E_CANTEXECUTE | RPC_E_SERVER_UNAVAILABLE) {
+ self.remove(delegate.to_token())?;
+ }
+ }
+ }
+ Ok(())
+ }
+}
+
+/// A thread-safe reference-counted array of delegates.
+struct Array<T: ComInterface> {
+ buffer: *mut Buffer<T>,
+ len: usize,
+ _phantom: std::marker::PhantomData<T>,
+}
+
+impl<T: ComInterface> Default for Array<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<T: ComInterface> Array<T> {
+ /// Creates a new, empty `Array<T>` with no capacity.
+ fn new() -> Self {
+ Self { buffer: std::ptr::null_mut(), len: 0, _phantom: std::marker::PhantomData }
+ }
+
+ /// Creates a new, empty `Array<T>` with the specified capacity.
+ fn with_capacity(capacity: usize) -> Result<Self> {
+ Ok(Self { buffer: Buffer::new(capacity)?, len: 0, _phantom: std::marker::PhantomData })
+ }
+
+ /// Swaps the contents of two `Array<T>` objects.
+ fn swap(&mut self, mut other: Self) -> Self {
+ unsafe { std::ptr::swap(&mut self.buffer, &mut other.buffer) };
+ std::mem::swap(&mut self.len, &mut other.len);
+ other
+ }
+
+ /// Returns `true` if the array contains no delegates.
+ fn is_empty(&self) -> bool {
+ self.len == 0
+ }
+
+ /// Returns the number of delegates in the array.
+ fn len(&self) -> usize {
+ self.len
+ }
+
+ /// Appends a delegate to the back of the array.
+ fn push(&mut self, delegate: Delegate<T>) {
+ unsafe {
+ std::ptr::write((*self.buffer).as_mut_ptr().add(self.len), delegate);
+ self.len += 1;
+ }
+ }
+
+ /// Returns a slice containing of all delegates.
+ fn as_slice(&self) -> &[Delegate<T>] {
+ if self.is_empty() {
+ &[]
+ } else {
+ unsafe { std::slice::from_raw_parts((*self.buffer).as_ptr(), self.len) }
+ }
+ }
+
+ /// Returns a mutable slice of all delegates.
+ fn as_mut_slice(&mut self) -> &mut [Delegate<T>] {
+ if self.is_empty() {
+ &mut []
+ } else {
+ unsafe { std::slice::from_raw_parts_mut((*self.buffer).as_mut_ptr(), self.len) }
+ }
+ }
+}
+
+impl<T: ComInterface> Clone for Array<T> {
+ fn clone(&self) -> Self {
+ if !self.is_empty() {
+ unsafe { (*self.buffer).0.add_ref() };
+ }
+ Self { buffer: self.buffer, len: self.len, _phantom: std::marker::PhantomData }
+ }
+}
+
+impl<T: ComInterface> Drop for Array<T> {
+ fn drop(&mut self) {
+ unsafe {
+ if !self.is_empty() && (*self.buffer).0.release() == 0 {
+ std::ptr::drop_in_place(self.as_mut_slice());
+ crate::imp::heap_free(self.buffer as _)
+ }
+ }
+ }
+}
+
+/// A reference-counted buffer.
+#[repr(C)]
+struct Buffer<T>(crate::imp::RefCount, std::marker::PhantomData<T>);
+
+impl<T: ComInterface> Buffer<T> {
+ /// Creates a new `Buffer` with the specified size in bytes.
+ fn new(len: usize) -> Result<*mut Self> {
+ if len == 0 {
+ Ok(std::ptr::null_mut())
+ } else {
+ let alloc_size = std::mem::size_of::<Self>() + len * std::mem::size_of::<Delegate<T>>();
+ let header = crate::imp::heap_alloc(alloc_size)? as *mut Self;
+ unsafe {
+ header.write(Self(crate::imp::RefCount::new(1), std::marker::PhantomData));
+ }
+ Ok(header)
+ }
+ }
+
+ /// Returns a raw pointer to the buffer's contents. The resulting pointer might be uninititalized.
+ fn as_ptr(&self) -> *const Delegate<T> {
+ unsafe { (self as *const Self).add(1) as *const _ }
+ }
+
+ /// Returns a raw mutable pointer to the buffer's contents. The resulting pointer might be uninititalized.
+ fn as_mut_ptr(&mut self) -> *mut Delegate<T> {
+ unsafe { (self as *mut Self).add(1) as *mut _ }
+ }
+}
+
+/// Holds either a direct or indirect reference to a delegate. A direct reference is typically
+/// agile while an indirect reference is an agile wrapper.
+#[derive(Clone)]
+enum Delegate<T> {
+ Direct(T),
+ Indirect(AgileReference<T>),
+}
+
+impl<T: ComInterface> Delegate<T> {
+ /// Creates a new `Delegate<T>`, containing a suitable reference to the specified delegate.
+ fn new(delegate: &T) -> Result<Self> {
+ if delegate.cast::<crate::imp::IAgileObject>().is_ok() {
+ Ok(Self::Direct(delegate.clone()))
+ } else {
+ Ok(Self::Indirect(AgileReference::new(delegate)?))
+ }
+ }
+
+ /// Returns an encoded token to identify the delegate.
+ fn to_token(&self) -> i64 {
+ unsafe {
+ match self {
+ Self::Direct(delegate) => crate::imp::EncodePointer(std::mem::transmute_copy(delegate)) as i64,
+ Self::Indirect(delegate) => crate::imp::EncodePointer(std::mem::transmute_copy(delegate)) as i64,
+ }
+ }
+ }
+
+ /// Invokes the delegates with the provided callback.
+ fn call<F: FnMut(&T) -> Result<()>>(&self, mut callback: F) -> Result<()> {
+ match self {
+ Self::Direct(delegate) => callback(delegate),
+ Self::Indirect(delegate) => callback(&delegate.resolve()?),
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/guid.rs b/third_party/rust/windows-core/src/guid.rs
new file mode 100644
index 0000000000..ddaa5611e8
--- /dev/null
+++ b/third_party/rust/windows-core/src/guid.rs
@@ -0,0 +1,136 @@
+#![allow(clippy::many_single_char_names)]
+
+use super::*;
+
+/// A globally unique identifier ([GUID](https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid))
+/// used to identify COM and WinRT interfaces.
+#[repr(C)]
+#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
+pub struct GUID {
+ pub data1: u32,
+ pub data2: u16,
+ pub data3: u16,
+ pub data4: [u8; 8],
+}
+
+impl GUID {
+ /// Creates a unique `GUID` value.
+ pub fn new() -> Result<Self> {
+ unsafe { imp::CoCreateGuid() }
+ }
+
+ /// Creates a `GUID` represented by the all-zero byte-pattern.
+ pub const fn zeroed() -> Self {
+ Self { data1: 0, data2: 0, data3: 0, data4: [0, 0, 0, 0, 0, 0, 0, 0] }
+ }
+
+ /// Creates a `GUID` with the given constant values.
+ pub const fn from_values(data1: u32, data2: u16, data3: u16, data4: [u8; 8]) -> Self {
+ Self { data1, data2, data3, data4 }
+ }
+
+ /// Creates a `GUID` from a `u128` value.
+ pub const fn from_u128(uuid: u128) -> Self {
+ Self { data1: (uuid >> 96) as u32, data2: (uuid >> 80 & 0xffff) as u16, data3: (uuid >> 64 & 0xffff) as u16, data4: (uuid as u64).to_be_bytes() }
+ }
+
+ /// Converts a `GUID` to a `u128` value.
+ pub const fn to_u128(&self) -> u128 {
+ ((self.data1 as u128) << 96) + ((self.data2 as u128) << 80) + ((self.data3 as u128) << 64) + u64::from_be_bytes(self.data4) as u128
+ }
+
+ /// Creates a `GUID` for a "generic" WinRT type.
+ pub const fn from_signature(signature: imp::ConstBuffer) -> Self {
+ let data = imp::ConstBuffer::from_slice(&[0x11, 0xf4, 0x7a, 0xd5, 0x7b, 0x73, 0x42, 0xc0, 0xab, 0xae, 0x87, 0x8b, 0x1e, 0x16, 0xad, 0xee]);
+
+ let data = data.push_other(signature);
+
+ let bytes = imp::sha1(&data).bytes();
+ let first = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
+
+ let second = u16::from_be_bytes([bytes[4], bytes[5]]);
+ let mut third = u16::from_be_bytes([bytes[6], bytes[7]]);
+ third = (third & 0x0fff) | (5 << 12);
+ let fourth = (bytes[8] & 0x3f) | 0x80;
+
+ Self::from_values(first, second, third, [fourth, bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]])
+ }
+}
+
+impl RuntimeType for GUID {
+ const SIGNATURE: imp::ConstBuffer = imp::ConstBuffer::from_slice(b"g16");
+}
+
+impl TypeKind for GUID {
+ type TypeKind = CopyType;
+}
+
+impl std::fmt::Debug for GUID {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{:08X?}-{:04X?}-{:04X?}-{:02X?}{:02X?}-{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}", self.data1, self.data2, self.data3, self.data4[0], self.data4[1], self.data4[2], self.data4[3], self.data4[4], self.data4[5], self.data4[6], self.data4[7])
+ }
+}
+
+impl std::convert::From<&str> for GUID {
+ fn from(value: &str) -> Self {
+ assert!(value.len() == 36, "Invalid GUID string");
+ let mut bytes = value.bytes();
+
+ let a = ((bytes.next_u32() * 16 + bytes.next_u32()) << 24) + ((bytes.next_u32() * 16 + bytes.next_u32()) << 16) + ((bytes.next_u32() * 16 + bytes.next_u32()) << 8) + bytes.next_u32() * 16 + bytes.next_u32();
+ assert!(bytes.next().unwrap() == b'-', "Invalid GUID string");
+ let b = ((bytes.next_u16() * 16 + (bytes.next_u16())) << 8) + bytes.next_u16() * 16 + bytes.next_u16();
+ assert!(bytes.next().unwrap() == b'-', "Invalid GUID string");
+ let c = ((bytes.next_u16() * 16 + bytes.next_u16()) << 8) + bytes.next_u16() * 16 + bytes.next_u16();
+ assert!(bytes.next().unwrap() == b'-', "Invalid GUID string");
+ let d = bytes.next_u8() * 16 + bytes.next_u8();
+ let e = bytes.next_u8() * 16 + bytes.next_u8();
+ assert!(bytes.next().unwrap() == b'-', "Invalid GUID string");
+
+ let f = bytes.next_u8() * 16 + bytes.next_u8();
+ let g = bytes.next_u8() * 16 + bytes.next_u8();
+ let h = bytes.next_u8() * 16 + bytes.next_u8();
+ let i = bytes.next_u8() * 16 + bytes.next_u8();
+ let j = bytes.next_u8() * 16 + bytes.next_u8();
+ let k = bytes.next_u8() * 16 + bytes.next_u8();
+
+ Self::from_values(a, b, c, [d, e, f, g, h, i, j, k])
+ }
+}
+
+impl std::convert::From<u128> for GUID {
+ fn from(value: u128) -> Self {
+ Self::from_u128(value)
+ }
+}
+
+impl std::convert::From<GUID> for u128 {
+ fn from(value: GUID) -> Self {
+ value.to_u128()
+ }
+}
+
+trait HexReader {
+ fn next_u8(&mut self) -> u8;
+ fn next_u16(&mut self) -> u16;
+ fn next_u32(&mut self) -> u32;
+}
+
+impl HexReader for std::str::Bytes<'_> {
+ fn next_u8(&mut self) -> u8 {
+ let value = self.next().unwrap();
+ match value {
+ b'0'..=b'9' => value - b'0',
+ b'A'..=b'F' => 10 + value - b'A',
+ b'a'..=b'f' => 10 + value - b'a',
+ _ => panic!(),
+ }
+ }
+
+ fn next_u16(&mut self) -> u16 {
+ self.next_u8().into()
+ }
+
+ fn next_u32(&mut self) -> u32 {
+ self.next_u8().into()
+ }
+}
diff --git a/third_party/rust/windows-core/src/hresult.rs b/third_party/rust/windows-core/src/hresult.rs
new file mode 100644
index 0000000000..4ff430f327
--- /dev/null
+++ b/third_party/rust/windows-core/src/hresult.rs
@@ -0,0 +1,140 @@
+use super::*;
+
+/// An error code value returned by most COM functions.
+#[repr(transparent)]
+#[derive(Copy, Clone, Default, Eq, PartialEq)]
+#[must_use]
+#[allow(non_camel_case_types)]
+pub struct HRESULT(pub i32);
+
+impl HRESULT {
+ /// Returns [`true`] if `self` is a success code.
+ #[inline]
+ pub const fn is_ok(self) -> bool {
+ self.0 >= 0
+ }
+
+ /// Returns [`true`] if `self` is a failure code.
+ #[inline]
+ pub const fn is_err(self) -> bool {
+ !self.is_ok()
+ }
+
+ /// Asserts that `self` is a success code.
+ ///
+ /// This will invoke the [`panic!`] macro if `self` is a failure code and display
+ /// the [`HRESULT`] value for diagnostics.
+ #[inline]
+ #[track_caller]
+ pub fn unwrap(self) {
+ assert!(self.is_ok(), "HRESULT 0x{:X}", self.0);
+ }
+
+ /// Converts the [`HRESULT`] to [`Result<()>`][Result<_>].
+ #[inline]
+ pub fn ok(self) -> Result<()> {
+ if self.is_ok() {
+ Ok(())
+ } else {
+ Err(Error::from(self))
+ }
+ }
+
+ /// Returns the [`Option`] as a [`Result`] if the option is a [`Some`] value, returning
+ /// a suitable error if not.
+ pub fn and_some<T: Interface>(self, some: Option<T>) -> Result<T> {
+ if self.is_ok() {
+ if let Some(result) = some {
+ Ok(result)
+ } else {
+ Err(Error::OK)
+ }
+ } else {
+ Err(Error::from(self))
+ }
+ }
+
+ /// Calls `op` if `self` is a success code, otherwise returns [`HRESULT`]
+ /// converted to [`Result<T>`].
+ #[inline]
+ pub fn and_then<F, T>(self, op: F) -> Result<T>
+ where
+ F: FnOnce() -> T,
+ {
+ self.ok()?;
+ Ok(op())
+ }
+
+ /// If the [`Result`] is [`Ok`] converts the `T::Abi` into `T`.
+ ///
+ /// # Safety
+ ///
+ /// Safe to call if
+ /// * `abi` is initialized if `self` is `Ok`
+ /// * `abi` can be safely transmuted to `T`
+ pub unsafe fn from_abi<T: Type<T>>(self, abi: T::Abi) -> Result<T> {
+ if self.is_ok() {
+ T::from_abi(abi)
+ } else {
+ Err(Error::from(self))
+ }
+ }
+
+ /// The error message describing the error.
+ pub fn message(&self) -> HSTRING {
+ let mut message = HeapString(std::ptr::null_mut());
+
+ unsafe {
+ let size = crate::imp::FormatMessageW(crate::imp::FORMAT_MESSAGE_ALLOCATE_BUFFER | crate::imp::FORMAT_MESSAGE_FROM_SYSTEM | crate::imp::FORMAT_MESSAGE_IGNORE_INSERTS, std::ptr::null(), self.0 as u32, 0, &mut message.0 as *mut _ as *mut _, 0, std::ptr::null());
+
+ HSTRING::from_wide(crate::imp::wide_trim_end(std::slice::from_raw_parts(message.0 as *const u16, size as usize))).unwrap_or_default()
+ }
+ }
+
+ /// Maps a Win32 error code to an HRESULT value.
+ pub const fn from_win32(error: u32) -> Self {
+ Self(if error as i32 <= 0 { error } else { (error & 0x0000_FFFF) | (7 << 16) | 0x8000_0000 } as i32)
+ }
+}
+
+impl RuntimeType for HRESULT {
+ const SIGNATURE: crate::imp::ConstBuffer = crate::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.HResult;i32)");
+}
+
+impl TypeKind for HRESULT {
+ type TypeKind = CopyType;
+}
+
+impl<T> std::convert::From<Result<T>> for HRESULT {
+ fn from(result: Result<T>) -> Self {
+ if let Err(error) = result {
+ return error.into();
+ }
+
+ HRESULT(0)
+ }
+}
+
+impl std::fmt::Display for HRESULT {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_fmt(format_args!("{:#010X}", self.0))
+ }
+}
+
+impl std::fmt::Debug for HRESULT {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_fmt(format_args!("HRESULT({})", self))
+ }
+}
+
+struct HeapString(*mut u16);
+
+impl Drop for HeapString {
+ fn drop(&mut self) {
+ if !self.0.is_null() {
+ unsafe {
+ crate::imp::heap_free(self.0 as _);
+ }
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/bindings.rs b/third_party/rust/windows-core/src/imp/bindings.rs
new file mode 100644
index 0000000000..840d673648
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/bindings.rs
@@ -0,0 +1,53 @@
+// Bindings generated by `windows-bindgen` 0.52.0
+
+#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
+::windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
+::windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
+::windows_targets::link!("kernel32.dll" "system" fn EncodePointer(ptr : *const ::core::ffi::c_void) -> *mut ::core::ffi::c_void);
+::windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const ::core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32);
+::windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL);
+::windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR);
+::windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC);
+::windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> HANDLE);
+::windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap : HANDLE, dwflags : HEAP_FLAGS, dwbytes : usize) -> *mut ::core::ffi::c_void);
+::windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap : HANDLE, dwflags : HEAP_FLAGS, lpmem : *const ::core::ffi::c_void) -> BOOL);
+::windows_targets::link!("kernel32.dll" "system" fn LoadLibraryExA(lplibfilename : PCSTR, hfile : HANDLE, dwflags : LOAD_LIBRARY_FLAGS) -> HMODULE);
+::windows_targets::link!("kernel32.dll" "system" fn SetEvent(hevent : HANDLE) -> BOOL);
+::windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
+::windows_targets::link!("ole32.dll" "system" fn CoTaskMemAlloc(cb : usize) -> *mut ::core::ffi::c_void);
+::windows_targets::link!("ole32.dll" "system" fn CoTaskMemFree(pv : *const ::core::ffi::c_void) -> ());
+::windows_targets::link!("oleaut32.dll" "system" fn SysAllocStringLen(strin : PCWSTR, ui : u32) -> BSTR);
+::windows_targets::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR) -> ());
+::windows_targets::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32);
+pub type BOOL = i32;
+pub type BSTR = *const u16;
+pub const ERROR_NO_UNICODE_TRANSLATION: WIN32_ERROR = 1113u32;
+pub const E_INVALIDARG: HRESULT = -2147024809i32;
+pub type FARPROC = ::core::option::Option<unsafe extern "system" fn() -> isize>;
+pub const FORMAT_MESSAGE_ALLOCATE_BUFFER: FORMAT_MESSAGE_OPTIONS = 256u32;
+pub const FORMAT_MESSAGE_FROM_SYSTEM: FORMAT_MESSAGE_OPTIONS = 4096u32;
+pub const FORMAT_MESSAGE_IGNORE_INSERTS: FORMAT_MESSAGE_OPTIONS = 512u32;
+pub type FORMAT_MESSAGE_OPTIONS = u32;
+pub type HANDLE = isize;
+pub type HEAP_FLAGS = u32;
+pub type HMODULE = isize;
+pub type HRESULT = i32;
+pub type LOAD_LIBRARY_FLAGS = u32;
+pub const LOAD_LIBRARY_SEARCH_DEFAULT_DIRS: LOAD_LIBRARY_FLAGS = 4096u32;
+pub type PCSTR = *const u8;
+pub type PCWSTR = *const u16;
+pub type PWSTR = *mut u16;
+#[repr(C)]
+pub struct SECURITY_ATTRIBUTES {
+ pub nLength: u32,
+ pub lpSecurityDescriptor: *mut ::core::ffi::c_void,
+ pub bInheritHandle: BOOL,
+}
+impl ::core::marker::Copy for SECURITY_ATTRIBUTES {}
+impl ::core::clone::Clone for SECURITY_ATTRIBUTES {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+pub type WAIT_EVENT = u32;
+pub type WIN32_ERROR = u32;
diff --git a/third_party/rust/windows-core/src/imp/com_bindings.rs b/third_party/rust/windows-core/src/imp/com_bindings.rs
new file mode 100644
index 0000000000..5a4c2bd15d
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/com_bindings.rs
@@ -0,0 +1,1370 @@
+// Bindings generated by `windows-bindgen` 0.52.0
+
+#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
+#[inline]
+pub unsafe fn CoCreateGuid() -> ::windows_core::Result<::windows_core::GUID> {
+ ::windows_targets::link!("ole32.dll" "system" fn CoCreateGuid(pguid : *mut ::windows_core::GUID) -> ::windows_core::HRESULT);
+ let mut result__ = ::std::mem::zeroed();
+ CoCreateGuid(&mut result__).from_abi(result__)
+}
+#[inline]
+pub unsafe fn RoGetAgileReference<P0>(options: AgileReferenceOptions, riid: *const ::windows_core::GUID, punk: P0) -> ::windows_core::Result<IAgileReference>
+where
+ P0: ::windows_core::IntoParam<::windows_core::IUnknown>,
+{
+ ::windows_targets::link!("ole32.dll" "system" fn RoGetAgileReference(options : AgileReferenceOptions, riid : *const ::windows_core::GUID, punk : * mut::core::ffi::c_void, ppagilereference : *mut * mut::core::ffi::c_void) -> ::windows_core::HRESULT);
+ let mut result__ = ::std::mem::zeroed();
+ RoGetAgileReference(options, riid, punk.into_param().abi(), &mut result__).from_abi(result__)
+}
+#[inline]
+pub unsafe fn GetErrorInfo(dwreserved: u32) -> ::windows_core::Result<IErrorInfo> {
+ ::windows_targets::link!("oleaut32.dll" "system" fn GetErrorInfo(dwreserved : u32, pperrinfo : *mut * mut::core::ffi::c_void) -> ::windows_core::HRESULT);
+ let mut result__ = ::std::mem::zeroed();
+ GetErrorInfo(dwreserved, &mut result__).from_abi(result__)
+}
+#[inline]
+pub unsafe fn SetErrorInfo<P0>(dwreserved: u32, perrinfo: P0) -> ::windows_core::Result<()>
+where
+ P0: ::windows_core::IntoParam<IErrorInfo>,
+{
+ ::windows_targets::link!("oleaut32.dll" "system" fn SetErrorInfo(dwreserved : u32, perrinfo : * mut::core::ffi::c_void) -> ::windows_core::HRESULT);
+ SetErrorInfo(dwreserved, perrinfo.into_param().abi()).ok()
+}
+pub const AGILEREFERENCE_DEFAULT: AgileReferenceOptions = AgileReferenceOptions(0i32);
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
+pub struct AgileReferenceOptions(pub i32);
+impl ::core::marker::Copy for AgileReferenceOptions {}
+impl ::core::clone::Clone for AgileReferenceOptions {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::default::Default for AgileReferenceOptions {
+ fn default() -> Self {
+ Self(0)
+ }
+}
+impl ::windows_core::TypeKind for AgileReferenceOptions {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::core::fmt::Debug for AgileReferenceOptions {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_tuple("AgileReferenceOptions").field(&self.0).finish()
+ }
+}
+pub const CLASS_E_CLASSNOTAVAILABLE: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147221231i32);
+pub const CO_E_NOTINITIALIZED: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147221008i32);
+#[repr(C)]
+pub struct DateTime {
+ pub UniversalTime: i64,
+}
+impl ::core::marker::Copy for DateTime {}
+impl ::core::clone::Clone for DateTime {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::fmt::Debug for DateTime {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct("DateTime").field("UniversalTime", &self.UniversalTime).finish()
+ }
+}
+impl ::windows_core::TypeKind for DateTime {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::windows_core::RuntimeType for DateTime {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.DateTime;i8)");
+}
+impl ::core::cmp::PartialEq for DateTime {
+ fn eq(&self, other: &Self) -> bool {
+ self.UniversalTime == other.UniversalTime
+ }
+}
+impl ::core::cmp::Eq for DateTime {}
+impl ::core::default::Default for DateTime {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
+pub const E_BOUNDS: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147483637i32);
+pub const E_NOINTERFACE: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147467262i32);
+pub const E_OUTOFMEMORY: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147024882i32);
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IAgileObject(::windows_core::IUnknown);
+impl IAgileObject {}
+::windows_core::imp::interface_hierarchy!(IAgileObject, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IAgileObject {
+ type Vtable = IAgileObject_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IAgileObject {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x94ea2b94_e9cc_49e0_c0ff_ee64ca8f5b90);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IAgileObject_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IAgileReference(::windows_core::IUnknown);
+impl IAgileReference {
+ pub unsafe fn Resolve<T>(&self) -> ::windows_core::Result<T>
+ where
+ T: ::windows_core::ComInterface,
+ {
+ let mut result__ = ::std::ptr::null_mut();
+ (::windows_core::Interface::vtable(self).Resolve)(::windows_core::Interface::as_raw(self), &<T as ::windows_core::ComInterface>::IID, &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(IAgileReference, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IAgileReference {
+ type Vtable = IAgileReference_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IAgileReference {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0xc03f6a43_65a4_9818_987e_e0b810d2a6f2);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IAgileReference_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub Resolve: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, riid: *const ::windows_core::GUID, ppvobjectreference: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IErrorInfo(::windows_core::IUnknown);
+impl IErrorInfo {
+ pub unsafe fn GetGUID(&self) -> ::windows_core::Result<::windows_core::GUID> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetGUID)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn GetSource(&self) -> ::windows_core::Result<::windows_core::BSTR> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetSource)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn GetDescription(&self) -> ::windows_core::Result<::windows_core::BSTR> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetDescription)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn GetHelpFile(&self) -> ::windows_core::Result<::windows_core::BSTR> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetHelpFile)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn GetHelpContext(&self) -> ::windows_core::Result<u32> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetHelpContext)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(IErrorInfo, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IErrorInfo {
+ type Vtable = IErrorInfo_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IErrorInfo {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x1cf2b120_547d_101b_8e65_08002b2bd119);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IErrorInfo_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub GetGUID: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, pguid: *mut ::windows_core::GUID) -> ::windows_core::HRESULT,
+ pub GetSource: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, pbstrsource: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>) -> ::windows_core::HRESULT,
+ pub GetDescription: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, pbstrdescription: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>) -> ::windows_core::HRESULT,
+ pub GetHelpFile: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, pbstrhelpfile: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>) -> ::windows_core::HRESULT,
+ pub GetHelpContext: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, pdwhelpcontext: *mut u32) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct ILanguageExceptionErrorInfo(::windows_core::IUnknown);
+impl ILanguageExceptionErrorInfo {
+ pub unsafe fn GetLanguageException(&self) -> ::windows_core::Result<::windows_core::IUnknown> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetLanguageException)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(ILanguageExceptionErrorInfo, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for ILanguageExceptionErrorInfo {
+ type Vtable = ILanguageExceptionErrorInfo_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for ILanguageExceptionErrorInfo {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x04a2dbf3_df83_116c_0946_0812abf6e07d);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct ILanguageExceptionErrorInfo_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub GetLanguageException: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, languageexception: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct ILanguageExceptionErrorInfo2(::windows_core::IUnknown);
+impl ILanguageExceptionErrorInfo2 {
+ pub unsafe fn GetLanguageException(&self) -> ::windows_core::Result<::windows_core::IUnknown> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).base__.GetLanguageException)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn GetPreviousLanguageExceptionErrorInfo(&self) -> ::windows_core::Result<ILanguageExceptionErrorInfo2> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetPreviousLanguageExceptionErrorInfo)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+ pub unsafe fn CapturePropagationContext<P0>(&self, languageexception: P0) -> ::windows_core::Result<()>
+ where
+ P0: ::windows_core::IntoParam<::windows_core::IUnknown>,
+ {
+ (::windows_core::Interface::vtable(self).CapturePropagationContext)(::windows_core::Interface::as_raw(self), languageexception.into_param().abi()).ok()
+ }
+ pub unsafe fn GetPropagationContextHead(&self) -> ::windows_core::Result<ILanguageExceptionErrorInfo2> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetPropagationContextHead)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(ILanguageExceptionErrorInfo2, ::windows_core::IUnknown, ILanguageExceptionErrorInfo);
+unsafe impl ::windows_core::Interface for ILanguageExceptionErrorInfo2 {
+ type Vtable = ILanguageExceptionErrorInfo2_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for ILanguageExceptionErrorInfo2 {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x5746e5c4_5b97_424c_b620_2822915734dd);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct ILanguageExceptionErrorInfo2_Vtbl {
+ pub base__: ILanguageExceptionErrorInfo_Vtbl,
+ pub GetPreviousLanguageExceptionErrorInfo: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, previouslanguageexceptionerrorinfo: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CapturePropagationContext: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, languageexception: *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub GetPropagationContextHead: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, propagatedlanguageexceptionerrorinfohead: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IPropertyValue(::windows_core::IUnknown);
+impl IPropertyValue {
+ pub fn Type(&self) -> ::windows_core::Result<PropertyType> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).Type)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn IsNumericScalar(&self) -> ::windows_core::Result<bool> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).IsNumericScalar)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt8(&self) -> ::windows_core::Result<u8> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt8)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt16(&self) -> ::windows_core::Result<i16> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt16(&self) -> ::windows_core::Result<u16> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt32(&self) -> ::windows_core::Result<i32> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt32)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt32(&self) -> ::windows_core::Result<u32> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt32)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt64(&self) -> ::windows_core::Result<i64> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt64)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt64(&self) -> ::windows_core::Result<u64> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt64)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetSingle(&self) -> ::windows_core::Result<f32> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetSingle)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetDouble(&self) -> ::windows_core::Result<f64> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetDouble)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetChar16(&self) -> ::windows_core::Result<u16> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetChar16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetBoolean(&self) -> ::windows_core::Result<bool> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetBoolean)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetString(&self) -> ::windows_core::Result<::windows_core::HSTRING> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetString)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetGuid(&self) -> ::windows_core::Result<::windows_core::GUID> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetGuid)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetDateTime(&self) -> ::windows_core::Result<DateTime> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetDateTime)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetTimeSpan(&self) -> ::windows_core::Result<TimeSpan> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetTimeSpan)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetPoint(&self) -> ::windows_core::Result<Point> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetPoint)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetSize(&self) -> ::windows_core::Result<Size> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetSize)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetRect(&self) -> ::windows_core::Result<Rect> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetRect)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt8Array(&self, value: &mut ::windows_core::Array<u8>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt8Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt16Array(&self, value: &mut ::windows_core::Array<i16>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt16Array(&self, value: &mut ::windows_core::Array<u16>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt32Array(&self, value: &mut ::windows_core::Array<i32>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt32Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt32Array(&self, value: &mut ::windows_core::Array<u32>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt32Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt64Array(&self, value: &mut ::windows_core::Array<i64>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt64Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt64Array(&self, value: &mut ::windows_core::Array<u64>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt64Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetSingleArray(&self, value: &mut ::windows_core::Array<f32>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetSingleArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetDoubleArray(&self, value: &mut ::windows_core::Array<f64>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetDoubleArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetChar16Array(&self, value: &mut ::windows_core::Array<u16>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetChar16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetBooleanArray(&self, value: &mut ::windows_core::Array<bool>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetBooleanArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetStringArray(&self, value: &mut ::windows_core::Array<::windows_core::HSTRING>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetStringArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInspectableArray(&self, value: &mut ::windows_core::Array<::windows_core::IInspectable>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetInspectableArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetGuidArray(&self, value: &mut ::windows_core::Array<::windows_core::GUID>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetGuidArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetDateTimeArray(&self, value: &mut ::windows_core::Array<DateTime>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetDateTimeArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetTimeSpanArray(&self, value: &mut ::windows_core::Array<TimeSpan>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetTimeSpanArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetPointArray(&self, value: &mut ::windows_core::Array<Point>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetPointArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetSizeArray(&self, value: &mut ::windows_core::Array<Size>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetSizeArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetRectArray(&self, value: &mut ::windows_core::Array<Rect>) -> ::windows_core::Result<()> {
+ let this = self;
+ unsafe { (::windows_core::Interface::vtable(this).GetRectArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+}
+::windows_core::imp::interface_hierarchy!(IPropertyValue, ::windows_core::IUnknown, ::windows_core::IInspectable);
+impl ::windows_core::RuntimeType for IPropertyValue {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"{4bd682dd-7554-40e9-9a9b-82654ede7e62}");
+}
+unsafe impl ::windows_core::Interface for IPropertyValue {
+ type Vtable = IPropertyValue_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IPropertyValue {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x4bd682dd_7554_40e9_9a9b_82654ede7e62);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IPropertyValue_Vtbl {
+ pub base__: ::windows_core::IInspectable_Vtbl,
+ pub Type: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut PropertyType) -> ::windows_core::HRESULT,
+ pub IsNumericScalar: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut bool) -> ::windows_core::HRESULT,
+ pub GetUInt8: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut u8) -> ::windows_core::HRESULT,
+ pub GetInt16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut i16) -> ::windows_core::HRESULT,
+ pub GetUInt16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut u16) -> ::windows_core::HRESULT,
+ pub GetInt32: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut i32) -> ::windows_core::HRESULT,
+ pub GetUInt32: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut u32) -> ::windows_core::HRESULT,
+ pub GetInt64: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut i64) -> ::windows_core::HRESULT,
+ pub GetUInt64: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut u64) -> ::windows_core::HRESULT,
+ pub GetSingle: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut f32) -> ::windows_core::HRESULT,
+ pub GetDouble: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut f64) -> ::windows_core::HRESULT,
+ pub GetChar16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut u16) -> ::windows_core::HRESULT,
+ pub GetBoolean: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut bool) -> ::windows_core::HRESULT,
+ pub GetString: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut ::std::mem::MaybeUninit<::windows_core::HSTRING>) -> ::windows_core::HRESULT,
+ pub GetGuid: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut ::windows_core::GUID) -> ::windows_core::HRESULT,
+ pub GetDateTime: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut DateTime) -> ::windows_core::HRESULT,
+ pub GetTimeSpan: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut TimeSpan) -> ::windows_core::HRESULT,
+ pub GetPoint: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut Point) -> ::windows_core::HRESULT,
+ pub GetSize: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut Size) -> ::windows_core::HRESULT,
+ pub GetRect: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut Rect) -> ::windows_core::HRESULT,
+ pub GetUInt8Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> ::windows_core::HRESULT,
+ pub GetInt16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut i16) -> ::windows_core::HRESULT,
+ pub GetUInt16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u16) -> ::windows_core::HRESULT,
+ pub GetInt32Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut i32) -> ::windows_core::HRESULT,
+ pub GetUInt32Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u32) -> ::windows_core::HRESULT,
+ pub GetInt64Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut i64) -> ::windows_core::HRESULT,
+ pub GetUInt64Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u64) -> ::windows_core::HRESULT,
+ pub GetSingleArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut f32) -> ::windows_core::HRESULT,
+ pub GetDoubleArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut f64) -> ::windows_core::HRESULT,
+ pub GetChar16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u16) -> ::windows_core::HRESULT,
+ pub GetBooleanArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut bool) -> ::windows_core::HRESULT,
+ pub GetStringArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut ::std::mem::MaybeUninit<::windows_core::HSTRING>) -> ::windows_core::HRESULT,
+ pub GetInspectableArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub GetGuidArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut ::windows_core::GUID) -> ::windows_core::HRESULT,
+ pub GetDateTimeArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut DateTime) -> ::windows_core::HRESULT,
+ pub GetTimeSpanArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut TimeSpan) -> ::windows_core::HRESULT,
+ pub GetPointArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut Point) -> ::windows_core::HRESULT,
+ pub GetSizeArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut Size) -> ::windows_core::HRESULT,
+ pub GetRectArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut Rect) -> ::windows_core::HRESULT,
+}
+#[doc(hidden)]
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IPropertyValueStatics(::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IPropertyValueStatics {
+ type Vtable = IPropertyValueStatics_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IPropertyValueStatics {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x629bdbc8_d932_4ff4_96b9_8d96c5c1e858);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IPropertyValueStatics_Vtbl {
+ pub base__: ::windows_core::IInspectable_Vtbl,
+ pub CreateEmpty: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt8: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: u8, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: i16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: u16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt32: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: i32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt32: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: u32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt64: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: i64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt64: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: u64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateSingle: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: f32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateDouble: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: f64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateChar16: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: u16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateBoolean: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: bool, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateString: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: ::std::mem::MaybeUninit<::windows_core::HSTRING>, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInspectable: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: *mut ::core::ffi::c_void, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateGuid: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: ::windows_core::GUID, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateDateTime: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: DateTime, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateTimeSpan: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: TimeSpan, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreatePoint: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: Point, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateSize: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: Size, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateRect: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value: Rect, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt8Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const u8, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const i16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const u16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt32Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const i32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt32Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const u32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInt64Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const i64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateUInt64Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const u64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateSingleArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const f32, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateDoubleArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const f64, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateChar16Array: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const u16, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateBooleanArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const bool, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateStringArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const ::std::mem::MaybeUninit<::windows_core::HSTRING>, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateInspectableArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const *mut ::core::ffi::c_void, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateGuidArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const ::windows_core::GUID, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateDateTimeArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const DateTime, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateTimeSpanArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const TimeSpan, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreatePointArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const Point, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateSizeArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const Size, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+ pub CreateRectArray: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, value_array_size: u32, value: *const Rect, result__: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IReference<T>(::windows_core::IUnknown, ::core::marker::PhantomData<T>)
+where
+ T: ::windows_core::RuntimeType + 'static;
+impl<T: ::windows_core::RuntimeType + 'static> IReference<T> {
+ pub fn Value(&self) -> ::windows_core::Result<T> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).Value)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn Type(&self) -> ::windows_core::Result<PropertyType> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).Type)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn IsNumericScalar(&self) -> ::windows_core::Result<bool> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).IsNumericScalar)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt8(&self) -> ::windows_core::Result<u8> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt8)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt16(&self) -> ::windows_core::Result<i16> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt16(&self) -> ::windows_core::Result<u16> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt32(&self) -> ::windows_core::Result<i32> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt32)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt32(&self) -> ::windows_core::Result<u32> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt32)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetInt64(&self) -> ::windows_core::Result<i64> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetInt64)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt64(&self) -> ::windows_core::Result<u64> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetUInt64)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetSingle(&self) -> ::windows_core::Result<f32> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetSingle)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetDouble(&self) -> ::windows_core::Result<f64> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetDouble)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetChar16(&self) -> ::windows_core::Result<u16> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetChar16)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetBoolean(&self) -> ::windows_core::Result<bool> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetBoolean)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetString(&self) -> ::windows_core::Result<::windows_core::HSTRING> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetString)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetGuid(&self) -> ::windows_core::Result<::windows_core::GUID> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetGuid)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetDateTime(&self) -> ::windows_core::Result<DateTime> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetDateTime)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetTimeSpan(&self) -> ::windows_core::Result<TimeSpan> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetTimeSpan)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetPoint(&self) -> ::windows_core::Result<Point> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetPoint)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetSize(&self) -> ::windows_core::Result<Size> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetSize)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetRect(&self) -> ::windows_core::Result<Rect> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).GetRect)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+ pub fn GetUInt8Array(&self, value: &mut ::windows_core::Array<u8>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt8Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt16Array(&self, value: &mut ::windows_core::Array<i16>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt16Array(&self, value: &mut ::windows_core::Array<u16>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt32Array(&self, value: &mut ::windows_core::Array<i32>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt32Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt32Array(&self, value: &mut ::windows_core::Array<u32>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt32Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInt64Array(&self, value: &mut ::windows_core::Array<i64>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetInt64Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetUInt64Array(&self, value: &mut ::windows_core::Array<u64>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetUInt64Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetSingleArray(&self, value: &mut ::windows_core::Array<f32>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetSingleArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetDoubleArray(&self, value: &mut ::windows_core::Array<f64>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetDoubleArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetChar16Array(&self, value: &mut ::windows_core::Array<u16>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetChar16Array)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetBooleanArray(&self, value: &mut ::windows_core::Array<bool>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetBooleanArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetStringArray(&self, value: &mut ::windows_core::Array<::windows_core::HSTRING>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetStringArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetInspectableArray(&self, value: &mut ::windows_core::Array<::windows_core::IInspectable>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetInspectableArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetGuidArray(&self, value: &mut ::windows_core::Array<::windows_core::GUID>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetGuidArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetDateTimeArray(&self, value: &mut ::windows_core::Array<DateTime>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetDateTimeArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetTimeSpanArray(&self, value: &mut ::windows_core::Array<TimeSpan>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetTimeSpanArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetPointArray(&self, value: &mut ::windows_core::Array<Point>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetPointArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetSizeArray(&self, value: &mut ::windows_core::Array<Size>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetSizeArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+ pub fn GetRectArray(&self, value: &mut ::windows_core::Array<Rect>) -> ::windows_core::Result<()> {
+ let this = &::windows_core::ComInterface::cast::<IPropertyValue>(self)?;
+ unsafe { (::windows_core::Interface::vtable(this).GetRectArray)(::windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() }
+ }
+}
+impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::CanInto<::windows_core::IUnknown> for IReference<T> {}
+impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::CanInto<::windows_core::IInspectable> for IReference<T> {}
+impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::CanTryInto<IPropertyValue> for IReference<T> {}
+impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::RuntimeType for IReference<T> {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = { ::windows_core::imp::ConstBuffer::new().push_slice(b"pinterface(").push_slice(b"{61c17706-2d65-11e0-9ae8-d48564015472}").push_slice(b";").push_other(<T as ::windows_core::RuntimeType>::SIGNATURE).push_slice(b")") };
+}
+unsafe impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::Interface for IReference<T> {
+ type Vtable = IReference_Vtbl<T>;
+}
+unsafe impl<T: ::windows_core::RuntimeType + 'static> ::windows_core::ComInterface for IReference<T> {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_signature(<Self as ::windows_core::RuntimeType>::SIGNATURE);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IReference_Vtbl<T>
+where
+ T: ::windows_core::RuntimeType + 'static,
+{
+ pub base__: ::windows_core::IInspectable_Vtbl,
+ pub Value: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut ::windows_core::AbiType<T>) -> ::windows_core::HRESULT,
+ pub T: ::core::marker::PhantomData<T>,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IRestrictedErrorInfo(::windows_core::IUnknown);
+impl IRestrictedErrorInfo {
+ pub unsafe fn GetErrorDetails(&self, description: *mut ::windows_core::BSTR, error: *mut ::windows_core::HRESULT, restricteddescription: *mut ::windows_core::BSTR, capabilitysid: *mut ::windows_core::BSTR) -> ::windows_core::Result<()> {
+ (::windows_core::Interface::vtable(self).GetErrorDetails)(::windows_core::Interface::as_raw(self), ::core::mem::transmute(description), error, ::core::mem::transmute(restricteddescription), ::core::mem::transmute(capabilitysid)).ok()
+ }
+ pub unsafe fn GetReference(&self) -> ::windows_core::Result<::windows_core::BSTR> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetReference)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(IRestrictedErrorInfo, ::windows_core::IUnknown);
+unsafe impl ::core::marker::Send for IRestrictedErrorInfo {}
+unsafe impl ::core::marker::Sync for IRestrictedErrorInfo {}
+unsafe impl ::windows_core::Interface for IRestrictedErrorInfo {
+ type Vtable = IRestrictedErrorInfo_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IRestrictedErrorInfo {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x82ba7092_4c88_427d_a7bc_16dd93feb67e);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IRestrictedErrorInfo_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub GetErrorDetails: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, description: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>, error: *mut ::windows_core::HRESULT, restricteddescription: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>, capabilitysid: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>) -> ::windows_core::HRESULT,
+ pub GetReference: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, reference: *mut ::std::mem::MaybeUninit<::windows_core::BSTR>) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IStringable(::windows_core::IUnknown);
+impl IStringable {
+ pub fn ToString(&self) -> ::windows_core::Result<::windows_core::HSTRING> {
+ let this = self;
+ unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).ToString)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ }
+ }
+}
+::windows_core::imp::interface_hierarchy!(IStringable, ::windows_core::IUnknown, ::windows_core::IInspectable);
+impl ::windows_core::RuntimeType for IStringable {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"{96369f54-8eb6-48f0-abce-c1b211e627c3}");
+}
+unsafe impl ::windows_core::Interface for IStringable {
+ type Vtable = IStringable_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IStringable {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x96369f54_8eb6_48f0_abce_c1b211e627c3);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IStringable_Vtbl {
+ pub base__: ::windows_core::IInspectable_Vtbl,
+ pub ToString: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, result__: *mut ::std::mem::MaybeUninit<::windows_core::HSTRING>) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IWeakReference(::windows_core::IUnknown);
+impl IWeakReference {
+ pub unsafe fn Resolve<T>(&self) -> ::windows_core::Result<T>
+ where
+ T: ::windows_core::ComInterface,
+ {
+ let mut result__ = ::std::ptr::null_mut();
+ (::windows_core::Interface::vtable(self).Resolve)(::windows_core::Interface::as_raw(self), &<T as ::windows_core::ComInterface>::IID, &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(IWeakReference, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IWeakReference {
+ type Vtable = IWeakReference_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IWeakReference {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x00000037_0000_0000_c000_000000000046);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IWeakReference_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub Resolve: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, riid: *const ::windows_core::GUID, objectreference: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq, ::core::fmt::Debug, ::core::clone::Clone)]
+pub struct IWeakReferenceSource(::windows_core::IUnknown);
+impl IWeakReferenceSource {
+ pub unsafe fn GetWeakReference(&self) -> ::windows_core::Result<IWeakReference> {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self).GetWeakReference)(::windows_core::Interface::as_raw(self), &mut result__).from_abi(result__)
+ }
+}
+::windows_core::imp::interface_hierarchy!(IWeakReferenceSource, ::windows_core::IUnknown);
+unsafe impl ::windows_core::Interface for IWeakReferenceSource {
+ type Vtable = IWeakReferenceSource_Vtbl;
+}
+unsafe impl ::windows_core::ComInterface for IWeakReferenceSource {
+ const IID: ::windows_core::GUID = ::windows_core::GUID::from_u128(0x00000038_0000_0000_c000_000000000046);
+}
+#[repr(C)]
+#[doc(hidden)]
+pub struct IWeakReferenceSource_Vtbl {
+ pub base__: ::windows_core::IUnknown_Vtbl,
+ pub GetWeakReference: unsafe extern "system" fn(this: *mut ::core::ffi::c_void, weakreference: *mut *mut ::core::ffi::c_void) -> ::windows_core::HRESULT,
+}
+pub const JSCRIPT_E_CANTEXECUTE: ::windows_core::HRESULT = ::windows_core::HRESULT(-1996357631i32);
+#[repr(C)]
+pub struct Point {
+ pub X: f32,
+ pub Y: f32,
+}
+impl ::core::marker::Copy for Point {}
+impl ::core::clone::Clone for Point {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::fmt::Debug for Point {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct("Point").field("X", &self.X).field("Y", &self.Y).finish()
+ }
+}
+impl ::windows_core::TypeKind for Point {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::windows_core::RuntimeType for Point {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.Point;f4;f4)");
+}
+impl ::core::cmp::PartialEq for Point {
+ fn eq(&self, other: &Self) -> bool {
+ self.X == other.X && self.Y == other.Y
+ }
+}
+impl ::core::cmp::Eq for Point {}
+impl ::core::default::Default for Point {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
+#[repr(transparent)]
+#[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
+pub struct PropertyType(pub i32);
+impl PropertyType {
+ pub const Empty: Self = Self(0i32);
+ pub const UInt8: Self = Self(1i32);
+ pub const Int16: Self = Self(2i32);
+ pub const UInt16: Self = Self(3i32);
+ pub const Int32: Self = Self(4i32);
+ pub const UInt32: Self = Self(5i32);
+ pub const Int64: Self = Self(6i32);
+ pub const UInt64: Self = Self(7i32);
+ pub const Single: Self = Self(8i32);
+ pub const Double: Self = Self(9i32);
+ pub const Char16: Self = Self(10i32);
+ pub const Boolean: Self = Self(11i32);
+ pub const String: Self = Self(12i32);
+ pub const Inspectable: Self = Self(13i32);
+ pub const DateTime: Self = Self(14i32);
+ pub const TimeSpan: Self = Self(15i32);
+ pub const Guid: Self = Self(16i32);
+ pub const Point: Self = Self(17i32);
+ pub const Size: Self = Self(18i32);
+ pub const Rect: Self = Self(19i32);
+ pub const OtherType: Self = Self(20i32);
+ pub const UInt8Array: Self = Self(1025i32);
+ pub const Int16Array: Self = Self(1026i32);
+ pub const UInt16Array: Self = Self(1027i32);
+ pub const Int32Array: Self = Self(1028i32);
+ pub const UInt32Array: Self = Self(1029i32);
+ pub const Int64Array: Self = Self(1030i32);
+ pub const UInt64Array: Self = Self(1031i32);
+ pub const SingleArray: Self = Self(1032i32);
+ pub const DoubleArray: Self = Self(1033i32);
+ pub const Char16Array: Self = Self(1034i32);
+ pub const BooleanArray: Self = Self(1035i32);
+ pub const StringArray: Self = Self(1036i32);
+ pub const InspectableArray: Self = Self(1037i32);
+ pub const DateTimeArray: Self = Self(1038i32);
+ pub const TimeSpanArray: Self = Self(1039i32);
+ pub const GuidArray: Self = Self(1040i32);
+ pub const PointArray: Self = Self(1041i32);
+ pub const SizeArray: Self = Self(1042i32);
+ pub const RectArray: Self = Self(1043i32);
+ pub const OtherTypeArray: Self = Self(1044i32);
+}
+impl ::core::marker::Copy for PropertyType {}
+impl ::core::clone::Clone for PropertyType {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::default::Default for PropertyType {
+ fn default() -> Self {
+ Self(0)
+ }
+}
+impl ::windows_core::TypeKind for PropertyType {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::core::fmt::Debug for PropertyType {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_tuple("PropertyType").field(&self.0).finish()
+ }
+}
+impl ::windows_core::RuntimeType for PropertyType {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Foundation.PropertyType;i4)");
+}
+pub struct PropertyValue;
+impl PropertyValue {
+ pub fn CreateEmpty() -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateEmpty)(::windows_core::Interface::as_raw(this), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt8(value: u8) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt8)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt16(value: i16) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt16)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt16(value: u16) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt16)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt32(value: i32) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt32)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt32(value: u32) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt32)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt64(value: i64) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt64)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt64(value: u64) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt64)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateSingle(value: f32) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateSingle)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateDouble(value: f64) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateDouble)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateChar16(value: u16) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateChar16)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateBoolean(value: bool) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateBoolean)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateString(value: &::windows_core::HSTRING) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateString)(::windows_core::Interface::as_raw(this), ::core::mem::transmute_copy(value), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInspectable<P0>(value: P0) -> ::windows_core::Result<::windows_core::IInspectable>
+ where
+ P0: ::windows_core::IntoParam<::windows_core::IInspectable>,
+ {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInspectable)(::windows_core::Interface::as_raw(this), value.into_param().abi(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateGuid(value: ::windows_core::GUID) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateGuid)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateDateTime(value: DateTime) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateDateTime)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateTimeSpan(value: TimeSpan) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateTimeSpan)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreatePoint(value: Point) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreatePoint)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateSize(value: Size) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateSize)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateRect(value: Rect) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateRect)(::windows_core::Interface::as_raw(this), value, &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt8Array(value: &[u8]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt8Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt16Array(value: &[i16]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt16Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt16Array(value: &[u16]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt16Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt32Array(value: &[i32]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt32Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt32Array(value: &[u32]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt32Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInt64Array(value: &[i64]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInt64Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateUInt64Array(value: &[u64]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateUInt64Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateSingleArray(value: &[f32]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateSingleArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateDoubleArray(value: &[f64]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateDoubleArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateChar16Array(value: &[u16]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateChar16Array)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateBooleanArray(value: &[bool]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateBooleanArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateStringArray(value: &[::windows_core::HSTRING]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateStringArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), ::core::mem::transmute(value.as_ptr()), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateInspectableArray(value: &[::core::option::Option<::windows_core::IInspectable>]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateInspectableArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), ::core::mem::transmute(value.as_ptr()), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateGuidArray(value: &[::windows_core::GUID]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateGuidArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateDateTimeArray(value: &[DateTime]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateDateTimeArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateTimeSpanArray(value: &[TimeSpan]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateTimeSpanArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreatePointArray(value: &[Point]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreatePointArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateSizeArray(value: &[Size]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateSizeArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ pub fn CreateRectArray(value: &[Rect]) -> ::windows_core::Result<::windows_core::IInspectable> {
+ Self::IPropertyValueStatics(|this| unsafe {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).CreateRectArray)(::windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr(), &mut result__).from_abi(result__)
+ })
+ }
+ #[doc(hidden)]
+ pub fn IPropertyValueStatics<R, F: FnOnce(&IPropertyValueStatics) -> ::windows_core::Result<R>>(callback: F) -> ::windows_core::Result<R> {
+ static SHARED: ::windows_core::imp::FactoryCache<PropertyValue, IPropertyValueStatics> = ::windows_core::imp::FactoryCache::new();
+ SHARED.call(callback)
+ }
+}
+impl ::windows_core::RuntimeName for PropertyValue {
+ const NAME: &'static str = "Windows.Foundation.PropertyValue";
+}
+pub const RPC_E_DISCONNECTED: ::windows_core::HRESULT = ::windows_core::HRESULT(-2147417848i32);
+#[repr(C)]
+pub struct Rect {
+ pub X: f32,
+ pub Y: f32,
+ pub Width: f32,
+ pub Height: f32,
+}
+impl ::core::marker::Copy for Rect {}
+impl ::core::clone::Clone for Rect {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::fmt::Debug for Rect {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct("Rect").field("X", &self.X).field("Y", &self.Y).field("Width", &self.Width).field("Height", &self.Height).finish()
+ }
+}
+impl ::windows_core::TypeKind for Rect {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::windows_core::RuntimeType for Rect {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.Rect;f4;f4;f4;f4)");
+}
+impl ::core::cmp::PartialEq for Rect {
+ fn eq(&self, other: &Self) -> bool {
+ self.X == other.X && self.Y == other.Y && self.Width == other.Width && self.Height == other.Height
+ }
+}
+impl ::core::cmp::Eq for Rect {}
+impl ::core::default::Default for Rect {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
+#[repr(C)]
+pub struct Size {
+ pub Width: f32,
+ pub Height: f32,
+}
+impl ::core::marker::Copy for Size {}
+impl ::core::clone::Clone for Size {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::fmt::Debug for Size {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct("Size").field("Width", &self.Width).field("Height", &self.Height).finish()
+ }
+}
+impl ::windows_core::TypeKind for Size {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::windows_core::RuntimeType for Size {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.Size;f4;f4)");
+}
+impl ::core::cmp::PartialEq for Size {
+ fn eq(&self, other: &Self) -> bool {
+ self.Width == other.Width && self.Height == other.Height
+ }
+}
+impl ::core::cmp::Eq for Size {}
+impl ::core::default::Default for Size {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
+#[repr(C)]
+pub struct TimeSpan {
+ pub Duration: i64,
+}
+impl ::core::marker::Copy for TimeSpan {}
+impl ::core::clone::Clone for TimeSpan {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl ::core::fmt::Debug for TimeSpan {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct("TimeSpan").field("Duration", &self.Duration).finish()
+ }
+}
+impl ::windows_core::TypeKind for TimeSpan {
+ type TypeKind = ::windows_core::CopyType;
+}
+impl ::windows_core::RuntimeType for TimeSpan {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Foundation.TimeSpan;i8)");
+}
+impl ::core::cmp::PartialEq for TimeSpan {
+ fn eq(&self, other: &Self) -> bool {
+ self.Duration == other.Duration
+ }
+}
+impl ::core::cmp::Eq for TimeSpan {}
+impl ::core::default::Default for TimeSpan {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/delay_load.rs b/third_party/rust/windows-core/src/imp/delay_load.rs
new file mode 100644
index 0000000000..26469c6d83
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/delay_load.rs
@@ -0,0 +1,25 @@
+use super::*;
+
+/// Attempts to load a function from a given library.
+///
+/// This is a small wrapper around `LoadLibrary` and `GetProcAddress`.
+///
+/// # Safety
+///
+/// * Both the library and function names must be valid null-terminated strings.
+pub unsafe fn delay_load<T>(library: crate::PCSTR, function: crate::PCSTR) -> Option<T> {
+ let library = LoadLibraryExA(library.0, 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+
+ if library == 0 {
+ return None;
+ }
+
+ let address = GetProcAddress(library, function.0);
+
+ if address.is_some() {
+ return Some(std::mem::transmute_copy(&address));
+ }
+
+ FreeLibrary(library);
+ None
+}
diff --git a/third_party/rust/windows-core/src/imp/factory_cache.rs b/third_party/rust/windows-core/src/imp/factory_cache.rs
new file mode 100644
index 0000000000..b36ab42ab3
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/factory_cache.rs
@@ -0,0 +1,161 @@
+use super::*;
+use crate::ComInterface;
+use std::marker::PhantomData;
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+#[doc(hidden)]
+pub struct FactoryCache<C, I> {
+ shared: AtomicPtr<std::ffi::c_void>,
+ _c: PhantomData<C>,
+ _i: PhantomData<I>,
+}
+
+impl<C, I> FactoryCache<C, I> {
+ pub const fn new() -> Self {
+ Self { shared: AtomicPtr::new(std::ptr::null_mut()), _c: PhantomData, _i: PhantomData }
+ }
+}
+
+impl<C: crate::RuntimeName, I: crate::ComInterface> FactoryCache<C, I> {
+ pub fn call<R, F: FnOnce(&I) -> crate::Result<R>>(&self, callback: F) -> crate::Result<R> {
+ loop {
+ // Attempt to load a previously cached factory pointer.
+ let ptr = self.shared.load(Ordering::Relaxed);
+
+ // If a pointer is found, the cache is primed and we're good to go.
+ if !ptr.is_null() {
+ return callback(unsafe { std::mem::transmute(&ptr) });
+ }
+
+ // Otherwise, we load the factory the usual way.
+ let factory = factory::<C, I>()?;
+
+ // If the factory is agile, we can safely cache it.
+ if factory.cast::<IAgileObject>().is_ok() {
+ if self.shared.compare_exchange_weak(std::ptr::null_mut(), factory.as_raw(), Ordering::Relaxed, Ordering::Relaxed).is_ok() {
+ std::mem::forget(factory);
+ }
+ } else {
+ // Otherwise, for non-agile factories we simply use the factory
+ // and discard after use as it is not safe to cache.
+ return callback(&factory);
+ }
+ }
+ }
+}
+
+// This is safe because `FactoryCache` only holds agile factory pointers, which are safe to cache and share between threads.
+unsafe impl<C, I> std::marker::Sync for FactoryCache<C, I> {}
+
+/// Attempts to load the factory object for the given WinRT class.
+/// This can be used to access COM interfaces implemented on a Windows Runtime class factory.
+pub fn factory<C: crate::RuntimeName, I: crate::ComInterface>() -> crate::Result<I> {
+ let mut factory: Option<I> = None;
+ let name = crate::HSTRING::from(C::NAME);
+
+ let code = if let Some(function) = unsafe { delay_load::<RoGetActivationFactory>(crate::s!("combase.dll"), crate::s!("RoGetActivationFactory")) } {
+ unsafe {
+ let mut code = function(std::mem::transmute_copy(&name), &I::IID, &mut factory as *mut _ as *mut _);
+
+ // If RoGetActivationFactory fails because combase hasn't been loaded yet then load combase
+ // automatically so that it "just works" for apartment-agnostic code.
+ if code == CO_E_NOTINITIALIZED {
+ if let Some(mta) = delay_load::<CoIncrementMTAUsage>(crate::s!("ole32.dll"), crate::s!("CoIncrementMTAUsage")) {
+ let mut cookie = std::ptr::null_mut();
+ let _ = mta(&mut cookie);
+ }
+
+ // Now try a second time to get the activation factory via the OS.
+ code = function(std::mem::transmute_copy(&name), &I::IID, &mut factory as *mut _ as *mut _);
+ }
+
+ code
+ }
+ } else {
+ CLASS_E_CLASSNOTAVAILABLE
+ };
+
+ // If this succeeded then return the resulting factory interface.
+ if code.is_ok() {
+ return code.and_some(factory);
+ }
+
+ // If not, first capture the error information from the failure above so that we
+ // can ultimately return this error information if all else fails.
+ let original: crate::Error = code.into();
+
+ // Now attempt to find the factory's implementation heuristically.
+ if let Some(i) = search_path(C::NAME, |library| unsafe { get_activation_factory(library, &name) }) {
+ i.cast()
+ } else {
+ Err(original)
+ }
+}
+
+// Remove the suffix until a match is found appending `.dll\0` at the end
+///
+/// For example, if the class name is
+/// "A.B.TypeName" then the attempted load order will be:
+/// 1. A.B.dll
+/// 2. A.dll
+fn search_path<F, R>(mut path: &str, mut callback: F) -> Option<R>
+where
+ F: FnMut(crate::PCSTR) -> crate::Result<R>,
+{
+ let suffix = b".dll\0";
+ let mut library = vec![0; path.len() + suffix.len()];
+ while let Some(pos) = path.rfind('.') {
+ path = &path[..pos];
+ library.truncate(path.len() + suffix.len());
+ library[..path.len()].copy_from_slice(path.as_bytes());
+ library[path.len()..].copy_from_slice(suffix);
+
+ if let Ok(r) = callback(crate::PCSTR::from_raw(library.as_ptr())) {
+ return Some(r);
+ }
+ }
+
+ None
+}
+
+unsafe fn get_activation_factory(library: crate::PCSTR, name: &crate::HSTRING) -> crate::Result<IGenericFactory> {
+ let function = delay_load::<DllGetActivationFactory>(library, crate::s!("DllGetActivationFactory")).ok_or_else(crate::Error::from_win32)?;
+ let mut abi = std::ptr::null_mut();
+ function(std::mem::transmute_copy(name), &mut abi).from_abi(abi)
+}
+
+type CoIncrementMTAUsage = extern "system" fn(cookie: *mut *mut std::ffi::c_void) -> crate::HRESULT;
+type RoGetActivationFactory = extern "system" fn(hstring: *mut std::ffi::c_void, interface: &crate::GUID, result: *mut *mut std::ffi::c_void) -> crate::HRESULT;
+type DllGetActivationFactory = extern "system" fn(name: *mut std::ffi::c_void, factory: *mut *mut std::ffi::c_void) -> crate::HRESULT;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn dll_search() {
+ let path = "A.B.TypeName";
+
+ // Test library successfully found
+ let mut results = Vec::new();
+ let end_result = search_path(path, |library| {
+ results.push(unsafe { library.to_string().unwrap() });
+ if unsafe { library.as_bytes() } == &b"A.dll"[..] {
+ Ok(42)
+ } else {
+ Err(crate::Error::OK)
+ }
+ });
+ assert!(matches!(end_result, Some(42)));
+ assert_eq!(results, vec!["A.B.dll", "A.dll"]);
+
+ // Test library never successfully found
+ let mut results = Vec::new();
+ let end_result = search_path(path, |library| {
+ results.push(unsafe { library.to_string().unwrap() });
+ crate::Result::<()>::Err(crate::Error::OK)
+ });
+ assert!(end_result.is_none());
+ assert_eq!(results, vec!["A.B.dll", "A.dll"]);
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/generic_factory.rs b/third_party/rust/windows-core/src/imp/generic_factory.rs
new file mode 100644
index 0000000000..5d3d254ca6
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/generic_factory.rs
@@ -0,0 +1,30 @@
+use crate::ComInterface;
+
+// A streamlined version of the IActivationFactory interface used by WinRT class factories used internally by the windows crate
+// to simplify code generation. Components should implement the `IActivationFactory` interface published by the windows crate.
+#[repr(transparent)]
+#[derive(Clone, PartialEq, Eq)]
+pub struct IGenericFactory(crate::IUnknown);
+
+impl IGenericFactory {
+ pub fn ActivateInstance<I: crate::ComInterface>(&self) -> crate::Result<I> {
+ unsafe {
+ let mut result__ = std::mem::zeroed();
+ (crate::Interface::vtable(self).ActivateInstance)(std::mem::transmute_copy(self), &mut result__ as *mut _ as *mut _).from_abi::<crate::IInspectable>(result__)?.cast()
+ }
+ }
+}
+
+#[repr(C)]
+pub struct IGenericFactory_Vtbl {
+ pub base__: crate::IInspectable_Vtbl,
+ pub ActivateInstance: unsafe extern "system" fn(this: *mut std::ffi::c_void, instance: *mut *mut std::ffi::c_void) -> crate::HRESULT,
+}
+
+unsafe impl crate::Interface for IGenericFactory {
+ type Vtable = IGenericFactory_Vtbl;
+}
+
+unsafe impl crate::ComInterface for IGenericFactory {
+ const IID: crate::GUID = crate::GUID::from_u128(0x00000035_0000_0000_c000_000000000046);
+}
diff --git a/third_party/rust/windows-core/src/imp/heap.rs b/third_party/rust/windows-core/src/imp/heap.rs
new file mode 100644
index 0000000000..2725ec6bc5
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/heap.rs
@@ -0,0 +1,35 @@
+use super::*;
+
+/// Allocate memory of size `bytes` using `HeapAlloc`.
+///
+/// The memory allocated by this function is uninitialized.
+///
+/// This function will fail in OOM situations, if the heap is otherwise corrupt,
+/// or if getting a handle to the process heap fails.
+pub fn heap_alloc(bytes: usize) -> crate::Result<*mut std::ffi::c_void> {
+ let ptr = unsafe { HeapAlloc(GetProcessHeap(), 0, bytes) };
+
+ if ptr.is_null() {
+ Err(E_OUTOFMEMORY.into())
+ } else {
+ // HeapAlloc is not guaranteed to return zero memory but usually does. This just ensures that
+ // it predictably returns non-zero memory for testing purposes. This is similar to what MSVC's
+ // debug allocator does for the same reason.
+ #[cfg(debug_assertions)]
+ unsafe {
+ std::ptr::write_bytes(ptr, 0xCC, bytes);
+ }
+ Ok(ptr)
+ }
+}
+
+/// Free memory allocated by `HeapAlloc` or `HeapReAlloc`.
+///
+/// The pointer is allowed to be null.
+///
+/// # Safety
+///
+/// `ptr` must be a valid pointer to memory allocated by `HeapAlloc` or `HeapReAlloc`
+pub unsafe fn heap_free(ptr: *mut std::ffi::c_void) {
+ HeapFree(GetProcessHeap(), 0, ptr);
+}
diff --git a/third_party/rust/windows-core/src/imp/mod.rs b/third_party/rust/windows-core/src/imp/mod.rs
new file mode 100644
index 0000000000..d5093fd2f3
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/mod.rs
@@ -0,0 +1,55 @@
+mod bindings;
+mod com_bindings;
+mod delay_load;
+mod factory_cache;
+mod generic_factory;
+mod heap;
+mod ref_count;
+mod sha1;
+mod waiter;
+mod weak_ref_count;
+
+pub use bindings::*;
+pub use com_bindings::*;
+pub use delay_load::*;
+pub use factory_cache::*;
+pub use generic_factory::*;
+pub use heap::*;
+pub use ref_count::*;
+pub use sha1::*;
+pub use waiter::*;
+pub use weak_ref_count::*;
+
+// This is a workaround since 1.56 does not include `bool::then_some`.
+pub fn then_some<T>(value: bool, t: T) -> Option<T> {
+ if value {
+ Some(t)
+ } else {
+ None
+ }
+}
+
+pub fn wide_trim_end(mut wide: &[u16]) -> &[u16] {
+ while let Some(last) = wide.last() {
+ match last {
+ 32 | 9..=13 => wide = &wide[..wide.len() - 1],
+ _ => break,
+ }
+ }
+ wide
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! interface_hierarchy {
+ ($child:ty, $parent:ty) => {
+ impl ::windows_core::CanInto<$parent> for $child {}
+ };
+ ($child:ty, $first:ty, $($rest:ty),+) => {
+ $crate::imp::interface_hierarchy!($child, $first);
+ $crate::imp::interface_hierarchy!($child, $($rest),+);
+ };
+}
+
+#[doc(hidden)]
+pub use interface_hierarchy;
diff --git a/third_party/rust/windows-core/src/imp/ref_count.rs b/third_party/rust/windows-core/src/imp/ref_count.rs
new file mode 100644
index 0000000000..6f179f28ae
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/ref_count.rs
@@ -0,0 +1,34 @@
+use std::sync::atomic::{fence, AtomicI32, Ordering};
+
+#[doc(hidden)]
+#[repr(transparent)]
+#[derive(Default)]
+pub struct RefCount(pub(crate) AtomicI32);
+
+impl RefCount {
+ /// Creates a new `RefCount` with an initial value of `1`.
+ pub fn new(count: u32) -> Self {
+ Self(AtomicI32::new(count as i32))
+ }
+
+ /// Increments the reference count, returning the new value.
+ pub fn add_ref(&self) -> u32 {
+ (self.0.fetch_add(1, Ordering::Relaxed) + 1) as u32
+ }
+
+ /// Decrements the reference count, returning the new value.
+ ///
+ /// This operation inserts an `Acquire` fence when the reference count reaches zero.
+ /// This prevents reordering before the object is destroyed.
+ pub fn release(&self) -> u32 {
+ let remaining = self.0.fetch_sub(1, Ordering::Release) - 1;
+
+ match remaining.cmp(&0) {
+ std::cmp::Ordering::Equal => fence(Ordering::Acquire),
+ std::cmp::Ordering::Less => panic!("Object has been over-released."),
+ std::cmp::Ordering::Greater => {}
+ }
+
+ remaining as u32
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/sha1.rs b/third_party/rust/windows-core/src/imp/sha1.rs
new file mode 100644
index 0000000000..5962a3d022
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/sha1.rs
@@ -0,0 +1,333 @@
+#![allow(clippy::many_single_char_names)]
+
+pub const fn sha1(data: &ConstBuffer) -> Digest {
+ let state: [u32; 5] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
+ let len: u64 = 0;
+ let blocks = Blocks { len: 0, data: [0; 64] };
+ let (blocks, len, state) = process_blocks(blocks, data, len, state);
+ digest(state, len, blocks)
+}
+
+const BUFFER_SIZE: usize = 1024;
+
+pub struct ConstBuffer {
+ data: [u8; BUFFER_SIZE],
+ head: usize,
+}
+
+impl ConstBuffer {
+ pub const fn from_slice(slice: &[u8]) -> Self {
+ let s = Self::new();
+ s.push_slice(slice)
+ }
+
+ pub const fn new() -> Self {
+ Self { data: [0; BUFFER_SIZE], head: 0 }
+ }
+
+ pub const fn push_slice(self, slice: &[u8]) -> Self {
+ self.push_amount(slice, slice.len())
+ }
+
+ const fn get(&self, index: usize) -> u8 {
+ self.data[index]
+ }
+
+ const fn len(&self) -> usize {
+ self.head
+ }
+
+ const fn as_slice(&self) -> &[u8] {
+ &self.data
+ }
+
+ pub const fn push_other(self, other: Self) -> Self {
+ self.push_amount(other.as_slice(), other.len())
+ }
+
+ const fn push_amount(mut self, slice: &[u8], amount: usize) -> Self {
+ let mut i = 0;
+ while i < amount {
+ self.data[self.head + i] = slice[i];
+ i += 1;
+ }
+ self.head += i;
+ self
+ }
+}
+
+struct Blocks {
+ len: u32,
+ data: [u8; 64],
+}
+
+const fn process_blocks(mut blocks: Blocks, data: &ConstBuffer, mut len: u64, mut state: [u32; 5]) -> (Blocks, u64, [u32; 5]) {
+ const fn as_block(input: &ConstBuffer, offset: usize) -> [u32; 16] {
+ let mut result = [0u32; 16];
+
+ let mut i = 0;
+ while i != 16 {
+ let off = offset + (i * 4);
+ result[i] = (input.get(off + 3) as u32) | ((input.get(off + 2) as u32) << 8) | ((input.get(off + 1) as u32) << 16) | ((input.get(off) as u32) << 24);
+ i += 1;
+ }
+ result
+ }
+
+ const fn clone_from_slice_64(mut data: [u8; 64], slice: &[u8], offset: usize, num_elems: usize) -> [u8; 64] {
+ let mut i = 0;
+ while i < num_elems {
+ data[i] = slice[offset + i];
+ i += 1;
+ }
+ data
+ }
+
+ let mut i = 0;
+ while i < data.len() {
+ if data.len() - i >= 64 {
+ let chunk_block = as_block(data, i);
+ len += 64;
+ state = process_state(state, chunk_block);
+ i += 64;
+ } else {
+ let num_elems = data.len() - i;
+ blocks.data = clone_from_slice_64(blocks.data, data.as_slice(), i, num_elems);
+ blocks.len = num_elems as u32;
+ break;
+ }
+ }
+ (blocks, len, state)
+}
+
+const fn process_state(mut state: [u32; 5], block: [u32; 16]) -> [u32; 5] {
+ let a = state[0];
+ let b = state[1];
+ let c = state[2];
+ let d = state[3];
+ let e = state[4];
+ let (block, b, e) = r0(block, a, b, c, d, e, 0);
+ let (block, a, d) = r0(block, e, a, b, c, d, 1);
+ let (block, e, c) = r0(block, d, e, a, b, c, 2);
+ let (block, d, b) = r0(block, c, d, e, a, b, 3);
+ let (block, c, a) = r0(block, b, c, d, e, a, 4);
+ let (block, b, e) = r0(block, a, b, c, d, e, 5);
+ let (block, a, d) = r0(block, e, a, b, c, d, 6);
+ let (block, e, c) = r0(block, d, e, a, b, c, 7);
+ let (block, d, b) = r0(block, c, d, e, a, b, 8);
+ let (block, c, a) = r0(block, b, c, d, e, a, 9);
+ let (block, b, e) = r0(block, a, b, c, d, e, 10);
+ let (block, a, d) = r0(block, e, a, b, c, d, 11);
+ let (block, e, c) = r0(block, d, e, a, b, c, 12);
+ let (block, d, b) = r0(block, c, d, e, a, b, 13);
+ let (block, c, a) = r0(block, b, c, d, e, a, 14);
+ let (block, b, e) = r0(block, a, b, c, d, e, 15);
+ let (block, a, d) = r1(block, e, a, b, c, d, 0);
+ let (block, e, c) = r1(block, d, e, a, b, c, 1);
+ let (block, d, b) = r1(block, c, d, e, a, b, 2);
+ let (block, c, a) = r1(block, b, c, d, e, a, 3);
+ let (block, b, e) = r2(block, a, b, c, d, e, 4);
+ let (block, a, d) = r2(block, e, a, b, c, d, 5);
+ let (block, e, c) = r2(block, d, e, a, b, c, 6);
+ let (block, d, b) = r2(block, c, d, e, a, b, 7);
+ let (block, c, a) = r2(block, b, c, d, e, a, 8);
+ let (block, b, e) = r2(block, a, b, c, d, e, 9);
+ let (block, a, d) = r2(block, e, a, b, c, d, 10);
+ let (block, e, c) = r2(block, d, e, a, b, c, 11);
+ let (block, d, b) = r2(block, c, d, e, a, b, 12);
+ let (block, c, a) = r2(block, b, c, d, e, a, 13);
+ let (block, b, e) = r2(block, a, b, c, d, e, 14);
+ let (block, a, d) = r2(block, e, a, b, c, d, 15);
+ let (block, e, c) = r2(block, d, e, a, b, c, 0);
+ let (block, d, b) = r2(block, c, d, e, a, b, 1);
+ let (block, c, a) = r2(block, b, c, d, e, a, 2);
+ let (block, b, e) = r2(block, a, b, c, d, e, 3);
+ let (block, a, d) = r2(block, e, a, b, c, d, 4);
+ let (block, e, c) = r2(block, d, e, a, b, c, 5);
+ let (block, d, b) = r2(block, c, d, e, a, b, 6);
+ let (block, c, a) = r2(block, b, c, d, e, a, 7);
+ let (block, b, e) = r3(block, a, b, c, d, e, 8);
+ let (block, a, d) = r3(block, e, a, b, c, d, 9);
+ let (block, e, c) = r3(block, d, e, a, b, c, 10);
+ let (block, d, b) = r3(block, c, d, e, a, b, 11);
+ let (block, c, a) = r3(block, b, c, d, e, a, 12);
+ let (block, b, e) = r3(block, a, b, c, d, e, 13);
+ let (block, a, d) = r3(block, e, a, b, c, d, 14);
+ let (block, e, c) = r3(block, d, e, a, b, c, 15);
+ let (block, d, b) = r3(block, c, d, e, a, b, 0);
+ let (block, c, a) = r3(block, b, c, d, e, a, 1);
+ let (block, b, e) = r3(block, a, b, c, d, e, 2);
+ let (block, a, d) = r3(block, e, a, b, c, d, 3);
+ let (block, e, c) = r3(block, d, e, a, b, c, 4);
+ let (block, d, b) = r3(block, c, d, e, a, b, 5);
+ let (block, c, a) = r3(block, b, c, d, e, a, 6);
+ let (block, b, e) = r3(block, a, b, c, d, e, 7);
+ let (block, a, d) = r3(block, e, a, b, c, d, 8);
+ let (block, e, c) = r3(block, d, e, a, b, c, 9);
+ let (block, d, b) = r3(block, c, d, e, a, b, 10);
+ let (block, c, a) = r3(block, b, c, d, e, a, 11);
+ let (block, b, e) = r4(block, a, b, c, d, e, 12);
+ let (block, a, d) = r4(block, e, a, b, c, d, 13);
+ let (block, e, c) = r4(block, d, e, a, b, c, 14);
+ let (block, d, b) = r4(block, c, d, e, a, b, 15);
+ let (block, c, a) = r4(block, b, c, d, e, a, 0);
+ let (block, b, e) = r4(block, a, b, c, d, e, 1);
+ let (block, a, d) = r4(block, e, a, b, c, d, 2);
+ let (block, e, c) = r4(block, d, e, a, b, c, 3);
+ let (block, d, b) = r4(block, c, d, e, a, b, 4);
+ let (block, c, a) = r4(block, b, c, d, e, a, 5);
+ let (block, b, e) = r4(block, a, b, c, d, e, 6);
+ let (block, a, d) = r4(block, e, a, b, c, d, 7);
+ let (block, e, c) = r4(block, d, e, a, b, c, 8);
+ let (block, d, b) = r4(block, c, d, e, a, b, 9);
+ let (block, c, a) = r4(block, b, c, d, e, a, 10);
+ let (block, b, e) = r4(block, a, b, c, d, e, 11);
+ let (block, a, d) = r4(block, e, a, b, c, d, 12);
+ let (block, e, c) = r4(block, d, e, a, b, c, 13);
+ let (block, d, b) = r4(block, c, d, e, a, b, 14);
+ let (_, c, a) = r4(block, b, c, d, e, a, 15);
+
+ state[0] = state[0].wrapping_add(a);
+ state[1] = state[1].wrapping_add(b);
+ state[2] = state[2].wrapping_add(c);
+ state[3] = state[3].wrapping_add(d);
+ state[4] = state[4].wrapping_add(e);
+ state
+}
+
+const fn digest(mut state: [u32; 5], len: u64, blocks: Blocks) -> Digest {
+ const fn clone_from_slice_128(mut data: [u8; 128], slice: &[u8], offset: usize, num_elems: usize) -> [u8; 128] {
+ let mut i = 0;
+ while i < num_elems {
+ data[i] = slice[offset + i];
+ i += 1;
+ }
+ data
+ }
+
+ const fn clone_slice_128(mut data: [u8; 128], slice: &[u8], _offset: usize) -> [u8; 128] {
+ let mut i = 0;
+ while i < slice.len() {
+ data[_offset + i] = slice[i];
+ i += 1;
+ }
+ data
+ }
+
+ const fn as_block(input: &[u8], offset: usize) -> [u32; 16] {
+ let mut result = [0u32; 16];
+
+ let mut i = 0;
+ while i != 16 {
+ let off = offset + (i * 4);
+ result[i] = (input[off + 3] as u32) | ((input[off + 2] as u32) << 8) | ((input[off + 1] as u32) << 16) | ((input[off] as u32) << 24);
+ i += 1;
+ }
+ result
+ }
+
+ let bits = (len + (blocks.len as u64)) * 8;
+ let extra = [(bits >> 56) as u8, (bits >> 48) as u8, (bits >> 40) as u8, (bits >> 32) as u8, (bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8];
+ let mut last = [0; 128];
+ let blocklen = blocks.len as usize;
+ last = clone_from_slice_128(last, &blocks.data, 0, blocklen);
+ last[blocklen] = 0x80;
+
+ if blocklen < 56 {
+ last = clone_slice_128(last, &extra, 56);
+ state = process_state(state, as_block(&last, 0));
+ } else {
+ last = clone_slice_128(last, &extra, 120);
+ state = process_state(state, as_block(&last, 0));
+ state = process_state(state, as_block(&last, 64));
+ }
+ Digest { data: state }
+}
+
+const fn rol(value: u32, bits: usize) -> u32 {
+ (value << bits) | (value >> (32 - bits))
+}
+
+const fn blk(block: &[u32], i: usize) -> u32 {
+ let value = block[(i + 13) & 15] ^ block[(i + 8) & 15] ^ block[(i + 2) & 15] ^ block[i];
+ rol(value, 1)
+}
+
+const fn r0(block: [u32; 16], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> ([u32; 16], u32, u32) {
+ let n = ((w & (x ^ y)) ^ y).wrapping_add(block[i]).wrapping_add(0x5a82_7999).wrapping_add(rol(v, 5));
+ z = z.wrapping_add(n);
+ w = rol(w, 30);
+ (block, w, z)
+}
+
+const fn r1(mut block: [u32; 16], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> ([u32; 16], u32, u32) {
+ block[i] = blk(&block, i);
+ let n = ((w & (x ^ y)) ^ y).wrapping_add(block[i]).wrapping_add(0x5a82_7999).wrapping_add(rol(v, 5));
+ z = z.wrapping_add(n);
+ w = rol(w, 30);
+ (block, w, z)
+}
+
+const fn r2(mut block: [u32; 16], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> ([u32; 16], u32, u32) {
+ block[i] = blk(&block, i);
+ let n = (w ^ x ^ y).wrapping_add(block[i]).wrapping_add(0x6ed9_eba1).wrapping_add(rol(v, 5));
+ z = z.wrapping_add(n);
+ w = rol(w, 30);
+ (block, w, z)
+}
+
+const fn r3(mut block: [u32; 16], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> ([u32; 16], u32, u32) {
+ block[i] = blk(&block, i);
+ let n = (((w | x) & y) | (w & x)).wrapping_add(block[i]).wrapping_add(0x8f1b_bcdc).wrapping_add(rol(v, 5));
+ z = z.wrapping_add(n);
+ w = rol(w, 30);
+ (block, w, z)
+}
+
+const fn r4(mut block: [u32; 16], v: u32, mut w: u32, x: u32, y: u32, mut z: u32, i: usize) -> ([u32; 16], u32, u32) {
+ block[i] = blk(&block, i);
+ let n = (w ^ x ^ y).wrapping_add(block[i]).wrapping_add(0xca62_c1d6).wrapping_add(rol(v, 5));
+ z = z.wrapping_add(n);
+ w = rol(w, 30);
+ (block, w, z)
+}
+
+pub struct Digest {
+ data: [u32; 5],
+}
+
+impl Digest {
+ pub const fn bytes(&self) -> [u8; 20] {
+ [
+ (self.data[0] >> 24) as u8,
+ (self.data[0] >> 16) as u8,
+ (self.data[0] >> 8) as u8,
+ self.data[0] as u8,
+ (self.data[1] >> 24) as u8,
+ (self.data[1] >> 16) as u8,
+ (self.data[1] >> 8) as u8,
+ self.data[1] as u8,
+ (self.data[2] >> 24) as u8,
+ (self.data[2] >> 16) as u8,
+ (self.data[2] >> 8) as u8,
+ self.data[2] as u8,
+ (self.data[3] >> 24) as u8,
+ (self.data[3] >> 16) as u8,
+ (self.data[3] >> 8) as u8,
+ self.data[3] as u8,
+ (self.data[4] >> 24) as u8,
+ (self.data[4] >> 16) as u8,
+ (self.data[4] >> 8) as u8,
+ self.data[4] as u8,
+ ]
+ }
+}
+
+impl std::fmt::Display for Digest {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ for i in self.data.iter() {
+ write!(f, "{:08x}", i)?;
+ }
+ Ok(())
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/waiter.rs b/third_party/rust/windows-core/src/imp/waiter.rs
new file mode 100644
index 0000000000..fe72143eb5
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/waiter.rs
@@ -0,0 +1,39 @@
+use super::*;
+
+#[doc(hidden)]
+pub struct Waiter(isize);
+pub struct WaiterSignaler(isize);
+
+impl Waiter {
+ pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> {
+ unsafe {
+ let handle = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null());
+ if handle == 0 {
+ Err(crate::Error::from_win32())
+ } else {
+ Ok((Waiter(handle), WaiterSignaler(handle)))
+ }
+ }
+ }
+}
+
+impl WaiterSignaler {
+ /// # Safety
+ /// Signals the `Waiter`. This is unsafe because the lifetime of `WaiterSignaler` is not tied
+ /// to the lifetime of the `Waiter`. This is not possible in this case because the `Waiter`
+ /// is used to signal a WinRT async completion and the compiler doesn't know that the lifetime
+ /// of the delegate is bounded by the calling function.
+ pub unsafe fn signal(&self) {
+ // https://github.com/microsoft/windows-rs/pull/374#discussion_r535313344
+ SetEvent(self.0);
+ }
+}
+
+impl Drop for Waiter {
+ fn drop(&mut self) {
+ unsafe {
+ WaitForSingleObject(self.0, 0xFFFFFFFF);
+ CloseHandle(self.0);
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/imp/weak_ref_count.rs b/third_party/rust/windows-core/src/imp/weak_ref_count.rs
new file mode 100644
index 0000000000..1f6a70a28a
--- /dev/null
+++ b/third_party/rust/windows-core/src/imp/weak_ref_count.rs
@@ -0,0 +1,240 @@
+use super::*;
+use crate::ComInterface;
+use std::sync::atomic::{AtomicIsize, Ordering};
+
+#[doc(hidden)]
+#[repr(transparent)]
+#[derive(Default)]
+pub struct WeakRefCount(AtomicIsize);
+
+impl WeakRefCount {
+ pub fn new() -> Self {
+ Self(AtomicIsize::new(1))
+ }
+
+ pub fn add_ref(&self) -> u32 {
+ self.0.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |count_or_pointer| then_some(!is_weak_ref(count_or_pointer), count_or_pointer + 1)).map(|u| u as u32 + 1).unwrap_or_else(|pointer| unsafe { TearOff::decode(pointer).strong_count.add_ref() })
+ }
+
+ pub fn release(&self) -> u32 {
+ self.0.fetch_update(Ordering::Release, Ordering::Relaxed, |count_or_pointer| then_some(!is_weak_ref(count_or_pointer), count_or_pointer - 1)).map(|u| u as u32 - 1).unwrap_or_else(|pointer| unsafe {
+ let tear_off = TearOff::decode(pointer);
+ let remaining = tear_off.strong_count.release();
+
+ // If this is the last strong reference, we can release the weak reference implied by the strong reference.
+ // There may still be weak references, so the WeakRelease is called to handle such possibilities.
+ if remaining == 0 {
+ TearOff::WeakRelease(&mut tear_off.weak_vtable as *mut _ as _);
+ }
+
+ remaining
+ })
+ }
+
+ /// # Safety
+ pub unsafe fn query(&self, iid: *const crate::GUID, object: *mut std::ffi::c_void) -> *mut std::ffi::c_void {
+ if *iid != IWeakReferenceSource::IID {
+ return std::ptr::null_mut();
+ }
+
+ let mut count_or_pointer = self.0.load(Ordering::Relaxed);
+
+ if is_weak_ref(count_or_pointer) {
+ return TearOff::from_encoding(count_or_pointer);
+ }
+
+ let tear_off = TearOff::new(object, count_or_pointer as u32);
+ let tear_off_ptr: *mut std::ffi::c_void = std::mem::transmute_copy(&tear_off);
+ let encoding: usize = ((tear_off_ptr as usize) >> 1) | (1 << (std::mem::size_of::<usize>() * 8 - 1));
+
+ loop {
+ match self.0.compare_exchange_weak(count_or_pointer, encoding as isize, Ordering::AcqRel, Ordering::Relaxed) {
+ Ok(_) => {
+ let result: *mut std::ffi::c_void = std::mem::transmute(tear_off);
+ TearOff::from_strong_ptr(result).strong_count.add_ref();
+ return result;
+ }
+ Err(pointer) => count_or_pointer = pointer,
+ }
+
+ if is_weak_ref(count_or_pointer) {
+ return TearOff::from_encoding(count_or_pointer);
+ }
+
+ TearOff::from_strong_ptr(tear_off_ptr).strong_count.0.store(count_or_pointer as i32, Ordering::SeqCst);
+ }
+ }
+}
+
+fn is_weak_ref(value: isize) -> bool {
+ value < 0
+}
+
+#[repr(C)]
+struct TearOff {
+ strong_vtable: *const IWeakReferenceSource_Vtbl,
+ weak_vtable: *const IWeakReference_Vtbl,
+ object: *mut std::ffi::c_void,
+ strong_count: RefCount,
+ weak_count: RefCount,
+}
+
+impl TearOff {
+ #[allow(clippy::new_ret_no_self)]
+ unsafe fn new(object: *mut std::ffi::c_void, strong_count: u32) -> IWeakReferenceSource {
+ std::mem::transmute(std::boxed::Box::new(TearOff {
+ strong_vtable: &Self::STRONG_VTABLE,
+ weak_vtable: &Self::WEAK_VTABLE,
+ object,
+ strong_count: RefCount::new(strong_count),
+ weak_count: RefCount::new(1),
+ }))
+ }
+
+ unsafe fn from_encoding(encoding: isize) -> *mut std::ffi::c_void {
+ let tear_off = TearOff::decode(encoding);
+ tear_off.strong_count.add_ref();
+ tear_off as *mut _ as *mut _
+ }
+
+ const STRONG_VTABLE: IWeakReferenceSource_Vtbl = IWeakReferenceSource_Vtbl {
+ base__: crate::IUnknown_Vtbl { QueryInterface: Self::StrongQueryInterface, AddRef: Self::StrongAddRef, Release: Self::StrongRelease },
+ GetWeakReference: Self::StrongDowngrade,
+ };
+
+ const WEAK_VTABLE: IWeakReference_Vtbl = IWeakReference_Vtbl {
+ base__: crate::IUnknown_Vtbl { QueryInterface: Self::WeakQueryInterface, AddRef: Self::WeakAddRef, Release: Self::WeakRelease },
+ Resolve: Self::WeakUpgrade,
+ };
+
+ unsafe fn from_strong_ptr<'a>(this: *mut std::ffi::c_void) -> &'a mut Self {
+ &mut *(this as *mut *mut std::ffi::c_void as *mut Self)
+ }
+
+ unsafe fn from_weak_ptr<'a>(this: *mut std::ffi::c_void) -> &'a mut Self {
+ &mut *((this as *mut *mut std::ffi::c_void).sub(1) as *mut Self)
+ }
+
+ unsafe fn decode<'a>(value: isize) -> &'a mut Self {
+ std::mem::transmute(value << 1)
+ }
+
+ unsafe fn query_interface(&self, iid: *const crate::GUID, interface: *mut *mut std::ffi::c_void) -> crate::HRESULT {
+ ((*(*(self.object as *mut *mut crate::IUnknown_Vtbl))).QueryInterface)(self.object, iid, interface)
+ }
+
+ unsafe extern "system" fn StrongQueryInterface(ptr: *mut std::ffi::c_void, iid: *const crate::GUID, interface: *mut *mut std::ffi::c_void) -> crate::HRESULT {
+ let this = Self::from_strong_ptr(ptr);
+
+ if iid.is_null() || interface.is_null() {
+ return ::windows_core::HRESULT(-2147467261); // E_POINTER
+ }
+
+ // Only directly respond to queries for the the tear-off's strong interface. This is
+ // effectively a self-query.
+ if *iid == IWeakReferenceSource::IID {
+ *interface = ptr;
+ this.strong_count.add_ref();
+ return crate::HRESULT(0);
+ }
+
+ // As the tear-off is sharing the identity of the object, simply delegate any remaining
+ // queries to the object.
+ this.query_interface(iid, interface)
+ }
+
+ unsafe extern "system" fn WeakQueryInterface(ptr: *mut std::ffi::c_void, iid: *const crate::GUID, interface: *mut *mut std::ffi::c_void) -> crate::HRESULT {
+ let this = Self::from_weak_ptr(ptr);
+
+ if iid.is_null() || interface.is_null() {
+ return ::windows_core::HRESULT(-2147467261); // E_POINTER
+ }
+
+ // While the weak vtable is packed into the same allocation as the strong vtable and
+ // tear-off, it represents a distinct COM identity and thus does not share or delegate to
+ // the object.
+
+ *interface = if *iid == IWeakReference::IID || *iid == crate::IUnknown::IID || *iid == IAgileObject::IID { ptr } else { std::ptr::null_mut() };
+
+ // TODO: implement IMarshal
+
+ if (*interface).is_null() {
+ E_NOINTERFACE
+ } else {
+ this.weak_count.add_ref();
+ crate::HRESULT(0)
+ }
+ }
+
+ unsafe extern "system" fn StrongAddRef(ptr: *mut std::ffi::c_void) -> u32 {
+ let this = Self::from_strong_ptr(ptr);
+
+ // Implement `AddRef` directly as we own the strong reference.
+ this.strong_count.add_ref()
+ }
+
+ unsafe extern "system" fn WeakAddRef(ptr: *mut std::ffi::c_void) -> u32 {
+ let this = Self::from_weak_ptr(ptr);
+
+ // Implement `AddRef` directly as we own the weak reference.
+ this.weak_count.add_ref()
+ }
+
+ unsafe extern "system" fn StrongRelease(ptr: *mut std::ffi::c_void) -> u32 {
+ let this = Self::from_strong_ptr(ptr);
+
+ // Forward strong `Release` to the object so that it can destroy itself. It will then
+ // decrement its weak reference and allow the tear-off to be released as needed.
+ ((*(*(this.object as *mut *mut crate::IUnknown_Vtbl))).Release)(this.object)
+ }
+
+ unsafe extern "system" fn WeakRelease(ptr: *mut std::ffi::c_void) -> u32 {
+ let this = Self::from_weak_ptr(ptr);
+
+ // Implement `Release` directly as we own the weak reference.
+ let remaining = this.weak_count.release();
+
+ // If there are no remaining references, it means that the object has already been
+ // destroyed. Go ahead and destroy the tear-off.
+ if remaining == 0 {
+ let _ = std::boxed::Box::from_raw(this);
+ }
+
+ remaining
+ }
+
+ unsafe extern "system" fn StrongDowngrade(ptr: *mut std::ffi::c_void, interface: *mut *mut std::ffi::c_void) -> crate::HRESULT {
+ let this = Self::from_strong_ptr(ptr);
+
+ // The strong vtable hands out a reference to the weak vtable. This is always safe and
+ // straightforward since a strong reference guarantees there is at least one weak
+ // reference.
+ *interface = &mut this.weak_vtable as *mut _ as _;
+ this.weak_count.add_ref();
+ crate::HRESULT(0)
+ }
+
+ unsafe extern "system" fn WeakUpgrade(ptr: *mut std::ffi::c_void, iid: *const crate::GUID, interface: *mut *mut std::ffi::c_void) -> crate::HRESULT {
+ let this = Self::from_weak_ptr(ptr);
+
+ this.strong_count
+ .0
+ .fetch_update(Ordering::Acquire, Ordering::Relaxed, |count| {
+ // Attempt to acquire a strong reference count to stabilize the object for the duration
+ // of the `QueryInterface` call.
+ then_some(count != 0, count + 1)
+ })
+ .map(|_| {
+ // Let the object respond to the upgrade query.
+ let result = this.query_interface(iid, interface);
+ // Decrement the temporary reference account used to stabilize the object.
+ this.strong_count.0.fetch_sub(1, Ordering::Relaxed);
+ // Return the result of the query.
+ result
+ })
+ .unwrap_or_else(|_| {
+ *interface = std::ptr::null_mut();
+ crate::HRESULT(0)
+ })
+ }
+}
diff --git a/third_party/rust/windows-core/src/inspectable.rs b/third_party/rust/windows-core/src/inspectable.rs
new file mode 100644
index 0000000000..a632a216ea
--- /dev/null
+++ b/third_party/rust/windows-core/src/inspectable.rs
@@ -0,0 +1,148 @@
+use super::*;
+
+/// A WinRT object that may be used as a polymorphic stand-in for any WinRT class, interface, or boxed value.
+/// [`IInspectable`] represents the
+/// [IInspectable](https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nn-inspectable-iinspectable)
+/// interface.
+#[repr(transparent)]
+#[derive(Clone, PartialEq, Eq)]
+pub struct IInspectable(pub IUnknown);
+
+impl IInspectable {
+ /// Returns the canonical type name for the underlying object.
+ pub fn GetRuntimeClassName(&self) -> Result<HSTRING> {
+ unsafe {
+ let mut abi = std::ptr::null_mut();
+ (self.vtable().GetRuntimeClassName)(std::mem::transmute_copy(self), &mut abi).ok()?;
+ Ok(std::mem::transmute(abi))
+ }
+ }
+}
+
+#[doc(hidden)]
+#[repr(C)]
+pub struct IInspectable_Vtbl {
+ pub base: IUnknown_Vtbl,
+ pub GetIids: unsafe extern "system" fn(this: *mut std::ffi::c_void, count: *mut u32, values: *mut *mut GUID) -> HRESULT,
+ pub GetRuntimeClassName: unsafe extern "system" fn(this: *mut std::ffi::c_void, value: *mut *mut std::ffi::c_void) -> HRESULT,
+ pub GetTrustLevel: unsafe extern "system" fn(this: *mut std::ffi::c_void, value: *mut i32) -> HRESULT,
+}
+
+unsafe impl Interface for IInspectable {
+ type Vtable = IInspectable_Vtbl;
+}
+
+unsafe impl ComInterface for IInspectable {
+ const IID: GUID = GUID::from_u128(0xaf86e2e0_b12d_4c6a_9c5a_d7aa65101e90);
+}
+
+impl CanInto<IUnknown> for IInspectable {}
+
+impl RuntimeType for IInspectable {
+ const SIGNATURE: crate::imp::ConstBuffer = crate::imp::ConstBuffer::from_slice(b"cinterface(IInspectable)");
+}
+
+impl RuntimeName for IInspectable {}
+
+#[cfg(feature = "implement")]
+impl IInspectable_Vtbl {
+ pub const fn new<Identity: IUnknownImpl, Name: RuntimeName, const OFFSET: isize>() -> Self {
+ unsafe extern "system" fn GetIids(_: *mut std::ffi::c_void, count: *mut u32, values: *mut *mut GUID) -> HRESULT {
+ // Note: even if we end up implementing this in future, it still doesn't need a this pointer
+ // since the data to be returned is type- not instance-specific so can be shared for all
+ // interfaces.
+ *count = 0;
+ *values = std::ptr::null_mut();
+ HRESULT(0)
+ }
+ unsafe extern "system" fn GetRuntimeClassName<T: RuntimeName>(_: *mut std::ffi::c_void, value: *mut *mut std::ffi::c_void) -> HRESULT {
+ let h: HSTRING = T::NAME.into(); // TODO: should be try_into
+ *value = std::mem::transmute(h);
+ HRESULT(0)
+ }
+ unsafe extern "system" fn GetTrustLevel(_: *mut std::ffi::c_void, value: *mut i32) -> HRESULT {
+ // Note: even if we end up implementing this in future, it still doesn't need a this pointer
+ // since the data to be returned is type- not instance-specific so can be shared for all
+ // interfaces.
+ *value = 0;
+ HRESULT(0)
+ }
+ Self { base: IUnknown_Vtbl::new::<Identity, OFFSET>(), GetIids, GetRuntimeClassName: GetRuntimeClassName::<Name>, GetTrustLevel }
+ }
+}
+
+impl std::fmt::Debug for IInspectable {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ // Attempts to retrieve the string representation of the object via the
+ // IStringable interface. If that fails, it will use the canonical type
+ // name to give some idea of what the object represents.
+ let name = <Self as ComInterface>::cast::<imp::IStringable>(self).and_then(|s| s.ToString()).or_else(|_| self.GetRuntimeClassName()).unwrap_or_default();
+ write!(f, "\"{}\"", name)
+ }
+}
+
+macro_rules! primitive_boxed_type {
+ ($(($t:ty, $m:ident)),+) => {
+ $(impl std::convert::TryFrom<$t> for IInspectable {
+ type Error = Error;
+ fn try_from(value: $t) -> Result<Self> {
+ imp::PropertyValue::$m(value)
+ }
+ }
+ impl std::convert::TryFrom<IInspectable> for $t {
+ type Error = Error;
+ fn try_from(value: IInspectable) -> Result<Self> {
+ <IInspectable as ComInterface>::cast::<imp::IReference<$t>>(&value)?.Value()
+ }
+ }
+ impl std::convert::TryFrom<&IInspectable> for $t {
+ type Error = Error;
+ fn try_from(value: &IInspectable) -> Result<Self> {
+ <IInspectable as ComInterface>::cast::<imp::IReference<$t>>(value)?.Value()
+ }
+ })*
+ };
+}
+primitive_boxed_type! {
+ (bool, CreateBoolean),
+ (u8, CreateUInt8),
+ (i16, CreateInt16),
+ (u16, CreateUInt16),
+ (i32, CreateInt32),
+ (u32, CreateUInt32),
+ (i64, CreateInt64),
+ (u64, CreateUInt64),
+ (f32, CreateSingle),
+ (f64, CreateDouble)
+}
+impl std::convert::TryFrom<&str> for IInspectable {
+ type Error = Error;
+ fn try_from(value: &str) -> Result<Self> {
+ let value: HSTRING = value.into();
+ imp::PropertyValue::CreateString(&value)
+ }
+}
+impl std::convert::TryFrom<HSTRING> for IInspectable {
+ type Error = Error;
+ fn try_from(value: HSTRING) -> Result<Self> {
+ imp::PropertyValue::CreateString(&value)
+ }
+}
+impl std::convert::TryFrom<&HSTRING> for IInspectable {
+ type Error = Error;
+ fn try_from(value: &HSTRING) -> Result<Self> {
+ imp::PropertyValue::CreateString(value)
+ }
+}
+impl std::convert::TryFrom<IInspectable> for HSTRING {
+ type Error = Error;
+ fn try_from(value: IInspectable) -> Result<Self> {
+ <IInspectable as ComInterface>::cast::<imp::IReference<HSTRING>>(&value)?.Value()
+ }
+}
+impl std::convert::TryFrom<&IInspectable> for HSTRING {
+ type Error = Error;
+ fn try_from(value: &IInspectable) -> Result<Self> {
+ <IInspectable as ComInterface>::cast::<imp::IReference<HSTRING>>(value)?.Value()
+ }
+}
diff --git a/third_party/rust/windows-core/src/interface.rs b/third_party/rust/windows-core/src/interface.rs
new file mode 100644
index 0000000000..602f9dbb7e
--- /dev/null
+++ b/third_party/rust/windows-core/src/interface.rs
@@ -0,0 +1,72 @@
+/// Provides low-level access to an interface vtable.
+///
+/// This trait is automatically implemented by the generated bindings and should not be
+/// implemented manually.
+///
+/// # Safety
+pub unsafe trait Interface: Sized {
+ type Vtable;
+
+ /// A reference to the interface's vtable
+ #[doc(hidden)]
+ fn vtable(&self) -> &Self::Vtable {
+ // SAFETY: the implementor of the trait guarantees that `Self` is castable to its vtable
+ unsafe { self.assume_vtable::<Self>() }
+ }
+
+ /// Cast this interface as a reference to the supplied interfaces `Vtable`
+ ///
+ /// # Safety
+ ///
+ /// This is safe if `T` is an equivalent interface to `Self` or a super interface.
+ /// In other words, `T::Vtable` must be equivalent to the beginning of `Self::Vtable`.
+ #[doc(hidden)]
+ unsafe fn assume_vtable<T: Interface>(&self) -> &T::Vtable {
+ &**(self.as_raw() as *mut *mut T::Vtable)
+ }
+
+ /// Returns the raw COM interface pointer. The resulting pointer continues to be owned by the `Interface` implementation.
+ #[inline(always)]
+ fn as_raw(&self) -> *mut std::ffi::c_void {
+ // SAFETY: implementors of this trait must guarantee that the implementing type has a pointer in-memory representation
+ unsafe { std::mem::transmute_copy(self) }
+ }
+
+ /// Returns the raw COM interface pointer and releases ownership. It the caller's responsibility to release the COM interface pointer.
+ fn into_raw(self) -> *mut std::ffi::c_void {
+ // SAFETY: implementors of this trait must guarantee that the implementing type has a pointer in-memory representation
+ let raw = self.as_raw();
+ std::mem::forget(self);
+ raw
+ }
+
+ /// Creates an `Interface` by taking ownership of the `raw` COM interface pointer.
+ ///
+ /// # Safety
+ ///
+ /// The `raw` pointer must be owned by the caller and represent a valid COM interface pointer. In other words,
+ /// it must point to a vtable beginning with the `IUnknown` function pointers and match the vtable of `Interface`.
+ unsafe fn from_raw(raw: *mut std::ffi::c_void) -> Self {
+ std::mem::transmute_copy(&raw)
+ }
+
+ /// Creates an `Interface` that is valid so long as the `raw` COM interface pointer is valid.
+ ///
+ /// # Safety
+ ///
+ /// The `raw` pointer must be a valid COM interface pointer. In other words, it must point to a vtable
+ /// beginning with the `IUnknown` function pointers and match the vtable of `Interface`.
+ unsafe fn from_raw_borrowed(raw: &*mut std::ffi::c_void) -> Option<&Self> {
+ if raw.is_null() {
+ None
+ } else {
+ Some(std::mem::transmute_copy(&raw))
+ }
+ }
+}
+
+/// # Safety
+#[doc(hidden)]
+pub unsafe fn from_raw_borrowed<T: Interface>(raw: &*mut std::ffi::c_void) -> Option<&T> {
+ T::from_raw_borrowed(raw)
+}
diff --git a/third_party/rust/windows-core/src/lib.rs b/third_party/rust/windows-core/src/lib.rs
new file mode 100644
index 0000000000..ea5c36d0c2
--- /dev/null
+++ b/third_party/rust/windows-core/src/lib.rs
@@ -0,0 +1,59 @@
+/*!
+Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs>
+*/
+
+#![doc(html_no_source)]
+#![allow(non_snake_case)]
+#![cfg_attr(windows_debugger_visualizer, debugger_visualizer(natvis_file = "../windows.natvis"))]
+
+extern crate self as windows_core;
+
+#[doc(hidden)]
+pub mod imp;
+
+mod agile_reference;
+mod array;
+mod as_impl;
+mod com_interface;
+mod error;
+mod event;
+mod guid;
+mod hresult;
+mod inspectable;
+mod interface;
+mod param;
+mod runtime_name;
+mod runtime_type;
+mod scoped_interface;
+mod strings;
+mod r#type;
+mod unknown;
+mod weak;
+
+pub use agile_reference::*;
+pub use array::*;
+pub use as_impl::*;
+pub use com_interface::*;
+pub use error::*;
+pub use event::*;
+pub use guid::*;
+pub use hresult::*;
+pub use inspectable::*;
+pub use interface::*;
+pub use param::*;
+pub use r#type::*;
+pub use runtime_name::*;
+pub use runtime_type::*;
+pub use scoped_interface::*;
+pub use strings::*;
+pub use unknown::*;
+pub use weak::*;
+
+/// A specialized [`Result`] type that provides Windows error information.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Attempts to load the factory object for the given WinRT class.
+/// This can be used to access COM interfaces implemented on a Windows Runtime class factory.
+pub fn factory<C: RuntimeName, I: ComInterface>() -> Result<I> {
+ crate::imp::factory::<C, I>()
+}
diff --git a/third_party/rust/windows-core/src/param.rs b/third_party/rust/windows-core/src/param.rs
new file mode 100644
index 0000000000..442b8e4967
--- /dev/null
+++ b/third_party/rust/windows-core/src/param.rs
@@ -0,0 +1,133 @@
+use super::*;
+
+#[doc(hidden)]
+pub enum Param<T: Type<T>> {
+ Owned(T),
+ Borrowed(T::Abi),
+}
+
+impl<T: Type<T>> Param<T> {
+ pub fn abi(&self) -> T::Abi {
+ unsafe {
+ match self {
+ Self::Owned(item) => std::mem::transmute_copy(item),
+ Self::Borrowed(borrowed) => std::mem::transmute_copy(borrowed),
+ }
+ }
+ }
+}
+
+#[doc(hidden)]
+pub trait TryIntoParam<T: Type<T>> {
+ fn try_into_param(self) -> Result<Param<T>>;
+}
+
+impl<T> TryIntoParam<T> for Option<&T>
+where
+ T: ComInterface,
+{
+ fn try_into_param(self) -> Result<Param<T>> {
+ match self {
+ Some(from) => Ok(Param::Borrowed(from.abi())),
+ None => Ok(Param::Borrowed(unsafe { std::mem::zeroed() })),
+ }
+ }
+}
+
+impl<T, U> TryIntoParam<T> for &U
+where
+ T: ComInterface,
+ U: ComInterface,
+ U: CanTryInto<T>,
+{
+ fn try_into_param(self) -> Result<Param<T>> {
+ if U::CAN_INTO {
+ Ok(Param::Borrowed(self.abi()))
+ } else {
+ Ok(Param::Owned(self.cast()?))
+ }
+ }
+}
+
+#[doc(hidden)]
+pub trait CanTryInto<T>: ComInterface
+where
+ T: ComInterface,
+{
+ const CAN_INTO: bool = false;
+}
+
+impl<T, U> CanTryInto<T> for U
+where
+ T: ComInterface,
+ U: ComInterface,
+ U: CanInto<T>,
+{
+ const CAN_INTO: bool = true;
+}
+
+#[doc(hidden)]
+pub trait CanInto<T>: Sized
+where
+ T: Clone,
+{
+ fn can_into(&self) -> &T {
+ unsafe { std::mem::transmute(self) }
+ }
+
+ fn can_clone_into(&self) -> T {
+ self.can_into().clone()
+ }
+}
+impl<T> CanInto<T> for T where T: Clone {}
+
+#[doc(hidden)]
+pub trait IntoParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized
+where
+ T: Type<T>,
+{
+ fn into_param(self) -> Param<T>;
+}
+
+impl<T> IntoParam<T> for Option<&T>
+where
+ T: Type<T>,
+{
+ fn into_param(self) -> Param<T> {
+ match self {
+ Some(item) => Param::Borrowed(item.abi()),
+ None => Param::Borrowed(unsafe { std::mem::zeroed() }),
+ }
+ }
+}
+
+impl<T, U> IntoParam<T, ReferenceType> for &U
+where
+ T: TypeKind<TypeKind = ReferenceType> + Clone,
+ U: TypeKind<TypeKind = ReferenceType> + Clone,
+ U: CanInto<T>,
+{
+ fn into_param(self) -> Param<T> {
+ Param::Borrowed(self.abi())
+ }
+}
+
+impl<T> IntoParam<T, ValueType> for &T
+where
+ T: TypeKind<TypeKind = ValueType> + Clone,
+{
+ fn into_param(self) -> Param<T> {
+ Param::Borrowed(self.abi())
+ }
+}
+
+impl<T, U> IntoParam<T, CopyType> for U
+where
+ T: TypeKind<TypeKind = CopyType> + Clone,
+ U: TypeKind<TypeKind = CopyType> + Clone,
+ U: CanInto<T>,
+{
+ fn into_param(self) -> Param<T> {
+ unsafe { Param::Owned(std::mem::transmute_copy(&self)) }
+ }
+}
diff --git a/third_party/rust/windows-core/src/runtime_name.rs b/third_party/rust/windows-core/src/runtime_name.rs
new file mode 100644
index 0000000000..c6af26ae61
--- /dev/null
+++ b/third_party/rust/windows-core/src/runtime_name.rs
@@ -0,0 +1,5 @@
+#[doc(hidden)]
+pub trait RuntimeName {
+ // TODO: needs to use ConstBuffer like RuntimeType to allow generic interfaces to have names for GetRuntimeClassName
+ const NAME: &'static str = "";
+}
diff --git a/third_party/rust/windows-core/src/runtime_type.rs b/third_party/rust/windows-core/src/runtime_type.rs
new file mode 100644
index 0000000000..c85a3889bc
--- /dev/null
+++ b/third_party/rust/windows-core/src/runtime_type.rs
@@ -0,0 +1,30 @@
+use super::*;
+
+#[doc(hidden)]
+pub trait RuntimeType: Type<Self> {
+ const SIGNATURE: crate::imp::ConstBuffer;
+}
+
+macro_rules! primitives {
+ ($(($t:ty, $s:literal)),+) => {
+ $(
+ impl RuntimeType for $t {
+ const SIGNATURE: crate::imp::ConstBuffer = crate::imp::ConstBuffer::from_slice($s);
+ }
+ )*
+ };
+}
+
+primitives! {
+ (bool, b"b1"),
+ (i8, b"i1"),
+ (u8, b"u1"),
+ (i16, b"i2"),
+ (u16, b"u2"),
+ (i32, b"i4"),
+ (u32, b"u4"),
+ (i64, b"i8"),
+ (u64, b"u8"),
+ (f32, b"f4"),
+ (f64, b"f8")
+}
diff --git a/third_party/rust/windows-core/src/scoped_interface.rs b/third_party/rust/windows-core/src/scoped_interface.rs
new file mode 100644
index 0000000000..1505b82b6e
--- /dev/null
+++ b/third_party/rust/windows-core/src/scoped_interface.rs
@@ -0,0 +1,36 @@
+use super::*;
+
+#[doc(hidden)]
+#[repr(C)]
+pub struct ScopedHeap {
+ pub vtable: *const std::ffi::c_void,
+ pub this: *const std::ffi::c_void,
+}
+
+#[doc(hidden)]
+pub struct ScopedInterface<'a, T: Interface> {
+ interface: T,
+ lifetime: std::marker::PhantomData<&'a T>,
+}
+
+impl<'a, T: Interface> ScopedInterface<'a, T> {
+ pub fn new(interface: T) -> Self {
+ Self { interface, lifetime: std::marker::PhantomData }
+ }
+}
+
+impl<'a, T: Interface> std::ops::Deref for ScopedInterface<'a, T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.interface
+ }
+}
+
+impl<'a, T: Interface> Drop for ScopedInterface<'a, T> {
+ fn drop(&mut self) {
+ unsafe {
+ let _ = std::boxed::Box::from_raw(self.interface.as_raw() as *const _ as *mut ScopedHeap);
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/strings/bstr.rs b/third_party/rust/windows-core/src/strings/bstr.rs
new file mode 100644
index 0000000000..5003117f92
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/bstr.rs
@@ -0,0 +1,162 @@
+use super::*;
+
+/// A BSTR string ([BSTR](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/string-manipulation-functions))
+/// is a length-prefixed wide string.
+#[repr(transparent)]
+pub struct BSTR(*const u16);
+
+impl BSTR {
+ /// Create an empty `BSTR`.
+ ///
+ /// This function does not allocate memory.
+ pub const fn new() -> Self {
+ Self(std::ptr::null_mut())
+ }
+
+ /// Returns `true` if the string is empty.
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns the length of the string.
+ pub fn len(&self) -> usize {
+ if self.0.is_null() {
+ 0
+ } else {
+ unsafe { crate::imp::SysStringLen(self.0) as usize }
+ }
+ }
+
+ /// Get the string as 16-bit wide characters (wchars).
+ pub fn as_wide(&self) -> &[u16] {
+ if self.0.is_null() {
+ return &[];
+ }
+
+ unsafe { std::slice::from_raw_parts(self.0, self.len()) }
+ }
+
+ /// Create a `BSTR` from a slice of 16 bit characters (wchars).
+ pub fn from_wide(value: &[u16]) -> Result<Self> {
+ if value.is_empty() {
+ return Ok(Self::new());
+ }
+
+ let result = unsafe { Self(crate::imp::SysAllocStringLen(value.as_ptr(), value.len().try_into()?)) };
+
+ if result.is_empty() {
+ Err(crate::imp::E_OUTOFMEMORY.into())
+ } else {
+ Ok(result)
+ }
+ }
+
+ /// # Safety
+ #[doc(hidden)]
+ pub unsafe fn from_raw(raw: *const u16) -> Self {
+ Self(raw)
+ }
+
+ /// # Safety
+ #[doc(hidden)]
+ pub fn into_raw(self) -> *const u16 {
+ unsafe { std::mem::transmute(self) }
+ }
+}
+
+impl std::clone::Clone for BSTR {
+ fn clone(&self) -> Self {
+ Self::from_wide(self.as_wide()).unwrap()
+ }
+}
+
+impl std::convert::From<&str> for BSTR {
+ fn from(value: &str) -> Self {
+ let value: std::vec::Vec<u16> = value.encode_utf16().collect();
+ Self::from_wide(&value).unwrap()
+ }
+}
+
+impl std::convert::From<std::string::String> for BSTR {
+ fn from(value: std::string::String) -> Self {
+ value.as_str().into()
+ }
+}
+
+impl std::convert::From<&std::string::String> for BSTR {
+ fn from(value: &std::string::String) -> Self {
+ value.as_str().into()
+ }
+}
+
+impl<'a> std::convert::TryFrom<&'a BSTR> for std::string::String {
+ type Error = std::string::FromUtf16Error;
+
+ fn try_from(value: &BSTR) -> std::result::Result<Self, Self::Error> {
+ std::string::String::from_utf16(value.as_wide())
+ }
+}
+
+impl std::convert::TryFrom<BSTR> for std::string::String {
+ type Error = std::string::FromUtf16Error;
+
+ fn try_from(value: BSTR) -> std::result::Result<Self, Self::Error> {
+ std::string::String::try_from(&value)
+ }
+}
+
+impl std::default::Default for BSTR {
+ fn default() -> Self {
+ Self(std::ptr::null_mut())
+ }
+}
+
+impl std::fmt::Display for BSTR {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::write!(f, "{}", crate::Decode(|| std::char::decode_utf16(self.as_wide().iter().cloned())))
+ }
+}
+
+impl std::fmt::Debug for BSTR {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::write!(f, "{}", self)
+ }
+}
+
+impl std::cmp::PartialEq for BSTR {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_wide() == other.as_wide()
+ }
+}
+
+impl std::cmp::Eq for BSTR {}
+
+impl std::cmp::PartialEq<BSTR> for &str {
+ fn eq(&self, other: &BSTR) -> bool {
+ other == self
+ }
+}
+
+impl std::cmp::PartialEq<BSTR> for String {
+ fn eq(&self, other: &BSTR) -> bool {
+ other == self
+ }
+}
+
+impl<T: AsRef<str> + ?Sized> std::cmp::PartialEq<T> for BSTR {
+ fn eq(&self, other: &T) -> bool {
+ self.as_wide().iter().copied().eq(other.as_ref().encode_utf16())
+ }
+}
+
+impl std::ops::Drop for BSTR {
+ fn drop(&mut self) {
+ if !self.0.is_null() {
+ unsafe { crate::imp::SysFreeString(self.0) }
+ }
+ }
+}
+
+impl TypeKind for BSTR {
+ type TypeKind = ValueType;
+}
diff --git a/third_party/rust/windows-core/src/strings/hstring.rs b/third_party/rust/windows-core/src/strings/hstring.rs
new file mode 100644
index 0000000000..a0a7f59fab
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/hstring.rs
@@ -0,0 +1,458 @@
+use super::*;
+
+/// A WinRT string ([HSTRING](https://docs.microsoft.com/en-us/windows/win32/winrt/hstring))
+/// is reference-counted and immutable.
+#[repr(transparent)]
+pub struct HSTRING(Option<std::ptr::NonNull<Header>>);
+
+impl HSTRING {
+ /// Create an empty `HSTRING`.
+ ///
+ /// This function does not allocate memory.
+ pub const fn new() -> Self {
+ Self(None)
+ }
+
+ /// Returns `true` if the string is empty.
+ pub const fn is_empty(&self) -> bool {
+ // An empty HSTRING is represented by a null pointer.
+ self.0.is_none()
+ }
+
+ /// Returns the length of the string.
+ pub fn len(&self) -> usize {
+ if let Some(header) = self.get_header() {
+ header.len as usize
+ } else {
+ 0
+ }
+ }
+
+ /// Get the string as 16-bit wide characters (wchars).
+ pub fn as_wide(&self) -> &[u16] {
+ unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len()) }
+ }
+
+ /// Returns a raw pointer to the `HSTRING` buffer.
+ pub fn as_ptr(&self) -> *const u16 {
+ if let Some(header) = self.get_header() {
+ header.data
+ } else {
+ const EMPTY: [u16; 1] = [0];
+ EMPTY.as_ptr()
+ }
+ }
+
+ /// Create a `HSTRING` from a slice of 16 bit characters (wchars).
+ pub fn from_wide(value: &[u16]) -> Result<Self> {
+ unsafe { Self::from_wide_iter(value.iter().copied(), value.len()) }
+ }
+
+ /// Get the contents of this `HSTRING` as a String lossily.
+ pub fn to_string_lossy(&self) -> std::string::String {
+ std::string::String::from_utf16_lossy(self.as_wide())
+ }
+
+ /// Get the contents of this `HSTRING` as a OsString.
+ #[cfg(windows)]
+ pub fn to_os_string(&self) -> std::ffi::OsString {
+ std::os::windows::ffi::OsStringExt::from_wide(self.as_wide())
+ }
+
+ /// # Safety
+ /// len must not be less than the number of items in the iterator.
+ unsafe fn from_wide_iter<I: Iterator<Item = u16>>(iter: I, len: usize) -> Result<Self> {
+ if len == 0 {
+ return Ok(Self::new());
+ }
+
+ let ptr = Header::alloc(len.try_into()?)?;
+
+ // Place each utf-16 character into the buffer and
+ // increase len as we go along.
+ for (index, wide) in iter.enumerate() {
+ debug_assert!(index < len);
+
+ std::ptr::write((*ptr).data.add(index), wide);
+ (*ptr).len = index as u32 + 1;
+ }
+
+ // Write a 0 byte to the end of the buffer.
+ std::ptr::write((*ptr).data.offset((*ptr).len as isize), 0);
+ Ok(Self(std::ptr::NonNull::new(ptr)))
+ }
+
+ fn get_header(&self) -> Option<&Header> {
+ if let Some(header) = &self.0 {
+ unsafe { Some(header.as_ref()) }
+ } else {
+ None
+ }
+ }
+}
+
+impl RuntimeType for HSTRING {
+ const SIGNATURE: crate::imp::ConstBuffer = crate::imp::ConstBuffer::from_slice(b"string");
+}
+
+impl TypeKind for HSTRING {
+ type TypeKind = ValueType;
+}
+
+impl Default for HSTRING {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Clone for HSTRING {
+ fn clone(&self) -> Self {
+ if let Some(header) = self.get_header() {
+ Self(std::ptr::NonNull::new(header.duplicate().unwrap()))
+ } else {
+ Self::new()
+ }
+ }
+}
+
+impl Drop for HSTRING {
+ fn drop(&mut self) {
+ if self.is_empty() {
+ return;
+ }
+
+ if let Some(header) = self.0.take() {
+ // REFERENCE_FLAG indicates a string backed by static or stack memory that is
+ // thus not reference-counted and does not need to be freed.
+ unsafe {
+ let header = header.as_ref();
+ if header.flags & REFERENCE_FLAG == 0 && header.count.release() == 0 {
+ crate::imp::heap_free(header as *const _ as *mut _);
+ }
+ }
+ }
+ }
+}
+
+unsafe impl Send for HSTRING {}
+unsafe impl Sync for HSTRING {}
+
+impl std::fmt::Display for HSTRING {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", Decode(|| std::char::decode_utf16(self.as_wide().iter().cloned())))
+ }
+}
+
+impl std::fmt::Debug for HSTRING {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "\"{}\"", self)
+ }
+}
+
+impl std::convert::From<&str> for HSTRING {
+ fn from(value: &str) -> Self {
+ unsafe { Self::from_wide_iter(value.encode_utf16(), value.len()).unwrap() }
+ }
+}
+
+impl std::convert::From<std::string::String> for HSTRING {
+ fn from(value: std::string::String) -> Self {
+ value.as_str().into()
+ }
+}
+
+impl std::convert::From<&std::string::String> for HSTRING {
+ fn from(value: &std::string::String) -> Self {
+ value.as_str().into()
+ }
+}
+
+#[cfg(windows)]
+impl std::convert::From<&std::path::Path> for HSTRING {
+ fn from(value: &std::path::Path) -> Self {
+ value.as_os_str().into()
+ }
+}
+
+#[cfg(windows)]
+impl std::convert::From<&std::ffi::OsStr> for HSTRING {
+ fn from(value: &std::ffi::OsStr) -> Self {
+ unsafe { Self::from_wide_iter(std::os::windows::ffi::OsStrExt::encode_wide(value), value.len()).unwrap() }
+ }
+}
+
+#[cfg(windows)]
+impl std::convert::From<std::ffi::OsString> for HSTRING {
+ fn from(value: std::ffi::OsString) -> Self {
+ value.as_os_str().into()
+ }
+}
+
+#[cfg(windows)]
+impl std::convert::From<&std::ffi::OsString> for HSTRING {
+ fn from(value: &std::ffi::OsString) -> Self {
+ value.as_os_str().into()
+ }
+}
+
+impl Eq for HSTRING {}
+
+impl Ord for HSTRING {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.as_wide().cmp(other.as_wide())
+ }
+}
+
+impl PartialOrd for HSTRING {
+ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl PartialEq for HSTRING {
+ fn eq(&self, other: &Self) -> bool {
+ *self.as_wide() == *other.as_wide()
+ }
+}
+
+impl PartialEq<std::string::String> for HSTRING {
+ fn eq(&self, other: &std::string::String) -> bool {
+ *self == **other
+ }
+}
+
+impl PartialEq<std::string::String> for &HSTRING {
+ fn eq(&self, other: &std::string::String) -> bool {
+ **self == **other
+ }
+}
+
+impl PartialEq<&std::string::String> for HSTRING {
+ fn eq(&self, other: &&std::string::String) -> bool {
+ *self == ***other
+ }
+}
+
+impl PartialEq<str> for HSTRING {
+ fn eq(&self, other: &str) -> bool {
+ self.as_wide().iter().copied().eq(other.encode_utf16())
+ }
+}
+
+impl PartialEq<str> for &HSTRING {
+ fn eq(&self, other: &str) -> bool {
+ **self == *other
+ }
+}
+
+impl PartialEq<&str> for HSTRING {
+ fn eq(&self, other: &&str) -> bool {
+ *self == **other
+ }
+}
+
+impl PartialEq<HSTRING> for str {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == *self
+ }
+}
+
+impl PartialEq<HSTRING> for &str {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == **self
+ }
+}
+
+impl PartialEq<&HSTRING> for str {
+ fn eq(&self, other: &&HSTRING) -> bool {
+ **other == *self
+ }
+}
+
+impl PartialEq<HSTRING> for std::string::String {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == **self
+ }
+}
+
+impl PartialEq<HSTRING> for &std::string::String {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == ***self
+ }
+}
+
+impl PartialEq<&HSTRING> for std::string::String {
+ fn eq(&self, other: &&HSTRING) -> bool {
+ **other == **self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<std::ffi::OsString> for HSTRING {
+ fn eq(&self, other: &std::ffi::OsString) -> bool {
+ *self == **other
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<std::ffi::OsString> for &HSTRING {
+ fn eq(&self, other: &std::ffi::OsString) -> bool {
+ **self == **other
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<&std::ffi::OsString> for HSTRING {
+ fn eq(&self, other: &&std::ffi::OsString) -> bool {
+ *self == ***other
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<std::ffi::OsStr> for HSTRING {
+ fn eq(&self, other: &std::ffi::OsStr) -> bool {
+ self.as_wide().iter().copied().eq(std::os::windows::ffi::OsStrExt::encode_wide(other))
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<std::ffi::OsStr> for &HSTRING {
+ fn eq(&self, other: &std::ffi::OsStr) -> bool {
+ **self == *other
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<&std::ffi::OsStr> for HSTRING {
+ fn eq(&self, other: &&std::ffi::OsStr) -> bool {
+ *self == **other
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<HSTRING> for std::ffi::OsStr {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == *self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<HSTRING> for &std::ffi::OsStr {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == **self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<&HSTRING> for std::ffi::OsStr {
+ fn eq(&self, other: &&HSTRING) -> bool {
+ **other == *self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<HSTRING> for std::ffi::OsString {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == **self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<HSTRING> for &std::ffi::OsString {
+ fn eq(&self, other: &HSTRING) -> bool {
+ *other == ***self
+ }
+}
+
+#[cfg(windows)]
+impl PartialEq<&HSTRING> for std::ffi::OsString {
+ fn eq(&self, other: &&HSTRING) -> bool {
+ **other == **self
+ }
+}
+
+impl<'a> std::convert::TryFrom<&'a HSTRING> for std::string::String {
+ type Error = std::string::FromUtf16Error;
+
+ fn try_from(hstring: &HSTRING) -> std::result::Result<Self, Self::Error> {
+ std::string::String::from_utf16(hstring.as_wide())
+ }
+}
+
+impl std::convert::TryFrom<HSTRING> for std::string::String {
+ type Error = std::string::FromUtf16Error;
+
+ fn try_from(hstring: HSTRING) -> std::result::Result<Self, Self::Error> {
+ std::string::String::try_from(&hstring)
+ }
+}
+
+#[cfg(windows)]
+impl<'a> std::convert::From<&'a HSTRING> for std::ffi::OsString {
+ fn from(hstring: &HSTRING) -> Self {
+ hstring.to_os_string()
+ }
+}
+
+#[cfg(windows)]
+impl std::convert::From<HSTRING> for std::ffi::OsString {
+ fn from(hstring: HSTRING) -> Self {
+ Self::from(&hstring)
+ }
+}
+
+impl IntoParam<PCWSTR> for &HSTRING {
+ fn into_param(self) -> Param<PCWSTR> {
+ Param::Owned(PCWSTR(self.as_ptr()))
+ }
+}
+
+const REFERENCE_FLAG: u32 = 1;
+
+#[repr(C)]
+struct Header {
+ flags: u32,
+ len: u32,
+ _0: u32,
+ _1: u32,
+ data: *mut u16,
+ count: crate::imp::RefCount,
+ buffer_start: u16,
+}
+
+impl Header {
+ fn alloc(len: u32) -> Result<*mut Header> {
+ debug_assert!(len != 0);
+ // Allocate enough space for header and two bytes per character.
+ // The space for the terminating null character is already accounted for inside of `Header`.
+ let alloc_size = std::mem::size_of::<Header>() + 2 * len as usize;
+
+ let header = crate::imp::heap_alloc(alloc_size)? as *mut Header;
+
+ // SAFETY: uses `std::ptr::write` (since `header` is unintialized). `Header` is safe to be all zeros.
+ unsafe {
+ header.write(std::mem::MaybeUninit::<Header>::zeroed().assume_init());
+ (*header).len = len;
+ (*header).count = crate::imp::RefCount::new(1);
+ (*header).data = &mut (*header).buffer_start;
+ }
+ Ok(header)
+ }
+
+ fn duplicate(&self) -> Result<*mut Header> {
+ if self.flags & REFERENCE_FLAG == 0 {
+ // If this is not a "fast pass" string then simply increment the reference count.
+ self.count.add_ref();
+ Ok(self as *const Header as *mut Header)
+ } else {
+ // Otherwise, allocate a new string and copy the value into the new string.
+ let copy = Header::alloc(self.len)?;
+ // SAFETY: since we are duplicating the string it is safe to copy all data from self to the initialized `copy`.
+ // We copy `len + 1` characters since `len` does not account for the terminating null character.
+ unsafe {
+ std::ptr::copy_nonoverlapping(self.data, (*copy).data, self.len as usize + 1);
+ }
+ Ok(copy)
+ }
+ }
+}
diff --git a/third_party/rust/windows-core/src/strings/literals.rs b/third_party/rust/windows-core/src/strings/literals.rs
new file mode 100644
index 0000000000..b9a08e529e
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/literals.rs
@@ -0,0 +1,156 @@
+/// A literal UTF-8 string with a trailing null terminator.
+#[macro_export]
+macro_rules! s {
+ ($s:literal) => {
+ $crate::PCSTR::from_raw(::std::concat!($s, '\0').as_ptr())
+ };
+}
+
+/// A literal UTF-16 wide string with a trailing null terminator.
+#[macro_export]
+macro_rules! w {
+ ($s:literal) => {{
+ const INPUT: &[u8] = $s.as_bytes();
+ const OUTPUT_LEN: usize = $crate::utf16_len(INPUT) + 1;
+ const OUTPUT: &[u16; OUTPUT_LEN] = {
+ let mut buffer = [0; OUTPUT_LEN];
+ let mut input_pos = 0;
+ let mut output_pos = 0;
+ while let Some((mut code_point, new_pos)) = $crate::decode_utf8_char(INPUT, input_pos) {
+ input_pos = new_pos;
+ if code_point <= 0xffff {
+ buffer[output_pos] = code_point as u16;
+ output_pos += 1;
+ } else {
+ code_point -= 0x10000;
+ buffer[output_pos] = 0xd800 + (code_point >> 10) as u16;
+ output_pos += 1;
+ buffer[output_pos] = 0xdc00 + (code_point & 0x3ff) as u16;
+ output_pos += 1;
+ }
+ }
+ &{ buffer }
+ };
+ $crate::PCWSTR::from_raw(OUTPUT.as_ptr())
+ }};
+}
+
+/// A literal HSTRING, length-prefixed wide string with a trailing null terminator.
+#[macro_export]
+macro_rules! h {
+ ($s:literal) => {{
+ const INPUT: &[u8] = $s.as_bytes();
+ const OUTPUT_LEN: usize = $crate::utf16_len(INPUT) + 1;
+ const RESULT: $crate::HSTRING = {
+ if OUTPUT_LEN == 1 {
+ unsafe { ::std::mem::transmute(::std::ptr::null::<u16>()) }
+ } else {
+ const OUTPUT: $crate::PCWSTR = $crate::w!($s);
+ const HEADER: $crate::HSTRING_HEADER = $crate::HSTRING_HEADER { flags: 0x11, len: (OUTPUT_LEN - 1) as u32, padding1: 0, padding2: 0, ptr: OUTPUT.as_ptr() };
+ // SAFETY: an `HSTRING` is exactly equivalent to a pointer to an `HSTRING_HEADER`
+ unsafe { ::std::mem::transmute::<&$crate::HSTRING_HEADER, $crate::HSTRING>(&HEADER) }
+ }
+ };
+ &RESULT
+ }};
+}
+
+#[doc(hidden)]
+pub const fn decode_utf8_char(bytes: &[u8], mut pos: usize) -> Option<(u32, usize)> {
+ if bytes.len() == pos {
+ return None;
+ }
+ let ch = bytes[pos] as u32;
+ pos += 1;
+ if ch <= 0x7f {
+ return Some((ch, pos));
+ }
+ if (ch & 0xe0) == 0xc0 {
+ if bytes.len() - pos < 1 {
+ return None;
+ }
+ let ch2 = bytes[pos] as u32;
+ pos += 1;
+ if (ch2 & 0xc0) != 0x80 {
+ return None;
+ }
+ let result: u32 = ((ch & 0x1f) << 6) | (ch2 & 0x3f);
+ if result <= 0x7f {
+ return None;
+ }
+ return Some((result, pos));
+ }
+ if (ch & 0xf0) == 0xe0 {
+ if bytes.len() - pos < 2 {
+ return None;
+ }
+ let ch2 = bytes[pos] as u32;
+ pos += 1;
+ let ch3 = bytes[pos] as u32;
+ pos += 1;
+ if (ch2 & 0xc0) != 0x80 || (ch3 & 0xc0) != 0x80 {
+ return None;
+ }
+ let result = ((ch & 0x0f) << 12) | ((ch2 & 0x3f) << 6) | (ch3 & 0x3f);
+ if result <= 0x7ff || (0xd800 <= result && result <= 0xdfff) {
+ return None;
+ }
+ return Some((result, pos));
+ }
+ if (ch & 0xf8) == 0xf0 {
+ if bytes.len() - pos < 3 {
+ return None;
+ }
+ let ch2 = bytes[pos] as u32;
+ pos += 1;
+ let ch3 = bytes[pos] as u32;
+ pos += 1;
+ let ch4 = bytes[pos] as u32;
+ pos += 1;
+ if (ch2 & 0xc0) != 0x80 || (ch3 & 0xc0) != 0x80 || (ch4 & 0xc0) != 0x80 {
+ return None;
+ }
+ let result = ((ch & 0x07) << 18) | ((ch2 & 0x3f) << 12) | ((ch3 & 0x3f) << 6) | (ch4 & 0x3f);
+ if result <= 0xffff || 0x10ffff < result {
+ return None;
+ }
+ return Some((result, pos));
+ }
+ None
+}
+
+#[doc(hidden)]
+#[repr(C)]
+pub struct HSTRING_HEADER {
+ pub flags: u32,
+ pub len: u32,
+ pub padding1: u32,
+ pub padding2: u32,
+ pub ptr: *const u16,
+}
+
+#[doc(hidden)]
+pub const fn utf16_len(bytes: &[u8]) -> usize {
+ let mut pos = 0;
+ let mut len = 0;
+ while let Some((code_point, new_pos)) = decode_utf8_char(bytes, pos) {
+ pos = new_pos;
+ len += if code_point <= 0xffff { 1 } else { 2 };
+ }
+ len
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ assert_eq!(decode_utf8_char(b"123", 0), Some((0x31, 1)));
+ assert_eq!(decode_utf8_char(b"123", 1), Some((0x32, 2)));
+ assert_eq!(decode_utf8_char(b"123", 2), Some((0x33, 3)));
+ assert_eq!(decode_utf8_char(b"123", 3), None);
+ assert_eq!(utf16_len(b"123"), 3);
+ assert_eq!(utf16_len("α & ω".as_bytes()), 5);
+ }
+}
diff --git a/third_party/rust/windows-core/src/strings/mod.rs b/third_party/rust/windows-core/src/strings/mod.rs
new file mode 100644
index 0000000000..94e7bfd992
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/mod.rs
@@ -0,0 +1,83 @@
+mod bstr;
+mod hstring;
+mod literals;
+mod pcstr;
+mod pcwstr;
+mod pstr;
+mod pwstr;
+
+pub use bstr::*;
+pub use hstring::*;
+#[doc(hidden)]
+pub use literals::*;
+pub use pcstr::*;
+pub use pcwstr::*;
+pub use pstr::*;
+pub use pwstr::*;
+
+use super::*;
+
+extern "C" {
+ #[doc(hidden)]
+ pub fn strlen(s: PCSTR) -> usize;
+ #[doc(hidden)]
+ pub fn wcslen(s: PCWSTR) -> usize;
+}
+
+/// An internal helper for decoding an iterator of chars and displaying them
+#[doc(hidden)]
+pub struct Decode<F>(pub F);
+
+impl<F, R, E> std::fmt::Display for Decode<F>
+where
+ F: Clone + FnOnce() -> R,
+ R: IntoIterator<Item = std::result::Result<char, E>>,
+{
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ use std::fmt::Write;
+ let iter = self.0.clone();
+ for c in iter().into_iter() {
+ f.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
+ }
+ Ok(())
+ }
+}
+
+/// Mirror of `std::char::decode_utf16` for utf-8.
+fn decode_utf8(mut buffer: &[u8]) -> impl Iterator<Item = std::result::Result<char, std::str::Utf8Error>> + '_ {
+ let mut current = "".chars();
+ let mut previous_error = None;
+ std::iter::from_fn(move || {
+ loop {
+ match (current.next(), previous_error) {
+ (Some(c), _) => return Some(Ok(c)),
+ // Return the previous error
+ (None, Some(e)) => {
+ previous_error = None;
+ return Some(Err(e));
+ }
+ // We're completely done
+ (None, None) if buffer.is_empty() => return None,
+ (None, None) => {
+ match std::str::from_utf8(buffer) {
+ Ok(s) => {
+ current = s.chars();
+ buffer = &[];
+ }
+ Err(e) => {
+ let (valid, rest) = buffer.split_at(e.valid_up_to());
+ // Skip the invalid sequence and stop completely if we ended early
+ let invalid_sequence_length = e.error_len()?;
+ buffer = &rest[invalid_sequence_length..];
+
+ // Set the current iterator to the valid section and indicate previous error
+ // SAFETY: `valid` is known to be valid utf-8 from error
+ current = unsafe { std::str::from_utf8_unchecked(valid) }.chars();
+ previous_error = Some(e);
+ }
+ }
+ }
+ }
+ }
+ })
+}
diff --git a/third_party/rust/windows-core/src/strings/pcstr.rs b/third_party/rust/windows-core/src/strings/pcstr.rs
new file mode 100644
index 0000000000..161db28785
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/pcstr.rs
@@ -0,0 +1,73 @@
+use super::*;
+
+/// A pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct PCSTR(pub *const u8);
+
+impl PCSTR {
+ /// Construct a new `PCSTR` from a raw pointer
+ pub const fn from_raw(ptr: *const u8) -> Self {
+ Self(ptr)
+ }
+
+ /// Construct a null `PCSTR`
+ pub fn null() -> Self {
+ Self(std::ptr::null())
+ }
+
+ /// Returns a raw pointer to the `PCSTR`
+ pub fn as_ptr(&self) -> *const u8 {
+ self.0
+ }
+
+ /// Checks whether the `PCSTR` is null
+ pub fn is_null(&self) -> bool {
+ self.0.is_null()
+ }
+
+ /// String data without the trailing 0
+ ///
+ /// # Safety
+ ///
+ /// The `PCSTR`'s pointer needs to be valid for reads up until and including the next `\0`.
+ pub unsafe fn as_bytes(&self) -> &[u8] {
+ let len = super::strlen(*self);
+ std::slice::from_raw_parts(self.0, len)
+ }
+
+ /// Copy the `PCSTR` into a Rust `String`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PCSTR::as_bytes`.
+ pub unsafe fn to_string(&self) -> std::result::Result<String, std::string::FromUtf8Error> {
+ String::from_utf8(self.as_bytes().into())
+ }
+
+ /// Allow this string to be displayed.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PCSTR::as_bytes`.
+ pub unsafe fn display(&self) -> impl std::fmt::Display + '_ {
+ Decode(move || decode_utf8(self.as_bytes()))
+ }
+}
+
+impl TypeKind for PCSTR {
+ type TypeKind = CopyType;
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn can_display() {
+ // 💖 followed by an invalid byte sequence and then an incomplete one
+ let s = [240, 159, 146, 150, 255, 240, 159, 0];
+ let s = PCSTR::from_raw(s.as_ptr());
+ assert_eq!("💖�", format!("{}", unsafe { s.display() }));
+ }
+}
diff --git a/third_party/rust/windows-core/src/strings/pcwstr.rs b/third_party/rust/windows-core/src/strings/pcwstr.rs
new file mode 100644
index 0000000000..8112d83855
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/pcwstr.rs
@@ -0,0 +1,69 @@
+use super::*;
+
+/// A pointer to a constant null-terminated string of 16-bit Unicode characters.
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct PCWSTR(pub *const u16);
+
+impl PCWSTR {
+ /// Construct a new `PCWSTR` from a raw pointer
+ pub const fn from_raw(ptr: *const u16) -> Self {
+ Self(ptr)
+ }
+
+ /// Construct a null `PCWSTR`
+ pub const fn null() -> Self {
+ Self(std::ptr::null())
+ }
+
+ /// Returns a raw pointer to the `PCWSTR`
+ pub const fn as_ptr(&self) -> *const u16 {
+ self.0
+ }
+
+ /// Checks whether the `PCWSTR` is null
+ pub fn is_null(&self) -> bool {
+ self.0.is_null()
+ }
+
+ /// String data without the trailing 0
+ ///
+ /// # Safety
+ ///
+ /// The `PCWSTR`'s pointer needs to be valid for reads up until and including the next `\0`.
+ pub unsafe fn as_wide(&self) -> &[u16] {
+ let len = super::wcslen(*self);
+ std::slice::from_raw_parts(self.0, len)
+ }
+
+ /// Copy the `PCWSTR` into a Rust `String`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PCWSTR::as_wide`.
+ pub unsafe fn to_string(&self) -> std::result::Result<String, std::string::FromUtf16Error> {
+ String::from_utf16(self.as_wide())
+ }
+
+ /// Copy the `PCWSTR` into an `HSTRING`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PCWSTR::as_wide`.
+ pub unsafe fn to_hstring(&self) -> Result<HSTRING> {
+ HSTRING::from_wide(self.as_wide())
+ }
+
+ /// Allow this string to be displayed.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PCWSTR::as_wide`.
+ pub unsafe fn display(&self) -> impl std::fmt::Display + '_ {
+ Decode(move || std::char::decode_utf16(self.as_wide().iter().cloned()))
+ }
+}
+
+impl TypeKind for PCWSTR {
+ type TypeKind = CopyType;
+}
diff --git a/third_party/rust/windows-core/src/strings/pstr.rs b/third_party/rust/windows-core/src/strings/pstr.rs
new file mode 100644
index 0000000000..d395953e0e
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/pstr.rs
@@ -0,0 +1,60 @@
+use super::*;
+
+/// A pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct PSTR(pub *mut u8);
+
+impl PSTR {
+ /// Construct a new `PSTR` from a raw pointer
+ pub const fn from_raw(ptr: *mut u8) -> Self {
+ Self(ptr)
+ }
+
+ /// Construct a null `PSTR`
+ pub fn null() -> Self {
+ Self(std::ptr::null_mut())
+ }
+
+ /// Returns a raw pointer to the `PSTR`
+ pub fn as_ptr(&self) -> *mut u8 {
+ self.0
+ }
+
+ /// Checks whether the `PSTR` is null
+ pub fn is_null(&self) -> bool {
+ self.0.is_null()
+ }
+
+ /// String data without the trailing 0
+ ///
+ /// # Safety
+ ///
+ /// The `PSTR`'s pointer needs to be valid for reads up until and including the next `\0`.
+ pub unsafe fn as_bytes(&self) -> &[u8] {
+ let len = super::strlen(PCSTR::from_raw(self.0));
+ std::slice::from_raw_parts(self.0, len)
+ }
+
+ /// Copy the `PSTR` into a Rust `String`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PSTR::as_bytes`.
+ pub unsafe fn to_string(&self) -> std::result::Result<String, std::string::FromUtf8Error> {
+ String::from_utf8(self.as_bytes().into())
+ }
+
+ /// Allow this string to be displayed.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PSTR::as_bytes`.
+ pub unsafe fn display(&self) -> impl std::fmt::Display + '_ {
+ Decode(move || decode_utf8(self.as_bytes()))
+ }
+}
+
+impl TypeKind for PSTR {
+ type TypeKind = CopyType;
+}
diff --git a/third_party/rust/windows-core/src/strings/pwstr.rs b/third_party/rust/windows-core/src/strings/pwstr.rs
new file mode 100644
index 0000000000..7eb21084d0
--- /dev/null
+++ b/third_party/rust/windows-core/src/strings/pwstr.rs
@@ -0,0 +1,69 @@
+use super::*;
+
+/// A pointer to a null-terminated string of 16-bit Unicode characters.
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct PWSTR(pub *mut u16);
+
+impl PWSTR {
+ /// Construct a new `PWSTR` from a raw pointer.
+ pub const fn from_raw(ptr: *mut u16) -> Self {
+ Self(ptr)
+ }
+
+ /// Construct a null `PWSTR`.
+ pub fn null() -> Self {
+ Self(std::ptr::null_mut())
+ }
+
+ /// Returns a raw pointer to the `PWSTR`.
+ pub fn as_ptr(&self) -> *mut u16 {
+ self.0
+ }
+
+ /// Checks whether the `PWSTR` is null.
+ pub fn is_null(&self) -> bool {
+ self.0.is_null()
+ }
+
+ /// String data without the trailing 0.
+ ///
+ /// # Safety
+ ///
+ /// The `PWSTR`'s pointer needs to be valid for reads up until and including the next `\0`.
+ pub unsafe fn as_wide(&self) -> &[u16] {
+ let len = super::wcslen(PCWSTR::from_raw(self.0));
+ std::slice::from_raw_parts(self.0, len)
+ }
+
+ /// Copy the `PWSTR` into a Rust `String`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PWSTR::as_wide`.
+ pub unsafe fn to_string(&self) -> std::result::Result<String, std::string::FromUtf16Error> {
+ String::from_utf16(self.as_wide())
+ }
+
+ /// Copy the `PWSTR` into an `HSTRING`.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PWSTR::as_wide`.
+ pub unsafe fn to_hstring(&self) -> Result<HSTRING> {
+ HSTRING::from_wide(self.as_wide())
+ }
+
+ /// Allow this string to be displayed.
+ ///
+ /// # Safety
+ ///
+ /// See the safety information for `PWSTR::as_wide`.
+ pub unsafe fn display(&self) -> impl std::fmt::Display + '_ {
+ Decode(move || std::char::decode_utf16(self.as_wide().iter().cloned()))
+ }
+}
+
+impl TypeKind for PWSTR {
+ type TypeKind = CopyType;
+}
diff --git a/third_party/rust/windows-core/src/type.rs b/third_party/rust/windows-core/src/type.rs
new file mode 100644
index 0000000000..c0d5aa5d61
--- /dev/null
+++ b/third_party/rust/windows-core/src/type.rs
@@ -0,0 +1,110 @@
+use super::*;
+
+#[doc(hidden)]
+pub trait TypeKind {
+ type TypeKind;
+}
+
+#[doc(hidden)]
+pub struct ReferenceType;
+
+#[doc(hidden)]
+pub struct ValueType;
+
+#[doc(hidden)]
+pub struct CopyType;
+
+#[doc(hidden)]
+pub trait Type<T: TypeKind, C = <T as TypeKind>::TypeKind>: TypeKind + Sized + Clone {
+ type Abi;
+ type Default;
+
+ fn abi(&self) -> Self::Abi {
+ unsafe { std::mem::transmute_copy(self) }
+ }
+
+ /// # Safety
+ unsafe fn from_abi(abi: Self::Abi) -> Result<Self>;
+ fn from_default(default: &Self::Default) -> Result<Self>;
+}
+
+impl<T> Type<T, ReferenceType> for T
+where
+ T: TypeKind<TypeKind = ReferenceType> + Clone,
+{
+ type Abi = *mut std::ffi::c_void;
+ type Default = Option<Self>;
+
+ unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
+ if !abi.is_null() {
+ Ok(std::mem::transmute_copy(&abi))
+ } else {
+ Err(Error::OK)
+ }
+ }
+
+ fn from_default(default: &Self::Default) -> Result<Self> {
+ default.as_ref().cloned().ok_or(Error::OK)
+ }
+}
+
+impl<T> Type<T, ValueType> for T
+where
+ T: TypeKind<TypeKind = ValueType> + Clone,
+{
+ type Abi = std::mem::MaybeUninit<Self>;
+ type Default = Self;
+
+ unsafe fn from_abi(abi: std::mem::MaybeUninit<Self>) -> Result<Self> {
+ Ok(abi.assume_init())
+ }
+
+ fn from_default(default: &Self::Default) -> Result<Self> {
+ Ok(default.clone())
+ }
+}
+
+impl<T> Type<T, CopyType> for T
+where
+ T: TypeKind<TypeKind = CopyType> + Clone,
+{
+ type Abi = Self;
+ type Default = Self;
+
+ unsafe fn from_abi(abi: Self) -> Result<Self> {
+ Ok(abi)
+ }
+
+ fn from_default(default: &Self) -> Result<Self> {
+ Ok(default.clone())
+ }
+}
+
+impl<T: Interface> TypeKind for T {
+ type TypeKind = ReferenceType;
+}
+
+impl<T> TypeKind for *mut T {
+ type TypeKind = CopyType;
+}
+
+macro_rules! primitives {
+ ($($t:ty),+) => {
+ $(
+ impl TypeKind for $t {
+ type TypeKind = CopyType;
+ }
+ )*
+ };
+}
+
+primitives!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, usize, isize);
+
+#[doc(hidden)]
+pub type AbiType<T> = <T as Type<T>>::Abi;
+
+/// # Safety
+#[doc(hidden)]
+pub unsafe fn from_abi<T: Type<T>>(abi: T::Abi) -> Result<T> {
+ T::from_abi(abi)
+}
diff --git a/third_party/rust/windows-core/src/unknown.rs b/third_party/rust/windows-core/src/unknown.rs
new file mode 100644
index 0000000000..3d3e6d92e6
--- /dev/null
+++ b/third_party/rust/windows-core/src/unknown.rs
@@ -0,0 +1,103 @@
+use super::*;
+
+/// All COM interfaces (and thus WinRT classes and interfaces) implement
+/// [IUnknown](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown)
+/// under the hood to provide reference-counted lifetime management as well as the ability
+/// to query for additional interfaces that the object may implement.
+#[repr(transparent)]
+pub struct IUnknown(std::ptr::NonNull<std::ffi::c_void>);
+
+#[doc(hidden)]
+#[repr(C)]
+pub struct IUnknown_Vtbl {
+ pub QueryInterface: unsafe extern "system" fn(this: *mut std::ffi::c_void, iid: *const GUID, interface: *mut *mut std::ffi::c_void) -> HRESULT,
+ pub AddRef: unsafe extern "system" fn(this: *mut std::ffi::c_void) -> u32,
+ pub Release: unsafe extern "system" fn(this: *mut std::ffi::c_void) -> u32,
+}
+
+unsafe impl Interface for IUnknown {
+ type Vtable = IUnknown_Vtbl;
+}
+
+unsafe impl ComInterface for IUnknown {
+ const IID: GUID = GUID::from_u128(0x00000000_0000_0000_c000_000000000046);
+}
+
+impl Clone for IUnknown {
+ fn clone(&self) -> Self {
+ unsafe {
+ (self.vtable().AddRef)(std::mem::transmute_copy(self));
+ }
+
+ Self(self.0)
+ }
+}
+
+impl Drop for IUnknown {
+ fn drop(&mut self) {
+ unsafe {
+ (self.vtable().Release)(std::mem::transmute_copy(self));
+ }
+ }
+}
+
+impl PartialEq for IUnknown {
+ fn eq(&self, other: &Self) -> bool {
+ // Since COM objects may implement multiple interfaces, COM identity can only
+ // be determined by querying for `IUnknown` explicitly and then comparing the
+ // pointer values. This works since `QueryInterface` is required to return
+ // the same pointer value for queries for `IUnknown`.
+ self.cast::<IUnknown>().unwrap().0 == other.cast::<IUnknown>().unwrap().0
+ }
+}
+
+impl Eq for IUnknown {}
+
+impl std::fmt::Debug for IUnknown {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_tuple("IUnknown").field(&self.0).finish()
+ }
+}
+
+#[doc(hidden)]
+pub trait IUnknownImpl {
+ type Impl;
+ /// Get a reference to the backing implementation.
+ fn get_impl(&self) -> &Self::Impl;
+
+ /// The classic `QueryInterface` method from COM.
+ ///
+ /// # Safety
+ ///
+ /// This function is safe to call as long as the interface pointer is non-null and valid for writes
+ /// of an interface pointer.
+ unsafe fn QueryInterface(&self, iid: *const GUID, interface: *mut *mut std::ffi::c_void) -> HRESULT;
+ /// Increments the reference count of the interface
+ fn AddRef(&self) -> u32;
+ /// Decrements the reference count causing the interface's memory to be freed when the count is 0
+ ///
+ /// # Safety
+ ///
+ /// This function should only be called when the interfacer pointer is no longer used as calling `Release`
+ /// on a non-aliased interface pointer and then using that interface pointer may result in use after free.
+ unsafe fn Release(&self) -> u32;
+}
+
+#[cfg(feature = "implement")]
+impl IUnknown_Vtbl {
+ pub const fn new<T: IUnknownImpl, const OFFSET: isize>() -> Self {
+ unsafe extern "system" fn QueryInterface<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void, iid: *const GUID, interface: *mut *mut std::ffi::c_void) -> HRESULT {
+ let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
+ (*this).QueryInterface(iid, interface)
+ }
+ unsafe extern "system" fn AddRef<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void) -> u32 {
+ let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
+ (*this).AddRef()
+ }
+ unsafe extern "system" fn Release<T: IUnknownImpl, const OFFSET: isize>(this: *mut std::ffi::c_void) -> u32 {
+ let this = (this as *mut *mut std::ffi::c_void).offset(OFFSET) as *mut T;
+ (*this).Release()
+ }
+ Self { QueryInterface: QueryInterface::<T, OFFSET>, AddRef: AddRef::<T, OFFSET>, Release: Release::<T, OFFSET> }
+ }
+}
diff --git a/third_party/rust/windows-core/src/weak.rs b/third_party/rust/windows-core/src/weak.rs
new file mode 100644
index 0000000000..fa3eb46452
--- /dev/null
+++ b/third_party/rust/windows-core/src/weak.rs
@@ -0,0 +1,23 @@
+use super::*;
+use std::marker::PhantomData;
+
+/// `Weak` holds a non-owning reference to an object.
+#[derive(Clone, PartialEq, Eq, Default)]
+pub struct Weak<I: ComInterface>(Option<crate::imp::IWeakReference>, PhantomData<I>);
+
+impl<I: ComInterface> Weak<I> {
+ /// Creates a new `Weak` object without any backing object.
+ pub fn new() -> Self {
+ Self(None, PhantomData)
+ }
+
+ /// Attempts to upgrade the weak reference to a strong reference.
+ pub fn upgrade(&self) -> Option<I> {
+ self.0.as_ref().and_then(|inner| unsafe { inner.Resolve().ok() })
+ }
+
+ pub(crate) fn downgrade(source: &crate::imp::IWeakReferenceSource) -> Result<Self> {
+ let reference = unsafe { source.GetWeakReference().ok() };
+ Ok(Self(reference, PhantomData))
+ }
+}
diff --git a/third_party/rust/windows-core/windows.natvis b/third_party/rust/windows-core/windows.natvis
new file mode 100644
index 0000000000..d7dcabd321
--- /dev/null
+++ b/third_party/rust/windows-core/windows.natvis
@@ -0,0 +1,84 @@
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+ <Type Name="windows_core::array::Array&lt;*&gt;">
+ <DisplayString>{{ len={len} }}</DisplayString>
+
+ <Expand>
+ <Item Name="[len]">len</Item>
+ <ArrayItems>
+ <Size>len</Size>
+ <ValuePointer>data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="windows_core::error::Error">
+ <Expand>
+ <ExpandedItem>code</ExpandedItem>
+ <Item Name="[info]">info</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="windows_core::hresult::HRESULT">
+ <DisplayString>{(HRESULT)__0}</DisplayString>
+ </Type>
+
+ <Type Name="windows_core::imp::ref_count::RefCount">
+ <DisplayString>{__0}</DisplayString>
+ </Type>
+
+ <Type Name="windows_core::strings::hstring::HSTRING">
+ <Intrinsic Name="header" Expression="*((windows_core::strings::hstring::Header**)this)" ReturnType="windows_core::strings::hstring::Header *" />
+ <Intrinsic Name="is_empty" Expression="header() == nullptr" />
+ <DisplayString Condition="is_empty()">""</DisplayString>
+ <DisplayString>{((char16_t*)header()->data),[header()->len]su}</DisplayString>
+
+ <Expand>
+ <Item Name="[len]">is_empty() ? (unsigned int)0 : header()->len</Item>
+ <Item Name="[ref_count]" Condition="!is_empty()">header()->count</Item>
+ <Item Name="[flags]" Condition="!is_empty()">header()->flags</Item>
+ <Synthetic Name="[chars]" Condition="!is_empty()">
+ <Expand>
+ <ArrayItems>
+ <Size>header()->len</Size>
+ <ValuePointer>(char16_t*)header()->data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Synthetic>
+ </Expand>
+ </Type>
+
+ <Type Name="windows_core::strings::pstr::PSTR">
+ <AlternativeType Name="windows_core::strings::pcstr::PCSTR" />
+ <Intrinsic Name="len" Expression="strlen(((char*)__0))" />
+ <DisplayString>{(char*)__0,[len()]s8}</DisplayString>
+ <Expand>
+ <Item Name="[len]">len()</Item>
+ <Synthetic Name="[chars]">
+ <Expand>
+ <ArrayItems>
+ <Size>len()</Size>
+ <ValuePointer>(char*)__0</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Synthetic>
+ </Expand>
+ </Type>
+
+ <Type Name="windows_core::strings::pwstr::PWSTR">
+ <AlternativeType Name="windows_core::strings::pcwstr::PCWSTR" />
+ <Intrinsic Name="len" Expression="wcslen(((WCHAR*)__0))" />
+ <DisplayString>{(char16_t*)__0,[len()]su}</DisplayString>
+
+ <Expand>
+ <Item Name="[len]">len()</Item>
+ <Synthetic Name="[chars]">
+ <Expand>
+ <ArrayItems>
+ <Size>len()</Size>
+ <ValuePointer>(char16_t*)__0</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Synthetic>
+ </Expand>
+ </Type>
+</AutoVisualizer>