1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/property/t_prop_ldd.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,440 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "t_prop_ldd.h"
1.20 +#include <kernel/kernel.h>
1.21 +#include "nk_priv.h"
1.22 +
1.23 +class DPropLDevice : public DLogicalDevice
1.24 + {
1.25 +public:
1.26 + DPropLDevice();
1.27 + virtual TInt Install();
1.28 + virtual void GetCaps(TDes8& aDes) const;
1.29 + virtual TInt Create(DLogicalChannelBase*& aChannel);
1.30 + };
1.31 +
1.32 +class DPropLChannel : public DLogicalChannelBase
1.33 + {
1.34 +public:
1.35 + DPropLChannel();
1.36 + ~DPropLChannel();
1.37 +
1.38 + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.39 + virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
1.40 +
1.41 +private:
1.42 + TInt Basic(RPropChannel::TBasicInfo* aInfo);
1.43 +
1.44 + static void CompleteFn(TAny* aPtr, TInt aReason);
1.45 + TInt iReason;
1.46 + NFastSemaphore iSem;
1.47 +
1.48 + };
1.49 +
1.50 +DECLARE_STANDARD_LDD()
1.51 +//
1.52 +// Create a new device
1.53 +//
1.54 + {
1.55 + return new DPropLDevice;
1.56 + }
1.57 +
1.58 +DPropLDevice::DPropLDevice()
1.59 +//
1.60 +// Constructor
1.61 +//
1.62 + {
1.63 + //iUnitsMask=0;
1.64 + iVersion = TVersion(1,0,1);
1.65 + // iParseMask = 0;
1.66 + }
1.67 +
1.68 +TInt DPropLDevice::Install()
1.69 +//
1.70 +// Install the device driver.
1.71 +//
1.72 + {
1.73 + TInt r = SetName(&KPropLdName);
1.74 + return r;
1.75 + }
1.76 +
1.77 +void DPropLDevice::GetCaps(TDes8&) const
1.78 +//
1.79 +// Return the Comm capabilities.
1.80 +//
1.81 + {
1.82 + }
1.83 +
1.84 +TInt DPropLDevice::Create(DLogicalChannelBase*& aChannel)
1.85 +//
1.86 +// Create a channel on the device.
1.87 +//
1.88 + {
1.89 + aChannel = new DPropLChannel;
1.90 + return aChannel ? KErrNone : KErrNoMemory;
1.91 + }
1.92 +
1.93 +DPropLChannel::DPropLChannel()
1.94 + {
1.95 + NKern::FSSetOwner(&iSem, NKern::CurrentThread());
1.96 + }
1.97 +
1.98 +TInt DPropLChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /* aInfo*/ , const TVersion& aVer)
1.99 +//
1.100 +// Create the channel from the passed info.
1.101 +//
1.102 + {
1.103 + if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
1.104 + return KErrNotSupported;
1.105 + return KErrNone;
1.106 + }
1.107 +
1.108 +DPropLChannel::~DPropLChannel()
1.109 + {
1.110 + }
1.111 +
1.112 +
1.113 +#define BASIC_ERROR(aRes, aCond) \
1.114 + {\
1.115 + if (!(aCond)) \
1.116 + { \
1.117 + Kern::Printf("Test '" #aCond "' fails; r = %d;\n\tfile '" __FILE__ "'; line %d;\n", aRes, __LINE__); \
1.118 + prop.Close(); \
1.119 + return EFalse; \
1.120 + } \
1.121 + }
1.122 +
1.123 +void DPropLChannel::CompleteFn(TAny* aPtr, TInt aReason)
1.124 + { // static
1.125 + DPropLChannel* self = (DPropLChannel*) aPtr;
1.126 + self->iReason = aReason;
1.127 + NKern::FSSignal(&self->iSem);
1.128 + }
1.129 +
1.130 +TBool DPropLChannel::Basic(RPropChannel::TBasicInfo* aInfo)
1.131 + {
1.132 +
1.133 + TUid category = aInfo->iCategory;
1.134 + TUint key = aInfo->iKey;
1.135 + TUint count = aInfo->iCount;
1.136 + RProperty::TType type = aInfo->iType;
1.137 +
1.138 + for (TUint i = 0; i < count; ++i)
1.139 + {
1.140 + RPropertyRef prop;
1.141 + TInt r = prop.Open(category, key);
1.142 + BASIC_ERROR(r, r == KErrNotFound);
1.143 + r = prop.Attach(category, key);
1.144 + BASIC_ERROR(r, r == KErrNone);
1.145 +
1.146 + // Defines the attributes and access control for a property. This can only be done
1.147 + // once for each property. Subsequent attempts to define the same property will return
1.148 + // KErrAlreadyExists.
1.149 +
1.150 + TSecurityPolicy policy;
1.151 +
1.152 + r = prop.Define(type, policy, policy);
1.153 + BASIC_ERROR(r, r == KErrNone);
1.154 + r = prop.Define(type, policy, policy);
1.155 + BASIC_ERROR(r, r == KErrAlreadyExists);
1.156 + r = prop.Delete();
1.157 + BASIC_ERROR(r, r == KErrNone);
1.158 +
1.159 + // Define fails with KErrArgument if wrong type or attribute was specified.
1.160 + r = prop.Define(RProperty::ETypeLimit, policy, policy);
1.161 + BASIC_ERROR(r, r == KErrArgument);
1.162 +
1.163 + static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
1.164 + TSecurityPolicy badPolicy;
1.165 + *(TInt*)&badPolicy = -1;
1.166 +
1.167 + r = prop.Define(type, badPolicy, policy);
1.168 + BASIC_ERROR(r, r == KErrArgument);
1.169 + r = prop.Define(type, KPassPolicy, badPolicy);
1.170 + BASIC_ERROR(r, r == KErrArgument);
1.171 +
1.172 + if (type == RProperty::EInt)
1.173 + {
1.174 + // Define fails with KErrArgument if aType is TInt and aPreallocate is not 0
1.175 + r = prop.Define(type, KPassPolicy, KPassPolicy, 16);
1.176 + BASIC_ERROR(r, r == KErrArgument);
1.177 +
1.178 + // Following defintion the property has a default value, 0 for integer properties
1.179 + r = prop.Define(RProperty::EInt, KPassPolicy, KPassPolicy);
1.180 + BASIC_ERROR(r, r == KErrNone);
1.181 + TInt value;
1.182 + r = prop.Get(value);
1.183 + BASIC_ERROR(r, r == KErrNone);
1.184 + BASIC_ERROR(value, value == 0);
1.185 + r = prop.Delete();
1.186 + BASIC_ERROR(r, r == KErrNone);
1.187 + }
1.188 + else
1.189 + {
1.190 + // Defne fails with KErrTooBig if aPeallocate is grater than KMaxPropertySize.
1.191 + r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize);
1.192 + BASIC_ERROR(r, r == KErrNone);
1.193 + r = prop.Delete();
1.194 + BASIC_ERROR(r, r == KErrNone);
1.195 + r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize+1);
1.196 + BASIC_ERROR(r, r == KErrTooBig);
1.197 +
1.198 + // Following defintion the property has a default value, zero-length data for byte-array and text
1.199 + // properties.
1.200 + r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy);
1.201 + BASIC_ERROR(r, r == KErrNone);
1.202 + TBuf8<16> buf;
1.203 + r = prop.Get(buf);
1.204 + BASIC_ERROR(r, r == KErrNone);
1.205 + BASIC_ERROR(buf.Size(), buf.Size() == 0);
1.206 + r = prop.Delete();
1.207 + BASIC_ERROR(r, r == KErrNone);
1.208 + }
1.209 +
1.210 + // Pending subscriptions for this property will not be completed until a new value is published.
1.211 + TPropertySubsRequest subs(CompleteFn, this);
1.212 + iReason = KRequestPending;
1.213 + r = prop.Subscribe(subs);
1.214 + r = prop.Define(type, KPassPolicy, KPassPolicy);
1.215 + BASIC_ERROR(r, r == KErrNone);
1.216 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.217 + r = prop.Delete();
1.218 + BASIC_ERROR(r, r == KErrNone);
1.219 + NKern::FSWait(&iSem);
1.220 + BASIC_ERROR(iReason, iReason == KErrNotFound);
1.221 +
1.222 + // If the property has not been defined Delete() fails with KErrNotFound.
1.223 + r = prop.Delete();
1.224 + BASIC_ERROR(r, r == KErrNotFound);
1.225 +
1.226 + // When deleted any pending subscriptions for the property will be completed with KErrNotFound.
1.227 + r = prop.Define(type, KPassPolicy, KPassPolicy);
1.228 + BASIC_ERROR(r, r == KErrNone);
1.229 + iReason = KRequestPending;
1.230 + r = prop.Subscribe(subs);
1.231 + BASIC_ERROR(r, r == KErrNone);
1.232 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.233 + r = prop.Delete();
1.234 + BASIC_ERROR(r, r == KErrNone);
1.235 + NKern::FSWait(&iSem);
1.236 + BASIC_ERROR(iReason, iReason == KErrNotFound);
1.237 +
1.238 + // Any new request will not complete until the property is defined and published again.
1.239 + iReason = KRequestPending;
1.240 + r = prop.Subscribe(subs);
1.241 + BASIC_ERROR(r, r == KErrNone);
1.242 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.243 + r = prop.Define(type, KPassPolicy, KPassPolicy);
1.244 + BASIC_ERROR(r, r == KErrNone);
1.245 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.246 + if (type == RProperty::EInt)
1.247 + {
1.248 + r = prop.Set(1);
1.249 + BASIC_ERROR(r, r == KErrNone);
1.250 + }
1.251 + else
1.252 + {
1.253 + TBuf8<16> buf((TUint8*) "Foo");
1.254 + r = prop.Set(buf);
1.255 + BASIC_ERROR(r, r == KErrNone);
1.256 + }
1.257 + NKern::FSWait(&iSem);
1.258 + BASIC_ERROR(iReason, iReason == KErrNone);
1.259 + r = prop.Delete();
1.260 + BASIC_ERROR(r, r == KErrNone);
1.261 +
1.262 + // If the property has not been defined Set()/Get() fail with KErrNotFound.
1.263 + {
1.264 + TInt value;
1.265 + TBuf8<16> buf;
1.266 + if (type == RProperty::EInt)
1.267 + {
1.268 + r = prop.Get(value);
1.269 + BASIC_ERROR(r, r == KErrNotFound);
1.270 + r = prop.Set(value);
1.271 + BASIC_ERROR(r, r == KErrNotFound);
1.272 + }
1.273 + else
1.274 + {
1.275 + r = prop.Get(buf);
1.276 + BASIC_ERROR(r, r == KErrNotFound);
1.277 + r = prop.Set(buf);
1.278 + BASIC_ERROR(r, r == KErrNotFound);
1.279 + }
1.280 + }
1.281 +
1.282 + r = prop.Define(type, KPassPolicy, KPassPolicy);
1.283 + BASIC_ERROR(r, r == KErrNone);
1.284 +
1.285 + // If the property is larger than KMaxPropertySize Set() fails with KErrTooBig
1.286 + {
1.287 + if (type == RProperty::EByteArray)
1.288 + {
1.289 + TBuf8<RProperty::KMaxPropertySize + 1> buf(RProperty::KMaxPropertySize + 1);
1.290 + r = prop.Set(buf);
1.291 + BASIC_ERROR(r, r == KErrTooBig);
1.292 + }
1.293 + }
1.294 +
1.295 + // When type of operation mismatch with the property type Set()/Get() fails with KErrArgument.
1.296 + {
1.297 + if (type != RProperty::EInt)
1.298 + {
1.299 + TInt value;
1.300 + r = prop.Get(value);
1.301 + BASIC_ERROR(r, r == KErrArgument);
1.302 + r = prop.Set(value);
1.303 + BASIC_ERROR(r, r == KErrArgument);
1.304 + }
1.305 + else
1.306 + {
1.307 + TBuf8<16> buf;
1.308 + r = prop.Get(buf);
1.309 + BASIC_ERROR(r, r == KErrArgument);
1.310 + r = prop.Set(buf);
1.311 + BASIC_ERROR(r, r == KErrArgument);
1.312 + }
1.313 + }
1.314 +
1.315 + // Get/Set
1.316 + if (type == RProperty::EInt)
1.317 + {
1.318 + r = prop.Set(1);
1.319 + BASIC_ERROR(r, r == KErrNone);
1.320 + TInt value = 0;
1.321 + r = prop.Get(value);
1.322 + BASIC_ERROR(r, r == KErrNone);
1.323 + BASIC_ERROR(value, value == 1);
1.324 + }
1.325 + else
1.326 + {
1.327 + TBuf8<16> ibuf((TUint8*)"Foo");
1.328 + TBuf8<16> obuf;
1.329 + r = prop.Set(ibuf);
1.330 + BASIC_ERROR(r, r == KErrNone);
1.331 + r = prop.Get(obuf);
1.332 + BASIC_ERROR(r, r == KErrNone);
1.333 + r = obuf.Compare(ibuf);
1.334 + BASIC_ERROR(r, r == 0);
1.335 + }
1.336 +
1.337 + // If the supplied buffer is too small Get() fails with KErrOverflow and the truncated value is reported.
1.338 + if (type == RProperty::EByteArray)
1.339 + {
1.340 + TBuf8<16> ibuf((TUint8*) "0123456789012345");
1.341 + TBuf8<16> obuf((TUint8*) "abcdefghigklmnop");
1.342 + TPtr8 optr((TUint8*) obuf.Ptr(), 0, 15);
1.343 + r = prop.Set(ibuf);
1.344 + BASIC_ERROR(r, r == KErrNone);
1.345 + r = prop.Get(optr);
1.346 + BASIC_ERROR(r, r == KErrOverflow);
1.347 + BASIC_ERROR(optr.Length(), optr.Length() == 15);
1.348 + BASIC_ERROR(obuf[14], obuf[14] == '4');
1.349 + BASIC_ERROR(obuf[15], obuf[15] == 'p');
1.350 + }
1.351 +
1.352 + // The calling thread will have the specified request status signalled when the property is next updated.
1.353 + iReason = KRequestPending;
1.354 + r = prop.Subscribe(subs);
1.355 + BASIC_ERROR(r, r == KErrNone);
1.356 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.357 + if (type == RProperty::EInt)
1.358 + {
1.359 + r = prop.Set(1);
1.360 + BASIC_ERROR(r, r == KErrNone);
1.361 + }
1.362 + else
1.363 + {
1.364 + TBuf8<16> buf((TUint8*) "Foo");
1.365 + r = prop.Set(buf);
1.366 + BASIC_ERROR(r, r == KErrNone);
1.367 + }
1.368 + NKern::FSWait(&iSem);
1.369 + BASIC_ERROR(iReason, iReason == KErrNone);
1.370 +
1.371 + r = prop.Delete();
1.372 + BASIC_ERROR(r, r == KErrNone);
1.373 +
1.374 + // Cancel an outstanding subscription request.
1.375 + // If it has not already completed, the request is completed with KErrCancelled.
1.376 + iReason = KRequestPending;
1.377 + r = prop.Subscribe(subs);
1.378 + BASIC_ERROR(r, r == KErrNone);
1.379 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.380 + prop.Cancel(subs);
1.381 + NKern::FSWait(&iSem);
1.382 + BASIC_ERROR(iReason, iReason == KErrCancel);
1.383 +
1.384 + r = prop.Define(type, KPassPolicy, KPassPolicy);
1.385 + BASIC_ERROR(r, r == KErrNone);
1.386 +
1.387 + iReason = KRequestPending;
1.388 + r = prop.Subscribe(subs);
1.389 + BASIC_ERROR(r, r == KErrNone);
1.390 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.391 + if (type == RProperty::EInt)
1.392 + {
1.393 + r = prop.Set(1);
1.394 + BASIC_ERROR(r, r == KErrNone);
1.395 + }
1.396 + else
1.397 + {
1.398 + TBuf8<16> buf((TUint8*) "Foo");
1.399 + r = prop.Set(buf);
1.400 + BASIC_ERROR(r, r == KErrNone);
1.401 + }
1.402 + NKern::FSWait(&iSem);
1.403 + BASIC_ERROR(iReason, iReason == KErrNone);
1.404 + prop.Cancel(subs);
1.405 + BASIC_ERROR(iReason, iReason == KErrNone);
1.406 +
1.407 + iReason = KRequestPending;
1.408 + r = prop.Subscribe(subs);
1.409 + BASIC_ERROR(r, r == KErrNone);
1.410 + BASIC_ERROR(iReason, iReason == KRequestPending);
1.411 + prop.Cancel(subs);
1.412 + NKern::FSWait(&iSem);
1.413 + BASIC_ERROR(iReason, iReason == KErrCancel);
1.414 +
1.415 + r = prop.Delete();
1.416 + BASIC_ERROR(r, r == KErrNone);
1.417 +
1.418 + prop.Close();
1.419 + }
1.420 + return ETrue;
1.421 + }
1.422 +
1.423 +//
1.424 +// Client requests.
1.425 +//
1.426 +TBool DPropLChannel::Request(TInt aFunction, TAny* a1, TAny*)
1.427 + {
1.428 + TBool r;
1.429 + switch (aFunction)
1.430 + {
1.431 + case RPropChannel::EBasicTests:
1.432 + RPropChannel::TBasicInfo info;
1.433 + kumemget32(&info, a1, sizeof(info));
1.434 + NKern::ThreadEnterCS();
1.435 + r = Basic(&info);
1.436 + NKern::ThreadLeaveCS();
1.437 + break;
1.438 + default:
1.439 + r = EFalse;
1.440 + break;
1.441 + }
1.442 + return r;
1.443 + }