rustclr/utils/
mod.rs

1use alloc::{string::String, vec::Vec};
2use windows_sys::Win32::{
3    Foundation::{
4        SysAllocString, 
5        SysStringLen,
6    }, 
7};
8
9/// Module related to safearray creation
10mod safearray;
11pub use safearray::*;
12 
13/// Module used to validate that the file corresponds to what is expected
14pub(crate) mod file;
15
16/// The `WinStr` trait provides methods for working with BSTRs (Binary String),
17/// a format commonly used in Windows API. BSTRs are wide strings (UTF-16) 
18/// with specific memory layouts, used for interoperation with COM 
19/// (Component Object Model) and other Windows-based APIs.
20pub trait WinStr {
21    /// Converts a Rust string into a BSTR.
22    ///
23    /// # Returns
24    ///
25    /// * `*const u16` - A pointer to the UTF-16 encoded BSTR.
26    ///
27    /// This method is implemented for `&str` and `String`, converting
28    /// them into BSTRs, and for `*const u16` as a passthrough.
29    ///
30    /// # Example
31    ///
32    /// ```
33    /// use rustclr::WinStr;
34    ///
35    /// let rust_str = "Hello, World!";
36    /// let bstr_ptr = rust_str.to_bstr();
37    ///
38    /// // Use the BSTR pointer in a COM function...
39    /// ```
40    fn to_bstr(&self) -> *const u16;
41
42    /// Converts a BSTR (pointer `*const u16`) back to a Rust `String`.
43    /// 
44    /// # Returns
45    ///
46    /// * `String` - A `String` containing the text from the BSTR if the trait
47    ///   is implemented for `*const u16`. For other types, returns an empty `String`.
48    ///
49    /// # Example
50    ///
51    /// ```
52    /// use rustclr::WinStr;
53    ///
54    /// let bstr: *const u16 = /* assume a BSTR from COM */;
55    /// let rust_string = bstr.to_string();
56    /// ```
57    fn to_string(&self) -> String {
58        String::new()
59    }
60}
61
62impl WinStr for &str {
63    /// Converts a `&str` to a BSTR.
64    ///
65    /// # Returns
66    ///
67    /// * `*const u16` - A pointer to the UTF-16 encoded BSTR.
68    fn to_bstr(&self) -> *const u16 {
69        let utf16_str = self.encode_utf16().chain(Some(0)).collect::<Vec<u16>>();
70        unsafe { SysAllocString(utf16_str.as_ptr()) }
71    }
72}
73
74impl WinStr for String {
75    /// Converts a `String` to a BSTR.
76    ///
77    /// # Returns
78    ///
79    /// * `*const u16` - A pointer to the UTF-16 encoded BSTR.
80    fn to_bstr(&self) -> *const u16 {
81        let utf16_str = self.encode_utf16().chain(Some(0)).collect::<Vec<u16>>();
82        unsafe { SysAllocString(utf16_str.as_ptr()) }
83    }
84}
85
86impl WinStr for *const u16 {
87    /// Passes through the BSTR pointer without modification.
88    ///
89    /// # Returns
90    ///
91    /// * `*const u16` - The original BSTR pointer.
92    fn to_bstr(&self) -> *const u16 {
93        *self
94    }
95
96    /// Converts a `*const u16` BSTR to a `String`.
97    ///
98    /// # Returns
99    ///
100    /// * `String` - A `String` containing the UTF-16 encoded text from the BSTR.
101    fn to_string(&self) -> String {
102        let len = unsafe { SysStringLen(*self) };
103        if len == 0 {
104            return String::new();
105        }
106
107        let slice = unsafe { core::slice::from_raw_parts(*self, len as usize) };
108        String::from_utf16_lossy(slice)
109    }
110}
111
112/// Generates a uuid used to create the AppDomain
113pub(crate) fn uuid() -> uuid::Uuid {
114    let mut buf = [0u8; 16];
115
116    for i in 0..4 {
117        let ticks = unsafe { core::arch::x86_64::_rdtsc() }; 
118        buf[i * 4 + 0] = (ticks >> 0) as u8;
119        buf[i * 4 + 1] = (ticks >> 8) as u8;
120        buf[i * 4 + 2] = (ticks >> 16) as u8;
121        buf[i * 4 + 3] = (ticks >> 24) as u8;
122    }
123
124    uuid::Uuid::from_bytes(buf)
125}
126
127/// Specifies the invocation type for a method, indicating if it is static or instance-based.
128pub enum Invocation {
129    /// Indicates that the method to invoke is static.
130    Static,
131
132    /// Indicates that the method to invoke is an instance method.
133    Instance,
134}