diff --git a/ChangeLog b/ChangeLog index 48b373e03..47fb57b0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-10-21 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (read_data): Move code for compressed data to ... + * grub-core/fs/ntfscomp.c (ntfscomp): ... here. + 2013-10-20 Vladimir Serbinenko * grub-core/kern/disk.c (grub_disk_write): Use malloc/free instead of diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 7e7d2df67..04bf8b5a5 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -373,7 +373,6 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, grub_disk_addr_t ofs, grub_size_t len, int cached, grub_disk_read_hook_t read_hook, void *read_hook_data) { - grub_disk_addr_t vcn; struct grub_ntfs_rlst cc, *ctx; if (len == 0) @@ -393,52 +392,23 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, return 0; } - if (u16at (pa, 0xC) & GRUB_NTFS_FLAG_COMPRESSED) - ctx->flags |= GRUB_NTFS_RF_COMP; - else - ctx->flags &= ~GRUB_NTFS_RF_COMP; ctx->cur_run = pa + u16at (pa, 0x20); - if (ctx->flags & GRUB_NTFS_RF_COMP) + ctx->next_vcn = u32at (pa, 0x10); + ctx->curr_lcn = 0; + + if ((pa[0xC] & GRUB_NTFS_FLAG_COMPRESSED) + && !(at->flags & GRUB_NTFS_AF_GPOS)) { if (!cached) return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); - if (at->sbuf) - { - if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == at->save_pos) - { - grub_disk_addr_t n; - - n = GRUB_NTFS_COM_LEN - (ofs - at->save_pos); - if (n > len) - n = len; - - grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n); - if (n == len) - return 0; - - dest += n; - len -= n; - ofs += n; - } - } - else - { - at->sbuf = grub_malloc (GRUB_NTFS_COM_LEN); - if (at->sbuf == NULL) - return grub_errno; - at->save_pos = 1; - } - - vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC >> ctx->comp.log_spc); - ctx->target_vcn &= ~0xFULL; + return (grub_ntfscomp_func) ? grub_ntfscomp_func (dest, ofs, len, ctx) + : grub_error (GRUB_ERR_BAD_FS, N_("module `%s' isn't loaded"), + "ntfscomp"); } - else - vcn = ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc); - ctx->next_vcn = u32at (pa, 0x10); - ctx->curr_lcn = 0; + ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc); while (ctx->next_vcn <= ctx->target_vcn) { if (grub_ntfs_read_run_list (ctx)) @@ -467,20 +437,12 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, return 0; } - if (!(ctx->flags & GRUB_NTFS_RF_COMP)) - { - grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, - read_hook, read_hook_data, ofs, len, - (char *) dest, - grub_ntfs_read_block, ofs + len, - ctx->comp.log_spc, 0); - return grub_errno; - } - - return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len, ctx, - vcn) : - grub_error (GRUB_ERR_BAD_FS, N_("module `%s' isn't loaded"), - "ntfscomp"); + grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, + read_hook, read_hook_data, ofs, len, + (char *) dest, + grub_ntfs_read_block, ofs + len, + ctx->comp.log_spc, 0); + return grub_errno; } static grub_err_t diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c index cf9e348f8..c1d2d30cb 100644 --- a/grub-core/fs/ntfscomp.c +++ b/grub-core/fs/ntfscomp.c @@ -289,10 +289,46 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) } static grub_err_t -ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, - grub_size_t len, struct grub_ntfs_rlst *ctx, grub_disk_addr_t vcn) +ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, + grub_size_t len, struct grub_ntfs_rlst *ctx) { grub_err_t ret; + grub_disk_addr_t vcn; + + if (ctx->attr->sbuf) + { + if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == ctx->attr->save_pos) + { + grub_disk_addr_t n; + + n = GRUB_NTFS_COM_LEN - (ofs - ctx->attr->save_pos); + if (n > len) + n = len; + + grub_memcpy (dest, ctx->attr->sbuf + ofs - ctx->attr->save_pos, n); + if (n == len) + return 0; + + dest += n; + len -= n; + ofs += n; + } + } + else + { + ctx->attr->sbuf = grub_malloc (GRUB_NTFS_COM_LEN); + if (ctx->attr->sbuf == NULL) + return grub_errno; + ctx->attr->save_pos = 1; + } + + vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC >> ctx->comp.log_spc); + ctx->target_vcn &= ~0xFULL; + while (ctx->next_vcn <= ctx->target_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + } ctx->comp.comp_head = ctx->comp.comp_tail = 0; ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR)); @@ -317,19 +353,19 @@ ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, grub_uint32_t t, n, o; t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); - if (read_block (ctx, at->sbuf, 1)) + if (read_block (ctx, ctx->attr->sbuf, 1)) { ret = grub_errno; goto quit; } - at->save_pos = t; + ctx->attr->save_pos = t; o = ofs % GRUB_NTFS_COM_LEN; n = GRUB_NTFS_COM_LEN - o; if (n > len) n = len; - grub_memcpy (dest, &at->sbuf[o], n); + grub_memcpy (dest, &ctx->attr->sbuf[o], n); if (n == len) goto quit; dest += n; @@ -349,15 +385,15 @@ ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, grub_uint32_t t; t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); - if (read_block (ctx, at->sbuf, 1)) + if (read_block (ctx, ctx->attr->sbuf, 1)) { ret = grub_errno; goto quit; } - at->save_pos = t; + ctx->attr->save_pos = t; - grub_memcpy (dest, at->sbuf, len); + grub_memcpy (dest, ctx->attr->sbuf, len); } quit: diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index 37983c4bb..e52c66349 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -98,9 +98,7 @@ enum enum { - GRUB_NTFS_RF_COMP = 1, - GRUB_NTFS_RF_CBLK = 2, - GRUB_NTFS_RF_BLNK = 4 + GRUB_NTFS_RF_BLNK = 1 }; struct grub_ntfs_bpb @@ -187,12 +185,10 @@ struct grub_ntfs_rlst struct grub_ntfs_comp comp; }; -typedef grub_err_t (*grub_ntfscomp_func_t) (struct grub_ntfs_attr * at, - grub_uint8_t *dest, +typedef grub_err_t (*grub_ntfscomp_func_t) (grub_uint8_t *dest, grub_disk_addr_t ofs, grub_size_t len, - struct grub_ntfs_rlst * ctx, - grub_disk_addr_t vcn); + struct grub_ntfs_rlst * ctx); extern grub_ntfscomp_func_t grub_ntfscomp_func;