Skip to content

Commit

Permalink
Use BSTR allocator as PCSTR and PCWSTR parameter allocator (#1657)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Apr 4, 2022
1 parent 3376a14 commit ea1a991
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 7 deletions.
8 changes: 8 additions & 0 deletions crates/libs/bindgen/src/replacements/bstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ pub fn gen() -> TokenStream {

unsafe { ::core::slice::from_raw_parts(self.0, self.len()) }
}

pub unsafe fn from_raw(raw: *const u16) -> Self {
Self(raw)
}

pub fn into_raw(self) -> *const u16 {
unsafe { std::mem::transmute(self) }
}
}
impl ::core::clone::Clone for BSTR {
fn clone(&self) -> Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/libs/windows/src/Windows/Win32/Foundation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ impl BSTR {
}
unsafe { ::core::slice::from_raw_parts(self.0, self.len()) }
}
pub unsafe fn from_raw(raw: *const u16) -> Self {
Self(raw)
}
pub fn into_raw(self) -> *const u16 {
unsafe { std::mem::transmute(self) }
}
}
impl ::core::clone::Clone for BSTR {
fn clone(&self) -> Self {
Expand Down
19 changes: 19 additions & 0 deletions crates/libs/windows/src/core/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,12 @@ impl BSTR {
}
unsafe { ::core::slice::from_raw_parts(self.0, self.len()) }
}
pub unsafe fn from_raw(raw: *const u16) -> Self {
Self(raw)
}
pub fn into_raw(self) -> *const u16 {
unsafe { std::mem::transmute(self) }
}
}
impl ::core::clone::Clone for BSTR {
fn clone(&self) -> Self {
Expand Down Expand Up @@ -1404,6 +1410,19 @@ unsafe impl ::windows::core::Abi for HINSTANCE {
}
pub const S_OK: ::windows::core::HRESULT = ::windows::core::HRESULT(0i32);
#[inline]
pub unsafe fn SysAllocStringByteLen<'a, Param0: ::windows::core::IntoParam<'a, ::windows::core::PCSTR>>(psz: Param0, len: u32) -> BSTR {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn SysAllocStringByteLen(psz: ::windows::core::PCSTR, len: u32) -> BSTR;
}
::core::mem::transmute(SysAllocStringByteLen(psz.into_param().abi(), ::core::mem::transmute(len)))
}
#[cfg(not(windows))]
unimplemented!("Unsupported target OS");
}
#[inline]
pub unsafe fn SysAllocStringLen(strin: &[u16]) -> BSTR {
#[cfg(windows)]
{
Expand Down
5 changes: 3 additions & 2 deletions crates/libs/windows/src/core/pcstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ unsafe impl Abi for PCSTR {
unsafe fn drop_param(param: &mut Param<'_, Self>) {
if let Param::Boxed(value) = param {
if !value.is_null() {
alloc::boxed::Box::from_raw(value.0 as *mut u8);
bindings::BSTR::from_raw(value.0 as _);
}
}
}
}
#[cfg(feature = "alloc")]
impl<'a> IntoParam<'a, PCSTR> for &str {
fn into_param(self) -> Param<'a, PCSTR> {
Param::Boxed(PCSTR(alloc::boxed::Box::<[u8]>::into_raw(self.bytes().chain(::core::iter::once(0)).collect::<alloc::vec::Vec<u8>>().into_boxed_slice()) as _))
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/868
unsafe { Param::Boxed(PCSTR(bindings::SysAllocStringByteLen(PCSTR(self.as_ptr()), self.len() as _).into_raw() as _)) }
}
}
#[cfg(feature = "alloc")]
Expand Down
8 changes: 5 additions & 3 deletions crates/libs/windows/src/core/pcwstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ unsafe impl Abi for PCWSTR {
unsafe fn drop_param(param: &mut Param<'_, Self>) {
if let Param::Boxed(value) = param {
if !value.is_null() {
alloc::boxed::Box::from_raw(value.0 as *mut u16);
bindings::BSTR::from_raw(value.0);
}
}
}
}
#[cfg(feature = "alloc")]
impl<'a> IntoParam<'a, PCWSTR> for &str {
fn into_param(self) -> Param<'a, PCWSTR> {
Param::Boxed(PCWSTR(alloc::boxed::Box::<[u16]>::into_raw(self.encode_utf16().chain(::core::iter::once(0)).collect::<alloc::vec::Vec<u16>>().into_boxed_slice()) as _))
unsafe { Param::Boxed(PCWSTR(bindings::SysAllocStringLen(&self.encode_utf16().collect::<alloc::vec::Vec<u16>>()).into_raw())) }
}
}
#[cfg(feature = "alloc")]
Expand All @@ -54,12 +54,14 @@ impl<'a> IntoParam<'a, PCWSTR> for alloc::string::String {
IntoParam::into_param(self.as_str())
}
}
#[cfg(feature = "alloc")]
impl<'a> IntoParam<'a, PCWSTR> for &::std::ffi::OsStr {
fn into_param(self) -> Param<'a, PCWSTR> {
use ::std::os::windows::ffi::OsStrExt;
Param::Boxed(PCWSTR(alloc::boxed::Box::<[u16]>::into_raw(self.encode_wide().chain(::core::iter::once(0)).collect::<alloc::vec::Vec<u16>>().into_boxed_slice()) as _))
unsafe { Param::Boxed(PCWSTR(bindings::SysAllocStringLen(&self.encode_wide().collect::<alloc::vec::Vec<u16>>()).into_raw())) }
}
}
#[cfg(feature = "alloc")]
impl<'a> IntoParam<'a, PCWSTR> for ::std::ffi::OsString {
fn into_param(self) -> Param<'a, PCWSTR> {
IntoParam::into_param(self.as_os_str())
Expand Down
14 changes: 12 additions & 2 deletions crates/tests/win32_arrays/tests/fixed.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use windows::{Win32::Storage::FileSystem::*, Win32::UI::Input::KeyboardAndMouse::*};
use windows::{Win32::Foundation::*, Win32::Storage::FileSystem::*, Win32::UI::Input::KeyboardAndMouse::*};

#[test]
fn keyboard_state() {
Expand All @@ -12,11 +12,21 @@ fn keyboard_state() {
}

#[test]
fn temp_file() {
fn temp_file_ansi() {
unsafe {
let mut buffer: [u8; 260] = std::mem::zeroed();
let a = GetTempFileNameA(".", "test", 0x7b, &mut buffer);
assert_eq!(a, 0x7b);
assert_eq!(&buffer[..12], b".\\tes7B.tmp\0");
}
}

#[test]
fn temp_file_wide() {
unsafe {
let mut buffer: [u16; 260] = std::mem::zeroed();
let a = GetTempFileNameW(".", "test", 0x7b, &mut buffer);
assert_eq!(a, 0x7b);
assert_eq!(SysAllocStringLen(&buffer[..12]), ".\\tes7B.tmp\0");
}
}
1 change: 1 addition & 0 deletions crates/tools/bindings/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn main() -> std::io::Result<()> {
"Windows.Win32.Foundation.HANDLE",
"Windows.Win32.Foundation.HINSTANCE",
"Windows.Win32.Foundation.S_OK",
"Windows.Win32.Foundation.SysAllocStringByteLen",
"Windows.Win32.Foundation.SysAllocStringLen",
"Windows.Win32.Foundation.SysFreeString",
"Windows.Win32.Foundation.SysStringLen",
Expand Down

0 comments on commit ea1a991

Please sign in to comment.