diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
index 4164a07029..2095a6fd4a 100644
--- a/.github/workflows/clippy.yml
+++ b/.github/workflows/clippy.yml
@@ -234,6 +234,8 @@ jobs:
run: cargo clippy -p test_standalone
- name: Clippy test_string_param
run: cargo clippy -p test_string_param
+ - name: Clippy test_strings
+ run: cargo clippy -p test_strings
- name: Clippy test_structs
run: cargo clippy -p test_structs
- name: Clippy test_sys
@@ -288,6 +290,8 @@ jobs:
run: cargo clippy -p windows-registry
- name: Clippy windows-result
run: cargo clippy -p windows-result
+ - name: Clippy windows-strings
+ run: cargo clippy -p windows-strings
- name: Clippy windows-sys
run: cargo clippy -p windows-sys
- name: Clippy windows-targets
diff --git a/.github/workflows/msrv-windows-registry.yml b/.github/workflows/msrv-windows-registry.yml
index a789efcdeb..6ada003a60 100644
--- a/.github/workflows/msrv-windows-registry.yml
+++ b/.github/workflows/msrv-windows-registry.yml
@@ -16,10 +16,7 @@ jobs:
strategy:
matrix:
rust: [1.60.0, stable, nightly]
- runs-on:
- - windows-latest
- - ubuntu-latest
- runs-on: ${{ matrix.runs-on }}
+ runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
diff --git a/.github/workflows/msrv-windows-strings.yml b/.github/workflows/msrv-windows-strings.yml
new file mode 100644
index 0000000000..9378fbc879
--- /dev/null
+++ b/.github/workflows/msrv-windows-strings.yml
@@ -0,0 +1,26 @@
+name: windows-strings
+
+on:
+ pull_request:
+ push:
+ paths-ignore:
+ - '.github/ISSUE_TEMPLATE/**'
+ branches:
+ - master
+
+env:
+ RUSTFLAGS: -Dwarnings
+
+jobs:
+ check:
+ strategy:
+ matrix:
+ rust: [1.60.0, stable, nightly]
+ runs-on: windows-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Prepare
+ run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
+ - name: Check
+ run: cargo check -p windows-strings --all-features
diff --git a/.github/workflows/msrv-windows-version.yml b/.github/workflows/msrv-windows-version.yml
index a39df7670b..e643a78c8f 100644
--- a/.github/workflows/msrv-windows-version.yml
+++ b/.github/workflows/msrv-windows-version.yml
@@ -16,10 +16,7 @@ jobs:
strategy:
matrix:
rust: [1.60.0, stable, nightly]
- runs-on:
- - windows-latest
- - ubuntu-latest
- runs-on: ${{ matrix.runs-on }}
+ runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
diff --git a/.github/workflows/msrv-windows.yml b/.github/workflows/msrv-windows.yml
index ebd08bc1c4..90a9b34c51 100644
--- a/.github/workflows/msrv-windows.yml
+++ b/.github/workflows/msrv-windows.yml
@@ -16,10 +16,7 @@ jobs:
strategy:
matrix:
rust: [1.70.0, stable, nightly]
- runs-on:
- - windows-2022
- - ubuntu-latest
- runs-on: ${{ matrix.runs-on }}
+ runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
diff --git a/.github/workflows/no-default-features.yml b/.github/workflows/no-default-features.yml
index 4049e286c7..36318f1d59 100644
--- a/.github/workflows/no-default-features.yml
+++ b/.github/workflows/no-default-features.yml
@@ -48,6 +48,8 @@ jobs:
run: cargo check -p windows-registry --no-default-features
- name: Check windows-result
run: cargo check -p windows-result --no-default-features
+ - name: Check windows-strings
+ run: cargo check -p windows-strings --no-default-features
- name: Check windows-sys
run: cargo check -p windows-sys --no-default-features
- name: Check windows-targets
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4aaaccfa78..e6944e4e45 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -262,6 +262,8 @@ jobs:
run: cargo clean
- name: Test test_string_param
run: cargo test -p test_string_param --target ${{ matrix.target }} ${{ matrix.etc }}
+ - name: Test test_strings
+ run: cargo test -p test_strings --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_structs
run: cargo test -p test_structs --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_sys
@@ -316,6 +318,8 @@ jobs:
run: cargo test -p windows-registry --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test windows-result
run: cargo test -p windows-result --target ${{ matrix.target }} ${{ matrix.etc }}
+ - name: Test windows-strings
+ run: cargo test -p windows-strings --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test windows-sys
run: cargo test -p windows-sys --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test windows-targets
diff --git a/crates/libs/core/.natvis b/crates/libs/core/.natvis
index d3a3630361..192804a511 100644
--- a/crates/libs/core/.natvis
+++ b/crates/libs/core/.natvis
@@ -15,60 +15,4 @@
{__0}
-
-
-
-
- ""
- {header()->data,[header()->len]su}
-
-
- - is_empty() ? (unsigned int)0 : header()->len
- - header()->count
- - header()->flags
-
-
-
- header()->len
- (char16_t*)header()->data
-
-
-
-
-
-
-
-
-
- {(char*)__0,[len()]s8}
-
- - len()
-
-
-
- len()
- (char*)__0
-
-
-
-
-
-
-
-
-
- {(char16_t*)__0,[len()]su}
-
-
- - len()
-
-
-
- len()
- (char16_t*)__0
-
-
-
-
-
diff --git a/crates/libs/core/Cargo.toml b/crates/libs/core/Cargo.toml
index f250d93a10..52cb1fdf2a 100644
--- a/crates/libs/core/Cargo.toml
+++ b/crates/libs/core/Cargo.toml
@@ -25,6 +25,10 @@ path = "../targets"
version = "0.1.1"
path = "../result"
+[dependencies.windows-strings]
+version = "0.1.0"
+path = "../strings"
+
[dependencies]
windows-implement = { path = "../implement", version = "0.57.0" }
windows-interface = { path = "../interface", version = "0.57.0" }
diff --git a/crates/libs/core/readme.md b/crates/libs/core/readme.md
index 5cde16742c..e65156e040 100644
--- a/crates/libs/core/readme.md
+++ b/crates/libs/core/readme.md
@@ -81,8 +81,8 @@ fn main() {
WaitForSingleObject(event, 0);
CloseHandle(event);
- MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
- MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
+ MessageBoxA(0 as _, s!("Ansi"), s!("Caption"), MB_OK);
+ MessageBoxW(0 as _, w!("Wide"), w!("Caption"), MB_OK);
}
}
```
diff --git a/crates/libs/core/src/imp/bindings.rs b/crates/libs/core/src/imp/bindings.rs
index b03b763bd9..599bc419a7 100644
--- a/crates/libs/core/src/imp/bindings.rs
+++ b/crates/libs/core/src/imp/bindings.rs
@@ -22,9 +22,6 @@ windows_targets::link!("ole32.dll" "system" fn CoTaskMemAlloc(cb : usize) -> *mu
windows_targets::link!("ole32.dll" "system" fn CoTaskMemFree(pv : *const core::ffi::c_void));
windows_targets::link!("ole32.dll" "system" fn PropVariantClear(pvar : *mut PROPVARIANT) -> HRESULT);
windows_targets::link!("ole32.dll" "system" fn PropVariantCopy(pvardest : *mut PROPVARIANT, pvarsrc : *const PROPVARIANT) -> HRESULT);
-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);
windows_targets::link!("oleaut32.dll" "system" fn VariantClear(pvarg : *mut VARIANT) -> HRESULT);
windows_targets::link!("oleaut32.dll" "system" fn VariantCopy(pvargdest : *mut VARIANT, pvargsrc : *const VARIANT) -> HRESULT);
windows_targets::link!("propsys.dll" "system" fn PropVariantCompareEx(propvar1 : *const PROPVARIANT, propvar2 : *const PROPVARIANT, unit : PROPVAR_COMPARE_UNIT, flags : PROPVAR_COMPARE_FLAGS) -> i32);
diff --git a/crates/libs/core/src/lib.rs b/crates/libs/core/src/lib.rs
index 9b0579e189..5ac18db1b5 100644
--- a/crates/libs/core/src/lib.rs
+++ b/crates/libs/core/src/lib.rs
@@ -15,7 +15,7 @@ extern crate self as windows_core;
#[macro_use]
extern crate alloc;
-use alloc::{boxed::Box, string::String, vec::Vec};
+use alloc::boxed::Box;
#[doc(hidden)]
pub mod imp;
@@ -38,7 +38,6 @@ mod r#ref;
mod runtime_name;
mod runtime_type;
mod scoped_interface;
-mod strings;
mod r#type;
mod unknown;
mod variant;
@@ -63,13 +62,13 @@ pub use r#type::*;
pub use runtime_name::*;
pub use runtime_type::*;
pub use scoped_interface::*;
-pub use strings::*;
pub use unknown::*;
pub use variant::*;
pub use weak::*;
pub use windows_implement::implement;
pub use windows_interface::interface;
pub use windows_result::*;
+pub use windows_strings::*;
/// 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.
diff --git a/crates/libs/strings/.natvis b/crates/libs/strings/.natvis
new file mode 100644
index 0000000000..1b6a5c7565
--- /dev/null
+++ b/crates/libs/strings/.natvis
@@ -0,0 +1,62 @@
+
+
+
+
+
+ ""
+ {header()->data,[header()->len]su}
+
+
+ - is_empty() ? (unsigned int)0 : header()->len
+ - header()->count
+ - header()->flags
+
+
+
+ header()->len
+ (char16_t*)header()->data
+
+
+
+
+
+
+
+
+
+ {(char*)__0,[len()]s8}
+
+ - len()
+
+
+
+ len()
+ (char*)__0
+
+
+
+
+
+
+
+
+
+ {(char16_t*)__0,[len()]su}
+
+
+ - len()
+
+
+
+ len()
+ (char16_t*)__0
+
+
+
+
+
+
+
+ {__0}
+
+
diff --git a/crates/libs/strings/Cargo.toml b/crates/libs/strings/Cargo.toml
new file mode 100644
index 0000000000..46643e0ced
--- /dev/null
+++ b/crates/libs/strings/Cargo.toml
@@ -0,0 +1,30 @@
+[package]
+name = "windows-strings"
+version = "0.1.0"
+authors = ["Microsoft"]
+edition = "2021"
+rust-version = "1.60"
+license = "MIT OR Apache-2.0"
+description = "Rust for Windows"
+repository = "https://github.com/microsoft/windows-rs"
+readme = "readme.md"
+categories = ["os::windows-apis"]
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+default-target = "x86_64-pc-windows-msvc"
+targets = []
+
+[dependencies.windows-targets]
+version = "0.52.5"
+path = "../targets"
+
+[dependencies.windows-result]
+version = "0.1.1"
+path = "../result"
+
+[features]
+default = ["std"]
+std = []
diff --git a/crates/libs/strings/license-apache-2.0 b/crates/libs/strings/license-apache-2.0
new file mode 100644
index 0000000000..b5ed4ecec2
--- /dev/null
+++ b/crates/libs/strings/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/crates/libs/strings/license-mit b/crates/libs/strings/license-mit
new file mode 100644
index 0000000000..9e841e7a26
--- /dev/null
+++ b/crates/libs/strings/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/crates/libs/strings/readme.md b/crates/libs/strings/readme.md
new file mode 100644
index 0000000000..6d1389f26b
--- /dev/null
+++ b/crates/libs/strings/readme.md
@@ -0,0 +1,36 @@
+## Windows string types
+
+The [windows-strings](https://crates.io/crates/windows-strings) crate provides common Windows string types used by various Windows APIs.
+
+* [Getting started](https://kennykerr.ca/rust-getting-started/)
+* [Samples](https://github.com/microsoft/windows-rs/tree/0.57.0/crates/samples)
+* [Releases](https://github.com/microsoft/windows-rs/releases)
+
+Start by adding the following to your Cargo.toml file:
+
+```toml
+[dependencies.windows-strings]
+version = "0.1"
+```
+
+Use the Windows string types as needed:
+
+```rust
+use windows_strings::*;
+
+const A: PCSTR = s!("ansi");
+const W: PCWSTR = w!("wide");
+
+fn main() -> Result<()> {
+ let b = BSTR::from("bstr");
+ let h = HSTRING::from("hstring");
+
+ assert_eq!(b, "bstr");
+ assert_eq!(h, "hstring");
+
+ assert_eq!(unsafe { A.to_string()? }, "ansi");
+ assert_eq!(unsafe { W.to_string()? }, "wide");
+
+ Ok(())
+}
+```
diff --git a/crates/libs/strings/src/bindings.rs b/crates/libs/strings/src/bindings.rs
new file mode 100644
index 0000000000..5ac479c727
--- /dev/null
+++ b/crates/libs/strings/src/bindings.rs
@@ -0,0 +1,20 @@
+#![allow(
+ non_snake_case,
+ non_upper_case_globals,
+ non_camel_case_types,
+ dead_code,
+ clippy::all
+)]
+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!("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 E_OUTOFMEMORY: HRESULT = 0x8007000E_u32 as _;
+pub type HANDLE = *mut core::ffi::c_void;
+pub type HEAP_FLAGS = u32;
+pub type HRESULT = i32;
+pub type PCWSTR = *const u16;
diff --git a/crates/libs/core/src/strings/bstr.rs b/crates/libs/strings/src/bstr.rs
similarity index 92%
rename from crates/libs/core/src/strings/bstr.rs
rename to crates/libs/strings/src/bstr.rs
index 750ff32075..dd413449e0 100644
--- a/crates/libs/core/src/strings/bstr.rs
+++ b/crates/libs/strings/src/bstr.rs
@@ -23,7 +23,7 @@ impl BSTR {
if self.0.is_null() {
0
} else {
- unsafe { imp::SysStringLen(self.0) as usize }
+ unsafe { bindings::SysStringLen(self.0) as usize }
}
}
@@ -49,14 +49,14 @@ impl BSTR {
}
let result = unsafe {
- Self(imp::SysAllocStringLen(
+ Self(bindings::SysAllocStringLen(
value.as_ptr(),
value.len().try_into()?,
))
};
if result.is_empty() {
- Err(imp::E_OUTOFMEMORY.into())
+ Err(Error::from_hresult(HRESULT(bindings::E_OUTOFMEMORY)))
} else {
Ok(result)
}
@@ -83,7 +83,7 @@ impl Clone for BSTR {
impl From<&str> for BSTR {
fn from(value: &str) -> Self {
- let value: Vec = value.encode_utf16().collect();
+ let value: alloc::vec::Vec = value.encode_utf16().collect();
Self::from_wide(&value).unwrap()
}
}
@@ -170,7 +170,7 @@ impl + ?Sized> PartialEq for BSTR {
impl Drop for BSTR {
fn drop(&mut self) {
if !self.0.is_null() {
- unsafe { imp::SysFreeString(self.0) }
+ unsafe { bindings::SysFreeString(self.0) }
}
}
}
diff --git a/crates/libs/core/src/strings/mod.rs b/crates/libs/strings/src/decode.rs
similarity index 86%
rename from crates/libs/core/src/strings/mod.rs
rename to crates/libs/strings/src/decode.rs
index 3033118c97..dbc9e2ea23 100644
--- a/crates/libs/core/src/strings/mod.rs
+++ b/crates/libs/strings/src/decode.rs
@@ -1,29 +1,5 @@
-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;
-}
-
/// An internal helper for decoding an iterator of chars and displaying them
-struct Decode(pub F);
+pub struct Decode(pub F);
impl core::fmt::Display for Decode
where
@@ -41,7 +17,7 @@ where
}
/// Mirror of `std::char::decode_utf16` for utf-8.
-fn decode_utf8(
+pub fn decode_utf8(
mut buffer: &[u8],
) -> impl Iterator- > + '_ {
let mut current = "".chars();
diff --git a/crates/libs/strings/src/heap.rs b/crates/libs/strings/src/heap.rs
new file mode 100644
index 0000000000..ffcb305bfd
--- /dev/null
+++ b/crates/libs/strings/src/heap.rs
@@ -0,0 +1,40 @@
+use super::*;
+use core::ffi::c_void;
+
+/// Allocate memory of size `bytes` using `HeapAlloc`.
+pub fn heap_alloc(bytes: usize) -> crate::Result<*mut c_void> {
+ #[cfg(windows)]
+ let ptr: *mut c_void = unsafe { bindings::HeapAlloc(bindings::GetProcessHeap(), 0, bytes) };
+
+ #[cfg(not(windows))]
+ let ptr: *mut c_void = unsafe {
+ extern "C" {
+ fn malloc(bytes: usize) -> *mut c_void;
+ }
+
+ malloc(bytes)
+ };
+
+ if ptr.is_null() {
+ Err(Error::from_hresult(HRESULT(bindings::E_OUTOFMEMORY)))
+ } else {
+ Ok(ptr)
+ }
+}
+
+/// Free memory allocated by `heap_alloc`.
+pub unsafe fn heap_free(ptr: *mut c_void) {
+ #[cfg(windows)]
+ {
+ bindings::HeapFree(bindings::GetProcessHeap(), 0, ptr);
+ }
+
+ #[cfg(not(windows))]
+ {
+ extern "C" {
+ fn free(ptr: *mut c_void);
+ }
+
+ free(ptr);
+ }
+}
diff --git a/crates/libs/core/src/strings/hstring.rs b/crates/libs/strings/src/hstring.rs
similarity index 97%
rename from crates/libs/core/src/strings/hstring.rs
rename to crates/libs/strings/src/hstring.rs
index c6b8a3472b..8de3c265f2 100644
--- a/crates/libs/core/src/strings/hstring.rs
+++ b/crates/libs/strings/src/hstring.rs
@@ -115,7 +115,7 @@ impl Drop for HSTRING {
unsafe {
let header = header.as_ref();
if header.flags & REFERENCE_FLAG == 0 && header.count.release() == 0 {
- imp::heap_free(header as *const _ as *mut _);
+ heap_free(header as *const _ as *mut _);
}
}
}
@@ -417,7 +417,7 @@ struct Header {
_0: u32,
_1: u32,
data: *mut u16,
- count: imp::RefCount,
+ count: RefCount,
buffer_start: u16,
}
@@ -428,15 +428,16 @@ impl Header {
// The space for the terminating null character is already accounted for inside of `Header`.
let alloc_size = core::mem::size_of::() + 2 * len as usize;
- let header = imp::heap_alloc(alloc_size)? as *mut Header;
+ let header = heap_alloc(alloc_size)? as *mut Header;
- // SAFETY: uses `ptr::write` (since `header` is unintialized). `Header` is safe to be all zeros.
unsafe {
+ // Use `ptr::write` (since `header` is unintialized). `Header` is safe to be all zeros.
header.write(core::mem::MaybeUninit::::zeroed().assume_init());
(*header).len = len;
- (*header).count = imp::RefCount::new(1);
+ (*header).count = RefCount::new(1);
(*header).data = &mut (*header).buffer_start;
}
+
Ok(header)
}
diff --git a/crates/libs/strings/src/lib.rs b/crates/libs/strings/src/lib.rs
new file mode 100644
index 0000000000..9039e9b54f
--- /dev/null
+++ b/crates/libs/strings/src/lib.rs
@@ -0,0 +1,52 @@
+/*!
+Learn more about Rust for Windows here:
+*/
+
+#![allow(non_snake_case)]
+#![cfg_attr(
+ windows_debugger_visualizer,
+ debugger_visualizer(natvis_file = "../.natvis")
+)]
+#![cfg_attr(all(not(feature = "std")), no_std)]
+
+extern crate alloc;
+use alloc::string::String;
+
+pub use windows_result::Result;
+use windows_result::*;
+
+mod bstr;
+pub use bstr::*;
+
+mod hstring;
+pub use hstring::*;
+
+mod bindings;
+
+mod decode;
+use decode::*;
+
+mod ref_count;
+use ref_count::*;
+
+mod heap;
+use heap::*;
+
+mod literals;
+pub use literals::*;
+
+mod pcstr;
+pub use pcstr::*;
+
+mod pcwstr;
+pub use pcwstr::*;
+
+mod pstr;
+pub use pstr::*;
+
+mod pwstr;
+pub use pwstr::*;
+
+extern "C" {
+ fn strlen(s: PCSTR) -> usize;
+}
diff --git a/crates/libs/core/src/strings/literals.rs b/crates/libs/strings/src/literals.rs
similarity index 100%
rename from crates/libs/core/src/strings/literals.rs
rename to crates/libs/strings/src/literals.rs
diff --git a/crates/libs/core/src/strings/pcstr.rs b/crates/libs/strings/src/pcstr.rs
similarity index 100%
rename from crates/libs/core/src/strings/pcstr.rs
rename to crates/libs/strings/src/pcstr.rs
diff --git a/crates/libs/core/src/strings/pcwstr.rs b/crates/libs/strings/src/pcwstr.rs
similarity index 83%
rename from crates/libs/core/src/strings/pcwstr.rs
rename to crates/libs/strings/src/pcwstr.rs
index 8ffa40a0fe..687413d394 100644
--- a/crates/libs/core/src/strings/pcwstr.rs
+++ b/crates/libs/strings/src/pcwstr.rs
@@ -32,26 +32,10 @@ impl PCWSTR {
///
/// The `PCWSTR`'s pointer needs to be valid for reads up until and including the next `\0`.
pub unsafe fn len(&self) -> usize {
- #[cfg(windows)]
- let len = {
- extern "C" {
- fn wcslen(s: *const u16) -> usize;
- }
- wcslen(self.0)
- };
-
- #[cfg(not(windows))]
- let len = {
- let mut len = 0;
- let mut ptr = self.0;
- while ptr.read() != 0 {
- len += 1;
- ptr = ptr.add(1);
- }
- len
- };
-
- len
+ extern "C" {
+ fn wcslen(s: *const u16) -> usize;
+ }
+ wcslen(self.0)
}
/// Returns `true` if the string length is zero, and `false` otherwise.
diff --git a/crates/libs/core/src/strings/pstr.rs b/crates/libs/strings/src/pstr.rs
similarity index 100%
rename from crates/libs/core/src/strings/pstr.rs
rename to crates/libs/strings/src/pstr.rs
diff --git a/crates/libs/core/src/strings/pwstr.rs b/crates/libs/strings/src/pwstr.rs
similarity index 100%
rename from crates/libs/core/src/strings/pwstr.rs
rename to crates/libs/strings/src/pwstr.rs
diff --git a/crates/libs/strings/src/ref_count.rs b/crates/libs/strings/src/ref_count.rs
new file mode 100644
index 0000000000..c6309f9fc9
--- /dev/null
+++ b/crates/libs/strings/src/ref_count.rs
@@ -0,0 +1,27 @@
+use core::sync::atomic::{fence, AtomicI32, Ordering};
+
+#[repr(transparent)]
+#[derive(Default)]
+pub struct RefCount(pub(crate) AtomicI32);
+
+impl RefCount {
+ pub fn new(count: u32) -> Self {
+ Self(AtomicI32::new(count as i32))
+ }
+
+ pub fn add_ref(&self) -> u32 {
+ (self.0.fetch_add(1, Ordering::Relaxed) + 1) as u32
+ }
+
+ pub fn release(&self) -> u32 {
+ let remaining = self.0.fetch_sub(1, Ordering::Release) - 1;
+
+ match remaining.cmp(&0) {
+ core::cmp::Ordering::Equal => fence(Ordering::Acquire),
+ core::cmp::Ordering::Less => panic!("Object has been over-released."),
+ core::cmp::Ordering::Greater => {}
+ }
+
+ remaining as u32
+ }
+}
diff --git a/crates/libs/sys/readme.md b/crates/libs/sys/readme.md
index 92da0a10b7..f86fe68728 100644
--- a/crates/libs/sys/readme.md
+++ b/crates/libs/sys/readme.md
@@ -82,8 +82,8 @@ fn main() {
WaitForSingleObject(event, 0);
CloseHandle(event);
- MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
- MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
+ MessageBoxA(0 as _, s!("Ansi"), s!("Caption"), MB_OK);
+ MessageBoxW(0 as _, w!("Wide"), w!("Caption"), MB_OK);
}
}
```
diff --git a/crates/libs/windows/readme.md b/crates/libs/windows/readme.md
index 92da0a10b7..f86fe68728 100644
--- a/crates/libs/windows/readme.md
+++ b/crates/libs/windows/readme.md
@@ -82,8 +82,8 @@ fn main() {
WaitForSingleObject(event, 0);
CloseHandle(event);
- MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
- MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
+ MessageBoxA(0 as _, s!("Ansi"), s!("Caption"), MB_OK);
+ MessageBoxW(0 as _, w!("Wide"), w!("Caption"), MB_OK);
}
}
```
diff --git a/crates/tests/debugger_visualizer/tests/test.rs b/crates/tests/debugger_visualizer/tests/test.rs
index 5f5fe01285..4754e62070 100644
--- a/crates/tests/debugger_visualizer/tests/test.rs
+++ b/crates/tests/debugger_visualizer/tests/test.rs
@@ -64,8 +64,8 @@ array : { len=0xd } [Type: windows_core::array::Array]
[11] : 0x21 [Type: unsigned char]
[12] : 0x0 [Type: unsigned char]
-pstr : "This is a PSTR" [Type: windows_core::strings::pstr::PSTR]
- [] [Type: windows_core::strings::pstr::PSTR]
+pstr : "This is a PSTR" [Type: windows_strings::pstr::PSTR]
+ [] [Type: windows_strings::pstr::PSTR]
[len] : 0xe
[chars]
[0] : 84 'T' [Type: char]
@@ -83,8 +83,8 @@ pstr : "This is a PSTR" [Type: windows_core::strings::pstr::PSTR]
[12] : 84 'T' [Type: char]
[13] : 82 'R' [Type: char]
-pcstr : "This is a PCSTR" [Type: windows_core::strings::pcstr::PCSTR]
- [] [Type: windows_core::strings::pcstr::PCSTR]
+pcstr : "This is a PCSTR" [Type: windows_strings::pcstr::PCSTR]
+ [] [Type: windows_strings::pcstr::PCSTR]
[len] : 0xf
[chars]
[0] : 84 'T' [Type: char]
@@ -103,8 +103,8 @@ pcstr : "This is a PCSTR" [Type: windows_core::strings::pcstr::PCSTR]
[13] : 84 'T' [Type: char]
[14] : 82 'R' [Type: char]
-pwstr : "This is a PWSTR" [Type: windows_core::strings::pwstr::PWSTR]
- [] [Type: windows_core::strings::pwstr::PWSTR]
+pwstr : "This is a PWSTR" [Type: windows_strings::pwstr::PWSTR]
+ [] [Type: windows_strings::pwstr::PWSTR]
[len] : 0xf
[chars]
[0] : 0x54 'T' [Type: char16_t]
@@ -123,8 +123,8 @@ pwstr : "This is a PWSTR" [Type: windows_core::strings::pwstr::PWSTR]
[13] : 0x54 'T' [Type: char16_t]
[14] : 0x52 'R' [Type: char16_t]
-pcwstr : "This is a PCWSTR" [Type: windows_core::strings::pcwstr::PCWSTR]
- [] [Type: windows_core::strings::pcwstr::PCWSTR]
+pcwstr : "This is a PCWSTR" [Type: windows_strings::pcwstr::PCWSTR]
+ [] [Type: windows_strings::pcwstr::PCWSTR]
[len] : 0x10
[chars]
[0] : 0x54 'T' [Type: char16_t]
@@ -144,14 +144,14 @@ pcwstr : "This is a PCWSTR" [Type: windows_core::strings::pcwstr::PCWS
[14] : 0x54 'T' [Type: char16_t]
[15] : 0x52 'R' [Type: char16_t]
-empty : "" [Type: windows_core::strings::hstring::HSTRING]
- [] [Type: windows_core::strings::hstring::HSTRING]
+empty : "" [Type: windows_strings::hstring::HSTRING]
+ [] [Type: windows_strings::hstring::HSTRING]
[len] : 0x0 [Type: unsigned int]
-hstring : "This is an HSTRING" [Type: windows_core::strings::hstring::HSTRING]
- [] [Type: windows_core::strings::hstring::HSTRING]
+hstring : "This is an HSTRING" [Type: windows_strings::hstring::HSTRING]
+ [] [Type: windows_strings::hstring::HSTRING]
[len] : 0x12 [Type: unsigned int]
- [ref_count] : 1 [Type: windows_core::imp::ref_count::RefCount]
+ [ref_count] : 1 [Type: windows_strings::ref_count::RefCount]
[flags] : 0x0 [Type: unsigned int]
[chars]
[0] : 0x54 'T' [Type: char16_t]
diff --git a/crates/tests/linux/Cargo.toml b/crates/tests/linux/Cargo.toml
index 6bc89e611f..8285f3b1ab 100644
--- a/crates/tests/linux/Cargo.toml
+++ b/crates/tests/linux/Cargo.toml
@@ -8,9 +8,8 @@ publish = false
doc = false
doctest = false
-[dependencies.windows]
-path = "../../libs/windows"
-features = [
- "Foundation",
- "Win32_Foundation",
-]
+[dependencies.windows-result]
+path = "../../libs/result"
+
+[dependencies.windows-core]
+path = "../../libs/core"
diff --git a/crates/tests/linux/tests/core.rs b/crates/tests/linux/tests/core.rs
new file mode 100644
index 0000000000..681d917e33
--- /dev/null
+++ b/crates/tests/linux/tests/core.rs
@@ -0,0 +1,16 @@
+use windows_core::*;
+
+#[interface("d888acaa-fb67-46a4-bb35-87cb37db5830")]
+unsafe trait ITest: IUnknown {}
+
+#[implement(ITest)]
+struct Test;
+
+impl ITest_Impl for Test_Impl {}
+
+#[test]
+fn test() {
+ let object = ComObject::new(Test);
+ let unknown: IUnknown = object.to_interface();
+ let _test: ITest = unknown.cast().expect("QueryInterface for ITest");
+}
diff --git a/crates/tests/linux/tests/hresult.rs b/crates/tests/linux/tests/result.rs
similarity index 84%
rename from crates/tests/linux/tests/hresult.rs
rename to crates/tests/linux/tests/result.rs
index 9eef4b7f32..3414132583 100644
--- a/crates/tests/linux/tests/hresult.rs
+++ b/crates/tests/linux/tests/result.rs
@@ -1,8 +1,9 @@
// This tests code paths in `windows-result` that are different on non-Windows platforms.
#![cfg(not(windows))]
-use windows::core::Error;
-use windows::Win32::Foundation::{E_FAIL, S_OK};
+use windows_result::*;
+pub const E_FAIL: HRESULT = HRESULT(0x80004005_u32 as _);
+pub const S_OK: HRESULT = HRESULT(0x0_u32 as _);
#[test]
fn basic_hresult() {
diff --git a/crates/tests/linux/tests/strings.rs b/crates/tests/linux/tests/strings.rs
deleted file mode 100644
index b2e2cc96d2..0000000000
--- a/crates/tests/linux/tests/strings.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use windows::core::*;
-
-#[test]
-fn test() {
- unsafe {
- let s: PCSTR = s!("hello world");
- assert_eq!(s.to_string().unwrap(), "hello world");
-
- let w: PCWSTR = w!("wide world");
- assert_eq!(w.to_string().unwrap(), "wide world");
- }
-}
diff --git a/crates/tests/readme/Cargo.toml b/crates/tests/readme/Cargo.toml
index c11d69d521..c450375600 100644
--- a/crates/tests/readme/Cargo.toml
+++ b/crates/tests/readme/Cargo.toml
@@ -4,10 +4,6 @@ version = "0.0.0"
edition = "2021"
publish = false
-[lib]
-doc = false
-doctest = false
-
[dependencies.windows]
path = "../../libs/windows"
features = [
@@ -42,5 +38,8 @@ path = "../../libs/registry"
[dev-dependencies.windows-version]
path = "../../libs/version"
+[dev-dependencies.windows-strings]
+path = "../../libs/strings"
+
[dev-dependencies.cppwinrt]
path = "../../libs/cppwinrt"
diff --git a/crates/tests/readme/src/lib.rs b/crates/tests/readme/src/lib.rs
index 6a1bd9cb79..33a0f04877 100644
--- a/crates/tests/readme/src/lib.rs
+++ b/crates/tests/readme/src/lib.rs
@@ -1,9 +1,10 @@
#![doc = include_str!("../../../../crates/libs/core/readme.md")]
+#![doc = include_str!("../../../../crates/libs/cppwinrt/readme.md")]
#![doc = include_str!("../../../../crates/libs/metadata/readme.md")]
#![doc = include_str!("../../../../crates/libs/registry/readme.md")]
#![doc = include_str!("../../../../crates/libs/result/readme.md")]
+#![doc = include_str!("../../../../crates/libs/strings/readme.md")]
#![doc = include_str!("../../../../crates/libs/sys/readme.md")]
#![doc = include_str!("../../../../crates/libs/targets/readme.md")]
#![doc = include_str!("../../../../crates/libs/version/readme.md")]
#![doc = include_str!("../../../../crates/libs/windows/readme.md")]
-#![doc = include_str!("../../../../crates/libs/cppwinrt/readme.md")]
diff --git a/crates/tests/strings/Cargo.toml b/crates/tests/strings/Cargo.toml
new file mode 100644
index 0000000000..afa47d0b8a
--- /dev/null
+++ b/crates/tests/strings/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "test_strings"
+version = "0.0.0"
+edition = "2021"
+publish = false
+
+[lib]
+doc = false
+doctest = false
+
+[dependencies.windows-strings]
+path = "../../libs/strings"
diff --git a/crates/tests/strings/src/lib.rs b/crates/tests/strings/src/lib.rs
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/crates/tests/strings/src/lib.rs
@@ -0,0 +1 @@
+
diff --git a/crates/tests/strings/tests/bstr.rs b/crates/tests/strings/tests/bstr.rs
new file mode 100644
index 0000000000..f5e92ffd97
--- /dev/null
+++ b/crates/tests/strings/tests/bstr.rs
@@ -0,0 +1,9 @@
+use windows_strings::*;
+
+#[test]
+fn bstr() -> Result<()> {
+ let s = BSTR::from("hello");
+ assert_eq!(s.len(), 5);
+
+ Ok(())
+}
diff --git a/crates/tests/strings/tests/hstring.rs b/crates/tests/strings/tests/hstring.rs
new file mode 100644
index 0000000000..8c98566c57
--- /dev/null
+++ b/crates/tests/strings/tests/hstring.rs
@@ -0,0 +1,9 @@
+use windows_strings::*;
+
+#[test]
+fn hstring() -> Result<()> {
+ let s = HSTRING::from("hello");
+ assert_eq!(s.len(), 5);
+
+ Ok(())
+}
diff --git a/crates/tests/strings/tests/literals.rs b/crates/tests/strings/tests/literals.rs
new file mode 100644
index 0000000000..701e50f5ae
--- /dev/null
+++ b/crates/tests/strings/tests/literals.rs
@@ -0,0 +1,15 @@
+use windows_strings::*;
+
+#[test]
+fn literals() -> Result<()> {
+ const A: PCSTR = s!("ansi");
+ assert_eq!(unsafe { A.to_string()? }, "ansi");
+
+ const W: PCWSTR = w!("wide");
+ assert_eq!(unsafe { W.to_string()? }, "wide");
+
+ const H: &HSTRING = h!("hstring");
+ assert_eq!(H, "hstring");
+
+ Ok(())
+}
diff --git a/crates/tools/bindings/src/core.txt b/crates/tools/bindings/src/core.txt
index 37a36bc164..41264afa28 100644
--- a/crates/tools/bindings/src/core.txt
+++ b/crates/tools/bindings/src/core.txt
@@ -6,9 +6,6 @@
--filter
Windows.Win32.Foundation.CloseHandle
Windows.Win32.Foundation.FreeLibrary
- Windows.Win32.Foundation.SysAllocStringLen
- Windows.Win32.Foundation.SysFreeString
- Windows.Win32.Foundation.SysStringLen
Windows.Win32.System.Com.CoIncrementMTAUsage
Windows.Win32.System.Com.CoTaskMemAlloc
Windows.Win32.System.Com.CoTaskMemFree
diff --git a/crates/tools/bindings/src/main.rs b/crates/tools/bindings/src/main.rs
index 518fdb8722..01fb1e609e 100644
--- a/crates/tools/bindings/src/main.rs
+++ b/crates/tools/bindings/src/main.rs
@@ -6,6 +6,7 @@ fn main() -> Result<()> {
run("crates/tools/bindings/src/metadata.txt")?;
run("crates/tools/bindings/src/registry.txt")?;
run("crates/tools/bindings/src/result.txt")?;
+ run("crates/tools/bindings/src/strings.txt")?;
run("crates/tools/bindings/src/sys.txt")?;
run("crates/tools/bindings/src/version.txt")?;
run("crates/tools/bindings/src/windows.txt")?;
diff --git a/crates/tools/bindings/src/strings.txt b/crates/tools/bindings/src/strings.txt
new file mode 100644
index 0000000000..bb0f637c00
--- /dev/null
+++ b/crates/tools/bindings/src/strings.txt
@@ -0,0 +1,13 @@
+// These will use `windows-sys` style bindings.
+
+--out crates/libs/strings/src/bindings.rs
+--config flatten sys minimal no-bindgen-comment
+
+--filter
+ Windows.Win32.Foundation.E_OUTOFMEMORY
+ Windows.Win32.Foundation.SysAllocStringLen
+ Windows.Win32.Foundation.SysFreeString
+ Windows.Win32.Foundation.SysStringLen
+ Windows.Win32.System.Memory.GetProcessHeap
+ Windows.Win32.System.Memory.HeapAlloc
+ Windows.Win32.System.Memory.HeapFree