- Timestamp:
- Jul 30, 2013 9:43:14 AM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r47401 r47469 9587 9587 <desc> 9588 9588 A guest user currently is not using the guest OS. 9589 <note>Currently only available for Windows guests since 9589 <note>Currently only available for Windows guests since 9590 9590 Windows 2000 SP2.</note> 9591 9591 <note>On Windows guests this function currently only supports … … 9595 9595 VBoxService's command line on the guest to 9596 9596 <pre>--vminfo-user-idle-threshold <ms></pre> 9597 , or by setting the per-VM guest property 9597 , or by setting the per-VM guest property 9598 9598 <pre>/VirtualBox/GuestAdd/VBoxService/--vminfo-user-idle-threshold <ms></pre> 9599 9599 with the RDONLYGUEST flag on the host. In both cases VBoxService needs … … 9602 9602 </const> 9603 9603 <const name="InUse" value="7"> 9604 <desc>A guest user continued using the guest OS after 9604 <desc>A guest user continued using the guest OS after 9605 9605 being idle.</desc> 9606 9606 </const> … … 10135 10135 <interface 10136 10136 name="IGuestSession" extends="$unknown" 10137 uuid=" c8e8607b-5e67-4073-8f14-146515d0c1ff"10137 uuid="1afeabbd-0c0b-458c-8026-04464892ae12" 10138 10138 wsmap="managed" 10139 10139 > … … 10183 10183 </result> 10184 10184 </desc> 10185 </attribute> 10186 <attribute name="protocolVersion" type="unsigned long" readonly="yes"> 10187 <desc>Returns the protocol version which is used by this session to 10188 communicate with the guest.</desc> 10185 10189 </attribute> 10186 10190 <attribute name="status" type="GuestSessionStatus" readonly="yes"> -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r45780 r47469 377 377 class GuestWaitEvent 378 378 { 379 379 380 public: 380 381 … … 387 388 const ComPtr<IEvent> Event(void) { return mEvent; }; 388 389 const std::list<VBoxEventType_T> Types(void) { return mEventTypes; }; 389 intSignal(IEvent *pEvent);390 virtual int Signal(IEvent *pEvent); 390 391 int Wait(RTMSINTERVAL uTimeoutMS); 391 392 392 393 protected: 393 394 395 /* Shutdown indicator. */ 396 bool fAborted; 397 /* Associated context ID (CID). */ 394 398 uint32_t mCID; 399 /** List of event types this event should 400 * be signalled on. */ 395 401 std::list<VBoxEventType_T> mEventTypes; 396 402 /** The event semaphore for triggering … … 418 424 public: 419 425 426 int baseInit(void); 427 void baseUninit(void); 428 int cancelWaitEvents(void); 420 429 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID); 421 int registerEvent(uint32_t uSessionID, uint32_t uObjectID, const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent); 422 void unregisterEvent(GuestWaitEvent *pEvent); 423 void unregisterEventListener(void); 430 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent); 431 void unregisterWaitEvent(GuestWaitEvent *pEvent); 424 432 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent); 425 433 … … 431 439 /** The next upcoming context ID for this object. */ 432 440 uint32_t mNextContextID; 433 /** Local listener for handling the waiting events. */ 434 ComPtr<IEventListener> mListener; 441 /** Local listener for handling the waiting events 442 * internally. */ 443 ComPtr<IEventListener> mLocalListener; 435 444 /** Critical section for wait events access. */ 436 445 RTCRITSECT mWaitEventCritSect; … … 463 472 464 473 int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID); 465 int register Event(const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent);474 int registerWaitEvent(const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent); 466 475 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms); 467 476 -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r45780 r47469 80 80 int readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, uint32_t *pcbRead, int *pGuestRc); 81 81 static HRESULT setErrorExternal(VirtualBoxBase *pInterface, int guestRc); 82 int startProcess( int *pGuestRc);82 int startProcess(uint32_t uTimeoutMS, int *pGuestRc); 83 83 int startProcessAsync(void); 84 int terminateProcess(int *pGuestRc); 84 int terminateProcess(uint32_t uTimeoutMS, int *pGuestRc); 85 static ProcessWaitResult_T waitFlagsToResultEx(uint32_t fWaitFlags, ProcessStatus_T procStatus, uint32_t uProcFlags, uint32_t uProtocol); 86 ProcessWaitResult_T waitFlagsToResult(uint32_t fWaitFlags); 85 87 int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, ProcessWaitResult_T &waitResult, int *pGuestRc); 86 88 int waitForInputNotify(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, ProcessInputStatus_T *pInputStatus, uint32_t *pcbProcessed); 87 89 int waitForOutput(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, void* pvData, size_t cbData, uint32_t *pcbRead); 88 int waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS, ProcessStatus_T *pProcessStatus, int *pGuestRc); 90 int waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, ProcessStatus_T *pProcessStatus, int *pGuestRc); 91 static bool waitResultImpliesEx(ProcessWaitResult_T waitResult, ProcessStatus_T procStatus, uint32_t uProcFlags, uint32_t uProtocol); 89 92 int writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten, int *pGuestRc); 90 93 /** @} */ … … 168 171 int TerminatedOk(LONG *pExitCode); 169 172 170 void Terminate(void);173 int Terminate(uint32_t uTimeoutMS, int *pGuestRc); 171 174 172 175 protected: -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r46524 r47469 273 273 STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout); 274 274 STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout); 275 STDMETHOD(COMGETTER(ProtocolVersion))(ULONG *aVersion); 275 276 STDMETHOD(COMGETTER(Environment))(ComSafeArrayOut(BSTR, aEnvironment)); 276 277 STDMETHOD(COMSETTER(Environment))(ComSafeArrayIn(IN_BSTR, aEnvironment)); … … 359 360 HRESULT isReadyExternal(void); 360 361 int onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData); 361 int startSessionInte nal(int *pGuestRc);362 int startSessionInternal(int *pGuestRc); 362 363 int startSessionAsync(void); 363 364 static DECLCALLBACK(int) … … 384 385 Guest *mParent; 385 386 /** 386 * This can safely be used without holding any locks. 387 * The session's event source. This source is used for 388 * serving the internal listener as well as all other 389 * external listeners that may register to it. 390 * 391 * Note: This can safely be used without holding any locks. 387 392 * An AutoCaller suffices to prevent it being destroy while in use and 388 393 * internally there is a lock providing the necessary serialization. -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r46526 r47469 115 115 #endif /* VBOX_WITH_GUEST_CONTROL */ 116 116 117 STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ComSafeArrayIn(IN_BSTR, aArguments), 117 STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ComSafeArrayIn(IN_BSTR, aArguments), 118 118 ComSafeArrayIn(AdditionsUpdateFlag_T, aFlags), IProgress **aProgress) 119 119 { … … 194 194 Assert(!pSession.isNull()); 195 195 int guestRc; 196 rc = pSession->startSessionInte nal(&guestRc);196 rc = pSession->startSessionInternal(&guestRc); 197 197 if (RT_FAILURE(rc)) 198 198 { … … 341 341 if (pSession == itSessions->second) 342 342 { 343 GuestSession *pCurSession = itSessions->second; 344 AssertPtr(pCurSession); 345 343 346 LogFlowFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n", 344 (GuestSession *)itSessions->second, itSessions->second->getId(), mData.mGuestSessions.size() - 1)); 347 pCurSession, pCurSession->getId(), mData.mGuestSessions.size() - 1)); 348 349 itSessions->second->Release(); 345 350 346 351 mData.mGuestSessions.erase(itSessions); … … 458 463 if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0')) 459 464 return setError(E_INVALIDARG, tr("No user name specified")); 465 if (RT_UNLIKELY((aPassword) == NULL || *(aPassword) == '\0')) 466 return setError(E_INVALIDARG, tr("No password specified")); 460 467 CheckComArgOutPointerValid(aGuestSession); 461 468 /* Rest is optional. */ -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r45801 r47469 25 25 26 26 #include <iprt/asm.h> 27 #include <iprt/cpp/utils.h> /* For unconst(). */ 27 28 #include <iprt/ctype.h> 28 29 #ifdef DEBUG … … 788 789 } 789 790 791 int GuestBase::baseInit(void) 792 { 793 int rc = RTCritSectInit(&mWaitEventCritSect); 794 795 LogFlowFuncLeaveRC(rc); 796 return rc; 797 } 798 799 void GuestBase::baseUninit(void) 800 { 801 LogFlowThisFuncEnter(); 802 803 int rc = RTCritSectDelete(&mWaitEventCritSect); 804 805 LogFlowFuncLeaveRC(rc); 806 /* No return value. */ 807 } 808 809 int GuestBase::cancelWaitEvents(void) 810 { 811 LogFlowThisFuncEnter(); 812 813 int rc = RTCritSectEnter(&mWaitEventCritSect); 814 if (RT_SUCCESS(rc)) 815 { 816 GuestWaitEventTypes::iterator itEventTypes = mWaitEvents.begin(); 817 while (itEventTypes != mWaitEvents.end()) 818 { 819 GuestWaitEvents::iterator itEvents = itEventTypes->second.begin(); 820 while (itEvents != itEventTypes->second.end()) 821 { 822 GuestWaitEvent *pEvent = (*itEvents); 823 AssertPtr(pEvent); 824 825 /* 826 * Just cancel the event and remove it from the wait events 827 * map. Don't delete it though, this (hopefully) is done by 828 * the caller using unregisterWaitEvent(). 829 */ 830 int rc2 = pEvent->Signal(NULL /* Cancel */); 831 AssertRC(rc2); 832 itEvents = itEventTypes->second.erase(itEvents); 833 } 834 835 itEventTypes = mWaitEvents.erase(itEventTypes); 836 } 837 838 int rc2 = RTCritSectLeave(&mWaitEventCritSect); 839 if (RT_SUCCESS(rc)) 840 rc = rc2; 841 } 842 843 LogFlowFuncLeaveRC(rc); 844 return rc; 845 } 846 790 847 int GuestBase::generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID) 791 848 { 792 849 AssertPtrReturn(puContextID, VERR_INVALID_POINTER); 793 850 794 uint32_t uCount = mNextContextID++;851 uint32_t uCount = ASMAtomicIncU32(&mNextContextID); 795 852 if (uCount == VBOX_GUESTCTRL_MAX_CONTEXTS) 796 853 uCount = 0; … … 804 861 } 805 862 806 int GuestBase::register Event(uint32_t uSessionID, uint32_t uObjectID,807 const std::list<VBoxEventType_T> &lstEvents,808 GuestWaitEvent **ppEvent)863 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, 864 const std::list<VBoxEventType_T> &lstEvents, 865 GuestWaitEvent **ppEvent) 809 866 { 810 867 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER); … … 871 928 } 872 929 873 void GuestBase::unregisterEvent(GuestWaitEvent *pEvent) 874 { 875 AssertPtrReturnVoid(pEvent); 930 void GuestBase::unregisterWaitEvent(GuestWaitEvent *pEvent) 931 { 932 if (!pEvent) /* Nothing to unregister. */ 933 return; 876 934 877 935 int rc = RTCritSectEnter(&mWaitEventCritSect); … … 897 955 898 956 delete pEvent; 957 pEvent = NULL; 899 958 900 959 int rc2 = RTCritSectLeave(&mWaitEventCritSect); … … 904 963 } 905 964 906 void GuestBase::unregisterEventListener(void)907 {908 if (mListener)909 {910 ComPtr<IEventSource> es;911 HRESULT hr = mConsole->COMGETTER(EventSource)(es.asOutParam());912 if (SUCCEEDED(hr))913 {914 Assert(!es.isNull());915 es->UnregisterListener(mListener);916 }917 918 mListener.setNull();919 }920 921 int rc2 = RTCritSectDelete(&mWaitEventCritSect);922 AssertRC(rc2);923 }924 925 965 int GuestBase::waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, 926 966 VBoxEventType_T *pType, IEvent **ppEvent) … … 943 983 vrc = VERR_COM_UNEXPECTED; 944 984 } 945 if (ppEvent) 985 if ( RT_SUCCESS(vrc) 986 && ppEvent) 946 987 pThisEvent.queryInterfaceTo(ppEvent); 988 989 unconst(pThisEvent).setNull(); 947 990 } 948 991 … … 973 1016 } 974 1017 975 int GuestObject::register Event(const std::list<VBoxEventType_T> &lstEvents,976 GuestWaitEvent **ppEvent)1018 int GuestObject::registerWaitEvent(const std::list<VBoxEventType_T> &lstEvents, 1019 GuestWaitEvent **ppEvent) 977 1020 { 978 1021 AssertPtr(mSession); 979 return GuestBase::register Event(mSession->getId(), mObjectID, lstEvents, ppEvent);1022 return GuestBase::registerWaitEvent(mSession->getId(), mObjectID, lstEvents, ppEvent); 980 1023 } 981 1024 … … 1009 1052 GuestWaitEvent::GuestWaitEvent(uint32_t uCID, 1010 1053 const std::list<VBoxEventType_T> &lstEvents) 1011 : mCID(uCID), 1054 : fAborted(false), 1055 mCID(uCID), 1012 1056 mEventTypes(lstEvents), 1013 1057 mEventSem(NIL_RTSEMEVENT) … … 1023 1067 } 1024 1068 1069 /** 1070 * Signals the event. Passing NULL will abort (cancel) 1071 * the event. 1072 * 1073 * @return IPRT status code. 1074 * @param pEvent IEvent to associate. 1075 */ 1025 1076 int GuestWaitEvent::Signal(IEvent *pEvent) 1026 1077 { 1027 AssertPtrReturn(pEvent, VERR_INVALID_POINTER);1028 1078 AssertReturn(mEventSem != NIL_RTSEMEVENT, VERR_CANCELLED); 1029 1079 1030 mEvent = pEvent; 1080 if (pEvent) 1081 mEvent = pEvent; 1082 else 1083 ASMAtomicWriteBool(&fAborted, true); 1031 1084 1032 1085 return RTSemEventSignal(mEventSem); … … 1035 1088 int GuestWaitEvent::Wait(RTMSINTERVAL uTimeoutMS) 1036 1089 { 1037 LogFlowThisFuncEnter(); 1038 1039 AssertReturn(mEventSem != NIL_RTSEMEVENT, VERR_CANCELLED); 1040 1041 RTMSINTERVAL msInterval = uTimeoutMS; 1042 if (!uTimeoutMS) 1043 msInterval = RT_INDEFINITE_WAIT; 1044 int rc = RTSemEventWait(mEventSem, msInterval); 1090 LogFlowThisFunc(("uTimeoutMS=%RU32ms\n", uTimeoutMS)); 1091 1092 int rc = VINF_SUCCESS; 1093 1094 if (ASMAtomicReadBool(&fAborted)) 1095 rc = VERR_CANCELLED; 1096 1097 if (RT_SUCCESS(rc)) 1098 { 1099 AssertReturn(mEventSem != NIL_RTSEMEVENT, VERR_CANCELLED); 1100 1101 RTMSINTERVAL msInterval = uTimeoutMS; 1102 if (!uTimeoutMS) 1103 msInterval = RT_INDEFINITE_WAIT; 1104 rc = RTSemEventWait(mEventSem, msInterval); 1105 if (ASMAtomicReadBool(&fAborted)) 1106 rc = VERR_CANCELLED; 1107 } 1045 1108 1046 1109 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r45078 r47469 2 2 /* $Id$ */ 3 3 /** @file 4 * VirtualBox Main - XXX.4 * VirtualBox Main - Guest directory handling. 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2012 Oracle Corporation8 * Copyright (C) 2012-2013 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 178 178 AssertPtr(mData.mSession); 179 179 int rc = mData.mSession->directoryRemoveFromList(this); 180 181 mData.mProcessTool.Terminate(); 180 AssertRC(rc); 181 182 HRESULT hr = S_OK; 183 184 int guestRc; 185 rc = mData.mProcessTool.Terminate(30 * 1000, &guestRc); 186 if (RT_FAILURE(rc)) 187 { 188 switch (rc) 189 { 190 case VERR_GSTCTL_GUEST_ERROR: 191 hr = GuestProcess::setErrorExternal(this, guestRc); 192 break; 193 194 case VERR_NOT_SUPPORTED: 195 /* Silently skip old Guest Additions which do not support killing the 196 * the guest directory handling process. */ 197 break; 198 199 default: 200 hr = setError(VBOX_E_IPRT_ERROR, 201 tr("Terminating open guest directory \"%s\" failed: %Rrc"), 202 mData.mName.c_str(), rc); 203 break; 204 } 205 } 182 206 183 207 /* … … 189 213 190 214 LogFlowFuncLeaveRC(rc); 191 return S_OK;215 return hr; 192 216 #endif /* VBOX_WITH_GUEST_CONTROL */ 193 217 } -
trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
r45805 r47469 175 175 if (SUCCEEDED(hr)) 176 176 { 177 mListener = thisListener;178 179 177 com::SafeArray <VBoxEventType_T> eventTypes; 180 178 eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); … … 182 180 eventTypes.push_back(VBoxEventType_OnGuestFileRead); 183 181 eventTypes.push_back(VBoxEventType_OnGuestFileWrite); 184 hr = mEventSource->RegisterListener( mListener,182 hr = mEventSource->RegisterListener(thisListener, 185 183 ComSafeArrayAsInParam(eventTypes), 186 184 TRUE /* Active listener */); 187 185 if (SUCCEEDED(hr)) 188 186 { 189 vrc = RTCritSectInit(&mWaitEventCritSect); 190 AssertRC(vrc); 187 vrc = baseInit(); 188 if (RT_SUCCESS(vrc)) 189 { 190 mLocalListener = thisListener; 191 } 191 192 } 192 193 else … … 229 230 230 231 #ifdef VBOX_WITH_GUEST_CONTROL 232 baseUninit(); 233 234 mEventSource->UnregisterListener(mLocalListener); 231 235 unconst(mEventSource).setNull(); 232 unregisterEventListener();233 236 #endif 234 237 … … 432 435 eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); 433 436 434 vrc = register Event(eventTypes, &pEvent);437 vrc = registerWaitEvent(eventTypes, &pEvent); 435 438 } 436 439 catch (std::bad_alloc) … … 452 455 vrc = waitForStatusChange(pEvent, 30 * 1000 /* Timeout in ms */, 453 456 NULL /* FileStatus */); 454 unregister Event(pEvent);457 unregisterWaitEvent(pEvent); 455 458 456 459 LogFlowFuncLeaveRC(vrc); … … 711 714 eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); 712 715 713 vrc = register Event(eventTypes, &pEvent);716 vrc = registerWaitEvent(eventTypes, &pEvent); 714 717 } 715 718 catch (std::bad_alloc) … … 739 742 NULL /* FileStatus */); 740 743 741 unregister Event(pEvent);744 unregisterWaitEvent(pEvent); 742 745 743 746 LogFlowFuncLeaveRC(vrc); … … 762 765 eventTypes.push_back(VBoxEventType_OnGuestFileRead); 763 766 764 vrc = register Event(eventTypes, &pEvent);767 vrc = registerWaitEvent(eventTypes, &pEvent); 765 768 } 766 769 catch (std::bad_alloc) … … 792 795 } 793 796 794 unregister Event(pEvent);797 unregisterWaitEvent(pEvent); 795 798 796 799 LogFlowFuncLeaveRC(vrc); … … 812 815 eventTypes.push_back(VBoxEventType_OnGuestFileRead); 813 816 814 vrc = register Event(eventTypes, &pEvent);817 vrc = registerWaitEvent(eventTypes, &pEvent); 815 818 } 816 819 catch (std::bad_alloc) … … 843 846 } 844 847 845 unregister Event(pEvent);848 unregisterWaitEvent(pEvent); 846 849 847 850 LogFlowFuncLeaveRC(vrc); … … 863 866 eventTypes.push_back(VBoxEventType_OnGuestFileOffsetChanged); 864 867 865 vrc = register Event(eventTypes, &pEvent);868 vrc = registerWaitEvent(eventTypes, &pEvent); 866 869 } 867 870 catch (std::bad_alloc) … … 885 888 vrc = waitForOffsetChange(pEvent, uTimeoutMS, puOffset); 886 889 887 unregister Event(pEvent);890 unregisterWaitEvent(pEvent); 888 891 889 892 LogFlowFuncLeaveRC(vrc); … … 1078 1081 eventTypes.push_back(VBoxEventType_OnGuestFileWrite); 1079 1082 1080 vrc = register Event(eventTypes, &pEvent);1083 vrc = registerWaitEvent(eventTypes, &pEvent); 1081 1084 } 1082 1085 catch (std::bad_alloc) … … 1109 1112 } 1110 1113 1111 unregister Event(pEvent);1114 unregisterWaitEvent(pEvent); 1112 1115 1113 1116 LogFlowFuncLeaveRC(vrc); … … 1132 1135 eventTypes.push_back(VBoxEventType_OnGuestFileWrite); 1133 1136 1134 vrc = register Event(eventTypes, &pEvent);1137 vrc = registerWaitEvent(eventTypes, &pEvent); 1135 1138 } 1136 1139 catch (std::bad_alloc) … … 1164 1167 } 1165 1168 1166 unregister Event(pEvent);1169 unregisterWaitEvent(pEvent); 1167 1170 1168 1171 LogFlowFuncLeaveRC(vrc); -
trunk/src/VBox/Main/src-client/GuestImpl.cpp
r47310 r47469 110 110 111 111 #ifdef VBOX_WITH_GUEST_CONTROL 112 unconst(mEventSource).createObject();113 Assert(!mEventSource.isNull());114 hr = mEventSource->init(static_cast<IGuest*>(this));112 hr = unconst(mEventSource).createObject(); 113 if (SUCCEEDED(hr)) 114 hr = mEventSource->init(static_cast<IGuest*>(this)); 115 115 #else 116 116 hr = S_OK; -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r45927 r47469 118 118 int rc2 = mProcess->signalWaitEvents(aType, aEvent); 119 119 #ifdef DEBUG_andy 120 LogFlow Func(("Signalling events of type=%ld, process=%p resulted in rc=%Rrc\n",121 aType, mProcess, rc2));120 LogFlowThisFunc(("Signalling events of type=%ld, process=%p resulted in rc=%Rrc\n", 121 aType, mProcess, rc2)); 122 122 #endif 123 123 break; … … 184 184 if (RT_SUCCESS(vrc)) 185 185 { 186 unconst(mEventSource).createObject(); 187 Assert(!mEventSource.isNull()); 188 hr = mEventSource->init(static_cast<IGuestProcess*>(this)); 186 hr = unconst(mEventSource).createObject(); 189 187 if (FAILED(hr)) 190 vrc = VERR_COM_UNEXPECTED; 188 vrc = VERR_NO_MEMORY; 189 else 190 { 191 hr = mEventSource->init(static_cast<IGuestProcess*>(this)); 192 if (FAILED(hr)) 193 vrc = VERR_COM_UNEXPECTED; 194 } 191 195 } 192 196 … … 203 207 if (SUCCEEDED(hr)) 204 208 { 205 mListener = thisListener;206 207 209 com::SafeArray <VBoxEventType_T> eventTypes; 208 210 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 209 211 eventTypes.push_back(VBoxEventType_OnGuestProcessInputNotify); 210 212 eventTypes.push_back(VBoxEventType_OnGuestProcessOutput); 211 hr = mEventSource->RegisterListener( mListener,213 hr = mEventSource->RegisterListener(thisListener, 212 214 ComSafeArrayAsInParam(eventTypes), 213 215 TRUE /* Active listener */); 214 216 if (SUCCEEDED(hr)) 215 217 { 216 vrc = RTCritSectInit(&mWaitEventCritSect); 217 AssertRC(vrc); 218 vrc = baseInit(); 219 if (RT_SUCCESS(vrc)) 220 { 221 mLocalListener = thisListener; 222 } 218 223 } 219 224 else … … 255 260 void GuestProcess::uninit(void) 256 261 { 257 LogFlowThisFunc(("mCmd=%s, PID=%RU32\n", 258 mData.mProcess.mCommand.c_str(), mData.mPID)); 262 LogFlowThisFuncEnter(); 259 263 260 264 /* Enclose the state transition Ready->InUninit->NotReady. */ … … 263 267 return; 264 268 265 int vrc = VINF_SUCCESS; 269 LogFlowThisFunc(("mCmd=%s, PID=%RU32\n", 270 mData.mProcess.mCommand.c_str(), mData.mPID)); 271 272 /* Terminate process if not already done yet. */ 273 int guestRc = VINF_SUCCESS; 274 int vrc = terminateProcess(30 * 1000, &guestRc); /** @todo Make timeouts configurable. */ 275 /* Note: Don't return here yet; first uninit all other stuff in 276 * case of failure. */ 266 277 267 278 #ifdef VBOX_WITH_GUEST_CONTROL 279 baseUninit(); 280 281 mEventSource->UnregisterListener(mLocalListener); 282 283 mLocalListener.setNull(); 268 284 unconst(mEventSource).setNull(); 269 unregisterEventListener();270 285 #endif 271 286 272 LogFlowFuncLeaveRC(vrc); 287 LogFlowThisFunc(("Returning rc=%Rrc, guestRc=%Rrc\n", 288 vrc, guestRc)); 273 289 } 274 290 … … 532 548 #ifndef DEBUG_andy 533 549 /* This should never happen! */ 534 AssertReleaseMsg(mData.mPID == uPID, ("Unterminated guest process ( PID %RU32) sent data to a newly started process (PID %RU32)\n",550 AssertReleaseMsg(mData.mPID == uPID, ("Unterminated guest process (guest PID %RU32) sent data to a newly started process (host PID %RU32)\n", 535 551 uPID, mData.mPID)); 536 552 #endif … … 665 681 666 682 vrc = checkPID(dataCb.uPID); 667 AssertRCReturn(vrc, vrc); 668 669 ProcessInputStatus_T inputStatus = ProcessInputStatus_Undefined; 670 switch (dataCb.uStatus) 671 { 672 case INPUT_STS_WRITTEN: 673 inputStatus = ProcessInputStatus_Written; 674 break; 675 case INPUT_STS_ERROR: 676 inputStatus = ProcessInputStatus_Broken; 677 break; 678 case INPUT_STS_TERMINATED: 679 inputStatus = ProcessInputStatus_Broken; 680 break; 681 case INPUT_STS_OVERFLOW: 682 inputStatus = ProcessInputStatus_Overflow; 683 break; 684 case INPUT_STS_UNDEFINED: 685 /* Fall through is intentional. */ 686 default: 687 AssertMsg(!dataCb.uProcessed, ("Processed data is not 0 in undefined input state\n")); 688 break; 689 } 690 691 if (inputStatus != ProcessInputStatus_Undefined) 692 { 693 fireGuestProcessInputNotifyEvent(mEventSource, mSession, this, 694 mData.mPID, 0 /* StdIn */, dataCb.uProcessed, inputStatus); 683 if (RT_SUCCESS(vrc)) 684 { 685 ProcessInputStatus_T inputStatus = ProcessInputStatus_Undefined; 686 switch (dataCb.uStatus) 687 { 688 case INPUT_STS_WRITTEN: 689 inputStatus = ProcessInputStatus_Written; 690 break; 691 case INPUT_STS_ERROR: 692 inputStatus = ProcessInputStatus_Broken; 693 break; 694 case INPUT_STS_TERMINATED: 695 inputStatus = ProcessInputStatus_Broken; 696 break; 697 case INPUT_STS_OVERFLOW: 698 inputStatus = ProcessInputStatus_Overflow; 699 break; 700 case INPUT_STS_UNDEFINED: 701 /* Fall through is intentional. */ 702 default: 703 AssertMsg(!dataCb.uProcessed, ("Processed data is not 0 in undefined input state\n")); 704 break; 705 } 706 707 if (inputStatus != ProcessInputStatus_Undefined) 708 { 709 fireGuestProcessInputNotifyEvent(mEventSource, mSession, this, 710 mData.mPID, 0 /* StdIn */, dataCb.uProcessed, inputStatus); 711 } 695 712 } 696 713 … … 709 726 int GuestProcess::onProcessStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData) 710 727 { 711 /* pCallback is optional. */728 AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER); 712 729 AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER); 713 730 … … 730 747 731 748 vrc = checkPID(dataCb.uPID); 732 AssertRCReturn(vrc, vrc);733 734 ProcessStatus_T procStatus = ProcessStatus_Undefined;735 int procRc = VINF_SUCCESS;736 737 switch (dataCb.uStatus)738 {739 case PROC_STS_STARTED:740 {741 procStatus = ProcessStatus_Started;742 mData.mPID = dataCb.uPID; /* Set the process PID. */743 break;744 }745 746 case PROC_STS_TEN:747 {748 procStatus = ProcessStatus_TerminatedNormally;749 mData.mExitCode = dataCb.uFlags; /* Contains the exit code. */750 break;751 }752 753 case PROC_STS_TES:754 {755 procStatus = ProcessStatus_TerminatedSignal;756 mData.mExitCode = dataCb.uFlags; /* Contains the signal. */757 break;758 }759 760 case PROC_STS_TEA:761 {762 procStatus = ProcessStatus_TerminatedAbnormally;763 break;764 }765 766 case PROC_STS_TOK:767 {768 procStatus = ProcessStatus_TimedOutKilled;769 break;770 }771 772 case PROC_STS_TOA:773 {774 procStatus = ProcessStatus_TimedOutAbnormally;775 break;776 }777 778 case PROC_STS_DWN:779 {780 procStatus = ProcessStatus_Down;781 break;782 }783 784 case PROC_STS_ERROR:785 {786 procRc = dataCb.uFlags; /* mFlags contains the IPRT error sent from the guest. */787 procStatus = ProcessStatus_Error;788 break;789 }790 791 case PROC_STS_UNDEFINED:792 default:793 {794 /* Silently skip this request. */795 procStatus = ProcessStatus_Undefined;796 break;797 }798 }799 800 LogFlowThisFunc(("Got rc=%Rrc, procSts=%ld, procRc=%Rrc\n",801 vrc, procStatus, procRc));802 803 /* Set the process status. */804 int rc2 = setProcessStatus(procStatus, procRc);805 749 if (RT_SUCCESS(vrc)) 806 vrc = rc2; 750 { 751 ProcessStatus_T procStatus = ProcessStatus_Undefined; 752 int procRc = VINF_SUCCESS; 753 754 switch (dataCb.uStatus) 755 { 756 case PROC_STS_STARTED: 757 { 758 procStatus = ProcessStatus_Started; 759 mData.mPID = dataCb.uPID; /* Set the process PID. */ 760 break; 761 } 762 763 case PROC_STS_TEN: 764 { 765 procStatus = ProcessStatus_TerminatedNormally; 766 mData.mExitCode = dataCb.uFlags; /* Contains the exit code. */ 767 break; 768 } 769 770 case PROC_STS_TES: 771 { 772 procStatus = ProcessStatus_TerminatedSignal; 773 mData.mExitCode = dataCb.uFlags; /* Contains the signal. */ 774 break; 775 } 776 777 case PROC_STS_TEA: 778 { 779 procStatus = ProcessStatus_TerminatedAbnormally; 780 break; 781 } 782 783 case PROC_STS_TOK: 784 { 785 procStatus = ProcessStatus_TimedOutKilled; 786 break; 787 } 788 789 case PROC_STS_TOA: 790 { 791 procStatus = ProcessStatus_TimedOutAbnormally; 792 break; 793 } 794 795 case PROC_STS_DWN: 796 { 797 procStatus = ProcessStatus_Down; 798 break; 799 } 800 801 case PROC_STS_ERROR: 802 { 803 procRc = dataCb.uFlags; /* mFlags contains the IPRT error sent from the guest. */ 804 procStatus = ProcessStatus_Error; 805 break; 806 } 807 808 case PROC_STS_UNDEFINED: 809 default: 810 { 811 /* Silently skip this request. */ 812 procStatus = ProcessStatus_Undefined; 813 break; 814 } 815 } 816 817 LogFlowThisFunc(("Got rc=%Rrc, procSts=%ld, procRc=%Rrc\n", 818 vrc, procStatus, procRc)); 819 820 /* Set the process status. */ 821 int rc2 = setProcessStatus(procStatus, procRc); 822 if (RT_SUCCESS(vrc)) 823 vrc = rc2; 824 } 807 825 808 826 LogFlowFuncLeaveRC(vrc); … … 832 850 833 851 vrc = checkPID(dataCb.uPID); 834 AssertRCReturn(vrc, vrc); 835 836 com::SafeArray<BYTE> data((size_t)dataCb.cbData); 837 if (dataCb.cbData) 838 data.initFrom((BYTE*)dataCb.pvData, dataCb.cbData); 839 840 fireGuestProcessOutputEvent(mEventSource, mSession, this, 841 mData.mPID, dataCb.uHandle, dataCb.cbData, ComSafeArrayAsInParam(data)); 852 if (RT_SUCCESS(vrc)) 853 { 854 com::SafeArray<BYTE> data((size_t)dataCb.cbData); 855 if (dataCb.cbData) 856 data.initFrom((BYTE*)dataCb.pvData, dataCb.cbData); 857 858 fireGuestProcessOutputEvent(mEventSource, mSession, this, 859 mData.mPID, dataCb.uHandle, dataCb.cbData, ComSafeArrayAsInParam(data)); 860 } 842 861 843 862 LogFlowFuncLeaveRC(vrc); … … 880 899 try 881 900 { 882 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 901 /* 902 * On Guest Additions < 4.3 there is no guarantee that the process status 903 * change arrives *after* the output event, e.g. if this was the last output 904 * block being read and the process will report status "terminate". 905 * So just skip checking for process status change and only wait for the 906 * output event. 907 */ 908 if (mSession->getProtocolVersion() >= 2) 909 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 883 910 eventTypes.push_back(VBoxEventType_OnGuestProcessOutput); 884 911 885 vrc = register Event(eventTypes, &pEvent);912 vrc = registerWaitEvent(eventTypes, &pEvent); 886 913 } 887 914 catch (std::bad_alloc) … … 911 938 pvData, cbData, pcbRead); 912 939 913 unregister Event(pEvent);940 unregisterWaitEvent(pEvent); 914 941 915 942 LogFlowFuncLeaveRC(vrc); … … 933 960 AssertMsg(RT_SUCCESS(procRc), ("Guest rc must not be an error (%Rrc)\n", procRc)); 934 961 935 if (mData.mStatus != procStatus) 962 if (mData.mStatus != procStatus) /* Was there a process status change? */ 936 963 { 937 964 mData.mStatus = procStatus; … … 965 992 } 966 993 967 int GuestProcess::startProcess( int *pGuestRc)968 { 969 LogFlowThisFunc((" aCmd=%s, aTimeoutMS=%RU32, fFlags=%x\n",970 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags));994 int GuestProcess::startProcess(uint32_t uTimeoutMS, int *pGuestRc) 995 { 996 LogFlowThisFunc(("uTimeoutMS=%RU32, procCmd=%s, procTimeoutMS=%RU32, procFlags=%x\n", 997 uTimeoutMS, mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags)); 971 998 972 999 /* Wait until the caller function (if kicked off by a thread) … … 984 1011 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 985 1012 986 vrc = register Event(eventTypes, &pEvent);1013 vrc = registerWaitEvent(eventTypes, &pEvent); 987 1014 } 988 1015 catch (std::bad_alloc) … … 1041 1068 if (RT_SUCCESS(vrc)) 1042 1069 vrc = mData.mProcess.mEnvironment.BuildEnvironmentBlock(&pvEnv, &cbEnv, NULL /* cEnv */); 1043 1044 uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS;1045 1070 1046 1071 if (RT_SUCCESS(vrc)) … … 1078 1103 paParms[i++].setUInt32(UINT32_MAX /* Infinite timeout */); 1079 1104 else 1080 paParms[i++].setUInt32( uTimeoutMS);1105 paParms[i++].setUInt32(mData.mProcess.mTimeoutMS); 1081 1106 if (uProtocol >= 2) 1082 1107 { … … 1104 1129 1105 1130 if (RT_SUCCESS(vrc)) 1106 vrc = waitForStatusChange(pEvent, ProcessWaitForFlag_Start,uTimeoutMS,1131 vrc = waitForStatusChange(pEvent, uTimeoutMS, 1107 1132 NULL /* Process status */, pGuestRc); 1108 unregister Event(pEvent);1133 unregisterWaitEvent(pEvent); 1109 1134 1110 1135 LogFlowFuncLeaveRC(vrc); … … 1158 1183 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1159 1184 1160 int vrc = pProcess->startProcess(NULL /* Guest rc, ignored */); 1185 int vrc = pProcess->startProcess(30 * 1000 /* 30s timeout */, 1186 NULL /* Guest rc, ignored */); 1161 1187 /* Nothing to do here anymore. */ 1162 1188 … … 1165 1191 } 1166 1192 1167 int GuestProcess::terminateProcess(int *pGuestRc) 1168 { 1169 LogFlowThisFuncEnter(); 1193 int GuestProcess::terminateProcess(uint32_t uTimeoutMS, int *pGuestRc) 1194 { 1195 /* pGuestRc is optional. */ 1196 LogFlowThisFunc(("uTimeoutMS=%RU32\n", uTimeoutMS)); 1170 1197 1171 1198 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1172 1199 1200 if (mData.mStatus != ProcessStatus_Started) 1201 { 1202 LogFlowThisFunc(("Process not started (yet), nothing to terminate\n")); 1203 return VINF_SUCCESS; /* Nothing to do (anymore). */ 1204 } 1205 1206 int vrc = VINF_SUCCESS; 1207 1173 1208 AssertPtr(mSession); 1174 if (mSession->getProtocolVersion() < 99) 1175 return VERR_NOT_SUPPORTED; 1176 1177 if (mData.mStatus != ProcessStatus_Started) 1178 return VINF_SUCCESS; /* Nothing to do (anymore). */ 1179 1180 int vrc; 1181 1182 GuestWaitEvent *pEvent = NULL; 1183 std::list < VBoxEventType_T > eventTypes; 1184 try 1185 { 1186 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 1187 1188 vrc = registerEvent(eventTypes, &pEvent); 1189 } 1190 catch (std::bad_alloc) 1191 { 1192 vrc = VERR_NO_MEMORY; 1193 } 1194 1195 if (RT_FAILURE(vrc)) 1196 return vrc; 1197 1198 VBOXHGCMSVCPARM paParms[4]; 1199 int i = 0; 1200 paParms[i++].setUInt32(pEvent->ContextID()); 1201 paParms[i++].setUInt32(mData.mPID); 1202 1203 alock.release(); /* Drop the write lock before sending. */ 1204 1205 vrc = sendCommand(HOST_EXEC_TERMINATE, i, paParms); 1209 /* Note: VBox < 4.3 (aka protocol version 1) does not 1210 * support this, so just skip. */ 1211 if (mSession->getProtocolVersion() < 2) 1212 vrc = VERR_NOT_SUPPORTED; 1213 1206 1214 if (RT_SUCCESS(vrc)) 1207 vrc = waitForStatusChange(pEvent, ProcessWaitForFlag_Terminate, 1208 30 * 1000 /* 30s timeout */, 1209 NULL /* ProcessStatus */, pGuestRc); 1210 unregisterEvent(pEvent); 1215 { 1216 GuestWaitEvent *pEvent = NULL; 1217 std::list < VBoxEventType_T > eventTypes; 1218 try 1219 { 1220 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 1221 1222 vrc = registerWaitEvent(eventTypes, &pEvent); 1223 } 1224 catch (std::bad_alloc) 1225 { 1226 vrc = VERR_NO_MEMORY; 1227 } 1228 1229 if (RT_FAILURE(vrc)) 1230 return vrc; 1231 1232 VBOXHGCMSVCPARM paParms[4]; 1233 int i = 0; 1234 paParms[i++].setUInt32(pEvent->ContextID()); 1235 paParms[i++].setUInt32(mData.mPID); 1236 1237 alock.release(); /* Drop the write lock before sending. */ 1238 1239 vrc = sendCommand(HOST_EXEC_TERMINATE, i, paParms); 1240 if (RT_SUCCESS(vrc)) 1241 vrc = waitForStatusChange(pEvent, uTimeoutMS, 1242 NULL /* ProcessStatus */, pGuestRc); 1243 unregisterWaitEvent(pEvent); 1244 } 1211 1245 1212 1246 LogFlowFuncLeaveRC(vrc); … … 1214 1248 } 1215 1249 1216 int GuestProcess::waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, ProcessWaitResult_T &waitResult, int *pGuestRc) 1217 { 1218 LogFlowThisFuncEnter(); 1219 1220 AssertReturn(fWaitFlags, VERR_INVALID_PARAMETER); 1221 1222 /*LogFlowThisFunc(("fWaitFlags=0x%x, uTimeoutMS=%RU32, mStatus=%RU32, mWaitCount=%RU32, mWaitEvent=%p, pGuestRc=%p\n", 1223 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent, pGuestRc));*/ 1224 1225 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1226 1227 /* Did some error occur before? Then skip waiting and return. */ 1228 if (mData.mStatus == ProcessStatus_Error) 1229 { 1230 waitResult = ProcessWaitResult_Error; 1231 AssertMsg(RT_FAILURE(mData.mRC), ("No error rc (%Rrc) set when guest process indicated an error\n", mData.mRC)); 1232 if (pGuestRc) 1233 *pGuestRc = mData.mRC; /* Return last set error. */ 1234 return VERR_GSTCTL_GUEST_ERROR; 1235 } 1236 1237 waitResult = ProcessWaitResult_None; 1250 /* static */ 1251 ProcessWaitResult_T GuestProcess::waitFlagsToResultEx(uint32_t fWaitFlags, 1252 ProcessStatus_T procStatus, uint32_t uProcFlags, 1253 uint32_t uProtocol) 1254 { 1255 ProcessWaitResult_T waitResult = ProcessWaitResult_None; 1256 1238 1257 if ( (fWaitFlags & ProcessWaitForFlag_Terminate) 1239 1258 || (fWaitFlags & ProcessWaitForFlag_StdIn) … … 1241 1260 || (fWaitFlags & ProcessWaitForFlag_StdErr)) 1242 1261 { 1243 switch ( mData.mStatus)1262 switch (procStatus) 1244 1263 { 1245 1264 case ProcessStatus_TerminatedNormally: … … 1266 1285 * anything here anymore and return. 1267 1286 */ 1268 if ( mData.mProcess.mFlags & ProcessCreateFlag_WaitForProcessStartOnly)1287 if (uProcFlags & ProcessCreateFlag_WaitForProcessStartOnly) 1269 1288 waitResult = ProcessWaitResult_Start; 1270 1289 break; … … 1273 1292 case ProcessStatus_Undefined: 1274 1293 case ProcessStatus_Starting: 1275 /* Do the waiting below. */1294 /* No result available yet. */ 1276 1295 break; 1277 1296 1278 1297 default: 1279 AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus));1280 return VERR_NOT_IMPLEMENTED;1298 AssertMsgFailed(("Unhandled process status %ld\n", procStatus)); 1299 break; 1281 1300 } 1282 1301 } 1283 1302 else if (fWaitFlags & ProcessWaitForFlag_Start) 1284 1303 { 1285 switch ( mData.mStatus)1304 switch (procStatus) 1286 1305 { 1287 1306 case ProcessStatus_Started: … … 1306 1325 case ProcessStatus_Undefined: 1307 1326 case ProcessStatus_Starting: 1308 /* Do the waiting below. */1327 /* No result available yet. */ 1309 1328 break; 1310 1329 1311 1330 default: 1312 AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus));1313 return VERR_NOT_IMPLEMENTED;1331 AssertMsgFailed(("Unhandled process status %ld\n", procStatus)); 1332 break; 1314 1333 } 1315 1334 } … … 1320 1339 ** @todo ProcessWaitForFlag_Std* flags are not implemented yet. 1321 1340 */ 1322 if ( mSession->getProtocolVersion() < 99)1341 if (uProtocol < 99) /* See @todo above. */ 1323 1342 { 1324 1343 if ( waitResult == ProcessWaitResult_None … … 1336 1355 } 1337 1356 1357 return waitResult; 1358 } 1359 1360 ProcessWaitResult_T GuestProcess::waitFlagsToResult(uint32_t fWaitFlags) 1361 { 1362 AssertPtr(mSession); 1363 return GuestProcess::waitFlagsToResultEx(fWaitFlags, mData.mStatus, mData.mProcess.mFlags, 1364 mSession->getProtocolVersion()); 1365 } 1366 1367 int GuestProcess::waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, ProcessWaitResult_T &waitResult, int *pGuestRc) 1368 { 1369 LogFlowThisFuncEnter(); 1370 1371 AssertReturn(fWaitFlags, VERR_INVALID_PARAMETER); 1372 1373 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1374 1375 LogFlowThisFunc(("fWaitFlags=0x%x, uTimeoutMS=%RU32, mStatus=%RU32, pGuestRc=%p\n", 1376 fWaitFlags, uTimeoutMS, mData.mStatus, pGuestRc)); 1377 1378 /* Did some error occur before? Then skip waiting and return. */ 1379 if (mData.mStatus == ProcessStatus_Error) 1380 { 1381 waitResult = ProcessWaitResult_Error; 1382 AssertMsg(RT_FAILURE(mData.mRC), ("No error rc (%Rrc) set when guest process indicated an error\n", mData.mRC)); 1383 if (pGuestRc) 1384 *pGuestRc = mData.mRC; /* Return last set error. */ 1385 return VERR_GSTCTL_GUEST_ERROR; 1386 } 1387 1388 waitResult = waitFlagsToResult(fWaitFlags); 1338 1389 LogFlowThisFunc(("procStatus=%ld, procRc=%Rrc, waitResult=%ld\n", 1339 1390 mData.mStatus, mData.mRC, waitResult)); … … 1357 1408 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 1358 1409 1359 vrc = register Event(eventTypes, &pEvent);1410 vrc = registerWaitEvent(eventTypes, &pEvent); 1360 1411 } 1361 1412 catch (std::bad_alloc) … … 1367 1418 return vrc; 1368 1419 1369 ProcessStatus_T processStatus; 1370 vrc = waitForStatusChange(pEvent, fWaitFlags, 1371 uTimeoutMS, &processStatus, pGuestRc); 1372 if (RT_SUCCESS(vrc)) 1373 { 1374 switch (processStatus) 1375 { 1376 case ProcessStatus_Started: 1377 waitResult = ProcessWaitResult_Start; 1378 break; 1379 1380 case ProcessStatus_TerminatedNormally: 1381 case ProcessStatus_TerminatedAbnormally: 1382 case ProcessStatus_TerminatedSignal: 1383 waitResult = ProcessWaitResult_Terminate; 1384 break; 1385 1386 case ProcessStatus_TimedOutKilled: 1387 case ProcessStatus_TimedOutAbnormally: 1388 waitResult = ProcessWaitResult_Timeout; 1389 break; 1390 1391 case ProcessStatus_Down: 1392 waitResult = ProcessWaitResult_Terminate; 1393 break; 1394 1395 case ProcessStatus_Error: 1396 waitResult = ProcessWaitResult_Error; 1397 break; 1398 1399 default: 1400 waitResult = ProcessWaitResult_Status; 1401 break; 1402 } 1403 } 1404 1405 unregisterEvent(pEvent); 1406 1407 LogFlowFuncLeaveRC(vrc); 1420 /* 1421 * Do the actual waiting. 1422 */ 1423 ProcessStatus_T processStatus = ProcessStatus_Undefined; 1424 uint64_t u64StartMS = RTTimeMilliTS(); 1425 for (;;) 1426 { 1427 uint64_t u32ElapsedMS = RTTimeMilliTS() - u64StartMS; 1428 if ( uTimeoutMS != RT_INDEFINITE_WAIT 1429 && u32ElapsedMS >= uTimeoutMS) 1430 { 1431 vrc = VERR_TIMEOUT; 1432 break; 1433 } 1434 1435 vrc = waitForStatusChange(pEvent, 1436 uTimeoutMS == RT_INDEFINITE_WAIT 1437 ? RT_INDEFINITE_WAIT : uTimeoutMS - u32ElapsedMS, 1438 &processStatus, pGuestRc); 1439 if (RT_SUCCESS(vrc)) 1440 { 1441 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1442 1443 waitResult = waitFlagsToResultEx(fWaitFlags, processStatus, 1444 mData.mProcess.mFlags, mSession->getProtocolVersion()); 1445 LogFlowThisFunc(("Got new status change: waitResult=%ld, processStatus=%ld\n", 1446 waitResult, processStatus)); 1447 if (ProcessWaitResult_None != waitResult) /* We got a waiting result. */ 1448 break; 1449 } 1450 else /* Waiting failed, bail out. */ 1451 break; 1452 } 1453 1454 unregisterWaitEvent(pEvent); 1455 1456 LogFlowThisFunc(("waitResult=%ld, processStatus=%ld, rc=%Rrc\n", 1457 waitResult, processStatus, vrc)); 1408 1458 return vrc; 1409 1459 } … … 1440 1490 } 1441 1491 1442 LogFlowFuncLeaveRC(vrc); 1492 LogFlowThisFunc(("Returning pEvent=%p, uHandle=%RU32, rc=%Rrc\n", 1493 pEvent, uHandle, vrc)); 1443 1494 return vrc; 1444 1495 } … … 1506 1557 } 1507 1558 1508 int GuestProcess::waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_tuTimeoutMS,1559 int GuestProcess::waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, 1509 1560 ProcessStatus_T *pProcessStatus, int *pGuestRc) 1510 1561 { 1511 1562 AssertPtrReturn(pEvent, VERR_INVALID_POINTER); 1563 /* pProcessStatus is optional. */ 1564 /* pGuestRc is optional. */ 1512 1565 1513 1566 VBoxEventType_T evtType; … … 1535 1588 hr = errorInfo->COMGETTER(ResultDetail)(&lGuestRc); 1536 1589 ComAssertComRC(hr); 1590 1591 LogFlowThisFunc(("resultDetail=%RI32 (rc=%Rrc)\n", 1592 lGuestRc, lGuestRc)); 1593 1537 1594 if (RT_FAILURE((int)lGuestRc)) 1538 1595 vrc = VERR_GSTCTL_GUEST_ERROR; … … 1542 1599 } 1543 1600 1544 LogFlow FuncLeaveRC(vrc);1601 LogFlowThisFunc(("Returning rc=%Rrc\n", vrc)); 1545 1602 return vrc; 1603 } 1604 1605 /* static */ 1606 bool GuestProcess::waitResultImpliesEx(ProcessWaitResult_T waitResult, 1607 ProcessStatus_T procStatus, uint32_t uProcFlags, 1608 uint32_t uProtocol) 1609 { 1610 bool fImplies; 1611 1612 switch (waitResult) 1613 { 1614 case ProcessWaitResult_Start: 1615 fImplies = procStatus == ProcessStatus_Started; 1616 break; 1617 1618 case ProcessWaitResult_Terminate: 1619 fImplies = ( procStatus == ProcessStatus_TerminatedNormally 1620 || procStatus == ProcessStatus_TerminatedSignal 1621 || procStatus == ProcessStatus_TerminatedAbnormally 1622 || procStatus == ProcessStatus_TimedOutKilled 1623 || procStatus == ProcessStatus_TimedOutAbnormally 1624 || procStatus == ProcessStatus_Down 1625 || procStatus == ProcessStatus_Error); 1626 break; 1627 1628 default: 1629 fImplies = false; 1630 break; 1631 } 1632 1633 return fImplies; 1546 1634 } 1547 1635 … … 1570 1658 try 1571 1659 { 1572 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 1660 /* 1661 * On Guest Additions < 4.3 there is no guarantee that the process status 1662 * change arrives *after* the input event, e.g. if this was the last input 1663 * block being written and the process will report status "terminate". 1664 * So just skip checking for process status change and only wait for the 1665 * input event. 1666 */ 1667 if (mSession->getProtocolVersion() >= 2) 1668 eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); 1573 1669 eventTypes.push_back(VBoxEventType_OnGuestProcessInputNotify); 1574 1670 1575 vrc = register Event(eventTypes, &pEvent);1671 vrc = registerWaitEvent(eventTypes, &pEvent); 1576 1672 } 1577 1673 catch (std::bad_alloc) … … 1593 1689 alock.release(); /* Drop the write lock before sending. */ 1594 1690 1691 uint32_t cbProcessed = 0; 1595 1692 vrc = sendCommand(HOST_EXEC_SET_INPUT, i, paParms); 1596 1693 if (RT_SUCCESS(vrc)) 1597 1694 { 1598 1695 ProcessInputStatus_T inputStatus; 1599 uint32_t cbProcessed;1600 vrc = waitForInputNotify(pEvent, uHandle, uTimeoutMS,&inputStatus, &cbProcessed);1696 vrc = waitForInputNotify(pEvent, uHandle, uTimeoutMS, 1697 &inputStatus, &cbProcessed); 1601 1698 if (RT_SUCCESS(vrc)) 1602 1699 { … … 1609 1706 } 1610 1707 1611 unregisterEvent(pEvent); 1612 1613 LogFlowFuncLeaveRC(vrc); 1708 unregisterWaitEvent(pEvent); 1709 1710 LogFlowThisFunc(("Returning cbProcessed=%RU32, rc=%Rrc\n", 1711 cbProcessed, vrc)); 1614 1712 return vrc; 1615 1713 } … … 1679 1777 1680 1778 int guestRc; 1681 int vrc = terminateProcess(&guestRc); 1779 int vrc = terminateProcess(30 * 1000 /* Timeout in ms */, 1780 &guestRc); 1682 1781 if (RT_FAILURE(vrc)) 1683 1782 { … … 1702 1801 } 1703 1802 1803 /* Remove the process from our internal session list. Only an API client 1804 * now may hold references to it. */ 1704 1805 AssertPtr(mSession); 1705 1806 mSession->processRemoveFromList(this); 1706 1807 1707 /* 1708 * Release autocaller before calling uninit. 1709 */ 1710 autoCaller.release(); 1711 1712 uninit(); 1713 1714 LogFlowFuncLeaveRC(vrc); 1808 LogFlowThisFunc(("Returning rc=%Rrc\n", vrc)); 1715 1809 return hr; 1716 1810 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 1867 1961 GuestProcessTool::~GuestProcessTool(void) 1868 1962 { 1869 Terminate( );1963 Terminate(30 * 1000, NULL /* pGuestRc */); 1870 1964 } 1871 1965 … … 1886 1980 int vrc = pSession->processCreateExInteral(mStartupInfo, pProcess); 1887 1981 if (RT_SUCCESS(vrc)) 1888 vrc = fAsync ? pProcess->startProcessAsync() : pProcess->startProcess(pGuestRc); 1982 vrc = fAsync ? pProcess->startProcessAsync() : pProcess->startProcess(30 * 1000 /* 30s timeout */, 1983 pGuestRc); 1889 1984 1890 1985 if ( RT_SUCCESS(vrc) … … 1998 2093 fWaitFlags |= ProcessWaitForFlag_StdErr; 1999 2094 2000 LogFlow Func(("waitFlags=0x%x\n", fWaitFlags));2095 LogFlowThisFunc(("waitFlags=0x%x\n", fWaitFlags)); 2001 2096 2002 2097 /** @todo Decrease timeout. */ … … 2120 2215 } 2121 2216 2122 void GuestProcessTool::Terminate(void)2217 int GuestProcessTool::Terminate(uint32_t uTimeoutMS, int *pGuestRc) 2123 2218 { 2124 2219 LogFlowThisFuncEnter(); 2125 2220 2221 int rc = VINF_SUCCESS; 2126 2222 if (!pProcess.isNull()) 2127 2223 { 2128 /** @todo Add pProcess.Terminate() here as soon as it's implemented. */2224 rc = pProcess->terminateProcess(uTimeoutMS, pGuestRc); 2129 2225 2130 2226 Assert(pSession); … … 2134 2230 pProcess.setNull(); 2135 2231 } 2136 2137 LogFlowThisFuncLeave(); 2138 } 2139 2232 else 2233 rc = VERR_NOT_FOUND; 2234 2235 LogFlowFuncLeaveRC(rc); 2236 return rc; 2237 } 2238 -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r45805 r47469 207 207 if (RT_SUCCESS(rc)) 208 208 { 209 unconst(mEventSource).createObject(); 210 Assert(!mEventSource.isNull()); 211 hr = mEventSource->init(static_cast<IGuestSession*>(this)); 209 hr = unconst(mEventSource).createObject(); 212 210 if (FAILED(hr)) 213 rc = VERR_COM_UNEXPECTED; 211 rc = VERR_NO_MEMORY; 212 else 213 { 214 hr = mEventSource->init(static_cast<IGuestSession*>(this)); 215 if (FAILED(hr)) 216 rc = VERR_COM_UNEXPECTED; 217 } 214 218 } 215 219 … … 226 230 if (SUCCEEDED(hr)) 227 231 { 228 mListener = thisListener;229 230 232 com::SafeArray <VBoxEventType_T> eventTypes; 231 233 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 232 hr = mEventSource->RegisterListener( mListener,234 hr = mEventSource->RegisterListener(thisListener, 233 235 ComSafeArrayAsInParam(eventTypes), 234 236 TRUE /* Active listener */); 235 237 if (SUCCEEDED(hr)) 236 238 { 239 mLocalListener = thisListener; 240 237 241 rc = RTCritSectInit(&mWaitEventCritSect); 238 242 AssertRC(rc); … … 258 262 autoInitSpan.setFailed(); 259 263 260 LogFlowFuncLeaveRC(rc); 264 LogFlowThisFunc(("mName=%s, mID=%RU32, mIsInternal=%RTbool, rc=%Rrc\n", 265 mData.mSession.mName.c_str(), mData.mSession.mID, mData.mSession.mIsInternal, rc)); 261 266 return rc; 262 267 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 284 289 itDirs != mData.mDirectories.end(); ++itDirs) 285 290 { 286 (*itDirs)-> uninit();291 (*itDirs)->Release(); 287 292 } 288 293 mData.mDirectories.clear(); … … 293 298 itFiles != mData.mFiles.end(); ++itFiles) 294 299 { 295 itFiles->second-> uninit();300 itFiles->second->Release(); 296 301 } 297 302 mData.mFiles.clear(); … … 302 307 itProcs != mData.mProcesses.end(); ++itProcs) 303 308 { 304 itProcs->second-> uninit();309 itProcs->second->Release(); 305 310 } 306 311 mData.mProcesses.clear(); … … 308 313 LogFlowThisFunc(("mNumObjects=%RU32\n", mData.mNumObjects)); 309 314 315 baseUninit(); 316 317 mEventSource->UnregisterListener(mLocalListener); 310 318 unconst(mEventSource).setNull(); 311 unregisterEventListener();312 319 313 320 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 457 464 458 465 mData.mTimeout = aTimeout; 466 467 LogFlowFuncLeaveRC(S_OK); 468 return S_OK; 469 #endif /* VBOX_WITH_GUEST_CONTROL */ 470 } 471 472 STDMETHODIMP GuestSession::COMGETTER(ProtocolVersion)(ULONG *aVersion) 473 { 474 #ifndef VBOX_WITH_GUEST_CONTROL 475 ReturnComNotImplemented(); 476 #else 477 LogFlowThisFuncEnter(); 478 479 CheckComArgOutPointerValid(aVersion); 480 481 AutoCaller autoCaller(this); 482 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 483 484 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 485 486 *aVersion = mData.mProtocolVersion; 459 487 460 488 LogFlowFuncLeaveRC(S_OK); … … 539 567 collection.detachTo(ComSafeArrayOutArg(aProcesses)); 540 568 569 LogFlowFunc(("mProcesses=%zu\n", collection.size())); 570 return S_OK; 571 #endif /* VBOX_WITH_GUEST_CONTROL */ 572 } 573 574 STDMETHODIMP GuestSession::COMGETTER(Directories)(ComSafeArrayOut(IGuestDirectory *, aDirectories)) 575 { 576 #ifndef VBOX_WITH_GUEST_CONTROL 577 ReturnComNotImplemented(); 578 #else 579 LogFlowThisFuncEnter(); 580 581 CheckComArgOutSafeArrayPointerValid(aDirectories); 582 583 AutoCaller autoCaller(this); 584 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 585 586 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 587 588 SafeIfaceArray<IGuestDirectory> collection(mData.mDirectories); 589 collection.detachTo(ComSafeArrayOutArg(aDirectories)); 590 591 LogFlowFunc(("mDirectories=%zu\n", collection.size())); 592 return S_OK; 593 #endif /* VBOX_WITH_GUEST_CONTROL */ 594 } 595 596 STDMETHODIMP GuestSession::COMGETTER(Files)(ComSafeArrayOut(IGuestFile *, aFiles)) 597 { 598 #ifndef VBOX_WITH_GUEST_CONTROL 599 ReturnComNotImplemented(); 600 #else 601 LogFlowThisFuncEnter(); 602 603 CheckComArgOutSafeArrayPointerValid(aFiles); 604 605 AutoCaller autoCaller(this); 606 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 607 608 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 609 610 SafeIfaceArray<IGuestFile> collection(mData.mFiles); 611 collection.detachTo(ComSafeArrayOutArg(aFiles)); 612 613 LogFlowFunc(("mFiles=%zu\n", collection.size())); 614 return S_OK; 615 #endif /* VBOX_WITH_GUEST_CONTROL */ 616 } 617 618 STDMETHODIMP GuestSession::COMGETTER(EventSource)(IEventSource ** aEventSource) 619 { 620 #ifndef VBOX_WITH_GUEST_CONTROL 621 ReturnComNotImplemented(); 622 #else 623 LogFlowThisFuncEnter(); 624 625 CheckComArgOutPointerValid(aEventSource); 626 627 AutoCaller autoCaller(this); 628 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 629 630 // no need to lock - lifetime constant 631 mEventSource.queryInterfaceTo(aEventSource); 632 541 633 LogFlowFuncLeaveRC(S_OK); 542 634 return S_OK; … … 544 636 } 545 637 546 STDMETHODIMP GuestSession::COMGETTER(Directories)(ComSafeArrayOut(IGuestDirectory *, aDirectories))547 {548 #ifndef VBOX_WITH_GUEST_CONTROL549 ReturnComNotImplemented();550 #else551 LogFlowThisFuncEnter();552 553 CheckComArgOutSafeArrayPointerValid(aDirectories);554 555 AutoCaller autoCaller(this);556 if (FAILED(autoCaller.rc())) return autoCaller.rc();557 558 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);559 560 SafeIfaceArray<IGuestDirectory> collection(mData.mDirectories);561 collection.detachTo(ComSafeArrayOutArg(aDirectories));562 563 LogFlowFuncLeaveRC(S_OK);564 return S_OK;565 #endif /* VBOX_WITH_GUEST_CONTROL */566 }567 568 STDMETHODIMP GuestSession::COMGETTER(Files)(ComSafeArrayOut(IGuestFile *, aFiles))569 {570 #ifndef VBOX_WITH_GUEST_CONTROL571 ReturnComNotImplemented();572 #else573 LogFlowThisFuncEnter();574 575 CheckComArgOutSafeArrayPointerValid(aFiles);576 577 AutoCaller autoCaller(this);578 if (FAILED(autoCaller.rc())) return autoCaller.rc();579 580 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);581 582 SafeIfaceArray<IGuestFile> collection(mData.mFiles);583 collection.detachTo(ComSafeArrayOutArg(aFiles));584 585 LogFlowFuncLeaveRC(S_OK);586 return S_OK;587 #endif /* VBOX_WITH_GUEST_CONTROL */588 }589 590 STDMETHODIMP GuestSession::COMGETTER(EventSource)(IEventSource ** aEventSource)591 {592 #ifndef VBOX_WITH_GUEST_CONTROL593 ReturnComNotImplemented();594 #else595 LogFlowThisFuncEnter();596 597 CheckComArgOutPointerValid(aEventSource);598 599 AutoCaller autoCaller(this);600 if (FAILED(autoCaller.rc())) return autoCaller.rc();601 602 // no need to lock - lifetime constant603 mEventSource.queryInterfaceTo(aEventSource);604 605 LogFlowFuncLeaveRC(S_OK);606 return S_OK;607 #endif /* VBOX_WITH_GUEST_CONTROL */608 }609 610 638 // private methods 611 639 /////////////////////////////////////////////////////////////////////////////// … … 617 645 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 618 646 619 /* Legacy Guest Additions don't support opening dedicated620 guest sessions . */647 /* Guest Additions < 4.3 don't support closing dedicated 648 guest sessions, skip. */ 621 649 if (mData.mProtocolVersion < 2) 622 650 { … … 638 666 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 639 667 640 vrc = register Event(mData.mSession.mID, 0 /* Object ID */,641 eventTypes, &pEvent);668 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 669 eventTypes, &pEvent); 642 670 } 643 671 catch (std::bad_alloc) … … 666 694 } 667 695 668 unregister Event(pEvent);696 unregisterWaitEvent(pEvent); 669 697 670 698 LogFlowFuncLeaveRC(vrc); … … 1319 1347 } 1320 1348 1321 int GuestSession::startSessionInte nal(int *pGuestRc)1349 int GuestSession::startSessionInternal(int *pGuestRc) 1322 1350 { 1323 1351 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); … … 1327 1355 mData.mSession.mOpenFlags, mData.mSession.mOpenTimeoutMS)); 1328 1356 1329 /* Legacy Guest Additionsdon't support opening dedicated1357 /* Guest Additions < 4.3 don't support opening dedicated 1330 1358 guest sessions. Simply return success here. */ 1331 1359 if (mData.mProtocolVersion < 2) … … 1353 1381 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 1354 1382 1355 vrc = register Event(mData.mSession.mID, 0 /* Object ID */,1356 eventTypes, &pEvent);1383 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 1384 eventTypes, &pEvent); 1357 1385 } 1358 1386 catch (std::bad_alloc) … … 1387 1415 } 1388 1416 1389 unregister Event(pEvent);1417 unregisterWaitEvent(pEvent); 1390 1418 1391 1419 LogFlowFuncLeaveRC(vrc); … … 1439 1467 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1440 1468 1441 int vrc = pSession->startSessionInte nal(NULL /* Guest rc, ignored */);1469 int vrc = pSession->startSessionInternal(NULL /* Guest rc, ignored */); 1442 1470 /* Nothing to do here anymore. */ 1443 1471 … … 1476 1504 LogFlowFunc(("Removing process ID=%RU32 (Session: %RU32), guest PID=%RU32 (now total %ld processes, %ld objects)\n", 1477 1505 pCurProc->getObjectID(), mData.mSession.mID, uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1)); 1506 1507 pCurProc->cancelWaitEvents(); 1508 1509 itProcs->second->Release(); 1478 1510 1479 1511 mData.mProcesses.erase(itProcs); … … 1772 1804 int GuestSession::queryInfo(void) 1773 1805 { 1774 #ifndef DEBUG_andy1775 /* Since the new functions are not fully implemented yet, force Main1776 to use protocol ver 1 so far. */1777 mData.mProtocolVersion = 1;1778 #else1779 #if 11780 /* For debugging only: Hardcode version. */1781 mData.mProtocolVersion = 2;1782 #else1783 1806 /* 1784 1807 * Try querying the guest control protocol version running on the guest. … … 1789 1812 1790 1813 uint32_t uVerAdditions = pGuest->getAdditionsVersion(); 1791 mData.mProtocolVersion = ( VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions) >= 4 1792 && VBOX_FULL_VERSION_GET_MINOR(uVerAdditions) >= 3) /** @todo What's about v5.0 ? */ 1814 uint32_t uVBoxMajor = VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions); 1815 uint32_t uVBoxMinor = VBOX_FULL_VERSION_GET_MINOR(uVerAdditions); 1816 1817 mData.mProtocolVersion = ( 1818 /* VBox 5.0 and up. */ 1819 uVBoxMajor >= 5 1820 /* VBox 4.3 and up. */ 1821 || (uVBoxMajor == 4 && uVBoxMinor >= 3)) 1793 1822 ? 2 /* Guest control 2.0. */ 1794 1823 : 1; /* Legacy guest control (VBox < 4.3). */ 1795 1824 /* Build revision is ignored. */ 1825 1826 LogFlowThisFunc(("uVerAdditions=%RU32 (%RU32.%RU32), mProtocolVersion=%RU32\n", 1827 uVerAdditions, uVBoxMajor, uVBoxMinor, mData.mProtocolVersion)); 1796 1828 1797 1829 /* Tell the user but don't bitch too often. */ … … 1799 1831 if (s_gctrlLegacyWarning++ < 3) /** @todo Find a bit nicer text. */ 1800 1832 LogRel((tr("Warning: Guest Additions are older (%ld.%ld) than host capabilities for guest control, please upgrade them. Using protocol version %ld now\n"), 1801 VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions), VBOX_FULL_VERSION_GET_MINOR(uVerAdditions), mData.mProtocolVersion)); 1802 #endif 1803 #endif 1833 uVBoxMajor, uVBoxMinor, mData.mProtocolVersion)); 1834 1804 1835 return VINF_SUCCESS; 1805 1836 } … … 1814 1845 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent, pGuestRc));*/ 1815 1846 1816 Auto WriteLock alock(this COMMA_LOCKVAL_SRC_POS);1847 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1817 1848 1818 1849 /* Did some error occur before? Then skip waiting and return. */ … … 1826 1857 } 1827 1858 1859 /* Guest Additions < 4.3 don't support session handling, skip. */ 1860 if (mData.mProtocolVersion < 2) 1861 { 1862 waitResult = GuestSessionWaitResult_WaitFlagNotSupported; 1863 1864 LogFlowThisFunc(("Installed Guest Additions don't support waiting for dedicated sessions, skipping\n")); 1865 return VINF_SUCCESS; 1866 } 1867 1828 1868 waitResult = GuestSessionWaitResult_None; 1829 1869 if (fWaitFlags & GuestSessionWaitForFlag_Terminate) … … 1911 1951 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 1912 1952 1913 vrc = register Event(mData.mSession.mID, 0 /* Object ID */,1914 eventTypes, &pEvent);1953 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 1954 eventTypes, &pEvent); 1915 1955 } 1916 1956 catch (std::bad_alloc) … … 1956 1996 } 1957 1997 1958 unregister Event(pEvent);1998 unregisterWaitEvent(pEvent); 1959 1999 1960 2000 LogFlowFuncLeaveRC(vrc); … … 2018 2058 2019 2059 /* Close session on guest. */ 2020 int guestRc ;2060 int guestRc = VINF_SUCCESS; 2021 2061 int rc = closeSession(0 /* Flags */, 30 * 1000 /* Timeout */, 2022 2062 &guestRc); … … 2029 2069 rc = rc2; 2030 2070 2031 /* 2032 * Release autocaller before calling uninit. 2033 */ 2034 autoCaller.release(); 2035 2036 uninit(); 2037 2038 LogFlowFuncLeaveRC(rc); 2071 LogFlowThisFunc(("Returning rc=%Rrc, guestRc=%Rrc\n", 2072 rc, guestRc)); 2039 2073 if (RT_FAILURE(rc)) 2040 2074 { … … 2854 2888 LogFlowThisFuncEnter(); 2855 2889 2856 com::SafeArray<LONG> affinity ;2890 com::SafeArray<LONG> affinityIgnored; 2857 2891 2858 2892 return ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment), 2859 ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity ), aProcess);2893 ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinityIgnored), aProcess); 2860 2894 #endif /* VBOX_WITH_GUEST_CONTROL */ 2861 2895 } -
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r46524 r47469 186 186 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 187 187 188 int vrc = pSession->startSessionInte nal(pGuestRc);188 int vrc = pSession->startSessionInternal(pGuestRc); 189 189 /* Nothing to do here anymore. */ 190 190 … … 319 319 rc = pSession->processCreateExInteral(procInfo, pProcess); 320 320 if (RT_SUCCESS(rc)) 321 rc = pProcess->startProcess(&guestRc); 321 rc = pProcess->startProcess(30 * 1000 /* 30s timeout */, 322 &guestRc); 322 323 if (RT_FAILURE(rc)) 323 324 { … … 462 463 } /* for */ 463 464 464 LogFlowThisFunc(("Copy loop ended with rc=%Rrc\n" ,rc)); 465 LogFlowThisFunc(("Copy loop ended with rc=%Rrc, cbWrittenTotal=%RU64, cbFileSize=%RU64\n", 466 rc, cbWrittenTotal, mSourceSize)); 465 467 466 468 if ( !fCanceled … … 531 533 } 532 534 533 if (!pProcess.isNull()) 534 pProcess->uninit(); 535 pProcess->Release(); 535 536 } /* processCreateExInteral */ 536 537 … … 638 639 rc = pSession->processCreateExInteral(procInfo, pProcess); 639 640 if (RT_SUCCESS(rc)) 640 rc = pProcess->startProcess(&guestRc); 641 rc = pProcess->startProcess(30 * 1000 /* 30s timeout */, 642 &guestRc); 641 643 if (RT_FAILURE(rc)) 642 644 { … … 802 804 } 803 805 804 if (!pProcess.isNull()) 805 pProcess->uninit(); 806 pProcess->Release(); 806 807 } 807 808
Note:
See TracChangeset
for help on using the changeset viewer.