--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/centralrepository/common/src/inifile.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,2310 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#define __INCLUDE_CAPABILITY_NAMES__
+#include <utf.h>
+#include "inifile.h"
+#include "datatype.h"
+#include "log.h"
+
+#define MAX(a,b) ((a)<(b)?(b):(a))
+#define MAX3(a,b,c) MAX(MAX(a,b),c)
+#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d))
+
+//Unicode text file prefix - FE,FF bytes.
+static const TUint16 KUcs2Bom = 0xfeff;
+
+//Repository (ini) file - signature
+_LIT(KSignature, "cenrep");
+static const TInt KSignatureLen = 6;
+
+//Repository (ini) file - version string and version number
+_LIT(KVersion, "version");
+static const TInt KVersionLen = 7;
+static const TUint KCurrentVersion = 1;
+
+//Repository (ini) file - supported types names
+_LIT(KTypeInt, "int");
+_LIT(KTypeReal, "real");
+_LIT(KTypeString, "string");
+_LIT(KTypeString8, "string8");
+_LIT(KTypeBinary, "binary");
+
+//Max type name length
+static const TInt KMaxTypeLen = 9;
+
+//The symbol used in repository (ini) files to note null data
+static const TChar KNullDataIndicator = '-';
+
+// Section identifiers in the repository (ini) file
+_LIT(KPlatSecSection, "[platsec]");
+static const TInt KPlatSecSectionLen = 9;
+
+_LIT(KOwnerSection, "[owner]");
+static const TInt KOwnerSectionLen = 7;
+
+_LIT(KTimeStampSection, "[timestamp]");
+static const TInt KTimeStampSectionLen = 11;
+
+_LIT(KMainSection, "[main]");
+static const TInt KMainSectionLen = 6;
+
+_LIT(KDefaultMetaSection, "[defaultmeta]");
+static const TInt KDefaultMetaSectionLen = 13 ;
+
+static const TInt KIniFileSectionLen = MAX4(KPlatSecSectionLen,KMainSectionLen,KTimeStampSectionLen, KDefaultMetaSectionLen);
+
+// Other useful string constants
+_LIT(KMaskString, "mask");
+static const TInt KMaskLen = 4;
+
+_LIT(KReadAccessSidString, "sid_rd");
+_LIT(KReadAccessCapString, "cap_rd");
+_LIT(KWriteAccessSidString, "sid_wr");
+_LIT(KWriteAccessCapString, "cap_wr");
+_LIT(KAccessAlwaysPass, "alwayspass");
+_LIT(KAccessAlwaysFail, "alwaysfail");
+// could do max of _LITs above
+static const TInt KMaxAccessTypeLen = 6;
+
+// longest capability string from CapabilityNames is 15
+static const TInt KMaxCapabilityStringLen = 20;
+
+static const TInt KBufLen = MAX3(KVersionLen, KSignatureLen, KIniFileSectionLen);
+
+
+
+const TUint KCr = '\r';
+const TUint KTab = '\t';
+const TUint KSpace = ' ';
+
+#ifdef CENTREP_CONV_TOOL
+_LIT(KTransactFileName, "transact");
+_LIT(KCrNl, "\r\n");
+_LIT(KHexIntFormat, "0x%X");
+_LIT(KUidFormat, "0x%08X");
+_LIT(KRangeMetaFmt, "0x%X 0x%X 0x%08X");
+_LIT(KMaskMetaFmt, "0x%X mask = 0x%X 0x%08X");
+
+_LIT(KRangePrefix, "0x%X 0x%X");
+_LIT(KMaskPrefix, "0x%08X mask = 0x%08X");
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// Local functions
+
+/**
+The function checks if the file with aFile name exists.
+@param aFile File name, including the full path.
+@return 0, if the file does not exist, non-zero value otherwise.
+@internalComponent
+*/
+/**
+#ifdef CENTREP_CONV_TOOL
+static TBool FileExists(const TDesC& aFile)
+ {
+ TEntry entry;
+ return TServerResources::iFs.Entry(aFile, entry) == KErrNone;
+ }
+#endif
+*/
+
+/**
+@internalComponent
+*/
+static TInt ReadFileL(RFile aFile, HBufC16*& aBuf)
+ {
+ TInt size;
+ TInt r = aFile.Size(size);
+ if(r!=KErrNone)
+ return r;
+ if(size<2)
+ return KErrCorrupt;
+
+ TInt len = size/2-1;
+ aBuf = HBufC16::NewL(len);
+ TPtr16 ptr16 = aBuf->Des();
+ TPtr8 ptr8((TUint8*)ptr16.Ptr(), 0, 2);
+ r = aFile.Read(ptr8, 2);
+ if(r!=KErrNone)
+ return r;
+
+ if(*ptr16.Ptr()!=KUcs2Bom)
+ {
+ __CENTREP_TRACE("File not Ucs2. No BOM");
+ return KErrCorrupt;
+ }
+ ptr8.Set((TUint8*)ptr16.Ptr(), 0, size-2);
+ r = aFile.Read(ptr8);
+ if(r!=KErrNone)
+ return r;
+ ptr16.SetLength(len);
+
+ return KErrNone;
+ }
+
+static TBool IsNegativeNumber(TLex& aLex)
+ {
+ if (aLex.Peek()=='-')
+ return ETrue;
+ else
+ return EFalse;
+ }
+
+/**
+@internalComponent
+*/
+static TInt ReadNumberL(TLex& aLex, TUint32& aVal)
+ {
+ TRadix radix = EDecimal;
+ if(aLex.Peek()=='0')
+ {
+ aLex.Inc();
+ if(aLex.Peek().GetLowerCase()=='x')
+ {
+ aLex.Inc();
+ radix = EHex;
+ }
+ else
+ aLex.UnGet();
+ }
+
+ if(aLex.Val(aVal, radix)!=KErrNone)
+ return KErrCorrupt;
+
+ return KErrNone;
+ }
+
+#ifdef CENTREP_CONV_TOOL
+/**
+@internalComponent
+*/
+static void WriteBinary(TDes& aBuf, const HBufC8* aString)
+ {
+ if(aString)
+ {
+ TInt len = aString->Length();
+ if(len==0)
+ aBuf.Append(KNullDataIndicator);
+ else
+ {
+ TPtr8 ptr8 = const_cast<HBufC8*>(aString)->Des();
+ for(TInt i=0;i<len;i++)
+ aBuf.AppendNumFixedWidth(ptr8[i], EHex, 2);
+ }
+ }
+ else
+ {
+ aBuf.Append(KNullDataIndicator);
+ }
+ }
+
+/**
+The function writes setting value into the supplied buffer (aBuf).
+@param aBuf The buffer where the setting value will be appended.
+@param aSetting Reference to the setting object
+@leave KErrGeneral If the supplied setting object has unknown type.
+@internalComponent
+*/
+static void AddSettingValueL(TDes& aBuf, const TServerSetting& aSetting)
+ {
+ switch(aSetting.Type())
+ {
+ case TServerSetting::EInt:
+ aBuf.Append(KTypeInt);
+ aBuf.Append(KSpace);
+ aBuf.AppendNum(aSetting.GetIntValue());
+ break;
+ case TServerSetting::EReal:
+ aBuf.Append(KTypeReal);
+ aBuf.Append(KSpace);
+ aBuf.AppendNum(aSetting.GetRealValue(), TRealFormat());
+ break;
+ case TServerSetting::EString:
+ aBuf.Append(KTypeBinary);
+ aBuf.Append(KSpace);
+ WriteBinary(aBuf, aSetting.GetStrValue());
+ break;
+ default:
+ User::Leave(KErrGeneral); //unknown setting type
+ break;
+ }
+ }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// CIniFileIn class
+
+TInt CIniFileIn::NewLC(RFs& aFs,CIniFileIn*& aIniFile,const TDesC& aFullFileName)
+ {
+ aIniFile = new(ELeave) CIniFileIn(aFs);
+ CleanupStack::PushL(aIniFile);
+ RFile file;
+ CleanupClosePushL(file);
+ TInt r = file.Open(aFs, aFullFileName, EFileRead|EFileStreamText);
+ if(r==KErrNone)
+ {
+
+#ifdef CENTREP_TRACE
+ aIniFile->iFullName = HBufC::NewL(aFullFileName.Length());
+ TPtr filename = aIniFile->iFullName->Des();
+ filename.Copy(aFullFileName);
+#endif
+ TInt rReadFile = ReadFileL(file,aIniFile->iBuf);
+ CleanupStack::PopAndDestroy(); //file
+ TInt rReadHeader=KErrNone;
+ if(rReadFile==KErrNone)
+ {
+ aIniFile->iLex.Assign(aIniFile->iBuf->Des());
+ rReadHeader=aIniFile->ReadHeaderL();
+ }
+
+ if((rReadFile==KErrCorrupt) || ( rReadHeader==KErrCorrupt))
+ {
+ return KErrCorrupt;
+ }
+ }
+ else
+ {
+ CleanupStack::Pop();//file
+ }
+ return r;
+
+
+ }
+
+CIniFileIn::~CIniFileIn()
+ {
+ delete iBuf;
+#ifdef CENTREP_TRACE
+ delete iFullName;
+#endif
+ }
+
+
+TInt CIniFileIn::ReadHeaderL()
+ {
+ TBuf<KBufLen> buf;
+
+ //
+ // Check file signature
+ //
+
+ SkipComments();
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if(iLex.TokenLength()>KSignatureLen)
+ {
+ __CENTREP_TRACE1("[%S] Invalid header signature",iFullName);
+ return(KErrCorrupt);
+ }
+ buf.CopyLC(iLex.MarkedToken());
+ if(buf.Compare(KSignature)!=0)
+ {
+ __CENTREP_TRACE1("[%S] Invalid header signature",iFullName);
+ return(KErrCorrupt);
+ }
+ //
+ // Check file version
+ //
+
+ SkipComments();
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if(iLex.TokenLength()>KVersionLen)
+ {
+ __CENTREP_TRACE1("[%S] Missing version keyword",iFullName);
+ return(KErrCorrupt);
+ }
+ buf.CopyLC(iLex.MarkedToken());
+ if(buf.Compare(KVersion)!=0)
+ {
+ __CENTREP_TRACE1("[%S] Missing version keyword",iFullName);
+ return(KErrCorrupt);
+ }
+ iLex.SkipSpace();
+
+ TUint version;
+ iLex.Val(version);
+ if(version>KCurrentVersion)
+ {
+ __CENTREP_TRACE1("[%S] Invalid version number",iFullName);
+ return(KErrNotSupported);
+ }
+ return( KErrNone);
+ }
+
+void CIniFileIn::SkipComments()
+ {
+ for(;;)
+ {
+ iLex.SkipSpace();
+
+ if(iLex.Peek()!='#')
+ break;
+
+ while(iLex.Get()!='\n' && !iLex.Eos()) {}
+ }
+ }
+
+void CIniFileIn::SkipEqualSign()
+ {
+ iLex.SkipSpace();
+ if(iLex.Peek()=='=')
+ iLex.Get();
+
+ iLex.SkipSpace();
+ }
+
+TInt CIniFileIn::ReadSettingOnlyL(TServerSetting& aSetting,TBool& aSingleMetaFound)
+ {
+ TInt ret = KErrNone;
+
+ aSingleMetaFound=EFalse;
+
+ SkipComments();
+ iLex.SkipSpace();
+
+ if(iLex.Eos())
+ return KErrNotFound;
+
+ TUint32 key;
+ TInt r=ReadNumberL(iLex, key);
+ if(r!=KErrNone)
+ {
+ // returns either KErrCorrupt or KErrNone
+ __CENTREP_TRACE1("[%S] Invalid single setting id",iFullName);
+ return r;
+ }
+ aSetting.SetKey(key);
+
+ iLex.SkipSpaceAndMark();
+ iLex.SkipCharacters();
+
+ if(iLex.TokenLength()>KMaxTypeLen)
+ {
+ __CENTREP_TRACE1("[%S] Invalid key type, must be one of: [int,real,string,string8,binary]",iFullName);
+ return KErrCorrupt;
+ }
+ TBuf<KMaxTypeLen> type;
+ type.CopyLC(iLex.MarkedToken());
+
+ iLex.SkipSpace();
+
+ if(type.Compare(KTypeInt)==0)
+ {
+ if (IsNegativeNumber(iLex))
+ {
+ TInt i;
+ if(iLex.Val(i)!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid negative integer value",iFullName);
+ return(KErrCorrupt);
+ }
+ aSetting.SetIntValue(i);
+ }
+ else
+ {
+ TUint32 i;
+ TInt r=ReadNumberL(iLex, i);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid integer value",iFullName);
+ return r;
+ }
+ aSetting.SetIntValue(i);
+ }
+ }
+ else if(type.Compare(KTypeReal)==0)
+ {
+ TReal r;
+ ret=iLex.Val(r,'.');
+ //iLex.Val with TReal can return KErrNoMemory
+ if (ret!=KErrNone)
+ {
+ if (ret==KErrNoMemory)
+ User::LeaveNoMemory();
+ else
+ {
+ __CENTREP_TRACE1("[%S] Invalid real value",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ TReal* temp = new(ELeave)TReal(r);
+ aSetting.SetRealValue(temp);
+ temp = NULL;
+ }
+ else if(type.Compare(KTypeString)==0)
+ {
+ HBufC8* s;
+ ret = ReadStringL(s);
+ if(ret != KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid string value",iFullName);
+ return KErrCorrupt;
+ }
+ aSetting.SetStrValue(s);
+ }
+
+ else if(type.Compare(KTypeString8)==0)
+ {
+ HBufC8* s;
+ ret = ReadString16To8L(s);
+ if(ret != KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid string8 value",iFullName);
+ return KErrCorrupt;
+ }
+ aSetting.SetStrValue(s);
+ }
+
+ else if(type.Compare(KTypeBinary)==0)
+ {
+ HBufC8* s = NULL;
+ ret = ReadBinaryL(s);
+ if(ret != KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid binary value",iFullName);
+ return KErrCorrupt;
+ }
+ aSetting.SetStrValue(s);
+ }
+ else
+ {
+ __CENTREP_TRACE1("[%S] Invalid key type, must be one of: [int,real,string,string8,binary]",iFullName);
+ return KErrCorrupt;
+ }
+ //skip any spaces or tabs
+ while(iLex.Peek()==KSpace || iLex.Peek()==KTab)
+ {
+ iLex.Inc();
+ }
+
+ TUint32 meta;
+
+ /**
+ carriage return reached which means that there is no meta AND capabilities
+ defined for this key. Thus setting meta to NULL to be able to set a value
+ from default section later.
+ */
+ if (iLex.Peek()==KCr)
+ {
+ meta = 0;
+ }
+ else
+ {
+ r=ReadNumberL(iLex, meta);
+ /**
+ If meta can not be read, it is not neccessary an error.
+ It might be not present for an individual key and it will be taken
+ from a default section.
+ If single meta is present, we need to remember so we can recognise a single
+ meta of 0 as distinct from no meta ( also sets meta to 0 ).
+ */
+ if(r!=KErrNone)
+ meta = 0;
+ else
+ aSingleMetaFound=ETrue;
+ }
+
+ aSetting.SetMeta(meta);
+
+ return KErrNone;
+ }
+
+/**
+Read an entire DefaultMeta section from ini file
+and create FDefault metadata entries
+
+@internalTechnology
+@return KErrNone, KErrCorrupt or KErrNotFound
+*/
+TInt CIniFileIn::ReadDefaultMetaSecSectionL(TUint32& aDefaultMeta, RDefaultMetaArray& aDefaultMetaRanges)
+ {
+ TBuf<KBufLen> buf;
+
+ //
+ // Check if a DefaultMeta section is present
+ //
+
+ SkipComments();
+
+ // we will need this section later to write the out file...
+ iLex.Mark(iMainSectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if( iLex.TokenLength()!=KDefaultMetaSectionLen ||
+ (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KDefaultMetaSection )!=0) )
+ {
+ // Meta not available
+ iLex.UnGetToMark();
+ return KErrNotFound;
+ }
+
+ //
+ // Lets read Meta settings
+ //
+
+ SkipComments();
+
+ // we might have a default Meta section first
+ if(KErrNone != ReadNumber(aDefaultMeta))
+ {
+ // should we log that no default read policy?
+ }
+
+
+ // now lets try range policies
+ TInt r=ReadRangeMetaDefaultsL(aDefaultMetaRanges);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Error parsing [defaultMeta]",iFullName);
+ return r;
+ }
+ iLex.Mark(iMainSectionMark);
+ return KErrNone;
+ }
+
+
+/**
+Reads Meta defaults as defined for range of indexes
+
+@internalTechnology
+@return KErrNone, KErrCorrupt
+*/
+TInt CIniFileIn::ReadRangeMetaDefaultsL(RDefaultMetaArray& aDefaultMetaRanges)
+{
+ TUint32 lowKey = 0;
+ TBuf<KBufLen> buf;
+
+ SkipComments();
+ while(KErrNone == ReadNumber(lowKey))
+ {
+ // highKey and mask needs to be zero'd every cycle...
+ TUint32 highKey = 0;
+ TUint32 mask = 0;
+ TUint32 defaultMeta = 0 ;
+
+ iLex.SkipSpace();
+ // may be not range but key & mask so lets check 'mask' keyword
+ if(!iLex.Peek().IsDigit())
+ {
+ //so should be mask then...
+ iLex.Mark();
+ while((iLex.Peek()!='=')&&(!iLex.Eos()))
+ {
+ iLex.Inc();
+
+ if(iLex.TokenLength() >= KMaskLen)
+ {
+ // so no '=' there
+ // not necessarily bad thing... could be space there first
+ break;
+ }
+
+ }
+
+ // check if KMaskLen is < buf length?
+ buf.CopyLC(iLex.MarkedToken());
+ if(buf.Compare(KMaskString)!=0)
+ {
+ __CENTREP_TRACE1("[%S] Missing 'mask' keyword [defaultMeta]",iFullName);
+ return KErrCorrupt;
+ }
+
+ iLex.SkipSpace();
+ if('=' != iLex.Get())
+ {
+ __CENTREP_TRACE1("[%S] Missing '=' for 'mask' keyword [defaultMeta]",iFullName);
+ return KErrCorrupt;
+ }
+ iLex.SkipSpace();
+ TInt r=ReadNumberL(iLex,mask);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid 'mask' for keyspace range [defaultMeta]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ else
+ {
+ TInt r = ReadNumberL(iLex,highKey);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid end of range [defaultMeta]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+
+
+ if(KErrNone == ReadNumber(defaultMeta))
+ {
+ TSettingsDefaultMeta metaDefault(defaultMeta,lowKey, highKey, mask);
+ aDefaultMetaRanges.AppendL(metaDefault);
+ }
+ else
+ {
+ // unfortunately, we can't tell if we got here because the default
+ // meta was bad or because there was an invalid start value for the range.
+ __CENTREP_TRACE1("[%S] Range defined without default or bad start of range [defaultMeta]",iFullName);
+ // range specified with no default Meta!
+ return KErrCorrupt;
+ }
+ SkipComments();
+ }
+ return KErrNone;
+}
+
+/**
+Read Owner section from ini file and extract owner UID
+
+@internalTechnology
+@return KErrNone, KErrCorrupt or KErrNotFound
+*/
+TInt CIniFileIn::ReadOwnerSectionL(TUint32 &aOwnerUID)
+ {
+ TBuf<KBufLen> buf;
+
+
+
+ SkipComments();
+
+ // we will need this section later to write the out file...
+ iLex.Mark(iMainSectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if( iLex.TokenLength()!=KOwnerSectionLen ||
+ (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KOwnerSection )!=0) )
+ {
+ // Owner section not available
+ iLex.UnGetToMark();
+ return KErrNotFound;
+ }
+ else
+ {
+ // Found an "owner" section - must be followed by a UID (hex number
+ // in format 0xnnnnn) to be valid!
+ iLex.SkipSpace() ;
+ if(iLex.Peek()=='0')
+ {
+ iLex.Inc();
+ if(iLex.Peek().GetLowerCase()=='x')
+ {
+ iLex.Inc();
+ if(iLex.Val(aOwnerUID, EHex)!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ else
+ {
+ __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ else
+ {
+ __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+
+ iLex.Mark(iMainSectionMark);
+
+ return KErrNone;
+ }
+
+/**
+Read Timestamp section from ini file and extract value as a TTime
+
+@internalTechnology
+@return KErrNone, KErrCorrupt or KErrNotFound
+*/
+TInt CIniFileIn::ReadTimeStampSectionL(TTime &aTimeStamp)
+ {
+ TBuf<25> buf;
+ SkipComments();
+
+ // we will need this section later to write the out file...
+ iLex.Mark(iMainSectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ buf.CopyLC( iLex.MarkedToken());
+
+ if( iLex.TokenLength()!=KTimeStampSectionLen ||
+ (buf.Compare( KTimeStampSection )!=0) )
+ {
+ // Timestamp section not available
+ iLex.UnGetToMark();
+ return KErrNotFound;
+ }
+ else
+ {
+ // Found a "timestamp" section - must be followed by a a timestamp
+ // either in format...
+ //
+ // YYYYMMDD:HHMMSS.MMMMMM where:
+ // YYYY = 4 digit year
+ // MM = 2 digit numeric month
+ // DD = 2 digit numeric date
+ // HH = 2 digit hour
+ // MM = 2 digit minute
+ // SS = 2 digit second
+ // MMMMMM = 6 digit microseconds
+ // Note that this is the format used for constructing/initialising
+ // a TTime from a string.
+ //
+ // ...or a 64-bit integer which can be converted to
+ // to a TTime to be considered valid!
+ //
+ iLex.SkipSpace();
+ iLex.Mark();
+ iLex.SkipCharacters() ;
+
+ buf.CopyLC(iLex.MarkedToken()) ;
+ if (aTimeStamp.Set(buf) !=KErrNone)
+ {
+ TInt64 intTimeStamp ;
+ iLex.UnGetToMark();
+ if (iLex.Val(intTimeStamp) != KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid time stamp [timestamp]",iFullName);
+ return KErrCorrupt;
+ }
+ else
+ {
+ aTimeStamp = intTimeStamp;
+ }
+ }
+ }
+ iLex.Mark(iMainSectionMark);
+ return KErrNone;
+ }
+
+/**
+Read a setting and it's single policy ( if it exists )
+
+@internalTechnology
+@return KErrNone, KErrCorrupt
+ aSetting setting read from ini file
+ aSingleReadPolicy single read policy if any
+ aSingleWritePolicy single write policy if any
+ aSingleReadPolicyFound ETrue if single read policy found with this key, EFalse if not
+ aSingleWritePolicyFound ETrue if single write policy found with this key, EFalse if not
+ aSingleMetaFound ETrue if single metadata found with this key, EFalse if not
+*/
+TInt CIniFileIn::ReadSettingL(TServerSetting& aSetting,TSecurityPolicy& aSingleReadPolicy,TSecurityPolicy& aSingleWritePolicy, TBool& aSingleReadPolicyFound, TBool& aSingleWritePolicyFound, TBool& aSingleMetaFound)
+ {
+ aSingleReadPolicyFound = EFalse;
+ aSingleWritePolicyFound = EFalse;
+
+ TInt error = ReadSettingOnlyL(aSetting, aSingleMetaFound);
+ if(KErrNone == error)
+ {
+ //Need to push into cleanupstack for string setting
+ aSetting.PushL();
+ // when multiple policies enabled then read in a loop
+
+ if (iLex.Peek() !=KCr)
+ {
+ // if neither read/write policy found we do not create TSettingsAccessPolicy at all...
+ TInt err=ReadRdPolicyL(aSingleReadPolicy);
+ if (err==KErrNone)
+ aSingleReadPolicyFound=ETrue;
+ else
+ {
+ //we need to return error code rather than assuming no single policy is found
+ if (err==KErrCorrupt || err==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (err == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid read setting",iFullName);
+ }
+#endif
+ aSetting.PopAndDestroy();
+ return err;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+
+ err=ReadWrPolicyL(aSingleWritePolicy);
+ if (err==KErrNone)
+ aSingleWritePolicyFound=ETrue;
+ else
+ {
+ //we need to return error code rather than assuming no single policy is found
+ if (err==KErrCorrupt || err==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (err == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid write setting",iFullName);
+ }
+#endif
+ aSetting.PopAndDestroy();
+ return err;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+ }
+
+ //Need to pop back the setting
+ aSetting.Pop();
+ }
+ return error;
+ }
+
+TInt CIniFileIn::SkipPlatSecSectionL()
+ {
+ HBufC* platSecSection;
+ TInt r=GetPlatSecSectionLC(platSecSection);
+ if(platSecSection)
+ CleanupStack::PopAndDestroy(platSecSection);
+ return r;
+ }
+
+TInt CIniFileIn::SkipOwnerSectionL()
+ {
+ HBufC* ownerSection;
+ TInt r=GetOwnerSectionLC(ownerSection);
+ if(ownerSection)
+ CleanupStack::PopAndDestroy(ownerSection);
+ return r;
+ }
+
+TInt CIniFileIn::SkipDefaultMetaSectionL()
+ {
+ HBufC* section;
+ TInt r=GetDefaultMetaSectionLC(section);
+ if(section)
+ CleanupStack::PopAndDestroy(section);
+ return r;
+ }
+
+TInt CIniFileIn::SkipTimeStampSectionL()
+ {
+ HBufC* timeStampSection;
+ TInt r=GetTimeStampSectionLC(timeStampSection);
+ if(timeStampSection)
+ CleanupStack::PopAndDestroy(timeStampSection);
+ return r;
+ }
+
+/**
+Read an entire PlatSec section from ini file
+and create TSecurityPolicy for default access and for range of indexes
+
+@internalTechnology
+@return KErrNone, KErrCorrupt or KErrNotFound
+*/
+TInt CIniFileIn::ReadPlatSecSectionL(TSecurityPolicy& aDefaultReadPolicy, TBool& aGotDefaultReadPolicy,
+ TSecurityPolicy& aDefaultWritePolicy, TBool& aGotDefaultWritePolicy,
+ RRangePolicyArray& aRangePolicies)
+
+ {
+ TBuf<KBufLen> buf;
+
+ aGotDefaultReadPolicy = EFalse ;
+ aGotDefaultWritePolicy = EFalse ;
+
+ //
+ // Check if the PlatSec section is present
+ //
+ SkipComments();
+
+ // we will need this section later to write the out file...
+ iLex.Mark(iMainSectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if( iLex.TokenLength()!=KPlatSecSectionLen ||
+ (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KPlatSecSection )!=0) )
+ {
+ // PlatSec section not available
+ iLex.UnGetToMark();
+ return KErrNotFound;
+ }
+
+ //
+ // Lets read the policies
+ //
+
+ SkipComments();
+ TInt r=KErrNone;
+ // we might have a default policies first
+ // check for default read policy
+ r=ReadRdPolicyL(aDefaultReadPolicy);
+ if (r==KErrNone)
+ aGotDefaultReadPolicy=ETrue;
+ else
+ {
+ //we need to return error code rather than assuming no default policy is found
+ if (r==KErrCorrupt || r==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (r == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid read policy [platsec]",iFullName);
+ }
+#endif
+ return r;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+ // check for default write policy
+ r=ReadWrPolicyL(aDefaultWritePolicy);
+ if (r==KErrNone)
+ aGotDefaultWritePolicy=ETrue;
+ else
+ {
+ //we need to return error code rather than assuming no default policy is found
+ if (r==KErrCorrupt || r==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (r == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid write policy [platsec]",iFullName);
+ }
+#endif
+ return r;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+ // now lets try range policies
+ r = ReadRangePoliciesL(aDefaultReadPolicy,aDefaultWritePolicy,aRangePolicies);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid range policy [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ // it must be the main section now so lets check
+ SkipComments();
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if(iLex.TokenLength()>KBufLen)
+ return KErrCorrupt;
+
+ buf.CopyLC(iLex.MarkedToken());
+ if(buf.Compare(KMainSection)!=0)
+ {
+ return KErrCorrupt;
+ }
+
+ iLex.Mark(iMainSectionMark);
+
+ return KErrNone;
+ }
+
+/**
+Reads TSecurityPolicy as defined for range of indexes
+
+@internalTechnology
+@return KErrNone, KErrCorrupt
+@leave KErrNotFound
+*/
+TInt CIniFileIn::ReadRangePoliciesL(const TSecurityPolicy& aDefaultReadPolicy,
+ const TSecurityPolicy& aDefaultWritePolicy,
+ RRangePolicyArray& aRangePolicies)
+{
+ TUint32 lowKey = 0;
+ TBuf<KBufLen> buf;
+
+ SkipComments();
+ while(KErrNone == ReadNumber(lowKey))
+ {
+ // highKey and mask needs to be zero'd every cycle...
+ TUint32 highKey = 0;
+ TUint32 mask = 0;
+ iLex.SkipSpace();
+ // may be not range but key & mask so lets check 'mask' keyword
+ if(!iLex.Peek().IsDigit())
+ {
+ //so should be mask then...
+ iLex.Mark();
+ while((iLex.Peek()!='=')&&(!iLex.Eos()))
+ {
+ iLex.Inc();
+
+ if(iLex.TokenLength() >= KMaskLen)
+ {
+ // so no '=' there
+ // not necessarily bad thing... could be space there first
+ break;
+ }
+
+ }
+
+ // check if KMaskLen is < buf length?
+ buf.CopyLC(iLex.MarkedToken());
+ if(buf.Compare(KMaskString)!=0)
+ {
+ __CENTREP_TRACE1("[%S] Missing 'mask' keyword for range [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+
+ iLex.SkipSpace();
+ if('=' != iLex.Get())
+ {
+ __CENTREP_TRACE1("[%S] Missing '=' for 'mask' keyword for range [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ iLex.SkipSpace();
+ TInt r = ReadNumberL(iLex,mask);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid value for 'mask' keyword [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ else
+ {
+ TInt r = ReadNumberL(iLex,highKey);
+ if(r!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid end of range [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+ TBool writePolicyFound = EFalse;
+ TBool readPolicyFound= EFalse;
+ TSecurityPolicy readPolicy;
+ TSecurityPolicy writePolicy;
+
+ TInt ret=KErrNone;
+ ret=ReadRdPolicyL(readPolicy);
+ if (ret==KErrNone)
+ readPolicyFound=ETrue;
+ else
+ {
+ if (ret==KErrCorrupt || ret==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (ret == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid read policy for range [platsec]",iFullName);
+ }
+#endif
+ return ret;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+ ret=ReadWrPolicyL(writePolicy);
+ if (ret==KErrNone)
+ writePolicyFound=ETrue;
+ else
+ {
+ if (ret==KErrCorrupt || ret==KErrNoMemory)
+ {
+#ifdef CENTREP_TRACE
+ if (ret == KErrCorrupt)
+ {
+ __CENTREP_TRACE1("[%S] Invalid write policy for range [platsec]",iFullName);
+ }
+#endif
+ return ret;
+ }
+ //else if ret!=KErrNone very likely it is KErrNotFound so leave
+ //the state of the writePolicyFound to EFalse
+ }
+ //If only one of the policy is specified,need to set the other one to default value
+ //to prevent it from being uninitialized
+ if(readPolicyFound || writePolicyFound)
+ {
+ if (!readPolicyFound)
+ readPolicy=aDefaultReadPolicy;
+ if (!writePolicyFound)
+ writePolicy=aDefaultWritePolicy;
+ TSettingsAccessPolicy settingsPolicy(readPolicy,writePolicy,
+ lowKey, highKey, mask);
+ aRangePolicies.AppendL(settingsPolicy);
+ }
+ else
+ {
+ // range specified with no policies!
+ __CENTREP_TRACE1("[%S] Range specified with no policies [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ SkipComments();
+ }
+ return KErrNone;
+}
+
+/**
+@internalTechnology
+@return TCapability as converted from string description
+@leave KErrNotFound
+*/
+TInt CIniFileIn::ReadCapabilityL(TCapability& aCapability)
+ {
+ iLex.SkipSpace();
+
+ if(iLex.Eos())
+ User::Leave(KErrNotFound);
+
+ // check if '=' still there and skip
+ SkipEqualSign();
+
+ iLex.Mark();
+
+ // potentially comma separated list of capabilities
+ // we read just one at the time
+ while(!iLex.Peek().IsSpace() && (iLex.Peek() != ',') && !iLex.Eos())
+ {
+ iLex.Inc();
+ if(iLex.TokenLength()>KMaxCapabilityStringLen)
+ {
+ __CENTREP_TRACE1("[%S] Invalid capability [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ }
+
+ TBuf<KMaxCapabilityStringLen> string;
+ string.CopyLC(iLex.MarkedToken());
+
+ // lets check against list of capabilities
+ TInt capability;
+
+ // descriptors...desriptors - we need it for conversion from const char[] to TPtr
+ HBufC *cap = HBufC::NewLC(KMaxCapabilityStringLen);
+ TPtr capPtr = cap->Des() ;
+ HBufC8 *capNarrow = HBufC8::NewLC(KMaxCapabilityStringLen) ;
+ for(capability=0; capability<ECapability_Limit; capability++)
+ {
+ // CapabilityNames is const char[]
+ *capNarrow = (const TUint8 *)CapabilityNames[capability];
+
+ capPtr.Copy(*capNarrow);
+ capPtr.LowerCase();
+ if(0 == string.Compare(capPtr))
+ {
+ aCapability=static_cast<TCapability>(capability);
+ CleanupStack::PopAndDestroy(capNarrow);
+ CleanupStack::PopAndDestroy(cap);
+ return KErrNone;
+ }
+ }
+ CleanupStack::PopAndDestroy(capNarrow);
+ CleanupStack::PopAndDestroy(cap);
+
+ // to satisfy compiler
+ aCapability=ECapability_Limit;
+
+ __CENTREP_TRACE1("[%S] Invalid capability [platsec]",iFullName);
+ // we didn't find anything
+ return KErrCorrupt;
+
+ }
+
+/**
+@internalTechnology
+@param aAlwaysPass will be true if the first capability is AlwaysPass
+ aAlwaysFail will be true if the first capability is AlwaysFail
+*/
+void CIniFileIn::CheckForAlwaysPassOrFailL(TBool& aAlwaysPass,TBool& aAlwaysFail)
+ {
+ iLex.SkipSpace();
+
+ if(iLex.Eos())
+ User::Leave(KErrNotFound);
+
+ // check if '=' still there and skip
+ SkipEqualSign();
+
+ iLex.Mark();
+ // we are just checking if AlwaysPass has been set
+ while(!iLex.Peek().IsSpace() && !iLex.Eos())
+ {
+ iLex.Inc();
+ if(iLex.TokenLength()>KMaxCapabilityStringLen)
+ {
+ iLex.UnGetToMark();
+ return;
+ }
+
+ }
+
+ TBuf<KMaxCapabilityStringLen> string;
+ string.CopyLC(iLex.MarkedToken());
+
+ aAlwaysPass=(string.Compare(KAccessAlwaysPass)==0);
+ aAlwaysFail=(string.Compare(KAccessAlwaysFail)==0);
+ //if not either AlwaysPass or AlwaysFail reset the Lex position to Mark
+ if(!(aAlwaysPass || aAlwaysFail))
+ iLex.UnGetToMark();
+ }
+
+TInt CIniFileIn::ReadCapabilitiesL(TSecurityPolicy& aPolicy)
+ {
+ // we can have 0-7 capabilities
+ const TInt maxCapWithoutSid = 7;
+ TCapability capabilities[maxCapWithoutSid];
+ TInt index = 0;
+ // initialise
+ for(index=0;index<maxCapWithoutSid;index++)
+ capabilities[index] = ECapability_None;
+
+ index = 0;
+
+ // lets read the first capability... there must be at least one!
+ TBool isAlwaysPass=EFalse;
+ TBool isAlwaysFail=EFalse;
+ CheckForAlwaysPassOrFailL(isAlwaysPass,isAlwaysFail);
+ if(isAlwaysPass || isAlwaysFail)
+ {
+ //default is set to EAlwaysFail
+ TSecurityPolicy policy;
+ if (isAlwaysPass)
+ policy=TSecurityPolicy(TSecurityPolicy::EAlwaysPass);
+ aPolicy.Set(policy.Package());
+ }
+ else
+ {
+ TInt r=ReadCapabilityL(capabilities[index]);
+ if(r!=KErrNone)
+ return r;
+
+ // do we have more?
+ iLex.SkipSpace();
+ index++;
+ while((iLex.Peek() == ','))
+ {
+ //if capabilities supplied is more than allowed return KErrCorrupt
+ if (index>=maxCapWithoutSid)
+ {
+ __CENTREP_TRACE1("[%S] Too many read capabilities [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ // skip comma
+ iLex.SkipAndMark(1);
+ r=ReadCapabilityL(capabilities[index]);
+ if(r!=KErrNone)
+ return r;
+ // do we have yet more?
+ iLex.SkipSpace();
+ index++;
+ }
+ TSecurityPolicy policy(static_cast<TCapability>(capabilities[0]),
+ static_cast<TCapability>(capabilities[1]),
+ static_cast<TCapability>(capabilities[2]),
+ static_cast<TCapability>(capabilities[3]),
+ static_cast<TCapability>(capabilities[4]),
+ static_cast<TCapability>(capabilities[5]),
+ static_cast<TCapability>(capabilities[6]));
+ aPolicy.Set(policy.Package());
+ }
+ return KErrNone;
+ }
+
+TInt CIniFileIn::ReadSidAndCapabilitiesL(TSecurityPolicy& aPolicy,const TDesC& aPolicyType,
+ TSecureId& aSid)
+ {
+ //SID was specified we can have 0-3 capabilities
+ const TInt maxCapWithSid = 3;
+
+ TCapability capabilities[maxCapWithSid];
+ TInt index = 0;
+ for(index=0;index<maxCapWithSid;index++)
+ capabilities[index] = ECapability_None;
+
+ // lets see what we have here...
+ iLex.SkipSpaceAndMark();
+
+ // we are looking for a string terminated by '='
+ // up to a certain length....
+ while((iLex.Peek()!='=')&&(!iLex.Eos()))
+ {
+ iLex.Inc();
+
+ if(iLex.TokenLength() >= KMaxAccessTypeLen)
+ {
+ // so no '=' there
+ // not necessarily bad thing... could be space there first
+ break;
+ }
+
+ }
+
+ TBuf<KMaxAccessTypeLen> string;
+ string.CopyLC(iLex.MarkedToken());
+
+ index = 0;
+ // lets check if there are any capabilities specified and if of correct type
+ if(0 == string.Compare(aPolicyType))
+ {
+ //Need to check for AlwaysPass or AlwaysFail
+ TBool isAlwaysPass=EFalse;
+ TBool isAlwaysFail=EFalse;
+ CheckForAlwaysPassOrFailL(isAlwaysPass,isAlwaysFail);
+ if(isAlwaysPass || isAlwaysFail)
+ {
+ //default is set to EAlwaysFail
+ TSecurityPolicy policy;
+ if (isAlwaysPass)
+ policy=TSecurityPolicy(TSecurityPolicy::EAlwaysPass);
+ aPolicy.Set(policy.Package());
+ }
+ else
+ {
+ // so we have some capabilities to read
+ TInt r = ReadCapabilityL(capabilities[index]);
+ if(r!=KErrNone)
+ return r;
+ // do we have more?
+ iLex.SkipSpace();
+ index++;
+ while((iLex.Peek() == ','))
+ {
+ //cannot permit more than 3 capabilities when followed by a SID
+ if (index>=maxCapWithSid)
+ {
+ __CENTREP_TRACE1("[%S] Too many read capabilities [platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ // skip comma
+ iLex.SkipAndMark(1);
+ TInt r= ReadCapabilityL(capabilities[index]);
+ if(r!=KErrNone)
+ return r;
+ // do we have yet more?
+ iLex.SkipSpace();
+ index++;
+ }
+ TSecurityPolicy policy(aSid,static_cast<TCapability>(capabilities[0]),
+ static_cast<TCapability>(capabilities[1]),
+ static_cast<TCapability>(capabilities[2]));
+ aPolicy.Set(policy.Package());
+ }
+ }
+ else
+ {
+ // so no capabilities just SID
+ // and the token wasn't for us either
+ iLex.UnGetToMark();
+ TSecurityPolicy policy(aSid);
+ aPolicy.Set(policy.Package());
+ }
+ return KErrNone;
+ }
+
+
+TInt CIniFileIn::ReadPolicyL(TSecurityPolicy& aPolicy,TInt aPolicyType)
+ {
+
+ // lets check if there a SID is specified
+ iLex.SkipSpaceAndMark();
+
+ if(iLex.Eos())
+ return KErrNotFound;
+
+ while((iLex.Peek()!='=')&&(!iLex.Eos()))
+ {
+ iLex.Inc();
+
+ if(iLex.TokenLength() >= KMaxAccessTypeLen)
+ {
+ // so no '=' there
+ // not necessarily bad thing... could be space there first
+ break;
+ }
+
+ }
+
+ // we are looking for either KReadAccessSid, KReadAccessCap, KWriteAccessSid,KWriteAccessCap
+ TBuf<KMaxAccessTypeLen> accessString;
+ accessString.CopyLC(iLex.MarkedToken());
+ iLex.SkipSpace();
+ TInt returnCode = KErrNotFound;
+ // we expect a combination of sid_rd1 cap_rd1 sid_wr1 cap_wr1
+ if(accessString.Compare(KReadAccessSidString)==0)
+ {
+ // we've got read - either SID or SID+CAP! Are we expecting read?
+ if(KReadPolicy == aPolicyType)
+ {
+ TUint32 sid;
+ SkipEqualSign();
+ if (ReadNumber(sid) != KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid SID (read)[platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ TSecureId sidId(sid);
+ // so we read sid and now we expect cap_rd1=cap1,cap2,..
+ // lets assume it's a SID+CAP for now
+ returnCode= ReadSidAndCapabilitiesL(aPolicy,KReadAccessCapString,sidId);
+ }
+ }
+ else if(accessString.Compare(KReadAccessCapString)==0)
+ {
+ // we've got read CAP only! Are we expecting read?
+ if(KReadPolicy == aPolicyType)
+ {
+ returnCode=ReadCapabilitiesL(aPolicy);
+ }
+ }
+ else if(accessString.Compare(KWriteAccessSidString)==0)
+ {
+ // we've got write - either SID or SID+CAP! Are we expecting read?
+ if(KWritePolicy == aPolicyType)
+ {
+ TUint32 sid;
+ SkipEqualSign();
+ if(ReadNumber(sid)!=KErrNone)
+ {
+ __CENTREP_TRACE1("[%S] Invalid SID (write)[platsec]",iFullName);
+ return KErrCorrupt;
+ }
+ TSecureId sidId(sid);
+ // lets assume SID+CAP for now
+ returnCode= ReadSidAndCapabilitiesL(aPolicy,KWriteAccessCapString,sidId);
+ }
+ }
+ else if(accessString.Compare(KWriteAccessCapString)==0)
+ {
+ // we've got write CAP only! Are we expecting write?
+ if(KWritePolicy == aPolicyType)
+ {
+ returnCode=ReadCapabilitiesL(aPolicy);
+ }
+ }
+ if(KErrNone != returnCode)
+ iLex.UnGetToMark();
+
+ return returnCode;
+ }
+
+TInt CIniFileIn::ReadRdPolicyL(TSecurityPolicy& aReadPolicy)
+ {
+ return ReadPolicyL(aReadPolicy,KReadPolicy);
+ }
+
+TInt CIniFileIn::ReadWrPolicyL(TSecurityPolicy& aReadPolicy)
+ {
+ return ReadPolicyL(aReadPolicy,KWritePolicy);
+ }
+
+TInt CIniFileIn::ReadStringL(HBufC8*& aString)
+ {
+ iLex.Mark();
+
+ TChar c = iLex.Peek();
+ TChar quote = 0;
+ if(c=='\'' || c=='\"')
+ {
+ iLex.SkipAndMark(1);
+ quote = c;
+ }
+
+ TBool complete = EFalse;
+
+ TInt len;
+ for(len=0;!iLex.Eos();len++)
+ {
+ c = iLex.Get();
+
+ if(quote ? c==quote : c.IsSpace())
+ {
+ complete = ETrue;
+ break;
+ }
+
+ if(c=='\\')
+ iLex.Get();
+ }
+
+ if(!complete || len>KMaxUnicodeStringLength)
+ return KErrCorrupt;
+
+ aString = HBufC8::NewL(len*2);
+ TPtr8 ptr8 = aString->Des();
+ ptr8.SetLength(len*2);
+ TPtr16 ptr16((TUint16*)ptr8.Ptr(), len, len);
+
+
+ iLex.UnGetToMark();
+
+ _LIT(KSpecialChars, "abfnrvt0");
+ static TUint8 specialChars[] = { '\a', '\b', '\f', '\n', '\r', '\v', '\t', '\0' };
+ for(TInt i=0;i<len;i++)
+ {
+ c = iLex.Get();
+
+ if(c=='\\')
+ {
+ c = iLex.Get();
+ TInt i = KSpecialChars().Locate(c);
+ if(i>=0)
+ c = specialChars[i];
+ }
+
+ ptr16[i] = (TUint16)c;
+
+ }
+
+ if(quote)
+ iLex.Inc(); // trailing quote
+
+ return KErrNone;
+ }
+
+
+
+TInt CIniFileIn::ReadString16To8L(HBufC8*& aString)
+ {
+ iLex.Mark();
+
+ TChar c = iLex.Peek();
+ TChar quote = 0;
+ if(c=='\'' || c=='\"')
+ {
+ iLex.SkipAndMark(1);
+ quote = c;
+ }
+
+ TBool complete = EFalse;
+
+ TInt len;
+ for(len=0;!iLex.Eos();len++)
+ {
+ c = iLex.Get();
+
+ if(quote ? c==quote : c.IsSpace())
+ {
+ complete = ETrue;
+ break;
+ }
+
+ if(c=='\\')
+ iLex.Get();
+ }
+
+ if(!complete || len>KMaxUnicodeStringLength)
+ return KErrCorrupt;
+
+ aString = HBufC8::NewLC(len*2);
+
+ HBufC16* tempBuffer = HBufC16::NewLC(len);
+
+ TPtr16 ptr16 = tempBuffer->Des();
+ TPtr8 ptr8 = aString->Des();
+ ptr8.SetLength(len*2);
+
+
+
+ iLex.UnGetToMark();
+
+ _LIT(KSpecialChars, "abfnrvt0");
+ static TUint8 specialChars[] = { '\a', '\b', '\f', '\n', '\r', '\v', '\t', '\0' };
+ for(TInt i=0;i<len;i++)
+ {
+ c = iLex.Get();
+
+ if(c=='\\')
+ {
+ c = iLex.Get();
+ TInt i = KSpecialChars().Locate(c);
+ if(i>=0)
+ c = specialChars[i];
+ }
+
+ ptr16.Append(c);
+
+ }
+
+ const TInt returnValue = CnvUtfConverter::ConvertFromUnicodeToUtf8(ptr8, ptr16);
+ if (returnValue==CnvUtfConverter::EErrorIllFormedInput)
+ {
+ CleanupStack::PopAndDestroy(tempBuffer);
+ CleanupStack::PopAndDestroy(aString);
+ return KErrCorrupt;
+ }
+ else if(returnValue<0)
+ User::Leave(KErrGeneral);
+
+ CleanupStack::PopAndDestroy(tempBuffer);
+ CleanupStack::Pop(aString);
+
+ if(quote)
+ iLex.Inc(); // trailing quote
+
+ return KErrNone;
+ }
+
+TInt CIniFileIn::ReadBinaryL(HBufC8*& aString)
+ {
+ iLex.Mark();
+ iLex.SkipCharacters();
+ TInt len = iLex.TokenLength();
+ iLex.UnGetToMark();
+
+ if(len==1 && iLex.Peek()==KNullDataIndicator)
+ {
+ iLex.Get();
+ aString = HBufC8::NewL(0);
+ TPtr8 ptr8 = aString->Des();
+ ptr8.SetLength(0);
+ return KErrNone;
+ }
+
+ if(len>KMaxBinaryLength*2 || len%2)
+ {
+ delete aString;
+ return KErrCorrupt;
+ }
+
+ len /= 2;
+ aString = HBufC8::NewL(len);
+ TPtr8 ptr8 = aString->Des();
+ ptr8.SetLength(len);
+
+ TBuf<2> buf(2);
+ for(TInt i=0;i<len;i++)
+ {
+ buf[0] = (TUint8)iLex.Get();
+ buf[1] = (TUint8)iLex.Get();
+ TLex lex(buf);
+ if(lex.Val(ptr8[i], EHex)!=KErrNone)
+ {
+ delete aString;
+ return KErrCorrupt;
+ }
+ }
+ return KErrNone;
+ }
+
+TInt CIniFileIn::ReadNumber(TUint32& aVal)
+ {
+ iLex.SkipSpace();
+
+ if(iLex.Eos())
+ return KErrNotFound;
+
+ TRadix radix = EDecimal;
+ if(iLex.Peek()=='0')
+ {
+ iLex.Inc();
+ if(iLex.Peek().GetLowerCase()=='x')
+ {
+ iLex.Inc();
+ radix = EHex;
+ }
+ else
+ iLex.UnGet();
+ }
+
+ return iLex.Val(aVal, radix);
+ }
+
+
+TInt CIniFileIn::GetOwnerSectionLC(HBufC*& aSection)
+ {
+ return( GetSectionLC(KOwnerSection(), aSection));
+ }
+
+TInt CIniFileIn::GetDefaultMetaSectionLC(HBufC*& aSection)
+ {
+ return( GetSectionLC(KDefaultMetaSection(), aSection));
+ }
+
+TInt CIniFileIn::GetTimeStampSectionLC(HBufC*& aSection)
+ {
+ return( GetSectionLC(KTimeStampSection(), aSection));
+ }
+
+TInt CIniFileIn::GetPlatSecSectionLC(HBufC*& aSection)
+ {
+ return( GetSectionLC(KPlatSecSection(), aSection));
+ }
+
+TInt CIniFileIn::GetSectionLC(const TDesC16& aSectionId, HBufC*& aSection)
+ {
+ TBuf<KBufLen> buf;
+ TLexMark sectionMark;
+ aSection=NULL;
+
+ SkipComments();
+
+ iLex.Mark(sectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if( (iLex.TokenLength() != aSectionId.Length()) &&
+ (buf.CopyLC(iLex.MarkedToken()), buf.Compare( aSectionId )!=0) )
+ {
+ // Expected section not found at this point in the file
+ // Note that this is not an error
+ iLex.UnGetToMark();
+ return KErrNone;
+ }
+
+ //
+ // Read in the section by grabbing text until we reach
+ // the start of another section.
+ //
+ while(!iLex.Eos())
+ {
+ // Wait for any other section marker
+ SkipComments();
+
+ iLex.Mark();
+
+ iLex.SkipCharacters();
+
+ if(iLex.TokenLength() <= KBufLen)
+ {
+ buf.CopyLC(iLex.MarkedToken());
+ if((buf.Compare(KMainSection) == 0) ||
+ (buf.Compare(KOwnerSection) == 0) ||
+ (buf.Compare(KPlatSecSection) == 0) ||
+ (buf.Compare(KTimeStampSection) == 0) ||
+ (buf.Compare(KDefaultMetaSection) == 0))
+ {
+ iLex.Mark(iMainSectionMark);
+ iLex.UnGetToMark() ;
+ TPtrC lex = iLex.MarkedToken(sectionMark);
+ HBufC* section = HBufC::NewMaxLC(lex.Length()); //'\n'
+ TPtr ptr = section->Des();
+ ptr.Copy(lex);
+ aSection=section;
+ return KErrNone;
+ }
+ }
+ }
+ return KErrCorrupt;
+ }
+
+TInt CIniFileIn::FindMainSectionL(void)
+ {
+ TBuf<KBufLen> buf;
+
+ //
+ // Check if a Main section is present
+ //
+
+ SkipComments();
+
+ // we will need this section later to write the out file...
+ iLex.Mark(iMainSectionMark);
+
+ iLex.Mark();
+ iLex.SkipCharacters();
+
+ if( iLex.TokenLength()!=KMainSectionLen ||
+ (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KMainSection )!=0) )
+ {
+ // Meta not available
+ iLex.UnGetToMark();
+ return KErrNotFound;
+ }
+
+ iLex.Mark(iMainSectionMark);
+ return KErrNone ;
+ }
+
+#ifdef CENTREP_TRACE
+HBufC* CIniFileIn::FullName()
+ {
+ return(iFullName);
+ }
+#endif
+
+#ifdef CENTREP_CONV_TOOL
+//===================================================================
+// TCompiledSecurityPolicy class
+// Used for accessing private data members of TSecurityPolicy. It
+// uses the fact that TSecurityPolicy class has a friend whose name
+// is TCompiledSecurityPolicy.
+// See dbms/tdbms/securitypolicy.h for similar strategy.
+//
+
+// The longest possible security string is one that has 7 capabilities.
+static const TInt KSecPolicyStrSize = KMaxCapabilityStringLen * 7 + 10;
+
+class TCompiledSecurityPolicy
+ {
+public:
+ TCompiledSecurityPolicy(const TSecurityPolicy& aSecurityPolicy) :
+ iSecurityPolicy(aSecurityPolicy) { }
+ const TDesC& TextualizePolicyL(TCapAccessMode aMode);
+
+private:
+ enum THeaderType
+ {
+ EHdrSecureId,
+ EHdrCapability
+ };
+
+ TCapability CapabilityAt(TInt aIndex) const;
+ void DoCapabilitySection(TInt aMaxNumCaps);
+ void AppendModeHeader(TCapAccessMode aAccessMode, THeaderType aType);
+
+private:
+ const TSecurityPolicy& iSecurityPolicy;
+ TBuf<KSecPolicyStrSize> iBuf;
+ };
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// CIniFileOut class
+/**
+Standard, phase-one CIniFileOut instance creation method.
+The created CIniFileOut instance will use a temporary text file to store the repository settings.
+CIniFileOut::CommitL() should be called at the end to finalize the changes.
+@return A pointer to a fully constructed CIniFileOut instance.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CIniFileOut* CIniFileOut::NewLC(RFs& aFs,const TDesC& aOutFileName)
+ {
+ CIniFileOut* inifile = new(ELeave) CIniFileOut(aFs);
+ CleanupStack::PushL(inifile);
+ inifile->ConstructL(aOutFileName);
+ return inifile;
+ }
+
+CIniFileOut::CIniFileOut(RFs& aFs)
+ : iCommited(EFalse), iTransFileBuf(4 * 1024),iFs(aFs)// 4K buffer size
+ {
+ }
+
+/**
+Standard, phase-two CIniFileOut instance creation method.
+Creates the transaction file.
+Initializes transaction file buffer - iTransFileBuf instance.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+void CIniFileOut::ConstructL(const TDesC& aOutFileName)
+ {
+ iOutFileName=aOutFileName.AllocL();
+ _LIT(KTmpExtension,"tmp");
+ User::LeaveIfError(iTransFilePath.Set(aOutFileName, NULL, &(KTmpExtension())));
+ User::LeaveIfError(iTransFile.Replace(iFs, iTransFilePath.FullName(), EFileWrite | EFileStreamText));
+ iTransFileBuf.Attach(iTransFile, 0);
+ }
+
+/**
+Closes and deletes the transaction file.
+If CIniFileOut::CommitL() has not been called prior the destructor call, all the changes
+will be lost.
+*/
+CIniFileOut::~CIniFileOut()
+ {
+ if (!iCommited)
+ {
+ iTransFileBuf.Close();
+ // If a debug build - record error
+ TInt fileDeleteErr=iFs.Delete(iTransFilePath.FullName());
+ #ifdef _DEBUG
+ if (fileDeleteErr != KErrNone)
+ {
+ RDebug::Print(_L("CIniFileOut::~CIniFileOut - Failed to delete file. Error = %d"), fileDeleteErr);
+ }
+ #else
+ (void)fileDeleteErr;
+ #endif
+
+ }
+ delete iOutFileName;
+ }
+
+/**
+The method writes supplied setting value to the output file.
+@param aSetting Setting instance, which value has to be written to the output file.
+@param accessPolicies A string descriptor, referencing related to aSetting access policies.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+void CIniFileOut::WriteSettingL(const TServerSetting& aSetting
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ ,TUint32 aCreVersion
+#endif
+ )
+ {
+ iBuf.Zero();
+ DoSettingL(aSetting
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ ,aCreVersion
+#endif
+ );
+ WriteLineL(iBuf);
+ }
+
+void CIniFileOut::WriteSettingL(const TServerSetting& aSetting,
+ const TSettingsAccessPolicy& aAccessPolicy
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ ,TUint32 aCreVersion
+#endif
+ )
+ {
+ iBuf.Zero();
+ DoSettingL(aSetting
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ ,aCreVersion
+#endif
+ );
+ iBuf.Append(KSpace);
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ if (aCreVersion<2 || (aCreVersion>=2 && aAccessPolicy.iHighKey!=0))
+#endif
+ AppendSecurityPolicyL(aAccessPolicy.iReadAccessPolicy, ECapReadAccess);
+ iBuf.Append(KSpace);
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ if (aCreVersion<2 || (aCreVersion>=2 && aAccessPolicy.iKeyMask!=0))
+#endif
+ AppendSecurityPolicyL(aAccessPolicy.iWriteAccessPolicy, ECapWriteAccess);
+ WriteLineL(iBuf);
+ }
+
+void CIniFileOut::DoSettingL(const TServerSetting& aSetting
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ ,TUint32 aCreVersion
+#endif
+ )
+ {
+ iBuf.AppendNum(aSetting.Key(), EDecimal);
+ iBuf.Append(KSpace);
+
+ ::AddSettingValueL(iBuf, aSetting);
+
+ iBuf.Append(KSpace);
+
+ if (!aSetting.Meta())
+ {
+ iBuf.AppendNum(0, EDecimal);
+ }
+ else
+ {
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ //need to check on the CRE Version too
+ TBool isClean=const_cast<TServerSetting&>(aSetting).IsClean();
+ if (aCreVersion<2 || (aCreVersion>=2 && (aSetting.IsIndividualMeta() || (!aSetting.IsIndividualMeta() && isClean ))))
+ {
+ TUint32 metaToWrite=aSetting.Meta();
+ //special case
+ if (aCreVersion>=2 && isClean && aSetting.IsIndividualMeta())
+ {
+ metaToWrite|=KMetaIndividual;
+ }
+ iBuf.AppendFormat(KHexIntFormat, metaToWrite);
+ }
+#else
+ iBuf.AppendFormat(KHexIntFormat, aSetting.Meta());
+#endif
+ }
+ }
+
+/**
+The method commits settings file changes.
+If the commit operation fails, the existing settings file will stay unchanged.
+@leave System-wide error codes.
+*/
+void CIniFileOut::CommitL()
+ {
+ iTransFileBuf.SynchL();
+ iTransFileBuf.Close();
+
+ User::LeaveIfError(iFs.Replace(iTransFilePath.FullName(),*iOutFileName));
+
+ iCommited = ETrue;
+ }
+
+void CIniFileOut::WriteMainSectionHeaderL()
+ {
+ WriteLineL(KMainSection());
+ }
+
+/**
+Writes a text line to the repository file.
+@param aData The string which will be written to the file as a single text line
+@leave System-wide error codes
+*/
+void CIniFileOut::WriteLineL(const TDesC& aData)
+ {
+ iTransFileBuf.WriteL(reinterpret_cast <const TUint8*> (aData.Ptr()), aData.Size());
+ iTransFileBuf.WriteL(reinterpret_cast <const TUint8*> (KCrNl().Ptr()), KCrNl().Size());
+ }
+
+/**
+Writes repository file header.
+@leave System-wide error codes
+*/
+void CIniFileOut::WriteHeaderL()
+ {
+ TBuf<64> buf;
+
+ buf.Append(KUcs2Bom);
+ buf.Append(KSignature);
+ WriteLineL(buf);
+
+ buf.Zero();
+ buf.Append(KVersion);
+ buf.Append(KSpace);
+ buf.AppendNum(KCurrentVersion);
+ buf.Append(KCrNl);
+ WriteLineL(buf);
+ }
+
+/**
+Writes owner section to repository file.
+*/
+void CIniFileOut::WriteOwnerSectionL(TUid aOwner)
+ {
+ if (aOwner.iUid != 0)
+ {
+ WriteLineL(KOwnerSection());
+ TBuf<32> buf;
+ buf.Format(KUidFormat, aOwner.iUid);
+ buf.Append(KCrNl);
+ WriteLineL(buf);
+ }
+ }
+
+/**
+Writes time stamp to repository file.
+@param aTime Time stamp
+@leave System-wide error codes
+*/
+void CIniFileOut::WriteTimeStampL(const TTime& aTime)
+ {
+ if(aTime.Int64() != 0)
+ {
+ WriteLineL(KTimeStampSection());
+ TBuf<32> buf;
+ buf.Num(aTime.Int64());
+ buf.Append(KCrNl);
+ WriteLineL(buf);
+ }
+ }
+
+/**
+Writes meta data to repository file.
+@param aFileIn Input repository file
+@leave System-wide error codes
+*/
+void CIniFileOut::WriteMetaDataL(TUint32 aDefaultMeta,
+ const RDefaultMetaArray& aDefaultMetaRanges)
+ {
+ if (!aDefaultMeta && !aDefaultMetaRanges.Count())
+ {
+ return;
+ }
+
+ WriteLineL(KDefaultMetaSection);
+
+ if (aDefaultMeta)
+ {
+ iBuf.Format(KHexIntFormat, aDefaultMeta);
+ WriteLineL(iBuf);
+ }
+
+ for (TInt i = 0; i<aDefaultMetaRanges.Count(); i++)
+ {
+ const TSettingsDefaultMeta& entry = aDefaultMetaRanges[i];
+ if (entry.HighKey())
+ {
+ iBuf.Format(KRangeMetaFmt, entry.LowKey(), entry.HighKey(),
+ entry.GetDefaultMetadata());
+ }
+ else
+ {
+ iBuf.Format(KMaskMetaFmt, entry.LowKey(), entry.KeyMask(),
+ entry.GetDefaultMetadata());
+ }
+ WriteLineL(iBuf);
+ }
+
+ WriteLineL(KCrNl());
+ }
+
+/**
+Writes platsec info to repository file.
+@param aFileIn Input repository file
+@leave System-wide error codes
+*/
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+void CIniFileOut::WritePlatSecL(const TSettingsAccessPolicy& aDefaultAccessPolicy,
+ const RRangePolicyArray& aRangePolicies,TUint32 aCreVersion)
+#else
+void CIniFileOut::WritePlatSecL(const TSecurityPolicy& aDefaultReadPolicy,
+ const TSecurityPolicy& aDefaultWritePolicy,
+ const RRangePolicyArray& aRangePolicies)
+#endif
+ {
+ WriteLineL(KPlatSecSection);
+
+ iBuf.Zero();
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
+ if (aCreVersion<2 || (aCreVersion>=2 && aDefaultAccessPolicy.iHighKey!=0))
+ AppendSecurityPolicyL(*(aDefaultAccessPolicy.GetReadAccessPolicy()), ECapReadAccess);
+ iBuf.Append(KSpace);
+ if (aCreVersion<2 || (aCreVersion>=2 && aDefaultAccessPolicy.iKeyMask!=0))
+ AppendSecurityPolicyL(*(aDefaultAccessPolicy.GetWriteAccessPolicy()), ECapWriteAccess);
+#else
+ AppendSecurityPolicyL(aDefaultReadPolicy, ECapReadAccess);
+ iBuf.Append(KSpace);
+ AppendSecurityPolicyL(aDefaultWritePolicy, ECapWriteAccess);
+#endif
+ WriteLineL(iBuf);
+
+ for(TInt i=0; i < aRangePolicies.Count(); i++)
+ {
+ const TSettingsAccessPolicy& e = aRangePolicies[i];
+ if (e.iHighKey != 0)
+ {
+ iBuf.Format(KRangePrefix, e.iLowKey, e.iHighKey);
+ }
+ else
+ {
+ iBuf.Format(KMaskPrefix, e.iLowKey, e.iKeyMask);
+ }
+
+ iBuf.Append(KSpace);
+
+ AppendSecurityPolicyL(e.iReadAccessPolicy, ECapReadAccess);
+ iBuf.Append(KSpace);
+ AppendSecurityPolicyL(e.iWriteAccessPolicy, ECapWriteAccess);
+ WriteLineL(iBuf);
+ }
+
+ WriteLineL(KCrNl());
+ }
+
+void CIniFileOut::AppendSecurityPolicyL(const TSecurityPolicy& aPolicy,
+ TCapAccessMode aRdWrMode)
+ {
+ TCompiledSecurityPolicy policy(aPolicy);
+ iBuf.Append(policy.TextualizePolicyL(aRdWrMode));
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+const TDesC& TCompiledSecurityPolicy::TextualizePolicyL(TCapAccessMode aMode)
+ {
+ iBuf.Zero();
+ AppendModeHeader(aMode, EHdrCapability);
+
+ switch (static_cast<TSecurityPolicy::TType>(iSecurityPolicy.iType))
+ {
+ case TSecurityPolicy::ETypeFail:
+ iBuf.Append(KAccessAlwaysFail);
+ break;
+ case TSecurityPolicy::ETypePass:
+ iBuf.Append(KAccessAlwaysPass);
+ break;
+ case TSecurityPolicy::ETypeC3:
+ DoCapabilitySection(3);
+ break;
+ case TSecurityPolicy::ETypeC7:
+ DoCapabilitySection(7);
+ break;
+ case TSecurityPolicy::ETypeS3:
+ iBuf.Zero(); // erase the "cap_rd", replace with sid_rd
+ AppendModeHeader(aMode, EHdrSecureId);
+ iBuf.AppendNum(iSecurityPolicy.iSecureId);
+
+ if (ECapability_HardLimit != iSecurityPolicy.iCaps[0])
+ {
+ iBuf.Append(KSpace);
+ AppendModeHeader(aMode, EHdrCapability);
+ DoCapabilitySection(3);
+ }
+ break;
+
+ default:
+ User::Leave(KErrCorrupt);
+ } // switch
+
+ return iBuf;
+ }
+
+TCapability TCompiledSecurityPolicy::CapabilityAt(TInt aIndex) const
+ {
+ if (aIndex < 3)
+ {
+ return static_cast <TCapability> (iSecurityPolicy.iCaps[aIndex]);
+ }
+ else if(aIndex < 7)
+ {
+ return static_cast <TCapability> (iSecurityPolicy.iExtraCaps[aIndex - 3]);
+ }
+ return ECapability_None;
+ }
+
+//
+void TCompiledSecurityPolicy::DoCapabilitySection(TInt aMaxNumCaps)
+ {
+ for (TInt i = 0; i < aMaxNumCaps; i++)
+ {
+ TCapability cap = CapabilityAt(i);
+
+ if (cap<0 || cap>= ECapability_Limit)
+ {
+ return;
+ }
+ if (i > 0)
+ {
+ iBuf.Append(',');
+ }
+
+ for (const char* p=CapabilityNames[cap]; *p; p++)
+ {
+ iBuf.Append((TUint16)*p);
+ }
+ } // for i
+ }
+
+void TCompiledSecurityPolicy::AppendModeHeader(TCapAccessMode aAccessMode,
+ THeaderType aType)
+ {
+ if (aAccessMode == ECapReadAccess)
+ {
+ if (aType == EHdrSecureId)
+ {
+ iBuf.Append(KReadAccessSidString); // "sid_rd"
+ }
+ else
+ {
+ iBuf.Append(KReadAccessCapString); // "cap_rd"
+ }
+ }
+ else
+ {
+ if (aType == EHdrSecureId)
+ {
+ iBuf.Append(KWriteAccessSidString); // "sid_wr"
+ }
+ else
+ {
+ iBuf.Append(KWriteAccessCapString); // "cap_wr"
+ }
+ }
+ iBuf.Append('=');
+ }
+#endif //CENTREP_CONV_TOOL