diff options
Diffstat (limited to 'include/VBox/GuestHost')
-rw-r--r-- | include/VBox/GuestHost/DragAndDrop.h | 332 | ||||
-rw-r--r-- | include/VBox/GuestHost/DragAndDropDefs.h | 83 | ||||
-rw-r--r-- | include/VBox/GuestHost/GuestControl.h | 219 | ||||
-rw-r--r-- | include/VBox/GuestHost/Makefile.kup | 0 | ||||
-rw-r--r-- | include/VBox/GuestHost/SharedClipboard-transfers.h | 1027 | ||||
-rw-r--r-- | include/VBox/GuestHost/SharedClipboard-win.h | 403 | ||||
-rw-r--r-- | include/VBox/GuestHost/SharedClipboard-x11.h | 156 | ||||
-rw-r--r-- | include/VBox/GuestHost/SharedClipboard.h | 217 | ||||
-rw-r--r-- | include/VBox/GuestHost/clipboard-helper.h | 281 |
9 files changed, 2718 insertions, 0 deletions
diff --git a/include/VBox/GuestHost/DragAndDrop.h b/include/VBox/GuestHost/DragAndDrop.h new file mode 100644 index 00000000..e986b9ad --- /dev/null +++ b/include/VBox/GuestHost/DragAndDrop.h @@ -0,0 +1,332 @@ +/* $Id: DragAndDrop.h $ */ +/** @file + * DnD - Shared functions between host and guest. + */ + +/* + * Copyright (C) 2014-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_DragAndDrop_h +#define VBOX_INCLUDED_GuestHost_DragAndDrop_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/assert.h> +#include <iprt/fs.h> +#include <iprt/list.h> + +/** DnDURIDroppedFiles flags. */ +typedef uint32_t DNDURIDROPPEDFILEFLAGS; + +/** No flags specified. */ +#define DNDURIDROPPEDFILE_FLAGS_NONE 0 + +/** + * Structure for keeping a DnD dropped files entry. + */ +typedef struct DNDDROPPEDFILESENTRY +{ + RTLISTNODE Node; + char *pszPath; +} DNDDROPPEDFILESENTRY; +/** Pointer to a DnD dropped files entry. */ +typedef DNDDROPPEDFILESENTRY *PDNDDROPPEDFILESENTRY; + +/** + * Structure for maintaining a "dropped files" directory + * on the host or guest. This will contain all received files & directories + * for a single drag and drop operation. + * + * In case of a failed drag and drop operation this can also + * perform a gentle rollback if required. + */ +typedef struct DNDDROPPEDFILES +{ + /** Open flags. */ + uint32_t m_fOpen; + /** Directory handle for drop directory. */ + RTDIR m_hDir; + /** Absolute path to drop directory. */ + char *pszPathAbs; + /** List for holding created directories in the case of a rollback. */ + RTLISTANCHOR m_lstDirs; + /** List for holding created files in the case of a rollback. */ + RTLISTANCHOR m_lstFiles; +} DNDDROPPEDFILES; +/** Pointer to a DnD dropped files directory. */ +typedef DNDDROPPEDFILES *PDNDDROPPEDFILES; + +int DnDDroppedFilesInit(PDNDDROPPEDFILES pDF); +int DnDDroppedFilesInitEx(PDNDDROPPEDFILES pDF, const char *pszPath, DNDURIDROPPEDFILEFLAGS fFlags); +void DnDDroppedFilesDestroy(PDNDDROPPEDFILES pDF); +int DnDDroppedFilesAddFile(PDNDDROPPEDFILES pDF, const char *pszFile); +int DnDDroppedFilesAddDir(PDNDDROPPEDFILES pDF, const char *pszDir); +int DnDDroppedFilesClose(PDNDDROPPEDFILES pDF); +bool DnDDroppedFilesIsOpen(PDNDDROPPEDFILES pDF); +int DnDDroppedFilesOpenEx(PDNDDROPPEDFILES pDF, const char *pszPath, DNDURIDROPPEDFILEFLAGS fFlags); +int DnDDroppedFilesOpenTemp(PDNDDROPPEDFILES pDF, DNDURIDROPPEDFILEFLAGS fFlags); +const char *DnDDroppedFilesGetDirAbs(PDNDDROPPEDFILES pDF); +int DnDDroppedFilesReopen(PDNDDROPPEDFILES pDF); +int DnDDroppedFilesReset(PDNDDROPPEDFILES pDF, bool fDelete); +int DnDDroppedFilesRollback(PDNDDROPPEDFILES pDF); + +bool DnDMIMEHasFileURLs(const char *pcszFormat, size_t cchFormatMax); +bool DnDMIMENeedsDropDir(const char *pcszFormat, size_t cchFormatMax); + +int DnDPathValidate(const char *pcszPath, bool fMustExist); + +/** DnD path conversion flags. */ +typedef uint32_t DNDPATHCONVERTFLAGS; + +/** No flags specified. + * This will convert the path to the universal tansport style. */ +#define DNDPATHCONVERT_FLAGS_TRANSPORT 0 +/** Converts the path to a OS-dependent path. */ +#define DNDPATHCONVERT_FLAGS_TO_DOS RT_BIT(0) + +/** Mask of all valid DnD path conversion flags. */ +#define DNDPATHCONVERT_FLAGS_VALID_MASK UINT32_C(0x1) + +int DnDPathConvert(char *pszPath, size_t cbPath, DNDPATHCONVERTFLAGS fFlags); +int DnDPathSanitizeFileName(char *pszPath, size_t cbPath); +int DnDPathRebase(const char *pcszPathAbs, const char *pcszBaseOld, const char *pcszBaseNew, char **ppszPath); + +/** DnDTransferObject flags. */ +typedef uint32_t DNDTRANSFEROBJECTFLAGS; + +/** No flags specified. */ +#define DNDTRANSFEROBJECT_FLAGS_NONE 0 + +/** Mask of all valid DnD transfer object flags. */ +#define DNDTRANSFEROBJECT_FLAGS_VALID_MASK UINT32_C(0x0) + +/** + * Enumeration for specifying a transfer object type. + */ +typedef enum DNDTRANSFEROBJTYPE +{ + /** Unknown type, do not use. */ + DNDTRANSFEROBJTYPE_UNKNOWN = 0, + /** Object is a file. */ + DNDTRANSFEROBJTYPE_FILE, + /** Object is a directory. */ + DNDTRANSFEROBJTYPE_DIRECTORY, + /** The usual 32-bit hack. */ + DNDTRANSFEROBJTYPE_32BIT_HACK = 0x7fffffff +} DNDTRANSFEROBJTYPE; + +/** + * Enumeration for specifying a path style. + */ +typedef enum DNDTRANSFEROBJPATHSTYLE +{ + /** Transport style (UNIX-y), the default. */ + DNDTRANSFEROBJPATHSTYLE_TRANSPORT = 0, + /** DOS style, containing back slashes. */ + DNDTRANSFEROBJPATHSTYLE_DOS, + /** The usual 32-bit hack. */ + DNDTRANSFEROBJPATHSTYLE_32BIT_HACK = 0x7fffffff +} DNDTRANSFEROBJPATHSTYLE; + +/** + * Structure for keeping a DnD transfer object. + */ +typedef struct DNDTRANSFEROBJECT +{ + RTLISTNODE Node; + /** The object's type. */ + DNDTRANSFEROBJTYPE enmType; + /** Index (in characters, UTF-8) at which the first destination segment starts. */ + uint16_t idxDst; + /** Allocated path. Includdes the absolute source path (if any) + destination segments. + * Transport (IPRT) style. */ + char *pszPath; + + /** Union containing data depending on the object's type. */ + union + { + /** Structure containing members for objects that + * are files. */ + struct + { + /** File handle. */ + RTFILE hFile; + /** File system object information of this file. */ + RTFSOBJINFO objInfo; + /** Bytes to proces for reading/writing. */ + uint64_t cbToProcess; + /** Bytes processed reading/writing. */ + uint64_t cbProcessed; + } File; + struct + { + /** Directory handle. */ + RTDIR hDir; + /** File system object information of this directory. */ + RTFSOBJINFO objInfo; + } Dir; + } u; +} DNDTRANSFEROBJECT; +/** Pointer to a DnD transfer object. */ +typedef DNDTRANSFEROBJECT *PDNDTRANSFEROBJECT; + +int DnDTransferObjectInit(PDNDTRANSFEROBJECT pObj); +int DnDTransferObjectInitEx(PDNDTRANSFEROBJECT pObj, DNDTRANSFEROBJTYPE enmType, const char *pcszPathSrcAbs, const char *pcszPathDst); +void DnDTransferObjectDestroy(PDNDTRANSFEROBJECT pObj); +void DnDTransferObjectClose(PDNDTRANSFEROBJECT pObj); +void DnDTransferObjectReset(PDNDTRANSFEROBJECT pObj); +const char *DnDTransferObjectGetSourcePath(PDNDTRANSFEROBJECT pObj); +const char *DnDTransferObjectGetDestPath(PDNDTRANSFEROBJECT pObj); +int DnDTransferObjectGetDestPathEx(PDNDTRANSFEROBJECT pObj, DNDTRANSFEROBJPATHSTYLE enmStyle, char *pszBuf, size_t cbBuf); +RTFMODE DnDTransferObjectGetMode(PDNDTRANSFEROBJECT pObj); +uint64_t DnDTransferObjectGetProcessed(PDNDTRANSFEROBJECT pObj); +uint64_t DnDTransferObjectGetSize(PDNDTRANSFEROBJECT pObj); +DNDTRANSFEROBJTYPE DnDTransferObjectGetType(PDNDTRANSFEROBJECT pObj); +int DnDTransferObjectSetSize(PDNDTRANSFEROBJECT pObj, uint64_t cbSize); +bool DnDTransferObjectIsComplete(PDNDTRANSFEROBJECT pObj); +bool DnDTransferObjectIsOpen(PDNDTRANSFEROBJECT pObj); +int DnDTransferObjectOpen(PDNDTRANSFEROBJECT pObj, uint64_t fOpen, RTFMODE fMode, DNDTRANSFEROBJECTFLAGS fFlags); +int DnDTransferObjectQueryInfo(PDNDTRANSFEROBJECT pObj); +int DnDTransferObjectRead(PDNDTRANSFEROBJECT pObj, void *pvBuf, size_t cbBuf, uint32_t *pcbRead); +int DnDTransferObjectWrite(PDNDTRANSFEROBJECT pObj, const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten); + +/** Defines the default chunk size of DnD data transfers. + * Supported on all (older) Guest Additions which also support DnD. */ +#define DND_DEFAULT_CHUNK_SIZE _64K + +/** Separator for a formats list. */ +#define DND_FORMATS_SEPARATOR_STR "\r\n" + +/** Default URI list path separator, if not specified otherwise. + * + * This is there for hysterical raisins, to not break older Guest Additions. + ** @todo Get rid of this. */ +#define DND_PATH_SEPARATOR_STR "\r\n" + +/** DnDTransferList flags. */ +typedef uint32_t DNDTRANSFERLISTFLAGS; + +/** No flags specified. */ +#define DNDTRANSFERLIST_FLAGS_NONE 0 +/** Enables recurisve directory handling. */ +#define DNDTRANSFERLIST_FLAGS_RECURSIVE RT_BIT(0) +/** Resolve all symlinks. Currently not supported and will be ignored. */ +#define DNDTRANSFERLIST_FLAGS_RESOLVE_SYMLINKS RT_BIT(1) +/** Keep the files + directory entries open while + * being in this list. */ +#define DNDTRANSFERLIST_FLAGS_KEEP_OPEN RT_BIT(2) +/** Lazy loading: Only enumerate sub directories when needed. Not implemented yet. + ** @todo Implement lazy loading. */ +#define DNDTRANSFERLIST_FLAGS_LAZY RT_BIT(3) + +/** Mask of all valid DnD transfer list flags. */ +#define DNDTRANSFERLIST_FLAGS_VALID_MASK UINT32_C(0xF) + +/** + * Enumeration for specifying a transfer list format. + */ +typedef enum DNDTRANSFERLISTFMT +{ + /** Unknown format, do not use. */ + DNDTRANSFERLISTFMT_UNKNOWN = 0, + /** Native format. */ + DNDTRANSFERLISTFMT_NATIVE, + /** URI format. */ + DNDTRANSFERLISTFMT_URI, + /** The usual 32-bit hack. */ + DNDTRANSFERLISTFMT_32BIT_HACK = 0x7fffffff +} DNDTRANSFERLISTFMT; + +/** + * Structure for keeping a DnD transfer list root entry. + * + * A root entry always is relative to the parent list maintaining it. + */ +typedef struct DNDTRANSFERLISTROOT +{ + /** List node. */ + RTLISTNODE Node; + /** Pointer to the allocated root path. + * - Relative to the list's root path + * - Always ends with a trailing slash + * - Always stored in transport style (UNIX-y). */ + char *pszPathRoot; +} DNDTRANSFERLISTROOT; +/** Pointer to a DnD list root entry. */ +typedef DNDTRANSFERLISTROOT *PDNDTRANSFERLISTROOT; + +/** + * Struct for keeping a DnD transfer list. + * + * All entries must share a common (absolute) root path. For different root paths another transfer list is needed. + */ +typedef struct DNDTRANSFERLIST +{ + /** Absolute root path of this transfer list, in native path style. + * Always ends with a separator. */ + char *pszPathRootAbs; + /** List of all relative (to \a pszPathRootAbs) top-level file/directory entries, of type DNDTRANSFERLISTROOT. + * Note: All paths are stored internally in transport style (UNIX paths) for + * easier conversion/handling! */ + RTLISTANCHOR lstRoot; + /** Total number of all transfer root entries. */ + uint64_t cRoots; + /** List of all transfer objects added, of type DNDTRANSFEROBJECT. + * + * The order of objects being added is crucial for traversing the tree. + * In other words, sub directories must come first before its contents. */ + RTLISTANCHOR lstObj; + /** Total number of all transfer objects. */ + uint64_t cObj; + /** Total size of all transfer objects, that is, the file + * size of all objects (in bytes). + * Note: Do *not* size_t here, as we also want to support large files + * on 32-bit guests. */ + uint64_t cbObjTotal; +} DNDTRANSFERLIST; +/** Pointer to a DNDTRANSFERLIST struct. */ +typedef DNDTRANSFERLIST *PDNDTRANSFERLIST; + +int DnDTransferListInit(PDNDTRANSFERLIST pList); +int DnDTransferListInitEx(PDNDTRANSFERLIST pList, const char *pcszRootPathAbs, DNDTRANSFERLISTFMT enmFmt); +void DnDTransferListDestroy(PDNDTRANSFERLIST pList); +void DnDTransferListReset(PDNDTRANSFERLIST pList); + +int DnDTransferListAppendPath(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char *pszPath, DNDTRANSFERLISTFLAGS fFlags); +int DnDTransferListAppendPathsFromBuffer(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char *pszPaths, size_t cbPaths, const char *pcszSeparator, DNDTRANSFERLISTFLAGS fFlags); +int DnDTransferListAppendPathsFromArray(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char * const *papcszPaths, size_t cPaths, DNDTRANSFERLISTFLAGS fFlags); +int DnDTransferListAppendRootsFromBuffer(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char *pszPaths, size_t cbPaths, const char *pcszSeparator, DNDTRANSFERLISTFLAGS fFlags); +int DnDTransferListAppendRootsFromArray(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char * const *papcszPaths, size_t cPaths, DNDTRANSFERLISTFLAGS fFlags); + +int DnDTransferListGetRootsEx(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, const char *pcszPathBase, const char *pcszSeparator, char **ppszBuffer, size_t *pcbBuffer); +int DnDTransferListGetRoots(PDNDTRANSFERLIST pList, DNDTRANSFERLISTFMT enmFmt, char **ppszBuffer, size_t *pcbBuffer); +uint64_t DnDTransferListGetRootCount(PDNDTRANSFERLIST pList); +const char *DnDTransferListGetRootPathAbs(PDNDTRANSFERLIST pList); + +PDNDTRANSFEROBJECT DnDTransferListObjGetFirst(PDNDTRANSFERLIST pList); +void DnDTransferListObjRemove(PDNDTRANSFERLIST pList, PDNDTRANSFEROBJECT pObj); +void DnDTransferListObjRemoveFirst(PDNDTRANSFERLIST pList); +uint64_t DnDTransferListObjCount(PDNDTRANSFERLIST pList); +uint64_t DnDTransferListObjTotalBytes(PDNDTRANSFERLIST pList); + +#endif /* !VBOX_INCLUDED_GuestHost_DragAndDrop_h */ + diff --git a/include/VBox/GuestHost/DragAndDropDefs.h b/include/VBox/GuestHost/DragAndDropDefs.h new file mode 100644 index 00000000..c00b38c3 --- /dev/null +++ b/include/VBox/GuestHost/DragAndDropDefs.h @@ -0,0 +1,83 @@ +/** @file + * Drag and Drop definitions - Common header for host service and guest clients. + */ + +/* + * Copyright (C) 2018-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_DragAndDropDefs_h +#define VBOX_INCLUDED_GuestHost_DragAndDropDefs_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + +/* + * The mode of operations. + */ +#define VBOX_DRAG_AND_DROP_MODE_OFF 0 +#define VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST 1 +#define VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST 2 +#define VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL 3 + +#define VBOX_DND_ACTION_IGNORE UINT32_C(0) +#define VBOX_DND_ACTION_COPY RT_BIT_32(0) +#define VBOX_DND_ACTION_MOVE RT_BIT_32(1) +#define VBOX_DND_ACTION_LINK RT_BIT_32(2) + +/** A single DnD action. */ +typedef uint32_t VBOXDNDACTION; +/** A list of (OR'ed) DnD actions. */ +typedef uint32_t VBOXDNDACTIONLIST; + +#define hasDnDCopyAction(a) ((a) & VBOX_DND_ACTION_COPY) +#define hasDnDMoveAction(a) ((a) & VBOX_DND_ACTION_MOVE) +#define hasDnDLinkAction(a) ((a) & VBOX_DND_ACTION_LINK) + +#define isDnDIgnoreAction(a) ((a) == VBOX_DND_ACTION_IGNORE) +#define isDnDCopyAction(a) ((a) == VBOX_DND_ACTION_COPY) +#define isDnDMoveAction(a) ((a) == VBOX_DND_ACTION_MOVE) +#define isDnDLinkAction(a) ((a) == VBOX_DND_ACTION_LINK) + +/** @def VBOX_DND_FORMATS_DEFAULT + * Default drag'n drop formats. + * Note: If you add new entries here, make sure you test those + * with all supported guest OSes! + */ +#define VBOX_DND_FORMATS_DEFAULT \ + "text/uri-list", \ + /* Text. */ \ + "text/html", \ + "text/plain;charset=utf-8", \ + "text/plain;charset=utf-16", \ + "text/plain", \ + "text/richtext", \ + "UTF8_STRING", \ + "TEXT", \ + "STRING", \ + /* OpenOffice formats. */ \ + /* See: https://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Common_Application_Features#OpenOffice.org_Clipboard_Data_Formats */ \ + "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"", \ + "application/x-openoffice;windows_formatname=\"Bitmap\"" + +#endif /* !VBOX_INCLUDED_GuestHost_DragAndDropDefs_h */ + diff --git a/include/VBox/GuestHost/GuestControl.h b/include/VBox/GuestHost/GuestControl.h new file mode 100644 index 00000000..9ef50515 --- /dev/null +++ b/include/VBox/GuestHost/GuestControl.h @@ -0,0 +1,219 @@ +/* $Id: GuestControl.h $ */ +/** @file + * Guest Control - Common Guest and Host Code. + * + * @todo r=bird: Just merge this with GuestControlSvc.h! + */ + +/* + * Copyright (C) 2016-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_GuestControl_h +#define VBOX_INCLUDED_GuestHost_GuestControl_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> + +/* Everything defined in this file lives in this namespace. */ +namespace guestControl { + +/** + * Process status when executed in the guest. + */ +enum eProcessStatus +{ + /** Process is in an undefined state. */ + PROC_STS_UNDEFINED = 0, + /** Process has been started. */ + PROC_STS_STARTED = 1, + /** Process terminated normally. */ + PROC_STS_TEN = 2, + /** Process terminated via signal. */ + PROC_STS_TES = 3, + /** Process terminated abnormally. */ + PROC_STS_TEA = 4, + /** Process timed out and was killed. */ + PROC_STS_TOK = 5, + /** Process timed out and was not killed successfully. */ + PROC_STS_TOA = 6, + /** Service/OS is stopping, process was killed. */ + PROC_STS_DWN = 7, + /** Something went wrong (error code in flags). */ + PROC_STS_ERROR = 8 +}; + +/** @todo r=bird: Most defines in this file needs to be scoped a little + * better! For instance INPUT_FLAG_NONE is very generic. */ + +/** + * Input flags, set by the host. This is needed for + * handling flags on the guest side. + * Note: Has to match Main's ProcessInputFlag_* flags! + */ +#define INPUT_FLAG_NONE 0x0 +#define INPUT_FLAG_EOF RT_BIT(0) + +/** + * Guest session creation flags. + * Only handled internally at the moment. + */ +#define SESSIONCREATIONFLAG_NONE 0x0 + +/** @name DIRREMOVEREC_FLAG_XXX - Guest directory removement flags. + * Essentially using what IPRT's RTDIRRMREC_F_ + * defines have to offer. + * @{ + */ +/** No remove flags specified. */ +#define DIRREMOVEREC_FLAG_NONE UINT32_C(0x0) +/** Recursively deletes the directory contents. */ +#define DIRREMOVEREC_FLAG_RECURSIVE RT_BIT(0) +/** Delete the content of the directory and the directory itself. */ +#define DIRREMOVEREC_FLAG_CONTENT_AND_DIR RT_BIT(1) +/** Only delete the content of the directory, omit the directory it self. */ +#define DIRREMOVEREC_FLAG_CONTENT_ONLY RT_BIT(2) +/** Mask of valid flags. */ +#define DIRREMOVEREC_FLAG_VALID_MASK UINT32_C(0x00000007) +/** @} */ + +/** @name EXECUTEPROCESSFLAG_XXX - Guest process creation flags. + * @note Has to match Main's ProcessCreateFlag_* flags! + * @{ + */ +#define EXECUTEPROCESSFLAG_NONE UINT32_C(0x0) +#define EXECUTEPROCESSFLAG_WAIT_START RT_BIT(0) +#define EXECUTEPROCESSFLAG_IGNORE_ORPHANED RT_BIT(1) +#define EXECUTEPROCESSFLAG_HIDDEN RT_BIT(2) +#define EXECUTEPROCESSFLAG_PROFILE RT_BIT(3) +#define EXECUTEPROCESSFLAG_WAIT_STDOUT RT_BIT(4) +#define EXECUTEPROCESSFLAG_WAIT_STDERR RT_BIT(5) +#define EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS RT_BIT(6) +#define EXECUTEPROCESSFLAG_UNQUOTED_ARGS RT_BIT(7) +/** @} */ + +/** @name OUTPUT_HANDLE_ID_XXX - Pipe handle IDs used internally for referencing + * to a certain pipe buffer. + * @{ + */ +#define OUTPUT_HANDLE_ID_STDOUT_DEPRECATED 0 /**< Needed for VBox hosts < 4.1.0. */ +#define OUTPUT_HANDLE_ID_STDOUT 1 +#define OUTPUT_HANDLE_ID_STDERR 2 +/** @} */ + +/** @name PATHRENAME_FLAG_XXX - Guest path rename flags. + * Essentially using what IPRT's RTPATHRENAME_FLAGS_XXX have to offer. + * @{ + */ +/** Do not replace anything. */ +#define PATHRENAME_FLAG_NO_REPLACE UINT32_C(0) +/** This will replace attempt any target which isn't a directory. */ +#define PATHRENAME_FLAG_REPLACE RT_BIT(0) +/** Don't allow symbolic links as part of the path. */ +#define PATHRENAME_FLAG_NO_SYMLINKS RT_BIT(1) +/** Mask of valid flags. */ +#define PATHRENAME_FLAG_VALID_MASK UINT32_C(0x00000003) +/** @} */ + +/** @name Defines for default (initial) guest process buffer lengths. + * Note: These defaults were the maximum values before; so be careful when raising those in order to + * not break running with older Guest Additions. + * @{ + */ +#define GUESTPROCESS_DEFAULT_CMD_LEN _1K +#define GUESTPROCESS_DEFAULT_ARGS_LEN _1K +#define GUESTPROCESS_DEFAULT_ENV_LEN _1K +#define GUESTPROCESS_DEFAULT_USER_LEN 128 +#define GUESTPROCESS_DEFAULT_PASSWORD_LEN 128 +#define GUESTPROCESS_DEFAULT_DOMAIN_LEN 256 +/** @} */ + +/** @name Defines for maximum guest process buffer lengths. + * @{ + */ +#define GUESTPROCESS_MAX_CMD_LEN _1M +#define GUESTPROCESS_MAX_ARGS_LEN _2M +#define GUESTPROCESS_MAX_ENV_LEN _4M +#define GUESTPROCESS_MAX_USER_LEN _64K +#define GUESTPROCESS_MAX_PASSWORD_LEN _64K +#define GUESTPROCESS_MAX_DOMAIN_LEN _64K +/** @} */ + +/** @name Internal tools built into VBoxService which are used in order + * to accomplish tasks host<->guest. + * @{ + */ +#define VBOXSERVICE_TOOL_CAT "vbox_cat" +#define VBOXSERVICE_TOOL_LS "vbox_ls" +#define VBOXSERVICE_TOOL_RM "vbox_rm" +#define VBOXSERVICE_TOOL_MKDIR "vbox_mkdir" +#define VBOXSERVICE_TOOL_MKTEMP "vbox_mktemp" +#define VBOXSERVICE_TOOL_STAT "vbox_stat" +/** @} */ + +/** Special process exit codes for "vbox_cat". */ +typedef enum VBOXSERVICETOOLBOX_CAT_EXITCODE +{ + VBOXSERVICETOOLBOX_CAT_EXITCODE_ACCESS_DENIED = RTEXITCODE_END, + VBOXSERVICETOOLBOX_CAT_EXITCODE_FILE_NOT_FOUND, + VBOXSERVICETOOLBOX_CAT_EXITCODE_PATH_NOT_FOUND, + VBOXSERVICETOOLBOX_CAT_EXITCODE_SHARING_VIOLATION, + VBOXSERVICETOOLBOX_CAT_EXITCODE_IS_A_DIRECTORY, + /** The usual 32-bit type hack. */ + VBOXSERVICETOOLBOX_CAT_32BIT_HACK = 0x7fffffff +} VBOXSERVICETOOLBOX_CAT_EXITCODE; + +/** Special process exit codes for "vbox_stat". */ +typedef enum VBOXSERVICETOOLBOX_STAT_EXITCODE +{ + VBOXSERVICETOOLBOX_STAT_EXITCODE_ACCESS_DENIED = RTEXITCODE_END, + VBOXSERVICETOOLBOX_STAT_EXITCODE_FILE_NOT_FOUND, + VBOXSERVICETOOLBOX_STAT_EXITCODE_PATH_NOT_FOUND, + VBOXSERVICETOOLBOX_STAT_EXITCODE_NET_PATH_NOT_FOUND, + VBOXSERVICETOOLBOX_STAT_EXITCODE_INVALID_NAME, + /** The usual 32-bit type hack. */ + VBOXSERVICETOOLBOX_STAT_32BIT_HACK = 0x7fffffff +} VBOXSERVICETOOLBOX_STAT_EXITCODE; + +/** + * Input status, reported by the client. + */ +enum eInputStatus +{ + /** Input is in an undefined state. */ + INPUT_STS_UNDEFINED = 0, + /** Input was written (partially, see cbProcessed). */ + INPUT_STS_WRITTEN = 1, + /** Input failed with an error (see flags for rc). */ + INPUT_STS_ERROR = 20, + /** Process has abandoned / terminated input handling. */ + INPUT_STS_TERMINATED = 21, + /** Too much input data. */ + INPUT_STS_OVERFLOW = 30 +}; + + + +} /* namespace guestControl */ + +#endif /* !VBOX_INCLUDED_GuestHost_GuestControl_h */ + diff --git a/include/VBox/GuestHost/Makefile.kup b/include/VBox/GuestHost/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/include/VBox/GuestHost/Makefile.kup 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 */ + diff --git a/include/VBox/GuestHost/SharedClipboard-win.h b/include/VBox/GuestHost/SharedClipboard-win.h new file mode 100644 index 00000000..79e3f37c --- /dev/null +++ b/include/VBox/GuestHost/SharedClipboard-win.h @@ -0,0 +1,403 @@ +/** @file + * Shared Clipboard - Common Guest and Host Code, for Windows OSes. + */ + +/* + * Copyright (C) 2006-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_win_h +#define VBOX_INCLUDED_GuestHost_SharedClipboard_win_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/critsect.h> +#include <iprt/types.h> +#include <iprt/win/windows.h> + +#include <VBox/GuestHost/SharedClipboard.h> + +# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS +# include <vector> + +# include <iprt/cpp/ministring.h> /* For RTCString. */ +# include <iprt/win/shlobj.h> /* For DROPFILES and friends. */ +# include <VBox/com/string.h> /* For Utf8Str. */ +# include <oleidl.h> + +# include <VBox/GuestHost/SharedClipboard-transfers.h> + +using namespace com; +# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ + +#ifndef WM_CLIPBOARDUPDATE +# define WM_CLIPBOARDUPDATE 0x031D +#endif + +#define SHCL_WIN_WNDCLASS_NAME "VBoxSharedClipboardClass" + +/** See: https://docs.microsoft.com/en-us/windows/desktop/dataxchg/html-clipboard-format + * Do *not* change the name, as this will break compatbility with other (legacy) applications! */ +#define SHCL_WIN_REGFMT_HTML "HTML Format" + +/** Default timeout (in ms) for passing down messages down the clipboard chain. */ +#define SHCL_WIN_CBCHAIN_TIMEOUT_MS 5000 + +/** Reports clipboard formats. */ +#define SHCL_WIN_WM_REPORT_FORMATS WM_USER +/** Reads data from the clipboard and sends it to the destination. */ +#define SHCL_WIN_WM_READ_DATA WM_USER + 1 +#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS +/** Starts a transfer on the guest. + * This creates the necessary IDataObject in the matching window thread. */ +# define SHCL_WIN_WM_TRANSFER_START WM_USER + 2 +#endif + +/* Dynamically load clipboard functions from User32.dll. */ +typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND); +typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER; + +typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND); +typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER; + +/** + * Structure for keeping function pointers for the new clipboard API. + * If the new API is not available, those function pointer are NULL. + */ +typedef struct _SHCLWINAPINEW +{ + PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener; + PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener; +} SHCLWINAPINEW, *PSHCLWINAPINEW; + +/** + * Structure for keeping variables which are needed to drive the old clipboard API. + */ +typedef struct _SHCLWINAPIOLD +{ + /** Timer ID for the refresh timer. */ + UINT timerRefresh; + /** Whether "pinging" the clipboard chain currently is in progress or not. */ + bool fCBChainPingInProcess; +} SHCLWINAPIOLD, *PSHCLWINAPIOLD; + +/** + * Structure for maintaining a Shared Clipboard context on Windows platforms. + */ +typedef struct _SHCLWINCTX +{ + /** Critical section to serialize access. */ + RTCRITSECT CritSect; + /** Window handle of our (invisible) clipbaord window. */ + HWND hWnd; + /** Window handle which is next to us in the clipboard chain. */ + HWND hWndNextInChain; + /** Window handle of the clipboard owner *if* we are the owner. */ + HWND hWndClipboardOwnerUs; + /** Structure for maintaining the new clipboard API. */ + SHCLWINAPINEW newAPI; + /** Structure for maintaining the old clipboard API. */ + SHCLWINAPIOLD oldAPI; +} SHCLWINCTX, *PSHCLWINCTX; + +int SharedClipboardWinOpen(HWND hWnd); +int SharedClipboardWinClose(void); +int SharedClipboardWinClear(void); + +int SharedClipboardWinCtxInit(PSHCLWINCTX pWinCtx); +void SharedClipboardWinCtxDestroy(PSHCLWINCTX pWinCtx); + +int SharedClipboardWinCheckAndInitNewAPI(PSHCLWINAPINEW pAPI); +bool SharedClipboardWinIsNewAPI(PSHCLWINAPINEW pAPI); + +int SharedClipboardWinChainAdd(PSHCLWINCTX pCtx); +int SharedClipboardWinChainRemove(PSHCLWINCTX pCtx); +VOID CALLBACK SharedClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult); +LRESULT SharedClipboardWinChainPassToNext(PSHCLWINCTX pWinCtx, UINT msg, WPARAM wParam, LPARAM lParam); + +SHCLFORMAT SharedClipboardWinClipboardFormatToVBox(UINT uFormat); +int SharedClipboardWinGetFormats(PSHCLWINCTX pCtx, PSHCLFORMATS pfFormats); + +#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS +int SharedClipboardWinGetRoots(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer); +int SharedClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **papszList, uint32_t *pcbList); +#endif + +int SharedClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue); +bool SharedClipboardWinIsCFHTML(const char *pszSource); +int SharedClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput); +int SharedClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput); + +LRESULT SharedClipboardWinHandleWMChangeCBChain(PSHCLWINCTX pWinCtx, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +int SharedClipboardWinHandleWMDestroy(PSHCLWINCTX pWinCtx); +int SharedClipboardWinHandleWMRenderAllFormats(PSHCLWINCTX pWinCtx, HWND hWnd); +int SharedClipboardWinHandleWMTimer(PSHCLWINCTX pWinCtx); + +int SharedClipboardWinAnnounceFormats(PSHCLWINCTX pWinCtx, SHCLFORMATS fFormats); +#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS +int SharedClipboardWinTransferCreate(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer); +void SharedClipboardWinTransferDestroy(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer); +#endif + +# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS +class SharedClipboardTransferList; +# ifndef FILEGROUPDESCRIPTOR +class FILEGROUPDESCRIPTOR; +# endif + +class SharedClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability +{ +public: + + enum Status + { + /** The object is uninitialized (not ready). */ + Uninitialized = 0, + /** The object is initialized and ready to use. */ + Initialized, + /** The operation has been successfully completed. */ + Completed, + /** The operation has been canceled. */ + Canceled, + /** An (unrecoverable) error occurred. */ + Error + }; + +public: + + SharedClipboardWinDataObject(PSHCLTRANSFER pTransfer, + LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0); + virtual ~SharedClipboardWinDataObject(void); + +public: /* IUnknown methods. */ + + STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + +public: /* IDataObject methods. */ + + STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium); + STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium); + STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc); + STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut); + STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease); + STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc); + STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection); + STDMETHOD(DUnadvise)(DWORD dwConnection); + STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise); + +#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC +public: /* IDataObjectAsyncCapability methods. */ + + STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects); + STDMETHOD(GetAsyncMode)(BOOL* pfIsOpAsync); + STDMETHOD(InOperation)(BOOL* pfInAsyncOp); + STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync); + STDMETHOD(StartOperation)(IBindCtx* pbcReserved); +#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */ + +public: + + int Init(void); + void OnTransferComplete(int rc = VINF_SUCCESS); + void OnTransferCanceled(); + +public: + + static DECLCALLBACK(int) readThread(RTTHREAD ThreadSelf, void *pvUser); + + static void logFormat(CLIPFORMAT fmt); + +protected: + + static int Thread(RTTHREAD hThread, void *pvUser); + + int readDir(PSHCLTRANSFER pTransfer, const Utf8Str &strPath); + + int copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal); + int createFileGroupDescriptorFromTransfer(PSHCLTRANSFER pTransfer, + bool fUnicode, HGLOBAL *phGlobal); + + bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex); + void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL, + LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL); +protected: + + /** + * Structure for keeping a single file system object entry. + */ + struct FSOBJENTRY + { + /** Relative path of the object. */ + Utf8Str strPath; + /** Related (cached) object information. */ + SHCLFSOBJINFO objInfo; + }; + + /** Vector containing file system objects with its (cached) objection information. */ + typedef std::vector<FSOBJENTRY> FsObjEntryList; + + /** The object's current status. */ + Status m_enmStatus; + /** The object's current reference count. */ + LONG m_lRefCount; + /** How many formats have been registered. */ + ULONG m_cFormats; + LPFORMATETC m_pFormatEtc; + LPSTGMEDIUM m_pStgMedium; + /** Pointer to the associated transfer object being handled. */ + PSHCLTRANSFER m_pTransfer; + /** Current stream object being used. */ + IStream *m_pStream; + /** Current object index being handled by the data object. + * This is needed to create the next IStream object for e.g. the next upcoming file/dir/++ in the transfer. */ + ULONG m_uObjIdx; + /** List of (cached) file system objects. */ + FsObjEntryList m_lstEntries; + /** Whether the transfer thread is running. */ + bool m_fRunning; + /** Event being triggered when reading the transfer list been completed. */ + RTSEMEVENT m_EventListComplete; + /** Event being triggered when the transfer has been completed. */ + RTSEMEVENT m_EventTransferComplete; + /** Registered format for CFSTR_FILEDESCRIPTORA. */ + UINT m_cfFileDescriptorA; + /** Registered format for CFSTR_FILEDESCRIPTORW. */ + UINT m_cfFileDescriptorW; + /** Registered format for CFSTR_FILECONTENTS. */ + UINT m_cfFileContents; + /** Registered format for CFSTR_PERFORMEDDROPEFFECT. */ + UINT m_cfPerformedDropEffect; +}; + +class SharedClipboardWinEnumFormatEtc : public IEnumFORMATETC +{ +public: + + SharedClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats); + virtual ~SharedClipboardWinEnumFormatEtc(void); + +public: /* IUnknown methods. */ + + STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + +public: /* IEnumFORMATETC methods. */ + + STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched); + STDMETHOD(Skip)(ULONG cFormats); + STDMETHOD(Reset)(void); + STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc); + +public: + + static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource); + static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc); + +private: + + LONG m_lRefCount; + ULONG m_nIndex; + ULONG m_nNumFormats; + LPFORMATETC m_pFormatEtc; +}; + +/** + * Own IStream implementation to implement file-based clipboard operations + * through HGCM. Needed on Windows hosts and guests. + */ +class SharedClipboardWinStreamImpl : public IStream +{ +public: + + SharedClipboardWinStreamImpl(SharedClipboardWinDataObject *pParent, PSHCLTRANSFER pTransfer, + const Utf8Str &strPath, PSHCLFSOBJINFO pObjInfo); + virtual ~SharedClipboardWinStreamImpl(void); + +public: /* IUnknown methods. */ + + STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + +public: /* IStream methods. */ + + STDMETHOD(Clone)(IStream** ppStream); + STDMETHOD(Commit)(DWORD dwFrags); + STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten); + STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags); + STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead); + STDMETHOD(Revert)(void); + STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos); + STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize); + STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags); + STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags); + STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead); + +public: /* Own methods. */ + + static HRESULT Create(SharedClipboardWinDataObject *pParent, PSHCLTRANSFER pTransfer, const Utf8Str &strPath, + PSHCLFSOBJINFO pObjInfo, IStream **ppStream); +private: + + /** Pointer to the parent data object. */ + SharedClipboardWinDataObject *m_pParent; + /** The stream object's current reference count. */ + LONG m_lRefCount; + /** Pointer to the associated Shared Clipboard transfer. */ + PSHCLTRANSFER m_pTransfer; + /** The object handle to use. */ + SHCLOBJHANDLE m_hObj; + /** Object path. */ + Utf8Str m_strPath; + /** (Cached) object information. */ + SHCLFSOBJINFO m_objInfo; + /** Number of bytes already processed. */ + uint64_t m_cbProcessed; + /** Whether this object already is in completed state or not. */ + bool m_fIsComplete; +}; + +/** + * Class for Windows-specifics for maintaining a single Shared Clipboard transfer. + * Set as pvUser / cbUser in SHCLTRANSFERCTX. + */ +class SharedClipboardWinTransferCtx +{ +public: + SharedClipboardWinTransferCtx() + : pDataObj(NULL) { } + + virtual ~SharedClipboardWinTransferCtx() + { + if (pDataObj) + delete pDataObj; + } + + /** Pointer to data object to use for this transfer. + * Can be NULL if not being used. */ + SharedClipboardWinDataObject *pDataObj; +}; +# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ +#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */ + diff --git a/include/VBox/GuestHost/SharedClipboard-x11.h b/include/VBox/GuestHost/SharedClipboard-x11.h new file mode 100644 index 00000000..967abeb5 --- /dev/null +++ b/include/VBox/GuestHost/SharedClipboard-x11.h @@ -0,0 +1,156 @@ +/** @file + * Shared Clipboard - Common X11 code. + */ + +/* + * Copyright (C) 2006-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_x11_h +#define VBOX_INCLUDED_GuestHost_SharedClipboard_x11_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <X11/Intrinsic.h> + +#include <iprt/thread.h> + +#include <VBox/GuestHost/SharedClipboard.h> + +/** Enables the Xt busy / update handling. */ +#define VBOX_WITH_SHARED_CLIPBOARD_XT_BUSY 1 + +/** + * Enumeration for all clipboard formats which we support on X11. + */ +typedef enum _SHCLX11FMT +{ + SHCLX11FMT_INVALID = 0, + SHCLX11FMT_TARGETS, + SHCLX11FMT_TEXT, /* Treat this as UTF-8, but it may really be ascii */ + SHCLX11FMT_UTF8, + SHCLX11FMT_BMP, + SHCLX11FMT_HTML +#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS + , SHCLX11FMT_URI_LIST +#endif +} SHCLX11FMT; + +/** + * The table maps X11 names to data formats + * and to the corresponding VBox clipboard formats. + */ +typedef struct SHCLX11FMTTABLE +{ + /** The X11 atom name of the format (several names can match one format). */ + const char *pcszAtom; + /** The format corresponding to the name. */ + SHCLX11FMT enmFmtX11; + /** The corresponding VBox clipboard format. */ + SHCLFORMAT uFmtVBox; +} SHCLX11FMTTABLE; + +#define NIL_CLIPX11FORMAT 0 + +/** Defines an index of the X11 clipboad format table. */ +typedef unsigned SHCLX11FMTIDX; + +/** + * Structure for maintaining a Shared Clipboard context on X11 platforms. + */ +typedef struct _SHCLX11CTX +{ + /** Opaque data structure describing the front-end. */ + PSHCLCONTEXT pFrontend; + /** Is an X server actually available? */ + bool fHaveX11; + /** The X Toolkit application context structure. */ + XtAppContext pAppContext; + + /** We have a separate thread to wait for window and clipboard events. */ + RTTHREAD Thread; + /** Flag indicating that the thread is in a started state. */ + bool fThreadStarted; + + /** The X Toolkit widget which we use as our clipboard client. It is never made visible. */ + Widget pWidget; + + /** Should we try to grab the clipboard on startup? */ + bool fGrabClipboardOnStart; + + /** The best text format X11 has to offer, as an index into the formats table. */ + SHCLX11FMTIDX idxFmtText; + /** The best bitmap format X11 has to offer, as an index into the formats table. */ + SHCLX11FMTIDX idxFmtBmp; + /** The best HTML format X11 has to offer, as an index into the formats table. */ + SHCLX11FMTIDX idxFmtHTML; +#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS + /** The best HTML format X11 has to offer, as an index into the formats table. */ + SHCLX11FMTIDX idxFmtURI; +#endif + /** What kind of formats does VBox have to offer? */ + SHCLFORMATS vboxFormats; + /** Cache of the last unicode data that we received. */ + void *pvUnicodeCache; + /** Size of the unicode data in the cache. */ + uint32_t cbUnicodeCache; + /** When we wish the clipboard to exit, we have to wake up the event + * loop. We do this by writing into a pipe. This end of the pipe is + * the end that another thread can write to. */ + int wakeupPipeWrite; + /** The reader end of the pipe. */ + int wakeupPipeRead; + /** A pointer to the XFixesSelectSelectionInput function. */ + void (*fixesSelectInput)(Display *, Window, Atom, unsigned long); + /** The first XFixes event number. */ + int fixesEventBase; +#ifdef VBOX_WITH_SHARED_CLIPBOARD_XT_BUSY + /** XtGetSelectionValue on some versions of libXt isn't re-entrant + * so block overlapping requests on this flag. */ + bool fXtBusy; + /** If a request is blocked on the previous flag, set this flag to request + * an update later - the first callback should check and clear this flag + * before processing the callback event. */ + bool fXtNeedsUpdate; +#endif +} SHCLX11CTX, *PSHCLX11CTX; + +/** @name Shared Clipboard APIs for X11. + * @{ + */ +int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCONTEXT pParent, bool fHeadless); +void ShClX11Destroy(PSHCLX11CTX pCtx); +int ShClX11ThreadStart(PSHCLX11CTX pCtx, bool grab); +int ShClX11ThreadStop(PSHCLX11CTX pCtx); +int ShClX11ReportFormatsToX11(PSHCLX11CTX pCtx, SHCLFORMATS vboxFormats); +int ShClX11ReadDataFromX11(PSHCLX11CTX pCtx, SHCLFORMATS vboxFormat, CLIPREADCBREQ *pReq); +/** @} */ + +/** @name Shared Clipboard callbacks which have to be implemented the X11 backend and host service. + * @{ + */ +DECLCALLBACK(int) ShClX11RequestDataForX11Callback(SHCLCONTEXT *pCtx, SHCLFORMAT Format, void **ppv, uint32_t *pcb); +DECLCALLBACK(void) ShClX11ReportFormatsCallback(SHCLCONTEXT *pCtx, SHCLFORMATS Formats); +DECLCALLBACK(void) ShClX11RequestFromX11CompleteCallback(SHCLCONTEXT *pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb); +/** @} */ + +#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_x11_h */ + diff --git a/include/VBox/GuestHost/SharedClipboard.h b/include/VBox/GuestHost/SharedClipboard.h new file mode 100644 index 00000000..177bac30 --- /dev/null +++ b/include/VBox/GuestHost/SharedClipboard.h @@ -0,0 +1,217 @@ +/** @file + * Shared Clipboard - Common guest and host Code. + */ + +/* + * Copyright (C) 2006-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_h +#define VBOX_INCLUDED_GuestHost_SharedClipboard_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/types.h> +#include <iprt/list.h> + +/** + * Shared Clipboard transfer direction. + */ +typedef enum SHCLTRANSFERDIR +{ + /** Unknown transfer directory. */ + SHCLTRANSFERDIR_UNKNOWN = 0, + /** Read transfer (from source). */ + SHCLTRANSFERDIR_FROM_REMOTE, + /** Write transfer (to target). */ + SHCLTRANSFERDIR_TO_REMOTE, + /** The usual 32-bit hack. */ + SHCLTRANSFERDIR_32BIT_HACK = 0x7fffffff +} SHCLTRANSFERDIR; +/** Pointer to a shared clipboard transfer direction. */ +typedef SHCLTRANSFERDIR *PSHCLTRANSFERDIR; + + +/** A single Shared Clipboard format (VBOX_SHCL_FMT_XXX). */ +typedef uint32_t SHCLFORMAT; +/** Pointer to a single Shared Clipboard format (VBOX_SHCL_FMT_XXX). */ +typedef SHCLFORMAT *PSHCLFORMAT; + +/** Bit map (flags) of Shared Clipboard formats (VBOX_SHCL_FMT_XXX). */ +typedef uint32_t SHCLFORMATS; +/** Pointer to a bit map of Shared Clipboard formats (VBOX_SHCL_FMT_XXX). */ +typedef SHCLFORMATS *PSHCLFORMATS; + + +/** + * Shared Clipboard data read request. + */ +typedef struct SHCLDATAREQ +{ + /** In which format the data needs to be sent. */ + SHCLFORMAT uFmt; + /** Read flags; currently unused. */ + uint32_t fFlags; + /** Maximum data (in byte) can be sent. */ + uint32_t cbSize; +} SHCLDATAREQ; +/** Pointer to a shared clipboard data request. */ +typedef SHCLDATAREQ *PSHCLDATAREQ; + +/** + * Shared Clipboard event payload (optional). + */ +typedef struct SHCLEVENTPAYLOAD +{ + /** Payload ID; currently unused. */ + uint32_t uID; + /** Size (in bytes) of actual payload data. */ + uint32_t cbData; + /** Pointer to actual payload data. */ + void *pvData; +} SHCLEVENTPAYLOAD; +/** Pointer to a shared clipboard event payload. */ +typedef SHCLEVENTPAYLOAD *PSHCLEVENTPAYLOAD; + +/** A shared clipboard event source ID. */ +typedef uint16_t SHCLEVENTSOURCEID; +/** Pointer to a shared clipboard event source ID. */ +typedef SHCLEVENTSOURCEID *PSHCLEVENTSOURCEID; + +/** A shared clipboard session ID. */ +typedef uint16_t SHCLSESSIONID; +/** Pointer to a shared clipboard session ID. */ +typedef SHCLSESSIONID *PSHCLSESSIONID; +/** NIL shared clipboard session ID. */ +#define NIL_SHCLSESSIONID UINT16_MAX + +/** A shared clipboard transfer ID. */ +typedef uint16_t SHCLTRANSFERID; +/** Pointer to a shared clipboard transfer ID. */ +typedef SHCLTRANSFERID *PSHCLTRANSFERID; +/** NIL shared clipboardtransfer ID. */ +#define NIL_SHCLTRANSFERID UINT16_MAX + +/** A shared clipboard event ID. */ +typedef uint32_t SHCLEVENTID; +/** Pointer to a shared clipboard event source ID. */ +typedef SHCLEVENTID *PSHCLEVENTID; +/** NIL shared clipboard event ID. */ +#define NIL_SHCLEVENTID UINT32_MAX + +/** + * Shared Clipboard event. + */ +typedef struct SHCLEVENT +{ + /** List node. */ + RTLISTNODE Node; + /** The event's ID, for self-reference. */ + SHCLEVENTID idEvent; + /** Reference count to this event. */ + uint32_t cRefs; + /** Event semaphore for signalling the event. */ + RTSEMEVENTMULTI hEvtMulSem; + /** Payload to this event, optional (NULL). */ + PSHCLEVENTPAYLOAD pPayload; +} SHCLEVENT; +/** Pointer to a shared clipboard event. */ +typedef SHCLEVENT *PSHCLEVENT; + +/** + * Shared Clipboard event source. + * + * Each event source maintains an own counter for events, so that it can be used + * in different contexts. + */ +typedef struct SHCLEVENTSOURCE +{ + /** The event source ID. */ + SHCLEVENTSOURCEID uID; + /** Next upcoming event ID. */ + SHCLEVENTID idNextEvent; + /** List of events (PSHCLEVENT). */ + RTLISTANCHOR lstEvents; +} SHCLEVENTSOURCE; +/** Pointer to a shared clipboard event source. */ +typedef SHCLEVENTSOURCE *PSHCLEVENTSOURCE; + +/** @name Shared Clipboard data payload functions. + * @{ + */ +int ShClPayloadAlloc(uint32_t uID, const void *pvData, uint32_t cbData, PSHCLEVENTPAYLOAD *ppPayload); +void ShClPayloadFree(PSHCLEVENTPAYLOAD pPayload); +/** @} */ + +/** @name Shared Clipboard event source functions. + * @{ + */ +int ShClEventSourceCreate(PSHCLEVENTSOURCE pSource, SHCLEVENTSOURCEID idEvtSrc); +void ShClEventSourceDestroy(PSHCLEVENTSOURCE pSource); +void ShClEventSourceReset(PSHCLEVENTSOURCE pSource); +/** @} */ + +/** @name Shared Clipboard event functions. + * @{ + */ +SHCLEVENTID ShClEventIdGenerateAndRegister(PSHCLEVENTSOURCE pSource); +SHCLEVENTID ShClEventGetLast(PSHCLEVENTSOURCE pSource); +uint32_t ShClEventRetain(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent); +uint32_t ShClEventRelease(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent); +int ShClEventSignal(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent, PSHCLEVENTPAYLOAD pPayload); +int ShClEventUnregister(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent); +int ShClEventWait(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent, RTMSINTERVAL uTimeoutMs, PSHCLEVENTPAYLOAD *ppPayload); + +void ShClEventPayloadDetach(PSHCLEVENTSOURCE pSource, SHCLEVENTID idEvent); +/** @} */ + +/** + * Shared Clipboard transfer source type. + * @note Part of saved state! + */ +typedef enum SHCLSOURCE +{ + /** Invalid source type. */ + SHCLSOURCE_INVALID = 0, + /** Source is local. */ + SHCLSOURCE_LOCAL, + /** Source is remote. */ + SHCLSOURCE_REMOTE, + /** The usual 32-bit hack. */ + SHCLSOURCE_32BIT_HACK = 0x7fffffff +} SHCLSOURCE; + +/** Opaque data structure for the X11/VBox frontend/glue code. + * @{ */ +struct SHCLCONTEXT; +typedef struct SHCLCONTEXT SHCLCONTEXT; +/** @} */ +/** Pointer to opaque data structure the X11/VBox frontend/glue code. */ +typedef SHCLCONTEXT *PSHCLCONTEXT; + +/** Opaque request structure for X11 clipboard data. + * @{ */ +struct CLIPREADCBREQ; +typedef struct CLIPREADCBREQ CLIPREADCBREQ; +/** @} */ + +#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_h */ + diff --git a/include/VBox/GuestHost/clipboard-helper.h b/include/VBox/GuestHost/clipboard-helper.h new file mode 100644 index 00000000..2444a7b3 --- /dev/null +++ b/include/VBox/GuestHost/clipboard-helper.h @@ -0,0 +1,281 @@ +/* $Id: clipboard-helper.h $ */ +/** @file + * Shared Clipboard - Some helper function for converting between the various EOLs. + */ + +/* + * Copyright (C) 2006-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_clipboard_helper_h +#define VBOX_INCLUDED_GuestHost_clipboard_helper_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/string.h> + +#include <VBox/GuestHost/SharedClipboard.h> + +/** Constants needed for string conversions done by the Linux/Mac clipboard code. */ +enum +{ + /** In Linux, lines end with a linefeed character. */ + VBOX_SHCL_LINEFEED = 0xa, + /** In Windows, lines end with a carriage return and a linefeed character. */ + VBOX_SHCL_CARRIAGERETURN = 0xd, + /** Little endian "real" UTF-16 strings start with this marker. */ + VBOX_SHCL_UTF16LEMARKER = 0xfeff, + /** Big endian "real" UTF-16 strings start with this marker. */ + VBOX_SHCL_UTF16BEMARKER = 0xfffe +}; + +/** + * Returns the length (in UTF-8 characters) of an UTF-16 string with LF EOL. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to return size for. + * @param cwcSrc Length of the string in RTUTF16 units. + * @param pchLen Where to return the length (in UTF-8 characters). + * Does not include terminator. + */ +int ShClUtf16LFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwcSrc, size_t *pchLen); + +/** + * Returns the length (in UTF-8 characters) of an UTF-16 string with CRLF EOL. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to return size for. + * @param cwcSrc Length of the source string in RTUTF16 units. + * @param pchLen Where to return the length (in UTF-8 characters). + * Does not include terminator. + */ +int ShClUtf16CRLFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwcSrc, size_t *pchLen); + +/** + * Returns the length (in characters) of an UTF-16 string, including terminator. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to return size for. + * @param cwcSrc Length of the source string in RTUTF16 units. + * @param pchLen Where to return the length (in UTF-8 characters). + * Does not include terminator. + */ +int ShClUtf16LenUtf8(PCRTUTF16 pcwszSrc, size_t cwcSrc, size_t *pchLen); + +/** + * Converts an UTF-16 string with LF EOL to an UTF-16 string with CRLF EOL. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to convert. + * @param cwcSrc Size of the string int RTUTF16 units. + * @param pwszDst Buffer to store the converted string to. + * @param cwcDst The size of \a pwszDst in RTUTF16 units. + */ +int ShClConvUtf16LFToCRLF(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 pwszDst, size_t cwcDst); + +/** + * Converts an UTF-16 string with LF EOL to an UTF-16 string with CRLF EOL. + * + * Convenience function which returns the allocated + converted string on success. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to convert. + * @param cwcSrc Size of the string int RTUTF16 units. + * @param ppwszDst Where to return the allocated converted string. Must be free'd by the caller. + * @param pcwDst Where to return the size of the converted string in RTUTF16 units. + * Does not include the terminator. + */ +int ShClConvUtf16LFToCRLFA(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 *ppwszDst, size_t *pcwDst); + +/** + * Converts an UTF-16 string with CRLF EOL to an UTF-16 string with LF EOL. + * + * @returns VBox status code. + * @param pcwszSrc UTF-16 string to convert. + * @param cwcSrc Size of the string in RTUTF16 units. + * @param pwszDst Where to store the converted string to. + * @param cwcDst The size of \a pwszDst in RTUTF16 units. + */ +int ShClConvUtf16CRLFToLF(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 pwszDst, size_t cwcDst); + +/** + * Converts an UTF-16 string with CRLF EOL to UTF-8 LF. + * + * @returns VBox status code. Will return VERR_NO_DATA if no data was converted. + * @param pcwszSrc UTF-16 string to convert. + * @param cbSrc Length of @a pwszSrc (in bytes). + * @param pszBuf Where to write the converted string. + * @param cbBuf The size of the buffer pointed to by @a pszBuf. + * @param pcbLen Where to store the size (in bytes) of the converted string. + * Does not include terminator. + */ +int ShClConvUtf16CRLFToUtf8LF(PCRTUTF16 pcwszSrc, size_t cbSrc, char *pszBuf, size_t cbBuf, size_t *pcbLen); + +/** +* Converts an HTML string from UTF-16 into UTF-8. +* +* @returns VBox status code. +* @param pcwszSrc UTF-16 string to convert. +* @param cwcSrc Length (in RTUTF16 units) of the source text. +* @param ppszDst Where to store the converted result on success. +* @param pcbDst Where to store the number of bytes written. +*/ +int ShClConvUtf16ToUtf8HTML(PCRTUTF16 pcwszSrc, size_t cwcSrc, char **ppszDst, size_t *pcbDst); + +/** + * Converts an UTF-8 string with LF EOL into UTF-16 CRLF. + * + * @returns VBox status code. + * @param pcszSrc UTF-8 string to convert. + * @param cbSrc Size of UTF-8 string to convert (in bytes), not counting the terminating zero. + * @param ppwszDst Where to return the allocated buffer on success. + * @param pcwDst Where to return the size (in RTUTF16 units) of the allocated buffer on success. + * Does not include terminator. + */ +int ShClConvUtf8LFToUtf16CRLF(const char *pcszSrc, size_t cbSrc, PRTUTF16 *ppwszDst, size_t *pcwDst); + +/** + * Converts a Latin-1 string with LF EOL into UTF-16 CRLF. + * + * @returns VBox status code. + * @param pcszSrc UTF-8 string to convert. + * @param cbSrc Size of string (in bytes), not counting the terminating zero. + * @param ppwszDst Where to return the allocated buffer on success. + * @param pcwDst Where to return the size (in RTUTF16 units) of the allocated buffer on success. + * Does not include terminator. + */ +int ShClConvLatin1LFToUtf16CRLF(const char *pcszSrc, size_t cbSrc, PRTUTF16 *ppwszDst, size_t *pcwDst); + +#pragma pack(1) +/** @todo r=bird: Why duplicate these structures here, we've got them in + * DevVGA.cpp already! */ +/** + * Bitmap File Header. Official win32 name is BITMAPFILEHEADER + * Always Little Endian. + */ +typedef struct BMFILEHEADER +{ + uint16_t uType; + uint32_t uSize; + uint16_t uReserved1; + uint16_t uReserved2; + uint32_t uOffBits; +} BMFILEHEADER; +#pragma pack() + +/** Pointer to a BMFILEHEADER structure. */ +typedef BMFILEHEADER *PBMFILEHEADER; +/** BMP file magic number */ +#define BITMAPHEADERMAGIC (RT_H2LE_U16_C(0x4d42)) + +/** + * Bitmap Info Header. Official win32 name is BITMAPINFOHEADER + * Always Little Endian. + */ +typedef struct BMINFOHEADER +{ + uint32_t uSize; + uint32_t uWidth; + uint32_t uHeight; + uint16_t uPlanes; + uint16_t uBitCount; + uint32_t uCompression; + uint32_t uSizeImage; + uint32_t uXBitsPerMeter; + uint32_t uYBitsPerMeter; + uint32_t uClrUsed; + uint32_t uClrImportant; +} BMINFOHEADER; +/** Pointer to a BMINFOHEADER structure. */ +typedef BMINFOHEADER *PBMINFOHEADER; + +/** + * Convert CF_DIB data to full BMP data by prepending the BM header. + * Allocates with RTMemAlloc. + * + * @returns VBox status code. + * @param pvSrc DIB data to convert + * @param cbSrc Size of the DIB data to convert in bytes + * @param ppvDst Where to store the pointer to the buffer for the + * destination data + * @param pcbDst Pointer to the size of the buffer for the destination + * data in bytes. + */ +int ShClDibToBmp(const void *pvSrc, size_t cbSrc, void **ppvDst, size_t *pcbDst); + +/** + * Get the address and size of CF_DIB data in a full BMP data in the input buffer. + * Does not do any allocation. + * + * @returns VBox status code. + * @param pvSrc BMP data to convert + * @param cbSrc Size of the BMP data to convert in bytes + * @param ppvDst Where to store the pointer to the destination data + * @param pcbDst Pointer to the size of the destination data in bytes + */ +int ShClBmpGetDib(const void *pvSrc, size_t cbSrc, const void **ppvDst, size_t *pcbDst); + +#ifdef LOG_ENABLED +/** + * Dumps HTML data to the debug log. + * + * @returns VBox status code. + * @param pszSrc HTML data to dump. + * @param cbSrc Size (in bytes) of HTML data to dump. + */ +int ShClDbgDumpHtml(const char *pszSrc, size_t cbSrc); + +/** + * Dumps data using a specified clipboard format. + * + * @param pv Pointer to data to dump. + * @param cb Size (in bytes) of data to dump. + * @param u32Format Clipboard format to use for dumping. + */ +void ShClDbgDumpData(const void *pv, size_t cb, SHCLFORMAT u32Format); +#endif /* LOG_ENABLED */ + +/** + * Translates a Shared Clipboard host function number to a string. + * + * @returns Function ID string name. + * @param uFn The function to translate. + */ +const char *ShClHostFunctionToStr(uint32_t uFn); + +/** + * Translates a Shared Clipboard host message enum to a string. + * + * @returns Message ID string name. + * @param uMsg The message to translate. + */ +const char *ShClHostMsgToStr(uint32_t uMsg); + +/** + * Translates a Shared Clipboard guest message enum to a string. + * + * @returns Message ID string name. + * @param uMsg The message to translate. + */ +const char *ShClGuestMsgToStr(uint32_t uMsg); + +#endif /* !VBOX_INCLUDED_GuestHost_clipboard_helper_h */ + |