os/kernelhwsrv/kerneltest/e32test/property/t_basic.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <e32kpan.h>
    17 #include "t_property.h"
    18 
    19 _LIT(KDefineName, "RProperty::Define() Basics");
    20  
    21 CPropDefine::CPropDefine(TUid aCategory, TUint aKey, RProperty::TType aType) : 
    22 	  CTestProgram(KDefineName), iCategory(aCategory), iKey(aKey), iType(aType)
    23 	{
    24 	}
    25 
    26 void CPropDefine::Run(TUint aCount)
    27 	{
    28 	TUid mySid;
    29 	mySid.iUid = RProcess().SecureId();
    30 
    31 	for(TUint i = 0; i < aCount; ++i)
    32 		{
    33 		RProperty prop;
    34 
    35 		//	Defines the attributes and access control for a property. This can only be done 
    36 		//	once for each property. Subsequent attempts to define the same property will return
    37 		//	KErrAlreadyExists.
    38 		TInt r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
    39 		TF_ERROR(r, r == KErrNone);
    40 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
    41 		TF_ERROR(r, r == KErrAlreadyExists);
    42 		r = prop.Delete(iCategory, iKey);
    43 		TF_ERROR(r, r == KErrNone);
    44 
    45 		// Test defining properties in the default category (==our SID)
    46 		r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy);
    47 		TF_ERROR(r, r == KErrNone);
    48 		r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy);
    49 		TF_ERROR(r, r == KErrAlreadyExists);
    50 		r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy);
    51 		TF_ERROR(r, r == KErrAlreadyExists);
    52 		r = prop.Delete(mySid, iKey);
    53 		TF_ERROR(r, r == KErrNone);
    54 
    55 		// Test re-definition doesn't change security settings
    56 		// Defect DEF050961 - Re-defining an RProperty causes the security policy to be overwritten
    57 		{
    58 		TInt expectedResult = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)?KErrPermissionDenied:KErrNone;
    59 		_LIT(KTestBytes,"abcd");
    60 		r = prop.Define(iCategory, iKey, iType, KFailPolicy, KFailPolicy);
    61 		TF_ERROR(r, r == KErrNone);
    62 		r = prop.Attach(iCategory, iKey);
    63 		TF_ERROR(r, r == KErrNone);
    64 		if (iType == RProperty::EInt)
    65 			r = prop.Set(1);
    66 		else
    67 			r = prop.Set(KTestBytes);
    68 		TF_ERROR(r, r == expectedResult);
    69 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
    70 		TF_ERROR(r, r == KErrAlreadyExists);
    71 		if (iType == RProperty::EInt)
    72 			r = prop.Set(1);
    73 		else
    74 			r = prop.Set(KTestBytes);
    75 		TF_ERROR(r, r == expectedResult);
    76 		r = prop.Delete(iCategory, iKey);
    77 		TF_ERROR(r, r == KErrNone);
    78 		prop.Close();
    79 		}
    80 
    81 		// Define fails with KErrArgument if wrong type or attribute was specified.
    82 		r = prop.Define(iCategory, iKey, RProperty::ETypeLimit, KPassPolicy, KPassPolicy);
    83 		TF_ERROR(r, r == KErrArgument);
    84 		const TInt removed_KPersistent_attribute = 0x100;
    85 		r  = prop.Define(iCategory, iKey, iType | removed_KPersistent_attribute, KPassPolicy, KPassPolicy);
    86 		TF_ERROR(r, r == KErrArgument);
    87 
    88 		TSecurityPolicy badPolicy;
    89 		*(TInt*)&badPolicy = -1;
    90 		r = prop.Define(iCategory, iKey, iType, badPolicy, KPassPolicy);
    91 		TF_ERROR(r, r == KErrArgument);
    92 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, badPolicy);
    93 		TF_ERROR(r, r == KErrArgument);
    94 
    95 		if (iType == RProperty::EInt)
    96 			{
    97 			// Define fails with KErrArgument if aType is TInt and aPreallocate is not 0
    98 			r = prop.Define(iCategory, iKey, RProperty::EInt, KPassPolicy, KPassPolicy, 16);
    99 			TF_ERROR(r, r == KErrArgument);
   100 
   101 			// Following defintion the property has a default value, 0 for integer properties
   102 			r = prop.Define(iCategory, iKey, RProperty::EInt, KPassPolicy, KPassPolicy);
   103 			TF_ERROR(r, r == KErrNone);
   104 			TInt value;
   105 			r = prop.Get(iCategory, iKey, value);
   106 			TF_ERROR(r, r == KErrNone);
   107 			TF_ERROR(value, value == 0);
   108 			r = prop.Delete(iCategory, iKey);
   109 			TF_ERROR(r, r == KErrNone);
   110 			}
   111 		else 
   112 			{
   113 			// Defne fails with KErrTooBig if aPeallocate is grater than KMaxPropertySize.
   114 			r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize);
   115 			TF_ERROR(r, r == KErrNone);
   116 			r = prop.Delete(iCategory, iKey);
   117 			TF_ERROR(r, r == KErrNone);
   118 			r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize + 1);
   119 			TF_ERROR(r, r == KErrTooBig);
   120 
   121 			// Following defintion the property has a default value, zero-length data for byte-array and text 
   122 			// properties. 
   123 			r = prop.Define(iCategory, iKey, RProperty::EByteArray, KPassPolicy, KPassPolicy);
   124 			TF_ERROR(r, r == KErrNone);
   125 			TBuf<16> buf;
   126 			r = prop.Get(iCategory, iKey, buf);
   127 			TF_ERROR(r, r == KErrNone);
   128 			TF_ERROR(buf.Size(), buf.Size() == 0);
   129 
   130 			TBuf8<16> buf8;
   131 			r = prop.Get(iCategory, iKey, buf8);
   132 			TF_ERROR(r, r == KErrNone);
   133 			TF_ERROR(buf8.Size(), buf8.Size() == 0);
   134 			r = prop.Delete(iCategory, iKey);
   135 			TF_ERROR(r, r == KErrNone);
   136 			}
   137 
   138 		// Pending subscriptions for this property will not be completed until a new value is published.
   139 		r = prop.Attach(iCategory, iKey);
   140 		TF_ERROR(r, r == KErrNone);
   141 		TRequestStatus status;
   142 		prop.Subscribe(status);
   143 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   144 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   145 		TF_ERROR(r, r == KErrNone);
   146 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   147 		r = prop.Delete(iCategory, iKey);
   148 		TF_ERROR(r, r == KErrNone);
   149 		User::WaitForRequest(status);
   150 		TF_ERROR(status.Int(), status.Int() == KErrNotFound);
   151 		prop.Close();
   152 		}
   153 	}
   154 
   155 _LIT(KDeleteName, "RProperty::Delete() Basics");
   156  
   157 CPropDelete::CPropDelete(TUid aCategory, TUint aKey, RProperty::TType aType) : 
   158 	  CTestProgram(KDeleteName), iCategory(aCategory), iKey(aKey), iType(aType)
   159 	{
   160 	}
   161 
   162 void CPropDelete::Run(TUint aCount)
   163 	{
   164 	TUid mySid;
   165 	mySid.iUid = RProcess().SecureId();
   166 	for(TUint i = 0; i < aCount; ++i)
   167 		{
   168 		RProperty prop;
   169 
   170 		// If the property has not been defined Delete fails with KErrNotFound.
   171 		TInt r = prop.Delete(iCategory, iKey);
   172 		TF_ERROR(r, r == KErrNotFound);
   173 	
   174 		// Test deleting properties in the default category (==our SID)
   175 		//deleting of property in the default category (==our SID) should fail until the property is defined
   176 		r = prop.Delete(iKey);
   177 		TF_ERROR(r, r == KErrNotFound);
   178 		
   179 		r = prop.Define(iKey, iType, KFailPolicy, KFailPolicy);
   180 		TF_ERROR(r, r == KErrNone);
   181 		r = prop.Delete(iKey);
   182 		TF_ERROR(r, r == KErrNone);
   183 				
   184 		r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy);
   185 		TF_ERROR(r, r == KErrNone);
   186 		r = prop.Delete(mySid, iKey);
   187 		TF_ERROR(r, r == KErrNone);
   188 		r = prop.Delete( iKey);
   189 		TF_ERROR(r, r == KErrNotFound);
   190 		
   191 		r = prop.Define(mySid, iKey, iType, KFailPolicy, KFailPolicy);
   192 		TF_ERROR(r, r == KErrNone);
   193 		r = prop.Delete( iKey);
   194 		TF_ERROR(r, r == KErrNone);
   195 		r = prop.Delete(mySid, iKey);
   196 		TF_ERROR(r, r == KErrNotFound);
   197 	
   198 		// Any pending subscriptions for this property will be completed with KErrNotFound.
   199 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   200 		TF_ERROR(r, r == KErrNone);
   201 		r = prop.Attach(iCategory, iKey);
   202 		TF_ERROR(r, r == KErrNone);
   203 		TRequestStatus status;
   204 		prop.Subscribe(status);
   205 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   206 		r = prop.Delete(iCategory, iKey);
   207 		TF_ERROR(r, r == KErrNone);
   208 		User::WaitForRequest(status);
   209 		TF_ERROR(status.Int(), status.Int() == KErrNotFound);
   210 
   211 		// Any new request will not complete until the property is defined and published again.
   212 		prop.Subscribe(status);
   213 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   214 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   215 		TF_ERROR(r, r == KErrNone);
   216 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   217 		if (iType == RProperty::EInt)
   218 			{
   219 			r = prop.Set(1);
   220 			TF_ERROR(r, r == KErrNone);
   221 			}
   222 		else
   223 			{
   224 			r = prop.Set(_L("Foo"));
   225 			TF_ERROR(r, r == KErrNone);
   226 			}
   227 		User::WaitForRequest(status);
   228 		TF_ERROR(status.Int(), status.Int() == KErrNone);
   229 		r = prop.Delete(iCategory, iKey);
   230 		TF_ERROR(r, r == KErrNone);
   231 		prop.Close();
   232 		}
   233 	}
   234 
   235 _LIT(KPanicName, "RProperty Panics");
   236 
   237 CPropPanic::CPropPanic(TUid aCategory, TUint aKey) : 
   238 	  CTestProgram(KPanicName), iCategory(aCategory), iKey(aKey)
   239 	{
   240 	}
   241 
   242 TInt CPropPanic::DoubleSubscribeThreadEntry(TAny* ptr)
   243 	{
   244 	CPropPanic* prog = (CPropPanic*) ptr;
   245 	RProperty prop;
   246 	TInt r = prop.Attach(prog->iCategory, prog->iKey, EOwnerThread);
   247 	TF_ERROR_PROG(prog, r, r == KErrNone);
   248 	TRequestStatus status;
   249 	prop.Subscribe(status);
   250 	// Next statement shall Panic.	
   251 	prop.Subscribe(status);
   252 	// Never get here
   253 	return KErrNone;
   254 	}
   255 
   256 TInt CPropPanic::BadHandleSubscribeThreadEntry(TAny* /*ptr*/)
   257 	{
   258 	RProperty prop;
   259 	TRequestStatus status;
   260 	prop.Subscribe(status);
   261 	return KErrNone;
   262 	}
   263 
   264 TInt CPropPanic::BadHandleCancelThreadEntry(TAny* /*ptr*/)
   265 	{
   266 	RProperty prop;
   267 	prop.Cancel();
   268 	return KErrNone;
   269 	}
   270 
   271 TInt CPropPanic::BadHandleGetIThreadEntry(TAny* /*ptr*/)
   272 	{
   273 	RProperty prop;
   274 	TInt i;
   275 	prop.Get(i);
   276 	return KErrNone;
   277 	}
   278 
   279 TInt CPropPanic::BadHandleGetBThreadEntry(TAny* /*ptr*/)
   280 	{
   281 	RProperty prop;
   282 	TBuf<64> buf;
   283 	prop.Get(buf);
   284 	return KErrNone;
   285 	}
   286 
   287 TInt CPropPanic::BadHandleSetIThreadEntry(TAny* /*ptr*/)
   288 	{
   289 	RProperty prop;
   290 	TInt i = 1;
   291 	prop.Set(i);
   292 	return KErrNone;
   293 	}
   294 
   295 TInt CPropPanic::BadHandleSetBThreadEntry(TAny* /*ptr*/)
   296 	{
   297 	RProperty prop;
   298 	TBuf<64> buf;
   299 	prop.Set(buf);
   300 	return KErrNone;
   301 	}
   302 
   303 TThreadFunction CPropPanic::BadHandles[] = {
   304 	CPropPanic::BadHandleSubscribeThreadEntry,
   305 	CPropPanic::BadHandleCancelThreadEntry,
   306 	CPropPanic::BadHandleGetIThreadEntry,
   307 	CPropPanic::BadHandleGetBThreadEntry,
   308 	CPropPanic::BadHandleSetIThreadEntry,
   309 	CPropPanic::BadHandleSetBThreadEntry,
   310 	NULL
   311 };
   312 
   313 void CPropPanic::Run(TUint /* aCount */)
   314 	{
   315 	// Only one subscriptoin per RProperty object is allowed, the caller will be paniced if
   316 	// there is already a subscription on this object.
   317 	TRequestStatus status;
   318 	TExitType exit;
   319 	RThread thr;
   320 	TInt r = thr.Create(KNullDesC, DoubleSubscribeThreadEntry, 0x2000, NULL, this);
   321 	TF_ERROR(r, r == KErrNone);
   322 	thr.Logon(status);
   323 
   324 	TBool jit = User::JustInTime();
   325 	User::SetJustInTime(EFalse);
   326 
   327 	thr.Resume();
   328 	User::WaitForRequest(status);
   329 	thr.Close();
   330 
   331 	User::SetJustInTime(jit);
   332 
   333 	TF_ERROR(status.Int(), status.Int() == ERequestAlreadyPending);	
   334 
   335 	for (TInt i = 0; BadHandles[i]; ++i)
   336 		{
   337 		r = thr.Create(KNullDesC, BadHandles[i], 0x2000, NULL, this);
   338 		TF_ERROR(r, r == KErrNone);
   339 		thr.Logon(status);
   340 
   341 		jit = User::JustInTime();
   342 		User::SetJustInTime(EFalse);
   343 
   344 		thr.Resume();
   345 		User::WaitForRequest(status);
   346 		exit = thr.ExitType();
   347 		thr.Close();
   348 
   349 		User::SetJustInTime(jit);
   350 
   351 		TF_ERROR(status.Int(), status.Int() == EBadHandle);	
   352 		TF_ERROR(exit, exit == EExitPanic);
   353 		}
   354 	}
   355 
   356 _LIT(KSetGetName, "RProperty::Set()/Get() Basics");
   357 
   358 CPropSetGet::CPropSetGet(TUid aCategory, TUint aKey, RProperty::TType aType) : 
   359 	  CTestProgram(KSetGetName), iCategory(aCategory), iKey(aKey), iType(aType)
   360 	{
   361 	}
   362 
   363 void CPropSetGet::Run(TUint aCount)
   364 	{
   365 	for(TUint i = 0; i < aCount; ++i)
   366 		{
   367 		TInt r;
   368 		RProperty prop;
   369 
   370 		r = prop.Attach(iCategory, iKey);
   371 		TF_ERROR(r, r == KErrNone);
   372 
   373 		// If the property has not been defined this fails with KErrNotFound.
   374 			{
   375 			TInt value;
   376 			TBuf<16> buf;
   377 			TBuf8<16> buf8;
   378 			if (iType == RProperty::EInt)
   379 				{
   380 				r = prop.Get(iCategory, iKey, value);
   381 				TF_ERROR(r, r == KErrNotFound);
   382 				r = prop.Set(iCategory, iKey, value);
   383 				TF_ERROR(r, r == KErrNotFound);
   384 				}
   385 			else
   386 				{
   387 				r = prop.Get(iCategory, iKey, buf);
   388 				TF_ERROR(r, r == KErrNotFound);
   389 				r = prop.Set(iCategory, iKey, buf);
   390 				TF_ERROR(r, r == KErrNotFound);
   391 				r = prop.Get(iCategory, iKey, buf8);
   392 				TF_ERROR(r, r == KErrNotFound);
   393 				r = prop.Set(iCategory, iKey, buf8);
   394 				TF_ERROR(r, r == KErrNotFound);
   395 				}
   396 
   397 			if (iType == RProperty::EInt)
   398 				{
   399 				r = prop.Get(value);
   400 				TF_ERROR(r, r == KErrNotFound);
   401 				r = prop.Set(value);
   402 				TF_ERROR(r, r == KErrNotFound);
   403 				}
   404 			else
   405 				{
   406 				r = prop.Get(buf);
   407 				TF_ERROR(r, r == KErrNotFound);
   408 				r = prop.Set(buf);
   409 				TF_ERROR(r, r == KErrNotFound);
   410 				r = prop.Get(buf8);
   411 				TF_ERROR(r, r == KErrNotFound);
   412 				r = prop.Set(buf8);
   413 				TF_ERROR(r, r == KErrNotFound);
   414 				}
   415 			}
   416 
   417 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   418 		TF_ERROR(r, r == KErrNone);
   419 
   420 		// Can set property to zero length
   421 			{
   422 			if (iType ==  RProperty::EByteArray)
   423 				{
   424 				TBuf8<20> buf8(20);
   425 				r = prop.Set(iCategory, iKey, KNullDesC8);
   426 				TF_ERROR(r, r == KErrNone);
   427 				r = prop.Get(iCategory, iKey, buf8);
   428 				TF_ERROR(r, r == KErrNone);
   429 				TF_ERROR(buf8.Length(), buf8.Length() == 0);
   430 				}
   431 			}
   432 
   433 		// If the property is larger than KMaxPropertySize this fails with KErrTooBig
   434 			{
   435 			if (iType ==  RProperty::EByteArray)
   436 				{
   437 				TBuf<RProperty::KMaxPropertySize/2 + 1> buf(RProperty::KMaxPropertySize/2 + 1);
   438 				TBuf8<RProperty::KMaxPropertySize + 1> buf8(RProperty::KMaxPropertySize + 1);
   439 				r = prop.Set(iCategory, iKey, buf);
   440 				TF_ERROR(r, r == KErrTooBig);
   441 				r = prop.Set(iCategory, iKey, buf8);
   442 				TF_ERROR(r, r == KErrTooBig);
   443 				r = prop.Set(buf);
   444 				TF_ERROR(r, r == KErrTooBig);
   445 				r = prop.Set(buf8);
   446 				TF_ERROR(r, r == KErrTooBig);
   447 				}
   448 			}
   449 
   450 		// When type of operation mismatch with the property type this fails with KErrArgument.
   451 			{
   452 			TInt value;
   453 			TBuf<16> buf;
   454 			TBuf8<16> buf8;
   455 			if (iType !=  RProperty::EInt)
   456 				{
   457 				r = prop.Get(iCategory, iKey, value);
   458 				TF_ERROR(r, r == KErrArgument);
   459 				r = prop.Set(iCategory, iKey, value);
   460 				TF_ERROR(r, r == KErrArgument);
   461 				r = prop.Get(value);
   462 				TF_ERROR(r, r == KErrArgument);
   463 				r = prop.Set(value);
   464 				TF_ERROR(r, r == KErrArgument);
   465 				}
   466 			else
   467 				{
   468 				r = prop.Get(iCategory, iKey, buf);
   469 				TF_ERROR(r, r == KErrArgument);
   470 				r = prop.Set(iCategory, iKey, buf);
   471 				TF_ERROR(r, r == KErrArgument);
   472 				r = prop.Get(iCategory, iKey, buf8);
   473 				TF_ERROR(r, r == KErrArgument);
   474 				r = prop.Set(iCategory, iKey, buf8);
   475 				TF_ERROR(r, r == KErrArgument);
   476 				r = prop.Get(buf);
   477 				TF_ERROR(r, r == KErrArgument);
   478 				r = prop.Set(buf);
   479 				TF_ERROR(r, r == KErrArgument);
   480 				r = prop.Get(buf8);
   481 				TF_ERROR(r, r == KErrArgument);
   482 				r = prop.Set(buf8);
   483 				TF_ERROR(r, r == KErrArgument);
   484 				}
   485 			}
   486 
   487 		// Get/Set
   488 		if (iType == RProperty::EInt)
   489 			{
   490 				{
   491 				r = prop.Set(1);
   492 				TF_ERROR(r, r == KErrNone);
   493 				TInt value = 0;
   494 				r = prop.Get(value);
   495 				TF_ERROR(r, r == KErrNone);
   496 				TF_ERROR(value, value == 1);
   497 				}
   498 				{
   499 				TInt value = 0;
   500 				r = prop.Set(iCategory, iKey, 1);
   501 				TF_ERROR(r, r == KErrNone);
   502 				r = prop.Get(iCategory, iKey, value);
   503 				TF_ERROR(r, r == KErrNone);
   504 				TF_ERROR(value, value == 1);
   505 				}
   506 			}
   507 		else 
   508 			{
   509 				{
   510 				TBuf<16> ibuf(_L("Foo"));
   511 				TBuf<16> obuf;
   512 				r = prop.Set(ibuf);
   513 				TF_ERROR(r, r == KErrNone);
   514 				r = prop.Get(obuf);
   515 				TF_ERROR(r, r == KErrNone);
   516 				r = obuf.Compare(ibuf);
   517 				TF_ERROR(r, r == 0);
   518 				}
   519 				{
   520 				TBuf8<16> ibuf8((TUint8*)"Foo");
   521 				TBuf8<16> obuf8;
   522 				r = prop.Set(ibuf8);
   523 				TF_ERROR(r, r == KErrNone);
   524 				r = prop.Get(obuf8);
   525 				TF_ERROR(r, r == KErrNone);
   526 				r = obuf8.Compare(ibuf8);
   527 				TF_ERROR(r, r == 0);
   528 				}
   529 				{
   530 				TBuf<16> ibuf(_L("Foo"));
   531 				TBuf<16> obuf;
   532 				r = prop.Set(iCategory, iKey, ibuf);
   533 				TF_ERROR(r, r == KErrNone);
   534 				r = prop.Get(iCategory, iKey, obuf);
   535 				TF_ERROR(r, r == KErrNone);
   536 				r = obuf.Compare(ibuf);
   537 				TF_ERROR(r, r == 0);
   538 				}
   539 				{
   540 				TBuf8<16> ibuf8((TUint8*)"Foo");
   541 				TBuf8<16> obuf8;
   542 				r = prop.Set(iCategory, iKey, ibuf8);
   543 				TF_ERROR(r, r == KErrNone);
   544 				r = prop.Get(iCategory, iKey, obuf8);
   545 				TF_ERROR(r, r == KErrNone);
   546 				r = obuf8.Compare(ibuf8);
   547 				TF_ERROR(r, r == 0);
   548 				}
   549 			}
   550 
   551 		// If the supplied buffer is too small this fails with KErrOverflow and the truncated value is reported.
   552 		if (iType == RProperty::EByteArray)
   553 			{
   554 				{
   555 				TBuf<16> ibuf(_L("0123456789012345"));
   556 				TBuf<16> obuf(_L("abcdefghigklmnop"));
   557 				TPtr optr((TUint16*) obuf.Ptr(), 0, 15);
   558 				r = prop.Set(iCategory, iKey, ibuf);
   559 				TF_ERROR(r, r == KErrNone);
   560 				r = prop.Get(iCategory, iKey, optr);
   561 				TF_ERROR(r, r == KErrOverflow);
   562 				TF_ERROR(optr.Length(), optr.Length() == 15); 
   563 				TF_ERROR(obuf[14], obuf[14] == TText('4')); 
   564 				TF_ERROR(obuf[15], obuf[15] == TText('p'));
   565 				}
   566 				{
   567 				TBuf8<16> ibuf8((TUint8*) "0123456789012345");
   568 				TBuf8<16> obuf8((TUint8*) "abcdefghigklmnop");
   569 				TPtr8 optr8((TUint8*) obuf8.Ptr(), 0, 15);
   570 				r = prop.Set(iCategory, iKey, ibuf8);
   571 				TF_ERROR(r, r == KErrNone);
   572 				r = prop.Get(iCategory, iKey, optr8);
   573 				TF_ERROR(r, r == KErrOverflow);
   574 				TF_ERROR(optr8.Length(), optr8.Length() == 15); 
   575 				TF_ERROR(obuf8[14], obuf8[14] == '4'); 
   576 				TF_ERROR(obuf8[15], obuf8[15] == 'p');
   577 				}
   578 				{
   579 				TBuf<16> ibuf(_L("0123456789012345"));
   580 				TBuf<16> obuf(_L("abcdefghigklmnop"));
   581 				TPtr optr((TUint16*) obuf.Ptr(), 0, 15);
   582 				r = prop.Set(ibuf);
   583 				TF_ERROR(r, r == KErrNone);
   584 				r = prop.Get(optr);
   585 				TF_ERROR(r, r == KErrOverflow);
   586 				TF_ERROR(optr.Length(), optr.Length() == 15); 
   587 				TF_ERROR(obuf[14], obuf[14] == TText('4')); 
   588 				TF_ERROR(obuf[15], obuf[15] == TText('p')); 
   589 				}
   590 				{
   591 				TBuf8<16> ibuf8((TUint8*) "0123456789012345");
   592 				TBuf8<16> obuf8((TUint8*) "abcdefghigklmnop");
   593 				TPtr8 optr8((TUint8*) obuf8.Ptr(), 0, 15);
   594 				r = prop.Set(ibuf8);
   595 				TF_ERROR(r, r == KErrNone);
   596 				r = prop.Get(optr8);
   597 				TF_ERROR(r, r == KErrOverflow);
   598 				TF_ERROR(optr8.Length(), optr8.Length() == 15); 
   599 				TF_ERROR(obuf8[14], obuf8[14] == '4'); 
   600 				TF_ERROR(obuf8[15], obuf8[15] == 'p');
   601 				}
   602 			}
   603 
   604 		// Get/Set zero-length data
   605 		if (iType == RProperty::EByteArray)
   606 			{
   607 				{
   608 				TBuf<16> ibuf(_L("Foo"));
   609 				TBuf<16> obuf;
   610 				TPtr nullbuf(NULL, 0);
   611 
   612 				r = prop.Set(ibuf);
   613 				TF_ERROR(r, r == KErrNone);
   614 				r = prop.Get(nullbuf);
   615 				TF_ERROR(r, r == KErrOverflow);
   616 				TF_ERROR(nullbuf.Length(), (nullbuf.Length() == 0));
   617 
   618 				r = prop.Set(nullbuf);
   619 				TF_ERROR(r, r == KErrNone);
   620 				r = prop.Get(obuf);
   621 				TF_ERROR(r, r == KErrNone);
   622 				TF_ERROR(obuf.Length(), (obuf.Length() == 0));
   623 				}
   624 				{
   625 				TBuf8<16> ibuf((TUint8*) "Foo");
   626 				TBuf8<16> obuf;
   627 				TPtr8 nullbuf(NULL, 0);
   628 
   629 				r = prop.Set(ibuf);
   630 				TF_ERROR(r, r == KErrNone);
   631 				r = prop.Get(nullbuf);
   632 				TF_ERROR(r, r == KErrOverflow);
   633 				TF_ERROR(nullbuf.Length(), (nullbuf.Length() == 0));
   634 
   635 				r = prop.Set(nullbuf);
   636 				TF_ERROR(r, r == KErrNone);
   637 				r = prop.Get(obuf);
   638 				TF_ERROR(r, r == KErrNone);
   639 				TF_ERROR(obuf.Length(), (obuf.Length() == 0));
   640 				}
   641 			}
   642 
   643 		r = prop.Delete(iCategory, iKey);
   644 		TF_ERROR(r, r == KErrNone);
   645 		prop.Close();
   646 		}
   647 	}
   648 
   649 		
   650 _LIT(KSubsCancelName, "RProperty::Subscribe()/Cancel() Basics");
   651  
   652 CPropSubsCancel::CPropSubsCancel(TUid aCategory, TUint aKey, RProperty::TType aType) : 
   653 	  CTestProgram(KSubsCancelName), iCategory(aCategory), iKey(aKey), iType(aType)
   654 	{
   655 	}
   656 
   657 
   658 void CPropSubsCancel::Run(TUint aCount)
   659 	{
   660 
   661 	for(TUint i = 0; i < aCount; ++i)
   662 		{
   663 		TRequestStatus status;
   664 		RProperty prop;
   665 
   666 		TInt r = prop.Attach(iCategory, iKey);
   667 		TF_ERROR(r, r == KErrNone);
   668 
   669 		// The calling thread will have the specified request status signalled when the property is next updated.
   670 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   671 		TF_ERROR(r, r == KErrNone);
   672 		prop.Subscribe(status);
   673 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   674 		if (iType == RProperty::EInt)
   675 			{
   676 			r = prop.Set(1);
   677 			TF_ERROR(r, r == KErrNone);
   678 			}
   679 		else
   680 			{
   681 			r = prop.Set(_L("Foo"));
   682 			TF_ERROR(r, r == KErrNone);
   683 			}
   684 		User::WaitForRequest(status);
   685 		TF_ERROR(status.Int(), status.Int() == KErrNone);
   686 		r = prop.Delete(iCategory, iKey);
   687 		TF_ERROR(r, r == KErrNone);
   688 	
   689 		// If the property has not been defined, the request will not complete until the property
   690 		// is defined and published.
   691 		prop.Subscribe(status);
   692 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   693 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   694 		TF_ERROR(r, r == KErrNone);
   695 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   696 		if (iType == RProperty::EInt)
   697 			{
   698 			r = prop.Set(1);
   699 			TF_ERROR(r, r == KErrNone);
   700 			}
   701 		else
   702 			{
   703 			r = prop.Set(_L("Foo"));
   704 			TF_ERROR(r, r == KErrNone);
   705 			}
   706 		User::WaitForRequest(status);
   707 		TF_ERROR(status.Int(), status.Int() == KErrNone);
   708 		r = prop.Delete(iCategory, iKey);
   709 		TF_ERROR(r, r == KErrNone);
   710 
   711 		// Cancel an outstanding subscription request for this property handle. 
   712 		// If it has not already completed, the request is completed with KErrCancelled.
   713 		prop.Subscribe(status);
   714 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   715 		prop.Cancel();		
   716 		User::WaitForRequest(status);
   717 		TF_ERROR(status.Int(), status.Int() == KErrCancel);
   718 
   719 		r = prop.Define(iCategory, iKey, iType, KPassPolicy, KPassPolicy);
   720 		TF_ERROR(r, r == KErrNone);
   721 		prop.Subscribe(status);
   722 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   723 		if (iType == RProperty::EInt)
   724 			{
   725 			r = prop.Set(1);
   726 			TF_ERROR(r, r == KErrNone);
   727 			}
   728 		else
   729 			{
   730 			r = prop.Set(_L("Foo"));
   731 			TF_ERROR(r, r == KErrNone);
   732 			}
   733 		User::WaitForRequest(status);
   734 		TF_ERROR(status.Int(), status.Int() == KErrNone);
   735 		prop.Cancel();		
   736 		TF_ERROR(status.Int(), status.Int() == KErrNone);
   737 
   738 		prop.Subscribe(status);
   739 		TF_ERROR(status.Int(), status.Int() == KRequestPending);
   740 		prop.Cancel();		
   741 		User::WaitForRequest(status);
   742 		TF_ERROR(status.Int(), status.Int() == KErrCancel);
   743 
   744 		r = prop.Delete(iCategory, iKey);
   745 		TF_ERROR(r, r == KErrNone);
   746 
   747 		prop.Close();
   748 		}
   749 	}
   750 
   751 _LIT(KSecurityName, "RProperty Security Basics (Master)");
   752  
   753 CPropSecurity::CPropSecurity(TUid aCategory, TUint aMasterKey, RProperty::TType aType, TUint aSlaveKeySlot) : 
   754 		CTestProgram(KSecurityName), iCategory(aCategory), iMasterKey(aMasterKey), 
   755 		iSlaveKeySlot(aSlaveKeySlot), iType(aType)
   756 	{
   757 	}
   758 
   759 _LIT(KSecuritySlavePath, "t_prop_sec.exe");
   760 
   761 void CPropSecurity::Run(TUint aCount)
   762 	{
   763 	for(TInt i=0; i<ECapability_Limit; i++)
   764 		if(!PlatSec::IsCapabilityEnforced((TCapability)i))
   765 			{
   766 			// System isn't configured with platform security enforced
   767 			// so don't bother running tests
   768 			return;
   769 			}
   770 
   771 	TArgs args;
   772 	args.iCount = aCount;
   773 	args.iCategory = iCategory;
   774 	args.iMasterKey = iMasterKey;
   775 	args.iSlaveKeySlot = iSlaveKeySlot;
   776 
   777 	RProperty prop;
   778 
   779 	TInt r = prop.Define(iCategory, iMasterKey, iType, KPassPolicy, KPassPolicy);
   780 	TF_ERROR(r, r == KErrNone);
   781 
   782 	Exec(KSecuritySlavePath, &args, sizeof(args));
   783 
   784 	Exec(_L("t_prop_define0.exe"), &args, sizeof(args));
   785 	Exec(_L("t_prop_define1.exe"), &args, sizeof(args));
   786 	Exec(_L("t_prop_define2.exe"), &args, sizeof(args));
   787 	Exec(_L("t_prop_define3.exe"), &args, sizeof(args));
   788 
   789 	r = prop.Delete(iCategory, iMasterKey);
   790 	TF_ERROR(r, r == KErrNone);
   791 	}