Changeset 24663 in vbox for trunk/src/VBox/Main
- Timestamp:
- Nov 14, 2009 11:55:15 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MachineImpl.cpp
r24649 r24663 2029 2029 2030 2030 STDMETHODIMP 2031 Machine::COMGETTER(GuestPropertyNotificationPatterns) 2031 Machine::COMGETTER(GuestPropertyNotificationPatterns)(BSTR *aPatterns) 2032 2032 { 2033 2033 CheckComArgOutPointerValid(aPatterns); … … 2038 2038 AutoReadLock alock(this); 2039 2039 2040 mHWData->mGuestPropertyNotificationPatterns.cloneTo(aPatterns); 2041 2042 return RT_LIKELY (aPatterns != NULL) ? S_OK : E_OUTOFMEMORY; /** @todo r=bird: this is wrong... :-) */ 2040 try 2041 { 2042 mHWData->mGuestPropertyNotificationPatterns.cloneTo(aPatterns); 2043 } 2044 catch (...) 2045 { 2046 return VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 2047 } 2048 2049 return S_OK; 2043 2050 } 2044 2051 2045 2052 STDMETHODIMP 2046 Machine::COMSETTER(GuestPropertyNotificationPatterns) 2047 { 2048 AssertLogRelReturn (VALID_PTR (aPatterns), E_POINTER);2053 Machine::COMSETTER(GuestPropertyNotificationPatterns)(IN_BSTR aPatterns) 2054 { 2055 CheckComArgNotNull(aPatterns); 2049 2056 AutoCaller autoCaller(this); 2050 2057 CheckComRCReturnRC(autoCaller.rc()); … … 2055 2062 CheckComRCReturnRC(rc); 2056 2063 2057 mHWData.backup(); 2058 mHWData->mGuestPropertyNotificationPatterns = aPatterns; 2059 2060 return RT_LIKELY (!mHWData->mGuestPropertyNotificationPatterns.isNull()) 2061 ? S_OK : E_OUTOFMEMORY; 2064 try 2065 { 2066 mHWData.backup(); 2067 mHWData->mGuestPropertyNotificationPatterns = aPatterns; 2068 } 2069 catch (...) 2070 { 2071 rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 2072 } 2073 return rc; 2062 2074 } 2063 2075 … … 3518 3530 try 3519 3531 { 3532 Utf8Str utf8Name(aName); 3533 Utf8Str utf8Flags(aFlags); 3534 3520 3535 AutoCaller autoCaller(this); 3521 3536 CheckComRCReturnRC(autoCaller.rc()); … … 3527 3542 3528 3543 rc = S_OK; 3529 3530 Utf8Str utf8Name(aName);3531 Utf8Str utf8Flags(aFlags);3532 Utf8Str utf8Patterns(mHWData->mGuestPropertyNotificationPatterns);3533 3534 bool matchAll = false;3535 if (utf8Patterns.isEmpty())3536 matchAll = true;3537 3538 3544 uint32_t fFlags = NILFLAG; 3539 3545 if ( (aFlags != NULL) … … 3550 3556 property.mFlags = NILFLAG; 3551 3557 3552 if (SUCCEEDED(rc)) 3553 { 3554 for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin(); 3555 it != mHWData->mGuestProperties.end(); 3556 ++it) 3557 if (it->strName == utf8Name) 3558 /** @todo r=bird: see efficiency rant in PushGuestProperty. (Yeah, I know, 3559 * this is simple and do an OK job atm.) */ 3560 for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin(); 3561 it != mHWData->mGuestProperties.end(); 3562 ++it) 3563 if (it->strName == utf8Name) 3564 { 3565 property = *it; 3566 if (it->mFlags & (RDONLYHOST)) 3567 rc = setError(E_ACCESSDENIED, 3568 tr("The property '%ls' cannot be changed by the host"), 3569 aName); 3570 else 3558 3571 { 3559 property = *it; 3560 if (it->mFlags & (RDONLYHOST)) 3561 rc = setError(E_ACCESSDENIED, 3562 tr("The property '%ls' cannot be changed by the host"), 3563 aName); 3564 else 3565 { 3566 mHWData.backup(); 3567 /* The backup() operation invalidates our iterator, so 3568 * get a new one. */ 3569 for (it = mHWData->mGuestProperties.begin(); 3570 it->strName != utf8Name; 3571 ++it) 3572 ; 3573 mHWData->mGuestProperties.erase (it); 3574 } 3575 found = true; 3576 break; 3572 mHWData.backup(); 3573 /* The backup() operation invalidates our iterator, so 3574 * get a new one. */ 3575 for (it = mHWData->mGuestProperties.begin(); 3576 it->strName != utf8Name; 3577 ++it) 3578 ; 3579 mHWData->mGuestProperties.erase (it); 3577 3580 } 3578 } 3581 found = true; 3582 break; 3583 } 3579 3584 if (found && SUCCEEDED(rc)) 3580 3585 { … … 3600 3605 } 3601 3606 if ( SUCCEEDED(rc) 3602 && ( matchAll 3603 || RTStrSimplePatternMultiMatch (utf8Patterns.raw(), RTSTR_MAX, 3604 utf8Name.raw(), RTSTR_MAX, NULL) 3605 ) 3606 ) 3607 mParent->onGuestPropertyChange (mData->mUuid, aName, aValue, aFlags); 3607 && ( mHWData->mGuestPropertyNotificationPatterns.isEmpty() 3608 || RTStrSimplePatternMultiMatch(mHWData->mGuestPropertyNotificationPatterns.raw(), RTSTR_MAX, 3609 utf8Name.raw(), RTSTR_MAX, NULL) ) 3610 ) 3611 { 3612 /** @todo r=bird: Why aren't we leaving the lock here? The 3613 * same code in PushGuestProperty does... */ 3614 mParent->onGuestPropertyChange(mData->mUuid, aName, aValue, aFlags); 3615 } 3608 3616 } 3609 3617 else … … 3620 3628 rc = E_FAIL; 3621 3629 else 3622 rc = directControl->AccessGuestProperty 3623 (aName, *aValue ? aValue : NULL, aFlags, 3624 true /* isSetter */, &dummy, &dummy64, &dummy); 3630 rc = directControl->AccessGuestProperty(aName, 3631 *aValue ? aValue : NULL, /** @todo Fix when adding DeleteGuestProperty(), see defect. */ 3632 aFlags, 3633 true /* isSetter */, 3634 &dummy, &dummy64, &dummy); 3625 3635 } 3626 3636 } … … 3666 3676 Utf8Str strPatterns(aPatterns); 3667 3677 3668 bool matchAll = false;3669 if ((NULL == aPatterns) || (0 == aPatterns[0]))3670 matchAll = true;3671 3678 if (!mHWData->mPropertyServiceActive) 3672 3679 { … … 3679 3686 it != mHWData->mGuestProperties.end(); 3680 3687 ++it) 3681 if ( matchAll3688 if ( strPatterns.isEmpty() 3682 3689 || RTStrSimplePatternMultiMatch(strPatterns.raw(), 3683 3690 RTSTR_MAX, … … 9208 9215 } 9209 9216 9210 STDMETHODIMP SessionMachine::PushGuestProperties(ComSafeArrayIn 9211 ComSafeArrayIn 9212 ComSafeArrayIn 9213 ComSafeArrayIn 9217 STDMETHODIMP SessionMachine::PushGuestProperties(ComSafeArrayIn(IN_BSTR, aNames), 9218 ComSafeArrayIn(IN_BSTR, aValues), 9219 ComSafeArrayIn(ULONG64, aTimestamps), 9220 ComSafeArrayIn(IN_BSTR, aFlags)) 9214 9221 { 9215 9222 LogFlowThisFunc(("\n")); … … 9218 9225 using namespace guestProp; 9219 9226 9220 AutoCaller autoCaller(this); 9221 AssertComRCReturn (autoCaller.rc(), autoCaller.rc()); 9227 AssertReturn(!ComSafeArrayInIsNull(aNames), E_POINTER); 9228 AssertReturn(!ComSafeArrayInIsNull(aValues), E_POINTER); 9229 AssertReturn(!ComSafeArrayInIsNull(aTimestamps), E_POINTER); 9230 AssertReturn(!ComSafeArrayInIsNull(aFlags), E_POINTER); 9231 9232 AutoCaller autoCaller(this); 9233 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 9222 9234 9223 9235 AutoWriteLock alock(this); 9224 9236 9225 /* Temporarily reset the registered flag, so that our machine state 9226 * changes (i.e. mHWData.backup()) succeed. (isMutable() used in 9227 * all setters will return FALSE for a Machine instance if mRegistered 9228 * is TRUE). This is copied from registeredInit(), and may or may not be 9229 * the right way to handle this. */ 9237 /* 9238 * Temporarily reset the registered flag, so that our machine state 9239 * changes (i.e. mHWData.backup()) succeed. (isMutable() used in all 9240 * setters will return FALSE for a Machine instance if mRegistered is TRUE). 9241 * 9242 * This is copied from registeredInit(), and may or may not be the right 9243 * way to handle this. 9244 */ 9245 Assert(!mData->mRegistered); 9230 9246 mData->mRegistered = FALSE; 9247 9231 9248 HRESULT rc = checkStateDependency(MutableStateDep); 9232 LogRel (("checkStateDependency(MutableStateDep) returned 0x%x\n", rc)); 9233 CheckComRCReturnRC(rc); 9234 9235 // ComAssertRet (mData->mMachineState < MachineState_Running, E_FAIL); 9236 9237 AssertReturn(!ComSafeArrayInIsNull (aNames), E_POINTER); 9238 AssertReturn(!ComSafeArrayInIsNull (aValues), E_POINTER); 9239 AssertReturn(!ComSafeArrayInIsNull (aTimestamps), E_POINTER); 9240 AssertReturn(!ComSafeArrayInIsNull (aFlags), E_POINTER); 9241 9242 com::SafeArray<IN_BSTR> names (ComSafeArrayInArg (aNames)); 9243 com::SafeArray<IN_BSTR> values (ComSafeArrayInArg (aValues)); 9244 com::SafeArray<ULONG64> timestamps (ComSafeArrayInArg (aTimestamps)); 9245 com::SafeArray<IN_BSTR> flags (ComSafeArrayInArg (aFlags)); 9249 AssertLogRelMsgReturn(SUCCEEDED(rc), ("%Rhrc\n", rc), rc); 9250 9251 com::SafeArray<IN_BSTR> names( ComSafeArrayInArg(aNames)); 9252 com::SafeArray<IN_BSTR> values( ComSafeArrayInArg(aValues)); 9253 com::SafeArray<ULONG64> timestamps(ComSafeArrayInArg(aTimestamps)); 9254 com::SafeArray<IN_BSTR> flags( ComSafeArrayInArg(aFlags)); 9255 9246 9256 DiscardSettings(); 9247 9257 mHWData.backup(); 9248 mHWData->mGuestProperties.erase (mHWData->mGuestProperties.begin(), 9258 9259 mHWData->mGuestProperties.erase(mHWData->mGuestProperties.begin(), 9249 9260 mHWData->mGuestProperties.end()); 9250 9261 for (unsigned i = 0; i < names.size(); ++i) 9251 9262 { 9252 9263 uint32_t fFlags = NILFLAG; 9253 validateFlags (Utf8Str(flags[i]).raw(), &fFlags);9264 validateFlags(Utf8Str(flags[i]).raw(), &fFlags); 9254 9265 HWData::GuestProperty property = { names[i], values[i], timestamps[i], fFlags }; 9255 mHWData->mGuestProperties.push_back (property); 9256 } 9266 mHWData->mGuestProperties.push_back(property); 9267 } 9268 9257 9269 mHWData->mPropertyServiceActive = false; 9270 9258 9271 alock.unlock(); 9259 9272 SaveSettings(); 9273 9260 9274 /* Restore the mRegistered flag. */ 9275 alock.lock(); 9261 9276 mData->mRegistered = TRUE; 9277 9262 9278 return S_OK; 9263 9279 #else … … 9276 9292 using namespace guestProp; 9277 9293 9278 CheckComArgNotNull 9279 if ( (aValue != NULL) && (!VALID_PTR (aValue) || !VALID_PTR(aFlags)))9294 CheckComArgNotNull(aName); 9295 if (aValue != NULL && (!VALID_PTR(aValue) || !VALID_PTR(aFlags))) 9280 9296 return E_POINTER; /* aValue can be NULL to indicate deletion */ 9281 9297 9282 9298 try 9283 9299 { 9300 /* 9301 * Convert input up front. 9302 */ 9303 Utf8Str utf8Name(aName); 9304 uint32_t fFlags = NILFLAG; 9305 if (aFlags) 9306 { 9307 Utf8Str utf8Flags(aFlags); 9308 int vrc = validateFlags(utf8Flags.raw(), &fFlags); 9309 AssertRCReturn(vrc, E_INVALIDARG); 9310 } 9311 9312 /* 9313 * Now grab the object lock and do the update 9314 */ 9284 9315 AutoCaller autoCaller(this); 9285 9316 CheckComRCReturnRC(autoCaller.rc()); … … 9287 9318 AutoWriteLock alock(this); 9288 9319 9320 AssertReturn(mHWData->mPropertyServiceActive, VBOX_E_INVALID_OBJECT_STATE); 9321 9289 9322 HRESULT rc = checkStateDependency(MutableStateDep); 9290 9323 CheckComRCReturnRC(rc); 9291 9324 9292 Utf8Str utf8Name(aName);9293 Utf8Str utf8Flags(aFlags);9294 Utf8Str utf8Patterns(mHWData->mGuestPropertyNotificationPatterns);9295 9296 uint32_t fFlags = NILFLAG;9297 if ((aFlags != NULL) && RT_FAILURE(validateFlags (utf8Flags.raw(), &fFlags)))9298 return E_INVALIDARG;9299 9300 bool matchAll = false;9301 if (utf8Patterns.isEmpty())9302 matchAll = true;9303 9304 9325 mHWData.backup(); 9326 9327 /** @todo r=bird: The careful memory handling doesn't work out here because 9328 * the catch block won't undo any damange we've done. So, if push_back throws 9329 * bad_alloc then you've lost the value. 9330 * 9331 * Another thing. Doing a linear search here isn't extremely efficient, esp. 9332 * since values that changes actually bubbles to the end of the list. Using 9333 * something that has an efficient lookup and can tollerate a bit of updates 9334 * would be nice. RTStrSpace is one suggestion (it's not perfect). Some 9335 * combination of RTStrCache (for sharing names and getting uniqueness into 9336 * the bargain) and hash/tree is another. */ 9305 9337 for (HWData::GuestPropertyList::iterator iter = mHWData->mGuestProperties.begin(); 9306 9338 iter != mHWData->mGuestProperties.end(); … … 9314 9346 { 9315 9347 HWData::GuestProperty property = { aName, aValue, aTimestamp, fFlags }; 9316 mHWData->mGuestProperties.push_back (property); 9317 } 9318 9319 /* send a callback notification if appropriate */ 9320 alock.leave(); 9321 if ( matchAll 9322 || RTStrSimplePatternMultiMatch(utf8Patterns.raw(), 9348 mHWData->mGuestProperties.push_back(property); 9349 } 9350 9351 /* 9352 * Send a callback notification if appropriate 9353 */ 9354 if ( mHWData->mGuestPropertyNotificationPatterns.isEmpty() 9355 || RTStrSimplePatternMultiMatch(mHWData->mGuestPropertyNotificationPatterns.raw(), 9323 9356 RTSTR_MAX, 9324 9357 utf8Name.raw(), … … 9326 9359 ) 9327 9360 { 9361 alock.leave(); 9362 9328 9363 mParent->onGuestPropertyChange(mData->mUuid, 9329 9364 aName, … … 9332 9367 } 9333 9368 } 9334 catch (std::bad_alloc &)9335 { 9336 return E_OUTOFMEMORY;9369 catch (...) 9370 { 9371 return VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 9337 9372 } 9338 9373 return S_OK; -
trunk/src/VBox/Main/include/MachineImpl.h
r24558 r24663 312 312 GuestPropertyList mGuestProperties; 313 313 BOOL mPropertyServiceActive; 314 BstrmGuestPropertyNotificationPatterns;314 Utf8Str mGuestPropertyNotificationPatterns; 315 315 316 316 FirmwareType_T mFirmwareType;
Note:
See TracChangeset
for help on using the changeset viewer.