|
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 } |