sl@0: // Copyright (c) 2008-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: // e32\e32test\demandpaging\d_pagingexample_2_post.cpp sl@0: // Demand paging migration example device driver d_pagingexample_2_post: a sl@0: // DLogicalChannelBase-dervied driver, post-migration sl@0: // sl@0: // sl@0: sl@0: #include "d_pagingexample.h" sl@0: #include sl@0: #include sl@0: sl@0: const TInt KDfcQThreadPriority = 25; sl@0: const TInt KBufferSize = KMaxTransferSize; sl@0: sl@0: // sl@0: // Logical channel sl@0: // sl@0: sl@0: class DExampleChannel : public DLogicalChannelBase sl@0: { sl@0: public: sl@0: typedef RPagingExample::TConfigData TConfigData; sl@0: typedef RPagingExample::TValueStruct TValueStruct; sl@0: public: sl@0: DExampleChannel(); sl@0: ~DExampleChannel(); sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); sl@0: TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); sl@0: TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2); sl@0: TInt DoCancel(TUint aMask); sl@0: private: sl@0: TDfcQue* DfcQ(); sl@0: void Shutdown(); sl@0: void GetConfig(TConfigData&); sl@0: void SetConfig(const TConfigData&); sl@0: TInt StartNotify(TRequestStatus* aStatus); sl@0: TInt StartAsyncGetValue(TInt* aValue, TRequestStatus* aStatus); sl@0: TInt StartAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus); sl@0: TInt StartRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus); sl@0: TInt StartReadDes(TDes8* aDesOut, TRequestStatus* aStatus); sl@0: TInt StartWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus); sl@0: TInt StartWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus); sl@0: void ReceiveToReadBuffer(); sl@0: void SendFromWriteBuffer(); sl@0: static void CancelDfcFunc(TAny* aPtr); sl@0: static void AsyncGetValueCompleteDfcFunc(TAny* aPtr); sl@0: static void AsyncGetValue2CompleteDfcFunc(TAny* aPtr); sl@0: static void ReceiveCompleteDfcFunc(TAny* aPtr); sl@0: static void SendCompleteDfcFunc(TAny* aPtr); sl@0: void CompleteNotify(); sl@0: void CompleteAsyncGetValue(); sl@0: void CompleteAsyncGetValue2(); sl@0: void CompleteRead(); sl@0: void CompleteWrite(); sl@0: void Cancel(); sl@0: private: sl@0: NFastMutex iLock; sl@0: TDynamicDfcQue* iDynamicDfcQ; sl@0: TConfigData iConfig; sl@0: DThread* iClient; sl@0: TDfc iCancelDfc; sl@0: sl@0: // Notify sl@0: TClientRequest* iNotifyRequest; sl@0: sl@0: // Async get value sl@0: TClientDataRequest* iAsyncGetValueRequest; sl@0: NTimer iAsyncGetValueTimer; sl@0: TDfc iAsyncGetValueDfc; sl@0: sl@0: // Async get value sl@0: TClientDataRequest2* iAsyncGetValue2Request; sl@0: NTimer iAsyncGetValue2Timer; sl@0: TDfc iAsyncGetValue2Dfc; sl@0: sl@0: // Read sl@0: TClientBufferRequest* iReadRequest; sl@0: NTimer iReadTimer; sl@0: TClientBuffer* iClientReadBuffer; sl@0: TDfc iCompleteReadDfc; sl@0: sl@0: // Write sl@0: TClientBufferRequest* iWriteRequest; sl@0: NTimer iWriteTimer; sl@0: TClientBuffer* iClientWriteBuffer; sl@0: TDfc iCompleteWriteDfc; sl@0: TUint8 iBuffer[KBufferSize]; sl@0: }; sl@0: sl@0: DExampleChannel::DExampleChannel() : sl@0: iCancelDfc(CancelDfcFunc, this, 0), sl@0: iAsyncGetValueTimer(NULL, this), sl@0: iAsyncGetValueDfc(AsyncGetValueCompleteDfcFunc, this, 0), sl@0: iAsyncGetValue2Timer(NULL, this), sl@0: iAsyncGetValue2Dfc(AsyncGetValue2CompleteDfcFunc, this, 0), sl@0: iReadTimer(NULL, this), sl@0: iCompleteReadDfc(ReceiveCompleteDfcFunc, this, 0), sl@0: iWriteTimer(NULL, this), sl@0: iCompleteWriteDfc(SendCompleteDfcFunc, this, 0) sl@0: { sl@0: iClient = &Kern::CurrentThread(); sl@0: iClient->Open(); sl@0: } sl@0: sl@0: DExampleChannel::~DExampleChannel() sl@0: { sl@0: Kern::SafeClose((DObject*&)iClient, NULL); sl@0: if (iDynamicDfcQ) sl@0: iDynamicDfcQ->Destroy(); sl@0: Kern::DestroyClientRequest(iNotifyRequest); sl@0: Kern::DestroyClientRequest(iAsyncGetValueRequest); sl@0: Kern::DestroyClientRequest(iAsyncGetValue2Request); sl@0: Kern::DestroyClientBufferRequest(iReadRequest); sl@0: Kern::DestroyClientBufferRequest(iWriteRequest); sl@0: } sl@0: sl@0: TDfcQue* DExampleChannel::DfcQ() sl@0: { sl@0: return iDynamicDfcQ; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) sl@0: { sl@0: TInt r; sl@0: sl@0: r = Kern::CreateClientRequest(iNotifyRequest); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientDataRequest(iAsyncGetValueRequest); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientDataRequest2(iAsyncGetValue2Request); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientBufferRequest(iWriteRequest, 1, TClientBufferRequest::EPinVirtual); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // create a dynamic DFC queue, which is used for handling client messages and for our own DFCs sl@0: r = Kern::DynamicDfcQCreate(iDynamicDfcQ, KDfcQThreadPriority, KPagingExample1PostLdd); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // todo: this will be the default anyway sl@0: iDynamicDfcQ->SetRealtimeState(ERealtimeStateOn); sl@0: sl@0: iCancelDfc.SetDfcQ(DfcQ()); sl@0: iAsyncGetValueDfc.SetDfcQ(DfcQ()); sl@0: iAsyncGetValue2Dfc.SetDfcQ(DfcQ()); sl@0: iCompleteReadDfc.SetDfcQ(DfcQ()); sl@0: iCompleteWriteDfc.SetDfcQ(DfcQ()); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DExampleChannel::Request(TInt aReqNo, TAny* a1, TAny* a2) sl@0: { sl@0: TInt r = KErrNone; sl@0: if (&Kern::CurrentThread() != iClient) sl@0: r = KErrAccessDenied; // we only support one client sl@0: else if (aReqNo==KMaxTInt) sl@0: { sl@0: // DoCancel sl@0: r = DoCancel((TInt)a1); sl@0: } sl@0: else if (aReqNo<0) sl@0: { sl@0: // DoRequest sl@0: TRequestStatus* pS=(TRequestStatus*)a1; sl@0: TAny* array[2] = { NULL, NULL }; sl@0: kumemget32(array, a2, 2 * sizeof(TAny*)); sl@0: r = DoRequest(~aReqNo, pS, array[0], array[1]); sl@0: if(r != KErrNone) sl@0: Kern::RequestComplete(pS, r); sl@0: r = KErrNone; sl@0: } sl@0: else sl@0: { sl@0: // DoControl sl@0: r = DoControl(aReqNo, a1, a2); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoControl(TInt aFunction,TAny* a1,TAny* /*a2*/) sl@0: { sl@0: TInt r = KErrNone; sl@0: TConfigData configBuffer; sl@0: switch (aFunction) sl@0: { sl@0: case RPagingExample::EGetConfig: sl@0: GetConfig(configBuffer); sl@0: umemput32(a1, (TAny*)&configBuffer, sizeof(TConfigData)); sl@0: break; sl@0: sl@0: case RPagingExample::ESetConfig: sl@0: umemget32(&configBuffer, a1, sizeof(TConfigData)); sl@0: SetConfig(configBuffer); sl@0: break; sl@0: sl@0: default: sl@0: r = KErrNotSupported; sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2) sl@0: { sl@0: TInt r = KErrNotSupported; sl@0: switch (aFunction) sl@0: { sl@0: case RPagingExample::ERequestNotify: sl@0: r = StartNotify(aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue: sl@0: r = StartAsyncGetValue((TInt*)a1, aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue2: sl@0: r = StartAsyncGetValue2((TInt*)a1, (TInt*)a2, aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestRead: sl@0: r = StartRead(a1, (TInt)a2, aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestReadDes: sl@0: r = StartReadDes((TDes8*)a1, aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWrite: sl@0: r = StartWrite(a1, (TInt)a2, aStatus); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWriteDes: sl@0: r = StartWriteDes((TDes8*)a1, aStatus); sl@0: break; sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoCancel(TUint /*aMask*/) sl@0: { sl@0: iCancelDfc.Enque(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::CancelDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->Cancel(); sl@0: } sl@0: sl@0: void DExampleChannel::Cancel() sl@0: { sl@0: if (iAsyncGetValueRequest->IsReady()) sl@0: { sl@0: iAsyncGetValueTimer.Cancel(); sl@0: iAsyncGetValueDfc.Cancel(); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValueRequest, KErrCancel); sl@0: } sl@0: sl@0: if (iAsyncGetValue2Request->IsReady()) sl@0: { sl@0: iAsyncGetValue2Timer.Cancel(); sl@0: iAsyncGetValue2Dfc.Cancel(); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValue2Request, KErrCancel); sl@0: } sl@0: sl@0: if (iReadRequest && iReadRequest->IsReady()) sl@0: { sl@0: iReadTimer.Cancel(); sl@0: iCompleteReadDfc.Cancel(); sl@0: Kern::QueueBufferRequestComplete(iClient, iReadRequest, KErrCancel); sl@0: Kern::DestroyClientBufferRequest(iReadRequest); sl@0: } sl@0: sl@0: if (iWriteRequest->IsReady()) sl@0: { sl@0: iWriteTimer.Cancel(); sl@0: iCompleteWriteDfc.Cancel(); sl@0: Kern::QueueBufferRequestComplete(iClient, iWriteRequest, KErrCancel); sl@0: } sl@0: } sl@0: sl@0: void DExampleChannel::Shutdown() sl@0: { sl@0: } sl@0: sl@0: void DExampleChannel::GetConfig(TConfigData& aConfigOut) sl@0: { sl@0: NKern::FMWait(&iLock); sl@0: aConfigOut = iConfig; sl@0: NKern::FMSignal(&iLock); sl@0: } sl@0: sl@0: void DExampleChannel::SetConfig(const TConfigData& aNewConfig) sl@0: { sl@0: NKern::FMWait(&iLock); sl@0: iConfig = aNewConfig; sl@0: NKern::FMSignal(&iLock); sl@0: } sl@0: sl@0: TInt DExampleChannel::StartNotify(TRequestStatus* aStatus) sl@0: { sl@0: // example implementation completes the request immediately sl@0: TInt r = iNotifyRequest->SetStatus(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: CompleteNotify(); // example implementation completes the request immediately sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::CompleteNotify() sl@0: { sl@0: Kern::QueueRequestComplete(iClient, iNotifyRequest, KErrNone); sl@0: } sl@0: sl@0: TInt DExampleChannel::StartAsyncGetValue(TInt* aValue, TRequestStatus* aStatus) sl@0: { sl@0: // use of TClientDataRequest API protected by fast mutex sl@0: NKern::FMWait(&iLock); sl@0: TInt r = iAsyncGetValueRequest->SetStatus(aStatus); sl@0: if (r == KErrNone) sl@0: iAsyncGetValueRequest->SetDestPtr(aValue); sl@0: NKern::FMSignal(&iLock); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // queue a timer to simulate an asynchronous operation sl@0: iAsyncGetValueTimer.OneShot(KAsyncDelay, iAsyncGetValueDfc); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::AsyncGetValueCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteAsyncGetValue(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteAsyncGetValue() sl@0: { sl@0: // use of TClientDataRequest API protected by fast mutex sl@0: NKern::FMWait(&iLock); sl@0: if (iAsyncGetValueRequest->IsReady()) sl@0: { sl@0: iAsyncGetValueRequest->Data().iValue1 = 1; sl@0: iAsyncGetValueRequest->Data().iValue2 = _L8("shrt"); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValueRequest, KErrNone); sl@0: } sl@0: NKern::FMSignal(&iLock); sl@0: } sl@0: sl@0: TInt DExampleChannel::StartAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus) sl@0: { sl@0: // use of TClientDataRequest API protected by fast mutex sl@0: NKern::FMWait(&iLock); sl@0: TInt r = iAsyncGetValue2Request->SetStatus(aStatus); sl@0: if (r == KErrNone) sl@0: iAsyncGetValue2Request->SetDestPtr1(aValue1); sl@0: if (r == KErrNone) sl@0: iAsyncGetValue2Request->SetDestPtr2(aValue2); sl@0: NKern::FMSignal(&iLock); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // queue a timer to simulate an asynchronous operation sl@0: iAsyncGetValue2Timer.OneShot(KAsyncDelay, iAsyncGetValue2Dfc); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::AsyncGetValue2CompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteAsyncGetValue2(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteAsyncGetValue2() sl@0: { sl@0: // use of TClientDataRequest API protected by fast mutex sl@0: NKern::FMWait(&iLock); sl@0: if (iAsyncGetValue2Request->IsReady()) sl@0: { sl@0: iAsyncGetValue2Request->Data1() = 1; sl@0: iAsyncGetValue2Request->Data2() = 2; sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValue2Request, KErrNone); sl@0: } sl@0: NKern::FMSignal(&iLock); sl@0: } sl@0: sl@0: TInt DExampleChannel::StartRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus) sl@0: { sl@0: // check length argument first sl@0: if (aLength < 1 || aLength > KBufferSize) sl@0: return KErrArgument; sl@0: sl@0: // normally drivers would pre-create a TClientBufferRequest where possible, but here we create sl@0: // one on demand to test this possibilty sl@0: NKern::ThreadEnterCS(); sl@0: TInt r = Kern::CreateClientBufferRequest(iReadRequest, 1, TClientBufferRequest::EPinVirtual); sl@0: NKern::ThreadLeaveCS(); // iReadRequest is deleted by the destructor sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // start request setup sl@0: r = iReadRequest->StartSetup(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // add client buffer, this does pinning in context of client thread sl@0: r = iReadRequest->AddBuffer(iClientReadBuffer, (TLinAddr)aBuffer, aLength, ETrue); sl@0: if (r != KErrNone) sl@0: return KErrNoMemory; sl@0: sl@0: iReadRequest->EndSetup(); sl@0: sl@0: ReceiveToReadBuffer(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DExampleChannel::StartReadDes(TDes8* aDesOut, TRequestStatus* aStatus) sl@0: { sl@0: // normally drivers would pre-create a TClientBufferRequest where possible, but here we create sl@0: // one on demand to test this possibilty sl@0: NKern::ThreadEnterCS(); sl@0: TInt r = Kern::CreateClientBufferRequest(iReadRequest, 1, TClientBufferRequest::EPinVirtual); sl@0: NKern::ThreadLeaveCS(); // iReadRequest is deleted by the destructor sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // start request setup sl@0: r = iReadRequest->StartSetup(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // add client descriptor, this does pinning in context of client thread sl@0: r = iReadRequest->AddBuffer(iClientReadBuffer, aDesOut); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // can check length argument here sl@0: TInt length = iClientReadBuffer->MaxLength(); sl@0: if (length < 1 || length > KBufferSize) sl@0: { sl@0: // need to reset object so it can be reused sl@0: iReadRequest->Reset(); sl@0: return KErrArgument; sl@0: } sl@0: sl@0: iReadRequest->EndSetup(); sl@0: sl@0: ReceiveToReadBuffer(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DExampleChannel::StartWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus) sl@0: { sl@0: // check length argument first sl@0: if (aLength < 1 || aLength > KBufferSize) sl@0: return KErrArgument; sl@0: sl@0: // demonstrate use the single-buffer version of Setup sl@0: TInt r = iWriteRequest->Setup(iClientWriteBuffer, aStatus, (TLinAddr)aBuffer, aLength); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: SendFromWriteBuffer(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DExampleChannel::StartWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus) sl@0: { sl@0: // demonstrate use the single-buffer version of Setup sl@0: TInt r = iWriteRequest->Setup(iClientWriteBuffer, aStatus, (TAny*)aDesIn); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // can check length argument here sl@0: TInt length = iClientWriteBuffer->Length(); sl@0: if (length < 1 || length > KBufferSize) sl@0: { sl@0: // need to reset object so it can be reused sl@0: iWriteRequest->Reset(); sl@0: return KErrArgument; sl@0: } sl@0: sl@0: SendFromWriteBuffer(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::ReceiveToReadBuffer() sl@0: { sl@0: // just queue a timer to simulate an asynchronous receive operation sl@0: // actually will return the previous contents of the buffer sl@0: NKern::FMWait(&iLock); sl@0: // The synchonisation is for illustrative purposes only - in a real driver we might make use of sl@0: // the configution here, so this would need to be protected from concurrent modification. sl@0: NKern::FMSignal(&iLock); sl@0: iReadTimer.OneShot(KAsyncDelay, iCompleteReadDfc); sl@0: } sl@0: sl@0: void DExampleChannel::SendFromWriteBuffer() sl@0: { sl@0: // just queue a timer to simulate an asynchronous send operation sl@0: NKern::FMWait(&iLock); sl@0: // The synchonisation is for illustrative purposes only - in a real driver we might make use of sl@0: // the configution here, so this would need to be protected from concurrent modification. sl@0: NKern::FMSignal(&iLock); sl@0: iWriteTimer.OneShot(KAsyncDelay, iCompleteWriteDfc); sl@0: } sl@0: sl@0: void DExampleChannel::ReceiveCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteRead(); sl@0: } sl@0: sl@0: void DExampleChannel::SendCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteWrite(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteRead() sl@0: { sl@0: TPtrC8 des(iBuffer, iClientReadBuffer->MaxLength()); sl@0: TInt r = Kern::ThreadBufWrite(iClient, iClientReadBuffer, des, 0, KChunkShiftBy0, iClient); sl@0: Kern::QueueBufferRequestComplete(iClient, iReadRequest, r); sl@0: Kern::DestroyClientBufferRequest(iReadRequest); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteWrite() sl@0: { sl@0: TPtr8 des(iBuffer, iClientWriteBuffer->Length()); sl@0: TInt r = Kern::ThreadBufRead(iClient, iClientWriteBuffer, des, 0, KChunkShiftBy0); sl@0: Kern::QueueBufferRequestComplete(iClient, iWriteRequest, r); sl@0: } sl@0: sl@0: // sl@0: // Logical device sl@0: // sl@0: sl@0: class DExampleFactory : public DLogicalDevice sl@0: { sl@0: public: sl@0: DExampleFactory(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); sl@0: }; sl@0: sl@0: DExampleFactory::DExampleFactory() sl@0: { sl@0: iParseMask = 0; sl@0: iVersion = TVersion(1, 0, 0); sl@0: } sl@0: sl@0: TInt DExampleFactory::Install() sl@0: { sl@0: return SetName(&KPagingExample2PostLdd); sl@0: } sl@0: sl@0: void DExampleFactory::GetCaps(TDes8& /*aDes*/) const sl@0: { sl@0: // not used but required as DLogicalDevice::GetCaps is pure virtual sl@0: } sl@0: sl@0: TInt DExampleFactory::Create(DLogicalChannelBase*& aChannel) sl@0: { sl@0: aChannel = new DExampleChannel; sl@0: return aChannel ? KErrNone : KErrNoMemory; sl@0: } sl@0: sl@0: DECLARE_STANDARD_LDD() sl@0: { sl@0: return new DExampleFactory; sl@0: }