sl@0: // Copyright (c) 2004-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 "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 "clirep.h" sl@0: #include sl@0: #include "srvparams.h" sl@0: #include "srvreqs.h" sl@0: sl@0: using namespace NCentralRepositoryConstants; sl@0: sl@0: RRepositorySession* CClientRepository::Session() sl@0: { sl@0: return static_cast(Dll::Tls()); sl@0: } sl@0: sl@0: CClientRepository* CClientRepository::NewLC(TUid aRepositoryUid) sl@0: { sl@0: CClientRepository* rep = new(ELeave) CClientRepository(); sl@0: CleanupStack::PushL(rep); sl@0: rep->ConstructL(aRepositoryUid); sl@0: return rep; sl@0: } sl@0: sl@0: void CClientRepository::ConstructL(TUid aRepositoryUid) sl@0: { sl@0: RRepositorySession* session = Session(); sl@0: sl@0: if(session == NULL) sl@0: { sl@0: session = new (ELeave) RRepositorySession(); sl@0: CleanupStack::PushL(session); sl@0: User::LeaveIfError(Dll::SetTls(session)); sl@0: CleanupStack::Pop(session); sl@0: User::LeaveIfError(session->Connect()); sl@0: } sl@0: else sl@0: { sl@0: session->IncrementSubSessionCounter(); sl@0: } sl@0: sl@0: iSubSession = new (ELeave) RRepositorySubSession(); sl@0: User::LeaveIfError(iSubSession->Open(session, EInitialise, TIpcArgs(aRepositoryUid.iUid))); sl@0: } sl@0: sl@0: CClientRepository::CClientRepository() sl@0: { sl@0: } sl@0: sl@0: CClientRepository::~CClientRepository() sl@0: { sl@0: if(iSubSession) sl@0: { sl@0: iSubSession->Close(); sl@0: delete iSubSession; sl@0: } sl@0: RRepositorySession* session = Session(); sl@0: if(session && session->DecrementSubSessionCounter() == 0) sl@0: { sl@0: //The last subSesssion is closed. Time to close the session. sl@0: session->Close(); sl@0: delete session; sl@0: Dll::FreeTls(); sl@0: //SetSession(NULL); sl@0: } sl@0: } sl@0: sl@0: TInt CClientRepository::Create(TUint32 aId, TInt aVal) sl@0: { sl@0: return iSubSession->SendReceive(ECreateInt, TIpcArgs(aId, aVal)); sl@0: } sl@0: sl@0: TInt CClientRepository::Create(TUint32 aId, const TReal& aVal) sl@0: { sl@0: TPckg p(aVal); sl@0: return iSubSession->SendReceive(ECreateReal, TIpcArgs(aId, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Create(TUint32 aId, const TDesC8& aVal) sl@0: { sl@0: return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &aVal)); sl@0: } sl@0: sl@0: TInt CClientRepository::Create(TUint32 aId, const TDesC16& aVal) sl@0: { sl@0: TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size()); sl@0: return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &ptr8)); sl@0: } sl@0: sl@0: TInt CClientRepository::Delete(TUint32 aId) sl@0: { sl@0: return iSubSession->SendReceive(EDelete, TIpcArgs(aId)); sl@0: } sl@0: sl@0: TInt CClientRepository::Delete(TUint32 aPartialKey, TUint32 aMask, TUint32 &aErrorKey) sl@0: { sl@0: aErrorKey = KUnspecifiedKey; // set in case not filled by server sl@0: TPckg p(aErrorKey); sl@0: return iSubSession->SendReceive(EDeleteRange, TIpcArgs(aPartialKey, aMask, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TInt& aVal) sl@0: { sl@0: TPckg p(aVal); sl@0: return iSubSession->SendReceive(EGetInt, TIpcArgs(aId, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Set(TUint32 aId, TInt aVal) sl@0: { sl@0: return iSubSession->SendReceive(ESetInt, TIpcArgs(aId, aVal)); sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TReal& aVal) sl@0: { sl@0: TPckg p(aVal); sl@0: return iSubSession->SendReceive(EGetReal, TIpcArgs(aId, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Set(TUint32 aId, const TReal& aVal) sl@0: { sl@0: TPckg p(aVal); sl@0: return iSubSession->SendReceive(ESetReal, TIpcArgs(aId, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TDes8& aVal) sl@0: { sl@0: TPckg p(aVal.MaxLength()); sl@0: return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TDes8& aVal, TInt& aActualLen) sl@0: { sl@0: aActualLen = aVal.MaxLength(); sl@0: TPckg p(aActualLen); sl@0: return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Set(TUint32 aId, const TDesC8& aVal) sl@0: { sl@0: return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &aVal)); sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TDes& aVal) sl@0: { sl@0: TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize()); sl@0: sl@0: TPckg p(ptr8.MaxLength()); sl@0: sl@0: TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p)); sl@0: sl@0: if(r==KErrNone || r==KErrOverflow) sl@0: { sl@0: TInt len = ptr8.Length(); sl@0: // note the following handles the case where client is getting an odd-length 8-bit sl@0: // descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero. sl@0: if(len&1) sl@0: { sl@0: ptr8.SetLength(len+1); // set the length before trying to write the value sl@0: ptr8[len] = 0; sl@0: } sl@0: aVal.SetLength((len + 1)/2); sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt CClientRepository::Get(TUint32 aId, TDes& aVal, TInt& aActualLen) sl@0: { sl@0: TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize()); sl@0: sl@0: aActualLen = ptr8.MaxLength(); sl@0: TPckg p(aActualLen); sl@0: sl@0: TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p)); sl@0: sl@0: if(r==KErrNone || r==KErrOverflow) sl@0: { sl@0: TInt len = ptr8.Length(); sl@0: // note the following handles the case where client is getting an odd-length 8-bit sl@0: // descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero. sl@0: if(len&1) sl@0: { sl@0: ptr8.SetLength(len+1); // set the length before trying to write the value sl@0: ptr8[len] = 0; sl@0: } sl@0: aVal.SetLength((len + 1)/2); sl@0: aActualLen = ((aActualLen + 1)/2); sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt CClientRepository::Set(TUint32 aId, const TDesC& aVal) sl@0: { sl@0: TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size()); sl@0: return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &ptr8)); sl@0: } sl@0: sl@0: TInt CClientRepository::GetMeta(TUint32 aId, TUint32& aMeta) sl@0: { sl@0: TPckg p(aMeta); sl@0: return iSubSession->SendReceive(EGetMeta, TIpcArgs(aId, &p)); sl@0: } sl@0: sl@0: TInt CClientRepository::Move(TUint32 aSourcePartialId, TUint32 aTargetPartialId, sl@0: TUint32 aIdMask, TUint32 &aErrorId) sl@0: { sl@0: aErrorId = KUnspecifiedKey; // set in case not filled by server sl@0: TPckg p(aErrorId); sl@0: TKeyFilter srcKeyIdentifier = {aSourcePartialId, aIdMask}; sl@0: TKeyFilter tgtKeyIdentifier = {aTargetPartialId, aIdMask}; sl@0: TPckg pSrc(srcKeyIdentifier); sl@0: TPckg pTrg(tgtKeyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EMove, TIpcArgs(&pSrc, &pTrg, &p)); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindL(TUint32 aPartialId, TUint32 aIdMask, sl@0: RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFind, TIpcArgs(&pIdentifier, 0, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, TInt aVal, sl@0: RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindEqInt, TIpcArgs(&pIdentifier, aVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TReal& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TPckg pVal(aVal); sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindEqReal, TIpcArgs(&pIdentifier, &pVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TDesC8& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &aVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TDesC& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2); sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &pVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: TInt aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindNeqInt, TIpcArgs(&pIdentifier, aVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TReal& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TPckg pVal(aVal); sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindNeqReal, TIpcArgs(&pIdentifier, &pVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TDesC8& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &aVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of sl@0: //operations valid in transactions. sl@0: TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask, sl@0: const TDesC& aVal, RArray& aFoundIds) sl@0: { sl@0: CleanupFailTransactionPushL(); sl@0: aFoundIds.Reset(); sl@0: sl@0: TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2); sl@0: TFixedArray uids; sl@0: TUint32* start = uids.Begin(); sl@0: TPtr8 ptr(reinterpret_cast(start), uids.Count() * uids.Length()); sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &pVal, &ptr)); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: r = GetFindResult(uids, aFoundIds); sl@0: if (r==KErrNoMemory) sl@0: User::LeaveNoMemory(); sl@0: } sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: /** Private helper function for all the Find~L functions. sl@0: No need to call FailTransaction since all the methods that call this method calls sl@0: FailTransaction prior to this method. sl@0: @internalComponent sl@0: */ sl@0: TInt CClientRepository::GetFindResult(const TFixedArray& aUids, RArray& aFoundIds) sl@0: { sl@0: iClientErr = KErrNone; sl@0: const TUint32 numFound = aUids[0]; sl@0: const TUint32 numInitial = numFound > KCentRepFindBufSize ? KCentRepFindBufSize : numFound; sl@0: const TUint32 numFinal = numFound > KCentRepFindBufSize ? numFound - KCentRepFindBufSize : 0; sl@0: sl@0: for(TUint32 i = 1; i <= numInitial; i++) sl@0: { sl@0: //initialise client error first sl@0: iClientErr=aFoundIds.Append(aUids[i]); sl@0: if (iClientErr!=KErrNone) sl@0: return iClientErr; sl@0: } sl@0: sl@0: if(numFinal) sl@0: { sl@0: TAny* tempBuf = User::Alloc(numFinal * sizeof(TUint32)); sl@0: if (tempBuf==NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: TPtr8 p(static_cast(tempBuf), numFinal * sizeof(TUint32)); sl@0: TInt r = iSubSession->SendReceive(EGetFindResult, TIpcArgs(&p)); sl@0: if (r == KErrNone) sl@0: { sl@0: for(TUint32 i = 0; i < numFinal; i++) sl@0: { sl@0: iClientErr=aFoundIds.Append(static_cast(tempBuf)[i]); sl@0: if (iClientErr!=KErrNone) sl@0: { sl@0: User::Free(tempBuf); sl@0: return iClientErr; sl@0: } sl@0: } sl@0: } sl@0: User::Free(tempBuf); sl@0: } sl@0: return iClientErr; sl@0: } sl@0: sl@0: TInt CClientRepository::NotifyRequest(TUint32 aId, TRequestStatus& aStatus) sl@0: { sl@0: TInt r = iSubSession->SendReceive(ENotifyRequestCheck, TIpcArgs(aId)); sl@0: if(r==KErrNone) sl@0: iSubSession->SendReceive(ENotifyRequest, TIpcArgs(aId), aStatus); sl@0: return r; sl@0: } sl@0: sl@0: TInt CClientRepository::NotifyCancel(TUint32 aId) sl@0: { sl@0: return iSubSession->SendReceive(ENotifyCancel, TIpcArgs(aId)); sl@0: } sl@0: sl@0: TInt CClientRepository::NotifyCancelAll() sl@0: { sl@0: return iSubSession->SendReceive(ENotifyCancelAll); sl@0: } sl@0: sl@0: TInt CClientRepository::NotifyRequest(TUint32 aPartialId, TUint32 aIdMask, sl@0: TRequestStatus& aStatus) sl@0: { sl@0: iSubSession->SendReceive(EGroupNotifyRequest, sl@0: TIpcArgs(aPartialId, aIdMask), aStatus); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CClientRepository::NotifyCancel(TUint32 aPartialId, TUint32 aIdMask) sl@0: { sl@0: TKeyFilter keyIdentifier = {aPartialId, aIdMask}; sl@0: TPckg pIdentifier(keyIdentifier); sl@0: sl@0: return iSubSession->SendReceive(EGroupNotifyCancel, TIpcArgs(&pIdentifier)); sl@0: } sl@0: sl@0: TInt CClientRepository::Reset() sl@0: { sl@0: return iSubSession->SendReceive(EResetAll); sl@0: } sl@0: sl@0: TInt CClientRepository::Reset(TUint32 aId) sl@0: { sl@0: return iSubSession->SendReceive(EReset, TIpcArgs(aId)); sl@0: } sl@0: sl@0: TInt CClientRepository::StartTransaction(TTransactionMode aMode) sl@0: { sl@0: return iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode)); sl@0: } sl@0: sl@0: void CClientRepository::StartTransaction(TTransactionMode aMode, TRequestStatus& aStatus) sl@0: { sl@0: iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode), aStatus); sl@0: } sl@0: sl@0: TInt CClientRepository::CommitTransaction(TUint32& aKeyInfo) sl@0: { sl@0: // set to KUnspecifiedKey in case failure happens before setting in server sl@0: aKeyInfo = KUnspecifiedKey; sl@0: TPckg p(aKeyInfo); sl@0: return iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&p)); sl@0: } sl@0: sl@0: void CClientRepository::CommitTransaction(TDes8& aKeyInfo, TRequestStatus& aStatus) sl@0: { sl@0: // set to KUnspecifiedKey in case failure happens before setting in server sl@0: aKeyInfo.Copy(TPckg(KUnspecifiedKey)); sl@0: iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&aKeyInfo), aStatus); sl@0: } sl@0: sl@0: void CClientRepository::CancelTransaction() sl@0: { sl@0: iSubSession->SendReceive(ETransactionCancel); sl@0: } sl@0: sl@0: static void CancelTransactionCleanupOperation(TAny* aRepository) sl@0: { sl@0: static_cast(aRepository)->CancelTransaction(); sl@0: } sl@0: sl@0: // So CancelTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar sl@0: void CClientRepository::CleanupCancelTransactionPushL() sl@0: { sl@0: CleanupStack::PushL(TCleanupItem(CancelTransactionCleanupOperation, this)); sl@0: } sl@0: sl@0: void CClientRepository::FailTransaction() sl@0: { sl@0: if (iClientErr==KErrNone) sl@0: iSubSession->SendReceive(ETransactionFail,TIpcArgs(KErrAbort)); sl@0: else sl@0: iSubSession->SendReceive(ETransactionFail,TIpcArgs(iClientErr)); sl@0: //reset the internal client code sl@0: iClientErr=KErrNone; sl@0: } sl@0: sl@0: // So FailTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar sl@0: static void FailTransactionCleanupOperation(TAny* aRepository) sl@0: { sl@0: static_cast(aRepository)->FailTransaction(); sl@0: } sl@0: sl@0: void CClientRepository::CleanupFailTransactionPushL() sl@0: { sl@0: CleanupStack::PushL(TCleanupItem(FailTransactionCleanupOperation, this)); sl@0: } sl@0: sl@0: TInt CClientRepository::TransactionState() sl@0: { sl@0: TInt iValue; sl@0: sl@0: TPckg p(iValue); sl@0: sl@0: iSubSession->SendReceive(ETransactionState, TIpcArgs(&p)); sl@0: sl@0: return iValue; sl@0: } sl@0: sl@0: TInt RRepositorySubSession::Open(RRepositorySession* aSession,TInt aFunction,const TIpcArgs& aArgs) sl@0: { sl@0: iSession = aSession; sl@0: return(CreateSubSession(*aSession, aFunction, aArgs)); sl@0: } sl@0: sl@0: void RRepositorySubSession::Close() sl@0: { sl@0: RSubSessionBase::CloseSubSession(EClose); sl@0: } sl@0: sl@0: TInt RRepositorySubSession::SendReceive(TInt aFunction) const sl@0: { sl@0: return RSubSessionBase::SendReceive(aFunction); sl@0: } sl@0: sl@0: TInt RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const sl@0: { sl@0: return RSubSessionBase::SendReceive(aFunction, aArgs); sl@0: } sl@0: sl@0: void RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) const sl@0: { sl@0: RSubSessionBase::SendReceive(aFunction, aArgs, aStatus); sl@0: } sl@0: sl@0: inline TInt RRepositorySession::IncrementSubSessionCounter() sl@0: { sl@0: return ++iSubSessionCounter; sl@0: } sl@0: sl@0: RRepositorySession ::RRepositorySession() sl@0: :iSubSessionCounter(1) sl@0: { sl@0: } sl@0: sl@0: inline TInt RRepositorySession::DecrementSubSessionCounter() sl@0: { sl@0: ASSERT(iSubSessionCounter > 0); sl@0: return --iSubSessionCounter; sl@0: } sl@0: sl@0: #if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__) sl@0: TInt RRepositorySession::SendReceive(TInt aFunction) const sl@0: { sl@0: return RSessionBase::SendReceive(aFunction); sl@0: } sl@0: sl@0: TInt RRepositorySession::SendReceive(TInt aFunction, sl@0: const TIpcArgs& aArgs) const sl@0: { sl@0: return RSessionBase::SendReceive(aFunction, aArgs); sl@0: } sl@0: sl@0: void RRepositorySession::SendReceive(TInt aFunction, const TIpcArgs& aArgs, sl@0: TRequestStatus& aStatus) const sl@0: { sl@0: RSessionBase::SendReceive(aFunction, aArgs, aStatus); sl@0: } sl@0: #endif sl@0: sl@0: LOCAL_C TInt StartServer(); sl@0: sl@0: TInt RRepositorySession::Connect() sl@0: { sl@0: const TVersion KVersion(KServerMajorVersion, KServerMinorVersion, sl@0: KServerBuildVersion); sl@0: TInt retry = 2; sl@0: TInt err = KErrGeneral; sl@0: // Use unlimited message slots as we can call subscribe multiple times per sl@0: // session. sl@0: TInt numMessageSlots = -1; sl@0: for(;;) sl@0: { sl@0: // Try to create a new session with the server. sl@0: err = CreateSession(KServerName, KVersion, numMessageSlots); sl@0: if((err != KErrNotFound) && (err != KErrServerTerminated)) sl@0: break; //completed sl@0: // Server not running, try to start it. sl@0: if(--retry==0) sl@0: break; // Failed. sl@0: err = StartServer(); sl@0: if((err != KErrNone) && (err != KErrAlreadyExists)) sl@0: break; // Launched server sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: // sl@0: // Start the server process or thread sl@0: // sl@0: LOCAL_C TInt StartServer() sl@0: { sl@0: const TUidType serverUid(KNullUid,KNullUid,KServerUid3); sl@0: // sl@0: // EPOC and EKA2 is easy, we just create a new server process. Simultaneous sl@0: // launching of two such processes should be detected when the second one sl@0: // attempts to create the server object, failing with KErrAlreadyExists. sl@0: // sl@0: RProcess server; sl@0: TInt r=server.Create(KServerImg,KNullDesC,serverUid); sl@0: sl@0: if (r!=KErrNone) sl@0: return r; sl@0: TRequestStatus stat; sl@0: server.Rendezvous(stat); sl@0: if (stat!=KRequestPending) sl@0: server.Kill(0); // abort startup sl@0: else sl@0: server.Resume(); // logon OK - start the server sl@0: User::WaitForRequest(stat); // wait for start or death sl@0: // we can't use the 'exit reason' if the server panicked as this sl@0: // is the panic 'reason' and may be '0' which cannot be distinguished sl@0: // from KErrNone sl@0: r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); sl@0: server.Close(); sl@0: return r; sl@0: } sl@0: