Skip to content

Commit b60d4cc

Browse files
authored
Bump to windows 0.60 (#22)
1 parent 0ff931e commit b60d4cc

File tree

5 files changed

+110
-92
lines changed

5 files changed

+110
-92
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ readme = "../readme.md"
2121
repository = "https://github.com/leonardder/rd_pipe-rs"
2222
license = "AGPL-3.0-or-later"
2323
categories = ["network-programming", "os::windows-apis"]
24-
edition = "2021"
24+
edition = "2024"
2525

2626
[lib]
2727
crate-type = ["cdylib"]
@@ -34,11 +34,11 @@ tracing-appender = "0.2.3"
3434
tracing-subscriber = "0.3.19"
3535
itertools = "0.14.0"
3636
winreg = { version = "0.55", features = ["transactions"] }
37+
windows-core = "0.60.1"
3738

3839
[dependencies.windows]
39-
version = "0.54.0"
40+
version = "0.60.0"
4041
features = [
41-
"implement",
4242
"Win32_Foundation",
4343
"Win32_System_SystemServices",
4444
"Win32_System_LibraryLoader",

src/class_factory.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,37 @@
1212
// You should have received a copy of the GNU Affero General Public License
1313
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1414

15-
use std::mem::transmute;
15+
use std::{fmt, mem::transmute};
1616
use tracing::{debug, instrument, trace};
1717
use windows::{
18-
core::{implement, IUnknown, Result, GUID},
1918
Win32::{
20-
Foundation::{BOOL, CLASS_E_NOAGGREGATION, E_NOINTERFACE},
21-
System::Com::{IClassFactory, IClassFactory_Impl},
19+
Foundation::{CLASS_E_NOAGGREGATION, E_NOINTERFACE},
20+
System::{
21+
Com::{IClassFactory, IClassFactory_Impl},
22+
RemoteDesktop::IWTSPlugin,
23+
},
2224
},
25+
core::{Error, GUID, IUnknown, Interface, Result, implement},
2326
};
24-
use windows::{
25-
core::{Error, Interface},
26-
Win32::System::RemoteDesktop::IWTSPlugin,
27-
};
27+
use windows_core::BOOL;
2828

2929
use crate::rd_pipe_plugin::RdPipePlugin;
3030

3131
#[implement(IClassFactory)]
3232
#[derive(Debug)]
3333
pub struct ClassFactory;
3434

35-
impl IClassFactory_Impl for ClassFactory {
36-
#[instrument]
35+
impl fmt::Debug for ClassFactory_Impl {
36+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37+
f.debug_struct("ClassFactory_Impl").finish()
38+
}
39+
}
40+
41+
impl IClassFactory_Impl for ClassFactory_Impl {
42+
#[instrument(skip(outer))]
3743
fn CreateInstance(
3844
&self,
39-
outer: Option<&IUnknown>,
45+
outer: windows_core::Ref<'_, IUnknown>,
4046
iid: *const GUID,
4147
object: *mut *mut core::ffi::c_void,
4248
) -> Result<()> {

src/lib.rs

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,38 @@ use crate::{
2020
class_factory::ClassFactory, rd_pipe_plugin::RdPipePlugin, registry::CLSID_RD_PIPE_PLUGIN,
2121
};
2222
use rd_pipe_plugin::REG_PATH;
23-
#[cfg(target_arch = "x86")]
24-
use registry::{ctx_add_to_registry, ctx_delete_from_registry};
2523
use registry::{
26-
delete_from_registry, inproc_server_add_to_registry, msts_add_to_registry, COM_CLS_FOLDER,
27-
TS_ADD_INS_FOLDER, TS_ADD_IN_RD_PIPE_FOLDER_NAME,
24+
COM_CLS_FOLDER, TS_ADD_IN_RD_PIPE_FOLDER_NAME, TS_ADD_INS_FOLDER, delete_from_registry,
25+
inproc_server_add_to_registry, msts_add_to_registry,
2826
};
27+
#[cfg(target_arch = "x86")]
28+
use registry::{ctx_add_to_registry, ctx_delete_from_registry};
2929
use std::{ffi::c_void, io, mem::transmute, panic, str::FromStr};
3030
use tokio::runtime::Runtime;
3131
use tracing::{debug, error, instrument, trace};
3232
use windows::{
33-
core::{Interface, PCWSTR},
3433
Win32::{
35-
Foundation::{ERROR_INVALID_FUNCTION, ERROR_INVALID_PARAMETER, HMODULE, WIN32_ERROR},
36-
System::LibraryLoader::GetModuleFileNameW,
37-
},
38-
};
39-
use windows::{
40-
core::{GUID, HRESULT},
41-
Win32::{
42-
Foundation::{BOOL, CLASS_E_CLASSNOTAVAILABLE, E_UNEXPECTED, S_OK},
34+
Foundation::{CLASS_E_CLASSNOTAVAILABLE, E_UNEXPECTED, S_OK},
4335
System::{
4436
Com::IClassFactory,
4537
LibraryLoader::DisableThreadLibraryCalls,
4638
RemoteDesktop::IWTSPlugin,
4739
SystemServices::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH},
4840
},
4941
},
42+
core::{GUID, HRESULT},
5043
};
44+
use windows::{
45+
Win32::{
46+
Foundation::{ERROR_INVALID_PARAMETER, HMODULE, WIN32_ERROR},
47+
System::LibraryLoader::GetModuleFileNameW,
48+
},
49+
core::{Interface, PCWSTR},
50+
};
51+
use windows_core::BOOL;
5152
use winreg::{
53+
HKEY, RegKey,
5254
enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE},
53-
RegKey, HKEY,
5455
};
5556

5657
lazy_static::lazy_static! {
@@ -70,7 +71,7 @@ fn get_log_level_from_registry(parent_key: HKEY) -> io::Result<u32> {
7071

7172
static mut INSTANCE: Option<HMODULE> = None;
7273

73-
#[no_mangle]
74+
#[unsafe(no_mangle)]
7475
pub extern "stdcall" fn DllMain(hinst: HMODULE, reason: u32, _reserved: *mut c_void) -> BOOL {
7576
match reason {
7677
DLL_PROCESS_ATTACH => {
@@ -112,7 +113,7 @@ pub extern "stdcall" fn DllMain(hinst: HMODULE, reason: u32, _reserved: *mut c_v
112113
true.into()
113114
}
114115

115-
#[no_mangle]
116+
#[unsafe(no_mangle)]
116117
#[instrument]
117118
pub extern "stdcall" fn DllGetClassObject(
118119
rclsid: *const GUID,
@@ -143,7 +144,7 @@ pub extern "stdcall" fn DllGetClassObject(
143144
S_OK
144145
}
145146

146-
#[no_mangle]
147+
#[unsafe(no_mangle)]
147148
#[instrument]
148149
pub extern "stdcall" fn VirtualChannelGetInstance(
149150
riid: *const GUID,
@@ -160,9 +161,13 @@ pub extern "stdcall" fn VirtualChannelGetInstance(
160161
return E_UNEXPECTED;
161162
}
162163
let pnumobjs = unsafe { &mut *pnumobjs };
163-
trace!("Checking whether result pointer is null (i.e. whether this call is a query for number of plugins or a query for the plugins itself)");
164+
trace!(
165+
"Checking whether result pointer is null (i.e. whether this call is a query for number of plugins or a query for the plugins itself)"
166+
);
164167
if ppo.is_null() {
165-
debug!("Result pointer is null, client is querying for number of objects. Setting pnumobjs to 1, since we only support one plugin");
168+
debug!(
169+
"Result pointer is null, client is querying for number of objects. Setting pnumobjs to 1, since we only support one plugin"
170+
);
166171
*pnumobjs = 1;
167172
} else {
168173
debug!("{} plugins requested", *pnumobjs);
@@ -172,9 +177,9 @@ pub extern "stdcall" fn VirtualChannelGetInstance(
172177
}
173178
let ppo = unsafe { &mut *ppo };
174179
trace!("Constructing the plugin");
175-
let plugin: IWTSPlugin = RdPipePlugin::new().into();
180+
let plugin = RdPipePlugin::new();
176181
trace!("Setting result pointer to plugin");
177-
*ppo = unsafe { transmute(plugin) };
182+
*ppo = unsafe { transmute(&plugin) };
178183
}
179184
S_OK
180185
}
@@ -184,7 +189,7 @@ const CMD_MSTS: char = 'r'; // Registers/unregisters RDP/MSTS support
184189
const CMD_CITRIX: char = 'x'; // Registers/unregisters Citrix support
185190
const CMD_LOCAL_MACHINE: char = 'm'; // If omitted, registers to HKEY_CURRENT_USER
186191

187-
#[no_mangle]
192+
#[unsafe(no_mangle)]
188193
#[instrument]
189194
pub extern "stdcall" fn DllInstall(install: bool, cmd_line: PCWSTR) -> HRESULT {
190195
debug!("DllInstall called");
@@ -224,37 +229,29 @@ pub extern "stdcall" fn DllInstall(install: bool, cmd_line: PCWSTR) -> HRESULT {
224229
error!("No channel names provided");
225230
return ERROR_INVALID_PARAMETER.into();
226231
}
227-
match unsafe { INSTANCE } {
228-
Some(h) => {
229-
let mut file_name = [0u16; 256];
230-
let path_string: String;
231-
match unsafe { GetModuleFileNameW(h, file_name.as_mut()) } > 0 {
232-
true => {
233-
path_string = String::from_utf16_lossy(&file_name);
234-
}
235-
false => {
236-
let e = windows::core::Error::from_win32();
237-
error!("Error calling GetModuleFileNameW: {}", e);
238-
return e.into();
239-
}
240-
}
241-
if let Err(e) = inproc_server_add_to_registry(
242-
scope_hkey,
243-
&COM_CLS_FOLDER,
244-
&path_string,
245-
&arguments[1..],
246-
) {
247-
let e: windows::core::Error =
248-
WIN32_ERROR(e.raw_os_error().unwrap() as u32).into();
249-
error!("Error calling inproc_server_add_to_registry: {}", e);
250-
return e.into();
251-
}
232+
let mut file_name = [0u16; 256];
233+
let path_string: String;
234+
match unsafe { GetModuleFileNameW(INSTANCE, file_name.as_mut()) } > 0 {
235+
true => {
236+
path_string = String::from_utf16_lossy(&file_name);
252237
}
253-
None => {
254-
error!("No hinstance to calculate dll path");
255-
return ERROR_INVALID_FUNCTION.into();
238+
false => {
239+
let e = windows::core::Error::from_win32();
240+
error!("Error calling GetModuleFileNameW: {}", e);
241+
return e.into();
256242
}
257243
}
244+
if let Err(e) = inproc_server_add_to_registry(
245+
scope_hkey,
246+
&COM_CLS_FOLDER,
247+
&path_string,
248+
&arguments[1..],
249+
) {
250+
let e: windows::core::Error =
251+
WIN32_ERROR(e.raw_os_error().unwrap() as u32).into();
252+
error!("Error calling inproc_server_add_to_registry: {}", e);
253+
return e.into();
254+
}
258255
}
259256
if commands.contains(CMD_MSTS) {
260257
if let Err(e) = msts_add_to_registry(scope_hkey) {

src/rd_pipe_plugin.rs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,31 @@
1616
use core::slice;
1717
use itertools::Itertools;
1818
use parking_lot::Mutex;
19-
use std::io;
19+
use std::{fmt, io};
2020
use std::{io::ErrorKind::WouldBlock, sync::Arc};
2121
use tokio::{
22-
io::{split, AsyncReadExt, AsyncWriteExt, WriteHalf},
22+
io::{AsyncReadExt, AsyncWriteExt, WriteHalf, split},
2323
net::windows::named_pipe::{NamedPipeServer, ServerOptions},
2424
task::JoinHandle,
25-
time::{sleep, Duration},
25+
time::{Duration, sleep},
2626
};
2727
use tracing::{debug, error, info, instrument, trace, warn};
28+
use windows::Win32::Foundation::ERROR_PIPE_NOT_CONNECTED;
2829
use windows::{
29-
core::{implement, AgileReference, Error, Interface, Result, BSTR, PCSTR},
3030
Win32::{
31-
Foundation::{BOOL, ERROR_PIPE_NOT_CONNECTED, E_UNEXPECTED},
31+
Foundation::E_UNEXPECTED,
3232
System::RemoteDesktop::{
3333
IWTSListener, IWTSListenerCallback, IWTSListenerCallback_Impl, IWTSPlugin,
3434
IWTSPlugin_Impl, IWTSVirtualChannel, IWTSVirtualChannelCallback,
3535
IWTSVirtualChannelCallback_Impl, IWTSVirtualChannelManager,
3636
},
3737
},
38+
core::{AgileReference, BSTR, Error, Interface, PCSTR, Result, implement},
3839
};
40+
use windows_core::{BOOL, OutRef};
3941
use winreg::{
42+
HKEY, RegKey,
4043
enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE},
41-
RegKey, HKEY,
4244
};
4345

4446
use crate::ASYNC_RUNTIME;
@@ -83,10 +85,19 @@ impl RdPipePlugin {
8385
}
8486
}
8587

86-
impl IWTSPlugin_Impl for RdPipePlugin {
87-
#[instrument]
88-
fn Initialize(&self, pchannelmgr: Option<&IWTSVirtualChannelManager>) -> Result<()> {
89-
let channel_mgr = match pchannelmgr {
88+
impl fmt::Debug for RdPipePlugin_Impl {
89+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90+
f.debug_struct("RdPipePlugin_Impl").finish()
91+
}
92+
}
93+
94+
impl IWTSPlugin_Impl for RdPipePlugin_Impl {
95+
#[instrument(skip(pchannelmgr))]
96+
fn Initialize(
97+
&self,
98+
pchannelmgr: windows_core::Ref<'_, IWTSVirtualChannelManager>,
99+
) -> Result<()> {
100+
let channel_mgr = match pchannelmgr.as_ref() {
90101
Some(m) => m,
91102
None => {
92103
error!("No pchannelmgr given when initializing");
@@ -142,31 +153,35 @@ impl RdPipeListenerCallback {
142153
}
143154
}
144155

145-
impl IWTSListenerCallback_Impl for RdPipeListenerCallback {
146-
#[instrument]
156+
impl fmt::Debug for RdPipeListenerCallback_Impl {
157+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
158+
f.debug_struct("RdPipeListenerCallback_Impl")
159+
.field("name", &self.name)
160+
.finish()
161+
}
162+
}
163+
164+
impl IWTSListenerCallback_Impl for RdPipeListenerCallback_Impl {
165+
#[instrument(skip(pchannel, ppcallback))]
147166
fn OnNewChannelConnection(
148167
&self,
149-
pchannel: Option<&IWTSVirtualChannel>,
168+
pchannel: windows_core::Ref<'_, IWTSVirtualChannel>,
150169
data: &BSTR,
151170
pbaccept: *mut BOOL,
152-
ppcallback: *mut Option<IWTSVirtualChannelCallback>,
171+
ppcallback: OutRef<'_, IWTSVirtualChannelCallback>,
153172
) -> Result<()> {
154-
debug!(
155-
"Creating new callback for channel {:?} with name {}",
156-
pchannel, &self.name
157-
);
158-
let channel = match pchannel {
173+
debug!("Creating new callback for channel with name {}", &self.name);
174+
let channel = match pchannel.as_ref() {
159175
Some(c) => c,
160176
None => return Err(Error::from(E_UNEXPECTED)),
161177
};
162178
let pbaccept = unsafe { &mut *pbaccept };
163-
let ppcallback = unsafe { &mut *ppcallback };
164179
*pbaccept = BOOL::from(true);
165180
debug!("Creating callback");
166181
let callback: IWTSVirtualChannelCallback =
167182
RdPipeChannelCallback::new(channel, &self.name).into();
168183
trace!("Callback {:?} created", callback);
169-
*ppcallback = Some(callback);
184+
ppcallback.write(callback.into()).unwrap();
170185
Ok(())
171186
}
172187
}
@@ -296,14 +311,14 @@ impl RdPipeChannelCallback {
296311
}
297312
}
298313

299-
impl Drop for RdPipeChannelCallback {
300-
#[instrument]
301-
fn drop(&mut self) {
302-
self.OnClose().unwrap_or_default();
314+
impl fmt::Debug for RdPipeChannelCallback_Impl {
315+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316+
f.debug_struct("RdPipeChannelCallback_Impl")
317+
.field("pipe_writer", &self.pipe_writer)
318+
.finish()
303319
}
304320
}
305-
306-
impl IWTSVirtualChannelCallback_Impl for RdPipeChannelCallback {
321+
impl IWTSVirtualChannelCallback_Impl for RdPipeChannelCallback_Impl {
307322
#[instrument]
308323
fn OnDataReceived(&self, cbsize: u32, pbuffer: *const u8) -> Result<()> {
309324
debug!("Data received, buffer has size {}", cbsize);

src/registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::io;
1616
use tracing::{debug, instrument, trace};
1717
use windows::core::GUID;
1818
use winreg::enums::KEY_ALL_ACCESS;
19-
use winreg::{enums::KEY_WRITE, transaction::Transaction, types::ToRegValue, RegKey, HKEY};
19+
use winreg::{HKEY, RegKey, enums::KEY_WRITE, transaction::Transaction, types::ToRegValue};
2020

2121
pub const CLSID_RD_PIPE_PLUGIN: GUID = GUID::from_u128(0xD1F74DC79FDE45BE9251FA72D4064DA3);
2222
const RD_PIPE_PLUGIN_NAME: &str = "RdPipe";

0 commit comments

Comments
 (0)