VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h@ 105635

Last change on this file since 105635 was 105635, checked in by vboxsync, 4 months ago

Shared Clipboard: Cleanup: Made a lot more functions static where possible and renamed the non-static ones to indicate its usage.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-internal.h 105635 2024-08-09 09:38:27Z vboxsync $ */
2/** @file
3 * Shared Clipboard Service - Internal header.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VBOX_INCLUDED_SRC_SharedClipboard_VBoxSharedClipboardSvc_internal_h
29#define VBOX_INCLUDED_SRC_SharedClipboard_VBoxSharedClipboardSvc_internal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <algorithm>
35#include <list>
36#include <map>
37
38#include <iprt/cpp/list.h> /* For RTCList. */
39#include <iprt/list.h>
40#include <iprt/semaphore.h>
41
42#include <VBox/hgcmsvc.h>
43#include <VBox/log.h>
44
45#include <VBox/HostServices/Service.h>
46#include <VBox/GuestHost/SharedClipboard.h>
47#include <VBox/GuestHost/SharedClipboard-transfers.h>
48
49using namespace HGCM;
50
51#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
52struct SHCLCLIENTSTATE;
53#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
54
55/**
56 * A queued message for the guest.
57 */
58typedef struct _SHCLCLIENTMSG
59{
60 /** The queue list entry. */
61 RTLISTNODE ListEntry;
62 /** Stored message ID (VBOX_SHCL_HOST_MSG_XXX). */
63 uint32_t idMsg;
64 /** Context ID. */
65 uint64_t idCtx;
66 /** Number of stored parameters in aParms. */
67 uint32_t cParms;
68 /** HGCM parameters. */
69 RT_FLEXIBLE_ARRAY_EXTENSION
70 VBOXHGCMSVCPARM aParms[RT_FLEXIBLE_ARRAY];
71} SHCLCLIENTMSG;
72/** Pointer to a queue message for the guest. */
73typedef SHCLCLIENTMSG *PSHCLCLIENTMSG;
74
75#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
76typedef struct SHCLCLIENTTRANSFERSTATE
77{
78 /** Directory of the transfer to start. */
79 SHCLTRANSFERDIR enmTransferDir;
80} SHCLCLIENTTRANSFERSTATE, *PSHCLCLIENTTRANSFERSTATE;
81#endif
82
83/**
84 * Structure for holding a single POD (plain old data) transfer.
85 *
86 * This mostly is plain text, but also can be stuff like bitmap (BMP) or other binary data.
87 */
88typedef struct SHCLCLIENTPODSTATE
89{
90 /** POD transfer direction. */
91 SHCLTRANSFERDIR enmDir;
92 /** Format of the data to be read / written. */
93 SHCLFORMAT uFormat;
94 /** How much data (in bytes) to read/write for the current operation. */
95 uint64_t cbToReadWriteTotal;
96 /** How much data (in bytes) already has been read/written for the current operation. */
97 uint64_t cbReadWritten;
98 /** Timestamp (in ms) of Last read/write operation. */
99 uint64_t tsLastReadWrittenMs;
100} SHCLCLIENTPODSTATE, *PSHCLCLIENTPODSTATE;
101
102/** @name SHCLCLIENTSTATE_FLAGS_XXX
103 * @note Part of saved state!
104 * @{ */
105/** No Shared Clipboard client flags defined. */
106#define SHCLCLIENTSTATE_FLAGS_NONE 0
107/** Client has a guest read operation active. Currently unused. */
108#define SHCLCLIENTSTATE_FLAGS_READ_ACTIVE RT_BIT(0)
109/** Client has a guest write operation active. Currently unused. */
110#define SHCLCLIENTSTATE_FLAGS_WRITE_ACTIVE RT_BIT(1)
111/** @} */
112
113/**
114 * Structure needed to support backwards compatbility for old(er) Guest Additions (< 6.1),
115 * which did not know the context ID concept then.
116 */
117typedef struct SHCLCLIENTLEGACYCID
118{
119 /** List node. */
120 RTLISTNODE Node;
121 /** The actual context ID. */
122 uint64_t uCID;
123 /** Not used yet; useful to have it in the saved state though. */
124 uint32_t enmType;
125 /** @todo Add an union here as soon as we utilize \a enmType. */
126 SHCLFORMAT uFormat;
127} SHCLCLIENTLEGACYCID;
128/** Pointer to a SHCLCLIENTLEGACYCID struct. */
129typedef SHCLCLIENTLEGACYCID *PSHCLCLIENTLEGACYCID;
130
131/**
132 * Structure for keeping legacy state, required for keeping backwards compatibility
133 * to old(er) Guest Additions.
134 */
135typedef struct SHCLCLIENTLEGACYSTATE
136{
137 /** List of context IDs (of type SHCLCLIENTLEGACYCID) for older Guest Additions which (< 6.1)
138 * which did not know the concept of context IDs. */
139 RTLISTANCHOR lstCID;
140 /** Number of context IDs currently in \a lstCID. */
141 uint16_t cCID;
142} SHCLCLIENTLEGACYSTATE;
143
144/**
145 * Structure for keeping generic client state data within the Shared Clipboard host service.
146 * This structure needs to be serializable by SSM (must be a POD type).
147 */
148typedef struct SHCLCLIENTSTATE
149{
150 struct SHCLCLIENTSTATE *pNext;
151 struct SHCLCLIENTSTATE *pPrev;
152
153 /** Backend-dependent opaque context structure.
154 * This contains data only known to a certain backend implementation.
155 * Optional and can be NULL. */
156 SHCLCONTEXT *pCtx;
157 /** The client's HGCM ID. Not related to the session ID below! */
158 uint32_t uClientID;
159 /** The client's session ID. */
160 SHCLSESSIONID uSessionID;
161 /** Guest feature flags, VBOX_SHCL_GF_0_XXX. */
162 uint64_t fGuestFeatures0;
163 /** Guest feature flags, VBOX_SHCL_GF_1_XXX. */
164 uint64_t fGuestFeatures1;
165 /** Chunk size to use for data transfers. */
166 uint32_t cbChunkSize;
167 /** Where the transfer sources its data from. */
168 SHCLSOURCE enmSource;
169 /** Client state flags of type SHCLCLIENTSTATE_FLAGS_. */
170 uint32_t fFlags;
171 /** POD (plain old data) state. */
172 SHCLCLIENTPODSTATE POD;
173#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
174 /** The client's transfers state. */
175 SHCLCLIENTTRANSFERSTATE Transfers;
176#endif
177} SHCLCLIENTSTATE, *PSHCLCLIENTSTATE;
178
179typedef struct _SHCLCLIENTCMDCTX
180{
181 uint64_t uContextID;
182} SHCLCLIENTCMDCTX, *PSHCLCLIENTCMDCTX;
183
184#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
185/**
186 * Structure for keeping transfer-related data per HGCM client.
187 */
188typedef struct _SHCLIENTTRANSFERS
189{
190 /** Transfer context. */
191 SHCLTRANSFERCTX Ctx;
192 /** Backends-specific transfers callbacks to use. */
193 SHCLTRANSFERCALLBACKS Callbacks;
194 /** Backends-specific transfers provider to use. */
195 SHCLTXPROVIDER Provider;
196} SHCLIENTTRANSFERS, *PSHCLIENTTRANSFERS;
197#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
198
199/** Prototypes for the Shared Clipboard backend. */
200struct SHCLBACKEND;
201typedef SHCLBACKEND *PSHCLBACKEND;
202
203/**
204 * Structure for keeping data per (connected) HGCM client.
205 */
206typedef struct _SHCLCLIENT
207{
208 /** Pointer to associated backend, if any.
209 * Might be NULL if not being used. */
210 PSHCLBACKEND pBackend;
211 /** General client state data. */
212 SHCLCLIENTSTATE State;
213 /** The critical section protecting the queue, event source and whatnot. */
214 RTCRITSECT CritSect;
215 /** The client's message queue (SHCLCLIENTMSG). */
216 RTLISTANCHOR MsgQueue;
217 /** Number of allocated messages (updated atomically, not under critsect). */
218 uint32_t volatile cMsgAllocated;
219 /** Legacy cruft we have to keep to support old(er) Guest Additions. */
220 SHCLCLIENTLEGACYSTATE Legacy;
221 /** The client's own event source.
222 * Needed for events which are not bound to a specific transfer. */
223 SHCLEVENTSOURCE EventSrc;
224#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
225 SHCLIENTTRANSFERS Transfers;
226#endif
227 /** Structure for keeping the client's pending (deferred return) state.
228 * A client is in a deferred state when it asks for the next HGCM message,
229 * but the service can't provide it yet. That way a client will block (on the guest side, does not return)
230 * until the service can complete the call. */
231 struct
232 {
233 /** The client's HGCM call handle. Needed for completing a deferred call. */
234 VBOXHGCMCALLHANDLE hHandle;
235 /** Message type (function number) to use when completing the deferred call.
236 * A non-0 value means the client is in pending mode. */
237 uint32_t uType;
238 /** Parameter count to use when completing the deferred call. */
239 uint32_t cParms;
240 /** Parameters to use when completing the deferred call. */
241 PVBOXHGCMSVCPARM paParms;
242 } Pending;
243} SHCLCLIENT, *PSHCLCLIENT;
244
245/**
246 * Structure for keeping a single event source map entry.
247 * Currently empty.
248 */
249typedef struct _SHCLEVENTSOURCEMAPENTRY
250{
251} SHCLEVENTSOURCEMAPENTRY;
252
253/** Map holding information about connected HGCM clients. Key is the (unique) HGCM client ID.
254 * The value is a weak pointer to PSHCLCLIENT, which is owned by HGCM. */
255typedef std::map<uint32_t, PSHCLCLIENT> ClipboardClientMap;
256
257/** Map holding information about event sources. Key is the (unique) event source ID. */
258typedef std::map<SHCLEVENTSOURCEID, SHCLEVENTSOURCEMAPENTRY> ClipboardEventSourceMap;
259
260/** Simple queue (list) which holds deferred (waiting) clients. */
261typedef std::list<uint32_t> ClipboardClientQueue;
262
263/**
264 * Structure for keeping the Shared Clipboard service extension state.
265 *
266 * A service extension is optional, and can be installed by a host component
267 * to communicate with the Shared Clipboard host service.
268 */
269typedef struct _SHCLEXTSTATE
270{
271 /** Pointer to the actual service extension handle.
272 *
273 * Must return VERR_NOT_SUPPORTED if the extension didn't handle the requested function.
274 * This will invoke the regular backend then.
275 */
276 PFNHGCMSVCEXT pfnExtension;
277 /** Opaque pointer to extension-provided data. Don't touch. */
278 void *pvExtension;
279 /** The HGCM client ID currently assigned to this service extension.
280 * At the moment only one HGCM client can be assigned per extension. */
281 uint32_t uClientID;
282 /** Whether the host service is reading clipboard data currently. */
283 bool fReadingData;
284 /** Whether the service extension has sent the clipboard formats while
285 * the the host service is reading clipboard data from it. */
286 bool fDelayedAnnouncement;
287 /** The actual clipboard formats announced while the host service
288 * is reading clipboard data from the extension. */
289 uint32_t fDelayedFormats;
290} SHCLEXTSTATE, *PSHCLEXTSTATE;
291
292extern SHCLEXTSTATE g_ExtState;
293
294/** @name Service client functions.
295 * @{
296 */
297PSHCLCLIENTMSG ShClSvcClientMsgAlloc(PSHCLCLIENT pClient, uint32_t uMsg, uint32_t cParms);
298void ShClSvcClientMsgFree(PSHCLCLIENT pClient, PSHCLCLIENTMSG pMsg);
299void ShClSvcClientMsgAdd(PSHCLCLIENT pClient, PSHCLCLIENTMSG pMsg, bool fAppend);
300
301int ShClSvcClientInit(PSHCLCLIENT pClient, uint32_t uClientID); /* For testcases. */
302
303void ShClSvcClientLock(PSHCLCLIENT pClient);
304void ShClSvcClientUnlock(PSHCLCLIENT pClient);
305
306int ShClSvcClientWakeup(PSHCLCLIENT pClient);
307/** @} */
308
309/** @name Service functions, accessible by the backends.
310 * Locking is between the (host) service thread and the platform-dependent (window) thread.
311 * @{
312 */
313int ShClSvcReadDataFromGuestAsync(PSHCLCLIENT pClient, SHCLFORMATS fFormats, PSHCLEVENT *ppEvent);
314int ShClSvcReadDataFromGuest(PSHCLCLIENT pClient, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb);
315int ShClSvcGuestDataSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
316int ShClSvcReportFormats(PSHCLCLIENT pClient, SHCLFORMATS fFormats);
317PSHCLBACKEND ShClSvcGetBackend(void);
318uint32_t ShClSvcGetMode(void);
319bool ShClSvcGetHeadless(void);
320bool ShClSvcLock(void);
321void ShClSvcUnlock(void);
322/** @} */
323
324/** @name Platform-dependent implementations for the Shared Clipboard host service ("backends"),
325 * called *only* by the host service.
326 * @{
327 */
328/**
329 * Structure for keeping Shared Clipboard backend instance data.
330 */
331typedef struct SHCLBACKEND
332{
333 /** Callback table to use.
334 * Some callbacks might be optional and therefore NULL -- see the table for more details. */
335 SHCLCALLBACKS Callbacks;
336} SHCLBACKEND;
337/** Pointer to a Shared Clipboard backend. */
338typedef SHCLBACKEND *PSHCLBACKEND;
339
340/**
341 * Called on initialization.
342 *
343 * @param pBackend Shared Clipboard backend to initialize.
344 * @param pTable The HGCM service call and parameter table. Mainly for
345 * adjusting the limits.
346 */
347int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable);
348
349/**
350 * Called on destruction.
351 *
352 * @param pBackend Shared Clipboard backend to destroy.
353 */
354void ShClBackendDestroy(PSHCLBACKEND pBackend);
355
356/**
357 * Called when a new HGCM client connects.
358 *
359 * @param pBackend Shared Clipboard backend to set callbacks for.
360 * @param pCallbacks Backend callbacks to use.
361 * When NULL is specified, the backend's default callbacks are being used.
362 */
363void ShClBackendSetCallbacks(PSHCLBACKEND pBackend, PSHCLCALLBACKS pCallbacks);
364
365/**
366 * Called when a new HGCM client connects.
367 *
368 * @returns VBox status code.
369 * @param pBackend Shared Clipboard backend to connect to.
370 * @param pClient Shared Clipboard client context.
371 * @param fHeadless Whether this is a headless connection or not.
372 */
373int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless);
374
375/**
376 * Called when a HGCM client disconnects.
377 *
378 * @returns VBox status code.
379 * @param pBackend Shared Clipboard backend to disconnect from.
380 * @param pClient Shared Clipboard client context.
381 */
382int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient);
383
384/**
385 * Called when the guest reports available clipboard formats to the host OS.
386 *
387 * @returns VBox status code.
388 * @param pBackend Shared Clipboard backend to announce formats to.
389 * @param pClient Shared Clipboard client context.
390 * @param fFormats The announced formats from the guest,
391 * VBOX_SHCL_FMT_XXX.
392 */
393int ShClBackendReportFormats(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats);
394
395/**
396 * Called when the guest wants to read host clipboard data.
397 *
398 * @returns VBox status code.
399 * @param pBackend Shared Clipboard backend to read data from.
400 * @param pClient Shared Clipboard client context.
401 * @param pCmdCtx Shared Clipboard command context.
402 * @param uFormat Clipboard format to read.
403 * @param pvData Where to return the read clipboard data.
404 * @param cbData Size (in bytes) of buffer where to return the clipboard data.
405 * @param pcbActual Where to return the amount of bytes read.
406 *
407 * @todo Document: Can return VINF_HGCM_ASYNC_EXECUTE to defer returning read
408 * data
409 */
410int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat,
411 void *pvData, uint32_t cbData, uint32_t *pcbActual);
412
413/**
414 * Called when the guest writes clipboard data to the host.
415 *
416 * @returns VBox status code.
417 * @param pBackend Shared Clipboard backend to write data to.
418 * @param pClient Shared Clipboard client context.
419 * @param pCmdCtx Shared Clipboard command context.
420 * @param uFormat Clipboard format to write.
421 * @param pvData Clipboard data to write.
422 * @param cbData Size (in bytes) of buffer clipboard data to write.
423 */
424int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
425
426/**
427 * Called when synchronization of the clipboard contents of the host clipboard with the guest is needed.
428 *
429 * @returns VBox status code.
430 * @param pBackend Shared Clipboard backend to synchronize.
431 * @param pClient Shared Clipboard client context.
432 */
433int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient);
434/** @} */
435
436#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
437/** @name Host implementations for Shared Clipboard transfers.
438 * @{
439 */
440/**
441 * Called before a transfer gets destroyed.
442 *
443 * @returns VBox status code.
444 * @param pBackend Shared Clipboard backend to use.
445 * @param pClient Shared Clipboard client context.
446 * @param pTransfer Shared Clipboard transfer to destroy.
447 */
448int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
449/**
450 * Called after a transfer status got processed.
451 *
452 * @returns VBox status code.
453 * @param pBackend Shared Clipboard backend to use.
454 * @param pClient Shared Clipboard client context.
455 * @param pTransfer Shared Clipboard transfer to process status for.
456 * @param enmSource Transfer source which issues the reply.
457 * @param enmStatus Transfer status.
458 * @param rcStatus Status code (IPRT-style). Depends on \a enmStatus set.
459 */
460int ShClBackendTransferHandleStatusReply(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLSOURCE enmSource, SHCLTRANSFERSTATUS enmStatus, int rcStatus);
461/** @} */
462#endif
463
464#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
465/** @name Internal Shared Clipboard transfer host service functions.
466 * @{
467 */
468int ShClSvcTransferMsgClientHandler(PSHCLCLIENT pClient, VBOXHGCMCALLHANDLE callHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival);
469int ShClSvcTransferMsgHostHandler(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
470/** @} */
471
472/** @name Shared Clipboard transfer interface implementations for guest -> host transfers.
473 * @{
474 */
475DECLCALLBACK(int) ShClSvcTransferIfaceGHRootListRead(PSHCLTXPROVIDERCTX pCtx);
476DECLCALLBACK(int) ShClSvcTransferIfaceGHListOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList);
477DECLCALLBACK(int) ShClSvcTransferIfaceGHListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList);
478DECLCALLBACK(int) ShClSvcTransferIfaceGHListHdrRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);
479DECLCALLBACK(int) ShClSvcTransferIfaceGHListEntryRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);
480DECLCALLBACK(int) ShClSvcTransferIfaceGHObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, PSHCLOBJHANDLE phObj);
481DECLCALLBACK(int) ShClSvcTransferIfaceGHObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj);
482DECLCALLBACK(int) ShClSvcTransferIfaceGHObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead);
483/** @} */
484#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
485
486/* Host unit testing interface */
487#ifdef UNIT_TEST
488uint32_t TestClipSvcGetMode(void);
489#endif
490
491#endif /* !VBOX_INCLUDED_SRC_SharedClipboard_VBoxSharedClipboardSvc_internal_h */
492
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette