From 8fc9c9630598492b193e1932db4a4176f8ad939c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Wed, 6 Apr 2016 08:44:38 +0200 Subject: [PATCH] Reworked decisions to undo related to unreadable records When an INDX or MFT record could not be read while undoing the creation of this record, there is nothing to do. However if this was undoing the deletion of the last entry in an index, a new void index block has to be created. --- ntfsprogs/playlog.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/ntfsprogs/playlog.c b/ntfsprogs/playlog.c index 00fa8c67..d8ba333d 100644 --- a/ntfsprogs/playlog.c +++ b/ntfsprogs/playlog.c @@ -4731,10 +4731,16 @@ printf("record lsn 0x%llx is %s than action %d lsn 0x%llx\n", err = 1; } } else { - /* Undoing a record create which was not done ? */ -// TODO make sure this is about a newly allocated record (with bad fixup) -// TODO check this is inputting a full record (record lth == data lth) - buffer = (char*)calloc(1, mftrecsz); + /* + * Could not read the MFT record : + * if this is undoing a record create (from scratch) + * which did not take place, there is nothing to redo, + * otherwise this is an error. + */ + if (check_full_mft(action,TRUE)) + executed = FALSE; + else + err = 1; } break; case ON_INDX : @@ -4765,13 +4771,28 @@ printf("index lsn 0x%llx is %s than action %d lsn 0x%llx\n", err = 1; } } else { - /* Undoing a record create which was not done ? */ -// TODO make sure this is about a newly allocated record (with bad fixup) -// TODO check this is inputting a full record (record lth == data lth) -// recreate an INDX record if this is the first entry - buffer = (char*)calloc(1, xsize); - err = create_indx(vol, action, buffer); - executed = TRUE; + /* + * Could not read the INDX record : + * if this is undoing a record create (from scratch) + * which did not take place, there is nothing to redo, + * otherwise this must be an error. + * However, after deleting the last index allocation + * in a block, the block is apparently zeroed + * and cannot be read. In this case we have to + * create an initial index block and apply the undo. + */ + if (check_full_index(action,TRUE)) + executed = FALSE; + else { + err = 1; + if (uop == AddIndexEntryAllocation) { + executed = TRUE; + buffer = (char*)calloc(1, xsize); + if (buffer) + err = create_indx(vol, + action, buffer); + } + } } break; case ON_RAW :