refactor: adjust windows file layout

Signed-off-by: cailue <cailue@bupt.edu.cn>
This commit is contained in:
cailue 2023-08-24 22:34:12 +08:00
parent 422062b432
commit c25d648321
12 changed files with 1309 additions and 1184 deletions

View File

@ -2,7 +2,7 @@
name = "clipboard"
version = "0.1.0"
edition = "2021"
build= "build.rs"
build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -1,573 +0,0 @@
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(deref_nullptr)]
use std::{boxed::Box, result::Result};
use thiserror::Error;
pub type size_t = ::std::os::raw::c_ulonglong;
pub type __vcrt_bool = bool;
pub type wchar_t = ::std::os::raw::c_ushort;
pub type POINTER_64_INT = ::std::os::raw::c_ulonglong;
pub type INT8 = ::std::os::raw::c_schar;
pub type PINT8 = *mut ::std::os::raw::c_schar;
pub type INT16 = ::std::os::raw::c_short;
pub type PINT16 = *mut ::std::os::raw::c_short;
pub type INT32 = ::std::os::raw::c_int;
pub type PINT32 = *mut ::std::os::raw::c_int;
pub type INT64 = ::std::os::raw::c_longlong;
pub type PINT64 = *mut ::std::os::raw::c_longlong;
pub type UINT8 = ::std::os::raw::c_uchar;
pub type PUINT8 = *mut ::std::os::raw::c_uchar;
pub type UINT16 = ::std::os::raw::c_ushort;
pub type PUINT16 = *mut ::std::os::raw::c_ushort;
pub type UINT32 = ::std::os::raw::c_uint;
pub type PUINT32 = *mut ::std::os::raw::c_uint;
pub type UINT64 = ::std::os::raw::c_ulonglong;
pub type PUINT64 = *mut ::std::os::raw::c_ulonglong;
pub type LONG32 = ::std::os::raw::c_int;
pub type PLONG32 = *mut ::std::os::raw::c_int;
pub type ULONG32 = ::std::os::raw::c_uint;
pub type PULONG32 = *mut ::std::os::raw::c_uint;
pub type DWORD32 = ::std::os::raw::c_uint;
pub type PDWORD32 = *mut ::std::os::raw::c_uint;
pub type INT_PTR = ::std::os::raw::c_longlong;
pub type PINT_PTR = *mut ::std::os::raw::c_longlong;
pub type UINT_PTR = ::std::os::raw::c_ulonglong;
pub type PUINT_PTR = *mut ::std::os::raw::c_ulonglong;
pub type LONG_PTR = ::std::os::raw::c_longlong;
pub type PLONG_PTR = *mut ::std::os::raw::c_longlong;
pub type ULONG_PTR = ::std::os::raw::c_ulonglong;
pub type PULONG_PTR = *mut ::std::os::raw::c_ulonglong;
pub type SHANDLE_PTR = ::std::os::raw::c_longlong;
pub type HANDLE_PTR = ::std::os::raw::c_ulonglong;
pub type UHALF_PTR = ::std::os::raw::c_uint;
pub type PUHALF_PTR = *mut ::std::os::raw::c_uint;
pub type HALF_PTR = ::std::os::raw::c_int;
pub type PHALF_PTR = *mut ::std::os::raw::c_int;
pub type SIZE_T = ULONG_PTR;
pub type PSIZE_T = *mut ULONG_PTR;
pub type SSIZE_T = LONG_PTR;
pub type PSSIZE_T = *mut LONG_PTR;
pub type DWORD_PTR = ULONG_PTR;
pub type PDWORD_PTR = *mut ULONG_PTR;
pub type LONG64 = ::std::os::raw::c_longlong;
pub type PLONG64 = *mut ::std::os::raw::c_longlong;
pub type ULONG64 = ::std::os::raw::c_ulonglong;
pub type PULONG64 = *mut ::std::os::raw::c_ulonglong;
pub type DWORD64 = ::std::os::raw::c_ulonglong;
pub type PDWORD64 = *mut ::std::os::raw::c_ulonglong;
pub type KAFFINITY = ULONG_PTR;
pub type PKAFFINITY = *mut KAFFINITY;
pub type PVOID = *mut ::std::os::raw::c_void;
pub type CHAR = ::std::os::raw::c_char;
pub type SHORT = ::std::os::raw::c_short;
pub type LONG = ::std::os::raw::c_long;
pub type WCHAR = wchar_t;
pub type PWCHAR = *mut WCHAR;
pub type LPWCH = *mut WCHAR;
pub type PWCH = *mut WCHAR;
pub type LPCWCH = *const WCHAR;
pub type PCWCH = *const WCHAR;
pub type NWPSTR = *mut WCHAR;
pub type LPWSTR = *mut WCHAR;
pub type PWSTR = *mut WCHAR;
pub type PZPWSTR = *mut PWSTR;
pub type PCZPWSTR = *const PWSTR;
pub type LPUWSTR = *mut WCHAR;
pub type PUWSTR = *mut WCHAR;
pub type LPCWSTR = *const WCHAR;
pub type PCWSTR = *const WCHAR;
pub type PZPCWSTR = *mut PCWSTR;
pub type PCZPCWSTR = *const PCWSTR;
pub type LPCUWSTR = *const WCHAR;
pub type PCUWSTR = *const WCHAR;
pub type PZZWSTR = *mut WCHAR;
pub type PCZZWSTR = *const WCHAR;
pub type PUZZWSTR = *mut WCHAR;
pub type PCUZZWSTR = *const WCHAR;
pub type PNZWCH = *mut WCHAR;
pub type PCNZWCH = *const WCHAR;
pub type PUNZWCH = *mut WCHAR;
pub type PCUNZWCH = *const WCHAR;
pub type PCHAR = *mut CHAR;
pub type LPCH = *mut CHAR;
pub type PCH = *mut CHAR;
pub type LPCCH = *const CHAR;
pub type PCCH = *const CHAR;
pub type NPSTR = *mut CHAR;
pub type LPSTR = *mut CHAR;
pub type PSTR = *mut CHAR;
pub type PZPSTR = *mut PSTR;
pub type PCZPSTR = *const PSTR;
pub type LPCSTR = *const CHAR;
pub type PCSTR = *const CHAR;
pub type PZPCSTR = *mut PCSTR;
pub type PCZPCSTR = *const PCSTR;
pub type PZZSTR = *mut CHAR;
pub type PCZZSTR = *const CHAR;
pub type PNZCH = *mut CHAR;
pub type PCNZCH = *const CHAR;
pub type TCHAR = ::std::os::raw::c_char;
pub type PTCHAR = *mut ::std::os::raw::c_char;
pub type TBYTE = ::std::os::raw::c_uchar;
pub type PTBYTE = *mut ::std::os::raw::c_uchar;
pub type LPTCH = LPCH;
pub type PTCH = LPCH;
pub type LPCTCH = LPCCH;
pub type PCTCH = LPCCH;
pub type PTSTR = LPSTR;
pub type LPTSTR = LPSTR;
pub type PUTSTR = LPSTR;
pub type LPUTSTR = LPSTR;
pub type PCTSTR = LPCSTR;
pub type LPCTSTR = LPCSTR;
pub type PCUTSTR = LPCSTR;
pub type LPCUTSTR = LPCSTR;
pub type PZZTSTR = PZZSTR;
pub type PUZZTSTR = PZZSTR;
pub type PCZZTSTR = PCZZSTR;
pub type PCUZZTSTR = PCZZSTR;
pub type PZPTSTR = PZPSTR;
pub type PNZTCH = PNZCH;
pub type PUNZTCH = PNZCH;
pub type PCNZTCH = PCNZCH;
pub type PCUNZTCH = PCNZCH;
pub type PSHORT = *mut SHORT;
pub type PLONG = *mut LONG;
pub type ULONG = ::std::os::raw::c_ulong;
pub type PULONG = *mut ULONG;
pub type USHORT = ::std::os::raw::c_ushort;
pub type PUSHORT = *mut USHORT;
pub type UCHAR = ::std::os::raw::c_uchar;
pub type PUCHAR = *mut UCHAR;
pub type PSZ = *mut ::std::os::raw::c_char;
pub type DWORD = ::std::os::raw::c_ulong;
pub type BOOL = ::std::os::raw::c_int;
pub type BYTE = ::std::os::raw::c_uchar;
pub type WORD = ::std::os::raw::c_ushort;
pub type FLOAT = f32;
pub type PFLOAT = *mut FLOAT;
pub type PBOOL = *mut BOOL;
pub type LPBOOL = *mut BOOL;
pub type PBYTE = *mut BYTE;
pub type LPBYTE = *mut BYTE;
pub type PINT = *mut ::std::os::raw::c_int;
pub type LPINT = *mut ::std::os::raw::c_int;
pub type PWORD = *mut WORD;
pub type LPWORD = *mut WORD;
pub type LPLONG = *mut ::std::os::raw::c_long;
pub type PDWORD = *mut DWORD;
pub type LPDWORD = *mut DWORD;
pub type LPVOID = *mut ::std::os::raw::c_void;
pub type LPCVOID = *const ::std::os::raw::c_void;
pub type INT = ::std::os::raw::c_int;
pub type UINT = ::std::os::raw::c_uint;
pub type PUINT = *mut ::std::os::raw::c_uint;
pub type va_list = *mut ::std::os::raw::c_char;
pub const TRUE: ::std::os::raw::c_int = 1;
pub const FALSE: ::std::os::raw::c_int = 0;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_HEADER {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
}
pub type CLIPRDR_HEADER = _CLIPRDR_HEADER;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_CAPABILITY_SET {
pub capabilitySetType: UINT16,
pub capabilitySetLength: UINT16,
}
pub type CLIPRDR_CAPABILITY_SET = _CLIPRDR_CAPABILITY_SET;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_GENERAL_CAPABILITY_SET {
pub capabilitySetType: UINT16,
pub capabilitySetLength: UINT16,
pub version: UINT32,
pub generalFlags: UINT32,
}
pub type CLIPRDR_GENERAL_CAPABILITY_SET = _CLIPRDR_GENERAL_CAPABILITY_SET;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_CAPABILITIES {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub cCapabilitiesSets: UINT32,
pub capabilitySets: *mut CLIPRDR_CAPABILITY_SET,
}
pub type CLIPRDR_CAPABILITIES = _CLIPRDR_CAPABILITIES;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_MONITOR_READY {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
}
pub type CLIPRDR_MONITOR_READY = _CLIPRDR_MONITOR_READY;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_TEMP_DIRECTORY {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub szTempDir: [::std::os::raw::c_char; 520usize],
}
pub type CLIPRDR_TEMP_DIRECTORY = _CLIPRDR_TEMP_DIRECTORY;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FORMAT {
pub formatId: UINT32,
pub formatName: *mut ::std::os::raw::c_char,
}
pub type CLIPRDR_FORMAT = _CLIPRDR_FORMAT;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FORMAT_LIST {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub numFormats: UINT32,
pub formats: *mut CLIPRDR_FORMAT,
}
pub type CLIPRDR_FORMAT_LIST = _CLIPRDR_FORMAT_LIST;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FORMAT_LIST_RESPONSE {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
}
pub type CLIPRDR_FORMAT_LIST_RESPONSE = _CLIPRDR_FORMAT_LIST_RESPONSE;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_LOCK_CLIPBOARD_DATA {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub clipDataId: UINT32,
}
pub type CLIPRDR_LOCK_CLIPBOARD_DATA = _CLIPRDR_LOCK_CLIPBOARD_DATA;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_UNLOCK_CLIPBOARD_DATA {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub clipDataId: UINT32,
}
pub type CLIPRDR_UNLOCK_CLIPBOARD_DATA = _CLIPRDR_UNLOCK_CLIPBOARD_DATA;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FORMAT_DATA_REQUEST {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub requestedFormatId: UINT32,
}
pub type CLIPRDR_FORMAT_DATA_REQUEST = _CLIPRDR_FORMAT_DATA_REQUEST;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FORMAT_DATA_RESPONSE {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub requestedFormatData: *const BYTE,
}
pub type CLIPRDR_FORMAT_DATA_RESPONSE = _CLIPRDR_FORMAT_DATA_RESPONSE;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FILE_CONTENTS_REQUEST {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub streamId: UINT32,
pub listIndex: UINT32,
pub dwFlags: UINT32,
pub nPositionLow: UINT32,
pub nPositionHigh: UINT32,
pub cbRequested: UINT32,
pub haveClipDataId: BOOL,
pub clipDataId: UINT32,
}
pub type CLIPRDR_FILE_CONTENTS_REQUEST = _CLIPRDR_FILE_CONTENTS_REQUEST;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _CLIPRDR_FILE_CONTENTS_RESPONSE {
pub connID: UINT32,
pub msgType: UINT16,
pub msgFlags: UINT16,
pub dataLen: UINT32,
pub streamId: UINT32,
pub cbRequested: UINT32,
pub requestedData: *const BYTE,
}
pub type CLIPRDR_FILE_CONTENTS_RESPONSE = _CLIPRDR_FILE_CONTENTS_RESPONSE;
pub type CliprdrClientContext = _cliprdr_client_context;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _NOTIFICATION_MESSAGE {
pub r#type: UINT32, // 0 - info, 1 - warning, 2 - error
pub msg: *const BYTE,
pub details: *const BYTE,
}
pub type NOTIFICATION_MESSAGE = _NOTIFICATION_MESSAGE;
pub type pcCliprdrServerCapabilities = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
capabilities: *const CLIPRDR_CAPABILITIES,
) -> UINT,
>;
pub type pcCliprdrClientCapabilities = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
capabilities: *const CLIPRDR_CAPABILITIES,
) -> UINT,
>;
pub type pcCliprdrMonitorReady = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
monitorReady: *const CLIPRDR_MONITOR_READY,
) -> UINT,
>;
pub type pcCliprdrTempDirectory = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
tempDirectory: *const CLIPRDR_TEMP_DIRECTORY,
) -> UINT,
>;
pub type pcNotifyClipboardMsg =
::std::option::Option<unsafe extern "C" fn(connID: UINT32, msg: *const NOTIFICATION_MESSAGE) -> UINT>;
pub type pcCliprdrClientFormatList = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatList: *const CLIPRDR_FORMAT_LIST,
) -> UINT,
>;
pub type pcCliprdrServerFormatList = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatList: *const CLIPRDR_FORMAT_LIST,
) -> UINT,
>;
pub type pcCliprdrClientFormatListResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatListResponse: *const CLIPRDR_FORMAT_LIST_RESPONSE,
) -> UINT,
>;
pub type pcCliprdrServerFormatListResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatListResponse: *const CLIPRDR_FORMAT_LIST_RESPONSE,
) -> UINT,
>;
pub type pcCliprdrClientLockClipboardData = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
lockClipboardData: *const CLIPRDR_LOCK_CLIPBOARD_DATA,
) -> UINT,
>;
pub type pcCliprdrServerLockClipboardData = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
lockClipboardData: *const CLIPRDR_LOCK_CLIPBOARD_DATA,
) -> UINT,
>;
pub type pcCliprdrClientUnlockClipboardData = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
unlockClipboardData: *const CLIPRDR_UNLOCK_CLIPBOARD_DATA,
) -> UINT,
>;
pub type pcCliprdrServerUnlockClipboardData = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
unlockClipboardData: *const CLIPRDR_UNLOCK_CLIPBOARD_DATA,
) -> UINT,
>;
pub type pcCliprdrClientFormatDataRequest = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatDataRequest: *const CLIPRDR_FORMAT_DATA_REQUEST,
) -> UINT,
>;
pub type pcCliprdrServerFormatDataRequest = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatDataRequest: *const CLIPRDR_FORMAT_DATA_REQUEST,
) -> UINT,
>;
pub type pcCliprdrClientFormatDataResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatDataResponse: *const CLIPRDR_FORMAT_DATA_RESPONSE,
) -> UINT,
>;
pub type pcCliprdrServerFormatDataResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
formatDataResponse: *const CLIPRDR_FORMAT_DATA_RESPONSE,
) -> UINT,
>;
pub type pcCliprdrClientFileContentsRequest = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
fileContentsRequest: *const CLIPRDR_FILE_CONTENTS_REQUEST,
) -> UINT,
>;
pub type pcCliprdrServerFileContentsRequest = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
fileContentsRequest: *const CLIPRDR_FILE_CONTENTS_REQUEST,
) -> UINT,
>;
pub type pcCliprdrClientFileContentsResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
fileContentsResponse: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
) -> UINT,
>;
pub type pcCliprdrServerFileContentsResponse = ::std::option::Option<
unsafe extern "C" fn(
context: *mut CliprdrClientContext,
fileContentsResponse: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
) -> UINT,
>;
// TODO: hide more members of clipboard context
#[repr(C)]
#[derive(Debug, Clone)]
pub struct _cliprdr_client_context {
pub Custom: *mut ::std::os::raw::c_void,
pub EnableFiles: BOOL,
pub EnableOthers: BOOL,
pub IsStopped: BOOL,
pub ResponseWaitTimeoutSecs: UINT32,
pub ServerCapabilities: pcCliprdrServerCapabilities,
pub ClientCapabilities: pcCliprdrClientCapabilities,
pub MonitorReady: pcCliprdrMonitorReady,
pub TempDirectory: pcCliprdrTempDirectory,
pub NotifyClipboardMsg: pcNotifyClipboardMsg,
pub ClientFormatList: pcCliprdrClientFormatList,
pub ServerFormatList: pcCliprdrServerFormatList,
pub ClientFormatListResponse: pcCliprdrClientFormatListResponse,
pub ServerFormatListResponse: pcCliprdrServerFormatListResponse,
pub ClientLockClipboardData: pcCliprdrClientLockClipboardData,
pub ServerLockClipboardData: pcCliprdrServerLockClipboardData,
pub ClientUnlockClipboardData: pcCliprdrClientUnlockClipboardData,
pub ServerUnlockClipboardData: pcCliprdrServerUnlockClipboardData,
pub ClientFormatDataRequest: pcCliprdrClientFormatDataRequest,
pub ServerFormatDataRequest: pcCliprdrServerFormatDataRequest,
pub ClientFormatDataResponse: pcCliprdrClientFormatDataResponse,
pub ServerFormatDataResponse: pcCliprdrServerFormatDataResponse,
pub ClientFileContentsRequest: pcCliprdrClientFileContentsRequest,
pub ServerFileContentsRequest: pcCliprdrServerFileContentsRequest,
pub ClientFileContentsResponse: pcCliprdrClientFileContentsResponse,
pub ServerFileContentsResponse: pcCliprdrServerFileContentsResponse,
pub LastRequestedFormatId: UINT32,
}
// #[link(name = "user32")]
// #[link(name = "ole32")]
extern "C" {
pub(crate) fn init_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
pub(crate) fn uninit_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
pub(crate) fn empty_cliprdr(context: *mut CliprdrClientContext, connID: UINT32) -> BOOL;
}
#[derive(Error, Debug)]
pub enum CliprdrError {
#[error("invalid cliprdr name")]
CliprdrName,
#[error("failed to init cliprdr")]
CliprdrInit,
#[error("unknown cliprdr error")]
Unknown,
}
impl CliprdrClientContext {
pub fn create(
enable_files: bool,
enable_others: bool,
response_wait_timeout_secs: u32,
notify_callback: pcNotifyClipboardMsg,
client_format_list: pcCliprdrClientFormatList,
client_format_list_response: pcCliprdrClientFormatListResponse,
client_format_data_request: pcCliprdrClientFormatDataRequest,
client_format_data_response: pcCliprdrClientFormatDataResponse,
client_file_contents_request: pcCliprdrClientFileContentsRequest,
client_file_contents_response: pcCliprdrClientFileContentsResponse,
) -> Result<Box<Self>, CliprdrError> {
let context = CliprdrClientContext {
Custom: 0 as *mut _,
EnableFiles: if enable_files { TRUE } else { FALSE },
EnableOthers: if enable_others { TRUE } else { FALSE },
IsStopped: FALSE,
ResponseWaitTimeoutSecs: response_wait_timeout_secs,
ServerCapabilities: None,
ClientCapabilities: None,
MonitorReady: None,
TempDirectory: None,
NotifyClipboardMsg: notify_callback,
ClientFormatList: client_format_list,
ServerFormatList: None,
ClientFormatListResponse: client_format_list_response,
ServerFormatListResponse: None,
ClientLockClipboardData: None,
ServerLockClipboardData: None,
ClientUnlockClipboardData: None,
ServerUnlockClipboardData: None,
ClientFormatDataRequest: client_format_data_request,
ServerFormatDataRequest: None,
ClientFormatDataResponse: client_format_data_response,
ServerFormatDataResponse: None,
ClientFileContentsRequest: client_file_contents_request,
ServerFileContentsRequest: None,
ClientFileContentsResponse: client_file_contents_response,
ServerFileContentsResponse: None,
LastRequestedFormatId: 0,
};
let mut context = Box::new(context);
unsafe {
if FALSE == init_cliprdr(&mut (*context)) {
println!("Failed to init cliprdr");
Err(CliprdrError::CliprdrInit)
} else {
Ok(context)
}
}
}
}
impl Drop for CliprdrClientContext {
fn drop(&mut self) {
unsafe {
if FALSE == uninit_cliprdr(&mut *self) {
println!("Failed to uninit cliprdr");
} else {
println!("Succeeded to uninit cliprdr");
}
}
}
}

View File

@ -1,34 +1,32 @@
use crate::cliprdr::*;
use hbb_common::log;
use hbb_common::{log, ResultType};
use std::sync::Mutex;
use crate::CliprdrServiceContext;
const CLIPBOARD_RESPONSE_WAIT_TIMEOUT_SECS: u32 = 30;
lazy_static::lazy_static! {
static ref CONTEXT_SEND: ContextSend = ContextSend{addr: Mutex::new(0)};
static ref CONTEXT_SEND: ContextSend = ContextSend{addr: Mutex::new(None)};
}
pub struct ContextSend {
addr: Mutex<u64>,
addr: Mutex<Option<Box<dyn CliprdrServiceContext>>>,
}
impl ContextSend {
#[inline]
pub fn is_enabled() -> bool {
*CONTEXT_SEND.addr.lock().unwrap() != 0
CONTEXT_SEND.addr.lock().unwrap().is_some()
}
pub fn set_is_stopped() {
let _res = Self::proc(|c| {
c.IsStopped = TRUE;
0
});
let _res = Self::proc(|c| c.set_is_stopped().map_err(|e| e.into()));
}
pub fn enable(enabled: bool) {
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
if enabled {
if *lock == 0 {
if lock.is_none() {
match crate::create_cliprdr_context(
true,
false,
@ -36,7 +34,7 @@ impl ContextSend {
) {
Ok(context) => {
log::info!("clipboard context for file transfer created.");
*lock = Box::into_raw(context) as _;
*lock = Some(context)
}
Err(err) => {
log::error!(
@ -47,27 +45,20 @@ impl ContextSend {
}
}
} else {
if *lock != 0 {
unsafe {
let _ = Box::from_raw(*lock as *mut CliprdrClientContext);
}
if let Some(_clp) = lock.take() {
*lock = None;
log::info!("clipboard context for file transfer destroyed.");
*lock = 0;
}
}
}
pub fn proc<F: FnOnce(&mut Box<CliprdrClientContext>) -> u32>(f: F) -> u32 {
let lock = CONTEXT_SEND.addr.lock().unwrap();
if *lock != 0 {
unsafe {
let mut context = Box::from_raw(*lock as *mut CliprdrClientContext);
let code = f(&mut context);
std::mem::forget(context);
code
}
} else {
0
pub fn proc<F: FnOnce(&mut Box<dyn CliprdrServiceContext>) -> ResultType<()>>(
f: F,
) -> ResultType<()> {
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
match lock.as_mut() {
Some(context) => f(context),
None => Ok(()),
}
}
}

View File

@ -1,4 +1,8 @@
use cliprdr::*;
use std::{
ffi::{CStr, CString},
sync::{Arc, Mutex, RwLock},
};
use hbb_common::{
allow_err, lazy_static, log,
tokio::sync::{
@ -8,19 +12,47 @@ use hbb_common::{
ResultType, SessionID,
};
use serde_derive::{Deserialize, Serialize};
use std::{
boxed::Box,
ffi::{CStr, CString},
sync::{Arc, Mutex, RwLock},
};
use thiserror::Error;
pub mod cliprdr;
pub mod context_send;
pub mod platform;
pub use context_send::*;
const ERR_CODE_SERVER_FUNCTION_NONE: u32 = 0x00000001;
const ERR_CODE_INVALID_PARAMETER: u32 = 0x00000002;
pub(crate) use platform::create_cliprdr_context;
/// Ability to handle Clipboard File from remote rustdesk client
///
/// # Note
/// There actually should be 2 parts to implement a useable clipboard file service,
/// but this only contains the RPC server part.
/// The local listener and transport part is too platform specific to wrap up in typeclasses.
pub trait CliprdrServiceContext: Send + Sync {
/// set to be stopped
fn set_is_stopped(&mut self) -> Result<(), CliprdrError>;
/// clear the content on clipboard
fn empty_clipboard(&mut self, conn_id: i32) -> bool;
/// run as a server for clipboard RPC
fn server_clip_file(&mut self, conn_id: i32, msg: ClipboardFile) -> Result<(), CliprdrError>;
}
#[derive(Error, Debug)]
pub enum CliprdrError {
#[error("invalid cliprdr name")]
CliprdrName,
#[error("failed to init cliprdr")]
CliprdrInit,
#[error("cliprdr out of memory")]
CliprdrOutOfMemory,
#[error("cliprdr internal error")]
ClipboardInternalError,
#[error("unknown cliprdr error")]
Unknown(u32),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "t", content = "c")]
pub enum ClipboardFile {
@ -164,554 +196,6 @@ fn send_data(conn_id: i32, data: ClipboardFile) {
}
}
pub fn empty_clipboard(context: &mut Box<CliprdrClientContext>, conn_id: i32) -> bool {
unsafe { TRUE == cliprdr::empty_cliprdr(&mut (**context), conn_id as u32) }
}
pub fn server_clip_file(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
msg: ClipboardFile,
) -> u32 {
let mut ret = 0;
match msg {
ClipboardFile::NotifyCallback { .. } => {
// unreachable
}
ClipboardFile::MonitorReady => {
log::debug!("server_monitor_ready called");
ret = server_monitor_ready(context, conn_id);
log::debug!("server_monitor_ready called, return {}", ret);
}
ClipboardFile::FormatList { format_list } => {
log::debug!("server_format_list called");
ret = server_format_list(context, conn_id, format_list);
log::debug!("server_format_list called, return {}", ret);
}
ClipboardFile::FormatListResponse { msg_flags } => {
log::debug!("format_list_response called");
ret = server_format_list_response(context, conn_id, msg_flags);
log::debug!("server_format_list_response called, return {}", ret);
}
ClipboardFile::FormatDataRequest {
requested_format_id,
} => {
log::debug!("format_data_request called");
ret = server_format_data_request(context, conn_id, requested_format_id);
log::debug!("server_format_data_request called, return {}", ret);
}
ClipboardFile::FormatDataResponse {
msg_flags,
format_data,
} => {
log::debug!("format_data_response called");
ret = server_format_data_response(context, conn_id, msg_flags, format_data);
log::debug!("server_format_data_response called, return {}", ret);
}
ClipboardFile::FileContentsRequest {
stream_id,
list_index,
dw_flags,
n_position_low,
n_position_high,
cb_requested,
have_clip_data_id,
clip_data_id,
} => {
log::debug!("file_contents_request called");
ret = server_file_contents_request(
context,
conn_id,
stream_id,
list_index,
dw_flags,
n_position_low,
n_position_high,
cb_requested,
have_clip_data_id,
clip_data_id,
);
log::debug!("server_file_contents_request called, return {}", ret);
}
ClipboardFile::FileContentsResponse {
msg_flags,
stream_id,
requested_data,
} => {
log::debug!("file_contents_response called");
ret = server_file_contents_response(
context,
conn_id,
msg_flags,
stream_id,
requested_data,
);
log::debug!("server_file_contents_response called, return {}", ret);
}
}
ret
}
pub fn server_monitor_ready(context: &mut Box<CliprdrClientContext>, conn_id: i32) -> u32 {
unsafe {
let monitor_ready = CLIPRDR_MONITOR_READY {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: 0 as UINT16,
dataLen: 0 as UINT32,
};
if let Some(f) = (**context).MonitorReady {
let ret = f(&mut (**context), &monitor_ready);
ret as u32
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn server_format_list(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
format_list: Vec<(i32, String)>,
) -> u32 {
unsafe {
let num_formats = format_list.len() as UINT32;
let mut formats = format_list
.into_iter()
.map(|format| {
if format.1.is_empty() {
CLIPRDR_FORMAT {
formatId: format.0 as UINT32,
formatName: 0 as *mut _,
}
} else {
let n = match CString::new(format.1) {
Ok(n) => n,
Err(_) => CString::new("").unwrap(),
};
CLIPRDR_FORMAT {
formatId: format.0 as UINT32,
formatName: n.into_raw(),
}
}
})
.collect::<Vec<CLIPRDR_FORMAT>>();
let format_list = CLIPRDR_FORMAT_LIST {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: 0 as UINT16,
dataLen: 0 as UINT32,
numFormats: num_formats,
formats: formats.as_mut_ptr(),
};
let ret = if let Some(f) = (**context).ServerFormatList {
f(&mut (**context), &format_list)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
};
for f in formats {
if !f.formatName.is_null() {
// retake pointer to free memory
let _ = CString::from_raw(f.formatName);
}
}
ret as u32
}
}
pub fn server_format_list_response(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
msg_flags: i32,
) -> u32 {
unsafe {
let format_list_response = CLIPRDR_FORMAT_LIST_RESPONSE {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: msg_flags as UINT16,
dataLen: 0 as UINT32,
};
if let Some(f) = (**context).ServerFormatListResponse {
f(&mut (**context), &format_list_response)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn server_format_data_request(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
requested_format_id: i32,
) -> u32 {
unsafe {
let format_data_request = CLIPRDR_FORMAT_DATA_REQUEST {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: 0 as UINT16,
dataLen: 0 as UINT32,
requestedFormatId: requested_format_id as UINT32,
};
if let Some(f) = (**context).ServerFormatDataRequest {
f(&mut (**context), &format_data_request)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn server_format_data_response(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
msg_flags: i32,
mut format_data: Vec<u8>,
) -> u32 {
unsafe {
let format_data_response = CLIPRDR_FORMAT_DATA_RESPONSE {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: msg_flags as UINT16,
dataLen: format_data.len() as UINT32,
requestedFormatData: format_data.as_mut_ptr(),
};
if let Some(f) = (**context).ServerFormatDataResponse {
f(&mut (**context), &format_data_response)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn server_file_contents_request(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
stream_id: i32,
list_index: i32,
dw_flags: i32,
n_position_low: i32,
n_position_high: i32,
cb_requested: i32,
have_clip_data_id: bool,
clip_data_id: i32,
) -> u32 {
unsafe {
let file_contents_request = CLIPRDR_FILE_CONTENTS_REQUEST {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: 0 as UINT16,
dataLen: 0 as UINT32,
streamId: stream_id as UINT32,
listIndex: list_index as UINT32,
dwFlags: dw_flags as UINT32,
nPositionLow: n_position_low as UINT32,
nPositionHigh: n_position_high as UINT32,
cbRequested: cb_requested as UINT32,
haveClipDataId: if have_clip_data_id { TRUE } else { FALSE },
clipDataId: clip_data_id as UINT32,
};
if let Some(f) = (**context).ServerFileContentsRequest {
f(&mut (**context), &file_contents_request)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn server_file_contents_response(
context: &mut Box<CliprdrClientContext>,
conn_id: i32,
msg_flags: i32,
stream_id: i32,
mut requested_data: Vec<u8>,
) -> u32 {
unsafe {
let file_contents_response = CLIPRDR_FILE_CONTENTS_RESPONSE {
connID: conn_id as UINT32,
msgType: 0 as UINT16,
msgFlags: msg_flags as UINT16,
dataLen: 4 + requested_data.len() as UINT32,
streamId: stream_id as UINT32,
cbRequested: requested_data.len() as UINT32,
requestedData: requested_data.as_mut_ptr(),
};
if let Some(f) = (**context).ServerFileContentsResponse {
f(&mut (**context), &file_contents_response)
} else {
ERR_CODE_SERVER_FUNCTION_NONE
}
}
}
pub fn create_cliprdr_context(
enable_files: bool,
enable_others: bool,
response_wait_timeout_secs: u32,
) -> ResultType<Box<CliprdrClientContext>> {
Ok(CliprdrClientContext::create(
enable_files,
enable_others,
response_wait_timeout_secs,
Some(notify_callback),
Some(client_format_list),
Some(client_format_list_response),
Some(client_format_data_request),
Some(client_format_data_response),
Some(client_file_contents_request),
Some(client_file_contents_response),
)?)
}
extern "C" fn notify_callback(conn_id: UINT32, msg: *const NOTIFICATION_MESSAGE) -> UINT {
log::debug!("notify_callback called");
let data = unsafe {
let msg = &*msg;
let details = if msg.details.is_null() {
Ok("")
} else {
CStr::from_ptr(msg.details as _).to_str()
};
match (CStr::from_ptr(msg.msg as _).to_str(), details) {
(Ok(m), Ok(d)) => {
let msgtype = format!(
"custom-{}-nocancel-nook-hasclose",
if msg.r#type == 0 {
"info"
} else if msg.r#type == 1 {
"warn"
} else {
"error"
}
);
let title = "Clipboard";
let text = if d.is_empty() {
m.to_string()
} else {
format!("{} {}", m, d)
};
ClipboardFile::NotifyCallback {
r#type: msgtype,
title: title.to_string(),
text,
}
}
_ => {
log::error!("notify_callback: failed to convert msg");
return ERR_CODE_INVALID_PARAMETER;
}
}
};
// no need to handle result here
send_data(conn_id as _, data);
0
}
extern "C" fn client_format_list(
_context: *mut CliprdrClientContext,
clip_format_list: *const CLIPRDR_FORMAT_LIST,
) -> UINT {
log::debug!("client_format_list called");
let conn_id;
let mut format_list: Vec<(i32, String)> = Vec::new();
unsafe {
let mut i = 0u32;
while i < (*clip_format_list).numFormats {
let format_data = &(*(*clip_format_list).formats.offset(i as isize));
if format_data.formatName.is_null() {
format_list.push((format_data.formatId as i32, "".to_owned()));
} else {
let format_name = CStr::from_ptr(format_data.formatName).to_str();
let format_name = match format_name {
Ok(n) => n.to_owned(),
Err(_) => {
log::warn!("failed to get format name");
"".to_owned()
}
};
format_list.push((format_data.formatId as i32, format_name));
}
// log::debug!("format list item {}: format id: {}, format name: {}", i, format_data.formatId, &format_name);
i += 1;
}
conn_id = (*clip_format_list).connID as i32;
}
let data = ClipboardFile::FormatList { format_list };
// no need to handle result here
if conn_id == 0 {
// msg_channel is used for debug, VEC_MSG_CHANNEL cannot be inspected by the debugger.
let msg_channel = VEC_MSG_CHANNEL.read().unwrap();
msg_channel
.iter()
.for_each(|msg_channel| allow_err!(msg_channel.sender.send(data.clone())));
} else {
send_data(conn_id, data);
}
0
}
extern "C" fn client_format_list_response(
_context: *mut CliprdrClientContext,
format_list_response: *const CLIPRDR_FORMAT_LIST_RESPONSE,
) -> UINT {
log::debug!("client_format_list_response called");
let conn_id;
let msg_flags;
unsafe {
conn_id = (*format_list_response).connID as i32;
msg_flags = (*format_list_response).msgFlags as i32;
}
let data = ClipboardFile::FormatListResponse { msg_flags };
send_data(conn_id, data);
0
}
extern "C" fn client_format_data_request(
_context: *mut CliprdrClientContext,
format_data_request: *const CLIPRDR_FORMAT_DATA_REQUEST,
) -> UINT {
log::debug!("client_format_data_request called");
let conn_id;
let requested_format_id;
unsafe {
conn_id = (*format_data_request).connID as i32;
requested_format_id = (*format_data_request).requestedFormatId as i32;
}
let data = ClipboardFile::FormatDataRequest {
requested_format_id,
};
// no need to handle result here
send_data(conn_id, data);
0
}
extern "C" fn client_format_data_response(
_context: *mut CliprdrClientContext,
format_data_response: *const CLIPRDR_FORMAT_DATA_RESPONSE,
) -> UINT {
log::debug!("cconn_idlient_format_data_response called");
let conn_id;
let msg_flags;
let format_data;
unsafe {
conn_id = (*format_data_response).connID as i32;
msg_flags = (*format_data_response).msgFlags as i32;
if (*format_data_response).requestedFormatData.is_null() {
format_data = Vec::new();
} else {
format_data = std::slice::from_raw_parts(
(*format_data_response).requestedFormatData,
(*format_data_response).dataLen as usize,
)
.to_vec();
}
}
let data = ClipboardFile::FormatDataResponse {
msg_flags,
format_data,
};
send_data(conn_id, data);
0
}
extern "C" fn client_file_contents_request(
_context: *mut CliprdrClientContext,
file_contents_request: *const CLIPRDR_FILE_CONTENTS_REQUEST,
) -> UINT {
log::debug!("client_file_contents_request called");
// TODO: support huge file?
// if (!cliprdr->hasHugeFileSupport)
// {
// if (((UINT64)fileContentsRequest->cbRequested + fileContentsRequest->nPositionLow) >
// UINT32_MAX)
// return ERROR_INVALID_PARAMETER;
// if (fileContentsRequest->nPositionHigh != 0)
// return ERROR_INVALID_PARAMETER;
// }
let conn_id;
let stream_id;
let list_index;
let dw_flags;
let n_position_low;
let n_position_high;
let cb_requested;
let have_clip_data_id;
let clip_data_id;
unsafe {
conn_id = (*file_contents_request).connID as i32;
stream_id = (*file_contents_request).streamId as i32;
list_index = (*file_contents_request).listIndex as i32;
dw_flags = (*file_contents_request).dwFlags as i32;
n_position_low = (*file_contents_request).nPositionLow as i32;
n_position_high = (*file_contents_request).nPositionHigh as i32;
cb_requested = (*file_contents_request).cbRequested as i32;
have_clip_data_id = (*file_contents_request).haveClipDataId == TRUE;
clip_data_id = (*file_contents_request).clipDataId as i32;
}
let data = ClipboardFile::FileContentsRequest {
stream_id,
list_index,
dw_flags,
n_position_low,
n_position_high,
cb_requested,
have_clip_data_id,
clip_data_id,
};
send_data(conn_id, data);
0
}
extern "C" fn client_file_contents_response(
_context: *mut CliprdrClientContext,
file_contents_response: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
) -> UINT {
log::debug!("client_file_contents_response called");
let conn_id;
let msg_flags;
let stream_id;
let requested_data;
unsafe {
conn_id = (*file_contents_response).connID as i32;
msg_flags = (*file_contents_response).msgFlags as i32;
stream_id = (*file_contents_response).streamId as i32;
if (*file_contents_response).requestedData.is_null() {
requested_data = Vec::new();
} else {
requested_data = std::slice::from_raw_parts(
(*file_contents_response).requestedData,
(*file_contents_response).cbRequested as usize,
)
.to_vec();
}
}
let data = ClipboardFile::FileContentsResponse {
msg_flags,
stream_id,
requested_data,
};
send_data(conn_id, data);
0
}
#[cfg(test)]
mod tests {
// #[test]

View File

@ -0,0 +1,10 @@
#[cfg(target_os = "windows")]
pub mod windows;
#[cfg(target_os = "windows")]
pub fn create_cliprdr_context(
enable_files: bool,
enable_others: bool,
response_wait_timeout_secs: u32,
) -> crate::ResultType<Box<dyn crate::CliprdrServiceContext>> {
windows::create_cliprdr_context(enable_files, enable_others, response_wait_timeout_secs)
}

File diff suppressed because it is too large Load Diff

View File

@ -1367,6 +1367,11 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
if (!clipboard)
return ERROR_INTERNAL_ERROR;
if (!IsClipboardFormatAvailable(CF_HDROP))
{
return ERROR_SUCCESS;
}
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
/* Ignore if other app is holding clipboard */
@ -1392,21 +1397,11 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
}
index = 0;
if (IsClipboardFormatAvailable(CF_HDROP))
{
UINT fsid = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
UINT fcid = RegisterClipboardFormat(CFSTR_FILECONTENTS);
formats[index++].formatId = fsid;
formats[index++].formatId = fcid;
}
else
{
while (formatId = EnumClipboardFormats(formatId) && index < numFormats)
formats[index++].formatId = formatId;
}
// IsClipboardFormatAvailable(CF_HDROP) is checked above
UINT fsid = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
UINT fcid = RegisterClipboardFormat(CFSTR_FILECONTENTS);
formats[index++].formatId = fsid;
formats[index++].formatId = fcid;
numFormats = index;
if (!CloseClipboard())

View File

@ -6,7 +6,7 @@ use std::sync::{
};
#[cfg(windows)]
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, ContextSend};
use clipboard::ContextSend;
use crossbeam_queue::ArrayQueue;
use hbb_common::config::{PeerConfig, TransferSerde};
use hbb_common::fs::{
@ -27,7 +27,7 @@ use hbb_common::tokio::{
sync::mpsc,
time::{self, Duration, Instant, Interval},
};
use hbb_common::{allow_err, fs, get_time, log, message_proto::*, Stream};
use hbb_common::{allow_err, fs, get_time, log, message_proto::*, ResultType, Stream};
use scrap::CodecFormat;
use crate::client::{
@ -281,9 +281,9 @@ impl<T: InvokeUiSession> Remote<T> {
#[cfg(windows)]
{
let conn_id = self.client_conn_id;
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
empty_clipboard(context, conn_id);
0
let _ = ContextSend::proc(|context| -> ResultType<()> {
context.empty_clipboard(conn_id);
Ok(())
});
}
}
@ -1578,8 +1578,10 @@ impl<T: InvokeUiSession> Remote<T> {
"Process clipboard message from server peer, stop: {}, is_stopping_allowed: {}, file_transfer_enabled: {}",
stop, is_stopping_allowed, file_transfer_enabled);
if !stop {
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
clipboard::server_clip_file(context, self.client_conn_id, clip)
let _ = ContextSend::proc(|context| -> ResultType<()> {
context
.server_clip_file(self.client_conn_id, clip)
.map_err(|e| e.into())
});
}
}

View File

@ -16,7 +16,7 @@ use crate::ipc::Connection;
#[cfg(not(any(target_os = "ios")))]
use crate::ipc::{self, Data};
#[cfg(windows)]
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, ContextSend};
use clipboard::ContextSend;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use hbb_common::tokio::sync::mpsc::unbounded_channel;
#[cfg(windows)]
@ -34,6 +34,7 @@ use hbb_common::{
sync::mpsc::{self, UnboundedSender},
task::spawn_blocking,
},
ResultType,
};
use serde_derive::Serialize;
@ -175,9 +176,9 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
#[cfg(windows)]
{
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
empty_clipboard(context, id);
0
let _ = ContextSend::proc(|context| -> ResultType<()> {
context.empty_clipboard(id);
Ok(())
});
}
@ -414,8 +415,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
ContextSend::set_is_stopped();
} else {
let conn_id = self.conn_id;
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
clipboard::server_clip_file(context, conn_id, _clip)
let _ = ContextSend::proc(|context| -> ResultType<()> {
context.server_clip_file(conn_id, _clip)
.map_err(|e| e.into())
});
}
}