Changeset 45109 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Mar 20, 2013 4:41:00 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 84401
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r45076 r45109 189 189 } 190 190 191 case CALLBACKTYPE_FILE_NOTIFY: 192 { 193 pvData = (PCALLBACKDATA_FILE_NOTIFY)RTMemAllocZ(sizeof(CALLBACKDATA_FILE_NOTIFY)); 194 AssertPtrReturn(pvData, VERR_NO_MEMORY); 195 cbData = sizeof(CALLBACKDATA_FILE_NOTIFY); 196 break; 197 } 198 191 199 default: 192 200 AssertMsgFailed(("Unknown callback type specified (%ld)\n", enmType)); … … 220 228 } 221 229 222 case CALLBACKTYPE_FILE_ READ:223 { 224 PCALLBACK PAYLOAD_FILE_NOTIFY_READ pThis = (PCALLBACKPAYLOAD_FILE_NOTIFY_READ)pvData;230 case CALLBACKTYPE_FILE_NOTIFY: 231 { 232 PCALLBACKDATA_FILE_NOTIFY pThis = (PCALLBACKDATA_FILE_NOTIFY)pvData; 225 233 AssertPtr(pThis); 226 if (pThis->pvData) 227 RTMemFree(pThis->pvData); 228 break; 234 switch (pThis->uType) 235 { 236 case GUEST_FILE_NOTIFYTYPE_READ: 237 { 238 if (pThis->u.read.pvData) 239 { 240 RTMemFree(pThis->u.read.pvData); 241 pThis->u.read.pvData = NULL; 242 } 243 244 break; 245 } 246 247 default: 248 break; 249 } 229 250 } 230 251 … … 264 285 Assert(cbCallback == sizeof(CALLBACKDATA_SESSION_NOTIFY)); 265 286 266 pThis->uType = pCB->uType; 267 pThis->uResult = pCB->uResult; 287 memcpy(pThis, pCB, sizeof(CALLBACKDATA_SESSION_NOTIFY)); 268 288 break; 269 289 } … … 275 295 Assert(cbCallback == sizeof(CALLBACKDATA_PROC_STATUS)); 276 296 277 pThis->uFlags = pCB->uFlags; 278 pThis->uPID = pCB->uPID; 279 pThis->uStatus = pCB->uStatus; 297 memcpy(pThis, pCB, sizeof(CALLBACKDATA_PROC_STATUS)); 280 298 break; 281 299 } … … 305 323 Assert(cbCallback == sizeof(CALLBACKDATA_PROC_INPUT)); 306 324 307 pThis->uProcessed = pCB->uProcessed; 308 pThis->uFlags = pCB->uFlags; 309 pThis->uPID = pCB->uPID; 310 pThis->uStatus = pCB->uStatus; 311 break; 312 } 313 325 memcpy(pThis, pCB, sizeof(CALLBACKDATA_PROC_INPUT)); 326 break; 327 } 328 329 case CALLBACKTYPE_FILE_NOTIFY: 330 { 331 PCALLBACKDATA_FILE_NOTIFY pThis = (PCALLBACKDATA_FILE_NOTIFY)pvData; 332 PCALLBACKDATA_FILE_NOTIFY pCB = (PCALLBACKDATA_FILE_NOTIFY)pvCallback; 333 Assert(cbCallback == sizeof(CALLBACKDATA_FILE_NOTIFY)); 334 335 memcpy(pThis, pCB, sizeof(CALLBACKDATA_FILE_NOTIFY)); 336 337 switch (pThis->uType) 338 { 339 case GUEST_FILE_NOTIFYTYPE_READ: 340 { 341 pThis->u.read.pvData = RTMemAlloc(pCB->u.read.cbData); 342 AssertPtrReturn(pThis->u.read.pvData, VERR_NO_MEMORY); 343 memcpy(pThis->u.read.pvData, pCB->u.read.pvData, pCB->u.read.cbData); 344 pThis->u.read.cbData = pCB->u.read.cbData; 345 break; 346 } 347 348 default: 349 break; 350 } 351 break; 352 } 353 354 #if 0 314 355 case CALLBACKTYPE_FILE_OPEN: 315 356 { … … 382 423 break; 383 424 } 384 425 #endif 385 426 default: 386 427 AssertMsgFailed(("Callback type not supported (%ld)\n", mType)); … … 1287 1328 } 1288 1329 1330 void GuestObject::callbackDelete(GuestCtrlCallback *pCallback) 1331 { 1332 if (pCallback) 1333 { 1334 delete pCallback; 1335 pCallback = NULL; 1336 } 1337 } 1338 1289 1339 bool GuestObject::callbackExists(uint32_t uContextID) 1290 1340 { … … 1306 1356 if (it != mObject.mCallbacks.end()) 1307 1357 { 1308 delete it->second;1309 1358 mObject.mCallbacks.erase(it); 1310 1359 -
trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
r44863 r45109 61 61 ///////////////////////////////////////////////////////////////////////////// 62 62 63 /** 64 * Initializes a file object but does *not* open the file on the guest 65 * yet. This is done in the dedidcated openFile call. 66 * 67 * @return IPRT status code. 68 * @param pConsole Pointer to console object. 69 * @param pSession Pointer to session object. 70 * @param uFileID Host-based file ID (part of the context ID). 71 * @param openInfo File opening information. 72 */ 63 73 int GuestFile::init(Console *pConsole, GuestSession *pSession, ULONG uFileID, const GuestFileOpenInfo &openInfo) 64 74 { … … 76 86 if (RT_SUCCESS(vrc)) 77 87 { 88 mData.mID = 0; 78 89 mData.mInitialSize = 0; 79 90 … … 257 268 { 258 269 case GUEST_DISCONNECTED: 259 vrc = onGuestDisconnected(pCbCtx, p Callback, pSvcCb); /* Affects all callbacks. */270 vrc = onGuestDisconnected(pCbCtx, pSvcCb, pCallback); /* Affects all callbacks. */ 260 271 break; 261 272 262 273 case GUEST_FILE_NOTIFY: 263 vrc = onFileNotify(pCbCtx, p Callback, pSvcCb);274 vrc = onFileNotify(pCbCtx, pSvcCb, pCallback); 264 275 break; 265 276 … … 273 284 LogFlowFuncLeaveRC(vrc); 274 285 #endif 286 return vrc; 287 } 288 289 int GuestFile::closeFile(int *pGuestRc) 290 { 291 LogFlowThisFunc(("strFile=%s\n", mData.mOpenInfo.mFileName.c_str())); 292 293 /* Prepare HGCM call. */ 294 VBOXHGCMSVCPARM paParms[4]; 295 int i = 1; /* Context ID will be set in sendFileComannd(). */ 296 paParms[i++].setUInt32(mData.mID /* Guest file ID */); 297 298 int guestRc; 299 int vrc = sendFileCommand(HOST_FILE_CLOSE, i, paParms, 30 * 1000 /* 30s timeout */, 300 &guestRc, NULL /* ppCallback */); 301 if (pGuestRc) 302 *pGuestRc = guestRc; 303 304 LogFlowFuncLeaveRC(vrc); 275 305 return vrc; 276 306 } … … 309 339 } 310 340 311 int GuestFile::onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, GuestCtrlCallback *pCallback, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData) 312 { 313 AssertPtrReturn(pCallback, VERR_INVALID_POINTER); 341 /* static */ 342 Utf8Str GuestFile::guestErrorToString(int guestRc) 343 { 344 Utf8Str strError; 345 346 /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */ 347 switch (guestRc) 348 { 349 case VERR_INVALID_VM_HANDLE: 350 strError += Utf8StrFmt(tr("VMM device is not available (is the VM running?)")); 351 break; 352 353 case VERR_HGCM_SERVICE_NOT_FOUND: 354 strError += Utf8StrFmt(tr("The guest execution service is not available")); 355 break; 356 357 case VERR_TIMEOUT: 358 strError += Utf8StrFmt(tr("The guest did not respond within time")); 359 break; 360 361 case VERR_CANCELLED: 362 strError += Utf8StrFmt(tr("The session operation was canceled")); 363 break; 364 365 case VERR_MAX_PROCS_REACHED: 366 strError += Utf8StrFmt(tr("Maximum number of concurrent guest files has been reached")); 367 break; 368 369 case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */ 370 strError += Utf8StrFmt(tr("Unable to retrieve requested information")); 371 break; 372 373 case VERR_NOT_FOUND: 374 strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)")); 375 break; 376 377 default: 378 strError += Utf8StrFmt("%Rrc", guestRc); 379 break; 380 } 381 382 return strError; 383 } 384 385 int GuestFile::onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData, 386 GuestCtrlCallback *pCallback) 387 { 388 AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER); 314 389 AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER); 390 /* pCallback is optional. */ 315 391 316 392 if (pSvcCbData->mParms < 3) 317 393 return VERR_INVALID_PARAMETER; 318 394 319 uint32_t uType; 320 void *pvData; uint32_t cbData; 395 int vrc = VINF_SUCCESS; 396 397 int idx = 0; /* Current parameter index. */ 398 CALLBACKDATA_FILE_NOTIFY dataCb; 321 399 /* pSvcCb->mpaParms[0] always contains the context ID. */ 322 pSvcCbData->mpaParms[1].getUInt32(&uType); 323 pSvcCbData->mpaParms[2].getPointer(&pvData, &cbData); 324 325 LogFlowThisFunc(("strName=%s, uType=%RU32, pvData=%p, cbData=%RU32, pCallback=%p\n", 326 mData.mOpenInfo.mFileName.c_str(), uType, pvData, cbData, pCallback)); 400 pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType); 401 pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.rc); 402 403 switch (dataCb.uType) 404 { 405 case GUEST_FILE_NOTIFYTYPE_ERROR: 406 /* No extra data. */ 407 break; 408 409 case GUEST_FILE_NOTIFYTYPE_OPEN: 410 if (pSvcCbData->mParms == 4) 411 { 412 pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle); 413 414 AssertMsg(mData.mID == 0, ("File ID already set to %RU32\n", mData.mID)); 415 mData.mID = dataCb.u.open.uHandle; 416 AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID), 417 ("File ID %RU32 does not match context ID %RU32\n", mData.mID, 418 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID))); 419 } 420 else 421 vrc = VERR_NOT_SUPPORTED; 422 break; 423 424 case GUEST_FILE_NOTIFYTYPE_CLOSE: 425 /* No extra data. */ 426 break; 427 428 case GUEST_FILE_NOTIFYTYPE_READ: 429 if (pSvcCbData->mParms == 4) 430 { 431 pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData, 432 &dataCb.u.read.cbData); 433 434 mData.mOffCurrent += dataCb.u.read.cbData; 435 } 436 else 437 vrc = VERR_NOT_SUPPORTED; 438 break; 439 440 case GUEST_FILE_NOTIFYTYPE_WRITE: 441 if (pSvcCbData->mParms == 4) 442 { 443 pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten); 444 445 mData.mOffCurrent += dataCb.u.write.cbWritten; 446 } 447 else 448 vrc = VERR_NOT_SUPPORTED; 449 break; 450 451 case GUEST_FILE_NOTIFYTYPE_SEEK: 452 if (pSvcCbData->mParms == 4) 453 { 454 pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual); 455 456 mData.mOffCurrent = dataCb.u.seek.uOffActual; 457 } 458 else 459 vrc = VERR_NOT_SUPPORTED; 460 break; 461 462 case GUEST_FILE_NOTIFYTYPE_TELL: 463 if (pSvcCbData->mParms == 4) 464 { 465 pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual); 466 467 mData.mOffCurrent = dataCb.u.tell.uOffActual; 468 } 469 else 470 vrc = VERR_NOT_SUPPORTED; 471 break; 472 473 default: 474 vrc = VERR_NOT_SUPPORTED; 475 break; 476 } 477 478 LogFlowThisFunc(("strName=%s, uType=%RU32, rc=%Rrc, pCallback=%p\n", 479 mData.mOpenInfo.mFileName.c_str(), dataCb.uType, dataCb.rc, pCallback)); 480 481 int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */ 482 if (RT_SUCCESS(vrc)) 483 { 484 /* Nothing to do here yet. */ 485 } 486 else if (vrc == VERR_NOT_SUPPORTED) 487 { 488 /* Also let the callback know. */ 489 guestRc = VERR_NOT_SUPPORTED; 490 } 327 491 328 492 /* Signal callback in every case (if available). */ 329 int vrc = VINF_SUCCESS;330 493 if (pCallback) 331 494 { 332 vrc = pCallback->SetData(pvData, cbData); 333 334 int rc2 = pCallback->Signal(); 495 int rc2 = pCallback->SetData(&dataCb, sizeof(dataCb)); 335 496 if (RT_SUCCESS(vrc)) 336 497 vrc = rc2; 498 rc2 = pCallback->Signal(guestRc); 499 if (RT_SUCCESS(vrc)) 500 vrc = rc2; 337 501 } 338 502 … … 341 505 } 342 506 343 int GuestFile::onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, GuestCtrlCallback *pCallback, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData) 344 { 345 AssertPtrReturn(pCallback, VERR_INVALID_POINTER); 346 347 LogFlowThisFunc(("strFile=%s, pCallback=%p\n", mData.mOpenInfo.mFileName.c_str(), pCallback)); 507 int GuestFile::onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData, 508 GuestCtrlCallback *pCallback) 509 { 510 AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER); 511 AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER); 512 /* pCallback is optional. */ 513 514 LogFlowThisFunc(("strFile=%s, pCallback=%p\n", 515 mData.mOpenInfo.mFileName.c_str(), pCallback)); 348 516 349 517 /* First, signal callback in every case. */ … … 364 532 mData.mOpenInfo.mDisposition.c_str(), mData.mOpenInfo.mCreationMode)); 365 533 366 /* Wait until the caller function (if kicked off by a thread) 367 * has returned and continue operation. */ 534 /* Prepare HGCM call. */ 535 VBOXHGCMSVCPARM paParms[8]; 536 int i = 1; /* Context ID will be set in sendFileComannd(). */ 537 paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(), 538 (ULONG)mData.mOpenInfo.mFileName.length() + 1); 539 paParms[i++].setPointer((void*)mData.mOpenInfo.mOpenMode.c_str(), 540 (ULONG)mData.mOpenInfo.mOpenMode.length() + 1); 541 paParms[i++].setPointer((void*)mData.mOpenInfo.mDisposition.c_str(), 542 (ULONG)mData.mOpenInfo.mDisposition.length() + 1); 543 paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode); 544 paParms[i++].setUInt64(mData.mOpenInfo.mInitialOffset); 545 546 int vrc = sendFileCommand(HOST_FILE_OPEN, i, paParms, 30 * 1000 /* 30s timeout */, 547 pGuestRc, NULL /* ppCallback */); 548 549 LogFlowFuncLeaveRC(vrc); 550 return vrc; 551 } 552 553 int GuestFile::readData(uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, 554 size_t *pcbRead, int *pGuestRc) 555 { 556 LogFlowThisFunc(("uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n", 557 uSize, uTimeoutMS, pvData, cbData)); 558 559 /* Prepare HGCM call. */ 560 VBOXHGCMSVCPARM paParms[4]; 561 int i = 1; /* Context ID will be set in sendFileComannd(). */ 562 paParms[i++].setUInt32(mData.mID /* File handle */); 563 paParms[i++].setUInt32(uSize /* Size (in bytes) to read */); 564 565 GuestCtrlCallback *pCallback = NULL; int guestRc; 566 int vrc = sendFileCommand(HOST_FILE_READ, i, paParms, uTimeoutMS, 567 &guestRc, &pCallback); 568 569 if (RT_SUCCESS(vrc)) 570 { 571 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 572 573 Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY)); 574 PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw(); 575 AssertPtr(pData); 576 Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ); 577 578 size_t cbRead = pData->u.read.cbData; 579 if (cbRead) 580 { 581 Assert(cbData >= cbRead); 582 memcpy(pvData, pData->u.read.pvData, cbRead); 583 } 584 585 LogFlowThisFunc(("cbRead=%RU32\n", cbRead)); 586 587 if (pcbRead) 588 *pcbRead = cbRead; 589 } 590 591 callbackDelete(pCallback); 592 593 if (pGuestRc) 594 *pGuestRc = guestRc; 595 596 LogFlowFuncLeaveRC(vrc); 597 return vrc; 598 } 599 600 int GuestFile::readDataAt(uint64_t uOffset, uint32_t uSize, uint32_t uTimeoutMS, 601 void *pvData, size_t cbData, 602 size_t *pcbRead, int *pGuestRc) 603 { 604 LogFlowThisFunc(("uOffset=%RU64, uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n", 605 uOffset, uSize, uTimeoutMS, pvData, cbData)); 606 607 /* Prepare HGCM call. */ 608 VBOXHGCMSVCPARM paParms[4]; 609 int i = 1; /* Context ID will be set in sendFileComannd(). */ 610 paParms[i++].setUInt32(mData.mID /* File handle */); 611 paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */); 612 paParms[i++].setUInt32(uSize /* Size (in bytes) to read */); 613 614 GuestCtrlCallback *pCallback = NULL; int guestRc; 615 int vrc = sendFileCommand(HOST_FILE_READ_AT, i, paParms, uTimeoutMS, 616 &guestRc, &pCallback); 617 618 if (RT_SUCCESS(vrc)) 619 { 620 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 621 622 Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY)); 623 PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw(); 624 AssertPtr(pData); 625 Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ); 626 627 size_t cbRead = pData->u.read.cbData; 628 if (cbRead) 629 { 630 Assert(cbData >= cbRead); 631 memcpy(pvData, pData->u.read.pvData, cbRead); 632 } 633 634 LogFlowThisFunc(("cbRead=%RU32\n", cbRead)); 635 636 if (pcbRead) 637 *pcbRead = cbRead; 638 } 639 640 callbackDelete(pCallback); 641 642 if (pGuestRc) 643 *pGuestRc = guestRc; 644 645 LogFlowFuncLeaveRC(vrc); 646 return vrc; 647 } 648 649 int GuestFile::seekAt(uint64_t uOffset, GUEST_FILE_SEEKTYPE eSeekType, 650 uint32_t uTimeoutMS, int *pGuestRc) 651 { 652 LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32\n", 653 uOffset, uTimeoutMS)); 654 655 /* Prepare HGCM call. */ 656 VBOXHGCMSVCPARM paParms[4]; 657 int i = 1; /* Context ID will be set in sendFileComannd(). */ 658 paParms[i++].setUInt32(mData.mID /* File handle */); 659 paParms[i++].setUInt32(eSeekType /* Seek method */); 660 paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */); 661 662 int guestRc; 663 int vrc = sendFileCommand(HOST_FILE_SEEK, i, paParms, uTimeoutMS, 664 &guestRc, NULL /* ppCallback */); 665 if (pGuestRc) 666 *pGuestRc = guestRc; 667 668 LogFlowFuncLeaveRC(vrc); 669 return vrc; 670 } 671 672 /** 673 * Handles the common parts of sending a file command to the guest. 674 * If ppCallback is returned it must be removed via callbackRemove() 675 * by the caller in any case. 676 * 677 * @return IPRT status code. 678 * @param uFunction HGCM function of command to send. 679 * @param uParms Number of HGCM parameters to send. 680 * At least one parameter must be present. 681 * @param paParms Array of HGCM parameters to send. 682 * Index [0] must not be used and will be 683 * filled out by the function. 684 * @param uTimeoutMS Timeout (in ms). 685 * @param pGuestRc Guest result. Optional. 686 * @param ppCallback Pointer which will receive the callback for 687 * further processing by the caller. Must 688 * be deleted with callbackDelete() when done. Optional. 689 */ 690 int GuestFile::sendFileCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms, 691 uint32_t uTimeoutMS, int *pGuestRc, GuestCtrlCallback **ppCallback) 692 { 693 AssertReturn(uParms, VERR_INVALID_PARAMETER); 694 AssertPtrReturn(paParms, VERR_INVALID_POINTER); 695 /** pGuestRc is optional. */ 696 /** ppCallback is optional. */ 697 698 LogFlowThisFunc(("strFile=%s, uFunction=%RU32, uParms=%RU32\n", 699 mData.mOpenInfo.mFileName.c_str(), uFunction, uParms)); 700 368 701 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 369 702 … … 376 709 uint32_t uContextID = 0; 377 710 378 GuestCtrlCallback *pCallback Open;711 GuestCtrlCallback *pCallback; 379 712 try 380 713 { 381 pCallback Open= new GuestCtrlCallback();714 pCallback = new GuestCtrlCallback(); 382 715 } 383 716 catch(std::bad_alloc &) … … 389 722 { 390 723 /* Create callback and add it to the map. */ 391 vrc = pCallback Open->Init(CALLBACKTYPE_FILE_OPEN);724 vrc = pCallback->Init(CALLBACKTYPE_FILE_NOTIFY); 392 725 if (RT_SUCCESS(vrc)) 393 vrc = callbackAdd(pCallback Open, &uContextID);726 vrc = callbackAdd(pCallback, &uContextID); 394 727 } 395 728 396 729 if (RT_SUCCESS(vrc)) 397 730 { 731 /* Assign context ID. */ 732 paParms[0].setUInt32(uContextID); 733 398 734 GuestSession *pSession = mData.mSession; 399 735 AssertPtr(pSession); 400 736 401 const GuestCredentials &sessionCreds = pSession->getCredentials(); 402 403 if (RT_SUCCESS(vrc)) 404 { 405 /* Prepare HGCM call. */ 406 VBOXHGCMSVCPARM paParms[8]; 407 int i = 0; 408 paParms[i++].setUInt32(uContextID); 409 paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(), 410 (ULONG)mData.mOpenInfo.mFileName.length() + 1); 411 paParms[i++].setPointer((void*)mData.mOpenInfo.mOpenMode.c_str(), 412 (ULONG)mData.mOpenInfo.mOpenMode.length() + 1); 413 paParms[i++].setPointer((void*)mData.mOpenInfo.mDisposition.c_str(), 414 (ULONG)mData.mOpenInfo.mDisposition.length() + 1); 415 paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode); 416 paParms[i++].setUInt64(mData.mOpenInfo.mInitialOffset); 417 418 /* Note: Don't hold the write lock in here. */ 419 vrc = sendCommand(HOST_FILE_OPEN, i, paParms); 420 } 421 422 /* Drop the write lock again before waiting. */ 423 alock.release(); 737 alock.release(); /* Drop the write lock again. */ 738 739 /* Note: Don't hold the write lock in here. */ 740 vrc = sendCommand(uFunction, uParms, paParms); 424 741 425 742 if (RT_SUCCESS(vrc)) … … 429 746 * Note: Be sure not keeping a AutoRead/WriteLock here. 430 747 */ 431 LogFlowThisFunc(("Waiting for callback (30s) ...\n")); 432 vrc = pCallbackOpen->Wait(30 * 1000 /* Wait 30s max. */); 748 LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", 749 uTimeoutMS)); 750 vrc = pCallback->Wait(uTimeoutMS); 433 751 if (RT_SUCCESS(vrc)) /* Wait was successful, check for supplied information. */ 434 752 { 435 int guestRc = pCallback Open->GetResultCode();753 int guestRc = pCallback->GetResultCode(); 436 754 if (RT_SUCCESS(guestRc)) 437 755 { 438 756 /* Nothing to do here yet. */ 439 757 } 758 else 759 vrc = VERR_GSTCTL_GUEST_ERROR; 440 760 441 761 if (pGuestRc) … … 443 763 LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc)); 444 764 } 445 else446 vrc = VERR_TIMEOUT;447 765 } 448 766 449 AutoWriteLock awlock(this COMMA_LOCKVAL_SRC_POS);450 451 AssertPtr(pCallback Open);767 alock.acquire(); /* Get write lock again. */ 768 769 AssertPtr(pCallback); 452 770 int rc2 = callbackRemove(uContextID); 453 771 if (RT_SUCCESS(vrc)) 454 772 vrc = rc2; 455 } 773 774 if (ppCallback) 775 { 776 /* Return callback to the caller which then will be 777 * responsible for removing it. Don't forget to lock write 778 * access before using this callback then! */ 779 *ppCallback = pCallback; 780 } 781 else 782 { 783 delete pCallback; 784 } 785 } 786 787 LogFlowFuncLeaveRC(vrc); 788 return vrc; 789 } 790 791 /* static */ 792 HRESULT GuestFile::setErrorExternal(VirtualBoxBase *pInterface, int guestRc) 793 { 794 AssertPtr(pInterface); 795 AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n")); 796 797 return pInterface->setError(VBOX_E_IPRT_ERROR, GuestFile::guestErrorToString(guestRc).c_str()); 798 } 799 800 int GuestFile::writeData(uint32_t uTimeoutMS, void *pvData, size_t cbData, 801 uint32_t *pcbWritten, int *pGuestRc) 802 { 803 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 804 AssertReturn(cbData, VERR_INVALID_PARAMETER); 805 806 LogFlowThisFunc(("uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n", 807 uTimeoutMS, pvData, cbData)); 808 809 /* Prepare HGCM call. */ 810 VBOXHGCMSVCPARM paParms[4]; 811 int i = 1; /* Context ID will be set in sendFileComannd(). */ 812 paParms[i++].setUInt32(mData.mID /* File handle */); 813 paParms[i++].setUInt32(cbData /* Size (in bytes) to write */); 814 paParms[i++].setPointer(pvData, cbData); 815 816 GuestCtrlCallback *pCallback = NULL; int guestRc; 817 int vrc = sendFileCommand(HOST_FILE_WRITE, i, paParms, uTimeoutMS, 818 &guestRc, &pCallback); 819 820 if (RT_SUCCESS(vrc)) 821 { 822 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 823 824 Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY)); 825 PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw(); 826 AssertPtr(pData); 827 Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE); 828 829 size_t cbWritten = pData->u.write.cbWritten; 830 LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten)); 831 832 if (pcbWritten) 833 *pcbWritten = cbWritten; 834 } 835 836 callbackDelete(pCallback); 837 838 if (pGuestRc) 839 *pGuestRc = guestRc; 840 841 LogFlowFuncLeaveRC(vrc); 842 return vrc; 843 } 844 845 int GuestFile::writeDataAt(uint64_t uOffset, uint32_t uTimeoutMS, 846 void *pvData, size_t cbData, 847 uint32_t *pcbWritten, int *pGuestRc) 848 { 849 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 850 AssertReturn(cbData, VERR_INVALID_PARAMETER); 851 852 LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n", 853 uOffset, uTimeoutMS, pvData, cbData)); 854 855 /* Prepare HGCM call. */ 856 VBOXHGCMSVCPARM paParms[4]; 857 int i = 1; /* Context ID will be set in sendFileComannd(). */ 858 paParms[i++].setUInt32(mData.mID /* File handle */); 859 paParms[i++].setUInt64(uOffset /* Offset where to starting writing */); 860 paParms[i++].setUInt32(cbData /* Size (in bytes) to write */); 861 paParms[i++].setPointer(pvData, cbData); 862 863 GuestCtrlCallback *pCallback = NULL; int guestRc; 864 int vrc = sendFileCommand(HOST_FILE_WRITE_AT, i, paParms, uTimeoutMS, 865 &guestRc, &pCallback); 866 867 if (RT_SUCCESS(vrc)) 868 { 869 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 870 871 Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY)); 872 PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw(); 873 AssertPtr(pData); 874 Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE); 875 876 size_t cbWritten = pData->u.write.cbWritten; 877 LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten)); 878 879 if (pcbWritten) 880 *pcbWritten = cbWritten; 881 } 882 883 callbackDelete(pCallback); 884 885 if (pGuestRc) 886 *pGuestRc = guestRc; 456 887 457 888 LogFlowFuncLeaveRC(vrc); … … 472 903 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 473 904 905 /* Close file on guest. */ 906 int guestRc; 907 int rc = closeFile(&guestRc); 908 /* On failure don't return here, instead do all the cleanup 909 * work first and then return an error. */ 910 474 911 AssertPtr(mData.mSession); 475 int rc = mData.mSession->fileRemoveFromList(this); 912 int rc2 = mData.mSession->fileRemoveFromList(this); 913 if (RT_SUCCESS(rc)) 914 rc = rc2; 476 915 477 916 /* … … 483 922 484 923 LogFlowFuncLeaveRC(rc); 924 if (RT_FAILURE(rc)) 925 { 926 if (rc == VERR_GSTCTL_GUEST_ERROR) 927 return GuestFile::setErrorExternal(this, guestRc); 928 929 return setError(VBOX_E_IPRT_ERROR, 930 tr("Closing guest file failed with %Rrc\n"), rc); 931 } 932 485 933 return S_OK; 486 934 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 504 952 ReturnComNotImplemented(); 505 953 #else 506 AutoCaller autoCaller(this); 507 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 508 509 ReturnComNotImplemented(); 954 if (aToRead == 0) 955 return setError(E_INVALIDARG, tr("The size to read is zero")); 956 CheckComArgOutSafeArrayPointerValid(aData); 957 958 AutoCaller autoCaller(this); 959 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 960 961 com::SafeArray<BYTE> data((size_t)aToRead); 962 Assert(data.size() >= aToRead); 963 964 HRESULT hr = S_OK; 965 966 size_t cbRead; int guestRc; 967 int vrc = readData(aToRead, aTimeoutMS, 968 data.raw(), aToRead, &cbRead, &guestRc); 969 if (RT_SUCCESS(vrc)) 970 { 971 if (data.size() != cbRead) 972 data.resize(cbRead); 973 data.detachTo(ComSafeArrayOutArg(aData)); 974 } 975 else 976 { 977 switch (vrc) 978 { 979 case VERR_GSTCTL_GUEST_ERROR: 980 hr = GuestFile::setErrorExternal(this, guestRc); 981 break; 982 983 default: 984 hr = setError(VBOX_E_IPRT_ERROR, 985 tr("Reading from file \"%s\" failed: %Rrc"), 986 mData.mOpenInfo.mFileName.c_str(), vrc); 987 break; 988 } 989 } 990 991 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64\n", vrc, cbRead)); 992 993 LogFlowFuncLeaveRC(vrc); 994 return hr; 510 995 #endif /* VBOX_WITH_GUEST_CONTROL */ 511 996 } … … 516 1001 ReturnComNotImplemented(); 517 1002 #else 518 AutoCaller autoCaller(this); 519 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 520 521 ReturnComNotImplemented(); 1003 if (aToRead == 0) 1004 return setError(E_INVALIDARG, tr("The size to read is zero")); 1005 CheckComArgOutSafeArrayPointerValid(aData); 1006 1007 AutoCaller autoCaller(this); 1008 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1009 1010 com::SafeArray<BYTE> data((size_t)aToRead); 1011 Assert(data.size() >= aToRead); 1012 1013 HRESULT hr = S_OK; 1014 1015 size_t cbRead; int guestRc; 1016 int vrc = readDataAt(aOffset, aToRead, aTimeoutMS, 1017 data.raw(), aToRead, &cbRead, &guestRc); 1018 if (RT_SUCCESS(vrc)) 1019 { 1020 if (data.size() != cbRead) 1021 data.resize(cbRead); 1022 data.detachTo(ComSafeArrayOutArg(aData)); 1023 } 1024 else 1025 { 1026 switch (vrc) 1027 { 1028 case VERR_GSTCTL_GUEST_ERROR: 1029 hr = GuestFile::setErrorExternal(this, guestRc); 1030 break; 1031 1032 default: 1033 hr = setError(VBOX_E_IPRT_ERROR, 1034 tr("Reading from file \"%s\" (at offset %RU64) failed: %Rrc"), 1035 mData.mOpenInfo.mFileName.c_str(), aOffset, vrc); 1036 break; 1037 } 1038 } 1039 1040 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64\n", vrc, cbRead)); 1041 1042 LogFlowFuncLeaveRC(vrc); 1043 return hr; 522 1044 #endif /* VBOX_WITH_GUEST_CONTROL */ 523 1045 } … … 528 1050 ReturnComNotImplemented(); 529 1051 #else 530 AutoCaller autoCaller(this); 531 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 532 533 ReturnComNotImplemented(); 1052 LogFlowThisFuncEnter(); 1053 1054 AutoCaller autoCaller(this); 1055 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1056 1057 HRESULT hr = S_OK; 1058 1059 GUEST_FILE_SEEKTYPE eSeekType; 1060 switch (aType) 1061 { 1062 case FileSeekType_Set: 1063 eSeekType = GUEST_FILE_SEEKTYPE_BEGIN; 1064 break; 1065 1066 case FileSeekType_Current: 1067 eSeekType = GUEST_FILE_SEEKTYPE_CURRENT; 1068 break; 1069 1070 default: 1071 return setError(E_INVALIDARG, tr("Invalid seek type specified")); 1072 break; 1073 } 1074 1075 int guestRc; 1076 int vrc = seekAt(aOffset, eSeekType, 1077 30 * 1000 /* 30s timeout */, &guestRc); 1078 if (RT_FAILURE(vrc)) 1079 { 1080 switch (vrc) 1081 { 1082 case VERR_GSTCTL_GUEST_ERROR: 1083 hr = GuestFile::setErrorExternal(this, guestRc); 1084 break; 1085 1086 default: 1087 hr = setError(VBOX_E_IPRT_ERROR, 1088 tr("Seeking file \"%s\" (to offset %RU64) failed: %Rrc"), 1089 mData.mOpenInfo.mFileName.c_str(), aOffset, vrc); 1090 break; 1091 } 1092 } 1093 1094 LogFlowFuncLeaveRC(vrc); 1095 return hr; 534 1096 #endif /* VBOX_WITH_GUEST_CONTROL */ 535 1097 } … … 552 1114 ReturnComNotImplemented(); 553 1115 #else 554 AutoCaller autoCaller(this); 555 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 556 557 ReturnComNotImplemented(); 1116 LogFlowThisFuncEnter(); 1117 1118 CheckComArgOutPointerValid(aWritten); 1119 1120 AutoCaller autoCaller(this); 1121 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1122 1123 HRESULT hr = S_OK; 1124 1125 com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); int guestRc; 1126 int vrc = writeData(aTimeoutMS, data.raw(), data.size(), (uint32_t*)aWritten, &guestRc); 1127 if (RT_FAILURE(vrc)) 1128 { 1129 switch (vrc) 1130 { 1131 case VERR_GSTCTL_GUEST_ERROR: 1132 hr = GuestFile::setErrorExternal(this, guestRc); 1133 break; 1134 1135 default: 1136 hr = setError(VBOX_E_IPRT_ERROR, 1137 tr("Writing to file \"%s\" failed: %Rrc"), 1138 mData.mOpenInfo.mFileName.c_str(), vrc); 1139 break; 1140 } 1141 } 1142 1143 LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, aWritten)); 1144 1145 LogFlowFuncLeaveRC(vrc); 1146 return hr; 558 1147 #endif /* VBOX_WITH_GUEST_CONTROL */ 559 1148 } … … 564 1153 ReturnComNotImplemented(); 565 1154 #else 566 AutoCaller autoCaller(this); 567 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 568 569 ReturnComNotImplemented(); 570 #endif /* VBOX_WITH_GUEST_CONTROL */ 571 } 572 1155 LogFlowThisFuncEnter(); 1156 1157 CheckComArgOutPointerValid(aWritten); 1158 1159 AutoCaller autoCaller(this); 1160 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1161 1162 HRESULT hr = S_OK; 1163 1164 com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); int guestRc; 1165 int vrc = writeData(aTimeoutMS, data.raw(), data.size(), (uint32_t*)aWritten, &guestRc); 1166 if (RT_FAILURE(vrc)) 1167 { 1168 switch (vrc) 1169 { 1170 case VERR_GSTCTL_GUEST_ERROR: 1171 hr = GuestFile::setErrorExternal(this, guestRc); 1172 break; 1173 1174 default: 1175 hr = setError(VBOX_E_IPRT_ERROR, 1176 tr("Writing to file \"%s\" (at offset %RU64) failed: %Rrc"), 1177 mData.mOpenInfo.mFileName.c_str(), aOffset, vrc); 1178 break; 1179 } 1180 } 1181 1182 LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, aWritten)); 1183 1184 LogFlowFuncLeaveRC(vrc); 1185 return hr; 1186 #endif /* VBOX_WITH_GUEST_CONTROL */ 1187 } 1188 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r45078 r45109 949 949 alock.acquire(); 950 950 951 AssertPtr(pCallbackRead);952 951 int rc2 = callbackRemove(uContextID); 953 952 if (RT_SUCCESS(vrc)) 954 953 vrc = rc2; 954 955 callbackDelete(pCallbackRead); 955 956 956 957 LogFlowFuncLeaveRC(vrc); … … 1015 1016 uint32_t uContextID = 0; 1016 1017 1017 GuestCtrlCallback *pCallbackStart ;1018 GuestCtrlCallback *pCallbackStart = NULL; 1018 1019 try 1019 1020 { … … 1174 1175 AutoWriteLock awlock(this COMMA_LOCKVAL_SRC_POS); 1175 1176 1176 AssertPtr(pCallbackStart);1177 1177 int rc2 = callbackRemove(uContextID); 1178 1178 if (RT_SUCCESS(vrc)) 1179 1179 vrc = rc2; 1180 1180 } 1181 1182 callbackDelete(pCallbackStart); 1181 1183 1182 1184 LogFlowFuncLeaveRC(vrc); … … 1305 1307 alock.acquire(); 1306 1308 1307 AssertPtr(pCallbackTerminate);1308 1309 int rc2 = callbackRemove(uContextID); 1309 1310 if (RT_SUCCESS(vrc)) 1310 1311 vrc = rc2; 1312 1313 callbackDelete(pCallbackTerminate); 1311 1314 1312 1315 LogFlowFuncLeaveRC(vrc); … … 1617 1620 vrc = rc2; 1618 1621 1622 callbackDelete(pCallbackWrite); 1623 1619 1624 LogFlowFuncLeaveRC(vrc); 1620 1625 return vrc; … … 1807 1812 AutoCaller autoCaller(this); 1808 1813 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1809 1810 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);1811 1814 1812 1815 HRESULT hr = S_OK; -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r45078 r45109 968 968 return rc; 969 969 970 /* Add the created file to our vector. */ 971 mData.mFiles[uNewFileID] = pFile; 972 mData.mNumObjects++; 973 Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS); 974 975 LogFlowFunc(("Added new file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n", 976 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects)); 970 int guestRc; 971 rc = pFile->openFile(&guestRc); 972 if (RT_SUCCESS(rc)) 973 { 974 /* Add the created file to our vector. */ 975 mData.mFiles[uNewFileID] = pFile; 976 mData.mNumObjects++; 977 Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS); 978 979 LogFlowFunc(("Added new file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n", 980 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects)); 981 } 982 983 if (pGuestRc) 984 *pGuestRc = guestRc; 977 985 978 986 LogFlowFuncLeaveRC(rc); … … 1794 1802 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1795 1803 1796 /* Close session on guest session. */1804 /* Close session on guest. */ 1797 1805 int guestRc; 1798 1806 int rc = closeSession(0 /* Flags */, 30 * 1000 /* Timeout */, … … 1816 1824 if (RT_FAILURE(rc)) 1817 1825 { 1818 /** @todo Handle guestRc! */ 1826 if (rc == VERR_GSTCTL_GUEST_ERROR) 1827 return GuestSession::setErrorExternal(this, guestRc); 1828 1819 1829 return setError(VBOX_E_IPRT_ERROR, 1820 1830 tr("Closing guest session failed with %Rrc\n"), rc); … … 2483 2493 { 2484 2494 case VERR_GSTCTL_GUEST_ERROR: 2485 hr = Guest Process::setErrorExternal(this, guestRc);2495 hr = GuestFile::setErrorExternal(this, guestRc); 2486 2496 break; 2487 2497 2488 2498 default: 2489 hr = setError(VBOX_E_IPRT_ERROR, tr("Opening file \"%s\" failed: %Rrc"),2499 hr = setError(VBOX_E_IPRT_ERROR, tr("Opening guest file \"%s\" failed: %Rrc"), 2490 2500 Utf8Str(aPath).c_str(), vrc); 2491 2501 break;
Note:
See TracChangeset
for help on using the changeset viewer.