Changeset 79027 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Jun 6, 2019 2:47:16 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp
r78946 r79027 165 165 * @param pDataHdr Where to store the read meta data header. 166 166 */ 167 static int vbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr)167 VBGLR3DECL(int) VbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr) 168 168 { 169 169 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); … … 206 206 207 207 /** 208 * Sends a guest clipboard data header to the host. 209 * 210 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_WRITE_DATA_HDR message 211 * from the host. 212 * 213 * @returns VBox status code. 214 * @param idClient The client id returned by VbglR3ClipboardConnect(). 215 * @param pDataHdr Pointer to data header to send. 216 */ 217 VBGLR3DECL(int) VbglR3ClipboardWriteDataHdr(HGCMCLIENTID idClient, const PVBOXCLIPBOARDDATAHDR pDataHdr) 218 { 219 VBoxClipboardWriteDataHdrMsg Msg; 220 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR); 221 222 VbglHGCMParmUInt32Set(&Msg.uFlags, pDataHdr->uFlags); /** @todo Not used yet. */ 223 VbglHGCMParmUInt32Set(&Msg.uScreenId, pDataHdr->uScreenId); /** @todo Not used for guest->host (yet). */ 224 VbglHGCMParmUInt64Set(&Msg.cbTotal, pDataHdr->cbTotal); 225 VbglHGCMParmUInt32Set(&Msg.cbMeta, pDataHdr->cbMeta); 226 VbglHGCMParmPtrSet(&Msg.cbMetaFmt, pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt); 227 VbglHGCMParmUInt32Set(&Msg.cbMetaFmt, pDataHdr->cbMetaFmt); 228 VbglHGCMParmUInt64Set(&Msg.cObjects, pDataHdr->cObjects); 229 VbglHGCMParmUInt32Set(&Msg.enmCompression, pDataHdr->enmCompression); /** @todo Not used yet. */ 230 VbglHGCMParmUInt32Set(&Msg.enmChecksumType, pDataHdr->enmChecksumType); /** @todo Not used yet. */ 231 VbglHGCMParmPtrSet(&Msg.cbChecksum, pDataHdr->pvChecksum, pDataHdr->cbChecksum); /** @todo Not used yet. */ 232 VbglHGCMParmUInt32Set(&Msg.cbChecksum, pDataHdr->cbChecksum); /** @todo Not used yet. */ 233 234 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 235 } 236 237 /** 208 238 * Reads a (meta) data chunk from the host. 209 239 * … … 261 291 * @returns IPRT status code. 262 292 * @param idClient The client id returned by VbglR3ClipboardConnect(). 263 * @param pDataHdr Where to store the data header data. 264 * @param pMetaData Returns the received meta data. Needs to be free'd by the caller. 293 * @param pDataHdr Pointer to data header to use. 294 * @param pvMeta Where to store the received meta data. 295 * @param cbMeta Size (in bytes) of meta data buffer. 296 * @param pcbRead How much bytes were read on success. Optional. 265 297 */ 266 298 static int vbglR3ClipboardReadMetaDataLoop(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr, 267 PSHAREDCLIPBOARDMETADATA pMetaData) 268 { 269 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); 270 AssertPtrReturn(pMetaData, VERR_INVALID_POINTER); 271 272 int rc; 273 uint32_t cbDataRecv; 299 void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead) 300 { 301 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); 302 AssertPtrReturn(pvMeta, VERR_INVALID_POINTER); 274 303 275 304 LogFlowFuncEnter(); 276 305 277 rc = vbglR3ClipboardReadDataHdr(idClient, pDataHdr);278 if (RT_FAILURE(rc)) 279 return rc;306 int rc = VINF_SUCCESS; 307 308 uint32_t cbReadTotal = 0; 280 309 281 310 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects)); 282 311 if (pDataHdr->cbMeta) 283 312 { 284 uint64_t cbDataTmp = 0; 285 void *pvDataTmp = RTMemAlloc(pDataHdr->cbMeta); 286 if (!pvDataTmp) 287 rc = VERR_NO_MEMORY; 288 289 if (RT_SUCCESS(rc)) 313 uint32_t cbToRead = RT_MIN(cbMeta, pDataHdr->cbMeta); 314 while (cbToRead) 290 315 { 291 const uint32_t cbMaxChunkSize = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE; 292 293 uint8_t *pvDataOff = (uint8_t *)pvDataTmp; 294 while (cbDataTmp < pDataHdr->cbMeta) 295 { 296 rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr, 297 pvDataOff, RT_MIN(pDataHdr->cbMeta - cbDataTmp, cbMaxChunkSize), 298 &cbDataRecv); 299 if (RT_SUCCESS(rc)) 300 { 301 LogFlowFunc(("cbDataRecv=%RU32, cbDataTmp=%RU64\n", cbDataRecv, cbDataTmp)); 302 Assert(cbDataTmp + cbDataRecv <= pDataHdr->cbMeta); 303 cbDataTmp += cbDataRecv; 304 pvDataOff += cbDataRecv; 305 } 306 else 307 break; 308 } 309 310 if (RT_SUCCESS(rc)) 311 { 312 Assert(cbDataTmp == pDataHdr->cbMeta); 313 314 LogFlowFunc(("Received %RU64 bytes of data\n", cbDataTmp)); 315 316 pMetaData->pvMeta = pvDataTmp; 317 pMetaData->cbMeta = cbDataTmp; 318 pMetaData->cbUsed = cbDataTmp; 319 } 320 else 321 RTMemFree(pvDataTmp); 316 uint32_t cbRead; 317 rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr, 318 (uint8_t *)pvMeta + cbReadTotal, cbToRead, &cbRead); 319 if (RT_FAILURE(rc)) 320 break; 321 322 Assert(cbToRead >= cbRead); 323 cbToRead -= cbRead; 324 325 cbReadTotal += cbRead; 322 326 } 323 327 } 324 else 325 SharedClipboardMetaDataDestroy(pMetaData); 328 329 if (RT_SUCCESS(rc)) 330 { 331 if (pcbRead) 332 *pcbRead = cbReadTotal; 333 } 326 334 327 335 LogFlowFuncLeaveRC(rc); … … 334 342 * @returns IPRT status code. 335 343 * @param idClient The client id returned by VbglR3ClipboardConnect(). 336 * @param URIList Where to store received meta data. 337 */ 338 static int vbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, SharedClipboardURIList &URIList) 339 { 340 /* The rest is optional. */ 341 342 VBOXCLIPBOARDDATAHDR dataHdr; 343 RT_ZERO(dataHdr); 344 345 dataHdr.cbMetaFmt = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE; 346 dataHdr.pvMetaFmt = RTMemAlloc(dataHdr.cbMetaFmt); 347 if (!dataHdr.pvMetaFmt) 348 return VERR_NO_MEMORY; 349 350 SHAREDCLIPBOARDMETADATA dataMeta; 351 SharedClipboardMetaDataInit(&dataMeta); 352 353 int rc = vbglR3ClipboardReadMetaDataLoop(idClient, &dataHdr, &dataMeta); 354 if (RT_SUCCESS(rc)) 355 { 356 /** 357 * Check if this is an URI event. If so, let VbglR3 do all the actual 358 * data transfer + file/directory creation internally without letting 359 * the caller know. 360 * 361 * This keeps the actual (guest OS-)dependent client (like VBoxClient / 362 * VBoxTray) small by not having too much redundant code. 363 */ 364 Assert(dataHdr.cbMetaFmt); 365 AssertPtr(dataHdr.pvMetaFmt); 366 if (SharedClipboardMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) /* URI data. */ 367 { 368 rc = URIList.SetFromURIData(dataMeta.pvMeta, dataMeta.cbMeta, 0 /* fFlags */); 369 370 #if 0 371 if (RT_SUCCESS(rc)) 372 rc = vbglR3ClipboardReadURIData(idClient, &dataHdr); 373 374 if (RT_SUCCESS(rc)) 375 { 376 if (pvData) 377 { 378 /* Reuse data buffer to fill in the transformed URI file list. */ 379 RTMemFree(pvData); 380 pvData = NULL; 381 } 382 383 #if 0 384 RTCString strData = lstURI.GetRootEntries(clipboardCache.GetDirAbs()); 385 Assert(!strData.isEmpty()); 386 387 cbData = strData.length() + 1; 388 LogFlowFunc(("URI list has %zu bytes\n", cbData)); 389 390 pvData = RTMemAlloc(cbData); 391 if (pvData) 392 { 393 memcpy(pvData, strData.c_str(), cbData); 394 } 395 else 396 rc = VERR_NO_MEMORY; 397 #endif 398 } 399 #endif 400 } 401 else /* Raw data. */ 402 { 403 /** @todo Implement this. */ 404 } 405 406 SharedClipboardMetaDataDestroy(&dataMeta); 407 } 408 409 if (dataHdr.pvMetaFmt) 410 { 411 RTMemFree(dataHdr.pvMetaFmt); 412 dataHdr.pvMetaFmt = NULL; 413 } 344 * @param pDataHdr Pointer to data header to use. 345 * @param pvMeta Where to store the received meta data. 346 * @param cbMeta Size (in bytes) of meta data buffer. 347 * @param pcbRead How much bytes were read on success. Optional. 348 */ 349 static int vbglR3ClipboardReadMetaDataInternal(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr, 350 void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead) 351 { 352 LogFlowFuncEnter(); 353 354 int rc = vbglR3ClipboardReadMetaDataLoop(idClient, pDataHdr, pvMeta, cbMeta, pcbRead); 414 355 415 356 LogFlowFuncLeaveRC(rc); … … 418 359 419 360 /** 361 * Reads the actual meta data from the host, extended version. 362 * 363 * @returns IPRT status code. 364 * @param idClient The client id returned by VbglR3ClipboardConnect(). 365 * @param pvMeta Where to store the received meta data. 366 * @param cbMeta Size (in bytes) of meta data buffer. 367 * @param pcbRead How much bytes were read on success. Optional. 368 */ 369 VBGLR3DECL(int) VbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr, 370 void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead) 371 { 372 return vbglR3ClipboardReadMetaDataInternal(idClient, pDataHdr, pvMeta, cbMeta, pcbRead); 373 } 374 375 /** 420 376 * Reads the actual meta data from the host. 421 377 * 422 378 * @returns IPRT status code. 423 379 * @param idClient The client id returned by VbglR3ClipboardConnect(). 424 * @param URIList Where to store received meta data. 425 */ 426 VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, SharedClipboardURIList &URIList) 427 { 428 return vbglR3ClipboardReadMetaDataEx(idClient, URIList); 429 } 430 431 VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const SharedClipboardURIList &URIList) 432 { 433 RT_NOREF(idClient, URIList); 380 * @param pvMeta Where to store the received meta data. 381 * @param cbMeta Size (in bytes) of meta data buffer. 382 * @param pcbRead How much bytes were read on success. Optional. 383 */ 384 VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr, 385 void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead) 386 { 387 return VbglR3ClipboardReadMetaDataEx(idClient, pDataHdr, pvMeta, cbMeta, pcbRead); 388 } 389 390 /** 391 * Writes the actual meta data to the host, extended version. 392 * 393 * @returns IPRT status code. 394 * @param idClient The client id returned by VbglR3ClipboardConnect(). 395 * @param pvMeta Pointer to meta data buffer. 396 * @param cbMeta Size (in bytes) of meta data buffer. 397 * @param pcbWritten How much bytes were written on success. Optional. 398 */ 399 VBGLR3DECL(int) VbglR3ClipboardWriteMetaDataEx(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten) 400 { 401 RT_NOREF(idClient, pvMeta, cbMeta, pcbWritten); 434 402 return 0; 403 } 404 405 /** 406 * Writes the actual meta data to the host. 407 * 408 * @returns IPRT status code. 409 * @param idClient The client id returned by VbglR3ClipboardConnect(). 410 * @param pvMeta Pointer to meta data buffer. 411 * @param cbMeta Size (in bytes) of meta data buffer. 412 * @param pcbWritten How much bytes were written on success. Optional. 413 */ 414 VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten) 415 { 416 return VbglR3ClipboardWriteMetaDataEx(idClient, pvMeta, cbMeta, pcbWritten); 435 417 } 436 418 … … 688 670 VBoxClipboardWriteFormatsMsg Msg; 689 671 690 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, 1);672 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, VBOX_SHARED_CLIPBOARD_CPARMS_FORMATS); 691 673 VbglHGCMParmUInt32Set(&Msg.formats, fFormats); 692 674 … … 709 691 { 710 692 VBoxClipboardWriteDataMsg Msg; 711 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, 2);693 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA); 712 694 VbglHGCMParmUInt32Set(&Msg.format, fFormat); 713 695 VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
Note:
See TracChangeset
for help on using the changeset viewer.