Changeset 74383 in vbox
- Timestamp:
- Sep 20, 2018 12:21:08 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 125203
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp
r74380 r74383 129 129 VBOXDNDHGACTIONMSG Msg; 130 130 RT_ZERO(Msg); 131 if (pCtx->uProtocol < 3) 132 { 133 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, uMsg, 7); 134 Msg.u.v1.uScreenId.SetUInt32(0); 135 Msg.u.v1.uX.SetUInt32(0); 136 Msg.u.v1.uY.SetUInt32(0); 137 Msg.u.v1.uDefAction.SetUInt32(0); 138 Msg.u.v1.uAllActions.SetUInt32(0); 139 Msg.u.v1.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp); 140 Msg.u.v1.cbFormats.SetUInt32(0); 141 } 142 else 143 { 144 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, uMsg, 8); 145 Msg.u.v3.uContext.SetUInt32(0); 146 Msg.u.v3.uScreenId.SetUInt32(0); 147 Msg.u.v3.uX.SetUInt32(0); 148 Msg.u.v3.uY.SetUInt32(0); 149 Msg.u.v3.uDefAction.SetUInt32(0); 150 Msg.u.v3.uAllActions.SetUInt32(0); 151 Msg.u.v3.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp); 152 Msg.u.v3.cbFormats.SetUInt32(0); 153 } 131 132 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, uMsg, 8); 133 Msg.u.v3.uContext.SetUInt32(0); 134 Msg.u.v3.uScreenId.SetUInt32(0); 135 Msg.u.v3.uX.SetUInt32(0); 136 Msg.u.v3.uY.SetUInt32(0); 137 Msg.u.v3.uDefAction.SetUInt32(0); 138 Msg.u.v3.uAllActions.SetUInt32(0); 139 Msg.u.v3.pvFormats.SetPtr(pszFormatsTmp, cbFormatsTmp); 140 Msg.u.v3.cbFormats.SetUInt32(0); 154 141 155 142 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 156 143 if (RT_SUCCESS(rc)) 157 144 { 158 if (pCtx->uProtocol < 3) 159 { 160 if (puScreenID) 161 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenID); 162 if (RT_SUCCESS(rc) && puX) 163 rc = Msg.u.v1.uX.GetUInt32(puX); 164 if (RT_SUCCESS(rc) && puY) 165 rc = Msg.u.v1.uY.GetUInt32(puY); 166 if (RT_SUCCESS(rc) && puDefAction) 167 rc = Msg.u.v1.uDefAction.GetUInt32(puDefAction); 168 if (RT_SUCCESS(rc) && puAllActions) 169 rc = Msg.u.v1.uAllActions.GetUInt32(puAllActions); 170 if (RT_SUCCESS(rc) && pcbFormats) 171 rc = Msg.u.v1.cbFormats.GetUInt32(pcbFormats); 172 } 173 else 174 { 175 /** @todo Context ID not used yet. */ 176 if (RT_SUCCESS(rc) && puScreenID) 177 rc = Msg.u.v3.uScreenId.GetUInt32(puScreenID); 178 if (RT_SUCCESS(rc) && puX) 179 rc = Msg.u.v3.uX.GetUInt32(puX); 180 if (RT_SUCCESS(rc) && puY) 181 rc = Msg.u.v3.uY.GetUInt32(puY); 182 if (RT_SUCCESS(rc) && puDefAction) 183 rc = Msg.u.v3.uDefAction.GetUInt32(puDefAction); 184 if (RT_SUCCESS(rc) && puAllActions) 185 rc = Msg.u.v3.uAllActions.GetUInt32(puAllActions); 186 if (RT_SUCCESS(rc) && pcbFormats) 187 rc = Msg.u.v3.cbFormats.GetUInt32(pcbFormats); 188 } 145 /** @todo Context ID not used yet. */ 146 if (RT_SUCCESS(rc) && puScreenID) 147 rc = Msg.u.v3.uScreenId.GetUInt32(puScreenID); 148 if (RT_SUCCESS(rc) && puX) 149 rc = Msg.u.v3.uX.GetUInt32(puX); 150 if (RT_SUCCESS(rc) && puY) 151 rc = Msg.u.v3.uY.GetUInt32(puY); 152 if (RT_SUCCESS(rc) && puDefAction) 153 rc = Msg.u.v3.uDefAction.GetUInt32(puDefAction); 154 if (RT_SUCCESS(rc) && puAllActions) 155 rc = Msg.u.v3.uAllActions.GetUInt32(puAllActions); 156 if (RT_SUCCESS(rc) && pcbFormats) 157 rc = Msg.u.v3.cbFormats.GetUInt32(pcbFormats); 189 158 190 159 if (RT_SUCCESS(rc)) … … 217 186 VBOXDNDHGLEAVEMSG Msg; 218 187 RT_ZERO(Msg); 219 if (pCtx->uProtocol < 3) 220 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_LEAVE, 0); 221 else 222 { 223 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_LEAVE, 1); 224 /** @todo Context ID not used yet. */ 225 Msg.u.v3.uContext.SetUInt32(0); 226 } 188 189 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_LEAVE, 1); 190 /** @todo Context ID not used yet. */ 191 Msg.u.v3.uContext.SetUInt32(0); 227 192 228 193 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 242 207 VBOXDNDHGCANCELMSG Msg; 243 208 RT_ZERO(Msg); 244 if (pCtx->uProtocol < 3) 245 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_CANCEL, 0); 246 else 247 { 248 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_CANCEL, 1); 249 /** @todo Context ID not used yet. */ 250 Msg.u.v3.uContext.SetUInt32(0); 251 } 209 210 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_EVT_CANCEL, 1); 211 /** @todo Context ID not used yet. */ 212 Msg.u.v3.uContext.SetUInt32(0); 252 213 253 214 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 279 240 VBOXDNDHGSENDDIRMSG Msg; 280 241 RT_ZERO(Msg); 281 if (pCtx->uProtocol < 3) 282 { 283 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DIR, 3); 284 Msg.u.v1.pvName.SetPtr(pszDirname, cbDirname); 285 Msg.u.v1.cbName.SetUInt32(cbDirname); 286 Msg.u.v1.fMode.SetUInt32(0); 287 } 288 else 289 { 290 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DIR, 4); 291 /** @todo Context ID not used yet. */ 292 Msg.u.v3.uContext.SetUInt32(0); 293 Msg.u.v3.pvName.SetPtr(pszDirname, cbDirname); 294 Msg.u.v3.cbName.SetUInt32(cbDirname); 295 Msg.u.v3.fMode.SetUInt32(0); 296 } 242 243 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DIR, 4); 244 /** @todo Context ID not used yet. */ 245 Msg.u.v3.uContext.SetUInt32(0); 246 Msg.u.v3.pvName.SetPtr(pszDirname, cbDirname); 247 Msg.u.v3.cbName.SetUInt32(cbDirname); 248 Msg.u.v3.fMode.SetUInt32(0); 297 249 298 250 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 299 251 if (RT_SUCCESS(rc)) 300 252 { 301 if (pCtx->uProtocol < 3) 302 { 303 rc = Msg.u.v1.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc); 304 rc = Msg.u.v1.fMode.GetUInt32(pfMode); AssertRC(rc); 305 } 306 else 307 { 308 /** @todo Context ID not used yet. */ 309 rc = Msg.u.v3.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc); 310 rc = Msg.u.v3.fMode.GetUInt32(pfMode); AssertRC(rc); 311 } 253 /** @todo Context ID not used yet. */ 254 rc = Msg.u.v3.cbName.GetUInt32(pcbDirnameRecv); AssertRC(rc); 255 rc = Msg.u.v3.fMode.GetUInt32(pfMode); AssertRC(rc); 312 256 313 257 AssertReturn(cbDirname >= *pcbDirnameRecv, VERR_TOO_MUCH_DATA); … … 323 267 * @returns IPRT status code. 324 268 * @param pCtx DnD context to use. 325 * @param pszFilename Where to store the file name of the file being transferred.326 * Only needed for protocol v1.327 * @param cbFilename Size (in bytes) of where to store the file name of the file being transferred.328 * Only needed for protocol v1.329 * @param pcbFilenameRev Size (in bytes) of the actual file name received.330 * Only needed for protocol v1.331 269 * @param pvData Where to store the file data chunk. 332 270 * @param cbData Size (in bytes) of where to store the data chunk. 333 271 * @param pcbDataRecv Size (in bytes) of the actual data chunk size received. 334 * @param pfMode Where to store the file creation mode.335 * Only needed for protocol v1.336 272 */ 337 273 static int vbglR3DnDHGRecvFileData(PVBGLR3GUESTDNDCMDCTX pCtx, 338 char *pszFilename,339 uint32_t cbFilename,340 uint32_t *pcbFilenameRecv,341 274 void *pvData, 342 275 uint32_t cbData, 343 uint32_t *pcbDataRecv, 344 uint32_t *pfMode) 276 uint32_t *pcbDataRecv) 345 277 { 346 278 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 347 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);348 AssertReturn(cbFilename, VERR_INVALID_PARAMETER);349 AssertPtrReturn(pcbFilenameRecv, VERR_INVALID_POINTER);350 279 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 351 280 AssertReturn(cbData, VERR_INVALID_PARAMETER); 352 281 AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER); 353 AssertPtrReturn(pfMode, VERR_INVALID_POINTER);354 282 355 283 VBOXDNDHGSENDFILEDATAMSG Msg; 356 284 RT_ZERO(Msg); 357 if (pCtx->uProtocol <= 1) 358 { 359 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_DATA, 5); 360 Msg.u.v1.pvName.SetPtr(pszFilename, cbFilename); 361 Msg.u.v1.cbName.SetUInt32(0); 362 Msg.u.v1.pvData.SetPtr(pvData, cbData); 363 Msg.u.v1.cbData.SetUInt32(0); 364 Msg.u.v1.fMode.SetUInt32(0); 365 } 366 else if (pCtx->uProtocol == 2) 367 { 368 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_DATA, 3); 369 Msg.u.v2.uContext.SetUInt32(0); 370 Msg.u.v2.pvData.SetPtr(pvData, cbData); 371 Msg.u.v2.cbData.SetUInt32(cbData); 372 } 373 else if (pCtx->uProtocol >= 3) 374 { 375 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_DATA, 5); 376 Msg.u.v3.uContext.SetUInt32(0); 377 Msg.u.v3.pvData.SetPtr(pvData, cbData); 378 Msg.u.v3.cbData.SetUInt32(0); 379 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 380 Msg.u.v3.cbChecksum.SetUInt32(0); 381 } 382 else 383 AssertMsgFailed(("Protocol %RU32 not implemented\n", pCtx->uProtocol)); 285 286 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_DATA, 5); 287 Msg.u.v3.uContext.SetUInt32(0); 288 Msg.u.v3.pvData.SetPtr(pvData, cbData); 289 Msg.u.v3.cbData.SetUInt32(0); 290 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 291 Msg.u.v3.cbChecksum.SetUInt32(0); 384 292 385 293 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 386 294 if (RT_SUCCESS(rc)) 387 295 { 388 if (pCtx->uProtocol <= 1) 389 { 390 rc = Msg.u.v1.cbName.GetUInt32(pcbFilenameRecv); AssertRC(rc); 391 rc = Msg.u.v1.cbData.GetUInt32(pcbDataRecv); AssertRC(rc); 392 rc = Msg.u.v1.fMode.GetUInt32(pfMode); AssertRC(rc); 393 394 AssertReturn(cbFilename >= *pcbFilenameRecv, VERR_TOO_MUCH_DATA); 395 AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); 396 } 397 else if (pCtx->uProtocol == 2) 398 { 399 /** @todo Context ID not used yet. */ 400 rc = Msg.u.v2.cbData.GetUInt32(pcbDataRecv); AssertRC(rc); 401 AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); 402 } 403 else if (pCtx->uProtocol >= 3) 404 { 405 /** @todo Context ID not used yet. */ 406 rc = Msg.u.v3.cbData.GetUInt32(pcbDataRecv); AssertRC(rc); 407 AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); 408 /** @todo Add checksum support. */ 409 } 410 else 411 AssertMsgFailed(("Protocol %RU32 not implemented\n", pCtx->uProtocol)); 296 /** @todo Context ID not used yet. */ 297 rc = Msg.u.v3.cbData.GetUInt32(pcbDataRecv); AssertRC(rc); 298 AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA); 299 /** @todo Add checksum support. */ 412 300 } 413 301 … … 443 331 VBOXDNDHGSENDFILEHDRMSG Msg; 444 332 RT_ZERO(Msg); 445 int rc; 446 if (pCtx->uProtocol <= 1) 447 rc = VERR_NOT_SUPPORTED; 448 else 449 { 450 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_HDR, 6); 451 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */ 452 Msg.pvName.SetPtr(pszFilename, cbFilename); 453 Msg.cbName.SetUInt32(cbFilename); 454 Msg.uFlags.SetUInt32(0); 455 Msg.fMode.SetUInt32(0); 456 Msg.cbTotal.SetUInt64(0); 457 458 rc = VINF_SUCCESS; 459 } 460 461 if (RT_SUCCESS(rc)) 462 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 333 334 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_FILE_HDR, 6); 335 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */ 336 Msg.pvName.SetPtr(pszFilename, cbFilename); 337 Msg.cbName.SetUInt32(cbFilename); 338 Msg.uFlags.SetUInt32(0); 339 Msg.fMode.SetUInt32(0); 340 Msg.cbTotal.SetUInt64(0); 341 342 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 463 343 if (RT_SUCCESS(rc)) 464 344 { … … 496 376 cbToRecvBytes, cToRecvObjs, pDataHdr->cbTotal, pDataHdr->cbMeta)); 497 377 498 /*499 * Only do accounting for protocol v3 and up.500 * The older protocols did not have any data accounting available, so501 * we simply tried to receive as much data as available and bail out.502 */503 const bool fDoAccounting = pCtx->uProtocol >= 3;504 505 378 /* Anything to do at all? */ 506 if (fDoAccounting) 507 { 508 /* Note: Do not check for cbToRecvBytes == 0 here, as this might be just 509 * a bunch of 0-byte files to be transferred. */ 510 if (!cToRecvObjs) 511 return VINF_SUCCESS; 512 } 379 /* Note: Do not check for cbToRecvBytes == 0 here, as this might be just 380 * a bunch of 0-byte files to be transferred. */ 381 if (!cToRecvObjs) 382 return VINF_SUCCESS; 513 383 514 384 /* … … 547 417 uint32_t fMode = 0; 548 418 549 /*550 * Only wait for new incoming commands for protocol v3 and up.551 * The older protocols did not have any data accounting available, so552 * we simply tried to receive as much data as available and bail out.553 */554 const bool fWait = pCtx->uProtocol >= 3;555 556 419 do 557 420 { … … 560 423 uint32_t uNextMsg; 561 424 uint32_t cNextParms; 562 rc = vbglR3DnDGetNextMsgType(pCtx, &uNextMsg, &cNextParms, fWait);425 rc = vbglR3DnDGetNextMsgType(pCtx, &uNextMsg, &cNextParms, true /* fWait */); 563 426 if (RT_SUCCESS(rc)) 564 427 { … … 589 452 rc = pDroppedFiles->AddDir(pszPathAbs); 590 453 591 if ( RT_SUCCESS(rc) 592 && fDoAccounting) 454 if (RT_SUCCESS(rc)) 593 455 { 594 456 Assert(cToRecvObjs); … … 620 482 { 621 483 rc = vbglR3DnDHGRecvFileData(pCtx, 622 szPathName,623 sizeof(szPathName),624 &cbPathName,625 484 pvChunk, 626 485 cbChunkMax, 627 &cbChunkRead, 628 &fMode); 629 486 &cbChunkRead); 630 487 LogFlowFunc(("HOST_DND_HG_SND_FILE_DATA: " 631 "szPathName=%s, cbPathName=%RU32, cbChunkRead=%RU32, fMode=0x%x, rc=%Rrc\n", 632 szPathName, cbPathName, cbChunkRead, fMode, rc)); 488 "cbChunkRead=%RU32, rc=%Rrc\n", cbChunkRead, rc)); 633 489 } 634 490 635 491 if ( RT_SUCCESS(rc) 636 && ( uNextMsg == HOST_DND_HG_SND_FILE_HDR 637 /* Protocol v1 always sends the file name, so opening the file every time. */ 638 || pCtx->uProtocol <= 1) 639 ) 492 && uNextMsg == HOST_DND_HG_SND_FILE_HDR) 640 493 { 641 494 char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName); … … 645 498 szPathName, cbPathName, fMode, cbFileSize)); 646 499 647 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; 648 if (pCtx->uProtocol <= 1) 649 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; 650 else 651 fOpen |= RTFILE_O_CREATE_REPLACE; 500 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE 501 | RTFILE_O_CREATE_REPLACE; 652 502 653 503 /* Is there already a file open, e.g. in transfer? */ … … 667 517 { 668 518 cbFileWritten = 0; 669 670 if (pCtx->uProtocol >= 2) /* Set the expected file size. */ 671 objFile.SetSize(cbFileSize); 519 objFile.SetSize(cbFileSize); 672 520 } 673 521 } … … 675 523 else 676 524 { 677 AssertMsgFailed(("ObjType=%RU32 , Proto=%RU32\n", objFile.GetType(), pCtx->uProtocol));525 AssertMsgFailed(("ObjType=%RU32\n", objFile.GetType())); 678 526 rc = VERR_WRONG_ORDER; 679 527 } … … 698 546 cbFileWritten += cbChunkWritten; 699 547 700 if (fDoAccounting) 701 { 702 Assert(cbChunkRead <= cbToRecvBytes); 703 cbToRecvBytes -= cbChunkRead; 704 } 548 Assert(cbChunkRead <= cbToRecvBytes); 549 cbToRecvBytes -= cbChunkRead; 705 550 } 706 551 } 707 552 708 bool fClose = false; 709 if (pCtx->uProtocol >= 2) 553 /* Data transfer complete? Close the file. */ 554 bool fClose = objFile.IsComplete(); 555 if (fClose) 710 556 { 711 /* Data transfer complete? Close the file. */ 712 fClose = objFile.IsComplete(); 713 if ( fClose 714 && fDoAccounting) 715 { 716 Assert(cToRecvObjs); 717 cToRecvObjs--; 718 } 719 720 /* Only since protocol v2 we know the file size upfront. */ 721 Assert(cbFileWritten <= cbFileSize); 557 Assert(cToRecvObjs); 558 cToRecvObjs--; 722 559 } 723 else 724 fClose = true; /* Always close the file after each chunk. */ 560 561 /* Only since protocol v2 we know the file size upfront. */ 562 Assert(cbFileWritten <= cbFileSize); 725 563 726 564 if (fClose) … … 751 589 break; 752 590 753 if (fDoAccounting) 591 LogFlowFunc(("cbToRecvBytes=%RU64, cToRecvObjs=%RU64\n", cbToRecvBytes, cToRecvObjs)); 592 if ( !cbToRecvBytes 593 && !cToRecvObjs) 754 594 { 755 LogFlowFunc(("cbToRecvBytes=%RU64, cToRecvObjs=%RU64\n", cbToRecvBytes, cToRecvObjs)); 756 if ( !cbToRecvBytes 757 && !cToRecvObjs) 758 { 759 break; 760 } 595 break; 761 596 } 762 597 … … 823 658 VBOXDNDHGSENDDATAMSG Msg; 824 659 RT_ZERO(Msg); 825 int rc; 826 if (pCtx->uProtocol < 3) 827 { 828 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DATA, 5); 829 Msg.u.v1.uScreenId.SetUInt32(0); 830 Msg.u.v1.pvFormat.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt); 831 Msg.u.v1.cbFormat.SetUInt32(0); 832 Msg.u.v1.pvData.SetPtr(pvData, cbData); 833 Msg.u.v1.cbData.SetUInt32(0); 834 835 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 836 if ( RT_SUCCESS(rc) 837 || rc == VERR_BUFFER_OVERFLOW) 838 { 839 /** @todo r=bird: The VERR_BUFFER_OVERFLOW case is probably broken as the 840 * status isn't returned to the caller (vbglR3DnDHGRecvDataLoop). 841 * This was the case before fixing the uninitalized variable. As 842 * other V0-2 protocol functions have been marked deprecated, it's 843 * probably a good idea to just remove this code and tell the 1-2 users 844 * to upgrade the host instead. Unused and untested weird code like this 845 * is just hard+costly to maintain and liability. 846 * (VERR_BUFFER_OVERFLOW == weird, no disrespect intended) */ 847 848 /* Unmarshal the whole message first. */ 849 rc = Msg.u.v1.uScreenId.GetUInt32(&pDataHdr->uScreenId); 850 AssertRC(rc); 851 if (RT_SUCCESS(rc)) 852 { 853 uint32_t cbFormatRecv; 854 rc = Msg.u.v1.cbFormat.GetUInt32(&cbFormatRecv); 855 AssertRC(rc); 856 if (RT_SUCCESS(rc)) 857 { 858 uint32_t cbDataRecv; 859 rc = Msg.u.v1.cbData.GetUInt32(&cbDataRecv); 860 AssertRC(rc); 861 if (RT_SUCCESS(rc)) 862 { 863 /* 864 * In case of VERR_BUFFER_OVERFLOW get the data sizes required 865 * for the format + data blocks. 866 */ 867 if ( cbFormatRecv >= pDataHdr->cbMetaFmt 868 || cbDataRecv >= pDataHdr->cbMeta) 869 rc = VERR_TOO_MUCH_DATA; 870 else 871 { 872 pDataHdr->cbMetaFmt = cbFormatRecv; 873 if (pcbDataRecv) 874 *pcbDataRecv = cbDataRecv; 875 LogFlowFuncLeaveRC(rc); 876 return rc; 877 } 878 } 879 } 880 } 881 } 882 } 883 else /* Protocol v3 and up. */ 884 { 885 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DATA, 5); 886 Msg.u.v3.uContext.SetUInt32(0); 887 Msg.u.v3.pvData.SetPtr(pvData, cbData); 888 Msg.u.v3.cbData.SetUInt32(0); 889 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 890 Msg.u.v3.cbChecksum.SetUInt32(0); 891 892 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 660 661 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_DATA, 5); 662 Msg.u.v3.uContext.SetUInt32(0); 663 Msg.u.v3.pvData.SetPtr(pvData, cbData); 664 Msg.u.v3.cbData.SetUInt32(0); 665 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 666 Msg.u.v3.cbChecksum.SetUInt32(0); 667 668 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 669 if (RT_SUCCESS(rc)) 670 { 671 uint32_t cbDataRecv; 672 rc = Msg.u.v3.cbData.GetUInt32(&cbDataRecv); 673 AssertRC(rc); 893 674 if (RT_SUCCESS(rc)) 894 675 { 895 uint32_t cbDataRecv; 896 rc = Msg.u.v3.cbData.GetUInt32(&cbDataRecv); 897 AssertRC(rc); 898 if (RT_SUCCESS(rc)) 899 { 900 /** @todo Use checksum for validating the received data. */ 901 if (pcbDataRecv) 902 *pcbDataRecv = cbDataRecv; 903 LogFlowFuncLeaveRC(rc); 904 return rc; 905 } 676 /** @todo Use checksum for validating the received data. */ 677 if (pcbDataRecv) 678 *pcbDataRecv = cbDataRecv; 679 LogFlowFuncLeaveRC(rc); 680 return rc; 906 681 } 907 682 } … … 968 743 * @returns IPRT status code. 969 744 * @param pCtx DnD context to use. 970 * @param pvData Where to store the receivd DnD data.971 * @param cbData Size (in bytes) of where to store the received DnD data.972 * @param pcbDataRecv Where to store how much bytes of data actually was received.973 *974 * @remark Deprecated function and not being used since protocl 3 anymore; will be removed.975 */976 static int vbglR3DnDHGRecvMoreData(PVBGLR3GUESTDNDCMDCTX pCtx, void *pvData, uint32_t cbData, uint32_t *pcbDataRecv)977 {978 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);979 AssertPtrReturn(pvData, VERR_INVALID_POINTER);980 AssertReturn(cbData, VERR_INVALID_PARAMETER);981 AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);982 983 VBOXDNDHGSENDMOREDATAMSG Msg;984 RT_ZERO(Msg);985 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_HG_SND_MORE_DATA, 2);986 Msg.pvData.SetPtr(pvData, cbData);987 Msg.cbData.SetUInt32(0);988 989 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));990 if ( RT_SUCCESS(rc)991 || rc == VERR_BUFFER_OVERFLOW)992 {993 rc = Msg.cbData.GetUInt32(pcbDataRecv); AssertRC(rc);994 AssertReturn(cbData >= *pcbDataRecv, VERR_TOO_MUCH_DATA);995 }996 return rc;997 }998 999 /**1000 * Host -> Guest1001 * Helper function for receiving the actual DnD data from the host. Do not call directly.1002 *1003 * @returns IPRT status code.1004 * @param pCtx DnD context to use.1005 745 * @param pDataHdr Where to store the data header data. 1006 746 * @param ppvData Returns the received meta data. Needs to be free'd by the caller. … … 1020 760 LogFlowFuncEnter(); 1021 761 1022 if (pCtx->uProtocol < 3) 1023 { 1024 uint64_t cbDataTmp = pCtx->cbMaxChunkSize; 1025 void *pvDataTmp = RTMemAlloc(cbDataTmp); 1026 1027 if (!cbDataTmp) 1028 return VERR_NO_MEMORY; 1029 1030 /* 1031 * Protocols < v3 contain the header information in every HOST_DND_HG_SND_DATA 1032 * message, so do the actual retrieving immediately. 1033 * 1034 * Also, the initial implementation used VERR_BUFFER_OVERFLOW as a return code to 1035 * indicate that there will be more data coming in after the initial data chunk. There 1036 * was no way of telling the total data size upfront (in form of a header or some such), 1037 * so also handle this case to not break backwards compatibility. 1038 */ 1039 rc = vbglR3DnDHGRecvDataRaw(pCtx, pDataHdr, pvDataTmp, pCtx->cbMaxChunkSize, &cbDataRecv); 1040 1041 /* See comment above. */ 1042 while (rc == VERR_BUFFER_OVERFLOW) 762 rc = vbglR3DnDHGRecvDataHdr(pCtx, pDataHdr); 763 if (RT_FAILURE(rc)) 764 return rc; 765 766 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects)); 767 if (pDataHdr->cbMeta) 768 { 769 uint64_t cbDataTmp = 0; 770 void *pvDataTmp = RTMemAlloc(pDataHdr->cbMeta); 771 if (!pvDataTmp) 772 rc = VERR_NO_MEMORY; 773 774 if (RT_SUCCESS(rc)) 1043 775 { 1044 uint32_t uNextMsg; 1045 uint32_t cNextParms; 1046 rc = vbglR3DnDGetNextMsgType(pCtx, &uNextMsg, &cNextParms, false /* fBlock */); 776 uint8_t *pvDataOff = (uint8_t *)pvDataTmp; 777 while (cbDataTmp < pDataHdr->cbMeta) 778 { 779 rc = vbglR3DnDHGRecvDataRaw(pCtx, pDataHdr, 780 pvDataOff, RT_MIN(pDataHdr->cbMeta - cbDataTmp, pCtx->cbMaxChunkSize), 781 &cbDataRecv); 782 if (RT_SUCCESS(rc)) 783 { 784 LogFlowFunc(("cbDataRecv=%RU32, cbDataTmp=%RU64\n", cbDataRecv, cbDataTmp)); 785 Assert(cbDataTmp + cbDataRecv <= pDataHdr->cbMeta); 786 cbDataTmp += cbDataRecv; 787 pvDataOff += cbDataRecv; 788 } 789 else 790 break; 791 } 792 1047 793 if (RT_SUCCESS(rc)) 1048 794 { 1049 switch(uNextMsg) 1050 { 1051 case HOST_DND_HG_SND_MORE_DATA: 1052 { 1053 /** @todo r=andy Don't use reallocate here; can go wrong with *really* big URI lists. 1054 * Instead send as many URI entries as possible per chunk and add those entries 1055 * to our to-process list for immediata processing. Repeat the step after processing then. */ 1056 LogFlowFunc(("HOST_DND_HG_SND_MORE_DATA cbDataTotal: %RU64 -> %RU64\n", 1057 cbDataTmp, cbDataTmp + pCtx->cbMaxChunkSize)); 1058 void *pvDataNew = RTMemRealloc(pvDataTmp, cbDataTmp + pCtx->cbMaxChunkSize); 1059 if (!pvDataNew) 1060 { 1061 rc = VERR_NO_MEMORY; 1062 break; 1063 } 1064 1065 pvDataTmp = pvDataNew; 1066 1067 uint8_t *pvDataOff = (uint8_t *)pvDataTmp + cbDataTmp; 1068 rc = vbglR3DnDHGRecvMoreData(pCtx, pvDataOff, pCtx->cbMaxChunkSize, &cbDataRecv); 1069 if ( RT_SUCCESS(rc) 1070 || rc == VERR_BUFFER_OVERFLOW) /* Still can return VERR_BUFFER_OVERFLOW. */ 1071 { 1072 cbDataTmp += cbDataRecv; 1073 } 1074 break; 1075 } 1076 case HOST_DND_HG_EVT_CANCEL: 1077 default: 1078 { 1079 rc = vbglR3DnDHGRecvCancel(pCtx); 1080 if (RT_SUCCESS(rc)) 1081 rc = VERR_CANCELLED; 1082 break; 1083 } 1084 } 1085 } 1086 } 1087 1088 if (RT_SUCCESS(rc)) 1089 { 1090 /* There was no way of telling the total data size upfront 1091 * (in form of a header or some such), so set the total data size here. */ 1092 pDataHdr->cbTotal = cbDataTmp; 1093 1094 *ppvData = pvDataTmp; 1095 *pcbData = cbDataTmp; 1096 } 1097 else 1098 RTMemFree(pvDataTmp); 1099 } 1100 else /* Protocol v3 and up. */ 1101 { 1102 rc = vbglR3DnDHGRecvDataHdr(pCtx, pDataHdr); 1103 if (RT_SUCCESS(rc)) 1104 { 1105 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects)); 1106 if (pDataHdr->cbMeta) 1107 { 1108 uint64_t cbDataTmp = 0; 1109 void *pvDataTmp = RTMemAlloc(pDataHdr->cbMeta); 1110 if (!pvDataTmp) 1111 rc = VERR_NO_MEMORY; 1112 1113 if (RT_SUCCESS(rc)) 1114 { 1115 uint8_t *pvDataOff = (uint8_t *)pvDataTmp; 1116 while (cbDataTmp < pDataHdr->cbMeta) 1117 { 1118 rc = vbglR3DnDHGRecvDataRaw(pCtx, pDataHdr, 1119 pvDataOff, RT_MIN(pDataHdr->cbMeta - cbDataTmp, pCtx->cbMaxChunkSize), 1120 &cbDataRecv); 1121 if (RT_SUCCESS(rc)) 1122 { 1123 LogFlowFunc(("cbDataRecv=%RU32, cbDataTmp=%RU64\n", cbDataRecv, cbDataTmp)); 1124 Assert(cbDataTmp + cbDataRecv <= pDataHdr->cbMeta); 1125 cbDataTmp += cbDataRecv; 1126 pvDataOff += cbDataRecv; 1127 } 1128 else 1129 break; 1130 } 1131 1132 if (RT_SUCCESS(rc)) 1133 { 1134 Assert(cbDataTmp == pDataHdr->cbMeta); 1135 1136 LogFlowFunc(("Received %RU64 bytes of data\n", cbDataTmp)); 1137 1138 *ppvData = pvDataTmp; 1139 *pcbData = cbDataTmp; 1140 } 1141 else 1142 RTMemFree(pvDataTmp); 1143 } 795 Assert(cbDataTmp == pDataHdr->cbMeta); 796 797 LogFlowFunc(("Received %RU64 bytes of data\n", cbDataTmp)); 798 799 *ppvData = pvDataTmp; 800 *pcbData = cbDataTmp; 1144 801 } 1145 802 else 1146 { 1147 *ppvData = NULL; 1148 *pcbData = 0; 1149 } 803 RTMemFree(pvDataTmp); 1150 804 } 805 } 806 else 807 { 808 *ppvData = NULL; 809 *pcbData = 0; 1151 810 } 1152 811 … … 1312 971 VBOXDNDGHREQPENDINGMSG Msg; 1313 972 RT_ZERO(Msg); 1314 if (pCtx->uProtocol < 3) 1315 { 1316 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_REQ_PENDING, 1); 1317 Msg.u.v1.uScreenId.SetUInt32(0); 1318 } 1319 else 1320 { 1321 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_REQ_PENDING, 2); 1322 /** @todo Context ID not used yet. */ 1323 Msg.u.v3.uContext.SetUInt32(0); 1324 Msg.u.v3.uScreenId.SetUInt32(0); 1325 } 973 974 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_REQ_PENDING, 2); 975 /** @todo Context ID not used yet. */ 976 Msg.u.v3.uContext.SetUInt32(0); 977 Msg.u.v3.uScreenId.SetUInt32(0); 1326 978 1327 979 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 1328 980 if (RT_SUCCESS(rc)) 1329 981 { 1330 if (pCtx->uProtocol < 3) 1331 { 1332 if (puScreenID) 1333 rc = Msg.u.v1.uScreenId.GetUInt32(puScreenID); 1334 } 1335 else 1336 { 1337 /** @todo Context ID not used yet. */ 1338 if (puScreenID) 1339 rc = Msg.u.v3.uContext.GetUInt32(puScreenID); 1340 } 982 /** @todo Context ID not used yet. */ 983 if (puScreenID) 984 rc = Msg.u.v3.uContext.GetUInt32(puScreenID); 1341 985 } 1342 986 … … 1370 1014 VBOXDNDGHDROPPEDMSG Msg; 1371 1015 RT_ZERO(Msg); 1372 if (pCtx->uProtocol < 3) 1373 { 1374 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 3); 1375 Msg.u.v1.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp); 1376 Msg.u.v1.cbFormat.SetUInt32(0); 1377 Msg.u.v1.uAction.SetUInt32(0); 1378 } 1379 else 1380 { 1381 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 4); 1382 Msg.u.v3.uContext.SetUInt32(0); 1383 Msg.u.v3.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp); 1384 Msg.u.v3.cbFormat.SetUInt32(0); 1385 Msg.u.v3.uAction.SetUInt32(0); 1386 } 1016 1017 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, HOST_DND_GH_EVT_DROPPED, 4); 1018 Msg.u.v3.uContext.SetUInt32(0); 1019 Msg.u.v3.pvFormat.SetPtr(pszFormatTmp, cbFormatTmp); 1020 Msg.u.v3.cbFormat.SetUInt32(0); 1021 Msg.u.v3.uAction.SetUInt32(0); 1387 1022 1388 1023 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 1389 1024 if (RT_SUCCESS(rc)) 1390 1025 { 1391 if (pCtx->uProtocol < 3) 1392 { 1393 if (pcbFormat) 1394 rc = Msg.u.v1.cbFormat.GetUInt32(pcbFormat); 1395 if (RT_SUCCESS(rc) && puAction) 1396 rc = Msg.u.v1.uAction.GetUInt32(puAction); 1397 } 1398 else 1399 { 1400 /** @todo Context ID not used yet. */ 1401 if (pcbFormat) 1402 rc = Msg.u.v3.cbFormat.GetUInt32(pcbFormat); 1403 if (RT_SUCCESS(rc) && puAction) 1404 rc = Msg.u.v3.uAction.GetUInt32(puAction); 1405 } 1026 /** @todo Context ID not used yet. */ 1027 if (pcbFormat) 1028 rc = Msg.u.v3.cbFormat.GetUInt32(pcbFormat); 1029 if (RT_SUCCESS(rc) && puAction) 1030 rc = Msg.u.v3.uAction.GetUInt32(puAction); 1406 1031 1407 1032 if (RT_SUCCESS(rc)) … … 1487 1112 VBOXDNDCONNECTMSG Msg; 1488 1113 RT_ZERO(Msg); 1489 if (pCtx->uProtocol < 3) 1490 { 1491 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_CONNECT, 2); 1492 Msg.u.v2.uProtocol.SetUInt32(pCtx->uProtocol); 1493 Msg.u.v2.uFlags.SetUInt32(0); /* Unused at the moment. */ 1494 } 1495 else 1496 { 1497 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_CONNECT, 3); 1498 /** @todo Context ID not used yet. */ 1499 Msg.u.v3.uContext.SetUInt32(0); 1500 Msg.u.v3.uProtocol.SetUInt32(pCtx->uProtocol); 1501 Msg.u.v3.uFlags.SetUInt32(0); /* Unused at the moment. */ 1502 } 1114 1115 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_CONNECT, 3); 1116 /** @todo Context ID not used yet. */ 1117 Msg.u.v3.uContext.SetUInt32(0); 1118 Msg.u.v3.uProtocol.SetUInt32(pCtx->uProtocol); 1119 Msg.u.v3.uFlags.SetUInt32(0); /* Unused at the moment. */ 1503 1120 1504 1121 rc2 = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1509 1126 } 1510 1127 1511 /* GUEST_DND_CONNECT not supported; play safe here and just use protocol v1. */ 1512 if (!fSupportsConnectReq) 1513 pCtx->uProtocol = 1; /* Fall back to protocol version 1 (< VBox 5.0). */ 1514 1515 pCtx->cbMaxChunkSize = _64K; /** @todo Use a scratch buffer on the heap? */ 1128 if (fSupportsConnectReq) 1129 { 1130 pCtx->cbMaxChunkSize = _64K; /** @todo Use a scratch buffer on the heap? */ 1131 } 1132 else /* GUEST_DND_CONNECT not supported; the user needs to upgrade the host. */ 1133 rc = VERR_NOT_SUPPORTED; 1516 1134 1517 1135 LogFlowFunc(("uClient=%RU32, uProtocol=%RU32, rc=%Rrc\n", pCtx->uClientID, pCtx->uProtocol, rc)); … … 1638 1256 break; 1639 1257 } 1640 case HOST_DND_HG_SND_DATA:1641 /* Protocol v1 + v2: Also contains the header data. */1642 RT_FALL_THROUGH();1643 1258 case HOST_DND_HG_SND_DATA_HDR: 1644 1259 { … … 1648 1263 break; 1649 1264 } 1650 case HOST_DND_HG_SND_MORE_DATA: /* Deprecated; kept for backwards compatibility. */1651 RT_FALL_THROUGH();1652 1265 case HOST_DND_HG_SND_DIR: 1653 1266 RT_FALL_THROUGH(); … … 1762 1375 VBOXDNDHGACKOPMSG Msg; 1763 1376 RT_ZERO(Msg); 1764 LogFlowFunc(("uProto=%RU32\n", pCtx->uProtocol)); 1765 if (pCtx->uProtocol < 3) 1766 { 1767 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_ACK_OP, 1); 1768 Msg.u.v1.uAction.SetUInt32(uAction); 1769 } 1770 else 1771 { 1772 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_ACK_OP, 2); 1773 /** @todo Context ID not used yet. */ 1774 Msg.u.v3.uContext.SetUInt32(0); 1775 Msg.u.v3.uAction.SetUInt32(uAction); 1776 } 1377 1378 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_ACK_OP, 2); 1379 /** @todo Context ID not used yet. */ 1380 Msg.u.v3.uContext.SetUInt32(0); 1381 Msg.u.v3.uAction.SetUInt32(uAction); 1777 1382 1778 1383 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1798 1403 VBOXDNDHGREQDATAMSG Msg; 1799 1404 RT_ZERO(Msg); 1800 if (pCtx->uProtocol < 3) 1801 { 1802 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_REQ_DATA, 1); 1803 Msg.u.v1.pvFormat.SetPtr((void*)pcszFormat, cbFormat); 1804 } 1805 else 1806 { 1807 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_REQ_DATA, 3); 1808 /** @todo Context ID not used yet. */ 1809 Msg.u.v3.uContext.SetUInt32(0); 1810 Msg.u.v3.pvFormat.SetPtr((void*)pcszFormat, cbFormat); 1811 Msg.u.v3.cbFormat.SetUInt32(cbFormat); 1812 } 1405 1406 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_REQ_DATA, 3); 1407 /** @todo Context ID not used yet. */ 1408 Msg.u.v3.uContext.SetUInt32(0); 1409 Msg.u.v3.pvFormat.SetPtr((void*)pcszFormat, cbFormat); 1410 Msg.u.v3.cbFormat.SetUInt32(cbFormat); 1813 1411 1814 1412 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1832 1430 VBOXDNDHGEVTPROGRESSMSG Msg; 1833 1431 RT_ZERO(Msg); 1834 if (pCtx->uProtocol < 3) 1835 { 1836 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_EVT_PROGRESS, 3); 1837 Msg.u.v1.uStatus.SetUInt32(uStatus); 1838 Msg.u.v1.uPercent.SetUInt32(uPercent); 1839 Msg.u.v1.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 1840 } 1841 else 1842 { 1843 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_EVT_PROGRESS, 4); 1844 /** @todo Context ID not used yet. */ 1845 Msg.u.v3.uContext.SetUInt32(0); 1846 Msg.u.v3.uStatus.SetUInt32(uStatus); 1847 Msg.u.v3.uPercent.SetUInt32(uPercent); 1848 Msg.u.v3.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 1849 } 1432 1433 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_HG_EVT_PROGRESS, 4); 1434 /** @todo Context ID not used yet. */ 1435 Msg.u.v3.uContext.SetUInt32(0); 1436 Msg.u.v3.uStatus.SetUInt32(uStatus); 1437 Msg.u.v3.uPercent.SetUInt32(uPercent); 1438 Msg.u.v3.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 1850 1439 1851 1440 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1877 1466 VBOXDNDGHACKPENDINGMSG Msg; 1878 1467 RT_ZERO(Msg); 1879 if (pCtx->uProtocol < 3) 1880 { 1881 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_ACK_PENDING, 3); 1882 Msg.u.v1.uDefAction.SetUInt32(uDefAction); 1883 Msg.u.v1.uAllActions.SetUInt32(uAllActions); 1884 Msg.u.v1.pvFormats.SetPtr((void*)pcszFormats, cbFormats); 1885 } 1886 else 1887 { 1888 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_ACK_PENDING, 5); 1889 /** @todo Context ID not used yet. */ 1890 Msg.u.v3.uContext.SetUInt32(0); 1891 Msg.u.v3.uDefAction.SetUInt32(uDefAction); 1892 Msg.u.v3.uAllActions.SetUInt32(uAllActions); 1893 Msg.u.v3.pvFormats.SetPtr((void*)pcszFormats, cbFormats); 1894 Msg.u.v3.cbFormats.SetUInt32(cbFormats); 1895 } 1468 1469 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_ACK_PENDING, 5); 1470 /** @todo Context ID not used yet. */ 1471 Msg.u.v3.uContext.SetUInt32(0); 1472 Msg.u.v3.uDefAction.SetUInt32(uDefAction); 1473 Msg.u.v3.uAllActions.SetUInt32(uAllActions); 1474 Msg.u.v3.pvFormats.SetPtr((void*)pcszFormats, cbFormats); 1475 Msg.u.v3.cbFormats.SetUInt32(cbFormats); 1896 1476 1897 1477 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1911 1491 void *pvData, uint64_t cbData, PVBOXDNDSNDDATAHDR pDataHdr) 1912 1492 { 1913 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1914 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 1915 AssertReturn(cbData, VERR_INVALID_PARAMETER); 1916 /* cbAdditionalData is optional. */ 1917 /* pDataHdr is optional in protocols < v3. */ 1918 1919 int rc = VINF_SUCCESS; 1920 1921 /* For protocol v3 and up we need to send the data header first. */ 1922 if (pCtx->uProtocol >= 3) 1923 { 1924 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); 1925 1926 VBOXDNDGHSENDDATAHDRMSG Msg; 1927 RT_ZERO(Msg); 1928 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DATA_HDR, 12); 1929 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */ 1930 Msg.uFlags.SetUInt32(0); /** @todo Not used yet. */ 1931 Msg.uScreenId.SetUInt32(0); /** @todo Not used for guest->host (yet). */ 1932 Msg.cbTotal.SetUInt64(pDataHdr->cbTotal); 1933 Msg.cbMeta.SetUInt32(pDataHdr->cbMeta); 1934 Msg.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt); 1935 Msg.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt); 1936 Msg.cObjects.SetUInt64(pDataHdr->cObjects); 1937 Msg.enmCompression.SetUInt32(0); /** @todo Not used yet. */ 1938 Msg.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID); /** @todo Not used yet. */ 1939 Msg.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 1940 Msg.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 1941 1942 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 1943 1944 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU64, rc=%Rrc\n", 1945 pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects, rc)); 1946 } 1493 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1494 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 1495 AssertReturn(cbData, VERR_INVALID_PARAMETER); 1496 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); 1497 1498 VBOXDNDGHSENDDATAHDRMSG MsgHdr; 1499 RT_ZERO(MsgHdr); 1500 1501 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DATA_HDR, 12); 1502 MsgHdr.uContext.SetUInt32(0); /** @todo Not used yet. */ 1503 MsgHdr.uFlags.SetUInt32(0); /** @todo Not used yet. */ 1504 MsgHdr.uScreenId.SetUInt32(0); /** @todo Not used for guest->host (yet). */ 1505 MsgHdr.cbTotal.SetUInt64(pDataHdr->cbTotal); 1506 MsgHdr.cbMeta.SetUInt32(pDataHdr->cbMeta); 1507 MsgHdr.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt); 1508 MsgHdr.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt); 1509 MsgHdr.cObjects.SetUInt64(pDataHdr->cObjects); 1510 MsgHdr.enmCompression.SetUInt32(0); /** @todo Not used yet. */ 1511 MsgHdr.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID); /** @todo Not used yet. */ 1512 MsgHdr.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 1513 MsgHdr.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 1514 1515 int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); 1516 1517 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU64, rc=%Rrc\n", 1518 pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects, rc)); 1947 1519 1948 1520 if (RT_SUCCESS(rc)) 1949 1521 { 1950 VBOXDNDGHSENDDATAMSG Msg; 1951 RT_ZERO(Msg); 1952 if (pCtx->uProtocol >= 3) 1953 { 1954 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DATA, 5); 1955 Msg.u.v3.uContext.SetUInt32(0); /** @todo Not used yet. */ 1956 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 1957 Msg.u.v3.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 1958 } 1959 else 1960 { 1961 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DATA, 2); 1962 1963 /* Total amount of bytes to send (meta data + all directory/file objects). */ 1964 /* Note: Only supports uint32_t, so this is *not* a typo. */ 1965 Msg.u.v1.cbTotalBytes.SetUInt32((uint32_t)pDataHdr->cbTotal); 1966 } 1522 VBOXDNDGHSENDDATAMSG MsgData; 1523 RT_ZERO(MsgData); 1524 1525 VBGL_HGCM_HDR_INIT(&MsgData.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DATA, 5); 1526 MsgData.u.v3.uContext.SetUInt32(0); /** @todo Not used yet. */ 1527 MsgData.u.v3.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 1528 MsgData.u.v3.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 1967 1529 1968 1530 uint32_t cbCurChunk; … … 1970 1532 uint32_t cbSent = 0; 1971 1533 1972 HGCMFunctionParameter *pParm = (pCtx->uProtocol >= 3) 1973 ? &Msg.u.v3.pvData 1974 : &Msg.u.v1.pvData; 1534 HGCMFunctionParameter *pParm = &MsgData.u.v3.pvData; 1535 1975 1536 while (cbSent < cbData) 1976 1537 { 1977 1538 cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk); 1978 1539 pParm->SetPtr(static_cast<uint8_t *>(pvData) + cbSent, cbCurChunk); 1979 if (pCtx->uProtocol > 2) 1980 Msg.u.v3.cbData.SetUInt32(cbCurChunk);1981 1982 rc = VbglR3HGCMCall(&Msg .hdr, sizeof(Msg));1540 1541 MsgData.u.v3.cbData.SetUInt32(cbCurChunk); 1542 1543 rc = VbglR3HGCMCall(&MsgData.hdr, sizeof(MsgData)); 1983 1544 if (RT_FAILURE(rc)) 1984 1545 break; … … 2023 1584 VBOXDNDGHSENDDIRMSG Msg; 2024 1585 RT_ZERO(Msg); 2025 if (pCtx->uProtocol < 3) 2026 { 2027 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DIR, 3); 2028 Msg.u.v1.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)cbPath); 2029 Msg.u.v1.cbName.SetUInt32((uint32_t)cbPath); 2030 Msg.u.v1.fMode.SetUInt32(pObj->GetMode()); 2031 } 2032 else 2033 { 2034 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DIR, 4); 2035 /** @todo Context ID not used yet. */ 2036 Msg.u.v3.uContext.SetUInt32(0); 2037 Msg.u.v3.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)cbPath); 2038 Msg.u.v3.cbName.SetUInt32((uint32_t)cbPath); 2039 Msg.u.v3.fMode.SetUInt32(pObj->GetMode()); 2040 } 2041 2042 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 2043 2044 LogFlowFuncLeaveRC(rc); 2045 return rc; 1586 1587 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_DIR, 4); 1588 /** @todo Context ID not used yet. */ 1589 Msg.u.v3.uContext.SetUInt32(0); 1590 Msg.u.v3.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)cbPath); 1591 Msg.u.v3.cbName.SetUInt32((uint32_t)cbPath); 1592 Msg.u.v3.fMode.SetUInt32(pObj->GetMode()); 1593 1594 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 2046 1595 } 2047 1596 … … 2066 1615 return VERR_NO_MEMORY; 2067 1616 2068 int rc;2069 2070 1617 RTCString strPath = pObj->GetDestPath(); 2071 1618 2072 1619 LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", strPath.c_str(), strPath.length(), 2073 1620 pObj->GetSize(), pObj->GetMode())); 2074 LogFlowFunc(("uProtocol=%RU32, uClientID=%RU32\n", pCtx->uProtocol, pCtx->uClientID)); 2075 2076 if (pCtx->uProtocol >= 2) /* Protocol version 2 and up sends a file header first. */ 2077 { 2078 VBOXDNDGHSENDFILEHDRMSG MsgHdr; 2079 RT_ZERO(MsgHdr); 2080 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_HDR, 6); 2081 MsgHdr.uContext.SetUInt32(0); /* Context ID; unused at the moment. */ 2082 MsgHdr.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1)); 2083 MsgHdr.cbName.SetUInt32((uint32_t)(strPath.length() + 1)); 2084 MsgHdr.uFlags.SetUInt32(0); /* Flags; unused at the moment. */ 2085 MsgHdr.fMode.SetUInt32(pObj->GetMode()); /* File mode */ 2086 MsgHdr.cbTotal.SetUInt64(pObj->GetSize()); /* File size (in bytes). */ 2087 2088 rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); 2089 2090 LogFlowFunc(("Sending file header resulted in %Rrc\n", rc)); 2091 } 2092 else 2093 rc = VINF_SUCCESS; 1621 1622 VBOXDNDGHSENDFILEHDRMSG MsgHdr; 1623 RT_ZERO(MsgHdr); 1624 1625 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_HDR, 6); 1626 MsgHdr.uContext.SetUInt32(0); /* Context ID; unused at the moment. */ 1627 MsgHdr.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1)); 1628 MsgHdr.cbName.SetUInt32((uint32_t)(strPath.length() + 1)); 1629 MsgHdr.uFlags.SetUInt32(0); /* Flags; unused at the moment. */ 1630 MsgHdr.fMode.SetUInt32(pObj->GetMode()); /* File mode */ 1631 MsgHdr.cbTotal.SetUInt64(pObj->GetSize()); /* File size (in bytes). */ 1632 1633 int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); 1634 1635 LogFlowFunc(("Sending file header resulted in %Rrc\n", rc)); 2094 1636 2095 1637 if (RT_SUCCESS(rc)) … … 2100 1642 VBOXDNDGHSENDFILEDATAMSG Msg; 2101 1643 RT_ZERO(Msg); 2102 switch (pCtx->uProtocol) 2103 { 2104 case 3: 2105 { 2106 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_DATA, 5); 2107 Msg.u.v3.uContext.SetUInt32(0); 2108 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 2109 Msg.u.v3.cbChecksum.SetUInt32(0); 2110 break; 2111 } 2112 2113 case 2: 2114 { 2115 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_DATA, 3); 2116 Msg.u.v2.uContext.SetUInt32(0); 2117 break; 2118 } 2119 2120 default: /* Protocol v1 */ 2121 { 2122 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_DATA, 5); 2123 Msg.u.v1.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1)); 2124 Msg.u.v1.cbName.SetUInt32((uint32_t)(strPath.length() + 1)); 2125 Msg.u.v1.fMode.SetUInt32(pObj->GetMode()); 2126 break; 2127 } 2128 } 1644 1645 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_DATA, 5); 1646 Msg.u.v3.uContext.SetUInt32(0); 1647 Msg.u.v3.pvChecksum.SetPtr(NULL, 0); 1648 Msg.u.v3.cbChecksum.SetUInt32(0); 2129 1649 2130 1650 uint64_t cbToReadTotal = pObj->GetSize(); … … 2143 1663 && cbRead) 2144 1664 { 2145 switch (pCtx->uProtocol) 2146 { 2147 case 3: 2148 { 2149 Msg.u.v3.pvData.SetPtr(pvBuf, cbRead); 2150 Msg.u.v3.cbData.SetUInt32(cbRead); 2151 /** @todo Calculate + set checksums. */ 2152 break; 2153 } 2154 2155 case 2: 2156 { 2157 Msg.u.v2.pvData.SetPtr(pvBuf, cbRead); 2158 Msg.u.v2.cbData.SetUInt32(cbRead); 2159 break; 2160 } 2161 2162 default: 2163 { 2164 Msg.u.v1.pvData.SetPtr(pvBuf, cbRead); 2165 Msg.u.v1.cbData.SetUInt32(cbRead); 2166 break; 2167 } 2168 } 1665 Msg.u.v3.pvData.SetPtr(pvBuf, cbRead); 1666 Msg.u.v3.cbData.SetUInt32(cbRead); 1667 /** @todo Calculate + set checksums. */ 2169 1668 2170 1669 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 2378 1877 VBOXDNDGHEVTERRORMSG Msg; 2379 1878 RT_ZERO(Msg); 2380 if (pCtx->uProtocol < 3) 2381 { 2382 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_EVT_ERROR, 1); 2383 Msg.u.v1.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 2384 } 2385 else 2386 { 2387 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_EVT_ERROR, 2); 2388 /** @todo Context ID not used yet. */ 2389 Msg.u.v3.uContext.SetUInt32(0); 2390 Msg.u.v3.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 2391 } 1879 1880 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_GH_EVT_ERROR, 2); 1881 /** @todo Context ID not used yet. */ 1882 Msg.u.v3.uContext.SetUInt32(0); 1883 Msg.u.v3.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 2392 1884 2393 1885 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
Note:
See TracChangeset
for help on using the changeset viewer.