diff options
Diffstat (limited to '')
-rw-r--r-- | include/VBox/GuestHost/SharedClipboard-transfers.h | 1027 |
1 files changed, 1027 insertions, 0 deletions
diff --git a/include/VBox/GuestHost/SharedClipboard-transfers.h b/include/VBox/GuestHost/SharedClipboard-transfers.h new file mode 100644 index 00000000..07abfcfa --- /dev/null +++ b/include/VBox/GuestHost/SharedClipboard-transfers.h @@ -0,0 +1,1027 @@ +/* $Id: SharedClipboard-transfers.h $ */ +/** @file + * Shared Clipboard - Shared transfer functions between host and guest. + */ + +/* + * Copyright (C) 2019-2020 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef VBOX_INCLUDED_GuestHost_SharedClipboard_transfers_h +#define VBOX_INCLUDED_GuestHost_SharedClipboard_transfers_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <map> + +#include <iprt/assert.h> +#include <iprt/critsect.h> +#include <iprt/fs.h> +#include <iprt/list.h> + +#include <iprt/cpp/list.h> +#include <iprt/cpp/ministring.h> + +#include <VBox/GuestHost/SharedClipboard.h> +#include <VBox/HostServices/VBoxClipboardSvc.h> + + +struct SHCLTRANSFER; +/** Pointer to a single shared clipboard transfer */ +typedef struct SHCLTRANSFER *PSHCLTRANSFER; + + +/** @name Shared Clipboard transfer definitions. + * @{ + */ + +/** + * Defines the transfer status codes. + */ +typedef enum +{ + /** No status set. */ + SHCLTRANSFERSTATUS_NONE = 0, + /** The transfer has been initialized but is not running yet. */ + SHCLTRANSFERSTATUS_INITIALIZED, + /** The transfer is active and running. */ + SHCLTRANSFERSTATUS_STARTED, + /** The transfer has been stopped. */ + SHCLTRANSFERSTATUS_STOPPED, + /** The transfer has been canceled. */ + SHCLTRANSFERSTATUS_CANCELED, + /** The transfer has been killed. */ + SHCLTRANSFERSTATUS_KILLED, + /** The transfer ran into an unrecoverable error. */ + SHCLTRANSFERSTATUS_ERROR, + /** The usual 32-bit hack. */ + SHCLTRANSFERSTATUS_32BIT_SIZE_HACK = 0x7fffffff +} SHCLTRANSFERSTATUSENUM; + +/** Defines a transfer status. */ +typedef uint32_t SHCLTRANSFERSTATUS; + +/** @} */ + +/** @name Shared Clipboard handles. + * @{ + */ + +/** A Shared Clipboard list handle. */ +typedef uint64_t SHCLLISTHANDLE; +/** Pointer to a Shared Clipboard list handle. */ +typedef SHCLLISTHANDLE *PSHCLLISTHANDLE; +/** Specifies an invalid Shared Clipboard list handle. + * @todo r=bird: The convention is NIL_SHCLLISTHANDLE. */ +#define SHCLLISTHANDLE_INVALID ((SHCLLISTHANDLE)UINT64_MAX) + +/** A Shared Clipboard object handle. */ +typedef uint64_t SHCLOBJHANDLE; +/** Pointer to a Shared Clipboard object handle. */ +typedef SHCLOBJHANDLE *PSHCLOBJHANDLE; +/** Specifies an invalid Shared Clipboard object handle. + * @todo r=bird: The convention is NIL_SHCLOBJHANDLE. */ +#define SHCLOBJHANDLE_INVALID ((SHCLOBJHANDLE)UINT64_MAX) + +/** @} */ + +/** @name Shared Clipboard open/create flags. + * @{ + */ +/** No flags. Initialization value. */ +#define SHCL_OBJ_CF_NONE UINT32_C(0x00000000) + +#if 0 /* These probably won't be needed either */ +/** Lookup only the object, do not return a handle. All other flags are ignored. */ +#define SHCL_OBJ_CF_LOOKUP UINT32_C(0x00000001) +/** Create/open a directory. */ +#define SHCL_OBJ_CF_DIRECTORY UINT32_C(0x00000004) +#endif + +/** Read/write requested access for the object. */ +#define SHCL_OBJ_CF_ACCESS_MASK_RW UINT32_C(0x00001000) +/** No access requested. */ +#define SHCL_OBJ_CF_ACCESS_NONE UINT32_C(0x00000000) +/** Read access requested. */ +#define SHCL_OBJ_CF_ACCESS_READ UINT32_C(0x00001000) + +/** Requested share access for the object. */ +#define SHCL_OBJ_CF_ACCESS_MASK_DENY UINT32_C(0x00008000) +/** Allow any access. */ +#define SHCL_OBJ_CF_ACCESS_DENYNONE UINT32_C(0x00000000) +/** Do not allow write. */ +#define SHCL_OBJ_CF_ACCESS_DENYWRITE UINT32_C(0x00008000) + +/** Requested access to attributes of the object. */ +#define SHCL_OBJ_CF_ACCESS_MASK_ATTR UINT32_C(0x00010000) +/** No access requested. */ +#define SHCL_OBJ_CF_ACCESS_ATTR_NONE UINT32_C(0x00000000) +/** Read access requested. */ +#define SHCL_OBJ_CF_ACCESS_ATTR_READ UINT32_C(0x00010000) + +/** Valid bits. */ +#define SHCL_OBJ_CF_VALID_MASK UINT32_C(0x00018000) +/** @} */ + +/** + * The available additional information in a SHCLFSOBJATTR object. + * @sa RTFSOBJATTRADD + */ +typedef enum _SHCLFSOBJATTRADD +{ + /** No additional information is available / requested. */ + SHCLFSOBJATTRADD_NOTHING = 1, + /** The additional unix attributes (SHCLFSOBJATTR::u::Unix) are + * available / requested. */ + SHCLFSOBJATTRADD_UNIX, + /** The additional extended attribute size (SHCLFSOBJATTR::u::EASize) is + * available / requested. */ + SHCLFSOBJATTRADD_EASIZE, + /** The last valid item (inclusive). + * The valid range is SHCLFSOBJATTRADD_NOTHING thru + * SHCLFSOBJATTRADD_LAST. */ + SHCLFSOBJATTRADD_LAST = SHCLFSOBJATTRADD_EASIZE, + /** The usual 32-bit hack. */ + SHCLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff +} SHCLFSOBJATTRADD; + + +/* Assert sizes of the IRPT types we're using below. */ +AssertCompileSize(RTFMODE, 4); +AssertCompileSize(RTFOFF, 8); +AssertCompileSize(RTINODE, 8); +AssertCompileSize(RTTIMESPEC, 8); +AssertCompileSize(RTDEV, 4); +AssertCompileSize(RTUID, 4); + +/** + * Shared Clipboard filesystem object attributes. + * + * @sa RTFSOBJATTR + */ +typedef struct _SHCLFSOBJATTR +{ + /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*. + * @remarks We depend on a number of RTFS_ defines to remain unchanged. + * Fortuntately, these are depending on windows, dos and unix + * standard values, so this shouldn't be much of a pain. */ + RTFMODE fMode; + + /** The additional attributes available. */ + SHCLFSOBJATTRADD enmAdditional; + + /** + * Additional attributes. + * + * Unless explicitly specified to an API, the API can provide additional + * data as it is provided by the underlying OS. + */ + union SHCLFSOBJATTRUNION + { + /** Additional Unix Attributes + * These are available when SHCLFSOBJATTRADD is set in fUnix. + */ + struct SHCLFSOBJATTRUNIX + { + /** The user owning the filesystem object (st_uid). + * This field is ~0U if not supported. */ + RTUID uid; + + /** The group the filesystem object is assigned (st_gid). + * This field is ~0U if not supported. */ + RTGID gid; + + /** Number of hard links to this filesystem object (st_nlink). + * This field is 1 if the filesystem doesn't support hardlinking or + * the information isn't available. + */ + uint32_t cHardlinks; + + /** The device number of the device which this filesystem object resides on (st_dev). + * This field is 0 if this information is not available. */ + RTDEV INodeIdDevice; + + /** The unique identifier (within the filesystem) of this filesystem object (st_ino). + * Together with INodeIdDevice, this field can be used as a OS wide unique id + * when both their values are not 0. + * This field is 0 if the information is not available. */ + RTINODE INodeId; + + /** User flags (st_flags). + * This field is 0 if this information is not available. */ + uint32_t fFlags; + + /** The current generation number (st_gen). + * This field is 0 if this information is not available. */ + uint32_t GenerationId; + + /** The device number of a character or block device type object (st_rdev). + * This field is 0 if the file isn't of a character or block device type and + * when the OS doesn't subscribe to the major+minor device idenfication scheme. */ + RTDEV Device; + } Unix; + + /** + * Extended attribute size. + */ + struct SHCLFSOBJATTREASIZE + { + /** Size of EAs. */ + RTFOFF cb; + } EASize; + + /** Padding the structure to a multiple of 8 bytes. */ + uint64_t au64Padding[5]; + } u; +} SHCLFSOBJATTR; +AssertCompileSize(SHCLFSOBJATTR, 48); +/** Pointer to a Shared Clipboard filesystem object attributes structure. */ +typedef SHCLFSOBJATTR *PSHCLFSOBJATTR; +/** Pointer to a const Shared Clipboard filesystem object attributes structure. */ +typedef const SHCLFSOBJATTR *PCSHCLFSOBJATTR; + +/** + * Shared Clipboard file system object information structure. + * + * @sa RTFSOBJINFO + */ +typedef struct _SHCLFSOBJINFO +{ + /** Logical size (st_size). + * For normal files this is the size of the file. + * For symbolic links, this is the length of the path name contained + * in the symbolic link. + * For other objects this fields needs to be specified. + */ + RTFOFF cbObject; + + /** Disk allocation size (st_blocks * DEV_BSIZE). */ + RTFOFF cbAllocated; + + /** Time of last access (st_atime). + * @remarks Here (and other places) we depend on the IPRT timespec to + * remain unchanged. */ + RTTIMESPEC AccessTime; + + /** Time of last data modification (st_mtime). */ + RTTIMESPEC ModificationTime; + + /** Time of last status change (st_ctime). + * If not available this is set to ModificationTime. + */ + RTTIMESPEC ChangeTime; + + /** Time of file birth (st_birthtime). + * If not available this is set to ChangeTime. + */ + RTTIMESPEC BirthTime; + + /** Attributes. */ + SHCLFSOBJATTR Attr; + +} SHCLFSOBJINFO; +AssertCompileSize(SHCLFSOBJINFO, 96); +/** Pointer to a Shared Clipboard filesystem object information structure. */ +typedef SHCLFSOBJINFO *PSHCLFSOBJINFO; +/** Pointer to a const Shared Clipboard filesystem object information + * structure. */ +typedef const SHCLFSOBJINFO *PCSHCLFSOBJINFO; + +/** + * Structure for keeping object open/create parameters. + */ +typedef struct _SHCLOBJOPENCREATEPARMS +{ + /** Path to object to open / create. */ + char *pszPath; + /** Size (in bytes) of path to to object. */ + uint32_t cbPath; + /** SHCL_OBJ_CF_* */ + uint32_t fCreate; + /** + * Attributes of object to open/create and + * returned actual attributes of opened/created object. + */ + SHCLFSOBJINFO ObjInfo; +} SHCLOBJOPENCREATEPARMS, *PSHCLOBJOPENCREATEPARMS; + +/** + * Structure for keeping a reply message. + */ +typedef struct _SHCLREPLY +{ + /** Message type of type VBOX_SHCL_REPLYMSGTYPE_XXX. */ + uint32_t uType; + /** IPRT result of overall operation. Note: int vs. uint32! */ + uint32_t rc; + union + { + struct + { + SHCLTRANSFERSTATUS uStatus; + } TransferStatus; + struct + { + SHCLLISTHANDLE uHandle; + } ListOpen; + struct + { + SHCLLISTHANDLE uHandle; + } ListClose; + struct + { + SHCLOBJHANDLE uHandle; + } ObjOpen; + struct + { + SHCLOBJHANDLE uHandle; + } ObjClose; + } u; + /** Pointer to optional payload. */ + void *pvPayload; + /** Payload size (in bytes). */ + uint32_t cbPayload; +} SHCLREPLY, *PSHCLREPLY; + +struct _SHCLLISTENTRY; +typedef _SHCLLISTENTRY SHCLLISTENTRY; + +/** Defines a single root list entry. Currently the same as a regular list entry. */ +typedef SHCLLISTENTRY SHCLROOTLISTENTRY; +/** Defines a pointer to a single root list entry. Currently the same as a regular list entry pointer. */ +typedef SHCLROOTLISTENTRY *PSHCLROOTLISTENTRY; + +/** + * Structure for keeping Shared Clipboard root list headers. + */ +typedef struct _SHCLROOTLISTHDR +{ + /** Roots listing flags; unused at the moment. */ + uint32_t fRoots; + /** Number of root list entries. */ + uint32_t cRoots; +} SHCLROOTLISTHDR, *PSHCLROOTLISTHDR; + +/** + * Structure for maintaining a Shared Clipboard root list. + */ +typedef struct _SHCLROOTLIST +{ + /** Root list header. */ + SHCLROOTLISTHDR Hdr; + /** Root list entries. */ + SHCLROOTLISTENTRY *paEntries; +} SHCLROOTLIST, *PSHCLROOTLIST; + +/** + * Structure for maintaining Shared Clipboard list open paramters. + */ +typedef struct _SHCLLISTOPENPARMS +{ + /** Listing flags (see VBOX_SHCL_LIST_FLAG_XXX). */ + uint32_t fList; + /** Size (in bytes) of the filter string. */ + uint32_t cbFilter; + /** Filter string. DOS wilcard-style. */ + char *pszFilter; + /** Size (in bytes) of the listing path. */ + uint32_t cbPath; + /** Listing path (absolute). If empty or NULL the listing's root path will be opened. */ + char *pszPath; +} SHCLLISTOPENPARMS, *PSHCLLISTOPENPARMS; + +/** + * Structure for keeping a Shared Clipboard list header. + */ +typedef struct _SHCLLISTHDR +{ + /** Feature flag(s). Not being used atm. */ + uint32_t fFeatures; + /** Total objects returned. */ + uint64_t cTotalObjects; + /** Total size (in bytes) returned. */ + uint64_t cbTotalSize; +} SHCLLISTHDR, *PSHCLLISTHDR; + +/** + * Structure for a Shared Clipboard list entry. + */ +typedef struct _SHCLLISTENTRY +{ + /** Entry name. */ + char *pszName; + /** Size (in bytes) of entry name. */ + uint32_t cbName; + /** Information flag(s). */ + uint32_t fInfo; + /** Size (in bytes) of the actual list entry. */ + uint32_t cbInfo; + /** Data of the actual list entry. */ + void *pvInfo; +} SHCLLISTENTRY, *PSHCLLISTENTRY; + +/** Maximum length (in UTF-8 characters) of a list entry name. */ +#define SHCLLISTENTRY_MAX_NAME RTPATH_MAX /** @todo Improve this to be more dynamic. */ + +/** + * Structure for maintaining a Shared Clipboard list. + */ +typedef struct _SHCLLIST +{ + /** List header. */ + SHCLLISTHDR Hdr; + /** List entries. */ + SHCLROOTLISTENTRY *paEntries; +} SHCLLIST, *PSHCLLIST; + +/** + * Structure for keeping a Shared Clipboard object data chunk. + */ +typedef struct _SHCLOBJDATACHUNK +{ + /** Handle of object this data chunk is related to. */ + uint64_t uHandle; + /** Pointer to actual data chunk. */ + void *pvData; + /** Size (in bytes) of data chunk. */ + uint32_t cbData; +} SHCLOBJDATACHUNK, *PSHCLOBJDATACHUNK; + +/** + * Enumeration for specifying a clipboard area object type. + */ +typedef enum _SHCLAREAOBJTYPE +{ + /** Unknown object type; do not use. */ + SHCLAREAOBJTYPE_UNKNOWN = 0, + /** Object is a directory. */ + SHCLAREAOBJTYPE_DIR, + /** Object is a file. */ + SHCLAREAOBJTYPE_FILE, + /** Object is a symbolic link. */ + SHCLAREAOBJTYPE_SYMLINK, + /** The usual 32-bit hack. */ + SHCLAREAOBJTYPE_32Bit_Hack = 0x7fffffff +} SHCLAREAOBJTYPE; + +/** Clipboard area ID. A valid area is >= 1. + * If 0 is specified, the last (most recent) area is meant. + * Set to UINT32_MAX if not initialized. */ +typedef uint32_t SHCLAREAID; + +/** Defines a non-initialized (nil) clipboard area. */ +#define NIL_SHCLAREAID UINT32_MAX + +/** SharedClipboardArea open flags. */ +typedef uint32_t SHCLAREAOPENFLAGS; + +/** No clipboard area open flags specified. */ +#define SHCLAREA_OPEN_FLAGS_NONE 0 +/** The clipboard area must not exist yet. */ +#define SHCLAREA_OPEN_FLAGS_MUST_NOT_EXIST RT_BIT(0) +/** Mask of all valid clipboard area open flags. */ +#define SHCLAREA_OPEN_FLAGS_VALID_MASK 0x1 + +/** Defines a clipboard area object state. */ +typedef uint32_t SHCLAREAOBJSTATE; + +/** No object state set. */ +#define SHCLAREAOBJSTATE_NONE 0 +/** The object is considered as being complete (e.g. serialized). */ +#define SHCLAREAOBJSTATE_COMPLETE RT_BIT(0) + +/** + * Lightweight structure to keep a clipboard area object's state. + * + * Note: We don't want to use the ClipboardURIObject class here, as this + * is too heavy for this purpose. + */ +typedef struct _SHCLAREAOBJ +{ + SHCLAREAOBJTYPE enmType; + SHCLAREAOBJSTATE fState; +} SHCLAREAOBJ, *PSHCLAREAOBJ; + +/** + * Class for maintaining a Shared Clipboard area on the host or guest. + * + * This will contain all received files & directories for a single Shared + * Clipboard operation. + * + * In case of a failed Shared Clipboard operation this class can also + * perform a gentle rollback if required. + */ +class SharedClipboardArea +{ +public: + + SharedClipboardArea(void); + SharedClipboardArea(const char *pszPath, SHCLAREAID uID = NIL_SHCLAREAID, + SHCLAREAOPENFLAGS fFlags = SHCLAREA_OPEN_FLAGS_NONE); + virtual ~SharedClipboardArea(void); + +public: + + uint32_t AddRef(void); + uint32_t Release(void); + + int Lock(void); + int Unlock(void); + + int AddObject(const char *pszPath, const SHCLAREAOBJ &Obj); + int GetObject(const char *pszPath, PSHCLAREAOBJ pObj); + + int Close(void); + bool IsOpen(void) const; + int OpenEx(const char *pszPath, SHCLAREAID uID = NIL_SHCLAREAID, + SHCLAREAOPENFLAGS fFlags = SHCLAREA_OPEN_FLAGS_NONE); + int OpenTemp(SHCLAREAID uID = NIL_SHCLAREAID, + SHCLAREAOPENFLAGS fFlags = SHCLAREA_OPEN_FLAGS_NONE); + SHCLAREAID GetID(void) const; + const char *GetDirAbs(void) const; + uint32_t GetRefCount(void); + int Reopen(void); + int Reset(bool fDeleteContent); + int Rollback(void); + +public: + + static int PathConstruct(const char *pszBase, SHCLAREAID uID, char *pszPath, size_t cbPath); + +protected: + + int initInternal(void); + int destroyInternal(void); + int closeInternal(void); + +protected: + + typedef std::map<RTCString, SHCLAREAOBJ> SharedClipboardAreaFsObjMap; + + /** Creation timestamp (in ms). */ + uint64_t m_tsCreatedMs; + /** Number of references to this instance. */ + volatile uint32_t m_cRefs; + /** Critical section for serializing access. */ + RTCRITSECT m_CritSect; + /** Open flags. */ + uint32_t m_fOpen; + /** Directory handle for root clipboard directory. */ + RTDIR m_hDir; + /** Absolute path to root clipboard directory. */ + RTCString m_strPathAbs; + /** List for holding created directories in the case of a rollback. */ + SharedClipboardAreaFsObjMap m_mapObj; + /** Associated clipboard area ID. */ + SHCLAREAID m_uID; +}; + +/** + * Structure for handling a single transfer object context. + */ +typedef struct _SHCLCLIENTTRANSFEROBJCTX +{ + SHCLTRANSFER *pTransfer; + SHCLOBJHANDLE uHandle; +} SHCLCLIENTTRANSFEROBJCTX, *PSHCLCLIENTTRANSFEROBJCTX; + +typedef struct _SHCLTRANSFEROBJSTATE +{ + /** How many bytes were processed (read / write) so far. */ + uint64_t cbProcessed; +} SHCLTRANSFEROBJSTATE, *PSHCLTRANSFEROBJSTATE; + +typedef struct _SHCLTRANSFEROBJ +{ + SHCLOBJHANDLE uHandle; + char *pszPathAbs; + SHCLFSOBJINFO objInfo; + SHCLSOURCE enmSource; + SHCLTRANSFEROBJSTATE State; +} SHCLTRANSFEROBJ, *PSHCLTRANSFEROBJ; + +/** + * Enumeration for specifying a Shared Clipboard object type. + */ +typedef enum _SHCLOBJTYPE +{ + /** Invalid object type. */ + SHCLOBJTYPE_INVALID = 0, + /** Object is a directory. */ + SHCLOBJTYPE_DIRECTORY, + /** Object is a file. */ + SHCLOBJTYPE_FILE, + /** Object is a symbolic link. */ + SHCLOBJTYPE_SYMLINK, + /** The usual 32-bit hack. */ + SHCLOBJTYPE_32BIT_SIZE_HACK = 0x7fffffff +} SHCLOBJTYPE; + +/** + * Structure for keeping transfer list handle information. + * This is using to map own (local) handles to the underlying file system. + */ +typedef struct _SHCLLISTHANDLEINFO +{ + /** The list node. */ + RTLISTNODE Node; + /** The list's handle. */ + SHCLLISTHANDLE hList; + /** Type of list handle. */ + SHCLOBJTYPE enmType; + /** Absolute local path of the list object. */ + char *pszPathLocalAbs; + union + { + /** Local data, based on enmType. */ + struct + { + union + { + RTDIR hDir; + RTFILE hFile; + }; + } Local; + } u; +} SHCLLISTHANDLEINFO, *PSHCLLISTHANDLEINFO; + +/** + * Structure for keeping transfer object handle information. + * This is using to map own (local) handles to the underlying file system. + */ +typedef struct _SHCLOBJHANDLEINFO +{ + /** The list node. */ + RTLISTNODE Node; + /** The object's handle. */ + SHCLOBJHANDLE hObj; + /** Type of object handle. */ + SHCLOBJTYPE enmType; + /** Absolute local path of the object. */ + char *pszPathLocalAbs; + union + { + /** Local data, based on enmType. */ + struct + { + union + { + RTDIR hDir; + RTFILE hFile; + }; + } Local; + } u; +} SHCLOBJHANDLEINFO, *PSHCLOBJHANDLEINFO; + +/** + * Structure for keeping a single root list entry. + */ +typedef struct _SHCLLISTROOT +{ + /** The list node. */ + RTLISTNODE Node; + /** Absolute path of entry. */ + char *pszPathAbs; +} SHCLLISTROOT, *PSHCLLISTROOT; + +/** + * Structure for maintaining an Shared Clipboard transfer state. + * Everything in here will be part of a saved state (later). + */ +typedef struct _SHCLTRANSFERSTATE +{ + /** The transfer's (local) ID. */ + SHCLTRANSFERID uID; + /** The transfer's current status. */ + SHCLTRANSFERSTATUS enmStatus; + /** The transfer's direction, seen from the perspective who created the transfer. */ + SHCLTRANSFERDIR enmDir; + /** The transfer's source, seen from the perspective who created the transfer. */ + SHCLSOURCE enmSource; +} SHCLTRANSFERSTATE, *PSHCLTRANSFERSTATE; + +/** + * Structure maintaining clipboard transfer provider context data. + * This is handed in to the provider implementation callbacks. + */ +typedef struct SHCLPROVIDERCTX +{ + /** Pointer to the related Shared Clipboard transfer. */ + PSHCLTRANSFER pTransfer; + /** User-defined data pointer. Can be NULL if not needed. */ + void *pvUser; +} SHCLPROVIDERCTX, *PSHCLPROVIDERCTX; + +/** + * Shared Clipboard transfer provider interface table. + */ +typedef struct SHCLPROVIDERINTERFACE +{ + DECLCALLBACKMEMBER(int, pfnTransferOpen)(PSHCLPROVIDERCTX pCtx); + DECLCALLBACKMEMBER(int, pfnTransferClose)(PSHCLPROVIDERCTX pCtx); + DECLCALLBACKMEMBER(int, pfnRootsGet)(PSHCLPROVIDERCTX pCtx, PSHCLROOTLIST *ppRootList); + DECLCALLBACKMEMBER(int, pfnListOpen)(PSHCLPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); + DECLCALLBACKMEMBER(int, pfnListClose)(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList); + DECLCALLBACKMEMBER(int, pfnListHdrRead)(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); + DECLCALLBACKMEMBER(int, pfnListHdrWrite)(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); + DECLCALLBACKMEMBER(int, pfnListEntryRead)(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pEntry); + DECLCALLBACKMEMBER(int, pfnListEntryWrite)(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pEntry); + DECLCALLBACKMEMBER(int, pfnObjOpen)(PSHCLPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, PSHCLOBJHANDLE phObj); + DECLCALLBACKMEMBER(int, pfnObjClose)(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj); + DECLCALLBACKMEMBER(int, pfnObjRead)(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, void *pvData, uint32_t cbData, + uint32_t fFlags, uint32_t *pcbRead); + DECLCALLBACKMEMBER(int, pfnObjWrite)(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, void *pvData, uint32_t cbData, + uint32_t fFlags, uint32_t *pcbWritten); +} SHCLPROVIDERINTERFACE, *PSHCLPROVIDERINTERFACE; + +/** + * Structure for the Shared Clipboard provider creation context. + */ +typedef struct _SHCLPROVIDERCREATIONCTX +{ + /** Specifies what the source of the provider is. */ + SHCLSOURCE enmSource; + /** The provider interface table. */ + SHCLPROVIDERINTERFACE Interface; + /** Provider callback data. */ + void *pvUser; +} SHCLPROVIDERCREATIONCTX, *PSHCLPROVIDERCREATIONCTX; + + +/** + * Structure for storing Shared Clipboard transfer callback data. + */ +typedef struct _SHCLTRANSFERCALLBACKDATA +{ + /** Pointer to related Shared Clipboard transfer. */ + PSHCLTRANSFER pTransfer; + /** Saved user pointer. */ + void *pvUser; + /** Size (in bytes) of data at user pointer. */ + size_t cbUser; +} SHCLTRANSFERCALLBACKDATA, *PSHCLTRANSFERCALLBACKDATA; + +/** + * Function callback table for Shared Clipboard transfers. + * + * All callbacks are optional and therefore can be NULL. + */ +typedef struct SHCLTRANSFERCALLBACKS +{ + /** User pointer to data. Optional and can be NULL. */ + void *pvUser; + /** Size (in bytes) of user data pointing at. Optional and can be 0. */ + size_t cbUser; + /** Called after the transfer has been initialized. */ + DECLCALLBACKMEMBER(int, pfnTransferInitialize)(PSHCLTRANSFERCALLBACKDATA pData); + /** Called before the transfer will be started. */ + DECLCALLBACKMEMBER(int, pfnTransferStart)(PSHCLTRANSFERCALLBACKDATA pData); + /** Called when reading / writing the list header is complete. */ + DECLCALLBACKMEMBER(void, pfnListHeaderComplete)(PSHCLTRANSFERCALLBACKDATA pData); + /** Called when reading / writing a list entry is complete. */ + DECLCALLBACKMEMBER(void, pfnListEntryComplete)(PSHCLTRANSFERCALLBACKDATA pData); + /** Called when the transfer is complete. */ + DECLCALLBACKMEMBER(void, pfnTransferComplete)(PSHCLTRANSFERCALLBACKDATA pData, int rc); + /** Called when the transfer has been canceled. */ + DECLCALLBACKMEMBER(void, pfnTransferCanceled)(PSHCLTRANSFERCALLBACKDATA pData); + /** Called when transfer resulted in an unrecoverable error. */ + DECLCALLBACKMEMBER(void, pfnTransferError)(PSHCLTRANSFERCALLBACKDATA pData, int rc); +} SHCLTRANSFERCALLBACKS, *PSHCLTRANSFERCALLBACKS; + +/** + * Structure for thread-related members for a single Shared Clipboard transfer. + */ +typedef struct _SHCLTRANSFERTHREAD +{ + /** Thread handle for the reading / writing thread. + * Can be NIL_RTTHREAD if not being used. */ + RTTHREAD hThread; + /** Thread started indicator. */ + volatile bool fStarted; + /** Thread stop flag. */ + volatile bool fStop; + /** Thread cancelled flag / indicator. */ + volatile bool fCancelled; +} SHCLTRANSFERTHREAD, *PSHCLTRANSFERTHREAD; + +/** + * A single Shared Clipboard transfer. + * + ** @todo Not yet thread safe. + */ +typedef struct SHCLTRANSFER +{ + /** The node member for using this struct in a RTList. */ + RTLISTNODE Node; + /** The transfer's state (for SSM, later). */ + SHCLTRANSFERSTATE State; + /** Absolute path to root entries. */ + char *pszPathRootAbs; + /** Timeout (in ms) for waiting of events. Default is 30s. */ + RTMSINTERVAL uTimeoutMs; + /** Maximum data chunk size (in bytes) to transfer. Default is 64K. */ + uint32_t cbMaxChunkSize; + /** The transfer's own event source. */ + SHCLEVENTSOURCE Events; + /** Current number of concurrent list handles. */ + uint32_t cListHandles; + /** Maximum number of concurrent list handles. */ + uint32_t cMaxListHandles; + /** Next upcoming list handle. */ + SHCLLISTHANDLE uListHandleNext; + /** List of all list handles elated to this transfer. */ + RTLISTANCHOR lstList; + /** Number of root entries in list. */ + uint64_t cRoots; + /** List of root entries of this transfer. */ + RTLISTANCHOR lstRoots; + /** Current number of concurrent object handles. */ + uint32_t cObjHandles; + /** Maximum number of concurrent object handles. */ + uint32_t cMaxObjHandles; + /** Next upcoming object handle. */ + SHCLOBJHANDLE uObjHandleNext; + /** Map of all objects handles related to this transfer. */ + RTLISTANCHOR lstObj; + /** The transfer's own (local) area, if any (can be NULL if not needed). + * The area itself has a clipboard area ID assigned. + * On the host this area ID gets shared (maintained / locked) across all VMs via VBoxSVC. */ + SharedClipboardArea *pArea; + /** The transfer's own provider context. */ + SHCLPROVIDERCTX ProviderCtx; + /** The transfer's provider interface. */ + SHCLPROVIDERINTERFACE ProviderIface; + /** The transfer's (optional) callback table. */ + SHCLTRANSFERCALLBACKS Callbacks; + /** Opaque pointer to implementation-specific parameters. */ + void *pvUser; + /** Size (in bytes) of implementation-specific parameters. */ + size_t cbUser; + /** Contains thread-related attributes. */ + SHCLTRANSFERTHREAD Thread; + /** Critical section for serializing access. */ + RTCRITSECT CritSect; +} SHCLTRANSFER, *PSHCLTRANSFER; + +/** + * Structure for keeping an Shared Clipboard transfer status report. + */ +typedef struct _SHCLTRANSFERREPORT +{ + /** Actual status to report. */ + SHCLTRANSFERSTATUS uStatus; + /** Result code (rc) to report; might be unused / invalid, based on enmStatus. */ + int rc; + /** Reporting flags. Currently unused and must be 0. */ + uint32_t fFlags; +} SHCLTRANSFERREPORT, *PSHCLTRANSFERREPORT; + +/** + * Structure for keeping Shared Clipboard transfer context around. + */ +typedef struct _SHCLTRANSFERCTX +{ + /** Critical section for serializing access. */ + RTCRITSECT CritSect; + /** List of transfers. */ + RTLISTANCHOR List; + /** Transfer ID allocation bitmap; clear bits are free, set bits are busy. */ + uint64_t bmTransferIds[VBOX_SHCL_MAX_TRANSFERS / sizeof(uint64_t) / 8]; + /** Number of running (concurrent) transfers. */ + uint16_t cRunning; + /** Maximum Number of running (concurrent) transfers. */ + uint16_t cMaxRunning; + /** Number of total transfers (in list). */ + uint16_t cTransfers; +} SHCLTRANSFERCTX, *PSHCLTRANSFERCTX; + +int ShClTransferObjCtxInit(PSHCLCLIENTTRANSFEROBJCTX pObjCtx); +void ShClTransferObjCtxDestroy(PSHCLCLIENTTRANSFEROBJCTX pObjCtx); +bool ShClTransferObjCtxIsValid(PSHCLCLIENTTRANSFEROBJCTX pObjCtx); + +int ShClTransferObjHandleInfoInit(PSHCLOBJHANDLEINFO pInfo); +void ShClTransferObjHandleInfoDestroy(PSHCLOBJHANDLEINFO pInfo); + +int ShClTransferObjOpenParmsInit(PSHCLOBJOPENCREATEPARMS pParms); +int ShClTransferObjOpenParmsCopy(PSHCLOBJOPENCREATEPARMS pParmsDst, PSHCLOBJOPENCREATEPARMS pParmsSrc); +void ShClTransferObjOpenParmsDestroy(PSHCLOBJOPENCREATEPARMS pParms); + +int ShClTransferObjOpen(PSHCLTRANSFER pTransfer, PSHCLOBJOPENCREATEPARMS pOpenCreateParms, PSHCLOBJHANDLE phObj); +int ShClTransferObjClose(PSHCLTRANSFER pTransfer, SHCLOBJHANDLE hObj); +int ShClTransferObjRead(PSHCLTRANSFER pTransfer, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t fFlags); +int ShClTransferObjWrite(PSHCLTRANSFER pTransfer, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten, uint32_t fFlags); + +PSHCLOBJDATACHUNK ShClTransferObjDataChunkDup(PSHCLOBJDATACHUNK pDataChunk); +void ShClTransferObjDataChunkDestroy(PSHCLOBJDATACHUNK pDataChunk); +void ShClTransferObjDataChunkFree(PSHCLOBJDATACHUNK pDataChunk); + +int ShClTransferCreate(PSHCLTRANSFER *ppTransfer); +int ShClTransferDestroy(PSHCLTRANSFER pTransfer); + +int ShClTransferInit(PSHCLTRANSFER pTransfer, uint32_t uID, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource); +int ShClTransferOpen(PSHCLTRANSFER pTransfer); +int ShClTransferClose(PSHCLTRANSFER pTransfer); + +int ShClTransferListOpen(PSHCLTRANSFER pTransfer, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); +int ShClTransferListClose(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList); +int ShClTransferListGetHeader(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList, PSHCLLISTHDR pHdr); +PSHCLTRANSFEROBJ ShClTransferListGetObj(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList, uint64_t uIdx); +int ShClTransferListRead(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList, PSHCLLISTENTRY pEntry); +int ShClTransferListWrite(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList, PSHCLLISTENTRY pEntry); +bool ShClTransferListHandleIsValid(PSHCLTRANSFER pTransfer, SHCLLISTHANDLE hList); + +int ShClPathSanitizeFilename(char *pszPath, size_t cbPath); +int ShClPathSanitize(char *pszPath, size_t cbPath); + +PSHCLROOTLIST ShClTransferRootListAlloc(void); +void ShClTransferRootListFree(PSHCLROOTLIST pRootList); + +PSHCLROOTLISTHDR ShClTransferRootListHdrDup(PSHCLROOTLISTHDR pRoots); +int ShClTransferRootListHdrInit(PSHCLROOTLISTHDR pRoots); +void ShClTransferRootListHdrDestroy(PSHCLROOTLISTHDR pRoots); + +int ShClTransferRootListEntryCopy(PSHCLROOTLISTENTRY pDst, PSHCLROOTLISTENTRY pSrc); +int ShClTransferRootListEntryInit(PSHCLROOTLISTENTRY pRootListEntry); +void ShClTransferRootListEntryDestroy(PSHCLROOTLISTENTRY pRootListEntry); +PSHCLROOTLISTENTRY ShClTransferRootListEntryDup(PSHCLROOTLISTENTRY pRootListEntry); + +int ShClTransferListHandleInfoInit(PSHCLLISTHANDLEINFO pInfo); +void ShClTransferListHandleInfoDestroy(PSHCLLISTHANDLEINFO pInfo); + +int ShClTransferListHdrAlloc(PSHCLLISTHDR *ppListHdr); +void ShClTransferListHdrFree(PSHCLLISTHDR pListHdr); +PSHCLLISTHDR ShClTransferListHdrDup(PSHCLLISTHDR pListHdr); +int ShClTransferListHdrInit(PSHCLLISTHDR pListHdr); +void ShClTransferListHdrDestroy(PSHCLLISTHDR pListHdr); +void ShClTransferListHdrReset(PSHCLLISTHDR pListHdr); +bool ShClTransferListHdrIsValid(PSHCLLISTHDR pListHdr); + +int ShClTransferListOpenParmsCopy(PSHCLLISTOPENPARMS pDst, PSHCLLISTOPENPARMS pSrc); +PSHCLLISTOPENPARMS ShClTransferListOpenParmsDup(PSHCLLISTOPENPARMS pParms); +int ShClTransferListOpenParmsInit(PSHCLLISTOPENPARMS pParms); +void ShClTransferListOpenParmsDestroy(PSHCLLISTOPENPARMS pParms); + +int ShClTransferListEntryAlloc(PSHCLLISTENTRY *ppListEntry); +void ShClTransferListEntryFree(PSHCLLISTENTRY pListEntry); +int ShClTransferListEntryCopy(PSHCLLISTENTRY pDst, PSHCLLISTENTRY pSrc); +PSHCLLISTENTRY ShClTransferListEntryDup(PSHCLLISTENTRY pListEntry); +int ShClTransferListEntryInit(PSHCLLISTENTRY pListEntry); +void ShClTransferListEntryDestroy(PSHCLLISTENTRY pListEntry); +bool ShClTransferListEntryIsValid(PSHCLLISTENTRY pListEntry); + +int ShClTransferSetInterface(PSHCLTRANSFER pTransfer, PSHCLPROVIDERCREATIONCTX pCreationCtx); +int ShClTransferRootsSet(PSHCLTRANSFER pTransfer, const char *pszRoots, size_t cbRoots); +void ShClTransferReset(PSHCLTRANSFER pTransfer); +SharedClipboardArea *ShClTransferGetArea(PSHCLTRANSFER pTransfer); + +uint32_t ShClTransferRootsCount(PSHCLTRANSFER pTransfer); +int ShClTransferRootsEntry(PSHCLTRANSFER pTransfer, uint64_t uIndex, PSHCLROOTLISTENTRY pEntry); +int ShClTransferRootsGet(PSHCLTRANSFER pTransfer, PSHCLROOTLIST *ppRootList); + +SHCLTRANSFERID ShClTransferGetID(PSHCLTRANSFER pTransfer); +SHCLTRANSFERDIR ShClTransferGetDir(PSHCLTRANSFER pTransfer); +SHCLSOURCE ShClTransferGetSource(PSHCLTRANSFER pTransfer); +SHCLTRANSFERSTATUS ShClTransferGetStatus(PSHCLTRANSFER pTransfer); +int ShClTransferRun(PSHCLTRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser); +int ShClTransferStart(PSHCLTRANSFER pTransfer); +void ShClTransferSetCallbacks(PSHCLTRANSFER pTransfer, PSHCLTRANSFERCALLBACKS pCallbacks); + +int ShClTransferCtxInit(PSHCLTRANSFERCTX pTransferCtx); +void ShClTransferCtxDestroy(PSHCLTRANSFERCTX pTransferCtx); +void ShClTransferCtxReset(PSHCLTRANSFERCTX pTransferCtx); +PSHCLTRANSFER ShClTransferCtxGetTransfer(PSHCLTRANSFERCTX pTransferCtx, uint32_t uIdx); +uint32_t ShClTransferCtxGetRunningTransfers(PSHCLTRANSFERCTX pTransferCtx); +uint32_t ShClTransferCtxGetTotalTransfers(PSHCLTRANSFERCTX pTransferCtx); +void ShClTransferCtxCleanup(PSHCLTRANSFERCTX pTransferCtx); +bool ShClTransferCtxTransfersMaximumReached(PSHCLTRANSFERCTX pTransferCtx); +int ShClTransferCtxTransferRegister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, uint32_t *pidTransfer); +int ShClTransferCtxTransferRegisterByIndex(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, uint32_t idTransfer); +int ShClTransferCtxTransferUnregister(PSHCLTRANSFERCTX pTransferCtx, uint32_t idTransfer); + +void ShClFsObjFromIPRT(PSHCLFSOBJINFO pDst, PCRTFSOBJINFO pSrc); + +bool ShClMIMEHasFileURLs(const char *pcszFormat, size_t cchFormatMax); +bool ShClMIMENeedsCache(const char *pcszFormat, size_t cchFormatMax); + +const char *ShClTransferStatusToStr(SHCLTRANSFERSTATUS enmStatus); + +#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_transfers_h */ + |