sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "t_property.h" sl@0: sl@0: _LIT(KDefineName, "RProperty::Define() Basics"); sl@0: sl@0: CPropDefine::CPropDefine(TUid aCategory, TUint aKey, RProperty::TType aType) : sl@0: CTestProgram(KDefineName), iCategory(aCategory), iKey(aKey), iType(aType) sl@0: { sl@0: } sl@0: sl@0: void CPropDefine::Run(TUint aCount) sl@0: { sl@0: TUid mySid; sl@0: mySid.iUid = RProcess().SecureId(); sl@0: sl@0: for(TUint i = 0; i < aCount; ++i) sl@0: { sl@0: RProperty prop; sl@0: sl@0: // Defines the attributes and access control for a property. This can only be done sl@0: // once for each property. Subsequent attempts to define the same property will return sl@0: // KErrAlreadyExists. sl@0: TInt r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrAlreadyExists); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // Test defining properties in the default category (==our SID) sl@0: r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrAlreadyExists); sl@0: r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrAlreadyExists); sl@0: r = prop.Delete(mySid, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // Test re-definition doesn't change security settings sl@0: // Defect DEF050961 - Re-defining an RProperty causes the security policy to be overwritten sl@0: { sl@0: TInt expectedResult = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)?KErrPermissionDenied:KErrNone; sl@0: _LIT(KTestBytes,"abcd"); sl@0: r = prop.Define(iCategory, iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Attach(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: if (iType == RProperty::EInt) sl@0: r = prop.Set(1); sl@0: else sl@0: r = prop.Set(KTestBytes); sl@0: TF_ERROR(r, r == expectedResult); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrAlreadyExists); sl@0: if (iType == RProperty::EInt) sl@0: r = prop.Set(1); sl@0: else sl@0: r = prop.Set(KTestBytes); sl@0: TF_ERROR(r, r == expectedResult); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: prop.Close(); sl@0: } sl@0: sl@0: // Define fails with KErrArgument if wrong type or attribute was specified. sl@0: r = prop.Define(iCategory, iKey, RProperty::ETypeLimit, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: const TInt removed_KPersistent_attribute = 0x100; sl@0: r = prop.Define(iCategory, iKey, iType | removed_KPersistent_attribute, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: sl@0: TSecurityPolicy badPolicy; sl@0: *(TInt*)&badPolicy = -1; sl@0: r = prop.Define(iCategory, iKey, iType, badPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, badPolicy); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: // Define fails with KErrArgument if aType is TInt and aPreallocate is not 0 sl@0: r = prop.Define(iCategory, iKey, RProperty::EInt, KPassPolicy, KPassPolicy, 16); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: sl@0: // Following defintion the property has a default value, 0 for integer properties sl@0: r = prop.Define(iCategory, iKey, RProperty::EInt, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TInt value; sl@0: r = prop.Get(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(value, value == 0); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: else sl@0: { sl@0: // Defne fails with KErrTooBig if aPeallocate is grater than KMaxPropertySize. sl@0: r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize + 1); sl@0: TF_ERROR(r, r == KErrTooBig); sl@0: sl@0: // Following defintion the property has a default value, zero-length data for byte-array and text sl@0: // properties. sl@0: r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TBuf<16> buf; sl@0: r = prop.Get(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(buf.Size(), buf.Size() == 0); sl@0: sl@0: TBuf8<16> buf8; sl@0: r = prop.Get(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(buf8.Size(), buf8.Size() == 0); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: sl@0: // Pending subscriptions for this property will not be completed until a new value is published. sl@0: r = prop.Attach(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TRequestStatus status; sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNotFound); sl@0: prop.Close(); sl@0: } sl@0: } sl@0: sl@0: _LIT(KDeleteName, "RProperty::Delete() Basics"); sl@0: sl@0: CPropDelete::CPropDelete(TUid aCategory, TUint aKey, RProperty::TType aType) : sl@0: CTestProgram(KDeleteName), iCategory(aCategory), iKey(aKey), iType(aType) sl@0: { sl@0: } sl@0: sl@0: void CPropDelete::Run(TUint aCount) sl@0: { sl@0: TUid mySid; sl@0: mySid.iUid = RProcess().SecureId(); sl@0: for(TUint i = 0; i < aCount; ++i) sl@0: { sl@0: RProperty prop; sl@0: sl@0: // If the property has not been defined Delete fails with KErrNotFound. sl@0: TInt r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: sl@0: // Test deleting properties in the default category (==our SID) sl@0: //deleting of property in the default category (==our SID) should fail until the property is defined sl@0: r = prop.Delete(iKey); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: sl@0: r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete(iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete(mySid, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete( iKey); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: sl@0: r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete( iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Delete(mySid, iKey); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: sl@0: // Any pending subscriptions for this property will be completed with KErrNotFound. sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Attach(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TRequestStatus status; sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNotFound); sl@0: sl@0: // Any new request will not complete until the property is defined and published again. sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Set(1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Set(_L("Foo")); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNone); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: prop.Close(); sl@0: } sl@0: } sl@0: sl@0: _LIT(KPanicName, "RProperty Panics"); sl@0: sl@0: CPropPanic::CPropPanic(TUid aCategory, TUint aKey) : sl@0: CTestProgram(KPanicName), iCategory(aCategory), iKey(aKey) sl@0: { sl@0: } sl@0: sl@0: TInt CPropPanic::DoubleSubscribeThreadEntry(TAny* ptr) sl@0: { sl@0: CPropPanic* prog = (CPropPanic*) ptr; sl@0: RProperty prop; sl@0: TInt r = prop.Attach(prog->iCategory, prog->iKey, EOwnerThread); sl@0: TF_ERROR_PROG(prog, r, r == KErrNone); sl@0: TRequestStatus status; sl@0: prop.Subscribe(status); sl@0: // Next statement shall Panic. sl@0: prop.Subscribe(status); sl@0: // Never get here sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleSubscribeThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: TRequestStatus status; sl@0: prop.Subscribe(status); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleCancelThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: prop.Cancel(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleGetIThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: TInt i; sl@0: prop.Get(i); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleGetBThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: TBuf<64> buf; sl@0: prop.Get(buf); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleSetIThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: TInt i = 1; sl@0: prop.Set(i); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CPropPanic::BadHandleSetBThreadEntry(TAny* /*ptr*/) sl@0: { sl@0: RProperty prop; sl@0: TBuf<64> buf; sl@0: prop.Set(buf); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TThreadFunction CPropPanic::BadHandles[] = { sl@0: CPropPanic::BadHandleSubscribeThreadEntry, sl@0: CPropPanic::BadHandleCancelThreadEntry, sl@0: CPropPanic::BadHandleGetIThreadEntry, sl@0: CPropPanic::BadHandleGetBThreadEntry, sl@0: CPropPanic::BadHandleSetIThreadEntry, sl@0: CPropPanic::BadHandleSetBThreadEntry, sl@0: NULL sl@0: }; sl@0: sl@0: void CPropPanic::Run(TUint /* aCount */) sl@0: { sl@0: // Only one subscriptoin per RProperty object is allowed, the caller will be paniced if sl@0: // there is already a subscription on this object. sl@0: TRequestStatus status; sl@0: TExitType exit; sl@0: RThread thr; sl@0: TInt r = thr.Create(KNullDesC, DoubleSubscribeThreadEntry, 0x2000, NULL, this); sl@0: TF_ERROR(r, r == KErrNone); sl@0: thr.Logon(status); sl@0: sl@0: TBool jit = User::JustInTime(); sl@0: User::SetJustInTime(EFalse); sl@0: sl@0: thr.Resume(); sl@0: User::WaitForRequest(status); sl@0: thr.Close(); sl@0: sl@0: User::SetJustInTime(jit); sl@0: sl@0: TF_ERROR(status.Int(), status.Int() == ERequestAlreadyPending); sl@0: sl@0: for (TInt i = 0; BadHandles[i]; ++i) sl@0: { sl@0: r = thr.Create(KNullDesC, BadHandles[i], 0x2000, NULL, this); sl@0: TF_ERROR(r, r == KErrNone); sl@0: thr.Logon(status); sl@0: sl@0: jit = User::JustInTime(); sl@0: User::SetJustInTime(EFalse); sl@0: sl@0: thr.Resume(); sl@0: User::WaitForRequest(status); sl@0: exit = thr.ExitType(); sl@0: thr.Close(); sl@0: sl@0: User::SetJustInTime(jit); sl@0: sl@0: TF_ERROR(status.Int(), status.Int() == EBadHandle); sl@0: TF_ERROR(exit, exit == EExitPanic); sl@0: } sl@0: } sl@0: sl@0: _LIT(KSetGetName, "RProperty::Set()/Get() Basics"); sl@0: sl@0: CPropSetGet::CPropSetGet(TUid aCategory, TUint aKey, RProperty::TType aType) : sl@0: CTestProgram(KSetGetName), iCategory(aCategory), iKey(aKey), iType(aType) sl@0: { sl@0: } sl@0: sl@0: void CPropSetGet::Run(TUint aCount) sl@0: { sl@0: for(TUint i = 0; i < aCount; ++i) sl@0: { sl@0: TInt r; sl@0: RProperty prop; sl@0: sl@0: r = prop.Attach(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // If the property has not been defined this fails with KErrNotFound. sl@0: { sl@0: TInt value; sl@0: TBuf<16> buf; sl@0: TBuf8<16> buf8; sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Get(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Get(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Get(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: } sl@0: sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Get(value); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(value); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Get(buf); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(buf); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Get(buf8); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: r = prop.Set(buf8); sl@0: TF_ERROR(r, r == KErrNotFound); sl@0: } sl@0: } sl@0: sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // Can set property to zero length sl@0: { sl@0: if (iType == RProperty::EByteArray) sl@0: { sl@0: TBuf8<20> buf8(20); sl@0: r = prop.Set(iCategory, iKey, KNullDesC8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(buf8.Length(), buf8.Length() == 0); sl@0: } sl@0: } sl@0: sl@0: // If the property is larger than KMaxPropertySize this fails with KErrTooBig sl@0: { sl@0: if (iType == RProperty::EByteArray) sl@0: { sl@0: TBuf buf(RProperty::KMaxPropertySize/2 + 1); sl@0: TBuf8 buf8(RProperty::KMaxPropertySize + 1); sl@0: r = prop.Set(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrTooBig); sl@0: r = prop.Set(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrTooBig); sl@0: r = prop.Set(buf); sl@0: TF_ERROR(r, r == KErrTooBig); sl@0: r = prop.Set(buf8); sl@0: TF_ERROR(r, r == KErrTooBig); sl@0: } sl@0: } sl@0: sl@0: // When type of operation mismatch with the property type this fails with KErrArgument. sl@0: { sl@0: TInt value; sl@0: TBuf<16> buf; sl@0: TBuf8<16> buf8; sl@0: if (iType != RProperty::EInt) sl@0: { sl@0: r = prop.Get(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Get(value); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(value); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Get(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(iCategory, iKey, buf); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Get(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(iCategory, iKey, buf8); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Get(buf); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(buf); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Get(buf8); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: r = prop.Set(buf8); sl@0: TF_ERROR(r, r == KErrArgument); sl@0: } sl@0: } sl@0: sl@0: // Get/Set sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: { sl@0: r = prop.Set(1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TInt value = 0; sl@0: r = prop.Get(value); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(value, value == 1); sl@0: } sl@0: { sl@0: TInt value = 0; sl@0: r = prop.Set(iCategory, iKey, 1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, value); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(value, value == 1); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: { sl@0: TBuf<16> ibuf(_L("Foo")); sl@0: TBuf<16> obuf; sl@0: r = prop.Set(ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(obuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = obuf.Compare(ibuf); sl@0: TF_ERROR(r, r == 0); sl@0: } sl@0: { sl@0: TBuf8<16> ibuf8((TUint8*)"Foo"); sl@0: TBuf8<16> obuf8; sl@0: r = prop.Set(ibuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(obuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = obuf8.Compare(ibuf8); sl@0: TF_ERROR(r, r == 0); sl@0: } sl@0: { sl@0: TBuf<16> ibuf(_L("Foo")); sl@0: TBuf<16> obuf; sl@0: r = prop.Set(iCategory, iKey, ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, obuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = obuf.Compare(ibuf); sl@0: TF_ERROR(r, r == 0); sl@0: } sl@0: { sl@0: TBuf8<16> ibuf8((TUint8*)"Foo"); sl@0: TBuf8<16> obuf8; sl@0: r = prop.Set(iCategory, iKey, ibuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, obuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = obuf8.Compare(ibuf8); sl@0: TF_ERROR(r, r == 0); sl@0: } sl@0: } sl@0: sl@0: // If the supplied buffer is too small this fails with KErrOverflow and the truncated value is reported. sl@0: if (iType == RProperty::EByteArray) sl@0: { sl@0: { sl@0: TBuf<16> ibuf(_L("0123456789012345")); sl@0: TBuf<16> obuf(_L("abcdefghigklmnop")); sl@0: TPtr optr((TUint16*) obuf.Ptr(), 0, 15); sl@0: r = prop.Set(iCategory, iKey, ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, optr); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(optr.Length(), optr.Length() == 15); sl@0: TF_ERROR(obuf[14], obuf[14] == TText('4')); sl@0: TF_ERROR(obuf[15], obuf[15] == TText('p')); sl@0: } sl@0: { sl@0: TBuf8<16> ibuf8((TUint8*) "0123456789012345"); sl@0: TBuf8<16> obuf8((TUint8*) "abcdefghigklmnop"); sl@0: TPtr8 optr8((TUint8*) obuf8.Ptr(), 0, 15); sl@0: r = prop.Set(iCategory, iKey, ibuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(iCategory, iKey, optr8); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(optr8.Length(), optr8.Length() == 15); sl@0: TF_ERROR(obuf8[14], obuf8[14] == '4'); sl@0: TF_ERROR(obuf8[15], obuf8[15] == 'p'); sl@0: } sl@0: { sl@0: TBuf<16> ibuf(_L("0123456789012345")); sl@0: TBuf<16> obuf(_L("abcdefghigklmnop")); sl@0: TPtr optr((TUint16*) obuf.Ptr(), 0, 15); sl@0: r = prop.Set(ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(optr); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(optr.Length(), optr.Length() == 15); sl@0: TF_ERROR(obuf[14], obuf[14] == TText('4')); sl@0: TF_ERROR(obuf[15], obuf[15] == TText('p')); sl@0: } sl@0: { sl@0: TBuf8<16> ibuf8((TUint8*) "0123456789012345"); sl@0: TBuf8<16> obuf8((TUint8*) "abcdefghigklmnop"); sl@0: TPtr8 optr8((TUint8*) obuf8.Ptr(), 0, 15); sl@0: r = prop.Set(ibuf8); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(optr8); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(optr8.Length(), optr8.Length() == 15); sl@0: TF_ERROR(obuf8[14], obuf8[14] == '4'); sl@0: TF_ERROR(obuf8[15], obuf8[15] == 'p'); sl@0: } sl@0: } sl@0: sl@0: // Get/Set zero-length data sl@0: if (iType == RProperty::EByteArray) sl@0: { sl@0: { sl@0: TBuf<16> ibuf(_L("Foo")); sl@0: TBuf<16> obuf; sl@0: TPtr nullbuf(NULL, 0); sl@0: sl@0: r = prop.Set(ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(nullbuf); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(nullbuf.Length(), (nullbuf.Length() == 0)); sl@0: sl@0: r = prop.Set(nullbuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(obuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(obuf.Length(), (obuf.Length() == 0)); sl@0: } sl@0: { sl@0: TBuf8<16> ibuf((TUint8*) "Foo"); sl@0: TBuf8<16> obuf; sl@0: TPtr8 nullbuf(NULL, 0); sl@0: sl@0: r = prop.Set(ibuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(nullbuf); sl@0: TF_ERROR(r, r == KErrOverflow); sl@0: TF_ERROR(nullbuf.Length(), (nullbuf.Length() == 0)); sl@0: sl@0: r = prop.Set(nullbuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = prop.Get(obuf); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(obuf.Length(), (obuf.Length() == 0)); sl@0: } sl@0: } sl@0: sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: prop.Close(); sl@0: } sl@0: } sl@0: sl@0: sl@0: _LIT(KSubsCancelName, "RProperty::Subscribe()/Cancel() Basics"); sl@0: sl@0: CPropSubsCancel::CPropSubsCancel(TUid aCategory, TUint aKey, RProperty::TType aType) : sl@0: CTestProgram(KSubsCancelName), iCategory(aCategory), iKey(aKey), iType(aType) sl@0: { sl@0: } sl@0: sl@0: sl@0: void CPropSubsCancel::Run(TUint aCount) sl@0: { sl@0: sl@0: for(TUint i = 0; i < aCount; ++i) sl@0: { sl@0: TRequestStatus status; sl@0: RProperty prop; sl@0: sl@0: TInt r = prop.Attach(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // The calling thread will have the specified request status signalled when the property is next updated. sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Set(1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Set(_L("Foo")); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNone); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // If the property has not been defined, the request will not complete until the property sl@0: // is defined and published. sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Set(1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Set(_L("Foo")); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNone); sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: // Cancel an outstanding subscription request for this property handle. sl@0: // If it has not already completed, the request is completed with KErrCancelled. sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: prop.Cancel(); sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrCancel); sl@0: sl@0: r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: if (iType == RProperty::EInt) sl@0: { sl@0: r = prop.Set(1); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: else sl@0: { sl@0: r = prop.Set(_L("Foo")); sl@0: TF_ERROR(r, r == KErrNone); sl@0: } sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNone); sl@0: prop.Cancel(); sl@0: TF_ERROR(status.Int(), status.Int() == KErrNone); sl@0: sl@0: prop.Subscribe(status); sl@0: TF_ERROR(status.Int(), status.Int() == KRequestPending); sl@0: prop.Cancel(); sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), status.Int() == KErrCancel); sl@0: sl@0: r = prop.Delete(iCategory, iKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: prop.Close(); sl@0: } sl@0: } sl@0: sl@0: _LIT(KSecurityName, "RProperty Security Basics (Master)"); sl@0: sl@0: CPropSecurity::CPropSecurity(TUid aCategory, TUint aMasterKey, RProperty::TType aType, TUint aSlaveKeySlot) : sl@0: CTestProgram(KSecurityName), iCategory(aCategory), iMasterKey(aMasterKey), sl@0: iSlaveKeySlot(aSlaveKeySlot), iType(aType) sl@0: { sl@0: } sl@0: sl@0: _LIT(KSecuritySlavePath, "t_prop_sec.exe"); sl@0: sl@0: void CPropSecurity::Run(TUint aCount) sl@0: { sl@0: for(TInt i=0; i