From 010e735129a0a1d21d3bafc0ffe57c896e2a9eb3 Mon Sep 17 00:00:00 2001 From: "cantab.net!aia21" Date: Fri, 9 Jan 2004 12:38:56 +0000 Subject: [PATCH] Initial revision --- include/compress.h | 0 libntfs/compress.c | 217 --------------------------------------------- 2 files changed, 217 deletions(-) create mode 100644 include/compress.h diff --git a/include/compress.h b/include/compress.h new file mode 100644 index 00000000..e69de29b diff --git a/libntfs/compress.c b/libntfs/compress.c index ceeb5c05..e69de29b 100644 --- a/libntfs/compress.c +++ b/libntfs/compress.c @@ -1,217 +0,0 @@ -/* - * compress.c - Compressed attribute handling code. Part of the Linux-NTFS - * project. - * - * Copyright (c) 2004 Anton Altaparmakov - * - * This program/include file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program/include file is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (in the main directory of the Linux-NTFS - * distribution in the file COPYING); if not, write to the Free Software - * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "attrib.h" -#include "debug.h" -#include "volume.h" -#include "types.h" -#include "layout.h" -#include "runlist.h" - -/** - * ntfs_compressed_attr_pread - read from a compressed attribute - * @na: ntfs attribute to read from - * @pos: byte position in the attribute to begin reading from - * @count: number of bytes to read - * @b: output data buffer - * - * NOTE: You probably want to be using attrib.c::ntfs_attr_pread() instead. - * - * This function will read @count bytes starting at offset @pos from the - * compressed ntfs attribute @na into the data buffer @b. - * - * On success, return the number of successfully read bytes. If this number - * is lower than @count this means that the read reached end of file or that - * an error was encountered during the read so that the read is partial. - * 0 means end of file or nothing was read (also return 0 when @count is 0). - * - * On error and nothing has been read, return -1 with errno set appropriately - * to the return code of ntfs_pread(), or to EINVAL in case of invalid - * arguments. - */ -s64 ntfs_compressed_attr_pread(ntfs_attr *na, const s64 pos, s64 count, - void *b) -{ - s64 br, to_read, ofs, total, total2; - u64 cb_size_mask; - VCN start_vcn, end_vcn; - ntfs_volume *vol; - runlist_element *rl; - u8 *ntfs_compression_buffer, *ntfs_uncompressed_buffer; - u8 *cb, *cb_pos, *cb_end; - u32 cb_size; - unsigned int nr_cbs, cb_clusters; - - Dprintf("%s(): Entering for inode 0x%Lx, attr 0x%x, pos 0x%Lx, " - "count 0x%Lx.\n", __FUNCTION__, - (unsigned long long)na->ni->mft_no, na->type, - (long long)pos, (long long)count); - if (!na || !NAttrCompressed(na) || !na->ni || !na->ni->vol || !b || - pos < 0 || count < 0) { - errno = EINVAL; - return -1; - } - /* - * Encrypted attributes are not supported. We return access denied, - * which is what Windows NT4 does, too. - */ - if (NAttrEncrypted(na)) { - errno = EACCES; - return -1; - } - if (!count) - return 0; - /* Truncate reads beyond end of attribute. */ - if (pos + count > na->data_size) { - if (pos >= na->data_size) - return 0; - count = na->data_size - pos; - } - /* If it is a resident attribute, simply use ntfs_attr_pread(). */ - if (!NAttrNonResident(na)) - return ntfs_attr_pread(na, pos, count, b); - total = total2 = 0; - /* Zero out reads beyond initialized size. */ - if (pos + count > na->initialized_size) { - if (pos >= na->initialized_size) { - memset(b, 0, count); - return count; - } - total2 = pos + count - na->initialized_size; - count -= total2; - memset((u8*)b + count, 0, total2); - } - vol = na->ni->vol; - cb_size = na->compression_block_size; - cb_size_mask = cb_size - 1UL; - cb_clusters = na->compression_block_clusters; - /* Need a temporary buffer for each loaded compression block. */ - ntfs_compression_buffer = malloc(cb_size); - if (!ntfs_compression_buffer) - return -1; - /* Need a temporary buffer for each uncompressed block. */ - ntfs_uncompressed_buffer = malloc(cb_size); - if (!ntfs_uncompressed_buffer) { - int eo = errno; - free(ntfs_compression_buffer); - errno = eo; - return -1; - } - /* - * The first vcn in the first compression block (cb) which we need to - * decompress. - */ - start_vcn = (pos & ~cb_size_mask) >> vol->cluster_size_bits; - /* - * The first vcn in the cb after the last cb which we need to - * decompress. - */ - end_vcn = ((pos + count + cb_size - 1) & ~cb_size_mask) >> - vol->cluster_size_bits; - /* Number of compression blocks (cbs) in the wanted vcn range. */ - nr_cbs = (end_vcn - start_vcn) << vol->cluster_size_bits >> - na->compression_block_size_bits; -do_next_cb: - nr_cbs--; - cb_pos = cb = ntfs_compression_buffer; - cb_end = cb + cb_size; - -// FIXME: I am here... (AIA) - - free(ntfs_compression_buffer); - free(ntfs_uncompressed_buffer); - errno = ENOTSUP; - return -1; - - /* Find the runlist element containing the vcn. */ - rl = ntfs_attr_find_vcn(na, pos >> vol->cluster_size_bits); - if (!rl) { - /* - * If the vcn is not present it is an out of bounds read. - * However, we already truncated the read to the data_size, - * so getting this here is an error. - */ - if (errno == ENOENT) - errno = EIO; - return -1; - } - /* - * Gather the requested data into the linear destination buffer. Note, - * a partial final vcn is taken care of by the @count capping of read - * length. - */ - ofs = pos - (rl->vcn << vol->cluster_size_bits); - for (; count; rl++, ofs = 0) { - if (!rl->length) - goto rl_err_out; - if (rl->lcn < (LCN)0) { - if (rl->lcn != (LCN)LCN_HOLE) - goto rl_err_out; - /* It is a hole, just zero the matching @b range. */ - to_read = min(count, (rl->length << - vol->cluster_size_bits) - ofs); - memset(b, 0, to_read); - /* Update progress counters. */ - total += to_read; - count -= to_read; - (u8*)b += to_read; - continue; - } - /* It is a real lcn, read it into @dst. */ - to_read = min(count, (rl->length << vol->cluster_size_bits) - - ofs); -retry: - Dprintf("%s(): Reading 0x%Lx bytes from vcn 0x%Lx, lcn 0x%Lx, " - "ofs 0x%Lx.\n", __FUNCTION__, to_read, - rl->vcn, rl->lcn, ofs); - br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) + - ofs, to_read, b); - /* If everything ok, update progress counters and continue. */ - if (br > 0) { - total += br; - count -= br; - (u8*)b += br; - continue; - } - /* If the syscall was interrupted, try again. */ - if (br == (s64)-1 && errno == EINTR) - goto retry; - if (total) - return total; - if (!br) - errno = EIO; - return -1; - } - /* Finally, return the number of bytes read. */ - return total + total2; -rl_err_out: - if (total) - return total; - errno = EIO; - return -1; -} -