Changeset 42411 in vbox for trunk/src/VBox
- Timestamp:
- Jul 26, 2012 2:07:13 PM (12 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r42382 r42411 8804 8804 <enum 8805 8805 name="ProcessWaitForFlag" 8806 uuid=" 858a99aa-4b3c-4863-9726-87386671f408"8806 uuid="23b550c7-78e1-437e-98f0-65fd9757bcd2" 8807 8807 > 8808 8808 <desc> … … 8812 8812 <const name="None" value="0"> 8813 8813 <desc>TODO</desc> 8814 </const> 8815 <const name="Exit" value="1"> 8814 </const> 8815 <const name="Start" value="1"> 8816 <desc>TODO</desc> 8817 </const> 8818 <const name="Terminate" value="2"> 8819 <desc>TODO</desc> 8820 </const> 8821 <const name="StdIn" value="4"> 8816 8822 <desc>TODO</desc> 8817 8823 </const> 8818 <const name="Std In" value="2">8824 <const name="StdOut" value="8"> 8819 8825 <desc>TODO</desc> 8820 8826 </const> 8821 <const name="Std Out" value="4">8827 <const name="StdErr" value="16"> 8822 8828 <desc>TODO</desc> 8823 </const> 8824 <const name="StdErr" value="8"> 8825 <desc>TODO</desc> 8826 </const> 8827 <const name="Start" value="16"> 8828 <desc>TODO</desc> 8829 </const> 8830 <const name="Status" value="32"> 8831 <desc>TODO</desc> 8832 </const> 8829 </const> 8833 8830 </enum> 8834 8831 8835 8832 <enum 8836 8833 name="ProcessWaitResult" 8837 uuid=" b03af138-c812-45eb-939d-5d564bd0b89a"8834 uuid="c593a234-21ee-4a67-85ef-ba0cc9b9b86a" 8838 8835 > 8839 8836 <desc> … … 8841 8838 </desc> 8842 8839 8843 <const name="None" value="0">8840 <const name="None" value="0"> 8844 8841 <desc>TODO</desc> 8845 8842 </const> 8846 <const name="Status" value="1"> 8843 <const name="Start" value="1"> 8844 <desc>TODO</desc> 8845 </const> 8846 <const name="Terminate" value="2"> 8847 <desc>TODO</desc> 8848 </const> 8849 <const name="Status" value="3"> 8847 8850 <desc>TODO</desc> 8848 8851 </const> 8849 <const name="Error" value="10">8852 <const name="Error" value="4"> 8850 8853 <desc>TODO</desc> 8851 8854 </const> 8852 <const name="Timeout" value="50">8855 <const name="Timeout" value="5"> 8853 8856 <desc>TODO</desc> 8854 8857 </const> 8855 <const name="StdIn" value="100">8858 <const name="StdIn" value="6"> 8856 8859 <desc>TODO</desc> 8857 8860 </const> 8858 <const name="StdOut" value="150">8861 <const name="StdOut" value="7"> 8859 8862 <desc>TODO</desc> 8860 8863 </const> 8861 <const name="StdErr" value="200">8864 <const name="StdErr" value="8"> 8862 8865 <desc>TODO</desc> 8863 8866 </const> … … 8944 8947 <enum 8945 8948 name="ProcessCreateFlag" 8946 uuid=" 1497c881-70b4-42dd-8b42-2ad76f004e3f"8949 uuid="91c8aba8-2e62-4fe5-b744-fcbd607971e2" 8947 8950 > 8948 8951 <desc> … … 8965 8968 <const name="NoProfile" value="8"> 8966 8969 <desc>Do not use the user's profile data when exeuting a process. Only available for Windows guests.</desc> 8970 </const> 8971 <const name="WaitForStdOut" value="16"> 8972 <desc>The guest process waits until all data from stdout is read out.</desc> 8973 </const> 8974 <const name="WaitForStdErr" value="32"> 8975 <desc>The guest process waits until all data from stderr is read out.</desc> 8967 8976 </const> 8968 8977 </enum> … … 9181 9190 <interface 9182 9191 name="IGuestSession" extends="$unknown" 9183 uuid=" 530aef35-6a48-455c-960c-aac5792abc38"9192 uuid="47a344ec-8495-49ad-bfab-8cd0ff8eb3cf" 9184 9193 wsmap="managed" 9185 9194 > … … 9221 9230 </attribute> 9222 9231 9223 <attribute name="timeout" type="unsigned long" readonly=" yes">9232 <attribute name="timeout" type="unsigned long" readonly="no"> 9224 9233 <desc> 9225 9234 TODO … … 9752 9761 </method> 9753 9762 9754 <method name="S etTimeout">9763 <method name="SymlinkCreate"> 9755 9764 <desc> 9756 9765 TODO … … 9760 9769 </result> 9761 9770 </desc> 9762 <param name=" timeoutMS" type="unsigned long" dir="in">9771 <param name="source" type="wstring" dir="in"> 9763 9772 <desc>TODO</desc> 9764 9773 </param> 9774 <param name="target" type="wstring" dir="in"> 9775 <desc>TODO</desc> 9776 </param> 9777 <param name="type" type="SymlinkType" dir="in"> 9778 <desc>TODO</desc> 9779 </param> 9765 9780 </method> 9766 9781 9767 <method name="Symlink Create">9782 <method name="SymlinkExists"> 9768 9783 <desc> 9769 9784 TODO … … 9773 9788 </result> 9774 9789 </desc> 9775 <param name="s ource" type="wstring" dir="in">9790 <param name="symlink" type="wstring" dir="in"> 9776 9791 <desc>TODO</desc> 9777 9792 </param> 9778 <param name=" target" type="wstring" dir="in">9793 <param name="exists" type="boolean" dir="return"> 9779 9794 <desc>TODO</desc> 9780 9795 </param> 9781 <param name="type" type="SymlinkType" dir="in">9782 <desc>TODO</desc>9783 </param>9784 9796 </method> 9785 9797 9786 <method name="Symlink Exists">9798 <method name="SymlinkRead"> 9787 9799 <desc> 9788 9800 TODO … … 9795 9807 <desc>TODO</desc> 9796 9808 </param> 9797 <param name=" exists" type="boolean" dir="return">9809 <param name="flags" type="SymlinkReadFlag" dir="in" safearray="yes"> 9798 9810 <desc>TODO</desc> 9799 9811 </param> 9812 <param name="target" type="wstring" dir="return"> 9813 <desc>TODO</desc> 9814 </param> 9800 9815 </method> 9801 9816 9802 <method name="SymlinkRe ad">9817 <method name="SymlinkRemoveDirectory"> 9803 9818 <desc> 9804 9819 TODO … … 9808 9823 </result> 9809 9824 </desc> 9810 <param name=" symlink" type="wstring" dir="in">9825 <param name="path" type="wstring" dir="in"> 9811 9826 <desc>TODO</desc> 9812 9827 </param> 9813 <param name="flags" type="SymlinkReadFlag" dir="in" safearray="yes">9814 <desc>TODO</desc>9815 </param>9816 <param name="target" type="wstring" dir="return">9817 <desc>TODO</desc>9818 </param>9819 9828 </method> 9820 9829 9821 <method name="SymlinkRemove Directory">9830 <method name="SymlinkRemoveFile"> 9822 9831 <desc> 9823 9832 TODO … … 9827 9836 </result> 9828 9837 </desc> 9829 <param name="path" type="wstring" dir="in">9830 <desc>TODO</desc>9831 </param>9832 </method>9833 9834 <method name="SymlinkRemoveFile">9835 <desc>9836 TODO9837 9838 <result name="VBOX_E_NOT_SUPPORTED">9839 TODO9840 </result>9841 </desc>9842 9838 <param name="file" type="wstring" dir="in"> 9843 9839 <desc>TODO</desc> … … 9849 9845 <interface 9850 9846 name="IProcess" extends="$unknown" 9851 uuid=" 8a308a2f-bea6-4786-80a0-4d07cd4bacaa"9847 uuid="f55af4a1-e280-40ac-83e1-921c0abcaf18" 9852 9848 wsmap="managed" 9853 9849 > … … 9903 9899 </desc> 9904 9900 </attribute> 9901 <attribute name="name" type="wstring" readonly="yes"> 9902 <desc> 9903 TODO 9904 <note> 9905 TODO 9906 </note> 9907 </desc> 9908 </attribute> 9905 9909 9906 9910 <method name="WaitFor"> 9907 9911 <desc> 9908 9912 TODO 9913 9914 <result name="VBOX_E_NOT_SUPPORTED"> 9915 TODO 9916 </result> 9917 </desc> 9918 <param name="waitFor" type="unsigned long" dir="in"> 9919 <desc>TODO</desc> 9920 </param> 9921 <param name="timeoutMS" type="unsigned long" dir="in"> 9922 <desc>TODO</desc> 9923 </param> 9924 <param name="reason" type="ProcessWaitResult" dir="return"> 9925 <desc>TODO</desc> 9926 </param> 9927 </method> 9928 9929 <method name="WaitForArray"> 9930 <desc> 9931 Scriptable version of <link to="#waitFor" />. 9909 9932 9910 9933 <result name="VBOX_E_NOT_SUPPORTED"> … … 10388 10411 <interface 10389 10412 name="IGuest" extends="$unknown" 10390 uuid=" 1413d910-e533-47af-a71b-919c106d2472"10413 uuid="9e0b07b1-490f-4413-8955-0a16515aac12" 10391 10414 wsmap="managed" 10392 10415 > … … 10805 10828 </desc> 10806 10829 </param> 10807 </method> 10830 </method> 10831 10832 <method name="findSession"> 10833 <desc> 10834 TODO 10835 </desc> 10836 <param name="sessionName" type="wstring" dir="in"> 10837 <desc> 10838 TODO 10839 </desc> 10840 </param> 10841 <param name="sessions" type="IGuestSession" safearray="yes" dir="return"> 10842 <desc> 10843 TODO 10844 </desc> 10845 </param> 10846 </method> 10808 10847 10809 10848 <method name="executeProcess"> -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42358 r42411 127 127 void Destroy(void); 128 128 129 int FillData(const void *pData, size_t cbData); 130 129 131 int Init(eVBoxGuestCtrlCallbackType enmType); 130 132 -
trunk/src/VBox/Main/include/GuestImpl.h
r42354 r42411 134 134 STDMETHOD(UpdateGuestAdditions)(IN_BSTR aSource, ULONG aFlags, IProgress **aProgress); 135 135 STDMETHOD(CreateSession)(IN_BSTR aUser, IN_BSTR aPassword, IN_BSTR aDomain, IN_BSTR aSessionName, IGuestSession **aGuestSession); 136 STDMETHOD(FindSession)(IN_BSTR aSessionName, ComSafeArrayOut(IGuestSession *, aSessions)); 136 137 137 138 // Public methods that are not in IDL (only called internally). -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42358 r42411 57 57 STDMETHOD(COMGETTER(ExecutablePath))(BSTR *aExecutablePath); 58 58 STDMETHOD(COMGETTER(ExitCode))(LONG *aExitCode); 59 STDMETHOD(COMGETTER(Name))(BSTR *aName); 59 60 STDMETHOD(COMGETTER(Pid))(ULONG *aPID); 60 61 STDMETHOD(COMGETTER(Status))(ProcessStatus_T *aStatus); … … 62 63 STDMETHOD(Read)(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData)); 63 64 STDMETHOD(Terminate)(void); 64 STDMETHOD(WaitFor)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason); 65 STDMETHOD(WaitFor)(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason); 66 STDMETHOD(WaitForArray)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason); 65 67 STDMETHOD(Write)(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten); 66 68 /** @} */ … … 79 81 int terminateProcess(void); 80 82 int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult); 81 HRESULT waitResultToErrorEx(const GuestProcessWaitResult &waitResult, bool fLog);82 83 int writeData(ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten); 83 84 /** @} */ … … 88 89 inline int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID); 89 90 inline int callbackRemove(ULONG uContextID); 91 inline bool isAlive(void); 92 HRESULT hgcmResultToError(int rc); 90 93 int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData); 91 94 int onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData); … … 96 99 int signalWaiters(ProcessWaitResult_T enmWaitResult, int rc = VINF_SUCCESS); 97 100 static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser); 101 HRESULT waitResultToErrorEx(const GuestProcessWaitResult &waitResult, bool fLog); 98 102 /** @} */ 99 103 … … 109 113 /** All related callbacks to this process. */ 110 114 GuestCtrlCallbacks mCallbacks; 115 /** The process' name. */ 116 Utf8Str mName; 111 117 /** The process start information. */ 112 118 GuestProcessInfo mProcess; … … 119 125 /** The current process status. */ 120 126 ProcessStatus_T mStatus; 121 /** Flag indicating whether the process has been started122 * so that it can't be started a second time. */123 bool mStarted;124 127 /** The next upcoming context ID. */ 125 128 ULONG mNextContextID; 129 /** The mutex for protecting the waiter(s). */ 130 RTSEMMUTEX mWaitMutex; 126 131 /** How many waiters? At the moment there can only 127 132 * be one. */ -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42354 r42411 61 61 STDMETHOD(COMGETTER(Id))(ULONG *aId); 62 62 STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout); 63 STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout); 63 64 STDMETHOD(COMGETTER(Environment))(ComSafeArrayOut(BSTR, aEnvironment)); 64 65 STDMETHOD(COMGETTER(Processes))(ComSafeArrayOut(IGuestProcess *, aProcesses)); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42354 r42411 2834 2834 } 2835 2835 2836 STDMETHODIMP Guest::FindSession(IN_BSTR aSessionName, ComSafeArrayOut(IGuestSession *, aSessions)) 2837 { 2838 ReturnComNotImplemented(); 2839 } 2840 -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42358 r42411 206 206 } 207 207 cbData = 0; 208 } 209 210 int GuestCtrlCallback::FillData(const void *pData, size_t cbData) 211 { 212 if (!cbData) 213 return VINF_SUCCESS; 214 AssertPtr(pData); 215 216 Assert(pvData == NULL); /* Can't reuse callbacks! */ 217 pvData = RTMemAlloc(cbData); 218 if (!pvData) 219 return VERR_NO_MEMORY; 220 221 memcpy(pvData, pData, cbData); 222 223 return VINF_SUCCESS; 208 224 } 209 225 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42358 r42411 75 75 mData.mProcessID = 0; 76 76 mData.mStatus = ProcessStatus_Undefined; 77 mData.mStarted = false;78 77 79 78 mData.mWaitCount = 0; 80 mData.mWaitEvent = N IL_RTSEMEVENT;79 mData.mWaitEvent = NULL; 81 80 82 81 HRESULT hr = BaseFinalConstruct(); … … 148 147 LogFlowThisFuncEnter(); 149 148 149 CheckComArgOutSafeArrayPointerValid(aArguments); 150 150 151 AutoCaller autoCaller(this); 151 152 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 152 153 CheckComArgOutSafeArrayPointerValid(aArguments);154 153 155 154 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); … … 179 178 LogFlowThisFuncEnter(); 180 179 180 CheckComArgOutSafeArrayPointerValid(aEnvironment); 181 181 182 AutoCaller autoCaller(this); 182 183 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 183 184 CheckComArgOutSafeArrayPointerValid(aEnvironment);185 184 186 185 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); … … 206 205 LogFlowThisFuncEnter(); 207 206 207 CheckComArgOutPointerValid(aExecutablePath); 208 208 209 AutoCaller autoCaller(this); 209 210 if (FAILED(autoCaller.rc())) return autoCaller.rc(); … … 225 226 LogFlowThisFuncEnter(); 226 227 228 CheckComArgOutPointerValid(aExitCode); 229 227 230 AutoCaller autoCaller(this); 228 231 if (FAILED(autoCaller.rc())) return autoCaller.rc(); … … 237 240 } 238 241 239 STDMETHODIMP GuestProcess::COMGETTER( Pid)(ULONG *aPID)242 STDMETHODIMP GuestProcess::COMGETTER(Name)(BSTR *aName) 240 243 { 241 244 #ifndef VBOX_WITH_GUEST_CONTROL … … 243 246 #else 244 247 LogFlowThisFuncEnter(); 248 249 CheckComArgOutPointerValid(aName); 250 251 AutoCaller autoCaller(this); 252 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 253 254 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 255 256 mData.mName.cloneTo(aName); 257 258 LogFlowFuncLeaveRC(S_OK); 259 return S_OK; 260 #endif /* VBOX_WITH_GUEST_CONTROL */ 261 } 262 263 STDMETHODIMP GuestProcess::COMGETTER(Pid)(ULONG *aPID) 264 { 265 #ifndef VBOX_WITH_GUEST_CONTROL 266 ReturnComNotImplemented(); 267 #else 268 LogFlowThisFuncEnter(); 269 270 CheckComArgOutPointerValid(aPID); 245 271 246 272 AutoCaller autoCaller(this); … … 436 462 } 437 463 464 inline bool GuestProcess::isAlive(void) 465 { 466 return ( mData.mStatus == ProcessStatus_Started 467 || mData.mStatus == ProcessStatus_Paused 468 || mData.mStatus == ProcessStatus_Terminating); 469 } 470 438 471 void GuestProcess::close(void) 439 472 { … … 467 500 } 468 501 502 HRESULT GuestProcess::hgcmResultToError(int rc) 503 { 504 if (RT_SUCCESS(rc)) 505 return S_OK; 506 507 HRESULT hr; 508 if (rc == VERR_INVALID_VM_HANDLE) 509 hr = setErrorNoLog(VBOX_E_VM_ERROR, 510 tr("VMM device is not available (is the VM running?)")); 511 else if (rc == VERR_NOT_FOUND) 512 hr = setErrorNoLog(VBOX_E_IPRT_ERROR, 513 tr("The guest execution service is not ready (yet)")); 514 else if (rc == VERR_HGCM_SERVICE_NOT_FOUND) 515 hr= setErrorNoLog(VBOX_E_IPRT_ERROR, 516 tr("The guest execution service is not available")); 517 else /* HGCM call went wrong. */ 518 hr = setErrorNoLog(E_UNEXPECTED, 519 tr("The HGCM call failed with error %Rrc"), rc); 520 return hr; 521 } 522 469 523 bool GuestProcess::isReady(void) 470 524 { … … 518 572 uint32_t uWaitFlags = mData.mWaitEvent 519 573 ? mData.mWaitEvent->GetWaitFlags() : 0; 520 if ( (uWaitFlags & ProcessWaitForFlag_Status) 521 || (uWaitFlags & ProcessWaitForFlag_StdIn)) 574 if (uWaitFlags & ProcessWaitForFlag_StdIn) 522 575 rc = signalWaiters(ProcessWaitResult_StdIn); 523 576 AssertRC(rc); … … 556 609 mData.mStatus = ProcessStatus_Started; 557 610 mData.mPID = pData->u32PID; 558 mData.mStarted = true;559 611 break; 560 612 } … … 562 614 case PROC_STS_TEN: 563 615 { 564 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);616 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 565 617 enmWaitResult = ProcessWaitResult_Status; 566 618 … … 572 624 case PROC_STS_TES: 573 625 { 574 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);626 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 575 627 enmWaitResult = ProcessWaitResult_Status; 576 628 … … 584 636 case PROC_STS_TEA: 585 637 { 586 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);638 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 587 639 enmWaitResult = ProcessWaitResult_Status; 588 640 … … 595 647 case PROC_STS_TOK: 596 648 { 597 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);649 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 598 650 enmWaitResult = ProcessWaitResult_Timeout; 599 651 … … 606 658 case PROC_STS_TOA: 607 659 { 608 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);660 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 609 661 enmWaitResult = ProcessWaitResult_Timeout; 610 662 … … 617 669 case PROC_STS_DWN: 618 670 { 619 fSignal = (uWaitFlags & ProcessWaitForFlag_ Exit);671 fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate); 620 672 enmWaitResult = ProcessWaitResult_Status; 621 673 … … 667 719 rc = pCallback->Signal(callbackRC); 668 720 669 if (!fSignal)670 fSignal = (uWaitFlags & ProcessWaitForFlag_Status);671 721 if (fSignal) 672 722 { … … 688 738 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData)); 689 739 690 int rc = VINF_SUCCESS; 691 692 /** @todo Fill data into callback. */ 740 /* Copy data into callback. */ 741 int rc = pCallback->FillData(pData->pvData, pData->cbData); 693 742 694 743 /* First, signal callback in every case. */ 695 pCallback->Signal(); 744 int rc2 = pCallback->Signal(); 745 if (RT_SUCCESS(rc)) 746 rc = rc2; 696 747 697 748 /* Then do the WaitFor signalling stuff. */ … … 716 767 } 717 768 718 if (!fSignal)719 fSignal = (uWaitFlags & ProcessWaitForFlag_Status);720 721 769 if (fSignal) 722 rc = signalWaiters( pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT 723 ? ProcessWaitResult_StdOut : ProcessWaitResult_StdErr); 770 { 771 rc2 = signalWaiters( pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT 772 ? ProcessWaitResult_StdOut : ProcessWaitResult_StdErr); 773 if (RT_SUCCESS(rc)) 774 rc = rc2; 775 } 724 776 AssertRC(rc); 725 777 … … 767 819 enmWaitResult, rc, mData.mWaitCount, mData.mWaitEvent)); 768 820 769 /* Note: No locking here -- already done in the callback dispatcher. */ 770 771 AssertPtr(mData.mWaitEvent); 772 int rc2 = mData.mWaitEvent->Signal(enmWaitResult, rc); 821 /* Note: No write locking here -- already done in the callback dispatcher. */ 822 823 int rc2 = VINF_SUCCESS; 824 if (mData.mWaitEvent) 825 rc2 = mData.mWaitEvent->Signal(enmWaitResult, rc); 773 826 LogFlowFuncLeaveRC(rc2); 774 827 return rc2; … … 780 833 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags)); 781 834 782 AssertReturn(!mData.mStarted, VERR_ALREADY_EXISTS); 835 /* Wait until the caller function (if kicked off by a thread) 836 * has returned and continue operation. */ 837 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 783 838 784 839 int rc; … … 788 843 return VERR_NO_MEMORY; 789 844 790 { 791 /* Wait until the caller function (if kicked off by a thread) 792 * has returned and continue operation. */ 793 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 794 795 mData.mStatus = ProcessStatus_Starting; 796 797 /* Create callback and add it to the map. */ 798 rc = pCallbackStart->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START); 799 if (RT_SUCCESS(rc)) 800 rc = callbackAdd(pCallbackStart, &uContextID); 801 } 802 845 mData.mStatus = ProcessStatus_Starting; 846 847 /* Create callback and add it to the map. */ 848 rc = pCallbackStart->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START); 803 849 if (RT_SUCCESS(rc)) 804 { 805 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 850 rc = callbackAdd(pCallbackStart, &uContextID); 851 852 if (RT_SUCCESS(rc)) 853 { 854 // AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 806 855 807 856 GuestSession *pSession = mData.mParent; … … 867 916 RTStrFree(pszArgs); 868 917 918 if (RT_FAILURE(rc)) 919 mData.mStatus = ProcessStatus_Error; 920 869 921 uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS; 870 922 … … 877 929 * Note: Be sure not keeping a AutoRead/WriteLock here. 878 930 */ 879 LogFlowFunc(( tr("Waiting for callback (%RU32ms) ...\n"), uTimeoutMS));931 LogFlowFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS)); 880 932 rc = pCallbackStart->Wait(uTimeoutMS); 881 933 if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */ 882 934 { 883 935 rc = pCallbackStart->GetResultCode(); 884 LogFlowFunc(( tr("Callback returned rc=%Rrc\n"), rc));936 LogFlowFunc(("Callback returned rc=%Rrc\n", rc)); 885 937 } 886 938 else … … 936 988 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 937 989 938 int rcIgnored = pProcess->startProcess(); 939 LogFlowFuncLeaveRC(rcIgnored); 990 int rc = pProcess->startProcess(); 991 if (RT_FAILURE(rc)) 992 { 993 /** @todo What now? */ 994 } 995 996 LogFlowFuncLeaveRC(rc); 940 997 return VINF_SUCCESS; 941 998 } … … 951 1008 int GuestProcess::waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult) 952 1009 { 953 LogFlowFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n", 954 fWaitFlags, uTimeoutMS, mData.mWaitCount, mData.mWaitEvent)); 1010 LogFlowThisFuncEnter(); 955 1011 956 1012 AssertReturn(fWaitFlags, VERR_INVALID_PARAMETER); 957 1013 958 1014 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1015 1016 LogFlowFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mStatus=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n", 1017 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent)); 1018 1019 ProcessStatus curStatus = mData.mStatus; 1020 1021 guestResult.mResult = ProcessWaitResult_None; 1022 guestResult.mRC = VINF_SUCCESS; 1023 1024 #if 1 1025 if ( (fWaitFlags & ProcessWaitForFlag_Start) 1026 && (curStatus != ProcessStatus_Undefined)) 1027 { 1028 guestResult.mResult = ProcessWaitResult_Start; /** @todo Fix this. */ 1029 } 1030 #else 1031 if ( (fWaitFlags & ProcessWaitForFlag_Terminate) 1032 || (fWaitFlags & ProcessWaitForFlag_StdIn) 1033 || (fWaitFlags & ProcessWaitForFlag_StdOut) 1034 || (fWaitFlags & ProcessWaitForFlag_StdErr)) 1035 { 1036 switch (mData.mStatus) 1037 { 1038 case ProcessStatus_TerminatedNormally: 1039 case ProcessStatus_TerminatedSignal: 1040 case ProcessStatus_TerminatedAbnormally: 1041 case ProcessStatus_Down: 1042 guestResult.mResult = ProcessWaitResult_Terminate; 1043 break; 1044 1045 case ProcessStatus_TimedOutKilled: 1046 case ProcessStatus_TimedOutAbnormally: 1047 guestResult.mResult = ProcessWaitResult_Timeout; 1048 break; 1049 1050 case ProcessStatus_Error: 1051 guestResult.mResult = ProcessWaitResult_Error; 1052 break; 1053 1054 default: 1055 AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus)); 1056 return VERR_NOT_IMPLEMENTED; 1057 } 1058 } 1059 else if (fWaitFlags & ProcessWaitForFlag_Start) 1060 { 1061 switch (mData.mStatus) 1062 { 1063 case ProcessStatus_Started: 1064 case ProcessStatus_Paused: 1065 case ProcessStatus_Terminating: 1066 guestResult.mResult = ProcessWaitResult_Start; 1067 break; 1068 1069 default: 1070 AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus)); 1071 return VERR_NOT_IMPLEMENTED; 1072 } 1073 } 1074 #endif 1075 1076 /* No waiting needed? Return immediately. */ 1077 if (guestResult.mResult != ProcessWaitResult_None) 1078 return VINF_SUCCESS; 959 1079 960 1080 if (mData.mWaitCount > 0) … … 962 1082 mData.mWaitCount++; 963 1083 964 Assert(mData.mWaitEvent == N IL_RTSEMEVENT);1084 Assert(mData.mWaitEvent == NULL); 965 1085 mData.mWaitEvent = new GuestProcessEvent(fWaitFlags); 966 1086 AssertPtrReturn(mData.mWaitEvent, VERR_NO_MEMORY); … … 971 1091 if (RT_SUCCESS(rc)) 972 1092 guestResult = mData.mWaitEvent->GetResult(); 1093 1094 alock.acquire(); /* Get the lock again. */ 973 1095 974 1096 /* Note: The caller always is responsible of deleting the … … 977 1099 mData.mWaitEvent = NULL; 978 1100 1101 mData.mWaitCount--; 1102 979 1103 LogFlowFuncLeaveRC(rc); 980 1104 return rc; … … 996 1120 997 1121 case ProcessStatus_TerminatedNormally: 998 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated normally (exit code: % d)"),1122 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated normally (exit code: %ld)"), 999 1123 mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode); 1000 1124 break; … … 1002 1126 case ProcessStatus_TerminatedSignal: 1003 1127 { 1004 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated through signal (signal: % d)"),1128 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated through signal (signal: %ld)"), 1005 1129 mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode); 1006 1130 break; … … 1009 1133 case ProcessStatus_TerminatedAbnormally: 1010 1134 { 1011 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated abnormally (exit code: % d)"),1135 strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated abnormally (exit code: %ld)"), 1012 1136 mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode); 1013 1137 break; … … 1084 1208 break; 1085 1209 1210 case VERR_NOT_AVAILABLE: 1211 strMsg += Utf8StrFmt(tr("Guest control service is not ready")); 1212 1086 1213 default: 1087 1214 strMsg += Utf8StrFmt(tr("Reported error %Rrc"), rc); … … 1183 1310 } 1184 1311 1185 STDMETHODIMP GuestProcess::WaitFor(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason) 1312 STDMETHODIMP GuestProcess::WaitFor(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason) 1313 { 1314 #ifndef VBOX_WITH_GUEST_CONTROL 1315 ReturnComNotImplemented(); 1316 #else 1317 LogFlowThisFuncEnter(); 1318 1319 CheckComArgOutPointerValid(aReason); 1320 1321 AutoCaller autoCaller(this); 1322 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1323 1324 /* 1325 * Note: Do not hold any locks here while waiting! 1326 */ 1327 HRESULT hr; 1328 1329 GuestProcessWaitResult waitRes; 1330 int rc = waitFor(aWaitFlags, aTimeoutMS, waitRes); 1331 if (RT_SUCCESS(rc)) 1332 { 1333 hr = waitResultToErrorEx(waitRes, true /* fLog */); 1334 if (SUCCEEDED(hr)) 1335 *aReason = waitRes.mResult; 1336 } 1337 else 1338 hr = setError(VBOX_E_IPRT_ERROR, 1339 tr("Waiting for process \"%s\" (PID %RU32) failed with rc=%Rrc"), 1340 mData.mProcess.mCommand.c_str(), mData.mPID, rc); 1341 LogFlowFuncLeaveRC(hr); 1342 return hr; 1343 #endif /* VBOX_WITH_GUEST_CONTROL */ 1344 } 1345 1346 STDMETHODIMP GuestProcess::WaitForArray(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason) 1186 1347 { 1187 1348 #ifndef VBOX_WITH_GUEST_CONTROL … … 1203 1364 fWaitFor |= flags[i]; 1204 1365 1205 HRESULT hr; 1206 1207 GuestProcessWaitResult guestResult; 1208 int rc = waitFor(fWaitFor, aTimeoutMS, guestResult); 1209 if (RT_SUCCESS(rc)) 1210 { 1211 hr = waitResultToErrorEx(guestResult, true /* fLog */); 1212 if (SUCCEEDED(hr)) 1213 *aReason = guestResult.mResult; 1214 } 1215 else 1216 hr = setError(VBOX_E_IPRT_ERROR, 1217 tr("Waiting for process \"%s\" (PID %RU32) failed with rc=%Rrc"), 1218 mData.mProcess.mCommand.c_str(), mData.mPID, rc); 1366 HRESULT hr = WaitFor(fWaitFor, aTimeoutMS, aReason); 1367 1219 1368 LogFlowFuncLeaveRC(hr); 1220 1369 return hr; -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42354 r42411 240 240 } 241 241 242 STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout) 243 { 244 #ifndef VBOX_WITH_GUEST_CONTROL 245 ReturnComNotImplemented(); 246 #else 247 LogFlowThisFuncEnter(); 248 249 AutoCaller autoCaller(this); 250 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 251 252 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 253 254 mData.mTimeout = aTimeout; 255 256 LogFlowFuncLeaveRC(S_OK); 257 return S_OK; 258 #endif /* VBOX_WITH_GUEST_CONTROL */ 259 } 260 242 261 STDMETHODIMP GuestSession::COMGETTER(Environment)(ComSafeArrayOut(BSTR, aEnvironment)) 243 262 { … … 435 454 && !(procInfo.mFlags & ProcessCreateFlag_WaitForProcessStartOnly) 436 455 && !(procInfo.mFlags & ProcessCreateFlag_Hidden) 437 && !(procInfo.mFlags & ProcessCreateFlag_NoProfile)) 456 && !(procInfo.mFlags & ProcessCreateFlag_NoProfile) 457 && !(procInfo.mFlags & ProcessCreateFlag_WaitForStdOut) 458 && !(procInfo.mFlags & ProcessCreateFlag_WaitForStdErr)) 438 459 { 439 460 return VERR_INVALID_PARAMETER;
Note:
See TracChangeset
for help on using the changeset viewer.