persistentstorage/dbms/sdbms/Sd_Sess2.cpp
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // DBMS server-session and support classes - "DBMS security" related - full support
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <s32file.h>
       
    19 #include "D32Strings.h"
       
    20 #include "SD_STD.H"
       
    21 #include "Sd_DbList.h"
       
    22 
       
    23 using namespace DBSC;
       
    24 
       
    25 CDbsSession::CDbsSession() :
       
    26 	iDbPolicyRqColl(TLinearOrder< TPair<TInt, TDbPolicyRequest> > (&Compare<TInt, TDbPolicyRequest>))
       
    27 	{
       
    28 	}
       
    29 
       
    30 /**
       
    31 New "DBMS security" related messages processed here!
       
    32 @param aMessage DBMS server message
       
    33 @param aDbsFunction DBMS server function code
       
    34 @return An error code (< 0) or a DBMS server session object handle (EDbsDatabase, EDbsIncremental,...).
       
    35 */
       
    36 TInt CDbsSession::ExtServiceL(const RMessage2& aMessage, TDbsFunction aDbsFunction)
       
    37 	{
       
    38 	TInt handle = 0;
       
    39 	switch(aDbsFunction)
       
    40 		{
       
    41 	case EDbsCreateDatabase:
       
    42 		handle=CreateDatabaseL(aMessage);
       
    43 		break;
       
    44 	case EDbsDatabaseList:
       
    45 		handle=GetDatabaseListL(aMessage);
       
    46 		break;
       
    47 	case EDbsCopyDatabase:
       
    48 		CopyDatabaseL(aMessage);
       
    49 		break;
       
    50 	case EDbsDeleteDatabase:
       
    51 		DeleteDatabaseL(aMessage);
       
    52 		break;
       
    53 	case EDbsGetSecurityPolicy:
       
    54 		GetSecurityPolicyL(aMessage);
       
    55 		break;
       
    56 	case EDbsGetBackupPath:
       
    57 		GetBackupPathL(aMessage);
       
    58 		break;
       
    59 	case EDbsGetBackupPaths:
       
    60 		handle=GetBackupPathsL(aMessage);
       
    61 		break;
       
    62 	default:
       
    63 		handle = KErrNotSupported;
       
    64 		break;
       
    65 		}
       
    66 	return handle;
       
    67 	}
       
    68 
       
    69 /**
       
    70 Extracts aMessage's "aIndex" argument (which is expected to be a file name) and
       
    71 stores it to CDbsServer::iFileName data member.
       
    72 @param aIndex The index of RMessage parameter
       
    73 @param aMessage
       
    74 @return A descriptor of the file name,extracted from aMessage and stored in CDbsServer::iFileName.
       
    75 */
       
    76 const TDesC& CDbsSession::ReadFileNameL(TInt aIndex, const RMessage2& aMessage)
       
    77 	{
       
    78 	TDes& name = Server().FileName();
       
    79 	aMessage.ReadL(aIndex, name);
       
    80 	return name;
       
    81 	}
       
    82 
       
    83 /**
       
    84 Extracts database name (aMessage's arg 0) and database format string (aMessage's arg 1)
       
    85 and use them to extract database properties, such as: database UID, access type (secure/non-secure),
       
    86 full database file path, database format string, drive number.
       
    87 @return A pointer to a TDbProps object, which contains some properties, extracted from the database name.
       
    88 */
       
    89 TDbProps* CDbsSession::ExtractDbPropsLC(const RMessage2& aMessage)
       
    90 	{
       
    91 	const TDesC& dbName = ReadFileNameL(0, aMessage);
       
    92 	const TDesC& dbFormat = ReadName0L(1, aMessage);
       
    93 	return Server().DbPropsFactory().ExtractLC(dbName, dbFormat);
       
    94 	}
       
    95 
       
    96 /**
       
    97 This method creates new EDbsDatabase type object.
       
    98 The related MPolicy interface will be retrieved and
       
    99 put together with the EDbsDatabase object in TEntry list.
       
   100 
       
   101 The initial contact for a database. Open a database source
       
   102 return the database handle for the client
       
   103 */
       
   104 TInt CDbsSession::OpenDatabaseL(const RMessage2& aMessage)
       
   105 	{
       
   106 	TDbProps* dbProps = ExtractDbPropsLC(aMessage);
       
   107 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(dbProps->iDbPolicyRequest);
       
   108 	Server().PolicyProxy().CheckL(aMessage, *policy);
       
   109 	TInt dbHandle = DoOpenDatabaseL(aMessage, *dbProps);
       
   110 	CleanupStack::PopAndDestroy(dbProps);
       
   111 	return dbHandle;
       
   112 	}
       
   113 
       
   114 
       
   115 /**
       
   116 SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
       
   117 Opens a database. It is used by both: OpenDatabase() and CreateDatabase() methods.
       
   118 @param aMessage DBMS server message:EDbsCreateDatabase or EDbsOpenDatabase.
       
   119 @param aDbProps A TDbProps object created from the database name and format string.
       
   120 @return A handle to the opened/created database object.
       
   121 @leave One of the system-wide error codes.
       
   122 */
       
   123 TInt CDbsSession::DoOpenDatabaseL(const RMessage2& aMessage, const TDbProps& aDbProps)
       
   124 	{
       
   125 	CDbsConnection* dbConnection = Sources().OpenLC(Server().Fs(), aDbProps.iPath, aDbProps.iFormatStr);
       
   126 	CDbObject* dbObj = DoAuthenticateL(dbConnection, aMessage);
       
   127 	dbConnection->Attach(dbObj);
       
   128 	CleanupStack::Pop(dbConnection);
       
   129 
       
   130 	//dbObj does not have to be pushed in the cleanup stack!
       
   131 	//NewDbEntryL() will take care of its destruction, if the database entry cannot be created.
       
   132 	//NewDbEntryL() will destroy the connection also in this case.
       
   133 	TInt dbHandle = 0;
       
   134 	NewDbEntryL(dbObj, aDbProps.iDbPolicyRequest, dbHandle);
       
   135 	return dbHandle;
       
   136 	}
       
   137 
       
   138 //SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
       
   139 //Authenticates a database.
       
   140 CDbObject* CDbsSession::DoAuthenticateL(CDbsConnection* aDbsConnection, const RMessage2&)
       
   141 	{
       
   142 	__ASSERT(aDbsConnection);
       
   143 	CDbSource& src = aDbsConnection->Source().Source();
       
   144 	return src.AuthenticateL();
       
   145 	}
       
   146 	
       
   147 
       
   148 //Adds a new database entry to the session list of database session objects.
       
   149 void CDbsSession::NewDbEntryL(CDbObject* aDbObject, const TDbPolicyRequest& aDbPolicyRequest, TInt& aDbHandle)
       
   150 	{
       
   151 	__ASSERT(aDbObject);
       
   152 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(aDbPolicyRequest);
       
   153 
       
   154 	aDbHandle = DoAdd(aDbObject, EDbsDatabase, policy);
       
   155 
       
   156 	//Store the database uid for later use
       
   157 	TInt err = iDbPolicyRqColl.Insert(aDbHandle, aDbPolicyRequest);
       
   158 	if(err != KErrNone)
       
   159 		{//If iDbPolicyRqColl.Insert() fails, then remove the object from TEntry list and then return.
       
   160 		TEntry& e = Object(aDbHandle);
       
   161 		Free(e);
       
   162 		User::Leave(err);
       
   163 		}
       
   164 	}
       
   165 
       
   166 /**
       
   167 Converts RDbs::TPolicyType parameter value to the internally used DBSC::TPolicyType value.
       
   168 @param aPolicyType Security policy type - client side
       
   169 @return Security policy type used on the server side.
       
   170 @leave KErrArgument if it is an invalid security policy type
       
   171 */
       
   172 static TPolicyType ConvertPolicyTypeL(RDbs::TPolicyType aPolicyType)
       
   173 	{
       
   174 	TPolicyType policyType = static_cast <TPolicyType> (1 << aPolicyType);
       
   175 	if(policyType > EPTLast || policyType <= EPTNone)
       
   176 		{
       
   177 		__LEAVE(KErrArgument);
       
   178 		}
       
   179 	return policyType;
       
   180 	}
       
   181 
       
   182 /**
       
   183 Creates secure shared database.
       
   184 @param aMessage DBMS server message: EDbsCreateDatabase.
       
   185 @return A handle to the created database object.
       
   186 @leave One of the system-wide error codes, including:
       
   187        KErrNotSupported An attempt to create non-secure shared database
       
   188 	   KErrAlreadyExists The database with the supplied name already exists
       
   189 */
       
   190 TInt CDbsSession::CreateDatabaseL(const RMessage2& aMessage)
       
   191 	{
       
   192 	TDbProps* dbProps = ExtractDbPropsLC(aMessage);
       
   193 	if(dbProps->iDbPolicyRequest.iAccessType == EATNonSecure)
       
   194 		{//This method works only for secure shared databases
       
   195 		__LEAVE(KErrNotSupported);
       
   196 		}
       
   197 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(dbProps->iDbPolicyRequest);
       
   198 	Server().PolicyProxy().CheckL(aMessage, *policy);
       
   199 	//Leave if the file is already there
       
   200 	::TEntry fileEntry;
       
   201 	TBool dbFileExist = Server().Fs().Entry(dbProps->iPath, fileEntry) == KErrNone;
       
   202 	if(dbFileExist)
       
   203 		{
       
   204 		__LEAVE(KErrAlreadyExists);
       
   205 		}
       
   206 	TInt dbHandle = 0;
       
   207 	TRAPD(err, dbHandle = DoCreateDatabaseL(aMessage, *dbProps));
       
   208 	if(err != KErrNone)
       
   209 		{//Cleanup if the creation fails
       
   210 		// Although the file delete below could return at error since we are
       
   211 		// already on an error-path a design decision has been made to ignore the
       
   212 		// error in favor of the one returned by DoCreateDatabaseL()
       
   213 
       
   214 		// If a debug build - record error
       
   215 		TInt fileDeleteErr = Server().Fs().Delete(dbProps->iPath);
       
   216 		#ifdef _DEBUG
       
   217 			if (fileDeleteErr != KErrNone)
       
   218 			{
       
   219 				RDebug::Print(_L("CDbsSession::CreateDatabaseL - Failed to delete file. Error = %d"), fileDeleteErr);
       
   220 			}
       
   221 		#endif
       
   222 
       
   223 		__LEAVE(err);
       
   224 		}
       
   225 	CleanupStack::PopAndDestroy(dbProps);
       
   226 	return dbHandle;
       
   227 	}
       
   228 
       
   229 //Creates secure shared database.
       
   230 //Originaly, the database were always created on the client side, using ::CreateDatabaseL() call.
       
   231 //I am not very sure how this function works and prefer to call ::CreateDatabaseL() to create
       
   232 //the database on the server side, then delete it and the open it in the same way, as it 
       
   233 //worked before for opening/sharing databases on the server side.
       
   234 TInt CDbsSession::DoCreateDatabaseL(const RMessage2& aMessage, const TDbProps& aDbProps)
       
   235 	{
       
   236 	CDbDatabase* db = ::CreateDatabaseL(TDbFormat::ECreate, Server().Fs(), aDbProps.iPath, aDbProps.iFormatStr);
       
   237 	delete db;
       
   238 	TInt dbHandle = DoOpenDatabaseL(aMessage, aDbProps);
       
   239 	return dbHandle;
       
   240 	}
       
   241 
       
   242 /**
       
   243 Copies an existing secure shared database to a new database.
       
   244 The new database will have the same security policy as the old one.
       
   245 @param aMessage DBMS server message (EDbsCopyDatabase)
       
   246 @leave One of the system-wide error codes, including KErrArgument - a null uid supplied
       
   247        as an argument.
       
   248 */
       
   249 void CDbsSession::CopyDatabaseL(const RMessage2& aMessage)
       
   250 	{
       
   251 	RDbPropsFactory& dbPropsFactory = Server().DbPropsFactory();
       
   252 	TUid uid;
       
   253 	uid.iUid = aMessage.Int2();
       
   254 	if(uid == KNullUid)
       
   255 		{
       
   256 		__LEAVE(KErrArgument);
       
   257 		}
       
   258 	//Do not change the order, because ReadFileNameL() uses the same place to store the names.
       
   259 	const TDesC& srcDbName = ReadFileNameL(0, aMessage);
       
   260 	TDbProps* srcDbProps = dbPropsFactory.ExtractLC(srcDbName, uid);
       
   261 	const TDesC& destDbName = ReadFileNameL(1, aMessage);
       
   262 	TDbProps* destDbProps = dbPropsFactory.ExtractLC(destDbName, uid);
       
   263 
       
   264 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(srcDbProps->iDbPolicyRequest);
       
   265 	Server().PolicyProxy().CheckL(aMessage, *policy);
       
   266 
       
   267 	CFileMan* fileMan = CFileMan::NewL(Server().Fs());
       
   268 	CleanupStack::PushL(fileMan);
       
   269 	__LEAVE_IF_ERROR(fileMan->Copy(srcDbProps->iPath, destDbProps->iPath, 0));
       
   270 	//"Copy" operation executed without errors. Now it is a time to turn off the read-only
       
   271 	//flag of the target file (which may be on if the source files is on a read-only drive)
       
   272 	__LEAVE_IF_ERROR(Server().Fs().SetAtt(destDbProps->iPath, 0, KEntryAttReadOnly));
       
   273 	CleanupStack::PopAndDestroy(3);//srcDbProps, destDbProps, fileMan
       
   274 	}
       
   275 
       
   276 /**
       
   277 Deletes secure shared database
       
   278 @param aMessage DBMS server message (EDbsDeleteDatabase)
       
   279 @leave One of the system-wide error codes, including KErrArgument - a null uid supplied
       
   280        as an argument.
       
   281 */
       
   282 void CDbsSession::DeleteDatabaseL(const RMessage2& aMessage)
       
   283 	{
       
   284 	TUid uid;
       
   285 	uid.iUid = aMessage.Int1();
       
   286 	if(uid == KNullUid)
       
   287 		{
       
   288 		__LEAVE(KErrArgument);
       
   289 		}
       
   290 	const TDesC& dbName = ReadFileNameL(0, aMessage);
       
   291 	TDbProps* dbProps = Server().DbPropsFactory().ExtractLC(dbName, uid);
       
   292 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(dbProps->iDbPolicyRequest);
       
   293 	Server().PolicyProxy().CheckL(aMessage, *policy);
       
   294 	__LEAVE_IF_ERROR(Server().Fs().Delete(dbProps->iPath));
       
   295 	CleanupStack::PopAndDestroy(dbProps);
       
   296 	}
       
   297 
       
   298 /**
       
   299 Gets the list of names of datatbases, which have the same uid.
       
   300 @param aMessage DBMS server message (EDbsDatabaseList)
       
   301 @return A stream handle to a stream with the database names found.
       
   302 @leave One of the system-wide error codes, including KErrArgument - a null uid supplied
       
   303        as an argument.
       
   304 */
       
   305 TInt CDbsSession::GetDatabaseListL(const RMessage2& aMessage)
       
   306 	{
       
   307 	CDbNamesFactory* dbNamesFactory = CDbNamesFactory::NewLC();
       
   308 	TDriveNumber driveNumber;
       
   309 	TDbPolicyRequest dbPolicyRequest;
       
   310 	CDbNamesFactory::ExtractArgs(aMessage, driveNumber, dbPolicyRequest);
       
   311 	if(dbPolicyRequest.iUid == KNullUid)
       
   312 		{
       
   313 		__LEAVE(KErrArgument);
       
   314 		}
       
   315 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(dbPolicyRequest);
       
   316 	Server().PolicyProxy().CheckL(aMessage, *policy);
       
   317 	CDbDatabaseNames* dbNames = dbNamesFactory->DbNamesLC(driveNumber, dbPolicyRequest, Server().DbPropsFactory(), Server().Fs());
       
   318 	//NewStreamL() will take care about destroying dbNames.
       
   319 	TInt streamHandle = NewStreamL(dbNames, Externalizer(dbNames), aMessage, policy);
       
   320 	CleanupStack::PopAndDestroy(dbNamesFactory);
       
   321 	return streamHandle;
       
   322 	}
       
   323 
       
   324 /**
       
   325 Gets database/table security policy.
       
   326 @param aMessage DBMS server message (EDbsGetSecurityPolicy)
       
   327 @leave One of the system-wide error codes, including KErrArgument - a null uid supplied
       
   328        as an argument.
       
   329 */
       
   330 void CDbsSession::GetSecurityPolicyL(const RMessage2& aMessage)
       
   331 	{
       
   332 	//No security policy check.
       
   333 	TUid dbUid = TUid::Uid(aMessage.Int0());
       
   334 	if(dbUid == KNullUid)
       
   335 		{
       
   336 		__LEAVE(KErrArgument);
       
   337 		}
       
   338 	TPolicyType policyTypeRq = ::ConvertPolicyTypeL(static_cast <RDbs::TPolicyType> (aMessage.Int1() & ~KTablePolicyMaskBit));
       
   339 	TBool tblPolicyRq = aMessage.Int1() & KTablePolicyMaskBit;
       
   340 	if(tblPolicyRq)
       
   341 		{
       
   342 		ReadName0L(2, aMessage);
       
   343 		if(Server().Name0() == KNullDesC)
       
   344 			{
       
   345 			__LEAVE(KErrArgument);
       
   346 			}
       
   347 		}
       
   348 	TDbPolicyRequest dbPolicyRequest;
       
   349 	dbPolicyRequest.iUid = dbUid;
       
   350 	dbPolicyRequest.iAccessType = EATSecure;
       
   351 	const MPolicy* policy = tblPolicyRq ? Server().PolicyProxy().TblPolicyL(dbPolicyRequest, Server().Name0()) : 
       
   352 										  Server().PolicyProxy().DbPolicyL(dbPolicyRequest);
       
   353 	__ASSERT(policy);
       
   354 	TSecurityPolicy secPolicy;
       
   355 	__LEAVE_IF_ERROR(policy->Get(policyTypeRq, secPolicy));
       
   356 	aMessage.WriteL(3, secPolicy.Package());
       
   357 	}
       
   358 
       
   359 /**
       
   360 The function extracts backup&restore process SID from aMessage argument (parameter 0).
       
   361 @param aMessage DBMS server message - EDbsGetBackupPath or EDbsGetBackupPaths.
       
   362 @return Backup&restore process SID
       
   363 @leave KErrArgument 0 or ECapability_None backup&restore process SID
       
   364 @internalComponent
       
   365 */
       
   366 static TSecureId BackupSIDL(const RMessage2& aMessage)
       
   367 	{
       
   368 	TSecureId backupSID = TSecureId(aMessage.Int0());
       
   369 	if(backupSID.iId == 0 || backupSID.iId == (TUint32)ECapability_None)
       
   370 		{
       
   371 		__LEAVE(KErrArgument);
       
   372 		}
       
   373 	return backupSID;
       
   374 	}
       
   375 	
       
   376 /**
       
   377 The function extracts database security policy UID from aMessage argument (parameter 1).
       
   378 @param aMessage DBMS server message - EDbsGetBackupPath or EDbsGetBackupPaths.
       
   379 @return Database security policy UID
       
   380 @leave KErrArgument Null database security policy UID
       
   381 @internalComponent
       
   382 */
       
   383 static TUid SecurityPolicyUidL(const RMessage2& aMessage)
       
   384 	{
       
   385 	TUid dbUid = TUid::Uid(aMessage.Int1());
       
   386 	if(dbUid == KNullUid)
       
   387 		{
       
   388 		__LEAVE(KErrArgument);
       
   389 		}
       
   390 	return dbUid;		
       
   391 	}
       
   392 
       
   393 /**
       
   394 The function gets the backup&restore process SID from the related database security policy,
       
   395 identified by aDbUid argument.
       
   396 @param aPolicyProxy A reference to CPolicyProxy object, which might be asked for particular 
       
   397                     database or table policy.
       
   398 @param aBackupSID Backup&restore process SID, extracted from RMessage2 object.
       
   399 @param aDbUid Database security policy UID, extracted from RMessage2 object.
       
   400 @return Backup&restore process SID, which is part of the database security policy.
       
   401 @leave KErrPermissionDenied - the supplied process SID does not match the database backup&
       
   402 						restore SID or the database backup&restore SID is 0 or ECapability_None. 
       
   403 @internalComponent
       
   404 */
       
   405 static TSecureId RegisteredBackupSIDL(CPolicyProxy& aPolicyProxy, TSecureId aBackupSID, TUid aDbUid)
       
   406 	{
       
   407 	TSecureId regBackupSID = aPolicyProxy.BackupSIDL(aDbUid);
       
   408 	if((regBackupSID == 0 || regBackupSID == (TUint32)ECapability_None) || aBackupSID != regBackupSID)
       
   409 		{
       
   410 		__LEAVE(KErrPermissionDenied);
       
   411 		}
       
   412 	return regBackupSID;
       
   413 	}
       
   414 	
       
   415 /**
       
   416 The method will return via aMessage argument the full path to the secure shared database, 
       
   417 which name is packed in aMessage argument too.
       
   418 @param aMessage DBMS server message (EDbsGetBackupPath)
       
   419 @leave One of the system-wide error codes, including:
       
   420 		- KErrArgument - 0 or ECapability_None process SID, null UID, 
       
   421 						 null or invalid database name,
       
   422 						 the database is not secure shared database;
       
   423 		- KErrNotFound - the database file does not exist;
       
   424 		- KErrPermissionDenied - the supplied process SID does not match the database backup&
       
   425 						 restore SID or the database backup&restore SID is 0 or ECapability_None. 
       
   426 @deprecated
       
   427 */
       
   428 void CDbsSession::GetBackupPathL(const RMessage2& aMessage)
       
   429 	{
       
   430 	//Backup&restore process SID
       
   431 	TSecureId backupSID = ::BackupSIDL(aMessage);
       
   432 	//Security policy UID
       
   433 	TUid dbUid = ::SecurityPolicyUidL(aMessage);
       
   434 	//Database name and drive, format: <drive>:<name>.<ext>
       
   435 	ReadName0L(2, aMessage);
       
   436 	if(Server().Name0() == KNullDesC)
       
   437 		{
       
   438 		__LEAVE(KErrArgument);
       
   439 		}
       
   440 	//Database path
       
   441 	RDbPropsFactory& dbPropsFactory = Server().DbPropsFactory();
       
   442 	TDbProps* dbProps = dbPropsFactory.ExtractLC(Server().Name0(), dbUid);
       
   443 	if(dbProps->iDbPolicyRequest.iAccessType != EATSecure)
       
   444 		{
       
   445 		__LEAVE(KErrArgument);
       
   446 		}
       
   447 	//Check if the database file exists
       
   448 	::TEntry fileEntry;
       
   449 	TBool dbFileExist = Server().Fs().Entry(dbProps->iPath, fileEntry) == KErrNone;
       
   450 	if(!dbFileExist)
       
   451 		{
       
   452 		__LEAVE(KErrNotFound);
       
   453 		}
       
   454 	//Get and check backup&restore SID 
       
   455 	TSecureId regBackupSID = ::RegisteredBackupSIDL(Server().PolicyProxy(), backupSID, dbUid);
       
   456     //
       
   457 	aMessage.WriteL(3, dbProps->iPath);
       
   458 	//
       
   459 	CleanupStack::PopAndDestroy(dbProps);
       
   460 	}
       
   461 
       
   462 /**
       
   463 This function processes "aFileEntries" array, which is a result of TFindFile::FindWildByDir()
       
   464 or TFindFile::FindWild() calls. In a loop the function will get an element from "aFileEntries" 
       
   465 array, copy it to a temporary string adding the drive and the path, and will add that string
       
   466 to "aDatabasePaths" array.
       
   467 Note: If the created full file path length is bigger than KDbMaxStrLen characters, then the 
       
   468 	  string will not be added to "aDatabasePaths" array!
       
   469 @param aFileEntries An array of file names, result of TFindFile::FindWildByDir() or 
       
   470 					TFindFile::FindWild() calls.
       
   471 @param aFileSpec	A string, containing the drive and the directory of the file names in
       
   472 					aFileEntries array.
       
   473 @param aDatabasePaths  Output argument. Each file name from aFileEntries array will be "decorated"
       
   474 					with the drive and path and then the created new string will be added to 
       
   475 					aDatabasePaths array.
       
   476 @leave One of the system-wide error codes, including KErrNoMemory.
       
   477 @internalComponent
       
   478 */
       
   479 static void ProcessFileEntriesL(CDir& aFileEntries, const TDesC& aFileSpec, 
       
   480 								CDbStrings& aDatabasePaths)
       
   481 	{
       
   482 	TParse parse;
       
   483 	__LEAVE_IF_ERROR(parse.Set(aFileSpec, NULL, NULL));
       
   484 	TInt cnt = aFileEntries.Count();
       
   485 	for(TInt i=0;i<cnt;++i)
       
   486 		{
       
   487 		TFileName fileName;
       
   488 		fileName.Copy(parse.DriveAndPath());
       
   489 		const ::TEntry& entry = aFileEntries[i];
       
   490 		fileName.Append(entry.iName);
       
   491 		if(fileName.Length() < KDbMaxStrLen)
       
   492 			{
       
   493 	    	aDatabasePaths.AddL(fileName);
       
   494 			}
       
   495 		}
       
   496 	}
       
   497 
       
   498 /**
       
   499 Gets a list of paths of the databases, which have the same security policy uid.
       
   500 @param aMessage DBMS server message (EDbsGetBackupPaths)
       
   501 @return A stream handle to a stream with the database names found.
       
   502 @leave One of the system-wide error codes, including:
       
   503 		- KErrArgument - 0 or ECapability_None process SID, null database security policy UID;
       
   504 		- KErrPermissionDenied - the supplied process SID does not match databases backup&
       
   505 						 restore SID or databases backup&restore SID is 0 or ECapability_None. 
       
   506 */
       
   507 TInt CDbsSession::GetBackupPathsL(const RMessage2& aMessage)
       
   508 	{
       
   509 	//Backup&restore process SID
       
   510 	TSecureId backupSID = ::BackupSIDL(aMessage);
       
   511 	//Security policy UID
       
   512 	TUid dbUid = ::SecurityPolicyUidL(aMessage);
       
   513 	//Get and check backup&restore SID 
       
   514 	TSecureId regBackupSID = ::RegisteredBackupSIDL(Server().PolicyProxy(), backupSID, dbUid);
       
   515 	//Get the related database security policy
       
   516 	TDbPolicyRequest dbPolicyRequest = {dbUid, EATSecure};
       
   517 	const MPolicy* policy = Server().PolicyProxy().DbPolicyL(dbPolicyRequest);
       
   518 	//
       
   519 	CDbStrings* dbPaths = CDbStrings::NewLC();
       
   520 	//DBMS server - private data path. CDbServer::iFileName used as a storage for the path.
       
   521 	__LEAVE_IF_ERROR(Server().Fs().PrivatePath(Server().FileName()));
       
   522 	//Construct search pattern. CDbServer::iName1 used as a storage for the search pattern.
       
   523 	RDbPropsFactory::ConstructCommonPart(dbUid, Server().Name1());
       
   524 	Server().Name1().Append('*');
       
   525 	//Search....
       
   526 	TFindFile findFile(Server().Fs());
       
   527 	CDir* fileEntries = NULL;
       
   528 	TInt err = findFile.FindWildByDir(Server().Name1(), Server().FileName(), fileEntries);
       
   529 	if(err == KErrNone)
       
   530 		{
       
   531 		do
       
   532 			{
       
   533 			__ASSERT(fileEntries);
       
   534 			CleanupStack::PushL(fileEntries);
       
   535 			::ProcessFileEntriesL(*fileEntries, findFile.File(), *dbPaths);
       
   536 			CleanupStack::PopAndDestroy(fileEntries);
       
   537 			fileEntries = NULL;
       
   538 			} while(findFile.FindWild(fileEntries) == KErrNone);
       
   539 		}
       
   540 	if(err != KErrNotFound && err != KErrNone)
       
   541 		{
       
   542 		__LEAVE(err);
       
   543 		}
       
   544 	//NewStreamL() will take care about destroying dbPaths.
       
   545 	TInt streamHandle = NewStreamL(dbPaths, Externalizer(dbPaths), aMessage, policy);
       
   546 	return streamHandle;
       
   547 	}