Files
mcp-memory/server/src/bin/test_clipboard_crash.rs
T

106 lines
3.6 KiB
Rust

#[cfg(target_os = "windows")]
fn main() {
println!("Starting Win32 clipboard listener isolation test");
let (_tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<()>();
std::thread::Builder::new()
.name("win32-clipboard-listener-isolation".to_string())
.spawn(move || {
use windows_sys::Win32::Foundation::*;
use windows_sys::Win32::System::DataExchange::*;
use windows_sys::Win32::UI::WindowsAndMessaging::*;
unsafe extern "system" fn wnd_proc(
hwnd: HWND,
msg: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
if msg == WM_CLIPBOARDUPDATE {
println!("WM_CLIPBOARDUPDATE received");
return 0;
}
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
}
unsafe {
let class_name: Vec<u16> =
"McpMemoryClipboardWatcherClassIsolation\0".encode_utf16().collect();
let wnd_class = WNDCLASSEXW {
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
style: 0,
lpfnWndProc: Some(wnd_proc),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: 0 as _,
hIcon: 0 as _,
hCursor: 0 as _,
hbrBackground: 0 as _,
lpszMenuName: std::ptr::null(),
lpszClassName: class_name.as_ptr(),
hIconSm: 0 as _,
};
let class_atom = RegisterClassExW(&wnd_class);
if class_atom == 0 {
println!("Failed to RegisterClassExW");
}
let hwnd = CreateWindowExW(
0,
class_name.as_ptr(),
std::ptr::null(),
0,
0,
0,
0,
0,
HWND_MESSAGE,
0 as _,
0 as _,
std::ptr::null(),
);
if hwnd == 0 as _ {
println!("Failed to create Win32 clipboard message window");
return;
}
if AddClipboardFormatListener(hwnd) == 0 {
println!("Failed to AddClipboardFormatListener");
DestroyWindow(hwnd);
return;
}
println!("Win32 clipboard listener registered successfully on HWND_MESSAGE.");
let mut msg: MSG = std::mem::zeroed();
while GetMessageW(&mut msg, 0 as _, 0, 0) > 0 {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
RemoveClipboardFormatListener(hwnd);
DestroyWindow(hwnd);
}
})
.expect("Failed to spawn thread");
// Run a basic tokio runtime to keep the main thread alive for a bit
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let _ = tokio::time::timeout(tokio::time::Duration::from_secs(3), async {
while let Some(()) = rx.recv().await {
println!("Got message from channel");
}
}).await;
});
println!("Isolation test completed without crash.");
}
#[cfg(not(target_os = "windows"))]
fn main() {
println!("Not on windows, skipping isolation test");
}