aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@gmail.com>2011-07-28 00:11:28 +0000
committerPaulo Alcantara <pcacjr@gmail.com>2011-09-11 04:09:57 +0000
commitf1ce35d08a51708f1ad4d6b833df32199f366f94 (patch)
tree19d77a0b23bc71fd4fe47c2e8b79ffd8c0a0b330
parent364a9f34bacbef821d894935a1f5564a4b3660f3 (diff)
downloadsyslinux-f1ce35d08a51708f1ad4d6b833df32199f366f94.tar.gz
syslinux-f1ce35d08a51708f1ad4d6b833df32199f366f94.tar.xz
syslinux-f1ce35d08a51708f1ad4d6b833df32199f366f94.zip
ntfs: fix bug in parse_data_run()
parse_data_run() used to get the wrong value of VCNs starting at LCN, so it was only getting the value 1 and the NTFS driver didn't look at the other VCNs. Now, everything seems to work, except the readdir() function :-P Signed-off-by: Paulo Alcantara <pcacjr@gmail.com>
-rw-r--r--core/fs/ntfs/ntfs.c67
-rw-r--r--core/fs/ntfs/ntfs.h119
2 files changed, 79 insertions, 107 deletions
diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c
index e1ba3e1e..b9eca4c0 100644
--- a/core/fs/ntfs/ntfs.c
+++ b/core/fs/ntfs/ntfs.c
@@ -82,13 +82,12 @@ static int fixups_writeback(struct fs_info *fs, NTFS_RECORD *nrec)
/* make it to point to the last two bytes of the RECORD's first sector */
block = (uint16_t *)((uint8_t *)nrec + SECTOR_SIZE(fs) - 2);
- while (usa_count) {
+ while (usa_count--) {
if (*block != usa_no)
goto out;
*block = *usa++;
block = (uint16_t *)((uint8_t *)block + SECTOR_SIZE(fs));
- usa_count--;
}
return 0;
@@ -214,32 +213,11 @@ out:
return false;
}
-enum {
- MAP_UNSPEC,
- MAP_START = 1 << 0,
- MAP_END = 1 << 1,
- MAP_ALLOCATED = 1 << 2,
- MAP_UNALLOCATED = 1 << 3,
- MAP_MASK = 0x0000000F,
-};
-
-struct mapping_chunk {
- uint64_t cur_vcn; /* Current Virtual Cluster Number */
- uint8_t vcn_len; /* Virtual Cluster Number length in bytes */
- uint64_t next_vcn; /* Next Virtual Cluster Number */
- uint8_t lcn_len; /* Logical Cluster Number length in bytes */
- int64_t cur_lcn; /* Logical Cluster Number offset */
- uint32_t flags; /* Specific flags of this chunk */
-};
-
static inline uint8_t *mapping_chunk_init(ATTR_RECORD *attr,
struct mapping_chunk *chunk,
uint32_t *offset)
{
memset(chunk, 0, sizeof(*chunk));
- chunk->cur_vcn = attr->data.non_resident.lowest_vcn;
- chunk->cur_lcn = 0LL;
-
*offset = 0U;
return (uint8_t *)attr + attr->data.non_resident.mapping_pairs_offset;
@@ -276,8 +254,6 @@ static int parse_data_run(const void *stream, uint32_t *offset,
if (!*offset)
chunk->flags |= MAP_START; /* initial chunk */
- chunk->cur_vcn = chunk->next_vcn;
-
count = *buf;
v = count & 0x0F;
l = count >> 4;
@@ -285,9 +261,6 @@ static int parse_data_run(const void *stream, uint32_t *offset,
if (v > 8 || l > 8) /* more than 8 bytes ? */
goto out;
- chunk->vcn_len = v;
- chunk->lcn_len = l;
-
byte = (uint8_t *)buf + v;
count = v;
@@ -298,7 +271,7 @@ static int parse_data_run(const void *stream, uint32_t *offset,
res = (res << byte_shift) | ((val + mask) ^ mask);
}
- chunk->next_vcn += res;
+ chunk->len = res; /* get length data */
byte = (uint8_t *)buf + v + l;
count = l;
@@ -311,14 +284,12 @@ static int parse_data_run(const void *stream, uint32_t *offset,
while (count--)
res = (res << byte_shift) | *byte--;
- chunk->cur_lcn += res;
- if (!chunk->cur_lcn) { /* is LCN 0 ? */
- /* then VCNS from cur_vcn to next_vcn - 1 are unallocated */
+ chunk->lcn += res;
+ /* are VCNS from cur_vcn to next_vcn - 1 unallocated ? */
+ if (!chunk->lcn)
chunk->flags |= MAP_UNALLOCATED;
- } else {
- /* otherwise they're all allocated */
+ else
chunk->flags |= MAP_ALLOCATED;
- }
*offset += v + l + 1;
@@ -412,8 +383,6 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
goto out;
}
- printf("here!\n");
-
/* note: INDEX_ROOT is always resident */
ir = (INDEX_ROOT *)((uint8_t *)attr +
attr->data.resident.value_offset);
@@ -457,14 +426,7 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
} else {
attr_len = (uint8_t *)attr + attr->len;
- memset((void *)&chunk, 0, sizeof(chunk));
- chunk.cur_vcn = attr->data.non_resident.lowest_vcn;
- chunk.cur_lcn = 0LL;
-
- stream = (uint8_t *)attr +
- attr->data.non_resident.mapping_pairs_offset;
- droffset = 0U;
-
+ stream = mapping_chunk_init(attr, &chunk, &droffset);
for (;;) {
err = parse_data_run(stream, &droffset, attr_len, &chunk);
if (err) {
@@ -483,10 +445,8 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
goto out;
}
- NTFS_PVT(inode)->data.non_resident.start_vcn = chunk.cur_vcn;
- NTFS_PVT(inode)->data.non_resident.next_vcn = chunk.next_vcn;
- NTFS_PVT(inode)->data.non_resident.vcn_no = chunk.vcn_len;
- NTFS_PVT(inode)->data.non_resident.lcn = chunk.cur_lcn;
+ NTFS_PVT(inode)->data.non_resident.len = chunk.len;
+ NTFS_PVT(inode)->data.non_resident.lcn = chunk.lcn;
inode->size = attr->data.non_resident.initialized_size;
}
}
@@ -629,8 +589,7 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
continue;
if (chunk.flags & MAP_ALLOCATED) {
- dprintf("%d cluster(s) starting at 0x%X\n", chunk.vcn_len,
- chunk.cur_lcn);
+ printf("%d cluster(s) starting at 0x%X\n", chunk.len, chunk.lcn);
memcpy(&chunks[i++], &chunk, sizeof chunk);
}
@@ -639,8 +598,8 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
i = 0;
while (chunks_count--) {
vcn = 0;
- lcn = chunks[i].cur_lcn;
- while (vcn < chunks[i].vcn_len) {
+ lcn = chunks[i].lcn;
+ while (vcn < chunks[i].len) {
block = ((lcn + vcn) << NTFS_SB(fs)->clust_shift) <<
SECTOR_SHIFT(fs) >> BLOCK_SHIFT(fs);
@@ -692,7 +651,7 @@ static struct inode *index_lookup(const char *dname, struct inode *dir)
}
not_found:
- printf("Index not found\n");
+ dprintf("Index not found\n");
out:
printf("%s not found!\n", dname);
diff --git a/core/fs/ntfs/ntfs.h b/core/fs/ntfs/ntfs.h
index 21876938..3174fe06 100644
--- a/core/fs/ntfs/ntfs.h
+++ b/core/fs/ntfs/ntfs.h
@@ -43,7 +43,7 @@ struct ntfs_bpb {
uint32_t unused_6;
uint8_t pad[428]; /* padding to a sector boundary (512 bytes) */
-} __attribute__((packed));
+} __attribute__((__packed__));
struct ntfs_sb_info {
block_t mft_block; /* The first MFT record block */
@@ -58,7 +58,7 @@ struct ntfs_sb_info {
unsigned clust_mask;
unsigned clust_size;
-} __attribute__((packed));
+} __attribute__((__packed__));
/* The NTFS in-memory inode structure */
struct ntfs_inode {
@@ -77,9 +77,7 @@ struct ntfs_inode {
uint32_t offset; /* Data offset */
} resident;
struct { /* Used only if non_resident is set */
- uint64_t start_vcn; /* Starting Virtual Cluster Number */
- uint64_t next_vcn; /* Next Virtual Cluster Number */
- uint8_t vcn_no; /* Number of Virtual Cluster Numbers */
+ uint8_t len;
int64_t lcn; /* Logical Cluster Number offset */
} non_resident;
} data;
@@ -104,6 +102,21 @@ struct ntfs_inode {
sector_t here; /* Sector corresponding to offset */
};
+enum {
+ MAP_UNSPEC,
+ MAP_START = 1 << 0,
+ MAP_END = 1 << 1,
+ MAP_ALLOCATED = 1 << 2,
+ MAP_UNALLOCATED = 1 << 3,
+ MAP_MASK = 0x0000000F,
+};
+
+struct mapping_chunk {
+ uint8_t len;
+ int64_t lcn; /* Logical Cluster Number */
+ uint32_t flags; /* Specific flags of this chunk */
+};
+
/* System defined attributes (32-bit)
* Each attribute type has a corresponding attribute name (in Unicode)
*/
@@ -186,7 +199,7 @@ typedef struct {
uint32_t magic;
uint16_t usa_ofs;
uint16_t usa_count;
-} __attribute__((packed)) NTFS_RECORD;
+} __attribute__((__packed__)) NTFS_RECORD;
/* The $MFT metadata file types */
typedef enum {
@@ -213,7 +226,7 @@ typedef enum {
enum {
MFT_RECORD_IN_USE = 0x0001,
MFT_RECORD_IS_DIRECTORY = 0x0002,
-} __attribute__((packed));
+} __attribute__((__packed__));
typedef struct {
uint32_t magic;
@@ -230,7 +243,7 @@ typedef struct {
uint16_t next_attr_instance;
uint16_t reserved;
uint32_t mft_record_no;
-} __attribute__((packed)) MFT_RECORD; /* 48 bytes */
+} __attribute__((__packed__)) MFT_RECORD; /* 48 bytes */
/* This is the version without the NTFS 3.1+ specific fields */
typedef struct {
@@ -246,7 +259,7 @@ typedef struct {
uint32_t bytes_allocated;
uint64_t base_mft_record;
uint16_t next_attr_instance;
-} __attribute__((packed)) MFT_RECORD_OLD; /* 42 bytes */
+} __attribute__((__packed__)) MFT_RECORD_OLD; /* 42 bytes */
enum {
ATTR_DEF_INDEXABLE = 0x02,
@@ -266,7 +279,7 @@ typedef struct {
uint32_t flags; /* Attr def flags */
uint64_t min_size;
uint64_t max_size;
-} __attribute__((packed)) ATTR_DEF;
+} __attribute__((__packed__)) ATTR_DEF;
/* Attribute flags (16-bit) */
enum {
@@ -275,12 +288,12 @@ enum {
ATTR_IS_ENCRYPTED = 0x4000,
ATTR_IS_SPARSE = 0x8000,
-} __attribute__((packed));
+} __attribute__((__packed__));
/* Flags of resident attributes (8-bit) */
enum {
RESIDENT_ATTR_IS_INDEXED = 0x01,
-} __attribute__((packed));
+} __attribute__((__packed__));
typedef struct {
uint32_t type; /* Attr. type code */
@@ -296,7 +309,7 @@ typedef struct {
uint16_t value_offset;
uint8_t flags; /* Flags of resident attributes */
int8_t reserved;
- } __attribute__((packed)) resident;
+ } __attribute__((__packed__)) resident;
struct { /* Non-resident attributes */
uint64_t lowest_vcn;
uint64_t highest_vcn;
@@ -306,9 +319,9 @@ typedef struct {
int64_t allocated_size;
int64_t initialized_size;
int64_t compressed_size;
- } __attribute__((packed)) non_resident;
- } __attribute__((packed)) data;
-} __attribute__((packed)) ATTR_RECORD;
+ } __attribute__((__packed__)) non_resident;
+ } __attribute__((__packed__)) data;
+} __attribute__((__packed__)) ATTR_RECORD;
/* Attribute: Standard Information (0x10)
* Note: always resident
@@ -322,7 +335,7 @@ typedef struct {
union {
struct { /* NTFS 1.2 (48 bytes) */
uint8_t reserved12[12];
- } __attribute__((packed)) v1;
+ } __attribute__((__packed__)) v1;
struct { /* NTFS 3.x (72 bytes) */
uint32_t max_version;
uint32_t version;
@@ -331,9 +344,9 @@ typedef struct {
uint32_t sec_id;
uint64_t quota_charged;
int64_t usn;
- } __attribute__((packed)) v3;
- } __attribute__((packed)) ver;
-} __attribute__((packed)) STANDARD_INFORMATION;
+ } __attribute__((__packed__)) v3;
+ } __attribute__((__packed__)) ver;
+} __attribute__((__packed__)) STANDARD_INFORMATION;
/* Attribute: Attribute List (0x20)
* Note: can be either resident or non-resident
@@ -348,7 +361,7 @@ typedef struct {
uint16_t instance;
uint16_t name[0]; /* Name in Unicode */
/* sizeof() = 26 + (attribute_name_length * 2) bytes */
-} __attribute__((packed)) ATTR_LIST_ENTRY;
+} __attribute__((__packed__)) ATTR_LIST_ENTRY;
#define NTFS_MAX_FILE_NAME_LEN 255
@@ -358,7 +371,7 @@ enum {
FILE_NAME_WIN32 = 0x01,
FILE_NAME_DOS = 0x02,
FILE_NAME_WIN32_AND_DOS = 0x03,
-} __attribute__((packed));
+} __attribute__((__packed__));
/* Attribute: Filename (0x30)
* Note: always resident
@@ -374,17 +387,17 @@ typedef struct {
uint32_t file_attrs;
union {
struct {
- uint16_t packed_ea_size;
+ uint16_t __packed___ea_size;
uint16_t reserved; /* reserved for alignment */
- } __attribute__((packed)) ea;
+ } __attribute__((__packed__)) ea;
struct {
uint32_t reparse_point_tag;
- } __attribute__((packed)) rp;
- } __attribute__((packed)) type;
+ } __attribute__((__packed__)) rp;
+ } __attribute__((__packed__)) type;
uint8_t file_name_len;
uint8_t file_name_type;
uint16_t file_name[0]; /* File name in Unicode */
-} __attribute__((packed)) FILE_NAME_ATTR;
+} __attribute__((__packed__)) FILE_NAME_ATTR;
/* GUID structure */
typedef struct {
@@ -392,7 +405,7 @@ typedef struct {
uint16_t data1;
uint16_t data2;
uint8_t data3[8];
-} __attribute__((packed)) GUID;
+} __attribute__((__packed__)) GUID;
typedef struct {
uint64_t mft_ref;
@@ -401,10 +414,10 @@ typedef struct {
GUID birth_vol_id;
GUID birth_obj_id;
GUID domain_id;
- } __attribute__((packed)) origin;
+ } __attribute__((__packed__)) origin;
uint8_t extended_info[48];
- } __attribute__((packed)) opt;
-} __attribute__((packed)) OBJ_ID_INDEX_DATA;
+ } __attribute__((__packed__)) opt;
+} __attribute__((__packed__)) OBJ_ID_INDEX_DATA;
/* Attribute: Object ID (NTFS 3.0+) (0x40)
* Note: always resident
@@ -416,10 +429,10 @@ typedef struct {
GUID birth_vol_id;
GUID birth_obj_id;
GUID domain_id;
- } __attribute__((packed)) origin;
+ } __attribute__((__packed__)) origin;
uint8_t extended_info[48];
- } __attribute__((packed)) opt;
-} __attribute__((packed)) OBJECT_ID_ATTR;
+ } __attribute__((__packed__)) opt;
+} __attribute__((__packed__)) OBJECT_ID_ATTR;
/* Attribute: Volume Name (0x60)
* Note: always resident
@@ -427,7 +440,7 @@ typedef struct {
*/
typedef struct {
uint16_t name[0]; /* The name of the volume in Unicode */
-} __attribute__((packed)) VOLUME_NAME;
+} __attribute__((__packed__)) VOLUME_NAME;
/* Volume flags (16-bit) */
enum {
@@ -445,7 +458,7 @@ enum {
VOLUME_FLAGS_MASK = 0xC03F,
VOLUME_MUST_MOUNT_RO_MASK = 0xC027,
-} __attribute__((packed));
+} __attribute__((__packed__));
/* Attribute: Volume Information (0x70)
* Note: always resident
@@ -456,14 +469,14 @@ typedef struct {
uint8_t major_ver;
uint8_t minor_ver;
uint16_t flags; /* Volume flags */
-} __attribute__((packed)) VOLUME_INFORMATION;
+} __attribute__((__packed__)) VOLUME_INFORMATION;
/* Attribute: Data attribute (0x80)
* Note: can be either resident or non-resident
*/
typedef struct {
uint8_t data[0];
-} __attribute__((packed)) DATA_ATTR;
+} __attribute__((__packed__)) DATA_ATTR;
/* Index header flags (8-bit) */
enum {
@@ -472,7 +485,7 @@ enum {
LEAF_NODE = 0,
INDEX_NODE = 1,
NODE_MASK = 1,
-} __attribute__((packed));
+} __attribute__((__packed__));
/* Header for the indexes, describing the INDEX_ENTRY records, which
* follow the INDEX_HEADER.
@@ -483,7 +496,7 @@ typedef struct {
uint32_t allocated_size;
uint8_t flags; /* Index header flags */
uint8_t reserved[3]; /* Align to 8-byte boundary */
-} __attribute__((packed)) INDEX_HEADER;
+} __attribute__((__packed__)) INDEX_HEADER;
/* Attribute: Index Root (0x90)
* Note: always resident
@@ -497,7 +510,7 @@ typedef struct {
uint8_t clust_per_index_block;
uint8_t reserved[3];
INDEX_HEADER index;
-} __attribute__((packed)) INDEX_ROOT;
+} __attribute__((__packed__)) INDEX_ROOT;
/* Attribute: Index allocation (0xA0)
* Note: always non-resident, of course! :-)
@@ -509,7 +522,7 @@ typedef struct {
int64_t lsn;
int64_t index_block_vcn; /* Virtual cluster number of the index block */
INDEX_HEADER index;
-} __attribute__((packed)) INDEX_BLOCK;
+} __attribute__((__packed__)) INDEX_BLOCK;
typedef INDEX_BLOCK INDEX_ALLOCATION;
@@ -518,36 +531,36 @@ enum {
INDEX_ENTRY_END = 2,
/* force enum bit width to 16-bit */
INDEX_ENTRY_SPACE_FILTER = 0xFFFF,
-} __attribute__((packed));
+} __attribute__((__packed__));
typedef struct {
union {
struct { /* Only valid when INDEX_ENTRY_END is not set */
uint64_t indexed_file;
- } __attribute__((packed)) dir;
+ } __attribute__((__packed__)) dir;
struct { /* Used for views/indexes to find the entry's data */
uint16_t data_offset;
uint16_t data_len;
uint32_t reservedV;
- } __attribute__((packed)) vi;
- } __attribute__((packed)) data;
+ } __attribute__((__packed__)) vi;
+ } __attribute__((__packed__)) data;
uint16_t len;
uint16_t key_len;
uint16_t flags; /* Index entry flags */
uint16_t reserved; /* Align to 8-byte boundary */
-} __attribute__((packed)) INDEX_ENTRY_HEADER;
+} __attribute__((__packed__)) INDEX_ENTRY_HEADER;
typedef struct {
union {
struct { /* Only valid when INDEX_ENTRY_END is not set */
uint64_t indexed_file;
- } __attribute__((packed)) dir;
+ } __attribute__((__packed__)) dir;
struct { /* Used for views/indexes to find the entry's data */
uint16_t data_offset;
uint16_t data_len;
uint32_t reservedV;
- } __attribute__((packed)) vi;
- } __attribute__((packed)) data;
+ } __attribute__((__packed__)) vi;
+ } __attribute__((__packed__)) data;
uint16_t len;
uint16_t key_len;
uint16_t flags; /* Index entry flags */
@@ -560,12 +573,12 @@ typedef struct {
//REPARSE_INDEX_KEY reparse;
//SID sid;
uint32_t owner_id;
- } __attribute__((packed)) key;
-} __attribute__((packed)) INDEX_ENTRY;
+ } __attribute__((__packed__)) key;
+} __attribute__((__packed__)) INDEX_ENTRY;
typedef struct {
uint8_t bitmap[0]; /* Array of bits */
-} __attribute__((packed)) BITMAP_ATTR;
+} __attribute__((__packed__)) BITMAP_ATTR;
static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs)
{