[101878] | 1 | /* $Id: wayland-helper-ipc.cpp 102064 2023-11-10 14:15:11Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * Guest Additions - IPC between VBoxClient and vboxwl tool.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
| 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
| 8 | *
|
---|
| 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
| 26 | */
|
---|
| 27 |
|
---|
| 28 | #include <sys/types.h>
|
---|
| 29 | #include <pwd.h>
|
---|
| 30 | #include <unistd.h>
|
---|
| 31 |
|
---|
| 32 | #include <iprt/cdefs.h>
|
---|
| 33 | #include <iprt/err.h>
|
---|
| 34 | #include <iprt/linux/sysfs.h>
|
---|
| 35 | #include <iprt/localipc.h>
|
---|
| 36 | #include <iprt/mem.h>
|
---|
| 37 | #include <iprt/crc.h>
|
---|
| 38 | #include <iprt/env.h>
|
---|
| 39 | #include <iprt/process.h>
|
---|
| 40 | #include <iprt/asm.h>
|
---|
| 41 |
|
---|
| 42 | #include <VBox/GuestHost/clipboard-helper.h>
|
---|
| 43 |
|
---|
| 44 | #include "VBoxClient.h"
|
---|
| 45 | #include "wayland-helper-ipc.h"
|
---|
| 46 |
|
---|
| 47 | RTDECL(int) vbcl_wayland_hlp_gtk_ipc_srv_name(char *szBuf, size_t cbBuf)
|
---|
| 48 | {
|
---|
| 49 | int rc;
|
---|
| 50 |
|
---|
| 51 | char pszActiveTTY[128];
|
---|
| 52 | size_t cchRead;
|
---|
| 53 | struct passwd *pwd;
|
---|
| 54 |
|
---|
| 55 | AssertReturn(RT_VALID_PTR(szBuf), VERR_INVALID_PARAMETER);
|
---|
| 56 | AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER);
|
---|
| 57 |
|
---|
| 58 | RT_BZERO(szBuf, cbBuf);
|
---|
| 59 | RT_ZERO(pszActiveTTY);
|
---|
| 60 |
|
---|
| 61 | rc = RTStrCat(szBuf, cbBuf, "GtkHlpIpcServer-");
|
---|
| 62 | if (RT_SUCCESS(rc))
|
---|
| 63 | rc = RTLinuxSysFsReadStrFile(pszActiveTTY, sizeof(pszActiveTTY) - 1 /* reserve last byte for string termination */,
|
---|
| 64 | &cchRead, "class/tty/tty0/active");
|
---|
| 65 | if (RT_SUCCESS(rc))
|
---|
| 66 | rc = RTStrCat(szBuf, cbBuf, pszActiveTTY);
|
---|
| 67 |
|
---|
| 68 | if (RT_SUCCESS(rc))
|
---|
| 69 | rc = RTStrCat(szBuf, cbBuf, "-");
|
---|
| 70 |
|
---|
| 71 | pwd = getpwuid(geteuid());
|
---|
| 72 | if (RT_VALID_PTR(pwd))
|
---|
| 73 | {
|
---|
| 74 | if (RT_VALID_PTR(pwd->pw_name))
|
---|
| 75 | rc = RTStrCat(szBuf, cbBuf, pwd->pw_name);
|
---|
| 76 | else
|
---|
| 77 | rc = VERR_NOT_FOUND;
|
---|
| 78 | }
|
---|
| 79 | else
|
---|
| 80 | rc = VERR_NOT_FOUND;
|
---|
| 81 |
|
---|
| 82 | return rc;
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | void vbcl::ipc::packet_dump(vbcl::ipc::packet_t *pPacket)
|
---|
| 86 | {
|
---|
| 87 | VBClLogVerbose(3, "IPC packet dump:\n");
|
---|
| 88 | VBClLogVerbose(3, "u64Crc : 0x%x\n", pPacket->u64Crc);
|
---|
| 89 | VBClLogVerbose(3, "uSessionId: %u\n", pPacket->uSessionId);
|
---|
| 90 | VBClLogVerbose(3, "idCmd : %u\n", pPacket->idCmd);
|
---|
| 91 | VBClLogVerbose(3, "cbData: : %u\n", pPacket->cbData);
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | bool vbcl::ipc::packet_verify(vbcl::ipc::packet_t *pPacket, size_t cbPacket)
|
---|
| 95 | {
|
---|
| 96 | bool fResult = false;
|
---|
| 97 |
|
---|
| 98 | AssertPtrReturn(pPacket, VERR_INVALID_PARAMETER);
|
---|
| 99 | AssertReturn(cbPacket > sizeof(vbcl::ipc::packet_t), VERR_INVALID_PARAMETER);
|
---|
| 100 |
|
---|
| 101 | AssertReturn( pPacket->idCmd > vbcl::ipc::CMD_UNKNOWN
|
---|
| 102 | && pPacket->idCmd < vbcl::ipc::CMD_MAX, VERR_INVALID_PARAMETER);
|
---|
| 103 |
|
---|
| 104 | /* Exact size match. */
|
---|
| 105 | if (pPacket->cbData == cbPacket)
|
---|
| 106 | {
|
---|
| 107 | /* CRC check. */
|
---|
| 108 | uint64_t u64Crc = pPacket->u64Crc;
|
---|
| 109 | pPacket->u64Crc = 0;
|
---|
| 110 | if (u64Crc != 0 && RTCrc64(pPacket, pPacket->cbData) == u64Crc)
|
---|
| 111 | {
|
---|
| 112 | /* Verify payload size. */
|
---|
| 113 | size_t cbPayload = 0;
|
---|
| 114 |
|
---|
| 115 | switch (pPacket->idCmd)
|
---|
| 116 | {
|
---|
| 117 | case vbcl::ipc::CLIP_FORMATS:
|
---|
| 118 | case vbcl::ipc::CLIP_FORMAT:
|
---|
| 119 | cbPayload = sizeof(vbcl::ipc::clipboard::formats_packet_t);
|
---|
| 120 | break;
|
---|
| 121 |
|
---|
| 122 | case vbcl::ipc::CLIP_DATA:
|
---|
| 123 | {
|
---|
| 124 | vbcl::ipc::clipboard::data_packet_t *pDataEx = (vbcl::ipc::clipboard::data_packet_t *)pPacket;
|
---|
| 125 | cbPayload = sizeof(vbcl::ipc::clipboard::data_packet_t) + pDataEx->cbData;
|
---|
| 126 | break;
|
---|
| 127 | }
|
---|
| 128 |
|
---|
| 129 | default:
|
---|
| 130 | break;
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | if (pPacket->cbData == cbPayload)
|
---|
| 134 | fResult = true;
|
---|
| 135 | else
|
---|
| 136 | VBClLogVerbose(3, "bad cmd size (%u vs %u)\n", pPacket->cbData, cbPayload);
|
---|
| 137 | }
|
---|
| 138 | else
|
---|
| 139 | VBClLogVerbose(3, "bad crc\n");
|
---|
| 140 |
|
---|
| 141 | /* Restore CRC. */
|
---|
| 142 | pPacket->u64Crc = u64Crc;
|
---|
| 143 | }
|
---|
| 144 | else
|
---|
| 145 | VBClLogVerbose(3, "bad size\n");
|
---|
| 146 |
|
---|
| 147 | return fResult;
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | int vbcl::ipc::packet_read(uint32_t uSessionId, RTLOCALIPCSESSION hSession, void **ppvData)
|
---|
| 151 | {
|
---|
| 152 | int rc;
|
---|
| 153 |
|
---|
| 154 | vbcl::ipc::packet_t Packet;
|
---|
| 155 |
|
---|
| 156 | AssertPtrReturn(ppvData, VERR_INVALID_PARAMETER);
|
---|
| 157 |
|
---|
| 158 | rc = RTLocalIpcSessionWaitForData(hSession, VBOX_GTKIPC_RX_TIMEOUT_MS);
|
---|
| 159 | if (RT_SUCCESS(rc))
|
---|
| 160 | {
|
---|
| 161 | /* Read IPC message header. */
|
---|
[102064] | 162 | rc = RTLocalIpcSessionRead(hSession, &Packet, sizeof(Packet), NULL);
|
---|
[101878] | 163 | if (RT_SUCCESS(rc))
|
---|
| 164 | {
|
---|
[102064] | 165 | bool fCheck = true;
|
---|
[101878] | 166 |
|
---|
| 167 | #define _CHECK(_cond, _msg, _ptr) \
|
---|
| 168 | if (fCheck) \
|
---|
| 169 | { \
|
---|
| 170 | fCheck &= _cond; \
|
---|
| 171 | if (!fCheck) \
|
---|
| 172 | VBClLogVerbose(3, _msg "\n", _ptr); \
|
---|
| 173 | }
|
---|
| 174 |
|
---|
[102064] | 175 | _CHECK(Packet.u64Crc > 0, "bad crc: 0x%x", Packet.u64Crc);
|
---|
| 176 | _CHECK(Packet.uSessionId == uSessionId, "bad session id: %u vs %u", (Packet.uSessionId, uSessionId));
|
---|
| 177 | _CHECK(Packet.cbData > sizeof(Packet), "bad cbData: %u", Packet.cbData);
|
---|
[101878] | 178 |
|
---|
[102064] | 179 | /* Receive the rest of a message. */
|
---|
| 180 | if (fCheck)
|
---|
| 181 | {
|
---|
| 182 | uint8_t *puData;
|
---|
| 183 |
|
---|
| 184 | puData = (uint8_t *)RTMemAllocZ(Packet.cbData);
|
---|
| 185 | if (RT_VALID_PTR(puData))
|
---|
[101878] | 186 | {
|
---|
[102064] | 187 | /* Add generic header to the beginning of the output buffer
|
---|
| 188 | * and receive the rest of the data into it. */
|
---|
| 189 | memcpy(puData, &Packet, sizeof(Packet));
|
---|
[101878] | 190 |
|
---|
[102064] | 191 | rc = RTLocalIpcSessionRead(hSession, puData + sizeof(Packet),
|
---|
| 192 | Packet.cbData - sizeof(Packet), NULL);
|
---|
| 193 | if (RT_SUCCESS(rc))
|
---|
[101878] | 194 | {
|
---|
[102064] | 195 | if (vbcl::ipc::packet_verify((vbcl::ipc::packet_t *)puData, Packet.cbData))
|
---|
[101878] | 196 | {
|
---|
[102064] | 197 | /* Now return received data to the caller. */
|
---|
| 198 | *ppvData = puData;
|
---|
[101878] | 199 | }
|
---|
[102064] | 200 | else
|
---|
| 201 | rc = VERR_NOT_EQUAL;
|
---|
| 202 | }
|
---|
[101878] | 203 |
|
---|
[102064] | 204 | if (RT_FAILURE(rc))
|
---|
| 205 | RTMemFree(puData);
|
---|
[101878] | 206 | }
|
---|
| 207 | else
|
---|
[102064] | 208 | rc = VERR_NO_MEMORY;
|
---|
[101878] | 209 | }
|
---|
[102064] | 210 | else
|
---|
| 211 | rc = VERR_INVALID_PARAMETER;
|
---|
[101878] | 212 |
|
---|
| 213 | if (RT_FAILURE(rc))
|
---|
| 214 | vbcl::ipc::packet_dump(&Packet);
|
---|
| 215 | }
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | return rc;
|
---|
| 219 | }
|
---|
| 220 |
|
---|
| 221 | int vbcl::ipc::packet_write(RTLOCALIPCSESSION hSession, vbcl::ipc::packet_t *pPacket)
|
---|
| 222 | {
|
---|
| 223 | int rc;
|
---|
| 224 |
|
---|
| 225 | AssertPtrReturn(pPacket, VERR_INVALID_PARAMETER);
|
---|
| 226 |
|
---|
| 227 | pPacket->u64Crc = 0;
|
---|
| 228 | pPacket->u64Crc = RTCrc64(pPacket, pPacket->cbData);
|
---|
| 229 |
|
---|
| 230 | Assert(pPacket->u64Crc);
|
---|
| 231 |
|
---|
| 232 | if (vbcl::ipc::packet_verify(pPacket, pPacket->cbData))
|
---|
| 233 | {
|
---|
| 234 | rc = RTLocalIpcSessionWrite(hSession, (void *)pPacket, pPacket->cbData);
|
---|
| 235 | if (RT_SUCCESS(rc))
|
---|
| 236 | rc = RTLocalIpcSessionFlush(hSession);
|
---|
| 237 | }
|
---|
| 238 | else
|
---|
| 239 | {
|
---|
| 240 | vbcl::ipc::packet_dump(pPacket);
|
---|
| 241 | rc = VERR_NOT_EQUAL;
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 | return rc;
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | int vbcl::ipc::clipboard::ClipboardIpc::send_formats(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 248 | {
|
---|
| 249 | vbcl::ipc::clipboard::formats_packet_t Packet;
|
---|
| 250 | SHCLFORMATS fFormats;
|
---|
| 251 | int rc = VINF_SUCCESS;
|
---|
| 252 |
|
---|
| 253 | RT_ZERO(Packet);
|
---|
| 254 |
|
---|
| 255 | Packet.Hdr.u64Crc = 0;
|
---|
| 256 | Packet.Hdr.uSessionId = uSessionId;
|
---|
| 257 | Packet.Hdr.idCmd = CLIP_FORMATS;
|
---|
| 258 | Packet.Hdr.cbData = sizeof(Packet);
|
---|
| 259 |
|
---|
| 260 | fFormats = m_fFmts.wait();
|
---|
| 261 | if (fFormats != m_fFmts.defaults())
|
---|
| 262 | {
|
---|
| 263 | Packet.fFormats = fFormats;
|
---|
| 264 | rc = vbcl::ipc::packet_write(hIpcSession, &Packet.Hdr);
|
---|
| 265 | }
|
---|
| 266 | else
|
---|
| 267 | rc = VERR_TIMEOUT;
|
---|
| 268 |
|
---|
| 269 | VBClLogVerbose(3, "%s: send_formats [sid=%u, fmts=0x%x], rc=%Rrc\n",
|
---|
| 270 | m_fServer ? "server" : "client", uSessionId, fFormats, rc);
|
---|
| 271 |
|
---|
| 272 | return rc;
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | int vbcl::ipc::clipboard::ClipboardIpc::recv_formats(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 276 | {
|
---|
| 277 | int rc;
|
---|
| 278 | vbcl::ipc::clipboard::formats_packet_t *pPacket;
|
---|
| 279 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 280 | SHCLFORMATS fFormats = VBOX_SHCL_FMT_NONE;
|
---|
| 281 |
|
---|
| 282 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 283 | if (RT_SUCCESS(rc))
|
---|
| 284 | {
|
---|
| 285 | if ( pPacket->Hdr.idCmd == CLIP_FORMATS
|
---|
| 286 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 287 | {
|
---|
| 288 | fFormats = pPacket->fFormats;
|
---|
| 289 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 290 | m_fFmts.set(fFormats);
|
---|
| 291 | }
|
---|
| 292 | else
|
---|
| 293 | rc = VERR_WRONG_ORDER;
|
---|
| 294 |
|
---|
| 295 | RTMemFree(pPacket);
|
---|
| 296 | }
|
---|
| 297 |
|
---|
| 298 | VBClLogVerbose(3, "%s: recv_formats [sid=%u, cmd=0x%x, fmts=0x%x], rc=%Rrc\n",
|
---|
| 299 | m_fServer ? "server" : "client", uSessionId, idCmd, fFormats, rc);
|
---|
| 300 |
|
---|
| 301 | return rc;
|
---|
| 302 | }
|
---|
| 303 |
|
---|
| 304 | int vbcl::ipc::clipboard::ClipboardIpc::send_format(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 305 | {
|
---|
| 306 | vbcl::ipc::clipboard::formats_packet_t Packet;
|
---|
| 307 | SHCLFORMAT uFormat;
|
---|
| 308 | int rc = VINF_SUCCESS;
|
---|
| 309 |
|
---|
| 310 | RT_ZERO(Packet);
|
---|
| 311 |
|
---|
| 312 | Packet.Hdr.u64Crc = 0;
|
---|
| 313 | Packet.Hdr.uSessionId = uSessionId;
|
---|
| 314 | Packet.Hdr.idCmd = CLIP_FORMAT;
|
---|
| 315 | Packet.Hdr.cbData = sizeof(Packet);
|
---|
| 316 |
|
---|
| 317 | uFormat = m_uFmt.wait();
|
---|
| 318 | if (uFormat != m_uFmt.defaults())
|
---|
| 319 | {
|
---|
| 320 | Packet.fFormats = uFormat;
|
---|
| 321 | rc = vbcl::ipc::packet_write(hIpcSession, &Packet.Hdr);
|
---|
| 322 | }
|
---|
| 323 | else
|
---|
| 324 | rc = VERR_TIMEOUT;
|
---|
| 325 |
|
---|
| 326 | VBClLogVerbose(3, "%s: send_format [sid=%u, fmt=0x%x], rc=%Rrc\n",
|
---|
| 327 | m_fServer ? "server" : "client", uSessionId, uFormat, rc);
|
---|
| 328 |
|
---|
| 329 | return rc;
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | int vbcl::ipc::clipboard::ClipboardIpc::recv_format(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 333 | {
|
---|
| 334 | int rc;
|
---|
| 335 | vbcl::ipc::clipboard::formats_packet_t *pPacket;
|
---|
| 336 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 337 | SHCLFORMATS uFormat = VBOX_SHCL_FMT_NONE;
|
---|
| 338 |
|
---|
| 339 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 340 | if (RT_SUCCESS(rc))
|
---|
| 341 | {
|
---|
| 342 | if ( pPacket->Hdr.idCmd == CLIP_FORMAT
|
---|
| 343 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 344 | {
|
---|
| 345 | uFormat = pPacket->fFormats;
|
---|
| 346 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 347 | m_uFmt.set(uFormat);
|
---|
| 348 | }
|
---|
| 349 | else
|
---|
| 350 | rc = VERR_WRONG_ORDER;
|
---|
| 351 |
|
---|
| 352 | RTMemFree(pPacket);
|
---|
| 353 | }
|
---|
| 354 |
|
---|
| 355 | VBClLogVerbose(3, "%s: recv_format [sid=%u, cmd=0x%x, fmts=0x%x], rc=%Rrc\n",
|
---|
| 356 | m_fServer ? "server" : "client", uSessionId, idCmd, uFormat, rc);
|
---|
| 357 |
|
---|
| 358 | return rc;
|
---|
| 359 | }
|
---|
| 360 |
|
---|
| 361 | int vbcl::ipc::clipboard::ClipboardIpc::send_data(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 362 | {
|
---|
| 363 | vbcl::ipc::clipboard::data_packet_t *pPacket;
|
---|
| 364 | int rc = VINF_SUCCESS;
|
---|
| 365 |
|
---|
| 366 | void *pvData;
|
---|
| 367 | uint32_t cbData;
|
---|
| 368 |
|
---|
| 369 | cbData = m_cbClipboardBuf.wait();
|
---|
| 370 | pvData = (void *)m_pvClipboardBuf.wait();
|
---|
| 371 | if ( cbData != m_cbClipboardBuf.defaults()
|
---|
| 372 | && pvData != (void *)m_pvClipboardBuf.defaults())
|
---|
| 373 | {
|
---|
| 374 | pPacket = (vbcl::ipc::clipboard::data_packet_t *)RTMemAllocZ(sizeof(vbcl::ipc::clipboard::data_packet_t) + cbData);
|
---|
| 375 | if (RT_VALID_PTR(pPacket))
|
---|
| 376 | {
|
---|
| 377 | pPacket->Hdr.u64Crc = 0;
|
---|
| 378 | pPacket->Hdr.uSessionId = uSessionId;
|
---|
| 379 | pPacket->Hdr.idCmd = CLIP_DATA;
|
---|
| 380 | pPacket->Hdr.cbData = sizeof(vbcl::ipc::clipboard::data_packet_t) + cbData;
|
---|
| 381 | pPacket->cbData = cbData;
|
---|
| 382 |
|
---|
| 383 | memcpy((uint8_t *)pPacket + sizeof(vbcl::ipc::clipboard::data_packet_t), pvData, cbData);
|
---|
| 384 | rc = vbcl::ipc::packet_write(hIpcSession, &pPacket->Hdr);
|
---|
| 385 | RTMemFree(pPacket);
|
---|
| 386 | }
|
---|
| 387 | else
|
---|
| 388 | rc = VERR_NO_MEMORY;
|
---|
| 389 | }
|
---|
| 390 | else
|
---|
| 391 | rc = VERR_TIMEOUT;
|
---|
| 392 |
|
---|
| 393 | VBClLogVerbose(3, "%s: send_data [sid=%u, cbData=%u], rc=%Rrc\n",
|
---|
| 394 | m_fServer ? "server" : "client", uSessionId, cbData, rc);
|
---|
| 395 |
|
---|
| 396 | return rc;
|
---|
| 397 | }
|
---|
| 398 |
|
---|
| 399 | int vbcl::ipc::clipboard::ClipboardIpc::recv_data(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 400 | {
|
---|
| 401 | int rc;
|
---|
| 402 | vbcl::ipc::clipboard::data_packet_t *pPacket;
|
---|
| 403 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 404 | uint32_t cbData = 0;
|
---|
| 405 |
|
---|
| 406 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 407 | if (RT_SUCCESS(rc))
|
---|
| 408 | {
|
---|
| 409 | if ( pPacket->Hdr.idCmd == CLIP_DATA
|
---|
| 410 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 411 | {
|
---|
| 412 | void *pvData = RTMemAllocZ(pPacket->cbData);
|
---|
| 413 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 414 | if (RT_VALID_PTR(pvData))
|
---|
| 415 | {
|
---|
| 416 | memcpy(pvData, (uint8_t *)pPacket + sizeof(vbcl::ipc::clipboard::data_packet_t), pPacket->cbData);
|
---|
| 417 | m_pvClipboardBuf.set((uint64_t)pvData);
|
---|
| 418 | cbData = pPacket->cbData;
|
---|
| 419 | m_cbClipboardBuf.set(cbData);
|
---|
| 420 | }
|
---|
| 421 | else
|
---|
| 422 | rc = VERR_NO_MEMORY;
|
---|
| 423 | }
|
---|
| 424 | else
|
---|
| 425 | rc = VERR_WRONG_ORDER;
|
---|
| 426 |
|
---|
| 427 | RTMemFree(pPacket);
|
---|
| 428 | }
|
---|
| 429 |
|
---|
| 430 | VBClLogVerbose(3, "%s: recv_data [sid=%u, cmd=0x%x, cbData=%u], rc=%Rrc\n",
|
---|
| 431 | m_fServer ? "server" : "client", uSessionId, idCmd, cbData, rc);
|
---|
| 432 |
|
---|
| 433 | return rc;
|
---|
| 434 | }
|
---|