Changeset 42234 in vbox
- Timestamp:
- Jul 19, 2012 4:43:43 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 79270
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42214 r42234 91 91 void Destroy(void); 92 92 93 eVBoxGuestCtrlCallbackType Type(void); 93 int Signal(int rc = VINF_SUCCESS, const Utf8Str &strMsg = ""); 94 95 Utf8Str GetMessage(void) { return mMessage; } 96 97 eVBoxGuestCtrlCallbackType GetType(void) { return mType; } 94 98 95 99 int Wait(ULONG uTimeoutMS); … … 109 113 /** The event semaphore triggering the*/ 110 114 RTSEMEVENT hEventSem; 111 /** Extended error information, if any. */ 112 ErrorInfo mErrorInfo; 115 /** Overall result code. */ 116 int mRC; 117 /** Error / information message to the 118 * result code. */ 119 Utf8Str mMessage; 113 120 }; 114 121 typedef std::map < uint32_t, GuestCtrlCallback* > GuestCtrlCallbacks; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42216 r42234 74 74 bool isReady(void); 75 75 ULONG getPID(void) { return mData.mPID; } 76 int onGuestDisconnected( void);77 int onProcessInputStatus( uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed);78 int onProcessStatusChange( uint32_t uStatus, uint32_t uFlags, uint32_t uPID);79 int onProcessOutput( uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData);76 int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData); 77 int onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData); 78 int onProcessStatusChange(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECSTATUS pData); 79 int onProcessOutput(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECOUT pData); 80 80 int prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars); 81 81 int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData); 82 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms); 82 83 int startProcess(void); 83 84 static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser); … … 105 106 ULONG mPID; 106 107 /** Internal, host-side process ID. */ 107 ULONG mProcessID;108 ULONG mProcessID; 108 109 /** The current process status. */ 109 110 ProcessStatus_T mStatus; … … 112 113 /** The next upcoming context ID. */ 113 114 ULONG mNextContextID; 115 /** Flag indicating someone is waiting for an event. */ 116 bool mWaiting; 117 /** The waiting mutex. */ 118 RTSEMMUTEX mWaitMutex; 119 /** The waiting flag(s). */ 120 uint32_t mWaitFlags; 114 121 /** The waiting event. */ 115 RTSEMEVENT m Event;122 RTSEMEVENT mWaitEvent; 116 123 } mData; 117 124 }; -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42214 r42234 139 139 } 140 140 141 eVBoxGuestCtrlCallbackType GuestCtrlCallback::Type(void) 142 { 143 return mType; 141 int GuestCtrlCallback::Signal(int rc /*= VINF_SUCCESS*/, const Utf8Str &strMsg /*= "" */) 142 { 143 AssertReturn(hEventSem != NIL_RTSEMEVENT, VERR_CANCELLED); 144 return RTSemEventSignal(hEventSem); 144 145 } 145 146 146 147 int GuestCtrlCallback::Wait(ULONG uTimeoutMS) 147 148 { 148 Assert (hEventSem != NIL_RTSEMEVENT);149 AssertReturn(hEventSem != NIL_RTSEMEVENT, VERR_CANCELLED); 149 150 150 151 RTMSINTERVAL msInterval = uTimeoutMS; 151 152 if (!uTimeoutMS) 152 153 msInterval = RT_INDEFINITE_WAIT; 153 return RTSemEventWait(hEventSem, msInterval); 154 int rc = RTSemEventWait(hEventSem, msInterval); 155 if (RT_SUCCESS(rc)) 156 { 157 /* Assign overall callback result. */ 158 rc = mRC; 159 } 160 161 return rc; 154 162 } 155 163 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42216 r42234 76 76 mData.mStatus = ProcessStatus_Undefined; 77 77 mData.mStarted = false; 78 mData.mWaiting = false; 79 mData.mWaitFlags = 0; 80 mData.mWaitMutex = NIL_RTSEMMUTEX; 81 mData.mWaitEvent = NIL_RTSEMEVENT; 78 82 79 83 return BaseFinalConstruct(); … … 103 107 mData.mConsole = aConsole; 104 108 mData.mParent = aSession; 105 mData.mPID = 0; /* Will be assigned by the guest OS later. */106 109 mData.mProcessID = aProcessID; 107 110 mData.mStatus = ProcessStatus_Starting; 108 111 /* Everything else will be set by the actual starting routine. */ 112 113 int rc = RTSemEventCreate(&mData.mWaitEvent); 114 if (RT_FAILURE(rc)) 115 return rc; 116 117 rc = RTSemMutexCreate(&mData.mWaitMutex); 118 if (RT_FAILURE(rc)) 119 return rc; 109 120 110 121 /* Asynchronously start the process on the guest by kicking off a … … 113 124 AssertReturn(pTask->isOk(), pTask->rc()); 114 125 115 intrc = RTThreadCreate(NULL, GuestProcess::startProcessThread,116 117 118 126 rc = RTThreadCreate(NULL, GuestProcess::startProcessThread, 127 (void *)pTask.get(), 0, 128 RTTHREADTYPE_MAIN_WORKER, 0, 129 "gctlPrcStart"); 119 130 if (RT_SUCCESS(rc)) 120 131 { … … 141 152 if (autoUninitSpan.uninitDone()) 142 153 return; 154 155 int rc = RTSemEventDestroy(mData.mWaitEvent); 156 AssertRC(rc); 157 rc = RTSemMutexDestroy(mData.mWaitMutex); 158 AssertRC(rc); 159 160 LogFlowFuncLeaveRC(rc); 143 161 } 144 162 … … 347 365 AssertReturn(cbData, VERR_INVALID_PARAMETER); 348 366 349 Auto WriteLock alock(this COMMA_LOCKVAL_SRC_POS);367 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 350 368 351 369 GuestCtrlCallbacks::const_iterator it … … 362 380 case GUEST_DISCONNECTED: 363 381 { 364 PCALLBACKDATACLIENTDISCONNECTED pC BData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvData);365 AssertPtr(pC BData);382 PCALLBACKDATACLIENTDISCONNECTED pCallbackData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvData); 383 AssertPtr(pCallbackData); 366 384 AssertReturn(sizeof(CALLBACKDATACLIENTDISCONNECTED) == cbData, VERR_INVALID_PARAMETER); 367 AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pC BData->hdr.u32Magic, VERR_INVALID_PARAMETER);368 369 rc = onGuestDisconnected( ); /* Affects all callbacks. */385 AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); 386 387 rc = onGuestDisconnected(pCallback, pCallbackData); /* Affects all callbacks. */ 370 388 break; 371 389 } … … 373 391 case GUEST_EXEC_SEND_STATUS: 374 392 { 375 PCALLBACKDATAEXECSTATUS pC BData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvData);376 AssertPtr(pC BData);393 PCALLBACKDATAEXECSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvData); 394 AssertPtr(pCallbackData); 377 395 AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbData, VERR_INVALID_PARAMETER); 378 AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pC BData->hdr.u32Magic, VERR_INVALID_PARAMETER);379 380 rc = onProcessStatusChange(pC BData->u32Status, pCBData->u32Flags, pCBData->u32PID);396 AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); 397 398 rc = onProcessStatusChange(pCallback, pCallbackData); 381 399 break; 382 400 } … … 384 402 case GUEST_EXEC_SEND_OUTPUT: 385 403 { 386 PCALLBACKDATAEXECOUT pC BData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvData);387 AssertPtr(pC BData);404 PCALLBACKDATAEXECOUT pCallbackData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvData); 405 AssertPtr(pCallbackData); 388 406 AssertReturn(sizeof(CALLBACKDATAEXECOUT) == cbData, VERR_INVALID_PARAMETER); 389 AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pC BData->hdr.u32Magic, VERR_INVALID_PARAMETER);390 391 Assert(mData.mPID == pC BData->u32PID);392 rc = onProcessOutput(pC BData->u32HandleId, pCBData->u32Flags, pCBData->pvData, pCBData->cbData);407 AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); 408 409 Assert(mData.mPID == pCallbackData->u32PID); 410 rc = onProcessOutput(pCallback, pCallbackData); 393 411 break; 394 412 } … … 396 414 case GUEST_EXEC_SEND_INPUT_STATUS: 397 415 { 398 PCALLBACKDATAEXECINSTATUS pC BData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvData);399 AssertPtr(pC BData);416 PCALLBACKDATAEXECINSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvData); 417 AssertPtr(pCallbackData); 400 418 AssertReturn(sizeof(CALLBACKDATAEXECINSTATUS) == cbData, VERR_INVALID_PARAMETER); 401 AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pC BData->hdr.u32Magic, VERR_INVALID_PARAMETER);402 403 Assert(mData.mPID == pC BData->u32PID);404 rc = onProcessInputStatus(pC BData->u32Status, pCBData->u32Flags, pCBData->cbProcessed);419 AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); 420 421 Assert(mData.mPID == pCallbackData->u32PID); 422 rc = onProcessInputStatus(pCallback, pCallbackData); 405 423 break; 406 424 } … … 439 457 } 440 458 441 int GuestProcess::onGuestDisconnected(void) 442 { 443 LogFlowFunc(("uPID=%RU32", mData.mPID)); 444 445 LogFlowFuncLeave(); 446 return 0; 447 } 448 449 int GuestProcess::onProcessInputStatus(uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed) 450 { 451 LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, cbDataProcessed=%RU32\n", 452 mData.mPID, uStatus, uFlags, cbDataProcessed)); 453 454 LogFlowFuncLeave(); 455 return 0; 456 } 457 458 int GuestProcess::onProcessStatusChange(uint32_t uStatus, uint32_t uFlags, uint32_t uPID) 459 { 460 LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32\n", 461 uPID, uStatus, uFlags)); 462 463 LogFlowFuncLeave(); 464 return 0; 465 } 466 467 int GuestProcess::onProcessOutput(uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData) 468 { 469 LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32\n", 470 mData.mPID, uHandle, uFlags, pvData, cbData)); 471 472 LogFlowFuncLeave(); 473 return 0; 459 int GuestProcess::onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData) 460 { 461 LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p", mData.mPID, pCallback, pData)); 462 463 /* First, signal callback in every case. */ 464 pCallback->Signal(); 465 466 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 467 int rc = RTSemEventSignal(mData.mWaitEvent); 468 AssertRC(rc); 469 470 LogFlowFuncLeaveRC(rc); 471 return rc; 472 } 473 474 int GuestProcess::onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData) 475 { 476 LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, cbProcessed=%RU32, pCallback=%p, pData=%p\n", 477 mData.mPID, pData->u32Status, pData->u32Flags, pData->cbProcessed, pCallback, pData)); 478 479 int rc = VINF_SUCCESS; 480 481 /** @todo Fill data into callback. */ 482 483 /* First, signal callback in every case. */ 484 pCallback->Signal(); 485 486 /* Then do the WaitFor signalling stuff. */ 487 if (mData.mWaitFlags & ProcessWaitForFlag_StdIn) 488 { 489 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 490 rc = RTSemEventSignal(mData.mWaitEvent); 491 AssertRC(rc); 492 } 493 494 LogFlowFuncLeaveRC(rc); 495 return rc; 496 } 497 498 int GuestProcess::onProcessStatusChange(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECSTATUS pData) 499 { 500 LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, pCallback=%p, pData=%p\n", 501 pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData)); 502 503 int rc = VINF_SUCCESS; 504 505 /* Get data from the callback payload. */ 506 mData.mStatus = (ProcessStatus_T)pData->u32Status; 507 if (mData.mPID) 508 Assert(mData.mPID == pData->u32PID); 509 510 Utf8Str strCallbackMsg; 511 bool fSignal = false; 512 switch (pData->u32Status) 513 { 514 case PROC_STS_STARTED: 515 fSignal = ( (mData.mWaitFlags & ProcessWaitForFlag_Start) 516 || (mData.mWaitFlags & ProcessWaitForFlag_Status)); 517 mData.mPID = pData->u32PID; 518 mData.mStarted = true; 519 520 rc = pCallback->Signal(VINF_SUCCESS, 521 Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"), 522 mData.mProcess.mCommand.c_str(), mData.mPID)); 523 break; 524 525 case PROC_STS_TEN: 526 { 527 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated normally (exit code: %RU32)"), 528 pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 529 LogRel((strErrDetail.c_str())); 530 rc = pCallback->Signal(VINF_SUCCESS, strErrDetail); 531 break; 532 } 533 534 case PROC_STS_TES: 535 { 536 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated through signal (exit code: %RU32)"), 537 pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 538 LogRel((strErrDetail.c_str())); 539 rc = pCallback->Signal(VERR_GENERAL_FAILURE /** @todo */, strErrDetail); 540 break; 541 } 542 543 case PROC_STS_TEA: 544 { 545 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated abnormally (exit code: %RU32)"), 546 pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 547 LogRel((strErrDetail.c_str())); 548 rc = pCallback->Signal(VERR_BROKEN_PIPE, strErrDetail); 549 break; 550 } 551 552 case PROC_STS_TOK: 553 { 554 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and was killed"), 555 pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID); 556 LogRel((strErrDetail.c_str())); 557 rc = pCallback->Signal(VERR_TIMEOUT, strErrDetail); 558 break; 559 } 560 561 case PROC_STS_TOA: 562 { 563 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and could not be killed\n"), 564 pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID); 565 LogRel((strErrDetail.c_str())); 566 rc = pCallback->Signal(VERR_TIMEOUT, strErrDetail); 567 break; 568 } 569 570 case PROC_STS_DWN: 571 { 572 Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) was killed because system is shutting down\n"), 573 mData.mProcess.mCommand.c_str(), mData.mPID); 574 LogRel((strErrDetail.c_str())); 575 /* 576 * If mFlags has CreateProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to 577 * our progress object. This is helpful for waiters which rely on the success of our progress object 578 * even if the executed process was killed because the system/VBoxService is shutting down. 579 * 580 * In this case mFlags contains the actual execution flags reached in via Guest::ExecuteProcess(). 581 */ 582 rc = pCallback->Signal( mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses 583 ? VINF_SUCCESS : VERR_CANCELLED, strErrDetail); 584 break; 585 } 586 587 case PROC_STS_ERROR: 588 { 589 /* Note: It's not required that the process 590 * has been started before. */ 591 Utf8Str strErrDetail; 592 if (pData->u32PID) 593 { 594 strErrDetail = Utf8StrFmt(tr("Guest process (PID %RU32) could not be started because of rc=%Rrc"), 595 pData->u32PID, pData->u32Flags); 596 } 597 else 598 { 599 switch (pData->u32Flags) /* u32Flags member contains the IPRT error code from guest side. */ 600 { 601 case VERR_FILE_NOT_FOUND: /* This is the most likely error. */ 602 strErrDetail = Utf8StrFmt(tr("The specified file was not found on guest")); 603 break; 604 605 case VERR_PATH_NOT_FOUND: 606 strErrDetail = Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest")); 607 break; 608 609 case VERR_BAD_EXE_FORMAT: 610 strErrDetail = Utf8StrFmt(tr("The specified file is not an executable format on guest")); 611 break; 612 613 case VERR_AUTHENTICATION_FAILURE: 614 strErrDetail = Utf8StrFmt(tr("The specified user was not able to logon on guest")); 615 break; 616 617 case VERR_TIMEOUT: 618 strErrDetail = Utf8StrFmt(tr("The guest did not respond within time")); 619 break; 620 621 case VERR_CANCELLED: 622 strErrDetail = Utf8StrFmt(tr("The execution operation was canceled")); 623 break; 624 625 case VERR_PERMISSION_DENIED: 626 strErrDetail = Utf8StrFmt(tr("Invalid user/password credentials")); 627 break; 628 629 case VERR_MAX_PROCS_REACHED: 630 strErrDetail = Utf8StrFmt(tr("Guest process could not be started because maximum number of parallel guest processes has been reached")); 631 break; 632 633 default: 634 strErrDetail = Utf8StrFmt(tr("Guest process reported error %Rrc"), 635 pData->u32Flags); 636 break; 637 } 638 639 AssertMsg(!strErrDetail.isEmpty()); 640 rc = pCallback->Signal(pData->u32Flags /* rc from guest. */, strErrDetail); 641 } 642 fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status; 643 break; 644 } 645 646 case PROC_STS_UNDEFINED: 647 default: 648 rc = pCallback->Signal(VERR_NOT_SUPPORTED, 649 Utf8StrFmt(tr("Got unsupported process status %RU32, skipping"), pData->u32Status)); 650 fSignal = true; /* Signal in any case. */ 651 break; 652 } 653 654 if (!fSignal) 655 fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status; 656 if (fSignal) 657 { 658 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 659 int rc2 = RTSemEventSignal(mData.mWaitEvent); 660 if (RT_SUCCESS(rc)) 661 rc = rc2; 662 } 663 664 LogFlowFuncLeaveRC(rc); 665 return rc; 666 } 667 668 int GuestProcess::onProcessOutput(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECOUT pData) 669 { 670 LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32, pCallback=%p, pData=%p\n", 671 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData)); 672 673 int rc = VINF_SUCCESS; 674 675 /** @todo Fill data into callback. */ 676 677 /* First, signal callback in every case. */ 678 pCallback->Signal(); 679 680 /* Then do the WaitFor signalling stuff. */ 681 bool fSignal = false; 682 if ( (mData.mWaitFlags & ProcessWaitForFlag_StdOut) 683 || (mData.mWaitFlags & ProcessWaitForFlag_StdErr)) 684 { 685 fSignal = true; 686 } 687 else if ( (mData.mWaitFlags & ProcessWaitForFlag_StdOut) 688 && (pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT)) 689 { 690 fSignal = true; 691 } 692 else if ( (mData.mWaitFlags & ProcessWaitForFlag_StdErr) 693 && (pData->u32HandleId == OUTPUT_HANDLE_ID_STDERR)) 694 { 695 fSignal = true; 696 } 697 698 if (fSignal) 699 { 700 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 701 rc = RTSemEventSignal(mData.mWaitEvent); 702 AssertRC(rc); 703 } 704 705 LogFlowFuncLeaveRC(rc); 706 return rc; 474 707 } 475 708 … … 484 717 LogFlowFuncLeave(); 485 718 return 0; 719 } 720 721 int GuestProcess::sendCommand(uint32_t uFunction, 722 uint32_t uParms, PVBOXHGCMSVCPARM paParms) 723 { 724 LogFlowFuncEnter(); 725 726 const ComObjPtr<Console> pConsole(mData.mConsole); 727 Assert(!pConsole.isNull()); 728 729 VMMDev *pVMMDev = NULL; 730 { 731 /* Make sure mParent is valid, so set the read lock while using. 732 * Do not keep this lock while doing the actual call, because in the meanwhile 733 * another thread could request a write lock which would be a bad idea ... */ 734 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 735 736 /* Forward the information to the VMM device. */ 737 pVMMDev = pConsole->getVMMDev(); 738 } 739 740 LogFlowFunc(("uFunction=%RU32, uParms=%RU32\n", uFunction, uParms)); 741 int rc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", uFunction, uParms, paParms); 742 if (RT_FAILURE(rc)) 743 { 744 } 745 746 LogFlowFuncLeaveRC(rc); 747 return rc; 486 748 } 487 749 … … 568 830 paParms[i++].setUInt32(mData.mProcess.mTimeoutMS); 569 831 570 const ComObjPtr<Console> pConsole(mData.mConsole); 571 Assert(!pConsole.isNull()); 572 573 VMMDev *pVMMDev = NULL; 574 { 575 /* Make sure mParent is valid, so set the read lock while using. 576 * Do not keep this lock while doing the actual call, because in the meanwhile 577 * another thread could request a write lock which would be a bad idea ... */ 578 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 579 580 /* Forward the information to the VMM device. */ 581 pVMMDev = pConsole->getVMMDev(); 582 } 583 584 LogFlowFunc(("hgcmHostCall numParms=%d, CID=%RU32\n", i, uContextID)); 585 rc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD, 586 i, paParms); 832 rc = sendCommand(HOST_EXEC_CMD, i, paParms); 587 833 } 588 834 … … 633 879 int GuestProcess::waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason) 634 880 { 635 LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p\n", 636 fFlags, uTimeoutMS, penmReason)); 637 638 LogFlowFuncLeave(); 639 return 0; 881 LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p, mWaitEvent=%p\n", 882 fFlags, uTimeoutMS, penmReason, &mData.mWaitEvent)); 883 884 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 885 886 if (ASMAtomicReadBool(&mData.mWaiting)) 887 return VERR_ALREADY_EXISTS; 888 889 int rc = RTSemMutexRequest(mData.mWaitMutex, uTimeoutMS); 890 if (RT_SUCCESS(rc)) 891 { 892 ASMAtomicWriteBool(&mData.mWaiting, true); 893 rc = RTSemEventWait(mData.mWaitEvent, uTimeoutMS); 894 if (RT_SUCCESS(rc)) 895 { 896 /** @todo Error handling after waiting. */ 897 } 898 899 int rc2 = RTSemMutexRelease(mData.mWaitMutex); 900 if (RT_SUCCESS(rc)) 901 rc = rc2; 902 } 903 904 LogFlowFuncLeaveRC(rc); 905 return rc; 640 906 } 641 907 … … 717 983 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 718 984 719 uint32_t f Flags= ProcessWaitForFlag_None;985 uint32_t fWaitFor = ProcessWaitForFlag_None; 720 986 com::SafeArray<ProcessWaitForFlag_T> flags(ComSafeArrayInArg(aFlags)); 721 987 for (size_t i = 0; i < flags.size(); i++) 722 f Flags|= flags[i];723 724 int rc = waitFor(f Flags, aTimeoutMS, aReason);988 fWaitFor |= flags[i]; 989 990 int rc = waitFor(fWaitFor, aTimeoutMS, aReason); 725 991 /** @todo Do setError() here. */ 726 992 HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
Note:
See TracChangeset
for help on using the changeset viewer.