commands/cenrep/cenrep.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // cenrep.cpp
       
     2 // 
       
     3 // Copyright (c) 2007 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/ioutils.h>
       
    14 #include <centralrepository.h>
       
    15 #include <fshell/ltkutils.h>
       
    16 #include <fshell/descriptorutils.h>
       
    17 
       
    18 using namespace IoUtils;
       
    19 
       
    20 class CCmdCenrep : public CCommandBase
       
    21 	{
       
    22 public:
       
    23 	static CCommandBase* NewLC();
       
    24 	~CCmdCenrep();
       
    25 private:
       
    26 	CCmdCenrep();
       
    27 	void PrintKeyL(TUint aKey, RBuf8& valDes);
       
    28 	template <class KEYTYPE>
       
    29 	void SetKeyL(const KEYTYPE& aVal);
       
    30 	void ListRepositoriesL();
       
    31 	void ForceSetKeyL(TInt aVal);
       
    32 	void ForceSetKeyL(const TDesC& aVal);
       
    33 	void SudoL(TRefByValue<const TDesC> aFmt, ...);
       
    34 	void AddFilesL(RArray<TUint>&, const TDesC& aMatch, const TDesC& aDir);
       
    35 
       
    36 private: // From CCommandBase.
       
    37 	virtual const TDesC& Name() const;
       
    38 	virtual void DoRunL();
       
    39 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
       
    40 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    41 private:
       
    42 	// Arguments
       
    43 	TUint iRepository;
       
    44 	TUint iKey;
       
    45 	// Options
       
    46 	HBufC* iStringVal;
       
    47 	TInt iIntVal;
       
    48 	TBool iForce;
       
    49 	TBool iDelete;
       
    50 	TBool iReset;
       
    51 	CRepository* iRep;
       
    52 	};
       
    53 
       
    54 CCommandBase* CCmdCenrep::NewLC()
       
    55 	{
       
    56 	CCmdCenrep* self = new(ELeave) CCmdCenrep();
       
    57 	CleanupStack::PushL(self);
       
    58 	self->BaseConstructL();
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 CCmdCenrep::~CCmdCenrep()
       
    63 	{
       
    64 	delete iStringVal;
       
    65 	delete iRep;
       
    66 	}
       
    67 
       
    68 CCmdCenrep::CCmdCenrep()
       
    69 	{
       
    70 	}
       
    71 
       
    72 const TDesC& CCmdCenrep::Name() const
       
    73 	{
       
    74 	_LIT(KName, "cenrep");	
       
    75 	return KName;
       
    76 	}
       
    77 
       
    78 void CCmdCenrep::DoRunL()
       
    79 	{
       
    80 	//__DEBUGGER();
       
    81 	if (iRepository == 0)
       
    82 		{
       
    83 		ListRepositoriesL();
       
    84 		return;
       
    85 		}
       
    86 
       
    87 	TRAPD(err, iRep = CRepository::NewL(TUid::Uid(iRepository)));
       
    88 	if (err && iForce)
       
    89 		{
       
    90 		// force create a repository?
       
    91 		}
       
    92 	else
       
    93 		{
       
    94 		if (err == KErrNotFound)
       
    95 			{
       
    96 			PrintError(err, _L("Repository 0x%x not found"), iRepository);
       
    97 			}
       
    98 		User::LeaveIfError(err);
       
    99 		}
       
   100 
       
   101 	if (iDelete)
       
   102 		{
       
   103 		if (!iArguments.IsPresent(1))
       
   104 			{
       
   105 			// Delete all
       
   106 			if (iForce)
       
   107 				{
       
   108 				SudoL(_L("--delete"));
       
   109 				}
       
   110 			else
       
   111 				{
       
   112 				TUint32 errorKey = 0;
       
   113 				err = iRep->Delete(0, 0, errorKey);
       
   114 				if (err && errorKey && errorKey != NCentralRepositoryConstants::KUnspecifiedKey)
       
   115 					{
       
   116 					PrintError(err, _L("Delete failed due to key 0x%x"), errorKey);
       
   117 					}
       
   118 				}
       
   119 			}
       
   120 		else
       
   121 			{
       
   122 			if (iForce)
       
   123 				{
       
   124 				SudoL(_L("--delete %d"), iKey);
       
   125 				}
       
   126 			else
       
   127 				{
       
   128 				err = iRep->Delete(iKey);
       
   129 				}
       
   130 			}
       
   131 		if (err == KErrPermissionDenied)
       
   132 			{
       
   133 			PrintError(err, _L("Delete failed, retry with --force"));
       
   134 			}
       
   135 		User::LeaveIfError(err);
       
   136 		}
       
   137 	else if (iReset)
       
   138 		{
       
   139 		if (iForce)
       
   140 			{
       
   141 			delete iRep;
       
   142 			iRep = NULL;
       
   143 			LtkUtils::RLtkBuf persistsName;
       
   144 			CleanupClosePushL(persistsName);
       
   145 			persistsName.AppendFormatL(_L("C:\\private\\10202be9\\persists\\%08x.cre"), iRepository);
       
   146 			err = FsL().Delete(persistsName);
       
   147 			LeaveIfErr(err, _L("Couldn't delete repository file %S"), &persistsName);
       
   148 			CleanupStack::PopAndDestroy(&persistsName);
       
   149 			}
       
   150 		else
       
   151 			{
       
   152 			User::LeaveIfError(iRep->Reset());
       
   153 			}
       
   154 		}
       
   155 	else if (iOptions.IsPresent(&iIntVal))
       
   156 		{
       
   157 		// Set int
       
   158 		SetKeyL(iIntVal);
       
   159 		}
       
   160 	else if (iOptions.IsPresent(&iStringVal))
       
   161 		{
       
   162 		// Set string
       
   163 		//TPtrC8 data((TUint8*)iStringVal->Ptr(), iStringVal->Size());
       
   164 		//SetKeyL(data);
       
   165 		SetKeyL(*iStringVal);
       
   166 		}
       
   167 	else if (!iArguments.IsPresent(1))
       
   168 		{
       
   169 		// Get all
       
   170 		if (iForce)
       
   171 			{
       
   172 			SudoL(KNullDesC);
       
   173 			}
       
   174 		else
       
   175 			{
       
   176 			RBuf8 valDes;
       
   177 			CleanupClosePushL(valDes);
       
   178 			valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength);
       
   179 
       
   180 			RArray<TUint32> keys;
       
   181 			CleanupClosePushL(keys);
       
   182 			iRep->FindL(0, 0, keys);
       
   183 			for (TInt i = 0; i < keys.Count(); i++)
       
   184 				{
       
   185 				PrintKeyL(keys[i], valDes);
       
   186 				}
       
   187 			CleanupStack::PopAndDestroy(2, &valDes); // keys, valDes
       
   188 			}
       
   189 		}
       
   190 	else
       
   191 		{
       
   192 		// Get
       
   193 		RBuf8 valDes;
       
   194 		CleanupClosePushL(valDes);
       
   195 		valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength * 3); // Because we also use this for hexifying
       
   196 		PrintKeyL(iKey, valDes);
       
   197 		CleanupStack::PopAndDestroy(&valDes);
       
   198 		}
       
   199 	}
       
   200 
       
   201 template <class KEYTYPE>
       
   202 void CCmdCenrep::SetKeyL(const KEYTYPE& aVal)
       
   203 	{
       
   204 	if (!iArguments.IsPresent(1))
       
   205 		{
       
   206 		LeaveIfErr(KErrArgument, _L("You must specify a key to set"));
       
   207 		}
       
   208 	if (iForce)
       
   209 		{
       
   210 		ForceSetKeyL(aVal);
       
   211 		}
       
   212 	else
       
   213 		{
       
   214 		TInt err = iRep->Set(iKey, aVal);
       
   215 		if (err == KErrArgument)
       
   216 			{
       
   217 			PrintError(err, _L("Key does not appear to be of the right type"));
       
   218 			}
       
   219 		User::LeaveIfError(err);
       
   220 		}
       
   221 	}
       
   222 
       
   223 void CCmdCenrep::ForceSetKeyL(TInt aVal)
       
   224 	{
       
   225 	SudoL(_L("%d --set-int %d"), iKey, aVal);
       
   226 	}
       
   227 
       
   228 void CCmdCenrep::ForceSetKeyL(const TDesC& aVal)
       
   229 	{
       
   230 	SudoL(_L("%d --set-string '%S'"), iKey, &aVal);
       
   231 	}
       
   232 
       
   233 void CCmdCenrep::PrintKeyL(TUint aKey, RBuf8& valDes)
       
   234 	{
       
   235 	TInt valInt;
       
   236 	valDes.Zero();
       
   237 	enum TType { EUnknown, EInt, EDes };
       
   238 	TType type = EUnknown;
       
   239 	TInt reallen = 0;
       
   240 
       
   241 	TInt err = KErrNotFound;
       
   242 
       
   243 	if (iForce)
       
   244 		{
       
   245 		SudoL(_L("%d"), aKey);
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		// Guess the value type
       
   250 		// Int?
       
   251 		if (type == EUnknown)
       
   252 			{
       
   253 			err = iRep->Get(aKey, valInt);
       
   254 			if (err != KErrArgument)
       
   255 				{
       
   256 				type = EInt;
       
   257 				}
       
   258 			}
       
   259 		
       
   260 		if (type == EUnknown)
       
   261 			{
       
   262 			// Des?
       
   263 			err = iRep->Get(aKey, valDes, reallen);
       
   264 			if (err != KErrArgument)
       
   265 				{
       
   266 				type = EDes;
       
   267 				}
       
   268 			}
       
   269 		}
       
   270 
       
   271 	switch(err)
       
   272 		{
       
   273 		case KErrNotFound:
       
   274 			PrintError(err, _L("Key not found"));
       
   275 			break;
       
   276 		case KErrArgument:
       
   277 			PrintError(err, _L("Unknown key type, not int, des8 or des16"));
       
   278 			break;
       
   279 		case KErrPermissionDenied:
       
   280 			PrintError(err, _L("Permission denied, retry with --force"));
       
   281 			break;
       
   282 		/* Won't happen because we now set our buffers to be the max size cenrep can handle
       
   283 		case KErrOverflow:
       
   284 			valDes16.ReallocL(reallen);
       
   285 			valDes8.ReallocL(reallen);
       
   286 			if (type == EDes8)
       
   287 				{
       
   288 				err = rep->Get(iKey, valDes8, reallen); // Better not fail this time!
       
   289 				}
       
   290 			else
       
   291 				{
       
   292 				err = rep->Get(iKey, valDes16, reallen); // Better not fail this time!
       
   293 				}
       
   294 		*/
       
   295 		case KErrNone:
       
   296 			// do nothing
       
   297 			break;
       
   298 		default:
       
   299 			PrintError(err, _L("Unrecognised error returned from CRepository"));
       
   300 			break;
       
   301 		}
       
   302 
       
   303 	if (err == KErrNone)
       
   304 		{
       
   305 		switch (type)
       
   306 			{
       
   307 			case EInt:
       
   308 				Printf(_L("Key 0x%08x TInt: %d (0x%x)\r\n"), aKey, valInt, valInt);
       
   309 				break;
       
   310 			/*case EDes8:
       
   311 				valDes16.Copy(valDes8);
       
   312 				Printf(_L("Key 0x%x TDesC8 length=%d: %S\r\n"), aKey, valDes16.Length(), &valDes16);
       
   313 				break;*/
       
   314 			case EDes:
       
   315 				{
       
   316 				TInt len = valDes.Length();
       
   317 
       
   318 				// Figure out if this string is likely to be 16bit ASCII, 8bit ASCII or just binary data
       
   319 				TBool wide = ETrue;
       
   320 				TBool ascii = ETrue;
       
   321 				if (len&1) wide = EFalse; // Odd number of bytes can't be 16-bit
       
   322 				for (TInt i = 0; i < len; i++)
       
   323 					{
       
   324 					TChar c(valDes[i]);
       
   325 					if ((i&1) && valDes[i] != 0) wide = EFalse;
       
   326 					if (!(c.IsPrint() && c < 127))
       
   327 						{
       
   328 						if (!(i&1)) wide = EFalse;
       
   329 						ascii = EFalse;
       
   330 						}
       
   331 					}
       
   332 
       
   333 				if (wide)
       
   334 					{
       
   335 					TPtr16 widePtr((TUint16*)valDes.Ptr(), len/2, valDes.MaxLength()/2);
       
   336 					Printf(_L("Key 0x%08x TDesC16 length=%d: %S\r\n"), aKey, widePtr.Length(), &widePtr);
       
   337 					}
       
   338 				else if (ascii)
       
   339 					{
       
   340 					Printf(_L8("Key 0x%08x TDesC8  length=%d: %S\r\n"), aKey, len, &valDes);
       
   341 					}
       
   342 				else
       
   343 					{
       
   344 					Printf(_L("Key 0x%08x TDesC8  hex dump:\r\n"), aKey);
       
   345 					LtkUtils::HexDumpToOutput(valDes, Stdout());
       
   346 					}
       
   347 				}
       
   348 				break;
       
   349 			default:
       
   350 				break;
       
   351 			}
       
   352 		}
       
   353 	}
       
   354 
       
   355 void CCmdCenrep::ArgumentsL(RCommandArgumentList& aArguments)
       
   356 	{
       
   357 	aArguments.AppendUintL(iRepository, _L("repository_uid"));
       
   358 	aArguments.AppendUintL(iKey, _L("key"));
       
   359  	}
       
   360 
       
   361 void CCmdCenrep::OptionsL(RCommandOptionList& aOptions)
       
   362 	{
       
   363 	aOptions.AppendIntL(iIntVal, _L("set-int"));
       
   364 	aOptions.AppendStringL(iStringVal, _L("set-string"));
       
   365 	aOptions.AppendBoolL(iForce, _L("force"));
       
   366 	aOptions.AppendBoolL(iDelete, _L("delete"));
       
   367 	aOptions.AppendBoolL(iReset, _L("reset"));
       
   368 	}
       
   369 
       
   370 EXE_BOILER_PLATE(CCmdCenrep)
       
   371 
       
   372 void CCmdCenrep::ListRepositoriesL()
       
   373 	{
       
   374 	RArray<TUint> uids;
       
   375 	CleanupClosePushL(uids);
       
   376 	AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\persists\\"));
       
   377 	AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\"));
       
   378 	AddFilesL(uids, _L("*.txt"), _L("Y:\\private\\10202be9\\"));
       
   379 
       
   380 	for (TInt i = 0; i < uids.Count(); i++)
       
   381 		{
       
   382 		Printf(_L("%08x\r\n"), uids[i]);
       
   383 		}
       
   384 	CleanupStack::PopAndDestroy(&uids);
       
   385 	}
       
   386 
       
   387 void CCmdCenrep::AddFilesL(RArray<TUint>& aUids, const TDesC& aMatch, const TDesC& aDir)
       
   388 	{
       
   389 	TFindFile finder(FsL());
       
   390 	CDir* files = NULL;
       
   391 	TInt err = finder.FindWildByDir(aMatch, aDir, files);
       
   392 
       
   393 	while (err == KErrNone)
       
   394 		{
       
   395 		for (TInt i = 0; i < files->Count(); i++)
       
   396 			{
       
   397 			TUint uid;
       
   398 			TLex lex((*files)[i].iName);
       
   399 			err = lex.Val(uid, EHex);
       
   400 			if (!err)
       
   401 				{
       
   402 				err = aUids.InsertInOrder(uid);
       
   403 				if (err == KErrAlreadyExists) err = KErrNone;
       
   404 				}
       
   405 			}
       
   406 		delete files;
       
   407 		files = NULL;
       
   408 		err = finder.FindWild(files);
       
   409 		}
       
   410 
       
   411 	if (err && err != KErrNotFound) LeaveIfErr(err, _L("Couldn't read directory %S"), &aDir);
       
   412 	}
       
   413 
       
   414 void CCmdCenrep::SudoL(TRefByValue<const TDesC> aFmt, ...)
       
   415 	{
       
   416 	VA_LIST args;
       
   417 	VA_START(args, aFmt);
       
   418 	
       
   419 	// We use sudo to give ourselves the SID of the repository, in the hope that will confer us more rights to access the data.
       
   420 	// Some repos might be configured to deny access even from their own SID; there's nothing we can do in that case
       
   421 	TBuf<256> commandLine;
       
   422 	commandLine.AppendFormat(_L("--sid 0x%x cenrep.exe 0x%x "), iRepository, iRepository);
       
   423 	commandLine.AppendFormatList(aFmt, args);
       
   424 	VA_END(args);
       
   425 
       
   426 	RChildProcess sudo;
       
   427 	CleanupClosePushL(sudo);
       
   428 	TRAPL(sudo.CreateL(_L("sudo.exe"), commandLine, IoSession(), Stdin(), Stdout(), Stderr()), _L("Couldn't create sudo process"));
       
   429 	TRequestStatus logon;
       
   430 	sudo.Run(logon);
       
   431 	User::WaitForRequest(logon);
       
   432 	LeaveIfErr(logon.Int(), _L("Error running sudo %S"), &commandLine);
       
   433 	CleanupStack::PopAndDestroy(&sudo);
       
   434 	}