VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/clipboard-common.cpp@ 103085

Last change on this file since 103085 was 101721, checked in by vboxsync, 14 months ago

Additions: X11/Wayland: Clipboard: fix memory zeroing on realloc (plus small refactoring), bugref:10194.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 4.8 KB
Line 
1/** $Id: clipboard-common.cpp 101721 2023-11-02 15:23:58Z vboxsync $ */
2/** @file
3 * Guest Additions - Shared Clipboard common code.
4 */
5
6/*
7 * Copyright (C) 2007-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32
33#ifdef LOG_GROUP
34# undef LOG_GROUP
35#endif
36#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
37#include <iprt/log.h>
38#include <iprt/mem.h>
39#include <iprt/err.h>
40
41#include "VBoxClient.h"
42#include "clipboard.h"
43
44RTDECL(int) VBClClipboardThreadStart(PRTTHREAD pThread, PFNRTTHREAD pfnThread, const char *pszName, void *pvUser)
45{
46 int rc;
47
48 rc = RTThreadCreate(pThread, pfnThread, pvUser, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, pszName);
49 if (RT_SUCCESS(rc))
50 rc = RTThreadUserWait(*pThread, RT_MS_30SEC /* msTimeout */);
51
52 if (RT_SUCCESS(rc))
53 VBClLogVerbose(1, "started %s thread\n", pszName);
54 else
55 LogRel(("unable to start %s thread, rc=%Rrc\n", pszName, rc));
56
57 return rc;
58}
59
60RTDECL(int) VBClClipboardReadHostEvent(PSHCLCONTEXT pCtx, const PFNHOSTCLIPREPORTFMTS pfnHGClipReport,
61 const PFNHOSTCLIPREAD pfnGHClipRead)
62{
63 int rc;
64
65 uint32_t idMsg = 0;
66 uint32_t cParms = 0;
67
68 AssertPtrReturn(pfnHGClipReport, VERR_INVALID_PARAMETER);
69 AssertPtrReturn(pfnGHClipRead, VERR_INVALID_PARAMETER);
70
71 PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
72 AssertPtrReturn(pEvent, VERR_NO_MEMORY);
73
74 rc = VbglR3ClipboardMsgPeekWait(&pCtx->CmdCtx, &idMsg, &cParms, NULL /* pidRestoreCheck */);
75 if (RT_SUCCESS(rc))
76 rc = VbglR3ClipboardEventGetNext(idMsg, cParms, &pCtx->CmdCtx, pEvent);
77
78 if (RT_SUCCESS(rc))
79 {
80 switch (pEvent->enmType)
81 {
82 /* Host reports new clipboard data is now available. */
83 case VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS:
84 {
85 rc = pfnHGClipReport(pEvent->u.fReportedFormats);
86 break;
87 }
88
89 /* Host wants to read data from guest clipboard. */
90 case VBGLR3CLIPBOARDEVENTTYPE_READ_DATA:
91 {
92 rc = pfnGHClipRead(pEvent->u.fReadData);
93 break;
94 }
95
96 default:
97 {
98 AssertMsgFailedBreakStmt(("Event type %RU32 not implemented\n", pEvent->enmType), rc = VERR_NOT_SUPPORTED);
99 }
100 }
101 }
102 else
103 LogFlowFunc(("Getting next event failed with %Rrc\n", rc));
104
105 VbglR3ClipboardEventFree(pEvent);
106
107 LogFlowFuncLeaveRC(rc);
108 return rc;
109}
110
111RTDECL(int) VBClClipboardReadHostClipboard(PVBGLR3SHCLCMDCTX pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb)
112{
113 int rc;
114
115 uint32_t cbRead = 0;
116 uint32_t cbData = _4K;
117
118 void *pvData;
119
120 pvData = RTMemAllocZ(cbData);
121 if (pvData)
122 {
123 rc = VbglR3ClipboardReadDataEx(pCtx, uFmt, pvData, cbData, &cbRead);
124
125 /*
126 * A return value of VINF_BUFFER_OVERFLOW tells us to try again with a
127 * larger buffer. The size of the buffer needed is placed in *pcb.
128 * So we start all over again.
129 */
130 if (rc == VINF_BUFFER_OVERFLOW)
131 {
132 /* cbRead contains the size required. */
133 pvData = RTMemReallocZ(pvData, cbData, cbRead);
134 cbData = cbRead;
135 if (pvData)
136 {
137 rc = VbglR3ClipboardReadDataEx(pCtx, uFmt, pvData, cbData, &cbRead);
138 if (rc == VINF_BUFFER_OVERFLOW)
139 rc = VERR_BUFFER_OVERFLOW;
140 }
141 else
142 rc = VERR_NO_MEMORY;
143 }
144
145 if (RT_SUCCESS(rc))
146 {
147 *pcb = cbRead; /* Actual bytes read. */
148 *ppv = pvData;
149 }
150 }
151 else
152 rc = VERR_NO_MEMORY;
153
154 if (!cbRead)
155 rc = VERR_NO_DATA;
156
157 if (RT_FAILURE(rc))
158 RTMemFree(pvData);
159
160 return rc;
161}
Note: See TracBrowser for help on using the repository browser.

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