diff -r 000000000000 -r 7f656887cf89 commands/cenrep/cenrep.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commands/cenrep/cenrep.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,434 @@ +// cenrep.cpp +// +// Copyright (c) 2007 - 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// + +#include +#include +#include +#include + +using namespace IoUtils; + +class CCmdCenrep : public CCommandBase + { +public: + static CCommandBase* NewLC(); + ~CCmdCenrep(); +private: + CCmdCenrep(); + void PrintKeyL(TUint aKey, RBuf8& valDes); + template + void SetKeyL(const KEYTYPE& aVal); + void ListRepositoriesL(); + void ForceSetKeyL(TInt aVal); + void ForceSetKeyL(const TDesC& aVal); + void SudoL(TRefByValue aFmt, ...); + void AddFilesL(RArray&, const TDesC& aMatch, const TDesC& aDir); + +private: // From CCommandBase. + virtual const TDesC& Name() const; + virtual void DoRunL(); + virtual void ArgumentsL(RCommandArgumentList& aArguments); + virtual void OptionsL(RCommandOptionList& aOptions); +private: + // Arguments + TUint iRepository; + TUint iKey; + // Options + HBufC* iStringVal; + TInt iIntVal; + TBool iForce; + TBool iDelete; + TBool iReset; + CRepository* iRep; + }; + +CCommandBase* CCmdCenrep::NewLC() + { + CCmdCenrep* self = new(ELeave) CCmdCenrep(); + CleanupStack::PushL(self); + self->BaseConstructL(); + return self; + } + +CCmdCenrep::~CCmdCenrep() + { + delete iStringVal; + delete iRep; + } + +CCmdCenrep::CCmdCenrep() + { + } + +const TDesC& CCmdCenrep::Name() const + { + _LIT(KName, "cenrep"); + return KName; + } + +void CCmdCenrep::DoRunL() + { + //__DEBUGGER(); + if (iRepository == 0) + { + ListRepositoriesL(); + return; + } + + TRAPD(err, iRep = CRepository::NewL(TUid::Uid(iRepository))); + if (err && iForce) + { + // force create a repository? + } + else + { + if (err == KErrNotFound) + { + PrintError(err, _L("Repository 0x%x not found"), iRepository); + } + User::LeaveIfError(err); + } + + if (iDelete) + { + if (!iArguments.IsPresent(1)) + { + // Delete all + if (iForce) + { + SudoL(_L("--delete")); + } + else + { + TUint32 errorKey = 0; + err = iRep->Delete(0, 0, errorKey); + if (err && errorKey && errorKey != NCentralRepositoryConstants::KUnspecifiedKey) + { + PrintError(err, _L("Delete failed due to key 0x%x"), errorKey); + } + } + } + else + { + if (iForce) + { + SudoL(_L("--delete %d"), iKey); + } + else + { + err = iRep->Delete(iKey); + } + } + if (err == KErrPermissionDenied) + { + PrintError(err, _L("Delete failed, retry with --force")); + } + User::LeaveIfError(err); + } + else if (iReset) + { + if (iForce) + { + delete iRep; + iRep = NULL; + LtkUtils::RLtkBuf persistsName; + CleanupClosePushL(persistsName); + persistsName.AppendFormatL(_L("C:\\private\\10202be9\\persists\\%08x.cre"), iRepository); + err = FsL().Delete(persistsName); + LeaveIfErr(err, _L("Couldn't delete repository file %S"), &persistsName); + CleanupStack::PopAndDestroy(&persistsName); + } + else + { + User::LeaveIfError(iRep->Reset()); + } + } + else if (iOptions.IsPresent(&iIntVal)) + { + // Set int + SetKeyL(iIntVal); + } + else if (iOptions.IsPresent(&iStringVal)) + { + // Set string + //TPtrC8 data((TUint8*)iStringVal->Ptr(), iStringVal->Size()); + //SetKeyL(data); + SetKeyL(*iStringVal); + } + else if (!iArguments.IsPresent(1)) + { + // Get all + if (iForce) + { + SudoL(KNullDesC); + } + else + { + RBuf8 valDes; + CleanupClosePushL(valDes); + valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength); + + RArray keys; + CleanupClosePushL(keys); + iRep->FindL(0, 0, keys); + for (TInt i = 0; i < keys.Count(); i++) + { + PrintKeyL(keys[i], valDes); + } + CleanupStack::PopAndDestroy(2, &valDes); // keys, valDes + } + } + else + { + // Get + RBuf8 valDes; + CleanupClosePushL(valDes); + valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength * 3); // Because we also use this for hexifying + PrintKeyL(iKey, valDes); + CleanupStack::PopAndDestroy(&valDes); + } + } + +template +void CCmdCenrep::SetKeyL(const KEYTYPE& aVal) + { + if (!iArguments.IsPresent(1)) + { + LeaveIfErr(KErrArgument, _L("You must specify a key to set")); + } + if (iForce) + { + ForceSetKeyL(aVal); + } + else + { + TInt err = iRep->Set(iKey, aVal); + if (err == KErrArgument) + { + PrintError(err, _L("Key does not appear to be of the right type")); + } + User::LeaveIfError(err); + } + } + +void CCmdCenrep::ForceSetKeyL(TInt aVal) + { + SudoL(_L("%d --set-int %d"), iKey, aVal); + } + +void CCmdCenrep::ForceSetKeyL(const TDesC& aVal) + { + SudoL(_L("%d --set-string '%S'"), iKey, &aVal); + } + +void CCmdCenrep::PrintKeyL(TUint aKey, RBuf8& valDes) + { + TInt valInt; + valDes.Zero(); + enum TType { EUnknown, EInt, EDes }; + TType type = EUnknown; + TInt reallen = 0; + + TInt err = KErrNotFound; + + if (iForce) + { + SudoL(_L("%d"), aKey); + } + else + { + // Guess the value type + // Int? + if (type == EUnknown) + { + err = iRep->Get(aKey, valInt); + if (err != KErrArgument) + { + type = EInt; + } + } + + if (type == EUnknown) + { + // Des? + err = iRep->Get(aKey, valDes, reallen); + if (err != KErrArgument) + { + type = EDes; + } + } + } + + switch(err) + { + case KErrNotFound: + PrintError(err, _L("Key not found")); + break; + case KErrArgument: + PrintError(err, _L("Unknown key type, not int, des8 or des16")); + break; + case KErrPermissionDenied: + PrintError(err, _L("Permission denied, retry with --force")); + break; + /* Won't happen because we now set our buffers to be the max size cenrep can handle + case KErrOverflow: + valDes16.ReallocL(reallen); + valDes8.ReallocL(reallen); + if (type == EDes8) + { + err = rep->Get(iKey, valDes8, reallen); // Better not fail this time! + } + else + { + err = rep->Get(iKey, valDes16, reallen); // Better not fail this time! + } + */ + case KErrNone: + // do nothing + break; + default: + PrintError(err, _L("Unrecognised error returned from CRepository")); + break; + } + + if (err == KErrNone) + { + switch (type) + { + case EInt: + Printf(_L("Key 0x%08x TInt: %d (0x%x)\r\n"), aKey, valInt, valInt); + break; + /*case EDes8: + valDes16.Copy(valDes8); + Printf(_L("Key 0x%x TDesC8 length=%d: %S\r\n"), aKey, valDes16.Length(), &valDes16); + break;*/ + case EDes: + { + TInt len = valDes.Length(); + + // Figure out if this string is likely to be 16bit ASCII, 8bit ASCII or just binary data + TBool wide = ETrue; + TBool ascii = ETrue; + if (len&1) wide = EFalse; // Odd number of bytes can't be 16-bit + for (TInt i = 0; i < len; i++) + { + TChar c(valDes[i]); + if ((i&1) && valDes[i] != 0) wide = EFalse; + if (!(c.IsPrint() && c < 127)) + { + if (!(i&1)) wide = EFalse; + ascii = EFalse; + } + } + + if (wide) + { + TPtr16 widePtr((TUint16*)valDes.Ptr(), len/2, valDes.MaxLength()/2); + Printf(_L("Key 0x%08x TDesC16 length=%d: %S\r\n"), aKey, widePtr.Length(), &widePtr); + } + else if (ascii) + { + Printf(_L8("Key 0x%08x TDesC8 length=%d: %S\r\n"), aKey, len, &valDes); + } + else + { + Printf(_L("Key 0x%08x TDesC8 hex dump:\r\n"), aKey); + LtkUtils::HexDumpToOutput(valDes, Stdout()); + } + } + break; + default: + break; + } + } + } + +void CCmdCenrep::ArgumentsL(RCommandArgumentList& aArguments) + { + aArguments.AppendUintL(iRepository, _L("repository_uid")); + aArguments.AppendUintL(iKey, _L("key")); + } + +void CCmdCenrep::OptionsL(RCommandOptionList& aOptions) + { + aOptions.AppendIntL(iIntVal, _L("set-int")); + aOptions.AppendStringL(iStringVal, _L("set-string")); + aOptions.AppendBoolL(iForce, _L("force")); + aOptions.AppendBoolL(iDelete, _L("delete")); + aOptions.AppendBoolL(iReset, _L("reset")); + } + +EXE_BOILER_PLATE(CCmdCenrep) + +void CCmdCenrep::ListRepositoriesL() + { + RArray uids; + CleanupClosePushL(uids); + AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\persists\\")); + AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\")); + AddFilesL(uids, _L("*.txt"), _L("Y:\\private\\10202be9\\")); + + for (TInt i = 0; i < uids.Count(); i++) + { + Printf(_L("%08x\r\n"), uids[i]); + } + CleanupStack::PopAndDestroy(&uids); + } + +void CCmdCenrep::AddFilesL(RArray& aUids, const TDesC& aMatch, const TDesC& aDir) + { + TFindFile finder(FsL()); + CDir* files = NULL; + TInt err = finder.FindWildByDir(aMatch, aDir, files); + + while (err == KErrNone) + { + for (TInt i = 0; i < files->Count(); i++) + { + TUint uid; + TLex lex((*files)[i].iName); + err = lex.Val(uid, EHex); + if (!err) + { + err = aUids.InsertInOrder(uid); + if (err == KErrAlreadyExists) err = KErrNone; + } + } + delete files; + files = NULL; + err = finder.FindWild(files); + } + + if (err && err != KErrNotFound) LeaveIfErr(err, _L("Couldn't read directory %S"), &aDir); + } + +void CCmdCenrep::SudoL(TRefByValue aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + + // We use sudo to give ourselves the SID of the repository, in the hope that will confer us more rights to access the data. + // Some repos might be configured to deny access even from their own SID; there's nothing we can do in that case + TBuf<256> commandLine; + commandLine.AppendFormat(_L("--sid 0x%x cenrep.exe 0x%x "), iRepository, iRepository); + commandLine.AppendFormatList(aFmt, args); + VA_END(args); + + RChildProcess sudo; + CleanupClosePushL(sudo); + TRAPL(sudo.CreateL(_L("sudo.exe"), commandLine, IoSession(), Stdin(), Stdout(), Stderr()), _L("Couldn't create sudo process")); + TRequestStatus logon; + sudo.Run(logon); + User::WaitForRequest(logon); + LeaveIfErr(logon.Int(), _L("Error running sudo %S"), &commandLine); + CleanupStack::PopAndDestroy(&sudo); + }