Return the attribute list attribute when enumerating attributes, too.

Thanks to Szakacsits Szabolcs for pointing this problem out.

(Logical change 1.48)
edge.strict_endians
cantab.net!aia21 2002-12-18 11:22:14 +00:00
parent 8ba6c67a1a
commit 471c5423f5
2 changed files with 69 additions and 2 deletions

View File

@ -163,6 +163,8 @@
- Add sanity check to ntfs_inode_close() to detect attempts at closing
extent inodes.
- Don't free extent inodes in attrib.c! (Szakacsits Szabolcs)
- Return the attribute list attribute when enumerating attributes, too.
Thanks to Szakacsits Szabolcs for pointing this problem out.
12/03/2002 - 1.6.0 - More mkntfs options and cleanups.
Fix typo in usage information of mkntfs. Thanks to Richard Russon for

View File

@ -1428,6 +1428,7 @@ static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name,
ATTR_RECORD *a;
uchar_t *al_name;
u32 al_name_len;
BOOL is_first_search = FALSE;
ni = ctx->ntfs_ino;
base_ni = ctx->base_ntfs_ino;
@ -1445,8 +1446,10 @@ static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name,
vol = base_ni->vol;
al_start = base_ni->attr_list;
al_end = al_start + base_ni->attr_list_size;
if (!ctx->al_entry)
if (!ctx->al_entry) {
ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
is_first_search = TRUE;
}
/*
* Iterate over entries in attribute list starting at @ctx->al_entry,
* or the entry following that, if @ctx->is_first is TRUE.
@ -1454,9 +1457,71 @@ static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name,
if (ctx->is_first) {
al_entry = ctx->al_entry;
ctx->is_first = FALSE;
} else
/*
* If an enumeration and the first attribute is higher than
* the attribute list itself, need to return the attribute list
* attribute.
*/
if (!type && is_first_search && le16_to_cpu(al_entry->type) >
le16_to_cpu(AT_ATTRIBUTE_LIST))
goto find_attr_list_attr;
} else {
al_entry = (ATTR_LIST_ENTRY*)((char*)ctx->al_entry +
le16_to_cpu(ctx->al_entry->length));
/*
* If this is an enumeration and the attribute list attribute
* is the next one in the enumeration sequence, just return the
* attribute list attribute from the base mft record as it is
* not listed in the attribute list itself.
*/
if (!type && le16_to_cpu(ctx->al_entry->type) <
le16_to_cpu(AT_ATTRIBUTE_LIST) &&
le16_to_cpu(al_entry->type) >
le16_to_cpu(AT_ATTRIBUTE_LIST)) {
int rc;
find_attr_list_attr:
/* Check for bogus calls. */
if (name || name_len || val || val_len || lowest_vcn) {
errno = EINVAL;
return -1;
}
/* We want the base record. */
ctx->ntfs_ino = base_ni;
ctx->mrec = ctx->base_mrec;
ctx->is_first = TRUE;
/* Sanity checks are performed elsewhere. */
ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
le16_to_cpu(ctx->mrec->attrs_offset));
/* Find the attribute list attribute. */
rc = ntfs_attr_find(AT_ATTRIBUTE_LIST, NULL, 0,
IGNORE_CASE, NULL, 0, ctx);
/*
* Setup the search context so the correct
* attribute is returned next time round.
*/
ctx->al_entry = al_entry;
ctx->is_first = TRUE;
/* Got it. Done. */
if (!rc)
return 0;
/* Error! If other than not found return it. */
if (errno != EINVAL)
return rc;
/* Not found?!? Absurd! Must be a bug... )-: */
Dprintf("%s(): BUG! Attribute list attribute not found "
"but it exists! Returning error "
"(EINVAL).", __FUNCTION__);
errno = EINVAL;
return -1;
}
}
for (;; al_entry = next_al_entry) {
/* Out of bounds check. */
if ((u8*)al_entry < base_ni->attr_list ||