Changeset 44935 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 6, 2013 4:40:36 PM (12 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r44649 r44935 8922 8922 8923 8923 <enum 8924 name="GuestSessionStatus" 8925 uuid="ac2669da-4624-44f2-85b5-0b0bfb8d8673" 8926 > 8927 <desc> 8928 Guest session statuses. 8929 </desc> 8930 <const name="Undefined" value="0"> 8931 <desc>Guest session is in an undefined state.</desc> 8932 </const> 8933 <const name="Starting" value="10"> 8934 <desc>Guest session is being started.</desc> 8935 </const> 8936 <const name="Started" value="100"> 8937 <desc>Guest session has been started.</desc> 8938 </const> 8939 <const name="Terminating" value="480"> 8940 <desc>Guest session is being terminated.</desc> 8941 </const> 8942 <const name="Terminated" value="500"> 8943 <desc>Guest session terminated normally.</desc> 8944 </const> 8945 <const name="TimedOutKilled" value="512"> 8946 <desc>Guest session timed out and was killed.</desc> 8947 </const> 8948 <const name="TimedOutAbnormally" value="513"> 8949 <desc>Guest session timed out and was not killed successfully.</desc> 8950 </const> 8951 <const name="Down" value="600"> 8952 <desc>Service/OS is stopping, guest session was killed.</desc> 8953 </const> 8954 <const name="Error" value="800"> 8955 <desc>Something went wrong.</desc> 8956 </const> 8957 </enum> 8958 8959 <enum 8924 8960 name="FileSeekType" 8925 8961 uuid="1b73f4f3-3515-4073-a506-76878d9e2541" … … 9232 9268 <desc>Process is in an undefined state.</desc> 9233 9269 </const> 9234 9235 9270 <const name="Starting" value="10"> 9236 9271 <desc>Process is being started.</desc> … … 9347 9382 <interface 9348 9383 name="IGuestSession" extends="$unknown" 9349 uuid=" 57eb82a8-822b-42c1-9d1c-5c54bc3d3250"9384 uuid="8490516f-9c2c-49e9-b283-35f3ce463f69" 9350 9385 wsmap="managed" 9351 9386 > … … 9399 9434 </result> 9400 9435 </desc> 9436 </attribute> 9437 9438 <attribute name="status" type="GuestSessionStatus" readonly="yes"> 9439 <desc>Returns the current session status.</desc> 9401 9440 </attribute> 9402 9441 -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r44863 r44935 318 318 319 319 /** 320 * Structure for keeping all the relevant process 321 * starting parameters around. 320 * Structure for keeping all the relevant guest session 321 * startup parameters around. 322 */ 323 class GuestSessionStartupInfo 324 { 325 public: 326 327 GuestSessionStartupInfo(void) 328 : mIsInternal(false /* Non-internal session */), 329 mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */), 330 mOpenFlags(0 /* No opening flags set */) { } 331 332 /** The session's friendly name. Optional. */ 333 Utf8Str mName; 334 /** The session's unique ID. Used to encode 335 * a context ID. */ 336 uint32_t mID; 337 /** Flag indicating if this is an internal session 338 * or not. Internal session are not accessible by 339 * public API clients. */ 340 bool mIsInternal; 341 /** Timeout (in ms) used for opening the session. */ 342 uint32_t mOpenTimeoutMS; 343 /** Session opening flags. */ 344 uint32_t mOpenFlags; 345 }; 346 347 348 /** 349 * Structure for keeping all the relevant guest process 350 * startup parameters around. 322 351 */ 323 352 class GuestProcessStartupInfo … … 341 370 /** Process priority. */ 342 371 ProcessPriority_T mPriority; 343 /** Process affinity. */ 372 /** Process affinity. At the moment we 373 * only support 64 VCPUs. API and 374 * guest can do more already! */ 344 375 uint64_t mAffinity; 345 376 }; -
trunk/src/VBox/Main/include/GuestImpl.h
r44863 r44935 141 141 Console *getConsole(void) { return mParent; } 142 142 int sessionRemove(GuestSession *pSession); 143 int sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain, 144 const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession); 143 int sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession); 145 144 inline bool sessionExists(uint32_t uSessionID); 146 145 #endif -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r44863 r44935 105 105 struct Data 106 106 { 107 /** The process start information. */107 /** The process startup information. */ 108 108 GuestProcessStartupInfo mProcess; 109 109 /** Exit code if process has been terminated. */ -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r44863 r44935 81 81 public: 82 82 83 int Run( void);83 int Run(int *pGuestRc); 84 84 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress); 85 85 static int taskThread(RTTHREAD Thread, void *pvUser); … … 251 251 DECLARE_EMPTY_CTOR_DTOR(GuestSession) 252 252 253 int init(Guest * aGuest, ULONG aSessionID, Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName);253 int init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds); 254 254 void uninit(void); 255 255 HRESULT FinalConstruct(void); … … 263 263 STDMETHOD(COMGETTER(Name))(BSTR *aName); 264 264 STDMETHOD(COMGETTER(Id))(ULONG *aId); 265 STDMETHOD(COMGETTER(Status))(GuestSessionStatus_T *aStatus); 265 266 STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout); 266 267 STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout); … … 343 344 const GuestEnvironment &getEnvironment(void); 344 345 Utf8Str getName(void); 345 ULONG getId(void) { return mData.mId; } 346 ULONG getId(void) { return mData.mSession.mID; } 347 static Utf8Str guestErrorToString(int guestRc); 346 348 int onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, GuestCtrlCallback *pCallback, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData); 347 int openSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc); 349 int openSession(int *pGuestRc); 350 int openSessionAsync(void); 351 static DECLCALLBACK(int) 352 openSessionThread(RTTHREAD Thread, void *pvUser); 348 353 Guest *getParent(void) { return mData.mParent; } 349 354 uint32_t getProtocolVersion(void) { return mData.mProtocolVersion; } … … 353 358 inline int processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess); 354 359 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms); 360 static HRESULT setErrorExternal(VirtualBoxBase *pInterface, int guestRc); 355 361 int startTaskAsync(const Utf8Str &strTaskDesc, GuestSessionTask *pTask, ComObjPtr<Progress> &pProgress); 356 362 int queryInfo(void); … … 361 367 struct Data 362 368 { 369 /** Pointer to the parent (Guest). */ 370 Guest *mParent; 371 /** The session credentials. */ 372 GuestCredentials mCredentials; 373 /** The session's startup info. */ 374 GuestSessionStartupInfo mSession; 375 /** The session's current status. */ 376 GuestSessionStatus_T mStatus; 377 /** The session's environment block. Can be 378 * overwritten/extended by ProcessCreate(Ex). */ 379 GuestEnvironment mEnvironment; 380 /** The session callback, needed for communicating 381 * with the guest. */ 382 GuestCtrlCallback mCallback; 383 /** Directory objects bound to this session. */ 384 SessionDirectories mDirectories; 385 /** File objects bound to this session. */ 386 SessionFiles mFiles; 387 /** Process objects bound to this session. */ 388 SessionProcesses mProcesses; 363 389 /** Guest control protocol version to be used. 364 390 * Guest Additions < VBox 4.3 have version 1, 365 391 * any newer version will have version 2. */ 366 uint32_t mProtocolVersion; 367 /** Flag indicating if this is an internal session 368 * or not. Internal session are not accessible by clients. */ 369 bool fInternal; 370 /** Pointer to the parent (Guest). */ 371 Guest *mParent; 372 /** The session credentials. */ 373 GuestCredentials mCredentials; 374 /** The (optional) session name. */ 375 Utf8Str mName; 376 /** The session ID. */ 377 ULONG mId; 378 /** The session timeout. Default is 30s. */ 379 ULONG mTimeout; 380 /** The session's environment block. Can be 381 * overwritten/extended by ProcessCreate(Ex). */ 382 GuestEnvironment mEnvironment; 383 /** The session callback, needed for communicating 384 * with the guest. */ 385 GuestCtrlCallback mCallback; 386 /** Directory objects bound to this session. */ 387 SessionDirectories mDirectories; 388 /** File objects bound to this session. */ 389 SessionFiles mFiles; 390 /** Process objects bound to this session. */ 391 SessionProcesses mProcesses; 392 uint32_t mProtocolVersion; 393 /** Session timeout (in ms). */ 394 uint32_t mTimeout; 392 395 /** Total number of session objects (processes, 393 396 * files, ...). */ 394 uint32_t mNumObjects;397 uint32_t mNumObjects; 395 398 } mData; 396 399 }; -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r44863 r44935 142 142 HRESULT hr = S_OK; 143 143 144 /* Create an anonymous session. This is required to run the Guest Additions 145 * update process with administrative rights. */ 144 /* 145 * Create an anonymous session. This is required to run the Guest Additions 146 * update process with administrative rights. 147 */ 148 GuestSessionStartupInfo startupInfo; 149 startupInfo.mName = "Updating Guest Additions"; 150 151 GuestCredentials guestCreds; 152 RT_ZERO(guestCreds); 153 146 154 ComObjPtr<GuestSession> pSession; 147 int rc = sessionCreate("" /* User */, "" /* Password */, "" /* Domain */, 148 "Updating Guest Additions" /* Name */, pSession); 155 int rc = sessionCreate(startupInfo, guestCreds, pSession); 149 156 if (RT_FAILURE(rc)) 150 157 { … … 166 173 { 167 174 Assert(!pSession.isNull()); 168 rc = pSession->queryInfo(); 175 int guestRc; 176 rc = pSession->openSession(&guestRc); 169 177 if (RT_FAILURE(rc)) 170 178 { 171 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not query guest session information: %Rrc"), rc); 179 /** @todo Handle guestRc! */ 180 181 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not open guest session: %Rrc"), rc); 172 182 } 173 183 else … … 208 218 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 209 219 220 LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n", 221 pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol)); 222 210 223 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 211 224 … … 260 273 { 261 274 case GUEST_DISCONNECTED: 262 break; 275 rc = pSession->dispatchToThis(pCtxCb, pSvcCb); 276 break; 263 277 264 278 case GUEST_SESSION_NOTIFY: … … 310 324 (GuestSession *)itSessions->second, itSessions->second->getId(), mData.mGuestSessions.size() - 1)); 311 325 312 mData.mGuestSessions.erase(itSessions );326 mData.mGuestSessions.erase(itSessions++); 313 327 314 328 rc = VINF_SUCCESS; … … 321 335 } 322 336 323 int Guest::sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain,324 const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession)337 int Guest::sessionCreate(const GuestSessionStartupInfo &ssInfo, 338 const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession) 325 339 { 326 340 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); … … 348 362 uNewSessionID = 0; 349 363 350 if (++uTries == UINT32_MAX)364 if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS) 351 365 break; /* Don't try too hard. */ 352 366 } … … 357 371 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 358 372 359 rc = pGuestSession->queryInfo(); 360 if (RT_FAILURE(rc)) throw rc; 361 rc = pGuestSession->init(this, uNewSessionID, 362 strUser, strPassword, strDomain, strSessionName); 373 /** @todo Use an overloaded copy operator. Later. */ 374 GuestSessionStartupInfo startupInfo; 375 startupInfo.mID = uNewSessionID; /* Assign new session ID. */ 376 startupInfo.mName = ssInfo.mName; 377 startupInfo.mOpenFlags = ssInfo.mOpenFlags; 378 startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS; 379 380 GuestCredentials guestCredentials; 381 if (!guestCreds.mUser.isEmpty()) 382 { 383 /** @todo Use an overloaded copy operator. Later. */ 384 guestCredentials.mUser = guestCreds.mUser; 385 guestCredentials.mPassword = guestCreds.mPassword; 386 guestCredentials.mDomain = guestCreds.mDomain; 387 } 388 else 389 { 390 /* Internal (annonymous) session. */ 391 startupInfo.mIsInternal = true; 392 } 393 394 rc = pGuestSession->init(this, startupInfo, guestCredentials); 363 395 if (RT_FAILURE(rc)) throw rc; 364 396 … … 373 405 * involve the main dispatcher to run. */ 374 406 alock.release(); 375 376 /** @todo Do we need an openSessioAsync() call? This might be377 * a problem on webservice calls (= timeouts) if opening the378 * guest session takes too long -> Then we also would379 * need some session.getStatus() API call! */380 381 /* Open (create) the session on the guest. */382 int guestRc;383 rc = pGuestSession->openSession(0 /* Flags */, 30 * 1000 /* 30s timeout */,384 &guestRc);385 if (RT_FAILURE(rc))386 {387 switch (rc)388 {389 case VERR_MAX_PROCS_REACHED:390 hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"),391 VBOX_GUESTCTRL_MAX_SESSIONS);392 break;393 394 /** @todo Add more errors here. */395 396 default:397 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session, rc=%Rrc"), rc);398 break;399 }400 401 /* Remove failed session again. */402 int rc2 = sessionRemove(pGuestSession);403 AssertRC(rc2);404 }405 else406 LogFlowFunc(("Created new guest session (pSession=%p, ID=%RU32), now %zu sessions total\n",407 (GuestSession *)pGuestSession, uNewSessionID, mData.mGuestSessions.size()));408 407 } 409 408 catch (int rc2) … … 433 432 LogFlowFuncEnter(); 434 433 435 /* Do not allow anonymous sessions (with system rights) with officialAPI. */434 /* Do not allow anonymous sessions (with system rights) with public API. */ 436 435 if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0')) 437 436 return setError(E_INVALIDARG, tr("No user name specified")); … … 442 441 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 443 442 444 HRESULT hr = S_OK; 443 GuestSessionStartupInfo startupInfo; 444 startupInfo.mName = aSessionName; 445 446 GuestCredentials guestCreds; 447 guestCreds.mUser = aUser; 448 guestCreds.mPassword = aPassword; 449 guestCreds.mDomain = aDomain; 445 450 446 451 ComObjPtr<GuestSession> pSession; 447 int rc = sessionCreate( aUser, aPassword, aDomain, aSessionName, pSession);452 int rc = sessionCreate(startupInfo, guestCreds, pSession); 448 453 if (RT_SUCCESS(rc)) 449 454 { … … 454 459 } 455 460 461 int guestRc; 462 if (RT_SUCCESS(rc)) 463 { 464 /** @todo Do we need to use openSessioAsync() here? Otherwise 465 * there might be a problem on webservice calls (= timeouts) 466 * if opening the guest session takes too long -> Use 467 * the new session.getStatus() API call! */ 468 469 /* Open (fork) the session on the guest. */ 470 rc = pSession->openSession(&guestRc); 471 if (RT_SUCCESS(rc)) 472 { 473 LogFlowFunc(("Created new guest session (pSession=%p), now %zu sessions total\n", 474 (GuestSession *)pSession, mData.mGuestSessions.size())); 475 } 476 } 477 478 HRESULT hr = S_OK; 479 456 480 if (RT_FAILURE(rc)) 457 481 { 458 482 switch (rc) 459 483 { 484 case VERR_GENERAL_FAILURE: /** @todo Special guest control rc needed! */ 485 hr = GuestSession::setErrorExternal(this, guestRc); 486 break; 487 460 488 case VERR_MAX_PROCS_REACHED: 461 489 hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"), … … 465 493 /** @todo Add more errors here. */ 466 494 467 default:468 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session , rc=%Rrc"), rc);495 default: 496 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); 469 497 break; 470 498 } -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r44863 r44935 405 405 * 406 406 * In protocol v1 we don't have the possibility to terminate/kill 407 * processes so it can happen that a formerly start process A407 * processes so it can happen that a formerly started process A 408 408 * (which has the context ID 0 (session=0, process=0, count=0) will 409 409 * send a delayed message to the host if this process has already … … 428 428 ? VINF_SUCCESS : VERR_NOT_FOUND; 429 429 } 430 #ifndef DEBUG_andy 430 431 /* This should never happen! */ 431 432 AssertReleaseMsg(mData.mPID == uPID, ("Unterminated guest process (PID %RU32) sent data to a newly started process (PID %RU32)\n", 432 433 uPID, mData.mPID)); 434 #endif 433 435 } 434 436 … … 1247 1249 1248 1250 /* Create callback and add it to the map. */ 1249 uint32_t uContextID = 0;1251 uint32_t uContextID; 1250 1252 if (RT_SUCCESS(vrc)) 1251 1253 vrc = callbackAdd(pCallbackTerminate, &uContextID); … … 1275 1277 { 1276 1278 int guestRc = pCallbackTerminate->GetResultCode(); 1277 LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc)); 1279 if (RT_SUCCESS(guestRc)) 1280 { 1281 /* Nothing to do here right now. */ 1282 } 1283 else 1284 vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */ 1285 1278 1286 if (pGuestRc) 1279 1287 *pGuestRc = guestRc; 1288 LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc)); 1280 1289 } 1281 1290 } -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r44863 r44935 44 44 #include <VBox/log.h> 45 45 46 47 /** 48 * Base class representing an internal 49 * asynchronous session task. 50 */ 51 class GuestSessionTaskInternal 52 { 53 public: 54 55 GuestSessionTaskInternal(GuestSession *pSession) 56 : mSession(pSession), 57 mRC(VINF_SUCCESS) { } 58 59 virtual ~GuestSessionTaskInternal(void) { } 60 61 int rc(void) const { return mRC; } 62 bool isOk(void) const { return RT_SUCCESS(mRC); } 63 const ComObjPtr<GuestSession> &Session(void) const { return mSession; } 64 65 protected: 66 67 const ComObjPtr<GuestSession> mSession; 68 int mRC; 69 }; 70 71 /** 72 * Class for asynchronously opening a guest session. 73 */ 74 class GuestSessionTaskInternalOpen : public GuestSessionTaskInternal 75 { 76 public: 77 78 GuestSessionTaskInternalOpen(GuestSession *pSession) 79 : GuestSessionTaskInternal(pSession) { } 80 }; 81 46 82 // constructor / destructor 47 83 ///////////////////////////////////////////////////////////////////////////// … … 68 104 /** 69 105 * Initializes a guest session but does *not* open in on the guest side 70 * yet. This needs to be done via the openSession() call.106 * yet. This needs to be done via the openSession() / openSessionAsync calls. 71 107 * 72 108 * @return IPRT status code. 73 * @param aGuest 74 * @param aSessionID 75 * @param aUser 76 * @param aPassword 77 * @param aDomain 78 * @param aName 109 ** @todo Docs! 79 110 */ 80 int GuestSession::init(Guest *aGuest, ULONG aSessionID, 81 Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName) 82 { 83 LogFlowThisFuncEnter(); 84 85 AssertPtrReturn(aGuest, VERR_INVALID_POINTER); 111 int GuestSession::init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, 112 const GuestCredentials &guestCreds) 113 { 114 LogFlowThisFunc(("pGuest=%p, ssInfo=%p, guestCreds=%p\n", 115 pGuest, &ssInfo, &guestCreds)); 116 117 AssertPtrReturn(pGuest, VERR_INVALID_POINTER); 86 118 87 119 /* Enclose the state transition NotReady->InInit->Ready. */ … … 89 121 AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED); 90 122 91 mData.mTimeout = 30 * 60 * 1000; /* Session timeout is 30 mins by default. */ 92 mData.mParent = aGuest; 93 mData.mId = aSessionID; 94 95 mData.mCredentials.mUser = aUser; 96 mData.mCredentials.mPassword = aPassword; 97 mData.mCredentials.mDomain = aDomain; 98 mData.mName = aName; 123 mData.mParent = pGuest; 124 125 /* Copy over startup info. */ 126 /** @todo Use an overloaded copy operator. Later. */ 127 mData.mSession.mID = ssInfo.mID; 128 mData.mSession.mIsInternal = ssInfo.mIsInternal; 129 mData.mSession.mName = ssInfo.mName; 130 mData.mSession.mOpenFlags = ssInfo.mOpenFlags; 131 mData.mSession.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS; 132 133 /** @todo Use an overloaded copy operator. Later. */ 134 mData.mCredentials.mUser = guestCreds.mUser; 135 mData.mCredentials.mPassword = guestCreds.mPassword; 136 mData.mCredentials.mDomain = guestCreds.mDomain; 137 138 mData.mStatus = GuestSessionStatus_Undefined; 99 139 mData.mNumObjects = 0; 100 140 101 /* Confirm a successful initialization when it's the case. */ 102 autoInitSpan.setSucceeded(); 103 104 LogFlowFuncLeaveRC(VINF_SUCCESS); 105 return VINF_SUCCESS; 141 int rc = queryInfo(); 142 if (RT_SUCCESS(rc)) 143 { 144 /* Confirm a successful initialization when it's the case. */ 145 autoInitSpan.setSucceeded(); 146 } 147 else 148 autoInitSpan.setFailed(); 149 150 LogFlowFuncLeaveRC(rc); 151 return rc; 106 152 } 107 153 … … 228 274 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 229 275 230 mData.m Name.cloneTo(aName);276 mData.mSession.mName.cloneTo(aName); 231 277 232 278 LogFlowFuncLeaveRC(S_OK); … … 249 295 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 250 296 251 *aId = mData.m Id;297 *aId = mData.mSession.mID; 252 298 253 299 LogFlowFuncLeaveRC(S_OK); … … 256 302 } 257 303 258 STDMETHODIMP GuestSession::COMGETTER( Timeout)(ULONG *aTimeout)259 { 260 #ifndef VBOX_WITH_GUEST_CONTROL 261 ReturnComNotImplemented(); 262 #else 263 LogFlowThisFuncEnter(); 264 265 CheckComArgOutPointerValid(a Timeout);304 STDMETHODIMP GuestSession::COMGETTER(Status)(GuestSessionStatus_T *aStatus) 305 { 306 #ifndef VBOX_WITH_GUEST_CONTROL 307 ReturnComNotImplemented(); 308 #else 309 LogFlowThisFuncEnter(); 310 311 CheckComArgOutPointerValid(aStatus); 266 312 267 313 AutoCaller autoCaller(this); … … 270 316 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 271 317 272 *a Timeout = mData.mTimeout;318 *aStatus = mData.mStatus; 273 319 274 320 LogFlowFuncLeaveRC(S_OK); … … 277 323 } 278 324 279 STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout) 280 { 281 #ifndef VBOX_WITH_GUEST_CONTROL 282 ReturnComNotImplemented(); 283 #else 284 LogFlowThisFuncEnter(); 285 286 AutoCaller autoCaller(this); 287 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 288 289 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 290 291 mData.mTimeout = aTimeout; 325 STDMETHODIMP GuestSession::COMGETTER(Timeout)(ULONG *aTimeout) 326 { 327 #ifndef VBOX_WITH_GUEST_CONTROL 328 ReturnComNotImplemented(); 329 #else 330 LogFlowThisFuncEnter(); 331 332 CheckComArgOutPointerValid(aTimeout); 333 334 AutoCaller autoCaller(this); 335 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 336 337 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 338 339 *aTimeout = mData.mTimeout; 292 340 293 341 LogFlowFuncLeaveRC(S_OK); … … 296 344 } 297 345 346 STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout) 347 { 348 #ifndef VBOX_WITH_GUEST_CONTROL 349 ReturnComNotImplemented(); 350 #else 351 LogFlowThisFuncEnter(); 352 353 AutoCaller autoCaller(this); 354 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 355 356 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 357 358 mData.mTimeout = aTimeout; 359 360 LogFlowFuncLeaveRC(S_OK); 361 return S_OK; 362 #endif /* VBOX_WITH_GUEST_CONTROL */ 363 } 364 298 365 STDMETHODIMP GuestSession::COMGETTER(Environment)(ComSafeArrayOut(BSTR, aEnvironment)) 299 366 { … … 311 378 312 379 size_t cEnvVars = mData.mEnvironment.Size(); 313 LogFlowThisFunc(("%s cEnvVars=%RU32\n", mData.mName.c_str(), cEnvVars)); 380 LogFlowThisFunc(("[%s]: cEnvVars=%RU32\n", 381 mData.mSession.mName.c_str(), cEnvVars)); 314 382 com::SafeArray<BSTR> environment(cEnvVars); 315 383 … … 431 499 if (mData.mProtocolVersion < 2) 432 500 { 433 LogFlowThisFunc(("Installed Guest Additions don't support closing separate sessions\n"));501 LogFlowThisFunc(("Installed Guest Additions don't support closing dedicated sessions, skipping\n")); 434 502 return VINF_SUCCESS; 435 503 } 504 505 /** @todo uFlags validation. */ 436 506 437 507 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); … … 446 516 if (RT_SUCCESS(vrc)) 447 517 { 448 uint32_t uContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mId, 0 /* Object */, 0 /* Count */); 518 /* The context ID only contains this session's ID; all other 519 * parameters like object and the count itself are not needed 520 * and therefore 0. */ 521 uint32_t uContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mSession.mID /* Session ID */, 522 0 /* Object */, 0 /* Count */); 449 523 450 524 VBOXHGCMSVCPARM paParms[4]; … … 452 526 int i = 0; 453 527 paParms[i++].setUInt32(uContextID); 454 paParms[i++].setUInt32( 0 /* Flags, unused. */);528 paParms[i++].setUInt32(uFlags); 455 529 456 530 vrc = sendCommand(HOST_SESSION_CLOSE, i, paParms); … … 468 542 { 469 543 int guestRc = mData.mCallback.GetResultCode(); 544 if (RT_SUCCESS(guestRc)) 545 { 546 /* Nothing to do here right now. */ 547 } 548 else 549 vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */ 550 470 551 if (pGuestRc) 471 552 *pGuestRc = guestRc; 472 553 LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc)); 473 554 } 474 else475 vrc = VERR_TIMEOUT;476 555 } 477 556 … … 499 578 Assert(mData.mDirectories.size()); 500 579 LogFlowFunc(("Removing directory \"%s\" (Session: %RU32) (now total %ld directories)\n", 501 Utf8Str(strName).c_str(), mData.m Id, mData.mDirectories.size() - 1));580 Utf8Str(strName).c_str(), mData.mSession.mID, mData.mDirectories.size() - 1)); 502 581 503 582 mData.mDirectories.erase(itDirs); … … 637 716 638 717 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 639 strPath.c_str(), mData.m Id));718 strPath.c_str(), mData.mSession.mID)); 640 719 641 720 LogFlowFuncLeaveRC(vrc); … … 721 800 #ifdef DEBUG 722 801 LogFlowThisFunc(("ID=%RU32, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n", 723 mData.m Id, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));802 mData.mSession.mID, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb)); 724 803 #endif 725 804 … … 727 806 switch (pCbCtx->uFunction) 728 807 { 808 case GUEST_DISCONNECTED: 809 /** @todo Handle closing all processes. */ 810 break; 811 729 812 case GUEST_SESSION_NOTIFY: 730 813 { … … 736 819 default: 737 820 /* Silently skip unknown callbacks. */ 821 rc = VERR_NOT_SUPPORTED; 738 822 break; 739 823 } … … 773 857 Assert(mData.mNumObjects); 774 858 LogFlowThisFunc(("Removing file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n", 775 Utf8Str(strName).c_str(), mData.m Id, mData.mFiles.size() - 1, mData.mNumObjects - 1));859 Utf8Str(strName).c_str(), mData.mSession.mID, mData.mFiles.size() - 1, mData.mNumObjects - 1)); 776 860 #ifdef DEBUG 777 861 ULONG cRefs = pFile->AddRef(); … … 874 958 875 959 LogFlowFunc(("Added new file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n", 876 openInfo.mFileName.c_str(), mData.m Id, mData.mFiles.size(), mData.mNumObjects));960 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects)); 877 961 878 962 LogFlowFuncLeaveRC(rc); … … 957 1041 Utf8Str GuestSession::getName(void) 958 1042 { 959 return mData.mName; 1043 return mData.mSession.mName; 1044 } 1045 1046 /* static */ 1047 Utf8Str GuestSession::guestErrorToString(int guestRc) 1048 { 1049 Utf8Str strError; 1050 1051 /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */ 1052 switch (guestRc) 1053 { 1054 case VERR_INVALID_VM_HANDLE: 1055 strError += Utf8StrFmt(tr("VMM device is not available (is the VM running?)")); 1056 break; 1057 1058 case VERR_HGCM_SERVICE_NOT_FOUND: 1059 strError += Utf8StrFmt(tr("The guest execution service is not available")); 1060 break; 1061 1062 case VERR_AUTHENTICATION_FAILURE: 1063 strError += Utf8StrFmt(tr("The specified user was not able to logon on guest")); 1064 break; 1065 1066 case VERR_TIMEOUT: 1067 strError += Utf8StrFmt(tr("The guest did not respond within time")); 1068 break; 1069 1070 case VERR_CANCELLED: 1071 strError += Utf8StrFmt(tr("The session operation was canceled")); 1072 break; 1073 1074 case VERR_PERMISSION_DENIED: 1075 strError += Utf8StrFmt(tr("Invalid user/password credentials")); 1076 break; 1077 1078 case VERR_MAX_PROCS_REACHED: 1079 strError += Utf8StrFmt(tr("Maximum number of parallel guest processes has been reached")); 1080 break; 1081 1082 case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */ 1083 strError += Utf8StrFmt(tr("Unable to retrieve requested information")); 1084 break; 1085 1086 case VERR_NOT_FOUND: 1087 strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)")); 1088 break; 1089 1090 default: 1091 strError += Utf8StrFmt("%Rrc", guestRc); 1092 break; 1093 } 1094 1095 return strError; 960 1096 } 961 1097 … … 975 1111 pSvcCbData->mpaParms[2].getUInt32(&dataCb.uResult); 976 1112 977 int rcCb = dataCb.uResult; /** @todo uint32_t vs. int. */978 979 1113 LogFlowThisFunc(("ID=%RU32, uType=%RU32, rc=%Rrc, pCallback=%p, pData=%p\n", 980 mData.m Id, dataCb.uType, rcCb, pCallback, pSvcCbData));1114 mData.mSession.mID, dataCb.uType, dataCb.uResult, pCallback, pSvcCbData)); 981 1115 982 1116 int vrc = VINF_SUCCESS; 1117 1118 int guestRc = dataCb.uResult; /** @todo uint32_t vs. int. */ 1119 switch (dataCb.uType) 1120 { 1121 case GUEST_SESSION_NOTIFYTYPE_ERROR: 1122 mData.mStatus = GuestSessionStatus_Error; 1123 break; 1124 1125 case GUEST_SESSION_NOTIFYTYPE_OPEN: 1126 if (RT_FAILURE(guestRc)) 1127 mData.mStatus = GuestSessionStatus_Started; 1128 break; 1129 1130 case GUEST_SESSION_NOTIFYTYPE_CLOSE: 1131 if (RT_FAILURE(guestRc)) 1132 mData.mStatus = GuestSessionStatus_Terminated; 1133 break; 1134 1135 default: 1136 vrc = VERR_NOT_SUPPORTED; 1137 break; 1138 } 1139 1140 if (RT_SUCCESS(vrc)) 1141 { 1142 if (RT_FAILURE(guestRc)) 1143 mData.mStatus = GuestSessionStatus_Error; 1144 } 1145 else if (vrc == VERR_NOT_SUPPORTED) 1146 { 1147 /* Also let the callback know. */ 1148 guestRc = VERR_NOT_SUPPORTED; 1149 } 983 1150 984 1151 /* … … 987 1154 if (pCallback) 988 1155 { 989 vrc = pCallback->SetData(&dataCb, sizeof(dataCb)); 990 991 int rc2 = pCallback->Signal(rcCb); 992 if (RT_SUCCESS(vrc)) 993 vrc = rc2; 994 } 1156 int rc2 = pCallback->SetData(&dataCb, sizeof(dataCb)); 1157 AssertRC(rc2); 1158 rc2 = pCallback->Signal(guestRc); 1159 AssertRC(rc2); 1160 } 1161 1162 LogFlowThisFunc(("ID=%RU32, guestRc=%Rrc\n", 1163 mData.mSession.mID, guestRc)); 995 1164 996 1165 LogFlowFuncLeaveRC(vrc); … … 998 1167 } 999 1168 1000 int GuestSession::openSession( uint32_t uFlags, uint32_t uTimeoutMS,int *pGuestRc)1169 int GuestSession::openSession(int *pGuestRc) 1001 1170 { 1002 1171 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1003 1172 1004 LogFlowThisFunc(("uProtocolVersion=%RU32, uFlags=%x, uTimeoutMS=%RU32\n",1005 mData.mProtocolVersion, uFlags, uTimeoutMS));1173 LogFlowThisFunc(("uProtocolVersion=%RU32, openFlags=%x, openTimeoutMS=%RU32\n", 1174 mData.mProtocolVersion, mData.mSession.mOpenFlags, mData.mSession.mOpenTimeoutMS)); 1006 1175 1007 1176 /* Legacy Guest Additions don't support opening dedicated 1008 guest sessions. */1177 guest sessions. Simply return success here. */ 1009 1178 if (mData.mProtocolVersion < 2) 1010 1179 { 1011 LogFlowThisFunc(("Installed Guest Additions don't support opening separate sessions\n")); 1180 mData.mStatus = GuestSessionStatus_Started; 1181 1182 LogFlowThisFunc(("Installed Guest Additions don't support opening dedicated sessions, skipping\n")); 1012 1183 return VINF_SUCCESS; 1013 1184 } 1014 1185 1015 /** @todo uFlags validation. */ 1186 /** @todo mData.mSession.uFlags validation. */ 1187 1188 /* Set current session status. */ 1189 mData.mStatus = GuestSessionStatus_Starting; 1016 1190 1017 1191 /* Destroy a pending callback request. */ … … 1025 1199 { 1026 1200 uint32_t uContextID = 1027 VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mId, 0 /* Object */, 0 /* Count */); 1201 VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mSession.mID /* Session ID */, 1202 0 /* Object */, 0 /* Count */); 1028 1203 1029 1204 VBOXHGCMSVCPARM paParms[8]; … … 1038 1213 paParms[i++].setPointer((void*)mData.mCredentials.mDomain.c_str(), 1039 1214 (ULONG)mData.mCredentials.mDomain.length() + 1); 1040 paParms[i++].setUInt32( uFlags);1215 paParms[i++].setUInt32(mData.mSession.mOpenFlags); 1041 1216 1042 1217 vrc = sendCommand(HOST_SESSION_CREATE, i, paParms); … … 1049 1224 * Note: Be sure not keeping a AutoRead/WriteLock here. 1050 1225 */ 1051 LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS));1052 vrc = mData.mCallback.Wait( uTimeoutMS);1226 LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", mData.mSession.mOpenTimeoutMS)); 1227 vrc = mData.mCallback.Wait(mData.mSession.mOpenTimeoutMS); 1053 1228 if (RT_SUCCESS(vrc)) /* Wait was successful, check for supplied information. */ 1054 1229 { 1055 1230 int guestRc = mData.mCallback.GetResultCode(); 1231 if (RT_SUCCESS(guestRc)) 1232 { 1233 /* Nothing to do here right now. */ 1234 } 1235 else 1236 vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */ 1237 1056 1238 if (pGuestRc) 1057 1239 *pGuestRc = guestRc; 1058 1240 LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc)); 1059 1241 } 1060 else 1061 vrc = VERR_TIMEOUT; 1062 } 1063 1064 AutoWriteLock awlock(this COMMA_LOCKVAL_SRC_POS); 1242 } 1243 1244 alock.acquire(); 1065 1245 1066 1246 /* Destroy callback. */ … … 1071 1251 } 1072 1252 1253 int GuestSession::openSessionAsync(void) 1254 { 1255 LogFlowThisFuncEnter(); 1256 1257 int vrc; 1258 1259 try 1260 { 1261 /* Asynchronously open the session on the guest by kicking off a 1262 * worker thread. */ 1263 std::auto_ptr<GuestSessionTaskInternalOpen> pTask(new GuestSessionTaskInternalOpen(this)); 1264 AssertReturn(pTask->isOk(), pTask->rc()); 1265 1266 vrc = RTThreadCreate(NULL, GuestSession::openSessionThread, 1267 (void *)pTask.get(), 0, 1268 RTTHREADTYPE_MAIN_WORKER, 0, 1269 "gctlSesOpen"); 1270 if (RT_SUCCESS(vrc)) 1271 { 1272 /* pTask is now owned by openSessionThread(), so release it. */ 1273 pTask.release(); 1274 } 1275 } 1276 catch(std::bad_alloc &) 1277 { 1278 vrc = VERR_NO_MEMORY; 1279 } 1280 1281 LogFlowFuncLeaveRC(vrc); 1282 return vrc; 1283 } 1284 1285 /* static */ 1286 DECLCALLBACK(int) GuestSession::openSessionThread(RTTHREAD Thread, void *pvUser) 1287 { 1288 LogFlowFunc(("pvUser=%p\n", pvUser)); 1289 1290 std::auto_ptr<GuestSessionTaskInternalOpen> pTask(static_cast<GuestSessionTaskInternalOpen*>(pvUser)); 1291 AssertPtr(pTask.get()); 1292 1293 const ComObjPtr<GuestSession> pSession(pTask->Session()); 1294 Assert(!pSession.isNull()); 1295 1296 AutoCaller autoCaller(pSession); 1297 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1298 1299 int vrc = pSession->openSession(NULL /* Guest rc, ignored */); 1300 /* Nothing to do here anymore. */ 1301 1302 LogFlowFuncLeaveRC(vrc); 1303 return vrc; 1304 } 1305 1073 1306 int GuestSession::processRemoveFromList(GuestProcess *pProcess) 1074 1307 { … … 1097 1330 Assert(mData.mNumObjects); 1098 1331 LogFlowFunc(("Removing process (Session: %RU32) with process ID=%RU32, guest PID=%RU32 (now total %ld processes, %ld objects)\n", 1099 mData.m Id, pCurProc->getObjectID(), uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));1332 mData.mSession.mID, pCurProc->getObjectID(), uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1)); 1100 1333 1101 1334 mData.mProcesses.erase(itProcs); … … 1192 1425 uNewProcessID = 0; 1193 1426 1194 if (++uTries == UINT32_MAX)1427 if (++uTries == VBOX_GUESTCTRL_MAX_OBJECTS) 1195 1428 break; /* Don't try too hard. */ 1196 1429 } … … 1215 1448 1216 1449 LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes, %ld objects)\n", 1217 mData.m Id, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects));1450 mData.mSession.mID, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects)); 1218 1451 1219 1452 return rc; … … 1285 1518 LogFlowFuncLeaveRC(vrc); 1286 1519 return vrc; 1520 } 1521 1522 /* static */ 1523 HRESULT GuestSession::setErrorExternal(VirtualBoxBase *pInterface, int guestRc) 1524 { 1525 AssertPtr(pInterface); 1526 AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n")); 1527 1528 return pInterface->setError(VBOX_E_IPRT_ERROR, GuestSession::guestErrorToString(guestRc).c_str()); 1287 1529 } 1288 1530 … … 1328 1570 int GuestSession::queryInfo(void) 1329 1571 { 1330 #if 1 1331 /* Since the new functions were not implemented yet, force Main to use protocol ver 1. */ 1572 #ifndef DEBUG_andy 1573 /* Since the new functions are not fully implemented yet, force Main 1574 to use protocol ver 1 so far. */ 1575 mData.mProtocolVersion = 1; 1576 #else 1577 #if 1 1578 /* For debugging only: Hardcode version. */ 1332 1579 mData.mProtocolVersion = 2; 1333 #else1580 #else 1334 1581 /* 1335 1582 * Try querying the guest control protocol version running on the guest. … … 1351 1598 LogRel((tr("Warning: Guest Additions are older (%ld.%ld) than host capabilities for guest control, please upgrade them. Using protocol version %ld now\n"), 1352 1599 VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions), VBOX_FULL_VERSION_GET_MINOR(uVerAdditions), mData.mProtocolVersion)); 1600 #endif 1353 1601 #endif 1354 1602 return VINF_SUCCESS; … … 1372 1620 int rc = closeSession(0 /* Flags */, 30 * 1000 /* Timeout */, 1373 1621 &guestRc); 1374 if (RT_FAILURE(rc)) 1375 { 1376 1377 } 1622 /* On failure don't return here, instead do all the cleanup 1623 * work first and then return an error. */ 1378 1624 1379 1625 /* Remove ourselves from the session list. */ 1380 mData.mParent->sessionRemove(this); 1626 int rc2 = mData.mParent->sessionRemove(this); 1627 if (RT_SUCCESS(rc)) 1628 rc = rc2; 1381 1629 1382 1630 /* … … 1387 1635 uninit(); 1388 1636 1389 LogFlowFuncLeave(); 1637 LogFlowFuncLeaveRC(rc); 1638 if (RT_FAILURE(rc)) 1639 { 1640 /** @todo Handle guestRc! */ 1641 return setError(VBOX_E_IPRT_ERROR, 1642 tr("Closing guest session failed with %Rrc\n"), rc); 1643 } 1644 1390 1645 return S_OK; 1391 1646 #endif /* VBOX_WITH_GUEST_CONTROL */ -
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r44869 r44935 176 176 } 177 177 178 int SessionTaskOpen::Run( void)178 int SessionTaskOpen::Run(int *pGuestRc) 179 179 { 180 180 LogFlowThisFuncEnter(); … … 186 186 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 187 187 188 int vrc = pSession->openSession(mFlags, mTimeoutMS, 189 NULL /* Guest rc, ignored */); 188 int vrc = pSession->openSession(pGuestRc); 190 189 /* Nothing to do here anymore. */ 191 190 … … 215 214 216 215 LogFlowFunc(("pTask=%p\n", task.get())); 217 return task->Run( );216 return task->Run(NULL /* guestRc */); 218 217 } 219 218
Note:
See TracChangeset
for help on using the changeset viewer.