enh: try harder to find RS02/RS03 sigs in non-exhaustive mode
Look at the extensive comments in the code for more context.
This commit is contained in:
@@ -167,6 +167,7 @@ int RS02Recognize(Image *image)
|
||||
Bitmap *try_next_header, *try_next_modulo;
|
||||
gint64 pos;
|
||||
gint64 header_modulo;
|
||||
gint64 triesleft = -1; /* infinity */
|
||||
int read_count = 0;
|
||||
int answered_continue = FALSE;
|
||||
gint64 max_sectors = 0;
|
||||
@@ -207,15 +208,37 @@ int RS02Recognize(Image *image)
|
||||
}
|
||||
}
|
||||
|
||||
/*** No exhaustive search on optical media unless explicitly requested. */
|
||||
/* This concludes the non-exhaustive search, where we tried to look for
|
||||
an ECC header signature on the sector right after the end of the ISO
|
||||
data. This doesn't always work, as some software tend to add some sectors
|
||||
after the end of the ISO (ImgBurn does this), or because the medium doesn't
|
||||
have any ISO9600 structure at all (some have only UDF for example), in that
|
||||
case the above quick search just does nothing.
|
||||
|
||||
By default, we don't launch an exhaustive search unless asked for.
|
||||
For example on the medium-info page, we won't do it unless enabled in the options,
|
||||
as the inserted medium might not have RS02 nor RS03 at all.
|
||||
Of course, when doing verify or repair, as it implies the user knows there is
|
||||
some ECC correction available on the medium, our caller will always require
|
||||
an exhaustive search. It's also always enabled if we're not reading from a
|
||||
drive but from a file on the hard drive, as seeking is very fast.
|
||||
|
||||
However even if not asked for an exhaustive search, and due to what has been
|
||||
explained in the first paragraph, we'll always try to read at least 3 sectors
|
||||
using the exhaustive search mechanism. On most images having ECC data, we'll
|
||||
find the header on the first try, at least on easy cases. This is a tradeoff
|
||||
to avoid having to display "no ECC data" on the medium-info page just because
|
||||
we didn't bother looking for it too hard, without bringing in the full
|
||||
exhaustive search which can take seconds or minutes on an optical drive with
|
||||
a medium that, in the end, doesn't have any ECC data.
|
||||
*/
|
||||
|
||||
if(!Closure->examineRS02 && image->type == IMAGE_MEDIUM)
|
||||
{ Verbose("RS02Recognize: skipping exhaustive RS02 search\n");
|
||||
FreeAlignedBuffer(ab);
|
||||
return FALSE;
|
||||
{ triesleft = 3; /* no exhaustive search asked and reading from optical drive */
|
||||
Verbose("RS02Recognize: quick RS02 search, attempting up to %" PRId64" sector reads max\n", triesleft);
|
||||
}
|
||||
|
||||
/*** Normal exhaustive search */
|
||||
else
|
||||
Verbose("RS02Recognize: No EH, entering exhaustive search\n");
|
||||
|
||||
header_modulo = (gint64)1<<62;
|
||||
|
||||
@@ -266,6 +289,10 @@ int RS02Recognize(Image *image)
|
||||
|
||||
result = try_sector(image, pos, &image->eccHeader, ab->buf);
|
||||
|
||||
if (--triesleft == 0 && result != HEADER_FOUND) {
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
switch(result)
|
||||
{ case TRY_NEXT_HEADER:
|
||||
SetBit(try_next_header, pos);
|
||||
@@ -304,9 +331,7 @@ int RS02Recognize(Image *image)
|
||||
header_modulo >>= 1;
|
||||
}
|
||||
|
||||
#ifndef WITH_CLI_ONLY_YES
|
||||
bail_out:
|
||||
#endif
|
||||
FreeBitmap(try_next_header);
|
||||
FreeBitmap(try_next_modulo);
|
||||
FreeAlignedBuffer(ab);
|
||||
|
||||
@@ -364,6 +364,7 @@ int RS03RecognizeImage(Image *image)
|
||||
{ recognize_context *rc = g_malloc0(sizeof(recognize_context));
|
||||
guint64 image_sectors;
|
||||
guint64 layer_size;
|
||||
gint64 triesleft = -1; /* infinity */
|
||||
int untested_layers;
|
||||
int layer, layer_sector;
|
||||
int i;
|
||||
@@ -399,18 +400,40 @@ int RS03RecognizeImage(Image *image)
|
||||
}
|
||||
}
|
||||
|
||||
/* No exhaustive search on optical media unless explicitly okayed by user */
|
||||
/* This concludes the non-exhaustive search, where we tried to look for
|
||||
an ECC header signature on the sector right after the end of the ISO
|
||||
data. This doesn't always work, as some software tend to add some sectors
|
||||
after the end of the ISO (ImgBurn does this), or because the medium doesn't
|
||||
have any ISO9600 structure at all (some have only UDF for example), in that
|
||||
case the above quick search just does nothing.
|
||||
|
||||
By default, we don't launch an exhaustive search unless asked for.
|
||||
For example on the medium-info page, we won't do it unless enabled in the options,
|
||||
as the inserted medium might not have RS02 nor RS03 at all.
|
||||
Of course, when doing verify or repair, as it implies the user knows there is
|
||||
some ECC correction available on the medium, our caller will always require
|
||||
an exhaustive search. It's also always enabled if we're not reading from a
|
||||
drive but from a file on the hard drive, as seeking is very fast.
|
||||
|
||||
However even if not asked for an exhaustive search, and due to what has been
|
||||
explained in the first paragraph, we'll always try to read at least 3 sectors
|
||||
using the exhaustive search mechanism. On most images having ECC data, we'll
|
||||
find the header on the first try, at least on easy cases. This is a tradeoff
|
||||
to avoid having to display "no ECC data" on the medium-info page just because
|
||||
we didn't bother looking for it too hard, without bringing in the full
|
||||
exhaustive search which can take seconds or minutes on an optical drive with
|
||||
a medium that, in the end, doesn't have any ECC data.
|
||||
*/
|
||||
|
||||
if(!Closure->examineRS03 && image->type == IMAGE_MEDIUM)
|
||||
{ free_recognize_context(rc);
|
||||
Verbose("RS03RecognizeImage: skipping exhaustive RS03 search\n");
|
||||
return FALSE;
|
||||
{ triesleft = 3; /* no exhaustive search asked and reading from optical drive */
|
||||
Verbose("RS03RecognizeImage: quick RS03 search, attempting up to %" PRId64" sector reads max\n", triesleft);
|
||||
}
|
||||
else
|
||||
Verbose("RS03RecognizeImage: No EH, entering exhaustive search\n");
|
||||
|
||||
/* Determine image size in augmented case. */
|
||||
|
||||
Verbose("RS03RecognizeImage: No EH, entering exhaustive search\n");
|
||||
|
||||
if(Closure->debugMode && Closure->mediumSize > 170)
|
||||
{ layer_size = Closure->mediumSize/GF_FIELDMAX;
|
||||
Verbose("Warning: image size set to %" PRId64 " for debugging!\n", Closure->mediumSize);
|
||||
@@ -475,6 +498,11 @@ int RS03RecognizeImage(Image *image)
|
||||
if(sector >= image_sectors)
|
||||
goto mark_invalid_layer;
|
||||
|
||||
if (triesleft-- == 0) {
|
||||
free_recognize_context(rc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch(image->type)
|
||||
{ case IMAGE_FILE:
|
||||
RS03ReadSectors(image, rc->layout[layer], rc->ab->buf,
|
||||
|
||||
@@ -2707,7 +2707,13 @@ Image* OpenImageFromDevice(char *device, int query_only)
|
||||
ExamineUDF(image);
|
||||
|
||||
read_capacity(image); /* Needed for ExamineECC() ! */
|
||||
ExamineECC(image);
|
||||
|
||||
/* if we allow blank and we have no max size set, don't bother looking for ECC,
|
||||
or ExamineECC could throw a Stop() and abort the operation */
|
||||
if (query_only == 2 && image->dh->readCapacity == 0 && image->dh->userAreaSize == 0)
|
||||
Verbose("Capacity is zero, skipping ExamineECC() as we allow blanks");
|
||||
else
|
||||
ExamineECC(image);
|
||||
|
||||
Verbose("# Calling query_size()\n");
|
||||
dh->sectors = query_size(image);
|
||||
|
||||
Reference in New Issue
Block a user