diff -r 000000000000 -r 2c201484c85f cryptoservices/filebasedcertificateandkeystores/test/keytool/keytool_utils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/filebasedcertificateandkeystores/test/keytool/keytool_utils.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,885 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#include +#include + +#include "keytool_utils.h" +#include "securityerr.h" +#include "compiledsecuritypolicy.h" + +_LIT(space, " "); + +_LIT(newline, "\n"); + +_LIT(KExtractable, "Extractable"); +_LIT(KSensitive, "Sensitive"); +_LIT(KAlwaysSensitive, "AlwaysSensitive"); +_LIT(KNeverExtractable, "NeverExtractable"); +_LIT(KLocal, "Local"); +_LIT(KEllipsis, "..."); + +_LIT(x509, "X509"); +_LIT(allusage, "AllUsage"); +_LIT(nousage, "NoUsage"); +_LIT(encrypt, "Encrypt"); +_LIT(decrypt, "Decrypt"); +_LIT(sign, "Sign"); +_LIT(signrecover, "SignRecover"); +_LIT(wrap, "Wrap"); +_LIT(unwrap, "Unwrap"); +_LIT(verify, "Verify"); +_LIT(verifyrecover, "VerifyRecover"); +_LIT(derive, "Derive"); +_LIT(nonrepudiation, "NonRepudiation"); + +const TInt KCursorOffset = 2; +static const TInt KMaxLabel = 32; +CConsoleBase* KeyToolUtils::iConsole = NULL; +RFile* KeyToolUtils::iFile = NULL; + +/*static*/ void KeyToolUtils::WriteErrorL(TInt aError) + { + + if ((aError <= -12000) && (aError >= -12100)) + { + PrintInfoL(_L("You have tsecdlg.dll in z:\\system\\notifiers.")); + PrintInfoL(_L("This notifier is for *testing only* please remove it and try again!")); + return; + } + + switch (aError) + { + case KErrNone: // 0 + PrintInfoL(_L("KErrNone")); + break; + + case KErrNotFound: // -1 + PrintInfoL(_L("KErrNotFound")); + break; + + case KErrNotSupported: // -5 + PrintInfoL(_L("KErrNotSupported")); + break; + + case KErrInUse: // -14 + PrintInfoL(_L("KErrInUse")); + break; + + case KErrNotReady: // -18 + PrintInfoL(_L("KErrNotReady")); + break; + + case KErrKeyAlgorithm: //-11006 + PrintInfoL(_L("KErrKeyAlgorithm")); + break; + + case KErrKeyUsage: //-11007 + PrintInfoL(_L("KErrKeyUsage")); + break; + + case KErrKeyValidity: //-11008 + PrintInfoL(_L("KErrKeyValidity")); + break; + + case KErrKeySize: //-11009 + PrintInfoL(_L("KErrKeySize")); + break; + + case KErrKeyAccess: //-11010 + PrintInfoL(_L("KErrKeyAccess")); + break; + + case KRequestPending: + PrintInfoL(_L("KRequestPending")); + break; + + case KErrAlreadyExists: + PrintInfoL(_L("KErrAlreadyExists")); + break; + + case KErrArgument: + PrintInfoL(_L("KErrArgument")); + break; + + case KErrBadName: // -28 + PrintInfoL(_L("KErrBadName")); + break; + + case KErrCorrupt: // -20 + PrintInfoL(_L("KErrCorrupt")); + break; + case KErrPrivateKeyNotFound: //-11011 + PrintInfoL(_L("KErrPrivateKeyNotFound")); + break; + + default: + { + TBuf<64> msg; + msg.Format(_L("Unknown (Code %d)"), aError); + PrintInfoL(msg); + } + break; + } + } + +/*static*/ void KeyToolUtils::WriteOctetStringL(const TDesC8& aString) + { + TInt index; + TInt counter; + counter = aString.Length(); + HBufC* buf = HBufC::NewLC(counter*6); + TPtr pBuf = buf->Des(); + for (index = 0; index < counter; index++) + { + pBuf.AppendFormat(_L("%01x"),aString[index]>>4); + pBuf.AppendFormat(_L("%01x"),aString[index]&0xf); + pBuf.Append(_L(" ")); + } + PrintInfoL(pBuf); + CleanupStack::PopAndDestroy();//buf + } + + +/*static*/ void KeyToolUtils::PrintUsageL(TUint aUsage) + { + PrintInfoL(_L("\t\tUsage : ")); + if (aUsage & 0x0000ffff) // In this range we are talking PKCS15 + { + PrintInfoL(_L("PKCS15 ")); + } + if (aUsage & 0xffff0000) // In this range we are talking X509 + { + PrintInfoL(x509); + } + if (aUsage == (TUint)EPKCS15UsageAll) + { + PrintInfoL(allusage); + return; + } + if (aUsage == EPKCS15UsageNone) + { + PrintInfoL(nousage); + return; + } + if (aUsage & EPKCS15UsageEncrypt) + { + PrintInfoL(encrypt); + } + if (aUsage & EPKCS15UsageDecrypt) + { + PrintInfoL(decrypt); + } + if (aUsage & EPKCS15UsageSign) + { + PrintInfoL(sign); + } + if (aUsage & EPKCS15UsageSignRecover) + { + PrintInfoL(signrecover); + } + if (aUsage & EPKCS15UsageWrap) + { + PrintInfoL(wrap); + } + if (aUsage & EPKCS15UsageUnwrap) + { + PrintInfoL(unwrap); + } + if (aUsage & EPKCS15UsageVerify) + { + PrintInfoL(verify); + } + if (aUsage & EPKCS15UsageVerifyRecover) + { + PrintInfoL(verifyrecover); + } + if (aUsage & EPKCS15UsageDerive) + { + PrintInfoL(derive); + } + if (aUsage & EPKCS15UsageNonRepudiation) + { + PrintInfoL(nonrepudiation); + } + if (aUsage & (TUint)EX509UsageDigitalSignature) + { + PrintInfoL(_L("DigitalSignature ")); + } + if (aUsage & EX509UsageNonRepudiation) + { + PrintInfoL(_L("NonRepudiation ")); + } + if (aUsage & EX509UsageKeyEncipherment) + { + PrintInfoL(_L("KeyEncipherment ")); + } + if (aUsage & EX509UsageDataEncipherment ) + { + PrintInfoL(_L("DataEncipherment ")); + } + if (aUsage & EX509UsageKeyAgreement ) + { + PrintInfoL(_L("KeyAgreement ")); + } + if (aUsage & EX509UsageKeyCertSign ) + { + PrintInfoL(_L("KeyCertSign ")); + } + if (aUsage & EX509UsageCRLSign ) + { + PrintInfoL(_L("CRLSign ")); + } + if (aUsage & EX509UsageEncipherOnly ) + { + PrintInfoL(_L("EncipherOnly ")); + } + if (aUsage & EX509UsageDecipherOnly) + { + PrintInfoL(_L("DecipherOnly ")); + } + + TBuf<32> buf; + _LIT(KKeyUsage, "\tCode: 0x%x "); + buf.Format(KKeyUsage, aUsage); + PrintInfoL(buf); + PrintInfoL(newline); + } + + +/*static*/ HBufC* KeyToolUtils::KeyAccessDesLC(TInt aAccess) + { + TBuf<128> access; + + if (aAccess & CCTKeyInfo::ESensitive) + { + access.Append(KSensitive); + access.Append(space); + } + + if (aAccess & CCTKeyInfo::EExtractable) + { + access.Append(KExtractable); + access.Append(space); + } + + if (aAccess & CCTKeyInfo::EAlwaysSensitive) + { + access.Append(KAlwaysSensitive); + access.Append(space); + } + + if (aAccess & CCTKeyInfo::ENeverExtractable) + { + access.Append(KNeverExtractable); + access.Append(space); + } + + if (aAccess & CCTKeyInfo::ELocal) + { + access.Append(KLocal); + access.Append(space); + } + return access.AllocLC(); + } + + +/*static*/ HBufC* KeyToolUtils::AlgorithmDesLC(CCTKeyInfo::EKeyAlgorithm aAlgorithm) + { + TBuf<32> alg; + + switch (aAlgorithm) + { + case CCTKeyInfo::EInvalidAlgorithm: + { + alg = _L("Invalid Algorithm"); + } + break; + case CCTKeyInfo::ERSA: + { + alg = _L("RSA"); + } + break; + case CCTKeyInfo::EDSA: + { + alg = _L("DSA"); + } + break; + case CCTKeyInfo::EDH : + { + alg = _L("Diffie Hellman"); + } + break; + default: + { + alg = _L("Unsupported algorithm!"); + } + } + return alg.AllocLC(); + } + + + +/*static*/ void KeyToolUtils::PrintKeyInfoL(const CCTKeyInfo& aKey, TBool aIsDetailed,TBool aPageWise) + { + HBufC* alg = KeyToolUtils::AlgorithmDesLC(aKey.Algorithm()); + TFileName buf; + + MCTToken& token = aKey.Token(); + TFileName msg,msg1; + const TDesC& tmp = token.Label(); + msg.Format(_L("Store Label: %S"), &tmp); + + const TDesC& tmp1 = token.Information(MCTToken::EVersion); + const TDesC& tmp2 = token.Information(MCTToken::ESerialNo); + const TDesC& tmp3 = token.Information(MCTToken::EManufacturer); + + msg1.Format(_L("Version: %S \t Serial Number: %S \t Manufacturer: %S Store Type: Read only"), &tmp1, &tmp2, &tmp3); + + if (!aIsDetailed) + { + PrintInfoL(msg, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(aKey.Label().Left(KMaxLabel)); + if (aKey.Label().Length() > KMaxLabel) + { + PrintInfoL(KEllipsis); + } + PrintInfoL(_L(" is a ")); + _LIT(KKeySizeShort, "%d"); + buf.Format(KKeySizeShort, aKey.Size()); + PrintInfoL(buf); + PrintInfoL(_L(" bits ")); + PrintInfoL(*alg); + PrintInfoL(_L(" key ")); + CleanupStack::PopAndDestroy(alg); + PrintInfoL(newline, aPageWise); + return; + } + + PrintInfoL(msg, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(msg1, aPageWise); + PrintInfoL(newline, aPageWise); + + PrintInfoL(_L("\t\tAlgorithm: ")); + PrintInfoL(*alg); + CleanupStack::PopAndDestroy(alg); + + _LIT(KKeySize, "\tSize: %d "); + buf.Format(KKeySize, aKey.Size()); + PrintInfoL(buf); + PrintInfoL(_L(" bits")); + PrintInfoL(newline, aPageWise); + + KeyToolUtils::PrintUsageL(aKey.Usage()); + + _LIT(KKeyOwner, "\t\tOwner : 0x%x "); + _LIT(KKeyUser, "\t\tUser : 0x%x "); + TCompiledSecurityPolicy managementPolicy = aKey.ManagementPolicy(); + TCompiledSecurityPolicy usePolicy = aKey.UsePolicy(); + + TUint32 mSecureid = managementPolicy.SecureId(); + if (mSecureid == 0xffffffff) + { + TCapability cab = managementPolicy.Capability(0); + _LIT(KKeyOwnerCab, "\t\tOwner : %S "); + // currently only possible for keyowner other than secure id. + if (cab == ECapabilityWriteDeviceData) + { + _LIT(KCab, "WriteDeviceData"); + buf.Format(KKeyOwnerCab, &KCab); + PrintInfoL(buf); + } + else + { + _LIT(KCab, "Unknown"); + buf.Format(KKeyOwnerCab, &KCab); + PrintInfoL(buf); + } + } + else + { + buf.Format(KKeyOwner, mSecureid); + PrintInfoL(buf); + } + PrintInfoL(newline, aPageWise); + + TUint32 uSecureid = usePolicy.SecureId(); + if (uSecureid == 0xffffffff) + { + TSecurityPolicy::TType utype = usePolicy.Type(); + _LIT(KKeyUserType, "\t\tUser : %S "); + // currently only possible for keyuser other than secure id + if (utype == TSecurityPolicy::ETypePass) + { + _LIT(KType, "ALL"); + buf.Format(KKeyUserType, &KType); + PrintInfoL(buf); + } + else + { + _LIT(KType, "Unknown"); + buf.Format(KKeyUserType, &KType); + PrintInfoL(buf); + } + } + else + { + buf.Format(KKeyUser, uSecureid); + PrintInfoL(buf); + if (uSecureid == KUidSecurityKeytool) + { + _LIT(KUser, " (KeyTool)"); + PrintInfoL(KUser); + } + } + PrintInfoL(newline, aPageWise); + + + _LIT(KKeySens, "\t\tAccess flags: "); + PrintInfoL(KKeySens); + + HBufC* access = KeyToolUtils::KeyAccessDesLC(aKey.AccessType()); + PrintInfoL(*access); + CleanupStack::PopAndDestroy(access); + + PrintInfoL(newline, aPageWise); + + _LIT(KKeyID, "\t\tID: "); + PrintInfoL(KKeyID); + KeyToolUtils::WriteOctetStringL(aKey.ID()); + PrintInfoL(newline, aPageWise); + + _LIT(KKeyLabel, "\t\tLabel: "); + PrintInfoL(KKeyLabel); + PrintInfoL(aKey.Label().Left(KMaxLabel)); + if (aKey.Label().Length() > KMaxLabel) + { + PrintInfoL(KEllipsis); + } + PrintInfoL(newline, aPageWise); + + _LIT(KKeyNative, "\t\tNative: Yes "); + _LIT(KKeyNotNative, "\t\tNative: No "); + if ( aKey.Native()) + { + PrintInfoL(KKeyNative); + } + else + { + PrintInfoL(KKeyNotNative); + } + PrintInfoL(newline, aPageWise); + + _LIT(KTimeFormat, "%1/%2/%3 %H:%T:%S"); + + _LIT(KKeyStartDate, "\t\tStart date: "); + PrintInfoL(KKeyStartDate); + if (aKey.StartDate().Int64() == 0) + { + PrintInfoL(_L("not set")); + } + else + { + aKey.StartDate().FormatL(buf, KTimeFormat); + PrintInfoL(buf); + } + + _LIT(KKeyEndDate, "\tEnd date: "); + PrintInfoL(KKeyEndDate); + + if (aKey.EndDate().Int64() == 0) + { + PrintInfoL(_L("not set")); + } + else + { + aKey.EndDate().FormatL(buf, KTimeFormat); + PrintInfoL(buf); + } + PrintInfoL(newline, aPageWise); + } + +/*static*/ TKeyUsagePKCS15 KeyToolUtils::ParseKeyUsage(TPtrC aUsage) + { + TKeyUsagePKCS15 usage = EPKCS15UsageNone; + + if (aUsage.Compare(allusage)==0) + { + return EPKCS15UsageAll; + } + if (aUsage.Compare(nousage)==0) + { + return EPKCS15UsageNone; + } + if (aUsage.Compare(encrypt)==0) + { + return EPKCS15UsageEncrypt; + } + if (aUsage.Compare(decrypt)==0) + { + return EPKCS15UsageDecrypt; + } + if (aUsage.Compare(sign)==0) + { + return EPKCS15UsageSign; + } + if (aUsage.Compare(signrecover)==0) + { + return EPKCS15UsageSignRecover; + } + if (aUsage.Compare(wrap)==0) + { + return EPKCS15UsageWrap; + } + if (aUsage.Compare(unwrap)==0) + { + return EPKCS15UsageUnwrap; + } + if (aUsage.Compare(verify)==0) + { + return EPKCS15UsageVerify; + } + if (aUsage.Compare(verifyrecover)==0) + { + return EPKCS15UsageVerifyRecover; + } + if (aUsage.Compare(derive)==0) + { + return EPKCS15UsageDerive; + } + if (aUsage.Compare(nonrepudiation)==0) + { + return EPKCS15UsageNonRepudiation; + } + return usage; + } + +/*static*/ CCTKeyInfo::EKeyAccess KeyToolUtils::ParseKeyAccess(TPtrC aAccess) + { + CKeyInfoBase::EKeyAccess access = CKeyInfoBase::EInvalidAccess; + + if (aAccess.Compare(KSensitive)==0) + { + access = CCTKeyInfo::ESensitive; + } + + if (aAccess.Compare(KExtractable)==0) + { + access = CCTKeyInfo::EExtractable; + } + + if (aAccess.Compare(KAlwaysSensitive)==0) + { + access = CCTKeyInfo::EAlwaysSensitive; + } + + if (aAccess.Compare(KNeverExtractable)==0) + { + access = CCTKeyInfo::ENeverExtractable; + } + + if (aAccess.Compare(KLocal)==0) + { + access = CCTKeyInfo::ELocal; + } + + return access; + } + + +/*static*/ RArray KeyToolUtils::MatchKey(RMPointerArray& aKeyList, TDesC& aLabel) + { + RArray ret; + + for (TInt j = 0; j < aKeyList.Count(); j++) + { + if (aKeyList[j]->Label().Match(aLabel) != KErrNotFound) + { + ret.Append(aKeyList[j]); + } + } + return ret; + } + +/*static*/ CCTKeyInfo* KeyToolUtils::findKey(RMPointerArray& aKeyList, TDesC& aLabel) + { + TInt keyIndex = -1; + // Select the key with the label we want! + for (TInt j = 0; j < aKeyList.Count(); j++) + { + if (aKeyList[j]->Label() == aLabel) + { + keyIndex = j; + break; + } + } + + if (keyIndex == -1) + { + return NULL; + } + return aKeyList[keyIndex]; + } + +/*static*/ const TDesC& KeyToolUtils::Uid2Des(TUid aUid) + { + if (aUid.iUid == swinstalluid) + { + return KSWInstall; + } + else if (aUid.iUid == swinstallocspuid) + { + return KSWInstallOCSP; + } + else if (aUid.iUid == midletinstalluid) + { + return KMidletInstall; + } + else if (aUid.iUid == tlsuid) + { + return KTls; + } + else if (aUid.iUid == tocspuid) + { + return KTOcsp; + } + + return KUnknown; + } + + +/*static*/ void KeyToolUtils::FilterCertsL(RMPointerArray& aCertList, TDesC& aLabel) + { + TInt j = 0; + while (j < aCertList.Count()) + { + if ( aCertList[j]->Label().Match(aLabel) == KErrNotFound) + { + CCTCertInfo* tmp = aCertList[j]; + tmp->Release(); + aCertList.Remove(j); + } + else + { + j++; + } + } + if (j ==0) + { + PrintInfoL(_L("Cannot find the specified Certificate")); + PrintInfoL(newline); + } + } + +/*static*/ void KeyToolUtils::FilterCertsL(RMPointerArray& aCertList, TCertificateOwnerType& aOwnerType) + { + TInt j = 0; + while (j < aCertList.Count()) + { + if ( aCertList[j]->CertificateOwnerType() != aOwnerType) + { + CCTCertInfo* tmp = aCertList[j]; + tmp->Release(); + aCertList.Remove(j); + } + else + { + j++; + } + } + if (j ==0) + { + PrintInfoL(_L("No Certificate Exist")); + PrintInfoL(newline); + } + } + +/*static*/ void KeyToolUtils::PrintCertInfoL(CCTCertInfo& aCertInfo, CCertificate& aCertificate,RArray aApps, TBool aIsDetailed,TBool aPageWise) + { + TFileName certFormat,ownerType; + + switch (aCertInfo.CertificateFormat()) + { + case EX509Certificate : + { + certFormat.Copy(_L("X509")); + } + break; + case EWTLSCertificate : + { + certFormat.Copy(_L("WTLS")); + } + break; + case EX968Certificate : + { + certFormat.Copy(_L("X968")); + } + break; + default : + { + certFormat.Copy(_L("Unknown certificate format!")); + } + } + + switch (aCertInfo.CertificateOwnerType()) + { + case EPeerCertificate : + { + ownerType.Copy(_L("Peer")); + } + break; + case EUserCertificate : + { + ownerType.Copy(_L("User")); + } + break; + case ECACertificate : + { + ownerType.Copy(_L("Root (CA)")); + } + break; + default : + { + ownerType.Copy(_L("Unknown")); + } + } + + MCTToken& token = aCertInfo.Token(); + TFileName msg,msg1; + const TDesC& tmp = token.Label(); + msg.Format(_L("Store Label: %S"), &tmp); + + const TDesC& tmp1 = token.Information(MCTToken::EVersion); + const TDesC& tmp2 = token.Information(MCTToken::ESerialNo); + const TDesC& tmp3 = token.Information(MCTToken::EManufacturer); + + msg1.Format(_L("Version: %S \t Serial Number: %S \t Manufacturer: %S "), &tmp1, &tmp2, &tmp3); + + if (!aIsDetailed) + { + PrintInfoL(msg, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(aCertInfo.Label()); + PrintInfoL(_L(" is a ")); + PrintInfoL(certFormat); + PrintInfoL(_L(" format which is a ")); + PrintInfoL(ownerType); + PrintInfoL(_L(" type ")); + PrintInfoL(newline, aPageWise); + return; + } + + PrintInfoL(msg, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(msg1, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(_L("\tLabel: ")); + PrintInfoL(aCertInfo.Label()); + + PrintInfoL(_L("\t\t")); + + PrintInfoL(_L("Format: ")); + PrintInfoL(certFormat); + PrintInfoL(_L("\t")); + PrintInfoL(_L("Owner Type: ")); + PrintInfoL(ownerType); + PrintInfoL(newline, aPageWise); + PrintInfoL(_L("\tIssuer Name: ")); + HBufC* issuer = aCertificate.IssuerL(); + PrintInfoL(*issuer); + delete issuer; + HBufC* subj = aCertificate.SubjectL(); + PrintInfoL(_L("\t\tSubject Name: ")); + PrintInfoL(*subj); + delete subj; + + PrintInfoL(newline, aPageWise); + CValidityPeriod vp = aCertificate.ValidityPeriod(); + + const TTime& start = vp.Start(); + const TTime& finish = vp.Finish(); + TBuf<30> dateString1; + start.FormatL(dateString1,(_L("%H%:1%T:%S %*E%*D %X%*N%Y %1 %2 %3"))); + + PrintInfoL(_L("\tValid From ")); + PrintInfoL(dateString1, aPageWise); + + TBuf<30> dateString2; + finish.FormatL(dateString2,(_L("%H%:1%T:%S %*E%*D %X%*N%Y %1 %2 %3"))); + + PrintInfoL(_L("\tValid Until ")); + PrintInfoL(dateString2, aPageWise); + PrintInfoL(newline, aPageWise); + PrintInfoL(_L("\tTrusted for Applications: ")); + for (TInt k = 0; k < aApps.Count(); k++) + { + PrintInfoL(Uid2Des(aApps[k]), aPageWise); + PrintInfoL(_L(" ")); + } + PrintInfoL(newline, aPageWise); + } + +void KeyToolUtils::SetConsole(CConsoleBase *aConsole ) + { + iConsole = aConsole; + } + +void KeyToolUtils::SetFile(RFile* aFile) + { + iFile = aFile; + } + +TBool KeyToolUtils::DoesFileExistsL(const RFs& aFs, const TDesC& aFileName) + { + TBool exists = EFalse; + TEntry* e = new(ELeave) TEntry(); + TInt err = aFs.Entry(aFileName, *e); + if (err == KErrNone && ! e->IsDir()) + { + exists = ETrue; + } + delete e; + return exists; + } + +/*static*/ void KeyToolUtils::PrintInfoL(const TDesC& aValue, TBool aPageWise) + { + if (iConsole) + { + TSize screenSize = iConsole->ScreenSize(); + if(aPageWise && (iConsole->WhereY() >= screenSize.iHeight - KCursorOffset)) + { + iConsole->Printf(_L("\nPress a key to continue...")); + iConsole->Getch(); + iConsole->ClearScreen(); + iConsole->SetPos(0); + } + iConsole->Printf(aValue); + } + else + { + TBuf8<256> buf8; + buf8.Copy(aValue); + TInt seekPos = 0; + iFile->Seek(ESeekEnd, seekPos); + User::LeaveIfError(iFile->Write(buf8)); + } + } +