|
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 // |
|
15 |
|
16 #include <e32def.h> |
|
17 #include <e32property.h> |
|
18 #include <s32file.h> |
|
19 #include <connect/sbdefs.h> |
|
20 #include "srvres.h" |
|
21 #include "cachemgr.h" |
|
22 #include "srvparams.h" |
|
23 #include "shrepos.h" |
|
24 #include "sessnotf.h" |
|
25 #include "backup.h" |
|
26 |
|
27 #define UNUSED_VAR(a) a = a |
|
28 |
|
29 _LIT (KBackupFileName, "BACKUP") ; |
|
30 _LIT (KRestoreFileName, "RESTORE") ; |
|
31 _LIT(KBackupFileExt, ".bak"); |
|
32 _LIT(KRestoreFileExt, ".rst"); |
|
33 |
|
34 |
|
35 TRepositoryBackupState CRepositoryBackupClient::iBackupStatus ; |
|
36 |
|
37 |
|
38 // |
|
39 // Backup stream index class - Used to hold association between a UID (in |
|
40 // our case the UID of a repository) and a stream ID - Can't use CStreamDictionary |
|
41 // because that only lets you retrieve stream IDs by a (previously known) UID rather |
|
42 // than iterate through its contentsretrieving UID/StreamID pairs... |
|
43 // |
|
44 |
|
45 |
|
46 // |
|
47 // CRepositoryBackupStreamIndex::AddL |
|
48 // |
|
49 // Add a new repository UID and stream ID pair to the index |
|
50 void CRepositoryBackupStreamIndex::AddL(TUid aUid, TStreamId aSettingStreamId, TStreamId aDeletedSettingsStreamId) |
|
51 { |
|
52 TRepositoryBackupStreamIndexElement newIndexElement; |
|
53 newIndexElement.Set(aUid,aSettingStreamId, aDeletedSettingsStreamId) ; |
|
54 iStreamIndex.AppendL(newIndexElement); |
|
55 } |
|
56 |
|
57 |
|
58 // |
|
59 // CRepositoryBackupStreamIndex::GetNext |
|
60 // |
|
61 // Iterate through the index retrieving the next Reposirory UID and Stream ID |
|
62 // pair. |
|
63 // |
|
64 TInt CRepositoryBackupStreamIndex::GetNext(TUid& aUid, TStreamId& aSettingsStreamId, TStreamId& aDeletedSettingsStreamId) |
|
65 { |
|
66 TInt error = KErrNone ; |
|
67 if (iIndex < iStreamIndex.Count()) |
|
68 { |
|
69 iStreamIndex[iIndex++].Get(aUid, aSettingsStreamId, aDeletedSettingsStreamId) ; |
|
70 } |
|
71 else |
|
72 { |
|
73 error = KErrNotFound ; |
|
74 } |
|
75 return error ; |
|
76 } |
|
77 |
|
78 |
|
79 // |
|
80 // Backup client class. |
|
81 // |
|
82 // Has Active object functionality to monitor the state of the publish and subscribe |
|
83 // flags associated with backup and restore and also implements MActiveBackupDataClient |
|
84 // to perform active backup according to the "proxy data holder" model. |
|
85 // |
|
86 |
|
87 |
|
88 |
|
89 // |
|
90 // Usual 2 phase construction factory NewL NewLC classes |
|
91 // |
|
92 CRepositoryBackupClient* CRepositoryBackupClient::NewLC(RFs& aFs) |
|
93 { |
|
94 CRepositoryBackupClient* me = new(ELeave)CRepositoryBackupClient(aFs); |
|
95 CleanupStack::PushL(me) ; |
|
96 me->ConstructL() ; |
|
97 return me ; |
|
98 } |
|
99 |
|
100 |
|
101 CRepositoryBackupClient* CRepositoryBackupClient::NewL(RFs& aFs) |
|
102 { |
|
103 CRepositoryBackupClient* me = CRepositoryBackupClient::NewLC(aFs) ; |
|
104 CleanupStack::Pop(me) ; |
|
105 return me ; |
|
106 } |
|
107 |
|
108 |
|
109 |
|
110 // |
|
111 // Constructor - doesn't really do anything! |
|
112 // |
|
113 CRepositoryBackupClient::CRepositoryBackupClient(RFs& aFs) : CActive(EPriorityStandard), iFs(aFs), iRomScanDone(EFalse) |
|
114 { |
|
115 } |
|
116 |
|
117 |
|
118 // |
|
119 // Phase 2 constructor |
|
120 // |
|
121 void CRepositoryBackupClient::ConstructL() |
|
122 { |
|
123 // Create repository object |
|
124 iRepository = new(ELeave) CServerRepository; |
|
125 |
|
126 // Notifier needed to open repositories. |
|
127 iNotifier = new(ELeave)CSessionNotifier ; |
|
128 |
|
129 // Attach to Backup/Restore Pub/Sub property. |
|
130 User::LeaveIfError(iBackupRestoreProperty.Attach(KUidSystemCategory, KUidBackupRestoreKey)) ; |
|
131 |
|
132 // Add ourself to the active scheduler |
|
133 CActiveScheduler::Add(this) ; |
|
134 |
|
135 // Initialise backup/restore status |
|
136 iBackupStatus = ENoBackupActivty ; |
|
137 |
|
138 // Set active and request notification of changes to backup/restore |
|
139 // Pub/Sub property. |
|
140 StartL() ; |
|
141 } |
|
142 |
|
143 |
|
144 |
|
145 // |
|
146 // Destructor |
|
147 // |
|
148 CRepositoryBackupClient::~CRepositoryBackupClient() |
|
149 { |
|
150 Cancel(); |
|
151 |
|
152 iBackupRestoreProperty.Close() ; |
|
153 |
|
154 if (iRepository) |
|
155 { |
|
156 iRepository->Close(*iNotifier) ; |
|
157 delete(iRepository); |
|
158 } |
|
159 |
|
160 if (iNotifier) |
|
161 delete(iNotifier) ; |
|
162 |
|
163 if (iActiveBackupClient) |
|
164 delete(iActiveBackupClient) ; |
|
165 } |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 // |
|
171 // DoCancel - mandatory for active objects. |
|
172 // |
|
173 void CRepositoryBackupClient::DoCancel() |
|
174 { |
|
175 iBackupRestoreProperty.Cancel() ; |
|
176 } |
|
177 |
|
178 |
|
179 |
|
180 // |
|
181 // RunError |
|
182 // |
|
183 TInt CRepositoryBackupClient::RunError(TInt aError) |
|
184 { |
|
185 UNUSED_VAR(aError); |
|
186 return KErrNone; |
|
187 } |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 // |
|
193 // Test BUR Pub/Sub property set status, and notify BUR that we're |
|
194 // ready to go as appropriate. |
|
195 // |
|
196 void CRepositoryBackupClient::TestBURstatusL(void) |
|
197 { |
|
198 TInt BURstatus ; |
|
199 |
|
200 if (iBackupRestoreProperty.Get(BURstatus) != KErrNotFound) |
|
201 { |
|
202 BURstatus &= KBURPartTypeMask ; |
|
203 switch (BURstatus) |
|
204 { |
|
205 case EBURUnset: // State not yet set. Treat as no backup/restore in progress. |
|
206 case EBURNormal: |
|
207 // No backup or restore in progress. Probably |
|
208 // means we've just completed an operation? |
|
209 iBackupStatus = ENoBackupActivty ; |
|
210 |
|
211 // Back to normal, so enable cache |
|
212 TServerResources::iCacheManager->EnableCache(); |
|
213 // delete the CActiveBackupClient |
|
214 if (iActiveBackupClient) |
|
215 { |
|
216 delete iActiveBackupClient ; |
|
217 iActiveBackupClient = NULL ; |
|
218 } |
|
219 break ; |
|
220 |
|
221 case EBURBackupFull : |
|
222 case EBURBackupPartial : |
|
223 // We don't distinguish between full and partial backups |
|
224 // as the Backup engine will give us UIDs for all the |
|
225 // repository data owners that want their stuff backed up |
|
226 // anyway. |
|
227 |
|
228 // We don't want cache activity during backup |
|
229 TServerResources::iCacheManager->DisableCache(); |
|
230 |
|
231 // Any (and all!) repositories which have been opened in the |
|
232 // course of system boot and normal operation will have been |
|
233 // added to TServerResources::iOwnerIdLookUpTable as they were |
|
234 // opened but there may well be repositories which need backing |
|
235 // up and haven't yet been opened so we need to make sure that |
|
236 // the lookup table is complete. |
|
237 CompleteOwnerIdLookupTableL(); |
|
238 |
|
239 // Register with BUR engine |
|
240 if (!iActiveBackupClient) |
|
241 { |
|
242 iActiveBackupClient = CActiveBackupClient::NewL(this) ; |
|
243 } |
|
244 iActiveBackupClient->ConfirmReadyForBURL(KErrNone); |
|
245 iBackupStatus = EBackupInProgress ; |
|
246 break ; |
|
247 |
|
248 case EBURRestoreFull : |
|
249 case EBURRestorePartial : |
|
250 // We don't distinguish between full and partial restore |
|
251 // either! |
|
252 |
|
253 // We don't want cache activity during restore either! |
|
254 TServerResources::iCacheManager->DisableCache(); |
|
255 |
|
256 // Register with BUR engine |
|
257 if (!iActiveBackupClient) |
|
258 { |
|
259 iActiveBackupClient = CActiveBackupClient::NewL(this) ; |
|
260 } |
|
261 iActiveBackupClient->ConfirmReadyForBURL(KErrNone); |
|
262 iBackupStatus = ERestoreInProgress ; |
|
263 break ; |
|
264 |
|
265 } |
|
266 } |
|
267 } |
|
268 |
|
269 |
|
270 // |
|
271 // Request notification of changes in BUR Pub/Sub status |
|
272 // |
|
273 void CRepositoryBackupClient::StartL() |
|
274 { |
|
275 if (!IsActive()) |
|
276 { |
|
277 TestBURstatusL(); |
|
278 NotifyChange(); |
|
279 } |
|
280 } |
|
281 |
|
282 |
|
283 // |
|
284 // Request notification of changes in BUR Pub/Sub status |
|
285 // |
|
286 void CRepositoryBackupClient::NotifyChange() |
|
287 { |
|
288 // Watch for changes in the property state. |
|
289 iBackupRestoreProperty.Subscribe(iStatus) ; |
|
290 SetActive(); |
|
291 } |
|
292 |
|
293 |
|
294 // |
|
295 // Handle changes of backup state through publish/subscribe |
|
296 // |
|
297 void CRepositoryBackupClient::RunL() |
|
298 { |
|
299 NotifyChange() ; |
|
300 TestBURstatusL(); |
|
301 } |
|
302 |
|
303 |
|
304 // |
|
305 // We can't estimate data size without A) having the SID of the data owner who's data |
|
306 // is to be backed up and B) going through the whole process of preparing the backup. |
|
307 // |
|
308 // The only sensible thing we can do is return an arbitrary value! |
|
309 // |
|
310 TUint CRepositoryBackupClient::GetExpectedDataSize(TDriveNumber /* aDrive */) |
|
311 { |
|
312 return KArbitraryNumber ; |
|
313 } |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 // |
|
319 // Called by BUR engine to request a chunk of backup data. |
|
320 // |
|
321 void CRepositoryBackupClient::GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished) |
|
322 { |
|
323 const TInt chunkSize = aBuffer.MaxSize() ; |
|
324 |
|
325 aFinished = EFalse ; |
|
326 |
|
327 // Pass a chunk of our prepared backup data in aBuffer |
|
328 User::LeaveIfError(iFile.Read(aBuffer, chunkSize)) ; |
|
329 TInt bytesRead = aBuffer.Length() ; |
|
330 |
|
331 // Check to see if this was the last chunk of data. |
|
332 if (bytesRead < chunkSize) |
|
333 { |
|
334 // Set "finished" flag so that BUR knows we're through... |
|
335 aFinished = ETrue ; |
|
336 |
|
337 // ...and then tidy up by closing and deleting the backup file. |
|
338 iFile.Close() ; |
|
339 TParse backupFilePath ; |
|
340 User::LeaveIfError(backupFilePath.Set(KBackupFileName, TServerResources::iBURDirectory, &KBackupFileExt)); |
|
341 iFs.Delete(backupFilePath.FullName()) ; |
|
342 } |
|
343 } |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 // |
|
351 // CRepositoryBackupClient::RestoreComplete |
|
352 // |
|
353 // Called when a Complete set of backup data has been received and written |
|
354 // to a file. We now need to open the file as a stream store, get the |
|
355 // index (list of repository UID and corresponding stream ID pairs, and then |
|
356 // reconstruct and save each repository in turn. |
|
357 // |
|
358 void CRepositoryBackupClient::RestoreComplete(TDriveNumber /* aDrive */) |
|
359 { |
|
360 } |
|
361 |
|
362 |
|
363 |
|
364 // |
|
365 // CRepositoryBackupClient::RestoreCompleteL |
|
366 // |
|
367 // Does the actual work of reconstructing repositories from backup data |
|
368 // |
|
369 // |
|
370 void CRepositoryBackupClient::RestoreCompleteL() |
|
371 { |
|
372 // All restore data recived so we can now recreate the repositories from the |
|
373 // backup store |
|
374 // Attempt to open the restore file as a CDirectFileStore |
|
375 TParse restoreFilePath ; |
|
376 User::LeaveIfError(restoreFilePath.Set(KRestoreFileName, TServerResources::iBURDirectory, &KRestoreFileExt)); |
|
377 CDirectFileStore* store = CDirectFileStore::OpenLC (iFs,restoreFilePath.FullName(), EFileRead|EFileShareReadersOnly); |
|
378 if (store->Type()[0] != KDirectFileStoreLayoutUid) |
|
379 { |
|
380 // store wasn't quite what we were expecting - can't return an error, can't leave |
|
381 // so all we can do is close the file, tidy up as best we can, and bail out!!!! |
|
382 CleanupStack::PopAndDestroy(store); |
|
383 iFs.Delete(restoreFilePath.FullName()) ; |
|
384 User::Leave(KErrCorrupt); |
|
385 } |
|
386 |
|
387 |
|
388 |
|
389 // Get the root stream and attempt to read a backup file header from it |
|
390 TStreamId rootStreamId = store->Root() ; |
|
391 RStoreReadStream rootStream ; |
|
392 RStoreReadStream indexStream ; |
|
393 rootStream.OpenLC(*store, rootStreamId); |
|
394 TRepositoryBackupStreamHeader header ; |
|
395 TRAPD(err, header.InternalizeL(rootStream)) ; |
|
396 |
|
397 // Check for a valid header by checking that the UID matches the UID |
|
398 // of Central Repository and that the version number is sane. |
|
399 if (err == KErrNotSupported) |
|
400 { |
|
401 // Not a valid header - assume it's an old style backup stream, |
|
402 // set extensions supported to none, set index stream to be |
|
403 // root stream and reset read pointer to beginning. |
|
404 iBackupExtensionsSupported = ENoBackupExtensions ; |
|
405 |
|
406 CleanupStack::PopAndDestroy(&rootStream) ; |
|
407 CleanupStack::PopAndDestroy(store) ; |
|
408 |
|
409 // Try re-opening as old-style backup stream with index |
|
410 // as root stream. |
|
411 CDirectFileStore* store = CDirectFileStore::OpenLC (iFs,restoreFilePath.FullName(), EFileRead|EFileShareReadersOnly); |
|
412 indexStream.OpenLC(*store, rootStreamId) ; |
|
413 } |
|
414 else |
|
415 { |
|
416 // Got a valid header. Check for extensions supported by this |
|
417 // stream and get stream to read index from |
|
418 CleanupStack::PopAndDestroy(&rootStream) ; |
|
419 iBackupExtensionsSupported = header.getBackupExtensionsSupported(); |
|
420 TStreamId indexStreamId = header.getIndexStreamId() ; |
|
421 indexStream.OpenLC (*store, indexStreamId) ; |
|
422 } |
|
423 |
|
424 CRepositoryBackupStreamIndex *restoreStreamIndex = CRepositoryBackupStreamIndex::NewLC(); |
|
425 restoreStreamIndex->InternalizeL(indexStream, iBackupExtensionsSupported); |
|
426 |
|
427 |
|
428 // Iterate through index and attempt restore of each repository stream |
|
429 // we find in it. |
|
430 restoreStreamIndex->Reset() ; |
|
431 TUid repositoryUid ; |
|
432 TStreamId settingsStreamId ; |
|
433 TStreamId deletedSettingsStreamId ; |
|
434 |
|
435 while (restoreStreamIndex->GetNext(repositoryUid, settingsStreamId, deletedSettingsStreamId) == KErrNone) |
|
436 { |
|
437 iRepository->OpenL(repositoryUid, *iNotifier, EFalse); |
|
438 iRepository->FailAllTransactions(); |
|
439 iRepository->RestoreRepositoryContentsL(*store, settingsStreamId, deletedSettingsStreamId); |
|
440 iRepository->CommitChangesL(); |
|
441 iRepository->Close(*iNotifier) ; |
|
442 } |
|
443 |
|
444 CleanupStack::PopAndDestroy(restoreStreamIndex) ; |
|
445 CleanupStack::PopAndDestroy(&indexStream); |
|
446 CleanupStack::PopAndDestroy(store); |
|
447 iFs.Delete(restoreFilePath.FullName()) ; |
|
448 } |
|
449 |
|
450 // |
|
451 // CRepositoryBackupClient::CompleteOwnerIdLookupTableL |
|
452 // |
|
453 // Open each repository in TServerResources::iDataDirectory. |
|
454 // Save the Rep UID and Owner Id of the rep to be used by |
|
455 // InitialiseGetProxyBackupDataL. |
|
456 void CRepositoryBackupClient::CompleteOwnerIdLookupTableL() |
|
457 { |
|
458 |
|
459 // Read contents of persist, install, and ROM directories and |
|
460 // use them to build a list of repository candidates. |
|
461 RArray <TUint32> repositoryList ; |
|
462 CleanupClosePushL(repositoryList) ; |
|
463 |
|
464 for (TBackupDirectoryScan scanDir = EScanRom; scanDir <= EScanPersist; scanDir = (TBackupDirectoryScan)(scanDir+1)) |
|
465 { |
|
466 TPtrC directoryName ; |
|
467 switch (scanDir) |
|
468 { |
|
469 case EScanRom : |
|
470 directoryName.Set(TServerResources::iRomDirectory->Des()) ; |
|
471 break ; |
|
472 |
|
473 case EScanInstall : |
|
474 directoryName.Set(TServerResources::iInstallDirectory->Des()) ; |
|
475 break ; |
|
476 |
|
477 case EScanPersist : |
|
478 directoryName.Set(TServerResources::iDataDirectory->Des()) ; |
|
479 break ; |
|
480 } |
|
481 |
|
482 CDir* directory; |
|
483 User::LeaveIfError(iFs.GetDir(directoryName, KEntryAttNormal, ESortNone, directory)); |
|
484 CleanupStack::PushL(directory); |
|
485 const TInt directoryFileCount = directory->Count(); |
|
486 for (TInt i = 0; i < directoryFileCount; i++) |
|
487 { |
|
488 // Attempt to extract a repository UID from directory entry |
|
489 TUid uid; |
|
490 if (KErrNone == TServerResources::GetUid(const_cast<TEntry&>((*directory)[i]), uid)) |
|
491 { |
|
492 repositoryList.InsertInUnsignedKeyOrder(uid.iUid) ; |
|
493 |
|
494 } |
|
495 } |
|
496 CleanupStack::PopAndDestroy(directory); |
|
497 } |
|
498 |
|
499 // Open all repositories in turn. Save repository UID and owner ID |
|
500 // in lookup table. |
|
501 for(TInt i = 0; i<repositoryList.Count(); i++) |
|
502 { |
|
503 // Look to see if this repository already has an entry in the owner ID lookup table |
|
504 if ( TServerResources::FindOwnerIdLookupMapping(repositoryList[i]) == KErrNotFound) |
|
505 { |
|
506 // Need to TRAP here as otherwise if ANY repository fails to open |
|
507 // (e.g. due to corruption) it would cause the entire backup to |
|
508 // fail |
|
509 TRAPD(err, iRepository->OpenL(TUid::Uid(repositoryList[i]), *iNotifier)); |
|
510 if (err == KErrNoMemory) |
|
511 { |
|
512 User::Leave(err) ; |
|
513 } |
|
514 |
|
515 else if (err == KErrNone) |
|
516 { |
|
517 // The act of opening a repository will cause it to add itself to the |
|
518 // Repository/Owner UID mapping table so we don't need to do anything |
|
519 // and can close it immediately! |
|
520 iRepository->Close(*iNotifier); |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 CleanupStack::PopAndDestroy() ; // repositoryList |
|
526 } |
|
527 |
|
528 // CRepositoryBackupClient::InitialiseGetProxyBackupDataL |
|
529 // |
|
530 // Prepare data to be backed up. We get the Sid/Uid of the entity whos data |
|
531 // is to be backed up. What we do is to open each repository in turn (identified |
|
532 // by directory listing), check its owner, and if it matches the Sid/Uid we've |
|
533 // been given by secure backup externalise it to a stream within a file store. |
|
534 // |
|
535 void CRepositoryBackupClient::InitialiseGetProxyBackupDataL(TSecureId aSID, TDriveNumber /* aDrive */) |
|
536 { |
|
537 // Prepare data for backup. |
|
538 |
|
539 // Create file store |
|
540 TParse backupFilePath ; |
|
541 User::LeaveIfError(backupFilePath.Set(KBackupFileName, TServerResources::iBURDirectory, &KBackupFileExt)); |
|
542 CDirectFileStore* store = CDirectFileStore::ReplaceLC(iFs, backupFilePath.FullName(), |
|
543 (EFileWrite | EFileShareExclusive)); |
|
544 const TUid uid2 = KNullUid ; |
|
545 store->SetTypeL(TUidType(KDirectFileStoreLayoutUid, uid2, KServerUid3)) ; |
|
546 |
|
547 // Create a Backup Stream index |
|
548 CRepositoryBackupStreamIndex* backupStreamIndex = CRepositoryBackupStreamIndex::NewLC(); |
|
549 |
|
550 // Find the reps owned by aSID |
|
551 for(TInt i = 0; i < TServerResources::iOwnerIdLookUpTable.Count(); ++i) |
|
552 { |
|
553 const TOwnerIdMapping& lookupTableEntry = TServerResources::iOwnerIdLookUpTable[i]; |
|
554 |
|
555 if ( lookupTableEntry.iOwner == aSID ) |
|
556 { |
|
557 // Found one match, open the repository and externalise content. |
|
558 TUid uid = TUid::Uid(lookupTableEntry.iRepUid); |
|
559 TRAPD(err,iRepository->OpenL(uid, *iNotifier)); |
|
560 if (err == KErrNoMemory) |
|
561 { |
|
562 User::Leave(err) ; |
|
563 } |
|
564 else if (err == KErrNone) |
|
565 { |
|
566 iRepository->FailAllTransactions(); |
|
567 // Add to store index and externalise |
|
568 // repository contents |
|
569 TStreamId settingStreamId ; |
|
570 TStreamId deletedSettingsStreamId ; |
|
571 iRepository->StoreRepositoryContentsL(*store, settingStreamId, deletedSettingsStreamId); |
|
572 backupStreamIndex->AddL(uid, settingStreamId, deletedSettingsStreamId) ; |
|
573 // Close repository. |
|
574 iRepository->Close(*iNotifier); |
|
575 } |
|
576 } |
|
577 } |
|
578 // Write the stream index/dictionary as root stream within the store |
|
579 // so we can access it when we do a restore later on |
|
580 RStoreWriteStream indexStream ; |
|
581 TStreamId indexStreamId = indexStream.CreateLC(*store) ; |
|
582 backupStreamIndex->ExternalizeL(indexStream) ; |
|
583 indexStream.CommitL() ; |
|
584 CleanupStack::PopAndDestroy(&indexStream) ; |
|
585 CleanupStack::PopAndDestroy (backupStreamIndex) ; |
|
586 |
|
587 // Create the Header and write it as the root stream within the store |
|
588 // so we can access it when we do a restore later on |
|
589 TRepositoryBackupStreamHeader header (indexStreamId) ; |
|
590 RStoreWriteStream rootStream ; |
|
591 TStreamId rootStreamId = rootStream.CreateLC(*store) ; |
|
592 header.ExternalizeL(rootStream) ; |
|
593 rootStream.CommitL() ; |
|
594 |
|
595 CleanupStack::PopAndDestroy(&rootStream) ; |
|
596 store->SetRootL(rootStreamId); |
|
597 store->CommitL(); |
|
598 CleanupStack::PopAndDestroy(store) ; |
|
599 |
|
600 // Attempt to open file containing store ready to read back and send to |
|
601 // BUR engine as a stream of bytes. |
|
602 User::LeaveIfError(iFile.Open(iFs, backupFilePath.FullName(), (EFileRead | EFileShareExclusive))) ; |
|
603 } |
|
604 |
|
605 |
|
606 |
|
607 |
|
608 // |
|
609 // CRepositoryBackupClient::InitialiseRestoreProxyBaseDataL |
|
610 // |
|
611 // Called when secure backup is about to start sending restore data. |
|
612 // |
|
613 void CRepositoryBackupClient::InitialiseRestoreProxyBaseDataL(TSecureId aSID, TDriveNumber /* aDrive*/) |
|
614 { |
|
615 // prepare for restore - Don't think we need to do anything here except prepare |
|
616 // data structures to receive incoming data |
|
617 |
|
618 // Save SID so we can check that it corresponds with the owner information |
|
619 // in the restored data. |
|
620 iSid = aSID ; |
|
621 |
|
622 // Open file to receive restored data |
|
623 TParse restoreFilePath ; |
|
624 User::LeaveIfError(restoreFilePath.Set(KRestoreFileName, TServerResources::iBURDirectory, &KRestoreFileExt)); |
|
625 User::LeaveIfError(iFile.Replace (iFs, restoreFilePath.FullName(), (EFileWrite | EFileShareExclusive))); |
|
626 } |
|
627 |
|
628 |
|
629 |
|
630 |
|
631 // |
|
632 // CRepositoryBackupClient::RestoreBaseDataSectionL |
|
633 // |
|
634 // Called when secure backup has a chunk of restore data for us. Last data |
|
635 // segment identified by aFinished. |
|
636 // |
|
637 void CRepositoryBackupClient::RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished) |
|
638 { |
|
639 // Receive a chunk of restore data in aBuffer |
|
640 User::LeaveIfError(iFile.Write (aBuffer)) ; |
|
641 if (aFinished) |
|
642 { |
|
643 iFile.Close() ; |
|
644 |
|
645 // All restore data recived so we can now recreate the repositories from the |
|
646 // backup store |
|
647 RestoreCompleteL(); |
|
648 } |
|
649 } |
|
650 |
|
651 void CRepositoryBackupClient::TerminateMultiStageOperation() |
|
652 { |
|
653 // Backup/Restore operation aborted! |
|
654 // Tidy up all temporary data. |
|
655 } |
|
656 |
|
657 |
|
658 // |
|
659 // CRepositoryBackupClient::GetDataChecksum |
|
660 // |
|
661 // Not required and we don't implement it. |
|
662 // |
|
663 TUint CRepositoryBackupClient::GetDataChecksum(TDriveNumber /* aDrive */) |
|
664 { |
|
665 return KArbitraryNumber; |
|
666 } |
|
667 |
|
668 // |
|
669 // CRepositoryBackupClient::GetSnapshotDataL |
|
670 // |
|
671 // Only required for incremental backup (which we don't support |
|
672 // |
|
673 void CRepositoryBackupClient::GetSnapshotDataL(TDriveNumber /* aDrive */, TPtr8& /* aBuffer */, TBool& /* aFinished */) |
|
674 { |
|
675 User::Leave(KErrNotSupported) ; |
|
676 } |
|
677 |
|
678 // |
|
679 // CRepositoryBackupClient::InitialiseGetBackupDataL |
|
680 // |
|
681 // Used by "normal" active backup to prepare data - we use |
|
682 // InitialiseRestoreProxyBaseDataL so this shouldn't be called! |
|
683 // |
|
684 void CRepositoryBackupClient::InitialiseGetBackupDataL(TDriveNumber /* aDrive */) |
|
685 { |
|
686 User::Leave(KErrNotSupported) ; |
|
687 } |
|
688 |
|
689 |
|
690 |
|
691 void CRepositoryBackupClient::InitialiseRestoreBaseDataL(TDriveNumber /* aDrive */) |
|
692 { |
|
693 // Check this! I Don't think this method should get called as we're a proxy |
|
694 // and so implement InitialiseGetProxyBackupDataL!! |
|
695 User::Leave(KErrNotSupported) ; |
|
696 } |
|
697 |
|
698 |
|
699 |
|
700 |
|
701 void CRepositoryBackupClient::InitialiseRestoreIncrementDataL(TDriveNumber /* aDrive */) |
|
702 { |
|
703 // Check this! I Don't think this method should get called as we're a proxy |
|
704 // so don't do incremental backup!! |
|
705 User::Leave(KErrNotSupported) ; |
|
706 } |
|
707 |
|
708 |
|
709 |
|
710 void CRepositoryBackupClient::RestoreIncrementDataSectionL(TDesC8& /* aBuffer */, TBool /* aFinished */) |
|
711 { |
|
712 // Check this! I Don't think this method should get called as we're a proxy |
|
713 // so don't do incremental backup!! |
|
714 User::Leave(KErrNotSupported) ; |
|
715 } |
|
716 |
|
717 |
|
718 // |
|
719 // Incremental backup isn't supported for the proxy data holder model so this |
|
720 // method should never be called. |
|
721 // |
|
722 // Not acceptable to leave even though it's an ...L function which we don't implement |
|
723 void CRepositoryBackupClient::AllSnapshotsSuppliedL() |
|
724 { |
|
725 ; |
|
726 } |
|
727 |
|
728 |
|
729 |
|
730 // |
|
731 // Incremental backup not supported |
|
732 // |
|
733 void CRepositoryBackupClient::ReceiveSnapshotDataL(TDriveNumber /* aDrive */, TDesC8& /* aBuffer */, TBool /* aLastSection */) |
|
734 { |
|
735 User::Leave(KErrNotSupported) ; |
|
736 } |
|
737 |
|
738 |