[101878] | 1 | /* $Id: wayland-helper-ipc.cpp 101878 2023-11-06 15:36:24Z 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 | size_t cbRead;
|
---|
| 156 |
|
---|
| 157 | AssertPtrReturn(ppvData, VERR_INVALID_PARAMETER);
|
---|
| 158 |
|
---|
| 159 | rc = RTLocalIpcSessionWaitForData(hSession, VBOX_GTKIPC_RX_TIMEOUT_MS);
|
---|
| 160 | if (RT_SUCCESS(rc))
|
---|
| 161 | {
|
---|
| 162 | /* Read IPC message header. */
|
---|
| 163 | rc = RTLocalIpcSessionRead(hSession, &Packet, sizeof(Packet), &cbRead);
|
---|
| 164 | if (RT_SUCCESS(rc))
|
---|
| 165 | {
|
---|
| 166 | if (cbRead == sizeof(Packet))
|
---|
| 167 | {
|
---|
| 168 | bool fCheck = true;
|
---|
| 169 |
|
---|
| 170 | #define _CHECK(_cond, _msg, _ptr) \
|
---|
| 171 | if (fCheck) \
|
---|
| 172 | { \
|
---|
| 173 | fCheck &= _cond; \
|
---|
| 174 | if (!fCheck) \
|
---|
| 175 | VBClLogVerbose(3, _msg "\n", _ptr); \
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | _CHECK(Packet.u64Crc > 0, "bad crc: 0x%x", Packet.u64Crc);
|
---|
| 179 | _CHECK(Packet.uSessionId == uSessionId, "bad session id: %u vs %u", (Packet.uSessionId, uSessionId));
|
---|
| 180 | _CHECK(Packet.cbData > sizeof(Packet), "bad cbData: %u", Packet.cbData);
|
---|
| 181 |
|
---|
| 182 | /* Receive the rest of a message. */
|
---|
| 183 | if (fCheck)
|
---|
| 184 | {
|
---|
| 185 | uint8_t *puData;
|
---|
| 186 |
|
---|
| 187 | puData = (uint8_t *)RTMemAllocZ(Packet.cbData);
|
---|
| 188 | if (RT_VALID_PTR(puData))
|
---|
| 189 | {
|
---|
| 190 | /* Add generic header to the beginning of the output buffer
|
---|
| 191 | * and receive the rest of the data into it. */
|
---|
| 192 | memcpy(puData, &Packet, sizeof(Packet));
|
---|
| 193 |
|
---|
| 194 | rc = RTLocalIpcSessionRead(hSession, puData + sizeof(Packet),
|
---|
| 195 | Packet.cbData - sizeof(Packet), &cbRead);
|
---|
| 196 | if (RT_SUCCESS(rc))
|
---|
| 197 | {
|
---|
| 198 | if (cbRead == (Packet.cbData - sizeof(Packet)))
|
---|
| 199 | {
|
---|
| 200 | if (vbcl::ipc::packet_verify((vbcl::ipc::packet_t *)puData, Packet.cbData))
|
---|
| 201 | {
|
---|
| 202 | /* Now return received data to the caller. */
|
---|
| 203 | *ppvData = puData;
|
---|
| 204 | }
|
---|
| 205 | else
|
---|
| 206 | rc = VERR_NOT_EQUAL;
|
---|
| 207 | }
|
---|
| 208 | else
|
---|
| 209 | rc = VERR_BUFFER_UNDERFLOW;
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | if (RT_FAILURE(rc))
|
---|
| 213 | RTMemFree(puData);
|
---|
| 214 | }
|
---|
| 215 | else
|
---|
| 216 | rc = VERR_NO_MEMORY;
|
---|
| 217 | }
|
---|
| 218 | else
|
---|
| 219 | rc = VERR_INVALID_PARAMETER;
|
---|
| 220 | }
|
---|
| 221 |
|
---|
| 222 | if (RT_FAILURE(rc))
|
---|
| 223 | vbcl::ipc::packet_dump(&Packet);
|
---|
| 224 | }
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 | return rc;
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | int vbcl::ipc::packet_write(RTLOCALIPCSESSION hSession, vbcl::ipc::packet_t *pPacket)
|
---|
| 231 | {
|
---|
| 232 | int rc;
|
---|
| 233 |
|
---|
| 234 | AssertPtrReturn(pPacket, VERR_INVALID_PARAMETER);
|
---|
| 235 |
|
---|
| 236 | pPacket->u64Crc = 0;
|
---|
| 237 | pPacket->u64Crc = RTCrc64(pPacket, pPacket->cbData);
|
---|
| 238 |
|
---|
| 239 | Assert(pPacket->u64Crc);
|
---|
| 240 |
|
---|
| 241 | if (vbcl::ipc::packet_verify(pPacket, pPacket->cbData))
|
---|
| 242 | {
|
---|
| 243 | rc = RTLocalIpcSessionWrite(hSession, (void *)pPacket, pPacket->cbData);
|
---|
| 244 | if (RT_SUCCESS(rc))
|
---|
| 245 | rc = RTLocalIpcSessionFlush(hSession);
|
---|
| 246 | }
|
---|
| 247 | else
|
---|
| 248 | {
|
---|
| 249 | vbcl::ipc::packet_dump(pPacket);
|
---|
| 250 | rc = VERR_NOT_EQUAL;
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | return rc;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | int vbcl::ipc::clipboard::ClipboardIpc::send_formats(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 257 | {
|
---|
| 258 | vbcl::ipc::clipboard::formats_packet_t Packet;
|
---|
| 259 | SHCLFORMATS fFormats;
|
---|
| 260 | int rc = VINF_SUCCESS;
|
---|
| 261 |
|
---|
| 262 | RT_ZERO(Packet);
|
---|
| 263 |
|
---|
| 264 | Packet.Hdr.u64Crc = 0;
|
---|
| 265 | Packet.Hdr.uSessionId = uSessionId;
|
---|
| 266 | Packet.Hdr.idCmd = CLIP_FORMATS;
|
---|
| 267 | Packet.Hdr.cbData = sizeof(Packet);
|
---|
| 268 |
|
---|
| 269 | fFormats = m_fFmts.wait();
|
---|
| 270 | if (fFormats != m_fFmts.defaults())
|
---|
| 271 | {
|
---|
| 272 | Packet.fFormats = fFormats;
|
---|
| 273 | rc = vbcl::ipc::packet_write(hIpcSession, &Packet.Hdr);
|
---|
| 274 | }
|
---|
| 275 | else
|
---|
| 276 | rc = VERR_TIMEOUT;
|
---|
| 277 |
|
---|
| 278 | VBClLogVerbose(3, "%s: send_formats [sid=%u, fmts=0x%x], rc=%Rrc\n",
|
---|
| 279 | m_fServer ? "server" : "client", uSessionId, fFormats, rc);
|
---|
| 280 |
|
---|
| 281 | return rc;
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | int vbcl::ipc::clipboard::ClipboardIpc::recv_formats(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 285 | {
|
---|
| 286 | int rc;
|
---|
| 287 | vbcl::ipc::clipboard::formats_packet_t *pPacket;
|
---|
| 288 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 289 | SHCLFORMATS fFormats = VBOX_SHCL_FMT_NONE;
|
---|
| 290 |
|
---|
| 291 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 292 | if (RT_SUCCESS(rc))
|
---|
| 293 | {
|
---|
| 294 | if ( pPacket->Hdr.idCmd == CLIP_FORMATS
|
---|
| 295 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 296 | {
|
---|
| 297 | fFormats = pPacket->fFormats;
|
---|
| 298 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 299 | m_fFmts.set(fFormats);
|
---|
| 300 | }
|
---|
| 301 | else
|
---|
| 302 | rc = VERR_WRONG_ORDER;
|
---|
| 303 |
|
---|
| 304 | RTMemFree(pPacket);
|
---|
| 305 | }
|
---|
| 306 |
|
---|
| 307 | VBClLogVerbose(3, "%s: recv_formats [sid=%u, cmd=0x%x, fmts=0x%x], rc=%Rrc\n",
|
---|
| 308 | m_fServer ? "server" : "client", uSessionId, idCmd, fFormats, rc);
|
---|
| 309 |
|
---|
| 310 | return rc;
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | int vbcl::ipc::clipboard::ClipboardIpc::send_format(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 314 | {
|
---|
| 315 | vbcl::ipc::clipboard::formats_packet_t Packet;
|
---|
| 316 | SHCLFORMAT uFormat;
|
---|
| 317 | int rc = VINF_SUCCESS;
|
---|
| 318 |
|
---|
| 319 | RT_ZERO(Packet);
|
---|
| 320 |
|
---|
| 321 | Packet.Hdr.u64Crc = 0;
|
---|
| 322 | Packet.Hdr.uSessionId = uSessionId;
|
---|
| 323 | Packet.Hdr.idCmd = CLIP_FORMAT;
|
---|
| 324 | Packet.Hdr.cbData = sizeof(Packet);
|
---|
| 325 |
|
---|
| 326 | uFormat = m_uFmt.wait();
|
---|
| 327 | if (uFormat != m_uFmt.defaults())
|
---|
| 328 | {
|
---|
| 329 | Packet.fFormats = uFormat;
|
---|
| 330 | rc = vbcl::ipc::packet_write(hIpcSession, &Packet.Hdr);
|
---|
| 331 | }
|
---|
| 332 | else
|
---|
| 333 | rc = VERR_TIMEOUT;
|
---|
| 334 |
|
---|
| 335 | VBClLogVerbose(3, "%s: send_format [sid=%u, fmt=0x%x], rc=%Rrc\n",
|
---|
| 336 | m_fServer ? "server" : "client", uSessionId, uFormat, rc);
|
---|
| 337 |
|
---|
| 338 | return rc;
|
---|
| 339 | }
|
---|
| 340 |
|
---|
| 341 | int vbcl::ipc::clipboard::ClipboardIpc::recv_format(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 342 | {
|
---|
| 343 | int rc;
|
---|
| 344 | vbcl::ipc::clipboard::formats_packet_t *pPacket;
|
---|
| 345 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 346 | SHCLFORMATS uFormat = VBOX_SHCL_FMT_NONE;
|
---|
| 347 |
|
---|
| 348 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 349 | if (RT_SUCCESS(rc))
|
---|
| 350 | {
|
---|
| 351 | if ( pPacket->Hdr.idCmd == CLIP_FORMAT
|
---|
| 352 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 353 | {
|
---|
| 354 | uFormat = pPacket->fFormats;
|
---|
| 355 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 356 | m_uFmt.set(uFormat);
|
---|
| 357 | }
|
---|
| 358 | else
|
---|
| 359 | rc = VERR_WRONG_ORDER;
|
---|
| 360 |
|
---|
| 361 | RTMemFree(pPacket);
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | VBClLogVerbose(3, "%s: recv_format [sid=%u, cmd=0x%x, fmts=0x%x], rc=%Rrc\n",
|
---|
| 365 | m_fServer ? "server" : "client", uSessionId, idCmd, uFormat, rc);
|
---|
| 366 |
|
---|
| 367 | return rc;
|
---|
| 368 | }
|
---|
| 369 |
|
---|
| 370 | int vbcl::ipc::clipboard::ClipboardIpc::send_data(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 371 | {
|
---|
| 372 | vbcl::ipc::clipboard::data_packet_t *pPacket;
|
---|
| 373 | int rc = VINF_SUCCESS;
|
---|
| 374 |
|
---|
| 375 | void *pvData;
|
---|
| 376 | uint32_t cbData;
|
---|
| 377 |
|
---|
| 378 | cbData = m_cbClipboardBuf.wait();
|
---|
| 379 | pvData = (void *)m_pvClipboardBuf.wait();
|
---|
| 380 | if ( cbData != m_cbClipboardBuf.defaults()
|
---|
| 381 | && pvData != (void *)m_pvClipboardBuf.defaults())
|
---|
| 382 | {
|
---|
| 383 | pPacket = (vbcl::ipc::clipboard::data_packet_t *)RTMemAllocZ(sizeof(vbcl::ipc::clipboard::data_packet_t) + cbData);
|
---|
| 384 | if (RT_VALID_PTR(pPacket))
|
---|
| 385 | {
|
---|
| 386 | pPacket->Hdr.u64Crc = 0;
|
---|
| 387 | pPacket->Hdr.uSessionId = uSessionId;
|
---|
| 388 | pPacket->Hdr.idCmd = CLIP_DATA;
|
---|
| 389 | pPacket->Hdr.cbData = sizeof(vbcl::ipc::clipboard::data_packet_t) + cbData;
|
---|
| 390 | pPacket->cbData = cbData;
|
---|
| 391 |
|
---|
| 392 | memcpy((uint8_t *)pPacket + sizeof(vbcl::ipc::clipboard::data_packet_t), pvData, cbData);
|
---|
| 393 | rc = vbcl::ipc::packet_write(hIpcSession, &pPacket->Hdr);
|
---|
| 394 | RTMemFree(pPacket);
|
---|
| 395 | }
|
---|
| 396 | else
|
---|
| 397 | rc = VERR_NO_MEMORY;
|
---|
| 398 | }
|
---|
| 399 | else
|
---|
| 400 | rc = VERR_TIMEOUT;
|
---|
| 401 |
|
---|
| 402 | VBClLogVerbose(3, "%s: send_data [sid=%u, cbData=%u], rc=%Rrc\n",
|
---|
| 403 | m_fServer ? "server" : "client", uSessionId, cbData, rc);
|
---|
| 404 |
|
---|
| 405 | return rc;
|
---|
| 406 | }
|
---|
| 407 |
|
---|
| 408 | int vbcl::ipc::clipboard::ClipboardIpc::recv_data(uint32_t uSessionId, RTLOCALIPCSESSION hIpcSession)
|
---|
| 409 | {
|
---|
| 410 | int rc;
|
---|
| 411 | vbcl::ipc::clipboard::data_packet_t *pPacket;
|
---|
| 412 | vbcl::ipc::command_t idCmd = CMD_UNKNOWN;
|
---|
| 413 | uint32_t cbData = 0;
|
---|
| 414 |
|
---|
| 415 | rc = vbcl::ipc::packet_read(uSessionId, hIpcSession, (void **)&pPacket);
|
---|
| 416 | if (RT_SUCCESS(rc))
|
---|
| 417 | {
|
---|
| 418 | if ( pPacket->Hdr.idCmd == CLIP_DATA
|
---|
| 419 | && vbcl::ipc::packet_verify(&pPacket->Hdr, pPacket->Hdr.cbData))
|
---|
| 420 | {
|
---|
| 421 | void *pvData = RTMemAllocZ(pPacket->cbData);
|
---|
| 422 | idCmd = pPacket->Hdr.idCmd;
|
---|
| 423 | if (RT_VALID_PTR(pvData))
|
---|
| 424 | {
|
---|
| 425 | memcpy(pvData, (uint8_t *)pPacket + sizeof(vbcl::ipc::clipboard::data_packet_t), pPacket->cbData);
|
---|
| 426 | m_pvClipboardBuf.set((uint64_t)pvData);
|
---|
| 427 | cbData = pPacket->cbData;
|
---|
| 428 | m_cbClipboardBuf.set(cbData);
|
---|
| 429 | }
|
---|
| 430 | else
|
---|
| 431 | rc = VERR_NO_MEMORY;
|
---|
| 432 | }
|
---|
| 433 | else
|
---|
| 434 | rc = VERR_WRONG_ORDER;
|
---|
| 435 |
|
---|
| 436 | RTMemFree(pPacket);
|
---|
| 437 | }
|
---|
| 438 |
|
---|
| 439 | VBClLogVerbose(3, "%s: recv_data [sid=%u, cmd=0x%x, cbData=%u], rc=%Rrc\n",
|
---|
| 440 | m_fServer ? "server" : "client", uSessionId, idCmd, cbData, rc);
|
---|
| 441 |
|
---|
| 442 | return rc;
|
---|
| 443 | }
|
---|