Skip to content

Commit

Permalink
add_inode: handle files with multiple $DATA attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
maharmstone committed Jan 1, 2021
1 parent e538754 commit 776de47
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 13 deletions.
10 changes: 5 additions & 5 deletions src/ntfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ ntfs_file::ntfs_file(ntfs& dev, uint64_t inode) : dev(dev), inode(inode) {
}

void read_nonresident_mappings(const ATTRIBUTE_RECORD_HEADER* att, list<mapping>& mappings,
uint32_t cluster_size) {
uint32_t cluster_size, uint64_t vdl) {
uint64_t next_vcn = att->Form.Nonresident.LowestVcn, current_lcn = 0, current_vcn;
uint8_t* stream = (uint8_t*)att + att->Form.Nonresident.MappingPairsOffset;
uint64_t max_cluster = att->Form.Nonresident.ValidDataLength / cluster_size;
uint64_t max_cluster = vdl / cluster_size;

if (att->Form.Nonresident.ValidDataLength & (cluster_size - 1))
if (vdl & (cluster_size - 1))
max_cluster++;

if (max_cluster == 0)
Expand Down Expand Up @@ -148,7 +148,7 @@ string ntfs_file::read_nonresident_attribute(size_t offset, size_t length, const
uint32_t cluster_size = dev.boot_sector->BytesPerSector * dev.boot_sector->SectorsPerCluster;
string ret;

read_nonresident_mappings(att, mappings, cluster_size);
read_nonresident_mappings(att, mappings, cluster_size, att->Form.Nonresident.ValidDataLength);

// FIXME - do we need to check that mappings is contiguous and in order?

Expand Down Expand Up @@ -268,7 +268,7 @@ list<mapping> ntfs_file::read_mappings(enum ntfs_attribute type, const u16string

uint32_t cluster_size = dev.boot_sector->BytesPerSector * dev.boot_sector->SectorsPerCluster;

read_nonresident_mappings(att, mappings, cluster_size);
read_nonresident_mappings(att, mappings, cluster_size, att->Form.Nonresident.ValidDataLength);

return false;
});
Expand Down
22 changes: 15 additions & 7 deletions src/ntfs2btrfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1656,6 +1656,9 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
map<string, tuple<uint32_t, string>> xattrs;
string filename, wof_compressed_data;
uint32_t cluster_size = dev.boot_sector->BytesPerSector * dev.boot_sector->SectorsPerCluster;
bool processed_data = false;
uint16_t compression_unit;
uint64_t vdl;

static const uint32_t sector_size = 0x1000; // FIXME

Expand Down Expand Up @@ -1687,20 +1690,23 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
return true;
}

if (att->FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM) {
if (att->FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM && !processed_data) {
file_size = att->Form.Resident.ValueLength;

inline_data = res_data;
} else {
if (file_size == 0)
if (!processed_data) {
file_size = att->Form.Nonresident.FileSize;
compression_unit = att->Form.Nonresident.CompressionUnit;
vdl = att->Form.Nonresident.ValidDataLength;
}

if (att->Form.Nonresident.CompressionUnit != 0) {
if (compression_unit != 0) {
list<mapping> comp_mappings;
string compdata;
uint64_t cus = 1 << att->Form.Nonresident.CompressionUnit;
uint64_t cus = 1 << compression_unit;

read_nonresident_mappings(att, comp_mappings, cluster_size);
read_nonresident_mappings(att, comp_mappings, cluster_size, vdl);

compdata.resize(cus * cluster_size);

Expand Down Expand Up @@ -1763,9 +1769,11 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
} else {
// FIXME - if ValidDataLength < FileSize, will need to zero end

read_nonresident_mappings(att, mappings, cluster_size);
read_nonresident_mappings(att, mappings, cluster_size, vdl);
}
}

processed_data = true;
} else { // ADS
static const char xattr_prefix[] = "user.";

Expand Down Expand Up @@ -1832,7 +1840,7 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
list<mapping> ads_mappings;
string ads_data;

read_nonresident_mappings(att, ads_mappings, cluster_size);
read_nonresident_mappings(att, ads_mappings, cluster_size, att->Form.Nonresident.ValidDataLength);

ads_data.resize(sector_align(att->Form.Nonresident.FileSize, cluster_size));
memset(ads_data.data(), 0, ads_data.length());
Expand Down
2 changes: 1 addition & 1 deletion src/ntfs2btrfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static inline uint64_t sector_align(uint64_t v, uint64_t s) {

// ntfs.cpp
void read_nonresident_mappings(const ATTRIBUTE_RECORD_HEADER* att, std::list<mapping>& mappings,
uint32_t cluster_size);
uint32_t cluster_size, uint64_t vdl);
std::string_view find_sd(uint32_t id, ntfs_file& secure, ntfs& dev);
void populate_skip_list(ntfs& dev, uint64_t inode, std::list<uint64_t>& skiplist);
void process_fixups(MULTI_SECTOR_HEADER* header, uint64_t length, unsigned int sector_size);
Expand Down

0 comments on commit 776de47

Please sign in to comment.