From 88fd0da19e0188f98fd23e5b0119183cd4217ab2 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 14 Aug 2026 13:42:25 +1000 Subject: [PATCH] [idd] clipboard: route file dataset records --- idd/LGCommon/CClipboardChannel.cpp | 17 ++++++++-- idd/LGCommon/CClipboardRing.cpp | 3 +- idd/LGCommon/ClipboardRing.h | 2 +- idd/LGIdd/transport/CClipboardHub.cpp | 45 ++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/idd/LGCommon/CClipboardChannel.cpp b/idd/LGCommon/CClipboardChannel.cpp index f4e457d7..a5402f02 100644 --- a/idd/LGCommon/CClipboardChannel.cpp +++ b/idd/LGCommon/CClipboardChannel.cpp @@ -91,14 +91,16 @@ namespace case KVMFR_CLIPBOARD_MESSAGE_REQUEST: return record.clipboardGeneration && record.transfer && - kvmfrClipboardFormatValid(record.format) && !record.offset && + kvmfrClipboardRepresentationFormatValid(record.format) && + !record.offset && !record.size && !record.flags && !record.token && !record.length && !record.sequence; case KVMFR_CLIPBOARD_MESSAGE_DATA: { if (!record.clipboardGeneration || !record.transfer || - !kvmfrClipboardFormatValid(record.format) || record.token || + !kvmfrClipboardRepresentationFormatValid(record.format) || + record.token || (record.flags & ~(KVMFR_CLIPBOARD_FLAG_BEGIN | KVMFR_CLIPBOARD_FLAG_END)) || (!record.length && !(record.flags & KVMFR_CLIPBOARD_FLAG_END)) || @@ -115,9 +117,18 @@ namespace case KVMFR_CLIPBOARD_MESSAGE_CANCEL: return record.transfer && !record.offset && !record.size && - (!record.format || kvmfrClipboardFormatValid(record.format)) && + (!record.format || + kvmfrClipboardRepresentationFormatValid(record.format)) && !record.flags && !record.length && !record.sequence; + case KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE: + case KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED: + case KVMFR_CLIPBOARD_MESSAGE_FILE_RELEASE: + case KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST: + case KVMFR_CLIPBOARD_MESSAGE_FILE_DATA: + case KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL: + return kvmfrClipboardFileMessageValid(&record); + default: return false; } diff --git a/idd/LGCommon/CClipboardRing.cpp b/idd/LGCommon/CClipboardRing.cpp index a096ef13..b31ea888 100644 --- a/idd/LGCommon/CClipboardRing.cpp +++ b/idd/LGCommon/CClipboardRing.cpp @@ -113,8 +113,9 @@ bool CClipboardRing::Valid(const ClipboardRingSlot& slot) { return slot.header.version == KVMFR_CLIPBOARD_VERSION && slot.header.type >= KVMFR_CLIPBOARD_MESSAGE_CLAIM && - slot.header.type <= KVMFR_CLIPBOARD_MESSAGE_GRANT && + slot.header.type <= KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL && slot.header.length <= KVMFR_CLIPBOARD_DATA_BYTES && (slot.header.type == KVMFR_CLIPBOARD_MESSAGE_DATA || + slot.header.type == KVMFR_CLIPBOARD_MESSAGE_FILE_DATA || !slot.header.length); } diff --git a/idd/LGCommon/ClipboardRing.h b/idd/LGCommon/ClipboardRing.h index 7f028a90..634a5ef0 100644 --- a/idd/LGCommon/ClipboardRing.h +++ b/idd/LGCommon/ClipboardRing.h @@ -26,7 +26,7 @@ #include static constexpr uint32_t LG_CLIPBOARD_MAPPING_MAGIC = 0x4c474342U; -static constexpr uint32_t LG_CLIPBOARD_MAPPING_VERSION = 1U; +static constexpr uint32_t LG_CLIPBOARD_MAPPING_VERSION = 2U; struct ClipboardRingSlot { diff --git a/idd/LGIdd/transport/CClipboardHub.cpp b/idd/LGIdd/transport/CClipboardHub.cpp index 6649a7fc..951df152 100644 --- a/idd/LGIdd/transport/CClipboardHub.cpp +++ b/idd/LGIdd/transport/CClipboardHub.cpp @@ -30,6 +30,29 @@ namespace return kvmfrClipboardTransferFromHelper(record.transfer); if (record.type == KVMFR_CLIPBOARD_MESSAGE_DATA) return kvmfrClipboardTransferFromClient(record.transfer); + if (record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_RELEASE || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST) + return kvmfrClipboardTransferFromHelper(record.transfer); + if (record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_DATA) + return kvmfrClipboardTransferFromClient(record.transfer); + return true; + } + + bool ValidClientDirection(const KVMFRClipboardMessage& record) + { + if (record.type == KVMFR_CLIPBOARD_MESSAGE_REQUEST) + return kvmfrClipboardTransferFromClient(record.transfer); + if (record.type == KVMFR_CLIPBOARD_MESSAGE_DATA) + return kvmfrClipboardTransferFromHelper(record.transfer); + if (record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_RELEASE || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST) + return kvmfrClipboardTransferFromClient(record.transfer); + if (record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_DATA) + return kvmfrClipboardTransferFromHelper(record.transfer); return true; } } @@ -87,6 +110,25 @@ ClipboardChannelResult CClipboardHub::HoldOrDiscard( return result; } + if (record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE || + record.type == KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST) + { + KVMFRClipboardMessage reject = {}; + reject.version = KVMFR_CLIPBOARD_VERSION; + reject.type = record.type == + KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE ? + KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED : + KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL; + reject.generation = record.generation; + reject.clipboardGeneration = record.clipboardGeneration; + reject.transfer = record.transfer; + reject.format = KVMFR_CLIPBOARD_FORMAT_FILES; + reject.token = KVMFR_CLIPBOARD_FILE_ERROR_DISCONNECTED; + const ClipboardChannelResult result = m_channel.Send(reject); + if (result != ClipboardChannelResult::ACCEPTED) + return result; + } + return ClipboardChannelResult::ACCEPTED; } @@ -344,7 +386,8 @@ ClipboardChannelResult CClipboardHub::SendClipboard( // Keep the shared lock through Send so Unbind cannot advance the binding // generation after validation but before the record enters the channel. CSRWSharedLock lock(m_lock); - if (m_stopped || !m_available || !m_active || !m_running || m_failed || + if (!ValidClientDirection(record) || + m_stopped || !m_available || !m_active || !m_running || m_failed || !m_source || record.generation != m_generation) return ClipboardChannelResult::FAILED; return m_channel.Send(record, data);