=== modified file 'grub-core/fs/ntfs.c' --- grub-core/fs/ntfs.c 2012-02-27 20:36:58 +0000 +++ grub-core/fs/ntfs.c 2012-04-23 14:24:39 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -87,7 +88,8 @@ } static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, - grub_uint32_t mftno); + grub_uint32_t mftno, + grub_disk_addr_t *start_sector); static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, grub_size_t len, int cached, @@ -154,7 +156,7 @@ else { if (read_mft (at->mft->data, at->emft_buf, - u32at (at->attr_cur, 0x10))) + u32at (at->attr_cur, 0x10), NULL)) return NULL; } @@ -398,7 +400,16 @@ { if (ofs + len > u32at (pa, 0x10)) return grub_error (GRUB_ERR_BAD_FS, "read out of range"); - grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); + pa += u32at (pa, 0x14) + ofs; + grub_memcpy (dest, pa, len); + if (read_hook) + { + if ((pa >= at->mft->buf) && (pa < at->mft->buf + 512)) + read_hook (at->mft->sector, pa - at->mft->buf, len); + else if ((pa >= at->mft->buf + 512) && (pa < at->mft->buf + 1024)) + read_hook (at->mft->sector + 1, pa - at->mft->buf - 512, + len); + } return 0; } @@ -537,11 +548,28 @@ } static grub_err_t -read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) +read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno, + grub_disk_addr_t *start_sector) { + auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, + unsigned offset, + unsigned length); + void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, + unsigned offset, + unsigned length) + { + if (start_sector) + { + if ((offset != 0) || (length != GRUB_DISK_SECTOR_SIZE)) + grub_error (GRUB_ERR_BAD_FS, "invalid mft location"); + *start_sector = sector; + start_sector = NULL; + } + } + if (read_attr (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), - data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) + data->mft_size << GRUB_NTFS_BLK_SHR, 0, read_hook)) return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); return fixup (buf, data->mft_size, "FILE"); } @@ -557,7 +585,7 @@ if (mft->buf == NULL) return grub_errno; - if (read_mft (mft->data, mft->buf, mftno)) + if (read_mft (mft->data, mft->buf, mftno, &mft->sector)) return grub_errno; flag = u16at (mft->buf, 0x16); @@ -661,10 +689,8 @@ *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, tmp, ns) = '\0'; } - if (namespace) - type |= GRUB_FSHELP_CASE_INSENSITIVE; - if (hook (ustr, type, fdiro)) + if (hook (ustr, type | GRUB_FSHELP_CASE_INSENSITIVE, fdiro)) { grub_free (ustr); return 1; @@ -706,7 +732,7 @@ if (mft->buf == NULL) return NULL; - if (read_mft (mft->data, mft->buf, mft->ino)) + if (read_mft (mft->data, mft->buf, mft->ino, &mft->sector)) return NULL; pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK); @@ -977,6 +1003,8 @@ if (grub_disk_read (disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf)) goto fail; + data->mmft.sector = data->mft_start + + grub_partition_get_start (disk->partition); data->uuid = grub_le_to_cpu64 (bpb.num_serial); @@ -1170,7 +1198,7 @@ if (mft->buf == NULL) goto fail; - if (read_mft (mft->data, mft->buf, mft->ino)) + if (read_mft (mft->data, mft->buf, mft->ino, &mft->sector)) goto fail; } === modified file 'include/grub/ntfs.h' --- include/grub/ntfs.h 2012-01-20 14:01:35 +0000 +++ include/grub/ntfs.h 2012-04-23 13:58:26 +0000 @@ -146,6 +146,7 @@ grub_uint64_t mtime; grub_uint32_t ino; int inode_read; + grub_disk_addr_t sector; struct grub_ntfs_attr attr; }; === modified file 'util/grub-fstest.c' --- util/grub-fstest.c 2012-03-08 18:09:05 +0000 +++ util/grub-fstest.c 2012-04-23 13:30:34 +0000 @@ -389,9 +389,11 @@ case CMD_BLOCKLIST: execute_command ("blocklist", n, args); grub_printf ("\n"); + break; case CMD_TESTLOAD: execute_command ("testload", n, args); grub_printf ("\n"); + break; case CMD_XNU_UUID: { grub_device_t dev;