Changeset 42272 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jul 20, 2012 2:42:40 PM (13 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42234 r42272 35 35 using namespace guestControl; 36 36 #endif 37 38 37 39 38 /** Maximum number of guest sessions a VM can have. */ … … 61 60 ((uContextID) & 0xffff) 62 61 63 62 /** Vector holding a process' CPU affinity. */ 64 63 typedef std::vector <LONG> ProcessAffinity; 64 /** Vector holding process startup arguments. */ 65 65 typedef std::vector <Utf8Str> ProcessArguments; 66 66 … … 94 94 95 95 Utf8Str GetMessage(void) { return mMessage; } 96 97 int GetResultCode(void) { return mRC; } 96 98 97 99 eVBoxGuestCtrlCallbackType GetType(void) { return mType; } … … 107 109 /** Was the callback canceled? */ 108 110 bool fCanceled; 111 /** Did the callback complete? */ 112 bool fCompleted; 109 113 /** Pointer to user-supplied data. */ 110 114 void *pvData; … … 124 128 * Simple structure mantaining guest credentials. 125 129 */ 126 class GuestCredentials 127 { 128 public: 129 130 131 public: 132 130 struct GuestCredentials 131 { 133 132 Utf8Str mUser; 134 133 Utf8Str mPassword; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42234 r42272 71 71 int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID); 72 72 int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData); 73 bool callbackExists(ULONG uContextID);73 inline bool callbackExists(ULONG uContextID); 74 74 bool isReady(void); 75 75 ULONG getPID(void) { return mData.mPID; } … … 81 81 int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData); 82 82 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms); 83 int startProcess(void); 83 int signalWaiters(int rc, const Utf8Str strMessage = ""); 84 int startProcess(int *pRC = NULL, Utf8Str *pstrMessage = NULL); 84 85 static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser); 85 86 int terminateProcess(void); -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42214 r42272 126 126 const GuestEnvironment &getEnvironment(void); 127 127 int processClose(ComObjPtr<GuestProcess> pProcess); 128 int processCreateExInteral( GuestProcessInfo &aProcInfo, IGuestProcess **aProcess);128 int processCreateExInteral(const GuestProcessInfo &aProcInfo, IGuestProcess **aProcess); 129 129 inline bool processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess); 130 130 inline int processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42214 r42272 700 700 AssertPtr(pHeader); 701 701 702 #ifdef DEBUG 703 LogFlowFunc(("uSession=%RU32, uProcess=%RU32, uCount=%RU32\n", 704 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHeader->u32ContextID), 705 VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(pHeader->u32ContextID), 706 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID))); 707 #endif 702 708 int rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms); 703 709 … … 2675 2681 int Guest::dispatchToSession(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData) 2676 2682 { 2683 LogFlowFuncEnter(); 2684 2677 2685 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 2678 2686 AssertReturn(cbData, VERR_INVALID_PARAMETER); … … 2680 2688 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2681 2689 2690 int rc; 2682 2691 GuestSessions::const_iterator itSession 2683 2692 = mData.mGuestSessions.find(VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID)); … … 2688 2697 2689 2698 alock.release(); 2690 return pSession->dispatchToProcess(uContextID, uFunction, pvData, cbData); 2691 } 2692 return VERR_NOT_FOUND; 2699 rc = pSession->dispatchToProcess(uContextID, uFunction, pvData, cbData); 2700 } 2701 else 2702 rc = VERR_NOT_FOUND; 2703 2704 LogFlowFuncLeaveRC(rc); 2705 return rc; 2693 2706 } 2694 2707 … … 2718 2731 2719 2732 int rc = VERR_MAX_PROCS_REACHED; 2733 if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS) 2734 return rc; 2735 2720 2736 try 2721 2737 { … … 2726 2742 for (;;) 2727 2743 { 2728 /* Is the context ID already used? Try next ID ...*/2729 if (!sessionExists( ++uNewSessionID))2744 /* Is the context ID already used? */ 2745 if (!sessionExists(uNewSessionID)) 2730 2746 { 2731 2747 rc = VINF_SUCCESS; 2732 2748 break; 2733 2749 } 2750 uNewSessionID++; 2734 2751 2735 2752 if (++uTries == UINT32_MAX) … … 2763 2780 inline bool Guest::sessionExists(uint32_t uSessionID) 2764 2781 { 2765 AssertReturn(uSessionID, false);2766 2767 2782 GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID); 2768 2783 return (itSessions == mData.mGuestSessions.end()) ? false : true; -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42234 r42272 37 37 uFlags(0), 38 38 fCanceled(false), 39 fCompleted(false), 39 40 pvData(NULL), 40 41 cbData(0), … … 47 48 uFlags(0), 48 49 fCanceled(false), 50 fCompleted(false), 49 51 pvData(NULL), 50 52 cbData(0), … … 62 64 int GuestCtrlCallback::Cancel(void) 63 65 { 66 if (ASMAtomicReadBool(&fCompleted)) 67 return VINF_SUCCESS; 64 68 if (!ASMAtomicReadBool(&fCanceled)) 65 69 { 66 int rc = RTSemEventSignal(hEventSem); 70 int rc = hEventSem != NIL_RTSEMEVENT 71 ? RTSemEventSignal(hEventSem) : VINF_SUCCESS; 67 72 if (RT_SUCCESS(rc)) 68 73 ASMAtomicXchgBool(&fCanceled, true); … … 128 133 void GuestCtrlCallback::Destroy(void) 129 134 { 135 int rc = Cancel(); 136 AssertRC(rc); 137 130 138 mType = VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN; 131 139 if (pvData) … … 152 160 if (!uTimeoutMS) 153 161 msInterval = RT_INDEFINITE_WAIT; 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; 162 return RTSemEventWait(hEventSem, msInterval); 162 163 } 163 164 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42237 r42272 68 68 HRESULT GuestProcess::FinalConstruct(void) 69 69 { 70 LogFlow ThisFunc(("\n"));70 LogFlowFuncEnter(); 71 71 72 72 mData.mExitCode = 0; … … 81 81 mData.mWaitEvent = NIL_RTSEMEVENT; 82 82 83 return BaseFinalConstruct(); 83 HRESULT hr = BaseFinalConstruct(); 84 LogFlowFuncLeaveRC(hr); 85 return hr; 84 86 } 85 87 … … 108 110 mData.mParent = aSession; 109 111 mData.mProcessID = aProcessID; 112 mData.mProcess = aProcInfo; 113 110 114 mData.mStatus = ProcessStatus_Starting; 111 115 /* Everything else will be set by the actual starting routine. */ … … 362 366 int GuestProcess::callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData) 363 367 { 368 /* LogFlowFunc(("uPID=%RU32, uContextID=%RU32, uFunction=%RU32, pvData=%p, cbData=%z\n", 369 mData.mPID, uContextID, uFunction, pvData, cbData));*/ 370 364 371 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 365 372 AssertReturn(cbData, VERR_INVALID_PARAMETER); 366 373 367 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 368 374 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 375 376 int rc; 369 377 GuestCtrlCallbacks::const_iterator it 370 378 = mData.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID)); … … 373 381 GuestCtrlCallback *pCallback = it->second; 374 382 AssertPtr(pCallback); 375 376 int rc;377 383 378 384 switch (uFunction) … … 429 435 break; 430 436 } 431 432 return rc; 433 } 434 435 return VERR_NOT_FOUND; 436 } 437 438 bool GuestProcess::callbackExists(ULONG uContextID) 439 { 440 AssertReturn(uContextID, false); 441 437 } 438 else 439 rc = VERR_NOT_FOUND; 440 441 //LogFlowFuncLeaveRC(rc); 442 return rc; 443 } 444 445 inline bool GuestProcess::callbackExists(ULONG uContextID) 446 { 442 447 GuestCtrlCallbacks::const_iterator it = mData.mCallbacks.find(uContextID); 443 448 return (it == mData.mCallbacks.end()) ? false : true; … … 459 464 int GuestProcess::onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData) 460 465 { 461 LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p ", mData.mPID, pCallback, pData));466 LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p\n", mData.mPID, pCallback, pData)); 462 467 463 468 /* First, signal callback in every case. */ 464 469 pCallback->Signal(); 465 470 466 Assert(mData.mWaitEvent != NIL_RTSEMEVENT);467 int rc = RTSemEventSignal(mData.mWaitEvent);471 /* Signal in any case. */ 472 int rc = signalWaiters(VERR_CANCELLED, tr("The guest got disconnected")); 468 473 AssertRC(rc); 469 474 … … 486 491 /* Then do the WaitFor signalling stuff. */ 487 492 if (mData.mWaitFlags & ProcessWaitForFlag_StdIn) 488 { 489 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 490 rc = RTSemEventSignal(mData.mWaitEvent); 491 AssertRC(rc); 492 } 493 rc = signalWaiters(VINF_SUCCESS); 493 494 494 495 LogFlowFuncLeaveRC(rc); … … 504 505 505 506 /* Get data from the callback payload. */ 506 mData.mStatus = (ProcessStatus_T)pData->u32Status;507 507 if (mData.mPID) 508 508 Assert(mData.mPID == pData->u32PID); 509 509 510 Utf8Str strCallbackMsg; 510 Utf8Str callbackMsg; 511 int callbackRC = VINF_SUCCESS; 512 511 513 bool fSignal = false; 512 514 switch (pData->u32Status) … … 515 517 fSignal = ( (mData.mWaitFlags & ProcessWaitForFlag_Start) 516 518 || (mData.mWaitFlags & ProcessWaitForFlag_Status)); 519 520 mData.mStatus = ProcessStatus_Started; 517 521 mData.mPID = pData->u32PID; 518 522 mData.mStarted = true; 519 523 520 rc = pCallback->Signal(VINF_SUCCESS,521 Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"),522 mData.mProcess.mCommand.c_str(), mData.mPID));524 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"), 525 mData.mProcess.mCommand.c_str(), mData.mPID); 526 LogRel((callbackMsg.c_str())); 523 527 break; 524 528 525 529 case PROC_STS_TEN: 526 530 { 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 mData.mStatus = ProcessStatus_TerminatedNormally; 532 533 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated normally (exit code: %d)"), 534 mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 535 LogRel((callbackMsg.c_str())); 531 536 break; 532 537 } … … 534 539 case PROC_STS_TES: 535 540 { 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); 541 mData.mStatus = ProcessStatus_TerminatedSignal; 542 543 callbackRC = VERR_INTERRUPTED; 544 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated through signal (exit code: %d)"), 545 mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 546 LogRel((callbackMsg.c_str())); 540 547 break; 541 548 } … … 543 550 case PROC_STS_TEA: 544 551 { 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); 552 mData.mStatus = ProcessStatus_TerminatedAbnormally; 553 554 callbackRC = VERR_BROKEN_PIPE; 555 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated abnormally (exit code: %d)"), 556 mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags); 557 LogRel((callbackMsg.c_str())); 549 558 break; 550 559 } … … 552 561 case PROC_STS_TOK: 553 562 { 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); 563 mData.mStatus = ProcessStatus_TimedOutKilled; 564 565 callbackRC = VERR_TIMEOUT; 566 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and was killed"), 567 mData.mProcess.mCommand.c_str(), mData.mPID); 568 LogRel((callbackMsg.c_str())); 558 569 break; 559 570 } … … 561 572 case PROC_STS_TOA: 562 573 { 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); 574 mData.mStatus = ProcessStatus_TimedOutAbnormally; 575 576 callbackRC = VERR_TIMEOUT; 577 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and could not be killed\n"), 578 mData.mProcess.mCommand.c_str(), mData.mPID); 579 LogRel((callbackMsg.c_str())); 567 580 break; 568 581 } … … 570 583 case PROC_STS_DWN: 571 584 { 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())); 585 mData.mStatus = ProcessStatus_Down; 586 575 587 /* 576 588 * If mFlags has CreateProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to … … 580 592 * In this case mFlags contains the actual execution flags reached in via Guest::ExecuteProcess(). 581 593 */ 582 rc = pCallback->Signal( mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses 583 ? VINF_SUCCESS : VERR_CANCELLED, strErrDetail); 594 callbackRC = mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses 595 ? VINF_SUCCESS : VERR_OBJECT_DESTROYED; 596 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) was killed because system is shutting down\n"), 597 mData.mProcess.mCommand.c_str(), mData.mPID); 598 LogRel((callbackMsg.c_str())); 584 599 break; 585 600 } … … 587 602 case PROC_STS_ERROR: 588 603 { 604 mData.mStatus = ProcessStatus_Error; 605 606 callbackRC = pData->u32Flags; 607 callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" could not be started: ", mData.mProcess.mCommand.c_str())); 608 589 609 /* Note: It's not required that the process 590 610 * has been started before. */ 591 Utf8Str strErrDetail;592 611 if (pData->u32PID) 593 612 { 594 strErrDetail = Utf8StrFmt(tr("Guest process (PID %RU32) could not be started because of rc=%Rrc"), 595 pData->u32PID, pData->u32Flags); 613 callbackMsg += Utf8StrFmt(tr("Error rc=%Rrc occured"), pData->u32Flags); 596 614 } 597 615 else 598 616 { 599 switch ( pData->u32Flags) /* u32Flags membercontains the IPRT error code from guest side. */617 switch (callbackRC) /* callbackRC contains the IPRT error code from guest side. */ 600 618 { 601 619 case VERR_FILE_NOT_FOUND: /* This is the most likely error. */ 602 strErrDetail= Utf8StrFmt(tr("The specified file was not found on guest"));620 callbackMsg += Utf8StrFmt(tr("The specified file was not found on guest")); 603 621 break; 604 622 605 623 case VERR_PATH_NOT_FOUND: 606 strErrDetail= Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest"));624 callbackMsg += Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest")); 607 625 break; 608 626 609 627 case VERR_BAD_EXE_FORMAT: 610 strErrDetail= Utf8StrFmt(tr("The specified file is not an executable format on guest"));628 callbackMsg += Utf8StrFmt(tr("The specified file is not an executable format on guest")); 611 629 break; 612 630 613 631 case VERR_AUTHENTICATION_FAILURE: 614 strErrDetail= Utf8StrFmt(tr("The specified user was not able to logon on guest"));632 callbackMsg += Utf8StrFmt(tr("The specified user was not able to logon on guest")); 615 633 break; 616 634 617 635 case VERR_TIMEOUT: 618 strErrDetail= Utf8StrFmt(tr("The guest did not respond within time"));636 callbackMsg += Utf8StrFmt(tr("The guest did not respond within time")); 619 637 break; 620 638 621 639 case VERR_CANCELLED: 622 strErrDetail= Utf8StrFmt(tr("The execution operation was canceled"));640 callbackMsg += Utf8StrFmt(tr("The execution operation was canceled")); 623 641 break; 624 642 625 643 case VERR_PERMISSION_DENIED: 626 strErrDetail= Utf8StrFmt(tr("Invalid user/password credentials"));644 callbackMsg += Utf8StrFmt(tr("Invalid user/password credentials")); 627 645 break; 628 646 629 647 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"));648 callbackMsg += Utf8StrFmt(tr("Maximum number of parallel guest processes has been reached")); 631 649 break; 632 650 633 651 default: 634 strErrDetail = Utf8StrFmt(tr("Guest process reported error %Rrc"), 635 pData->u32Flags); 652 callbackMsg += Utf8StrFmt(tr("Reported error %Rrc"), callbackRC); 636 653 break; 637 654 } 638 639 Assert(!strErrDetail.isEmpty());640 rc = pCallback->Signal(pData->u32Flags /* rc from guest. */, strErrDetail);641 655 } 642 fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status; 656 657 LogRel((callbackMsg.c_str())); 643 658 break; 644 659 } … … 646 661 case PROC_STS_UNDEFINED: 647 662 default: 648 rc = pCallback->Signal(VERR_NOT_SUPPORTED, 649 Utf8StrFmt(tr("Got unsupported process status %RU32, skipping"), pData->u32Status));663 664 /* Silently skip this request. */ 650 665 fSignal = true; /* Signal in any case. */ 651 666 break; 652 667 } 668 669 /* 670 * Now do the signalling stuff. 671 */ 672 rc = pCallback->Signal(callbackRC, callbackMsg); 653 673 654 674 if (!fSignal) … … 656 676 if (fSignal) 657 677 { 658 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 659 int rc2 = RTSemEventSignal(mData.mWaitEvent); 678 int rc2 = signalWaiters(callbackRC, callbackMsg); 660 679 if (RT_SUCCESS(rc)) 661 680 rc = rc2; … … 748 767 } 749 768 750 int GuestProcess::startProcess(void) 751 { 769 int GuestProcess::signalWaiters(int rc, const Utf8Str strMessage) 770 { 771 LogFlowFunc(("rc=%Rrc, strMessage=%s, mWaiting=%RTbool, mWaitEvent=%p\n", 772 rc, strMessage.c_str(), mData.mWaiting, mData.mWaitEvent)); 773 774 /* Note: No locking here -- already done in the callback dispatcher. */ 775 776 /* We have to set the error information here because the waiters are public 777 * Main clients which rely on it. */ 778 if (RT_FAILURE(rc)) 779 { 780 HRESULT hr = setError(VBOX_E_IPRT_ERROR, strMessage.c_str()); 781 ComAssertRC(hr); 782 } 783 784 int rc2 = VINF_SUCCESS; 785 if ( mData.mWaiting 786 && mData.mWaitEvent != NIL_RTSEMEVENT) 787 { 788 rc2 = RTSemEventSignal(mData.mWaitEvent); 789 AssertRC(rc2); 790 } 791 792 LogFlowFuncLeaveRC(rc2); 793 return rc2; 794 } 795 796 int GuestProcess::startProcess(int *pRC, Utf8Str *pstrMessage) 797 { 798 /* Parameters are optional. */ 799 752 800 LogFlowFunc(("aCmd=%s, aTimeoutMS=%RU32, fFlags=%x\n", 753 801 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags)); … … 757 805 int rc; 758 806 ULONG uContextID; 759 GuestCtrlCallback *pCallbackStart = (GuestCtrlCallback *)RTMemAlloc(sizeof(GuestCtrlCallback));807 GuestCtrlCallback *pCallbackStart = new GuestCtrlCallback(); 760 808 if (!pCallbackStart) 761 809 return VERR_NO_MEMORY; … … 774 822 if (RT_SUCCESS(rc)) 775 823 { 776 Assert(uContextID);777 778 824 ComObjPtr<GuestSession> pSession(mData.mParent); 779 825 Assert(!pSession.isNull()); … … 844 890 */ 845 891 rc = pCallbackStart->Wait(mData.mProcess.mTimeoutMS); 846 } 847 } 848 849 LogFlowFuncLeave(); 892 if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */ 893 { 894 if (pRC) 895 *pRC = pCallbackStart->GetResultCode(); 896 if (pstrMessage) 897 *pstrMessage = pCallbackStart->GetMessage(); 898 } 899 } 900 } 901 902 if (pCallbackStart) 903 delete pCallbackStart; 904 905 LogFlowFuncLeaveRC(rc); 850 906 return rc; 851 907 } … … 862 918 863 919 int rc = pProcess->startProcess(); 864 865 LogFlowFuncLeave(); 920 AssertRC(rc); 921 922 LogFlowFuncLeaveRC(rc); 866 923 return rc; 867 924 } … … 879 936 int GuestProcess::waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason) 880 937 { 881 LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p, mWaitEvent=%p\n",882 fFlags, uTimeoutMS, penmReason, &mData.mWaitEvent));883 884 938 Assert(mData.mWaitEvent != NIL_RTSEMEVENT); 885 939 … … 887 941 return VERR_ALREADY_EXISTS; 888 942 943 /* At the moment we only support one waiter at a time. */ 889 944 int rc = RTSemMutexRequest(mData.mWaitMutex, uTimeoutMS); 890 945 if (RT_SUCCESS(rc)) … … 902 957 } 903 958 904 LogFlowFuncLeaveRC(rc);905 959 return rc; 906 960 } … … 981 1035 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 982 1036 983 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 984 1037 /* 1038 * Note: Do not hold any locks here while waiting! 1039 */ 985 1040 uint32_t fWaitFor = ProcessWaitForFlag_None; 986 1041 com::SafeArray<ProcessWaitForFlag_T> flags(ComSafeArrayInArg(aFlags)); -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42214 r42272 61 61 62 62 AssertPtrReturn(aGuest, VERR_INVALID_POINTER); 63 AssertReturn(aSessionID, VERR_INVALID_PARAMETER);64 63 65 64 /* Enclose the state transition NotReady->InInit->Ready. */ … … 67 66 AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED); 68 67 68 mData.mTimeout = 30 * 60 * 1000; /* Session timeout is 30 mins by default. */ 69 69 mData.mParent = aGuest; 70 70 mData.mId = aSessionID; … … 352 352 int GuestSession::dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData) 353 353 { 354 LogFlowFuncEnter(); 355 354 356 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 355 357 AssertReturn(cbData, VERR_INVALID_PARAMETER); … … 357 359 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 358 360 361 int rc; 359 362 SessionProcesses::const_iterator itProc 360 363 = mData.mProcesses.find(VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID)); … … 365 368 366 369 alock.release(); 367 return pProcess->callbackDispatcher(uContextID, uFunction, pvData, cbData); 368 } 369 return VERR_NOT_FOUND; 370 rc = pProcess->callbackDispatcher(uContextID, uFunction, pvData, cbData); 371 } 372 else 373 rc = VERR_NOT_FOUND; 374 375 LogFlowFuncLeaveRC(rc); 376 return rc; 370 377 } 371 378 … … 414 421 } 415 422 416 int GuestSession::processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess) 417 { 418 AssertPtrReturn(aProcess, VERR_INVALID_POINTER); 419 423 int GuestSession::processCreateExInteral(const GuestProcessInfo &aProcInfo, IGuestProcess **aProcess) 424 { 420 425 /* Validate flags. */ 421 426 if (aProcInfo.mFlags) … … 430 435 } 431 436 437 GuestProcessInfo procInfo = aProcInfo; 438 432 439 /* Adjust timeout. If set to 0, we define 433 440 * an infinite timeout. */ 434 if ( aProcInfo.mTimeoutMS == 0)435 aProcInfo.mTimeoutMS = UINT32_MAX;441 if (procInfo.mTimeoutMS == 0) 442 procInfo.mTimeoutMS = UINT32_MAX; 436 443 437 444 /** @tood Implement process priority + affinity. */ 438 445 439 int rc = VERR_MAX_THRDS_REACHED; 446 int rc = VERR_MAX_PROCS_REACHED; 447 if (mData.mProcesses.size() >= VBOX_GUESTCTRL_MAX_PROCESSES) 448 return rc; 440 449 441 450 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); … … 447 456 for (;;) 448 457 { 449 /* Is the context ID already used? Try next ID ...*/450 if (!processExists(uNewProcessID ++, NULL /* pProgress */))458 /* Is the context ID already used? */ 459 if (!processExists(uNewProcessID, NULL /* pProgress */)) 451 460 { 452 461 /* Callback with context ID was not found. This means … … 456 465 break; 457 466 } 467 uNewProcessID++; 458 468 459 469 if (++uTries == UINT32_MAX) … … 470 480 471 481 rc = pGuestProcess->init(mData.mParent->getConsole() /* Console */, this /* Session */, 472 uNewProcessID, aProcInfo);482 uNewProcessID, procInfo); 473 483 if (RT_FAILURE(rc)) throw rc; 474 484 … … 489 499 inline bool GuestSession::processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess) 490 500 { 491 AssertReturn(uProcessID, false);492 493 501 SessionProcesses::const_iterator it = mData.mProcesses.find(uProcessID); 494 502 if (it != mData.mProcesses.end()) … … 932 940 com::SafeArray<LONG> affinity; 933 941 934 return ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment), 935 ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity), aProcess); 942 HRESULT hr = ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment), 943 ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity), aProcess); 944 LogFlowFuncLeaveRC(hr); 945 return hr; 936 946 #endif /* VBOX_WITH_GUEST_CONTROL */ 937 947 } … … 957 967 958 968 procInfo.mCommand = Utf8Str(aCommand); 959 960 com::SafeArray<IN_BSTR> arguments(ComSafeArrayInArg(aArguments)); 961 procInfo.mArguments.reserve(arguments.size()); 962 for (size_t i = 0; i < arguments.size(); i++) 963 procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i])); 969 procInfo.mFlags = ProcessCreateFlag_None; 970 971 if (aArguments) 972 { 973 com::SafeArray<IN_BSTR> arguments(ComSafeArrayInArg(aArguments)); 974 procInfo.mArguments.reserve(arguments.size()); 975 for (size_t i = 0; i < arguments.size(); i++) 976 procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i])); 977 } 964 978 965 979 int rc = VINF_SUCCESS; 966 980 967 /* Create the process environment: 981 /* 982 * Create the process environment: 968 983 * - Apply the session environment in a first step, and 969 984 * - Apply environment variables specified by this call to 970 985 * have the chance of overwriting/deleting session entries. 971 986 */ 972 procInfo.mEnvironment = mData.mEnvironment; 973 com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment)); 974 for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++) 975 rc = mData.mEnvironment.Set(Utf8Str(environment[i])); 987 procInfo.mEnvironment = mData.mEnvironment; /* Apply original session environment. */ 988 if (aEnvironment) /* Apply/overwrite environment, if set. */ 989 { 990 com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment)); 991 for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++) 992 rc = mData.mEnvironment.Set(Utf8Str(environment[i])); 993 } 976 994 977 995 if (RT_SUCCESS(rc)) 978 996 { 979 com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags)); 980 for (size_t i = 0; i < flags.size(); i++) 981 procInfo.mFlags |= flags[i]; 997 if (aFlags) 998 { 999 com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags)); 1000 for (size_t i = 0; i < flags.size(); i++) 1001 procInfo.mFlags |= flags[i]; 1002 } 982 1003 983 1004 procInfo.mTimeoutMS = aTimeoutMS; 984 1005 985 com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity)); 986 procInfo.mAffinity.reserve(affinity.size()); 987 for (size_t i = 0; i < affinity.size(); i++) 988 procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */ 1006 if (aAffinity) 1007 { 1008 com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity)); 1009 procInfo.mAffinity.reserve(affinity.size()); 1010 for (size_t i = 0; i < affinity.size(); i++) 1011 procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */ 1012 } 989 1013 990 1014 procInfo.mPriority = aPriority;
Note:
See TracChangeset
for help on using the changeset viewer.