ib_shell_item/string/
mod.rs1use std::{mem, ptr};
2
3use widestring::U16CStr;
4use windows::{
5 Win32::{
6 System::Com::{CoTaskMemAlloc, CoTaskMemFree, CoTaskMemRealloc},
7 UI::Shell::Common::{STRRET, STRRET_WSTR},
8 },
9 core::PWSTR,
10};
11
12pub mod bar;
13
14#[allow(unused)]
15pub fn strret_free(s: STRRET) {
16 if s.uType == STRRET_WSTR.0 as u32 {
17 unsafe { CoTaskMemFree(Some(s.Anonymous.pOleStr.0 as *mut _)) };
18 }
19}
20
21#[allow(unused)]
23pub fn str_to_co_task(s: &str) -> PWSTR {
24 let len = s.encode_utf16().count() + 1;
25
26 let ptr = unsafe { CoTaskMemAlloc(len * mem::size_of::<u16>()) };
27 if ptr.is_null() {
28 return PWSTR(ptr::null_mut());
29 }
30
31 let ptr = ptr as *mut u16;
32 unsafe {
33 for (i, ch) in s.encode_utf16().enumerate() {
34 ptr.add(i).write(ch);
35 }
36 ptr.add(len - 1).write(0);
37 }
38
39 PWSTR(ptr)
40}
41
42pub(crate) fn prefix_u16cstr_ptr(name: &U16CStr, prefix: &[u16]) -> PWSTR {
45 let ptr = unsafe {
46 CoTaskMemRealloc(
47 Some(name.as_ptr().cast()),
48 (prefix.len() + name.len() + 1) * size_of::<u16>(),
49 )
50 } as *mut u16;
51
52 if ptr.is_null() {
53 return PWSTR(name.as_ptr() as _);
54 }
55
56 unsafe {
57 ptr::copy_nonoverlapping(prefix.as_ptr(), ptr, prefix.len());
58 ptr::copy_nonoverlapping(name.as_ptr(), ptr.add(prefix.len()), name.len() + 1);
59 }
60
61 PWSTR(ptr)
62}
63
64#[allow(dead_code)]
66pub(crate) fn suffix_u16cstr_ptr(s: &U16CStr, suffix: &[u16]) -> PWSTR {
67 let ptr = unsafe {
68 CoTaskMemRealloc(
69 Some(s.as_ptr().cast()),
70 (s.len() + suffix.len() + 1) * size_of::<u16>(),
71 )
72 } as *mut u16;
73
74 if ptr.is_null() {
75 return PWSTR(s.as_ptr() as _);
76 }
77
78 unsafe {
79 ptr::copy_nonoverlapping(suffix.as_ptr(), ptr.add(s.len()), suffix.len());
80 ptr.add(s.len() + suffix.len()).write(0);
81 }
82
83 PWSTR(ptr)
84}