|
1 /* |
|
2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "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 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * CIntegrityServices implementation |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 /** |
|
21 @file |
|
22 @released |
|
23 @internalTechnology |
|
24 */ |
|
25 |
|
26 #include "integrityservices.h" |
|
27 #include "journal.h" |
|
28 #include "log.h" |
|
29 #include "cleanuputils.h" |
|
30 #include "operationfunctions.h" |
|
31 |
|
32 |
|
33 #include <f32file.h> |
|
34 |
|
35 using namespace Swi; |
|
36 |
|
37 namespace Swi |
|
38 { |
|
39 /** |
|
40 * This is a trivial C class that just encapsulates a TEntryArray object in order to |
|
41 * facilitate its storage on the heap. |
|
42 * |
|
43 * @released |
|
44 * @internalComponent |
|
45 */ |
|
46 class CEntryArray : public CBase |
|
47 { |
|
48 public: |
|
49 inline TEntryArray& operator()(); |
|
50 |
|
51 private: |
|
52 /** |
|
53 * Container to hold file entries |
|
54 */ |
|
55 TEntryArray iEntryArray; |
|
56 }; |
|
57 |
|
58 inline TEntryArray& CEntryArray::operator()() |
|
59 { |
|
60 return iEntryArray; |
|
61 } |
|
62 } //namespace |
|
63 |
|
64 EXPORT_C CIntegrityServices* CIntegrityServices::NewL(TInt64 aTransactionID, const TDesC& aPath) |
|
65 { |
|
66 CIntegrityServices* self = CIntegrityServices::NewLC(aTransactionID, aPath); |
|
67 CleanupStack::Pop(self); |
|
68 return self; |
|
69 } |
|
70 |
|
71 EXPORT_C CIntegrityServices* CIntegrityServices::NewLC(TInt64 aTransactionID, const TDesC& aPath) |
|
72 { |
|
73 CIntegrityServices* self = new(ELeave) CIntegrityServices(aTransactionID); |
|
74 CleanupStack::PushL(self); |
|
75 self->ConstructL(aPath); |
|
76 return self; |
|
77 } |
|
78 |
|
79 EXPORT_C CIntegrityServices::CIntegrityServices(TInt64 aTransactionID) : iTransactionID(aTransactionID) |
|
80 { |
|
81 } |
|
82 |
|
83 EXPORT_C CIntegrityServices::~CIntegrityServices() |
|
84 { |
|
85 delete iJournal; |
|
86 iFs.Close(); |
|
87 |
|
88 iLoader.Close(); |
|
89 } |
|
90 |
|
91 EXPORT_C void CIntegrityServices::ConstructL(const TDesC& aPath) |
|
92 { |
|
93 DEBUG_PRINTF2(_L8("Integrity Services - Opening session with Session ID %Ld."), iTransactionID); |
|
94 |
|
95 // check that the supplied path is valid |
|
96 User::LeaveIfError(iFs.Connect()); |
|
97 User::LeaveIfError(iFs.IsValidName(aPath)); |
|
98 |
|
99 User::LeaveIfError(iLoader.Connect()); |
|
100 |
|
101 // store the journal path and create the journal |
|
102 TParsePtrC pathPtr(aPath); |
|
103 iJournalPath = pathPtr.Path(); |
|
104 iJournal = CJournal::NewL(iFs, iLoader, iTransactionID, iJournalPath); |
|
105 iSystemDrive = RFs::GetSystemDrive(); |
|
106 } |
|
107 |
|
108 void CIntegrityServices::SimulatePowerFailureL(TFailType /*aFailType*/, TFailPosition /*aFailPosition*/, const TDesC& /*aFailFileName*/) |
|
109 { |
|
110 // only implemented in derived test class |
|
111 } |
|
112 |
|
113 /*static*/ void CIntegrityServices::NormalizeDirectoryName(TDes& aFileName) |
|
114 { |
|
115 // Directories are represented in the integrity tree and integrity journal exactly as files, |
|
116 // without the trailing slash |
|
117 TInt lastCharPos = aFileName.Length() - 1; |
|
118 if ( lastCharPos >= 0 && aFileName[lastCharPos] == KPathDelimiter && |
|
119 aFileName.Locate(KPathDelimiter) != lastCharPos) // Take care not to remove slash from "c:\" and the like |
|
120 { |
|
121 aFileName.Delete(lastCharPos, 1); |
|
122 } |
|
123 } |
|
124 |
|
125 EXPORT_C void CIntegrityServices::AddL(const TDesC& aFileName) |
|
126 { |
|
127 DEBUG_PRINTF3(_L("Integrity Services - Session %Ld, Adding File: %S."), |
|
128 iTransactionID, &aFileName); |
|
129 |
|
130 HBufC* localFilenameHeap = aFileName.AllocLC(); |
|
131 TPtr localFilename = localFilenameHeap->Des(); |
|
132 NormalizeDirectoryName(localFilename); // If it is a directory name, make sure to normalize it |
|
133 |
|
134 // Record the added file or directory in the journal |
|
135 SimulatePowerFailureL(EFailAddingNewFile, EBeforeJournal, aFileName); |
|
136 iJournal->AddL(localFilename); |
|
137 SimulatePowerFailureL(EFailAddingNewFile, EAfterJournal, aFileName); |
|
138 CleanupStack::PopAndDestroy(localFilenameHeap); |
|
139 } |
|
140 |
|
141 void CIntegrityServices::CopyToBackupL(const TDesC& aSource, const TDesC& aBackup) |
|
142 { |
|
143 // Copying a file isn't atomic so we create a temporary backup file first |
|
144 RBuf backupTmpName; |
|
145 backupTmpName.Create(aBackup.Length() + 4); |
|
146 CleanupClosePushL(backupTmpName); |
|
147 backupTmpName.Copy(aBackup); |
|
148 _LIT(KTmpExt, ".tmp"); |
|
149 backupTmpName.Append(KTmpExt); |
|
150 |
|
151 // Copying a file is not an atomic operation so add the temporary |
|
152 // file to the journal to enable cleanup if a power failure occurs before |
|
153 // the rename |
|
154 SimulatePowerFailureL(EFailAddingTempFile, EBeforeJournal, backupTmpName); |
|
155 iJournal->TemporaryL(backupTmpName); |
|
156 SimulatePowerFailureL(EFailAddingTempFile, EAfterJournal, backupTmpName); |
|
157 |
|
158 CFileMan* fileMan = CFileMan::NewL(iFs); |
|
159 CleanupStack::PushL(fileMan); |
|
160 |
|
161 TInt err = fileMan->Copy(aSource, backupTmpName); |
|
162 DEBUG_PRINTF4(_L("CopyToBackupL: Copying %S to %S, err %d"), &aSource, &backupTmpName, err); |
|
163 User::LeaveIfError(err); |
|
164 |
|
165 // Backup is complete, use RFs::Rename as atomic 'commit' of backup |
|
166 err = iFs.Rename(backupTmpName, aBackup); |
|
167 DEBUG_PRINTF2(_L("CopyToBackupL: Commit backup returned error %d"), err); |
|
168 User::LeaveIfError(err); |
|
169 CleanupStack::PopAndDestroy(2, &backupTmpName); // backupTmpName, fileMan |
|
170 |
|
171 // Now the backup is safe the original can be deleted |
|
172 err = iLoader.Delete(aSource); |
|
173 DEBUG_PRINTF3(_L("CopyToBackupL: RLoader::Delete %S returned error %d"), &aSource, err); |
|
174 User::LeaveIfError(err); |
|
175 } |
|
176 |
|
177 EXPORT_C void CIntegrityServices::RemoveL(const TDesC& aFileName) |
|
178 { |
|
179 DEBUG_PRINTF3(_L("Integrity Services - Session %Ld, Removing File: %S"), iTransactionID, &aFileName); |
|
180 |
|
181 // before doing anything check that the file or directory exists |
|
182 TEntry entry; |
|
183 User::LeaveIfError(iFs.Entry(aFileName, entry)); |
|
184 |
|
185 // We might need to grow this buffer by one byte later |
|
186 HBufC* localFilenameHeap = HBufC::NewLC(aFileName.Length() + 1); |
|
187 TPtr localFilename = localFilenameHeap->Des(); |
|
188 localFilename.Copy(aFileName); |
|
189 |
|
190 TBool isFilenameDir = entry.IsDir(); |
|
191 // The "if" below is not functionally necessary, but it is a slight optimization - |
|
192 // so that we won't attempt to normalize directory name on files. The optimization is not |
|
193 // done in AddL or NormalizeDirectoryName itself, since we don't have future use for TEntry there, and the cost for RFs::Entry overweighs the one for NormalizeDirectoryName |
|
194 if ( isFilenameDir ) |
|
195 { |
|
196 NormalizeDirectoryName(localFilename); |
|
197 } |
|
198 |
|
199 RBuf backupFileName; |
|
200 backupFileName.CreateL(KMaxFileName); |
|
201 CleanupClosePushL(backupFileName); |
|
202 SimulatePowerFailureL(EFailRemovingFile, EBeforeJournal, aFileName); |
|
203 iJournal->RemoveL(localFilename, backupFileName); |
|
204 |
|
205 if (backupFileName.Length()) |
|
206 { |
|
207 SimulatePowerFailureL(EFailRemovingFile, EAfterJournal, aFileName); |
|
208 |
|
209 TInt err = iFs.MkDirAll(backupFileName); |
|
210 if(err != KErrNone && err != KErrAlreadyExists) |
|
211 { |
|
212 User::Leave(err); |
|
213 } |
|
214 |
|
215 SimulatePowerFailureL(EFailRemovingFile, EBeforeAction, aFileName); |
|
216 |
|
217 _LIT(KSysBinMatch, "?:\\sys\\bin\\*"); |
|
218 if (localFilename.MatchF(KSysBinMatch) == 0) |
|
219 { |
|
220 // A copy is slower than a rename to only use the |
|
221 // demand paging safe API for files in sys\bin |
|
222 CopyToBackupL(localFilename, backupFileName); |
|
223 } |
|
224 else |
|
225 { |
|
226 err = iFs.Rename(localFilename, backupFileName); |
|
227 DEBUG_PRINTF4(_L("Renamed %S as %S error %d"), &localFilename, &backupFileName, err); |
|
228 User::LeaveIfError(err); |
|
229 } |
|
230 SimulatePowerFailureL(EFailRemovingFile, EAfterAction, aFileName); |
|
231 } |
|
232 else |
|
233 { |
|
234 DEBUG_PRINTF2(_L("%S already backed up"), &aFileName); |
|
235 SimulatePowerFailureL(EFailRemovingFile, EBeforeAction, aFileName); |
|
236 // If backupFileName is zero-length, the file was added earlier |
|
237 // in the same journal and doesn't need to be backed up. |
|
238 if (isFilenameDir) |
|
239 { |
|
240 CFileMan* fileman = CFileMan::NewL(iFs); |
|
241 CleanupStack::PushL(fileman); |
|
242 // Make sure to append slash before calling RmDir - otherwise it deletes the parent directory |
|
243 if (localFilename[localFilename.Length()-1] != KPathDelimiter) |
|
244 { |
|
245 localFilename.Append(KPathDelimiter); |
|
246 } |
|
247 User::LeaveIfError(fileman->RmDir(localFilename)); // A directory cannot be a paged exec., so we don't have to use iLoader |
|
248 CleanupStack::PopAndDestroy(fileman); |
|
249 } |
|
250 else |
|
251 { |
|
252 User::LeaveIfError(iLoader.Delete(aFileName)); |
|
253 } |
|
254 SimulatePowerFailureL(EFailRemovingFile, EAfterAction, aFileName); |
|
255 } |
|
256 |
|
257 // Don't leave an empty directory structure, try pruning it |
|
258 RemoveDirectoryTreeL(iFs, aFileName); |
|
259 |
|
260 CleanupStack::PopAndDestroy(2, localFilenameHeap); // backupFileName |
|
261 } |
|
262 |
|
263 EXPORT_C void CIntegrityServices::TemporaryL(const TDesC& aFileName) |
|
264 { |
|
265 DEBUG_PRINTF3(_L("Integrity Services - Session %Ld, Temporary File: %S."), |
|
266 iTransactionID, &aFileName); |
|
267 |
|
268 // record the temporary file or directory in the journal |
|
269 SimulatePowerFailureL(EFailAddingTempFile, EBeforeJournal, aFileName); |
|
270 iJournal->TemporaryL(aFileName); |
|
271 SimulatePowerFailureL(EFailAddingTempFile, EAfterJournal, aFileName); |
|
272 } |
|
273 |
|
274 EXPORT_C void CIntegrityServices::CommitL() |
|
275 { |
|
276 DEBUG_PRINTF2(_L8("Integrity Services - Commiting Session %Ld."), iTransactionID); |
|
277 iJournal->SynchL(); |
|
278 iJournal->StartCommitL(); |
|
279 |
|
280 SimulatePowerFailureL(EFailInstallComplete, EBeforeJournal, KNullDesC); |
|
281 iJournal->WriteJournalEventL(EInstallComplete); |
|
282 SimulatePowerFailureL(EFailInstallComplete, EAfterJournal, KNullDesC); |
|
283 |
|
284 DeleteFilesL(*iJournal, EBackupFile); |
|
285 |
|
286 SimulatePowerFailureL(EFailBackupFilesRemoved, EBeforeJournal, KNullDesC); |
|
287 iJournal->WriteJournalEventL(EBackupFilesRemoved); |
|
288 SimulatePowerFailureL(EFailBackupFilesRemoved, EAfterJournal, KNullDesC); |
|
289 |
|
290 DeleteFilesL(*iJournal, ETempFile); |
|
291 |
|
292 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
293 iJournal->WriteJournalEventL(ETempFilesRemoved); |
|
294 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
295 |
|
296 iJournal->FinishCommitL(); |
|
297 } |
|
298 |
|
299 EXPORT_C void CIntegrityServices::RollBackL(TBool aAllTransactions) |
|
300 { |
|
301 DEBUG_PRINTF2(_L8("Integrity Services - Rolling Back Session %Ld."), iTransactionID); |
|
302 |
|
303 if (aAllTransactions) |
|
304 { |
|
305 // search for and rollback any transaction drive list |
|
306 TDriveUnit systemDrive(iSystemDrive); |
|
307 RBuf fileSpec; |
|
308 fileSpec.CreateL(systemDrive.Name(), KMaxFileName); |
|
309 CleanupClosePushL(fileSpec); |
|
310 fileSpec.Append(iJournalPath); |
|
311 fileSpec.Append(KMatchAny); |
|
312 fileSpec.Append(KExtDelimiter); |
|
313 fileSpec.Append(KDriveExt); |
|
314 |
|
315 RDir dir; |
|
316 TInt err = dir.Open(iFs, fileSpec, KEntryAttNormal); |
|
317 if (err == KErrNone) |
|
318 { |
|
319 CEntryArray* entryArrayContainer = new (ELeave) CEntryArray; |
|
320 CleanupStack::PushL(entryArrayContainer); |
|
321 TEntryArray& entryArray = (*entryArrayContainer)(); |
|
322 err = dir.Read(entryArray); |
|
323 dir.Close(); |
|
324 if (err != KErrNone && err != KErrEof) |
|
325 { |
|
326 User::Leave(err); |
|
327 } |
|
328 TInt entryCount = entryArray.Count(); |
|
329 for(TInt index = 0; index < entryCount; ++index) |
|
330 { |
|
331 // check that the entry is not a directory |
|
332 if(!entryArray[index].IsDir()) |
|
333 { |
|
334 TLex lex(entryArray[index].iName); |
|
335 TInt64 transactionID; |
|
336 if(lex.Val(transactionID, EHex) == KErrNone) |
|
337 { |
|
338 CJournal* journal = NULL; |
|
339 TRAP(err, journal = CJournal::NewL(iFs, iLoader, transactionID, iJournalPath)); |
|
340 if(err == KErrNone) |
|
341 { |
|
342 CleanupStack::PushL(journal); |
|
343 // start the recovery, do not let corrupt journals prevent |
|
344 // recovery of other journals |
|
345 iStartedJournalRollback = ETrue; |
|
346 TRAP(err, RollBackJournalL(*journal)); |
|
347 if(err != KErrNone && err != KErrCorrupt) |
|
348 { |
|
349 // unexpected error |
|
350 User::Leave(err); |
|
351 } |
|
352 CleanupStack::PopAndDestroy(journal); |
|
353 } |
|
354 } |
|
355 } |
|
356 } |
|
357 CleanupStack::PopAndDestroy(entryArrayContainer); |
|
358 } |
|
359 else if(err != KErrPathNotFound && err != KErrNotFound && err != KErrNotReady) |
|
360 { |
|
361 // unexpected error |
|
362 User::Leave(err); |
|
363 } |
|
364 CleanupStack::PopAndDestroy(&fileSpec); |
|
365 } |
|
366 else |
|
367 { |
|
368 // rollback only this transaction |
|
369 TRAPD(err, RollBackJournalL(*iJournal)); |
|
370 if(err != KErrNone && err != KErrPathNotFound && err != KErrNotFound |
|
371 && err != KErrNotReady) |
|
372 { |
|
373 // unexpected error |
|
374 User::Leave(err); |
|
375 } |
|
376 } |
|
377 } |
|
378 |
|
379 void CIntegrityServices::RollBackJournalL(CJournal& aJournal) |
|
380 { |
|
381 aJournal.SynchL(); |
|
382 |
|
383 #ifdef __WINSCW__ |
|
384 // For 2 minutes after initial boot, DLLs are not unloaded. If we are doing a |
|
385 // rollback, we need to make sure any pending unloadeds are actioned, otherwise a |
|
386 // previously loaded DLL could cause the rollback to fail on windows (on arm it is legal to |
|
387 // delete a loaded DLL/EXE, whilst on windows it is not). |
|
388 RLoader loader; |
|
389 TInt r = loader.Connect(); |
|
390 if(r == KErrNone) |
|
391 { |
|
392 (void)loader.CancelLazyDllUnload(); |
|
393 loader.Close(); |
|
394 } |
|
395 #endif |
|
396 |
|
397 for(TInt index = 0; index < aJournal.Drives().Count(); index++) |
|
398 { |
|
399 // check to see if this drive has already been completed |
|
400 if(aJournal.CompletedDrives().Find(aJournal.Drives()[index]) != KErrNotFound) |
|
401 { |
|
402 continue; |
|
403 } |
|
404 |
|
405 // only attempt to recover writeable drives that are present |
|
406 TDriveInfo info; |
|
407 User::LeaveIfError(iFs.Drive(info, aJournal.Drives()[index])); |
|
408 if (!(info.iMediaAtt & KMediaAttWriteProtected) && info.iType!=EMediaNotPresent) |
|
409 { |
|
410 TRAPD(err, RollBackDriveL(aJournal, aJournal.Drives()[index])); |
|
411 if(err != KErrNone && err != KErrPathNotFound && err != KErrNotFound |
|
412 && err != KErrNotReady) |
|
413 { |
|
414 // unexpected error |
|
415 User::Leave(err); |
|
416 } |
|
417 } |
|
418 } |
|
419 } |
|
420 |
|
421 void CIntegrityServices::RollBackDriveL(CJournal& aJournal, TInt aDrive) |
|
422 { |
|
423 aJournal.StartRollbackL(aDrive); |
|
424 |
|
425 DEBUG_PRINTF3(_L8("Integrity Services - Rolling Back drive %d, last event %d."), aDrive, aJournal.LastEvent()); |
|
426 switch (aJournal.LastEvent()) |
|
427 { |
|
428 // Transaction did not complete, rollback required |
|
429 case ERemovedFile: |
|
430 case EBackupFile: |
|
431 case ETempFile: |
|
432 case EAddedFile: |
|
433 case EAddedFilesRemoved: |
|
434 case ERemovedFilesRestored: |
|
435 // rollback this individual journal from where it last got to. |
|
436 switch (aJournal.LastEventL(aDrive)) |
|
437 { |
|
438 case ERemovedFile: |
|
439 case EBackupFile: |
|
440 case ETempFile: |
|
441 case EAddedFile: |
|
442 DeleteFilesL(aJournal, EAddedFile, aDrive); |
|
443 |
|
444 SimulatePowerFailureL(EFailNewFilesRemoved, EBeforeJournal, KNullDesC); |
|
445 aJournal.WriteJournalEventL(EAddedFilesRemoved, aDrive); |
|
446 SimulatePowerFailureL(EFailNewFilesRemoved, EAfterJournal, KNullDesC); |
|
447 |
|
448 RestoreFilesL(aJournal, aDrive); |
|
449 |
|
450 SimulatePowerFailureL(EFailOldFilesRestored, EBeforeJournal, KNullDesC); |
|
451 aJournal.WriteJournalEventL(ERemovedFilesRestored, aDrive); |
|
452 SimulatePowerFailureL(EFailOldFilesRestored, EAfterJournal, KNullDesC); |
|
453 |
|
454 DeleteFilesL(aJournal, ETempFile, aDrive); |
|
455 |
|
456 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
457 aJournal.WriteJournalEventL(ETempFilesRemoved, aDrive); |
|
458 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
459 break; |
|
460 |
|
461 // Transaction did not complete, rollback did not complete, resume rollback |
|
462 case EAddedFilesRemoved: |
|
463 RestoreFilesL(aJournal, aDrive); |
|
464 |
|
465 SimulatePowerFailureL(EFailOldFilesRestored, EBeforeJournal, KNullDesC); |
|
466 aJournal.WriteJournalEventL(ERemovedFilesRestored, aDrive); |
|
467 SimulatePowerFailureL(EFailOldFilesRestored, EAfterJournal, KNullDesC); |
|
468 |
|
469 DeleteFilesL(aJournal, ETempFile, aDrive); |
|
470 |
|
471 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
472 aJournal.WriteJournalEventL(ETempFilesRemoved, aDrive); |
|
473 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
474 break; |
|
475 |
|
476 case ERemovedFilesRestored: |
|
477 DeleteFilesL(aJournal, ETempFile, aDrive); |
|
478 |
|
479 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
480 aJournal.WriteJournalEventL(ETempFilesRemoved, aDrive); |
|
481 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
482 break; |
|
483 |
|
484 case ETempFilesRemoved: |
|
485 break; |
|
486 |
|
487 // nothing was done, just delete the journal file |
|
488 case ENone: |
|
489 break; |
|
490 |
|
491 // Erk! Bad state, bad state! |
|
492 default: |
|
493 User::Leave(KErrCorrupt); |
|
494 break; |
|
495 } |
|
496 break; |
|
497 |
|
498 // Transaction complete, just need to remove the backup |
|
499 case EInstallComplete: |
|
500 case EBackupFilesRemoved: |
|
501 switch (aJournal.LastEventL(aDrive)) |
|
502 { |
|
503 // At least one journal had a complete transaction... |
|
504 // roll forwards all journal files. |
|
505 case ERemovedFile: |
|
506 case EBackupFile: |
|
507 case ETempFile: |
|
508 case EAddedFile: |
|
509 case EInstallComplete: |
|
510 DeleteFilesL(aJournal, EBackupFile, aDrive); |
|
511 |
|
512 SimulatePowerFailureL(EFailBackupFilesRemoved, EBeforeJournal, KNullDesC); |
|
513 aJournal.WriteJournalEventL(EBackupFilesRemoved, aDrive); |
|
514 SimulatePowerFailureL(EFailBackupFilesRemoved, EAfterJournal, KNullDesC); |
|
515 |
|
516 DeleteFilesL(aJournal, ETempFile, aDrive); |
|
517 |
|
518 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
519 aJournal.WriteJournalEventL(ETempFilesRemoved, aDrive); |
|
520 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
521 break; |
|
522 |
|
523 case EBackupFilesRemoved: |
|
524 DeleteFilesL(aJournal, ETempFile, aDrive); |
|
525 |
|
526 SimulatePowerFailureL(EFailTempFilesRemoved, EBeforeJournal, KNullDesC); |
|
527 aJournal.WriteJournalEventL(ETempFilesRemoved, aDrive); |
|
528 SimulatePowerFailureL(EFailTempFilesRemoved, EAfterJournal, KNullDesC); |
|
529 break; |
|
530 |
|
531 case ETempFilesRemoved: |
|
532 break; |
|
533 |
|
534 // nothing was done, just delete the journal file |
|
535 case ENone: |
|
536 break; |
|
537 |
|
538 // unknown state |
|
539 default: |
|
540 User::Leave(KErrCorrupt); |
|
541 break; |
|
542 } |
|
543 break; |
|
544 |
|
545 case ETempFilesRemoved: |
|
546 break; |
|
547 |
|
548 // nothing was done, just delete the journal file |
|
549 case ENone: |
|
550 break; |
|
551 |
|
552 // unknown state |
|
553 default: |
|
554 User::Leave(KErrCorrupt); |
|
555 break; |
|
556 } |
|
557 |
|
558 aJournal.FinishRollbackL(aDrive); |
|
559 } |
|
560 |
|
561 void CIntegrityServices::RestoreFilesL(CJournal& aJournal, TInt aDrive) |
|
562 { |
|
563 DEBUG_PRINTF2(_L8("Integrity Services - RestoreFilesL drive = %d"), aDrive); |
|
564 if (aDrive == -1) |
|
565 { |
|
566 // This applies to all journals |
|
567 aJournal.RestoreFilesL(ERemovedFile, *this, EFailRestoringFile); |
|
568 } |
|
569 else |
|
570 { |
|
571 // specific drive version |
|
572 aJournal.RestoreFilesL(ERemovedFile, aDrive, *this, EFailRestoringFile); |
|
573 } |
|
574 } |
|
575 |
|
576 void CIntegrityServices::DeleteFilesL(CJournal& aJournal, TIntegrityServicesEvent aEvent, TInt aDrive) |
|
577 { |
|
578 DEBUG_PRINTF3(_L8("Integrity Services - Delete Files drive = %d, event = %d"), aDrive, aEvent); |
|
579 if (aDrive == -1) |
|
580 { |
|
581 // This applies to all journals |
|
582 aJournal.DeleteFilesL(aEvent, *this, EFailDeletingFile); |
|
583 } |
|
584 else |
|
585 { |
|
586 // specific drive version |
|
587 aJournal.DeleteFilesL(aEvent, aDrive, *this, EFailDeletingFile); |
|
588 } |
|
589 } |