Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions crates/libs/core/src/strings/bstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ impl BSTR {

/// 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.as_ptr(), self.len()) }
}

unsafe { std::slice::from_raw_parts(self.0, self.len()) }
/// Returns a raw pointer to the `BSTR` buffer.
pub fn as_ptr(&self) -> *const u16 {
if !self.is_empty() {
self.0
} else {
const EMPTY: [u16; 1] = [0];
EMPTY.as_ptr()
}
}

/// Create a `BSTR` from a slice of 16 bit characters (wchars).
Expand Down Expand Up @@ -105,6 +111,12 @@ impl TryFrom<BSTR> for String {
}
}

impl IntoParam<PCWSTR> for &BSTR {
unsafe fn into_param(self) -> Param<PCWSTR> {
Param::Owned(PCWSTR(self.as_ptr()))
}
}

impl Default for BSTR {
fn default() -> Self {
Self(std::ptr::null_mut())
Expand Down
12 changes: 12 additions & 0 deletions crates/libs/core/src/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ impl std::fmt::Debug for PROPVARIANT {
}
}

impl std::fmt::Display for VARIANT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::write!(f, "{}", BSTR::try_from(self).unwrap_or_default())
}
}

impl std::fmt::Display for PROPVARIANT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::write!(f, "{}", BSTR::try_from(self).unwrap_or_default())
}
}

impl PartialEq for VARIANT {
fn eq(&self, other: &Self) -> bool {
unsafe {
Expand Down
65 changes: 47 additions & 18 deletions crates/samples/windows/wmi/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use windows::{
core::*, Win32::System::Com::*, Win32::System::Ole::*, Win32::System::Variant::*,
Win32::System::Wmi::*,
};
use windows::{core::*, Win32::System::Com::*, Win32::System::Wmi::*};

fn main() -> Result<()> {
unsafe {
Expand All @@ -24,6 +21,10 @@ fn main() -> Result<()> {
let server =
locator.ConnectServer(&BSTR::from("root\\cimv2"), None, None, None, 0, None, None)?;

//
// ExecQuery example
//

let query = server.ExecQuery(
&BSTR::from("WQL"),
&BSTR::from("select Caption from Win32_LogicalDisk"),
Expand All @@ -37,26 +38,54 @@ fn main() -> Result<()> {
query.Next(WBEM_INFINITE, &mut row, &mut returned).ok()?;

if let Some(row) = &row[0] {
let mut value = Default::default();
let mut value = VARIANT::default();
row.Get(w!("Caption"), 0, &mut value, None, None)?;
println!(
"{}",
VarFormat(
&value,
None,
VARFORMAT_FIRST_DAY_SYSTEMDEFAULT,
VARFORMAT_FIRST_WEEK_SYSTEMDEFAULT,
0
)?
);

// TODO: workaround for https://github.com/microsoft/windows-rs/issues/539
VariantClear(&mut value)?;
println!("{value}",);
} else {
break;
}
}

//
// ExecMethod example
//

let class_name = BSTR::from("Win32_Process");
let method_name = BSTR::from("Create");

let mut class = None;
server.GetObject(
&class_name,
Default::default(),
None,
Some(&mut class),
None,
)?;
let class = class.unwrap();

let mut input = None;
class.GetMethod(&method_name, 0, &mut input, std::ptr::null_mut())?;
let input = input.unwrap();

let object = input.SpawnInstance(0)?;
object.Put(w!("CommandLine"), 0, &VARIANT::from("notepad.exe"), 0)?;

let mut output = None;
server.ExecMethod(
&class_name,
&method_name,
Default::default(),
None,
&object,
Some(&mut output),
None,
)?;
let output = output.unwrap();

let mut value = VARIANT::default();
output.Get(w!("ReturnValue"), 0, &mut value, None, None)?;
println!("`Create` method return value: {value}");

Ok(())
}
}
2 changes: 2 additions & 0 deletions crates/tests/variant/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ fn test_variant() -> Result<()> {
assert_eq!(BSTR::try_from(&v)?, "3.5");

assert_eq!(format!("{v:?}"), "VARIANT { type: 5, value: 3.5 }");
assert_eq!(format!("{v}"), "3.5");

let clone = v.clone();
assert_eq!(v, clone);
Expand Down Expand Up @@ -219,6 +220,7 @@ fn test_propvariant() -> Result<()> {
assert_eq!(BSTR::try_from(&v)?, "3.5");

assert_eq!(format!("{v:?}"), "PROPVARIANT { type: 5, value: 3.5 }");
assert_eq!(format!("{v}"), "3.5");

let clone = v.clone();
assert_eq!(v, clone);
Expand Down