儲存庫 vbox 的更動 55644
- 時間撮記:
- 2015-5-4 下午01:27:35 (10 年 以前)
- svn:sync-xref-src-repo-rev:
- 100019
- 位置:
- trunk/src/VBox/Main
- 檔案:
-
- 修改 9 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Main/Makefile.kmk
r55615 r55644 741 741 src-client/EmulatedUSBImpl.cpp \ 742 742 src-client/GuestImpl.cpp \ 743 src-client/GuestDirectoryImpl.cpp \744 src-client/GuestFileImpl.cpp \745 src-client/GuestFsObjInfoImpl.cpp \746 src-client/GuestProcessImpl.cpp \747 src-client/GuestSessionImpl.cpp \748 743 src-client/GuestCtrlImpl.cpp \ 749 744 src-client/KeyboardImpl.cpp \ … … 774 769 VBoxC_SOURCES += \ 775 770 src-client/GuestSessionImplTasks.cpp \ 776 src-client/GuestCtrlPrivate.cpp 771 src-client/GuestCtrlPrivate.cpp \ 772 src-client/GuestDirectoryImpl.cpp \ 773 src-client/GuestFileImpl.cpp \ 774 src-client/GuestFsObjInfoImpl.cpp \ 775 src-client/GuestProcessImpl.cpp \ 776 src-client/GuestSessionImpl.cpp 777 777 endif 778 778 ifdef VBOX_WITH_DRAG_AND_DROP -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r55631 r55644 1 1 /* $Id$ */ 2 2 /** @file 3 *4 3 * Internal helpers/structures for guest control functionality. 5 4 */ -
trunk/src/VBox/Main/include/GuestImpl.h
r55613 r55644 27 27 28 28 #include "AdditionsFacilityImpl.h" 29 #include "GuestCtrlImplPrivate.h" 29 #ifdef VBOX_WITH_GUEST_CONTROL 30 # include "GuestCtrlImplPrivate.h" 31 # include "GuestSessionImpl.h" 32 #endif 30 33 #ifdef VBOX_WITH_DRAG_AND_DROP 31 34 # include "GuestDnDSourceImpl.h" 32 35 # include "GuestDnDTargetImpl.h" 33 36 #endif 34 #include " GuestSessionImpl.h"37 #include "EventImpl.h" 35 38 #include "HGCM.h" 36 39 … … 72 75 /** Static callback for handling guest control notifications. */ 73 76 static DECLCALLBACK(int) i_notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvData, uint32_t cbData); 77 #endif 74 78 static DECLCALLBACK(void) i_staticUpdateStats(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick); 75 #endif76 79 /** @} */ 77 80 … … 96 99 return setErrorInternal(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, false, true); 97 100 } 98 #ifdef VBOX_WITH_GUEST_CONTROL99 int i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);100 101 uint32_t i_getAdditionsVersion(void) { return mData.mAdditionsVersionFull; } 101 102 VBOXOSTYPE i_getGuestOSType(void) { return mData.mOSType; } 103 #ifdef VBOX_WITH_GUEST_CONTROL 104 int i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb); 102 105 int i_sessionRemove(GuestSession *pSession); 103 106 int i_sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds, … … 174 177 typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::const_iterator FacilityMapIterConst; 175 178 179 #ifdef VBOX_WITH_GUEST_CONTROL 176 180 /** Map for keeping the guest sessions. The primary key marks the guest session ID. */ 177 181 typedef std::map <uint32_t, ComObjPtr<GuestSession> > GuestSessions; 182 #endif 178 183 179 184 struct Data … … 192 197 uint32_t mAdditionsFeatures; 193 198 Utf8Str mInterfaceVersion; 199 #ifdef VBOX_WITH_GUEST_CONTROL 194 200 GuestSessions mGuestSessions; 195 201 uint32_t mNextSessionID; 202 #endif 196 203 } mData; 197 204 … … 208 215 const ComObjPtr<Console> mParent; 209 216 210 #ifdef VBOX_WITH_GUEST_CONTROL211 217 /** 212 218 * This can safely be used without holding any locks. … … 215 221 */ 216 222 const ComObjPtr<EventSource> mEventSource; 223 #ifdef VBOX_WITH_GUEST_CONTROL 217 224 /** General extension callback for guest control. */ 218 225 HGCMSVCEXTHANDLE mhExtCtrl; -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r52085 r55644 17 17 18 18 #include "GuestImpl.h" 19 #include "GuestSessionImpl.h" 20 #include "GuestCtrlImplPrivate.h" 19 #ifdef VBOX_WITH_GUEST_CONTROL 20 # include "GuestSessionImpl.h" 21 # include "GuestCtrlImplPrivate.h" 22 #endif 21 23 22 24 #include "Global.h" … … 49 51 #include <VBox/log.h> 50 52 53 #ifdef VBOX_WITH_GUEST_CONTROL 51 54 52 55 // public methods only for internal purposes 53 56 ///////////////////////////////////////////////////////////////////////////// 54 57 55 #ifdef VBOX_WITH_GUEST_CONTROL56 58 /** 57 59 * Static callback function for receiving updates on guest control commands … … 112 114 return rc; 113 115 } 116 117 // private methods 118 ///////////////////////////////////////////////////////////////////////////// 119 120 int Guest::i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 121 { 122 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb)); 123 124 AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER); 125 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 126 127 LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n", 128 pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol)); 129 130 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 131 132 uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID); 133 #ifdef DEBUG 134 LogFlowFunc(("uSessionID=%RU32 (%zu total)\n", 135 uSessionID, mData.mGuestSessions.size())); 136 #endif 137 GuestSessions::const_iterator itSession 138 = mData.mGuestSessions.find(uSessionID); 139 140 int rc; 141 if (itSession != mData.mGuestSessions.end()) 142 { 143 ComObjPtr<GuestSession> pSession(itSession->second); 144 Assert(!pSession.isNull()); 145 146 alock.release(); 147 148 bool fDispatch = true; 149 #ifdef DEBUG 150 /* 151 * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA 152 * it means that that guest could not handle the entire message 153 * because of its exceeding size. This should not happen on daily 154 * use but testcases might try this. It then makes no sense to dispatch 155 * this further because we don't have a valid context ID. 156 */ 157 if ( pCtxCb->uFunction == GUEST_EXEC_STATUS 158 && pSvcCb->mParms >= 5) 159 { 160 CALLBACKDATA_PROC_STATUS dataCb; 161 /* pSvcCb->mpaParms[0] always contains the context ID. */ 162 pSvcCb->mpaParms[1].getUInt32(&dataCb.uPID); 163 pSvcCb->mpaParms[2].getUInt32(&dataCb.uStatus); 164 pSvcCb->mpaParms[3].getUInt32(&dataCb.uFlags); 165 pSvcCb->mpaParms[4].getPointer(&dataCb.pvData, &dataCb.cbData); 166 167 if ( ( dataCb.uStatus == PROC_STS_ERROR) 168 /** @todo Note: Due to legacy reasons we cannot change uFlags to 169 * int32_t, so just cast it for now. */ 170 && ((int32_t)dataCb.uFlags == VERR_TOO_MUCH_DATA)) 171 { 172 LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n")); 173 174 Assert(dataCb.uPID == 0); 175 fDispatch = false; 176 } 177 } 178 #endif 179 if (fDispatch) 180 { 181 switch (pCtxCb->uFunction) 182 { 183 case GUEST_DISCONNECTED: 184 rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb); 185 break; 186 187 case GUEST_EXEC_STATUS: 188 case GUEST_EXEC_OUTPUT: 189 case GUEST_EXEC_INPUT_STATUS: 190 case GUEST_EXEC_IO_NOTIFY: 191 rc = pSession->i_dispatchToProcess(pCtxCb, pSvcCb); 192 break; 193 194 case GUEST_FILE_NOTIFY: 195 rc = pSession->i_dispatchToFile(pCtxCb, pSvcCb); 196 break; 197 198 case GUEST_SESSION_NOTIFY: 199 rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb); 200 break; 201 202 default: 203 /* 204 * Try processing generic messages which might 205 * (or might not) supported by certain objects. 206 * If the message either is not found or supported 207 * by the approprirate object, try handling it 208 * in this session object. 209 */ 210 rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb); 211 if ( rc == VERR_NOT_FOUND 212 || rc == VERR_NOT_SUPPORTED) 213 { 214 alock.acquire(); 215 216 rc = pSession->dispatchGeneric(pCtxCb, pSvcCb); 217 } 218 #ifndef DEBUG_andy 219 if (rc == VERR_NOT_IMPLEMENTED) 220 AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction)); 221 #endif 222 break; 223 } 224 } 225 else 226 rc = VERR_NOT_FOUND; 227 } 228 else 229 rc = VERR_NOT_FOUND; 230 231 LogFlowFuncLeaveRC(rc); 232 return rc; 233 } 234 235 int Guest::i_sessionRemove(GuestSession *pSession) 236 { 237 AssertPtrReturn(pSession, VERR_INVALID_POINTER); 238 239 LogFlowThisFuncEnter(); 240 241 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 242 243 int rc = VERR_NOT_FOUND; 244 245 LogFlowThisFunc(("Removing session (ID=%RU32) ...\n", pSession->i_getId())); 246 247 GuestSessions::iterator itSessions = mData.mGuestSessions.begin(); 248 while (itSessions != mData.mGuestSessions.end()) 249 { 250 if (pSession == itSessions->second) 251 { 252 #ifdef DEBUG_andy 253 ULONG cRefs = pSession->AddRef(); 254 Assert(cRefs >= 2); 255 LogFlowThisFunc(("pCurSession=%p, cRefs=%RU32\n", pSession, cRefs - 2)); 256 pSession->Release(); 257 #endif 258 /* Make sure to consume the pointer before the one of the 259 * iterator gets released. */ 260 ComObjPtr<GuestSession> pCurSession = pSession; 261 262 LogFlowThisFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n", 263 pSession, pSession->i_getId(), mData.mGuestSessions.size() - 1)); 264 265 rc = pSession->i_onRemove(); 266 mData.mGuestSessions.erase(itSessions); 267 268 alock.release(); /* Release lock before firing off event. */ 269 270 fireGuestSessionRegisteredEvent(mEventSource, pCurSession, 271 false /* Unregistered */); 272 pCurSession.setNull(); 273 break; 274 } 275 276 itSessions++; 277 } 278 279 LogFlowFuncLeaveRC(rc); 280 return rc; 281 } 282 283 int Guest::i_sessionCreate(const GuestSessionStartupInfo &ssInfo, 284 const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession) 285 { 286 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 287 288 int rc = VERR_MAX_PROCS_REACHED; 289 if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS) 290 return rc; 291 292 try 293 { 294 /* Create a new session ID and assign it. */ 295 uint32_t uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE; 296 uint32_t uTries = 0; 297 298 for (;;) 299 { 300 /* Is the context ID already used? */ 301 if (!i_sessionExists(uNewSessionID)) 302 { 303 rc = VINF_SUCCESS; 304 break; 305 } 306 uNewSessionID++; 307 if (uNewSessionID >= VBOX_GUESTCTRL_MAX_SESSIONS) 308 uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE; 309 310 if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS) 311 break; /* Don't try too hard. */ 312 } 313 if (RT_FAILURE(rc)) throw rc; 314 315 /* Create the session object. */ 316 HRESULT hr = pGuestSession.createObject(); 317 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 318 319 /** @todo Use an overloaded copy operator. Later. */ 320 GuestSessionStartupInfo startupInfo; 321 startupInfo.mID = uNewSessionID; /* Assign new session ID. */ 322 startupInfo.mName = ssInfo.mName; 323 startupInfo.mOpenFlags = ssInfo.mOpenFlags; 324 startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS; 325 326 GuestCredentials guestCredentials; 327 if (!guestCreds.mUser.isEmpty()) 328 { 329 /** @todo Use an overloaded copy operator. Later. */ 330 guestCredentials.mUser = guestCreds.mUser; 331 guestCredentials.mPassword = guestCreds.mPassword; 332 guestCredentials.mDomain = guestCreds.mDomain; 333 } 334 else 335 { 336 /* Internal (annonymous) session. */ 337 startupInfo.mIsInternal = true; 338 } 339 340 rc = pGuestSession->init(this, startupInfo, guestCredentials); 341 if (RT_FAILURE(rc)) throw rc; 342 343 /* 344 * Add session object to our session map. This is necessary 345 * before calling openSession because the guest calls back 346 * with the creation result of this session. 347 */ 348 mData.mGuestSessions[uNewSessionID] = pGuestSession; 349 350 alock.release(); /* Release lock before firing off event. */ 351 352 fireGuestSessionRegisteredEvent(mEventSource, pGuestSession, 353 true /* Registered */); 354 } 355 catch (int rc2) 356 { 357 rc = rc2; 358 } 359 360 LogFlowFuncLeaveRC(rc); 361 return rc; 362 } 363 364 inline bool Guest::i_sessionExists(uint32_t uSessionID) 365 { 366 GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID); 367 return (itSessions == mData.mGuestSessions.end()) ? false : true; 368 } 369 114 370 #endif /* VBOX_WITH_GUEST_CONTROL */ 371 372 373 // implementation of public methods 374 ///////////////////////////////////////////////////////////////////////////// 375 HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain, 376 const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession) 377 378 { 379 #ifndef VBOX_WITH_GUEST_CONTROL 380 ReturnComNotImplemented(); 381 #else /* VBOX_WITH_GUEST_CONTROL */ 382 383 LogFlowFuncEnter(); 384 385 /* Do not allow anonymous sessions (with system rights) with public API. */ 386 if (RT_UNLIKELY(!aUser.length())) 387 return setError(E_INVALIDARG, tr("No user name specified")); 388 389 GuestSessionStartupInfo startupInfo; 390 startupInfo.mName = aSessionName; 391 392 GuestCredentials guestCreds; 393 guestCreds.mUser = aUser; 394 guestCreds.mPassword = aPassword; 395 guestCreds.mDomain = aDomain; 396 397 ComObjPtr<GuestSession> pSession; 398 int rc = i_sessionCreate(startupInfo, guestCreds, pSession); 399 if (RT_SUCCESS(rc)) 400 { 401 /* Return guest session to the caller. */ 402 HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam()); 403 if (FAILED(hr2)) 404 rc = VERR_COM_OBJECT_NOT_FOUND; 405 } 406 407 if (RT_SUCCESS(rc)) 408 /* Start (fork) the session asynchronously 409 * on the guest. */ 410 rc = pSession->i_startSessionAsync(); 411 412 HRESULT hr = S_OK; 413 414 if (RT_FAILURE(rc)) 415 { 416 switch (rc) 417 { 418 case VERR_MAX_PROCS_REACHED: 419 hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"), 420 VBOX_GUESTCTRL_MAX_SESSIONS); 421 break; 422 423 /** @todo Add more errors here. */ 424 425 default: 426 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); 427 break; 428 } 429 } 430 431 LogFlowThisFunc(("Returning rc=%Rhrc\n", hr)); 432 return hr; 433 #endif /* VBOX_WITH_GUEST_CONTROL */ 434 } 435 436 HRESULT Guest::findSession(const com::Utf8Str &aSessionName, std::vector<ComPtr<IGuestSession> > &aSessions) 437 { 438 #ifndef VBOX_WITH_GUEST_CONTROL 439 ReturnComNotImplemented(); 440 #else /* VBOX_WITH_GUEST_CONTROL */ 441 442 LogFlowFuncEnter(); 443 444 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 445 446 Utf8Str strName(aSessionName); 447 std::list < ComObjPtr<GuestSession> > listSessions; 448 449 GuestSessions::const_iterator itSessions = mData.mGuestSessions.begin(); 450 while (itSessions != mData.mGuestSessions.end()) 451 { 452 if (strName.contains(itSessions->second->i_getName())) /** @todo Use a (simple) pattern match (IPRT?). */ 453 listSessions.push_back(itSessions->second); 454 itSessions++; 455 } 456 457 LogFlowFunc(("Sessions with \"%s\" = %RU32\n", 458 aSessionName.c_str(), listSessions.size())); 459 460 aSessions.resize(listSessions.size()); 461 if (listSessions.size()) 462 { 463 size_t i = 0; 464 for (std::list < ComObjPtr<GuestSession> >::const_iterator it = listSessions.begin(); it != listSessions.end(); ++it, ++i) 465 (*it).queryInterfaceTo(aSessions[i].asOutParam()); 466 467 return S_OK; 468 469 } 470 471 return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND, 472 tr("Could not find sessions with name '%s'"), 473 aSessionName.c_str()); 474 #endif /* VBOX_WITH_GUEST_CONTROL */ 475 } 115 476 116 477 HRESULT Guest::updateGuestAdditions(const com::Utf8Str &aSource, const std::vector<com::Utf8Str> &aArguments, … … 217 578 } 218 579 219 // private methods220 /////////////////////////////////////////////////////////////////////////////221 222 int Guest::i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)223 {224 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));225 226 AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);227 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);228 229 LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n",230 pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));231 232 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);233 234 uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID);235 #ifdef DEBUG236 LogFlowFunc(("uSessionID=%RU32 (%zu total)\n",237 uSessionID, mData.mGuestSessions.size()));238 #endif239 GuestSessions::const_iterator itSession240 = mData.mGuestSessions.find(uSessionID);241 242 int rc;243 if (itSession != mData.mGuestSessions.end())244 {245 ComObjPtr<GuestSession> pSession(itSession->second);246 Assert(!pSession.isNull());247 248 alock.release();249 250 bool fDispatch = true;251 #ifdef DEBUG252 /*253 * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA254 * it means that that guest could not handle the entire message255 * because of its exceeding size. This should not happen on daily256 * use but testcases might try this. It then makes no sense to dispatch257 * this further because we don't have a valid context ID.258 */259 if ( pCtxCb->uFunction == GUEST_EXEC_STATUS260 && pSvcCb->mParms >= 5)261 {262 CALLBACKDATA_PROC_STATUS dataCb;263 /* pSvcCb->mpaParms[0] always contains the context ID. */264 pSvcCb->mpaParms[1].getUInt32(&dataCb.uPID);265 pSvcCb->mpaParms[2].getUInt32(&dataCb.uStatus);266 pSvcCb->mpaParms[3].getUInt32(&dataCb.uFlags);267 pSvcCb->mpaParms[4].getPointer(&dataCb.pvData, &dataCb.cbData);268 269 if ( ( dataCb.uStatus == PROC_STS_ERROR)270 /** @todo Note: Due to legacy reasons we cannot change uFlags to271 * int32_t, so just cast it for now. */272 && ((int32_t)dataCb.uFlags == VERR_TOO_MUCH_DATA))273 {274 LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n"));275 276 Assert(dataCb.uPID == 0);277 fDispatch = false;278 }279 }280 #endif281 if (fDispatch)282 {283 switch (pCtxCb->uFunction)284 {285 case GUEST_DISCONNECTED:286 rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);287 break;288 289 case GUEST_EXEC_STATUS:290 case GUEST_EXEC_OUTPUT:291 case GUEST_EXEC_INPUT_STATUS:292 case GUEST_EXEC_IO_NOTIFY:293 rc = pSession->i_dispatchToProcess(pCtxCb, pSvcCb);294 break;295 296 case GUEST_FILE_NOTIFY:297 rc = pSession->i_dispatchToFile(pCtxCb, pSvcCb);298 break;299 300 case GUEST_SESSION_NOTIFY:301 rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);302 break;303 304 default:305 /*306 * Try processing generic messages which might307 * (or might not) supported by certain objects.308 * If the message either is not found or supported309 * by the approprirate object, try handling it310 * in this session object.311 */312 rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);313 if ( rc == VERR_NOT_FOUND314 || rc == VERR_NOT_SUPPORTED)315 {316 alock.acquire();317 318 rc = pSession->dispatchGeneric(pCtxCb, pSvcCb);319 }320 #ifndef DEBUG_andy321 if (rc == VERR_NOT_IMPLEMENTED)322 AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction));323 #endif324 break;325 }326 }327 else328 rc = VERR_NOT_FOUND;329 }330 else331 rc = VERR_NOT_FOUND;332 333 LogFlowFuncLeaveRC(rc);334 return rc;335 }336 337 int Guest::i_sessionRemove(GuestSession *pSession)338 {339 AssertPtrReturn(pSession, VERR_INVALID_POINTER);340 341 LogFlowThisFuncEnter();342 343 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);344 345 int rc = VERR_NOT_FOUND;346 347 LogFlowThisFunc(("Removing session (ID=%RU32) ...\n", pSession->i_getId()));348 349 GuestSessions::iterator itSessions = mData.mGuestSessions.begin();350 while (itSessions != mData.mGuestSessions.end())351 {352 if (pSession == itSessions->second)353 {354 #ifdef DEBUG_andy355 ULONG cRefs = pSession->AddRef();356 Assert(cRefs >= 2);357 LogFlowThisFunc(("pCurSession=%p, cRefs=%RU32\n", pSession, cRefs - 2));358 pSession->Release();359 #endif360 /* Make sure to consume the pointer before the one of the361 * iterator gets released. */362 ComObjPtr<GuestSession> pCurSession = pSession;363 364 LogFlowThisFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n",365 pSession, pSession->i_getId(), mData.mGuestSessions.size() - 1));366 367 rc = pSession->i_onRemove();368 mData.mGuestSessions.erase(itSessions);369 370 alock.release(); /* Release lock before firing off event. */371 372 fireGuestSessionRegisteredEvent(mEventSource, pCurSession,373 false /* Unregistered */);374 pCurSession.setNull();375 break;376 }377 378 itSessions++;379 }380 381 LogFlowFuncLeaveRC(rc);382 return rc;383 }384 385 int Guest::i_sessionCreate(const GuestSessionStartupInfo &ssInfo,386 const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession)387 {388 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);389 390 int rc = VERR_MAX_PROCS_REACHED;391 if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS)392 return rc;393 394 try395 {396 /* Create a new session ID and assign it. */397 uint32_t uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;398 uint32_t uTries = 0;399 400 for (;;)401 {402 /* Is the context ID already used? */403 if (!i_sessionExists(uNewSessionID))404 {405 rc = VINF_SUCCESS;406 break;407 }408 uNewSessionID++;409 if (uNewSessionID >= VBOX_GUESTCTRL_MAX_SESSIONS)410 uNewSessionID = VBOX_GUESTCTRL_SESSION_ID_BASE;411 412 if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS)413 break; /* Don't try too hard. */414 }415 if (RT_FAILURE(rc)) throw rc;416 417 /* Create the session object. */418 HRESULT hr = pGuestSession.createObject();419 if (FAILED(hr)) throw VERR_COM_UNEXPECTED;420 421 /** @todo Use an overloaded copy operator. Later. */422 GuestSessionStartupInfo startupInfo;423 startupInfo.mID = uNewSessionID; /* Assign new session ID. */424 startupInfo.mName = ssInfo.mName;425 startupInfo.mOpenFlags = ssInfo.mOpenFlags;426 startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;427 428 GuestCredentials guestCredentials;429 if (!guestCreds.mUser.isEmpty())430 {431 /** @todo Use an overloaded copy operator. Later. */432 guestCredentials.mUser = guestCreds.mUser;433 guestCredentials.mPassword = guestCreds.mPassword;434 guestCredentials.mDomain = guestCreds.mDomain;435 }436 else437 {438 /* Internal (annonymous) session. */439 startupInfo.mIsInternal = true;440 }441 442 rc = pGuestSession->init(this, startupInfo, guestCredentials);443 if (RT_FAILURE(rc)) throw rc;444 445 /*446 * Add session object to our session map. This is necessary447 * before calling openSession because the guest calls back448 * with the creation result of this session.449 */450 mData.mGuestSessions[uNewSessionID] = pGuestSession;451 452 alock.release(); /* Release lock before firing off event. */453 454 fireGuestSessionRegisteredEvent(mEventSource, pGuestSession,455 true /* Registered */);456 }457 catch (int rc2)458 {459 rc = rc2;460 }461 462 LogFlowFuncLeaveRC(rc);463 return rc;464 }465 466 inline bool Guest::i_sessionExists(uint32_t uSessionID)467 {468 GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID);469 return (itSessions == mData.mGuestSessions.end()) ? false : true;470 }471 472 // implementation of public methods473 /////////////////////////////////////////////////////////////////////////////474 HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain,475 const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession)476 477 {478 #ifndef VBOX_WITH_GUEST_CONTROL479 ReturnComNotImplemented();480 #else /* VBOX_WITH_GUEST_CONTROL */481 482 LogFlowFuncEnter();483 484 /* Do not allow anonymous sessions (with system rights) with public API. */485 if (RT_UNLIKELY(!aUser.length()))486 return setError(E_INVALIDARG, tr("No user name specified"));487 488 GuestSessionStartupInfo startupInfo;489 startupInfo.mName = aSessionName;490 491 GuestCredentials guestCreds;492 guestCreds.mUser = aUser;493 guestCreds.mPassword = aPassword;494 guestCreds.mDomain = aDomain;495 496 ComObjPtr<GuestSession> pSession;497 int rc = i_sessionCreate(startupInfo, guestCreds, pSession);498 if (RT_SUCCESS(rc))499 {500 /* Return guest session to the caller. */501 HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam());502 if (FAILED(hr2))503 rc = VERR_COM_OBJECT_NOT_FOUND;504 }505 506 if (RT_SUCCESS(rc))507 /* Start (fork) the session asynchronously508 * on the guest. */509 rc = pSession->i_startSessionAsync();510 511 HRESULT hr = S_OK;512 513 if (RT_FAILURE(rc))514 {515 switch (rc)516 {517 case VERR_MAX_PROCS_REACHED:518 hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"),519 VBOX_GUESTCTRL_MAX_SESSIONS);520 break;521 522 /** @todo Add more errors here. */523 524 default:525 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc);526 break;527 }528 }529 530 LogFlowThisFunc(("Returning rc=%Rhrc\n", hr));531 return hr;532 #endif /* VBOX_WITH_GUEST_CONTROL */533 }534 535 HRESULT Guest::findSession(const com::Utf8Str &aSessionName, std::vector<ComPtr<IGuestSession> > &aSessions)536 {537 #ifndef VBOX_WITH_GUEST_CONTROL538 ReturnComNotImplemented();539 #else /* VBOX_WITH_GUEST_CONTROL */540 541 LogFlowFuncEnter();542 543 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);544 545 Utf8Str strName(aSessionName);546 std::list < ComObjPtr<GuestSession> > listSessions;547 548 GuestSessions::const_iterator itSessions = mData.mGuestSessions.begin();549 while (itSessions != mData.mGuestSessions.end())550 {551 if (strName.contains(itSessions->second->i_getName())) /** @todo Use a (simple) pattern match (IPRT?). */552 listSessions.push_back(itSessions->second);553 itSessions++;554 }555 556 LogFlowFunc(("Sessions with \"%s\" = %RU32\n",557 aSessionName.c_str(), listSessions.size()));558 559 aSessions.resize(listSessions.size());560 if (listSessions.size())561 {562 size_t i = 0;563 for (std::list < ComObjPtr<GuestSession> >::const_iterator it = listSessions.begin(); it != listSessions.end(); ++it, ++i)564 (*it).queryInterfaceTo(aSessions[i].asOutParam());565 566 return S_OK;567 568 }569 570 return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND,571 tr("Could not find sessions with name '%s'"),572 aSessionName.c_str());573 #endif /* VBOX_WITH_GUEST_CONTROL */574 }575 -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r55611 r55644 19 19 * Header Files * 20 20 ******************************************************************************/ 21 #ifndef VBOX_WITH_GUEST_CONTROL 22 # error "VBOX_WITH_GUEST_CONTROL must defined in this file" 23 #endif 21 24 #include "GuestCtrlImplPrivate.h" 22 25 #include "GuestSessionImpl.h" -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r55640 r55644 23 23 #include "GuestDnDSourceImpl.h" 24 24 #include "GuestDnDPrivate.h" 25 #include "ConsoleImpl.h" 25 26 26 27 #include "Global.h" 27 28 #include "AutoCaller.h" 28 29 30 #include <iprt/asm.h> 29 31 #include <iprt/dir.h> 30 32 #include <iprt/file.h> -
trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
r55640 r55644 22 22 #include "GuestImpl.h" 23 23 #include "GuestDnDTargetImpl.h" 24 #include "ConsoleImpl.h" 24 25 25 26 #include "Global.h" … … 28 29 #include <algorithm> /* For std::find(). */ 29 30 31 #include <iprt/asm.h> 30 32 #include <iprt/file.h> 31 33 #include <iprt/dir.h> -
trunk/src/VBox/Main/src-client/GuestImpl.cpp
r55613 r55644 17 17 18 18 #include "GuestImpl.h" 19 #include "GuestSessionImpl.h" 20 19 #ifdef VBOX_WITH_GUEST_CONTROL 20 # include "GuestSessionImpl.h" 21 #endif 21 22 #include "Global.h" 22 23 #include "ConsoleImpl.h" … … 109 110 AssertMsgRC(vrc, ("Failed to create guest statistics update timer (%Rrc)\n", vrc)); 110 111 111 #ifdef VBOX_WITH_GUEST_CONTROL112 112 hr = unconst(mEventSource).createObject(); 113 113 if (SUCCEEDED(hr)) 114 114 hr = mEventSource->init(); 115 #else116 hr = S_OK;117 #endif118 115 119 116 #ifdef VBOX_WITH_DRAG_AND_DROP … … 185 182 #endif 186 183 187 #ifdef VBOX_WITH_GUEST_CONTROL188 184 unconst(mEventSource).setNull(); 189 #endif190 185 unconst(mParent) = NULL; 191 186 … … 517 512 HRESULT Guest::getEventSource(ComPtr<IEventSource> &aEventSource) 518 513 { 519 #ifndef VBOX_WITH_GUEST_CONTROL520 ReturnComNotImplemented();521 #else522 514 LogFlowThisFuncEnter(); 523 515 … … 527 519 LogFlowFuncLeaveRC(S_OK); 528 520 return S_OK; 529 #endif /* VBOX_WITH_GUEST_CONTROL */530 521 } 531 522 … … 544 535 HRESULT Guest::getSessions(std::vector<ComPtr<IGuestSession> > &aSessions) 545 536 { 537 #ifdef VBOX_WITH_GUEST_CONTROL 546 538 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 547 539 … … 552 544 553 545 return S_OK; 546 #else 547 ReturnComNotImplemented(); 548 #endif 554 549 } 555 550 … … 997 992 * @param aDomain Domain of guest user account. Optional. 998 993 * @param enmState New state to indicate. 999 * @param p uDetails Pointer to state details. Optional.994 * @param pbDetails Pointer to state details. Optional. 1000 995 * @param cbDetails Size (in bytes) of state details. Pass 0 if not used. 1001 996 */ 1002 997 void Guest::i_onUserStateChange(Bstr aUser, Bstr aDomain, VBoxGuestUserState enmState, 1003 const uint8_t *p uDetails, uint32_t cbDetails)998 const uint8_t *pbDetails, uint32_t cbDetails) 1004 999 { 1005 1000 LogFlowThisFunc(("\n")); -
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r55631 r55644 21 21 *******************************************************************************/ 22 22 #include "GuestImpl.h" 23 #ifndef VBOX_WITH_GUEST_CONTROL 24 # error "VBOX_WITH_GUEST_CONTROL must defined in this file" 25 #endif 23 26 #include "GuestSessionImpl.h" 24 27 #include "GuestCtrlImplPrivate.h"
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器