Skip to content

Commit

Permalink
ntfs_file::loop_through_atts: use reference rather than pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
maharmstone committed Sep 27, 2021
1 parent 1317c88 commit 0925eb9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 52 deletions.
32 changes: 16 additions & 16 deletions src/ntfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,18 +222,18 @@ buffer_t ntfs_file::read(uint64_t offset, uint32_t length, enum ntfs_attribute t
buffer_t ret;
bool found = false;

loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER* att, const string_view& res_data, const u16string_view& att_name) -> bool {
if (att->TypeCode != type || name != att_name)
loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER& att, const string_view& res_data, const u16string_view& att_name) -> bool {
if (att.TypeCode != type || name != att_name)
return true;

if (att->Flags & ATTRIBUTE_FLAG_ENCRYPTED)
if (att.Flags & ATTRIBUTE_FLAG_ENCRYPTED)
throw formatted_error("Cannot read encrypted attribute");

if (att->Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK)
if (att.Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK)
throw formatted_error("FIXME - handle reading compressed attribute"); // FIXME

if (att->FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
ret = read_nonresident_attribute(offset, length, att);
if (att.FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
ret = read_nonresident_attribute(offset, length, &att);
else {
if (offset >= res_data.length())
ret.clear();
Expand Down Expand Up @@ -261,16 +261,16 @@ buffer_t ntfs_file::read(uint64_t offset, uint32_t length, enum ntfs_attribute t
list<mapping> ntfs_file::read_mappings(enum ntfs_attribute type, const u16string_view& name) {
list<mapping> mappings;

loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER* att, const string_view&, const u16string_view& att_name) -> bool {
if (att->TypeCode != type || name != att_name)
loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER& att, const string_view&, const u16string_view& att_name) -> bool {
if (att.TypeCode != type || name != att_name)
return true;

if (att->FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM)
if (att.FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM)
throw formatted_error("Attribute is resident");

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

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

return false;
});
Expand Down Expand Up @@ -530,7 +530,7 @@ void populate_skip_list(ntfs& dev, uint64_t inode, list<uint64_t>& skiplist) {
}, 0);
}

void ntfs_file::loop_through_atts(const function<bool(const ATTRIBUTE_RECORD_HEADER*, const string_view&, const u16string_view&)>& func) {
void ntfs_file::loop_through_atts(const function<bool(const ATTRIBUTE_RECORD_HEADER&, const string_view&, const u16string_view&)>& func) {
auto att = reinterpret_cast<const ATTRIBUTE_RECORD_HEADER*>((uint8_t*)file_record + file_record->FirstAttributeOffset);
size_t offset = file_record->FirstAttributeOffset;
buffer_t attlist;
Expand Down Expand Up @@ -584,7 +584,7 @@ void ntfs_file::loop_through_atts(const function<bool(const ATTRIBUTE_RECORD_HEA
if (att->NameLength != 0)
name = u16string_view((char16_t*)((uint8_t*)file_record + offset + att->NameOffset), att->NameLength);

if (!func(att, data, name))
if (!func(*att, data, name))
return;

break;
Expand Down Expand Up @@ -643,7 +643,7 @@ void ntfs_file::loop_through_atts(const function<bool(const ATTRIBUTE_RECORD_HEA
if (att->NameLength != 0)
name = u16string_view((char16_t*)((uint8_t*)oth.file_record + offset + att->NameOffset), att->NameLength);

if (!func(att, data, name))
if (!func(*att, data, name))
return;

break;
Expand Down Expand Up @@ -683,7 +683,7 @@ void ntfs_file::loop_through_atts(const function<bool(const ATTRIBUTE_RECORD_HEA
if (att->NameLength != 0)
name = u16string_view((char16_t*)((uint8_t*)file_record + offset + att->NameOffset), att->NameLength);

if (!func(att, data, name))
if (!func(*att, data, name))
return;

offset += att->RecordLength;
Expand All @@ -698,8 +698,8 @@ string ntfs_file::get_filename() {
do {
uint64_t dir_num = 0;

f->loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER* att, const string_view& res_data, const u16string_view&) -> bool {
if (att->TypeCode != ntfs_attribute::FILE_NAME || att->FormCode != NTFS_ATTRIBUTE_FORM::RESIDENT_FORM)
f->loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER& att, const string_view& res_data, const u16string_view&) -> bool {
if (att.TypeCode != ntfs_attribute::FILE_NAME || att.FormCode != NTFS_ATTRIBUTE_FORM::RESIDENT_FORM)
return true;

auto fn = reinterpret_cast<const FILE_NAME*>(res_data.data());
Expand Down
2 changes: 1 addition & 1 deletion src/ntfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ class ntfs_file {
return file_record->Flags & FILE_RECORD_IS_DIRECTORY;
}

void loop_through_atts(const std::function<bool(const ATTRIBUTE_RECORD_HEADER*, const std::string_view&, const std::u16string_view&)>& func);
void loop_through_atts(const std::function<bool(const ATTRIBUTE_RECORD_HEADER&, const std::string_view&, const std::u16string_view&)>& func);
std::string get_filename();

FILE_RECORD_SEGMENT_HEADER* file_record;
Expand Down
70 changes: 35 additions & 35 deletions src/ntfs2btrfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1921,10 +1921,10 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir

is_dir = f.is_directory();

f.loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER* att, const string_view& res_data, const u16string_view& name) -> bool {
switch (att->TypeCode) {
f.loop_through_atts([&](const ATTRIBUTE_RECORD_HEADER& att, const string_view& res_data, const u16string_view& name) -> bool {
switch (att.TypeCode) {
case ntfs_attribute::STANDARD_INFORMATION:
if (att->FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
if (att.FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
throw formatted_error("Error - STANDARD_INFORMATION is non-resident"); // FIXME - can this happen?

standard_info.resize(res_data.length());
Expand All @@ -1933,7 +1933,7 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir

case ntfs_attribute::DATA:
if (name.empty()) { // main file data
if (att->Flags & ATTRIBUTE_FLAG_ENCRYPTED) {
if (att.Flags & ATTRIBUTE_FLAG_ENCRYPTED) {
clear_line();

if (filename.empty())
Expand All @@ -1944,18 +1944,18 @@ 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 && !processed_data) {
file_size = vdl = att->Form.Resident.ValueLength;
if (att.FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM && !processed_data) {
file_size = vdl = att.Form.Resident.ValueLength;

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

if (!(att->Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK))
if (!(att.Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK))
compression_unit = 0;
}

Expand All @@ -1967,10 +1967,10 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
else
last_vcn = mappings.back().vcn + mappings.back().length;

if (last_vcn < att->Form.Nonresident.LowestVcn)
mappings.emplace_back(0, last_vcn, att->Form.Nonresident.LowestVcn - last_vcn);
if (last_vcn < att.Form.Nonresident.LowestVcn)
mappings.emplace_back(0, last_vcn, att.Form.Nonresident.LowestVcn - last_vcn);

read_nonresident_mappings(att, mappings2, cluster_size, vdl);
read_nonresident_mappings(&att, mappings2, cluster_size, vdl);

mappings.splice(mappings.end(), mappings2);
}
Expand All @@ -1984,7 +1984,7 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir

// FIXME - check xattr_name not reserved

if (att->Flags & ATTRIBUTE_FLAG_ENCRYPTED) {
if (att.Flags & ATTRIBUTE_FLAG_ENCRYPTED) {
clear_line();

if (filename.empty())
Expand All @@ -1995,7 +1995,7 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
break;
}

if (att->Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK) {
if (att.Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK) {
clear_line();

if (filename.empty())
Expand All @@ -2010,18 +2010,18 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir

uint32_t hash = calc_crc32c(0xfffffffe, (const uint8_t*)name2.data(), (uint32_t)name2.length());

if (att->FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM) {
if (att.FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM) {
if (ads_name == "WofCompressedData") {
wof_compressed_data.resize(res_data.length());
memcpy(wof_compressed_data.data(), res_data.data(), res_data.length());
} else {
if (att->Form.Resident.ValueLength > max_xattr_size) {
if (att.Form.Resident.ValueLength > max_xattr_size) {
clear_line();

if (filename.empty())
filename = f.get_filename();

warnings.emplace_back(fmt::format("Skipping overly large ADS {}:{} ({} > {})", filename, ads_name, att->Form.Resident.ValueLength, max_xattr_size));
warnings.emplace_back(fmt::format("Skipping overly large ADS {}:{} ({} > {})", filename, ads_name, att.Form.Resident.ValueLength, max_xattr_size));

break;
}
Expand All @@ -2032,30 +2032,30 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
xattrs.emplace(name2, make_pair(hash, buf));
}
} else {
if (att->Form.Nonresident.FileSize > max_xattr_size && ads_name != "WofCompressedData") {
if (att.Form.Nonresident.FileSize > max_xattr_size && ads_name != "WofCompressedData") {
clear_line();

if (filename.empty())
filename = f.get_filename();

warnings.emplace_back(fmt::format("Skipping overly large ADS {}:{} ({} > {})", filename, ads_name, att->Form.Nonresident.FileSize, max_xattr_size));
warnings.emplace_back(fmt::format("Skipping overly large ADS {}:{} ({} > {})", filename, ads_name, att.Form.Nonresident.FileSize, max_xattr_size));

break;
}

list<mapping> ads_mappings;

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

buffer_t ads_data((size_t)sector_align(att->Form.Nonresident.FileSize, cluster_size));
buffer_t ads_data((size_t)sector_align(att.Form.Nonresident.FileSize, cluster_size));
memset(ads_data.data(), 0, ads_data.size());

for (const auto& m : ads_mappings) {
dev.seek(m.lcn * cluster_size);
dev.read(ads_data.data() + (m.vcn * cluster_size), (size_t)(m.length * cluster_size));
}

ads_data.resize((size_t)att->Form.Nonresident.FileSize);
ads_data.resize((size_t)att.Form.Nonresident.FileSize);

if (ads_name == "WofCompressedData")
wof_compressed_data.swap(ads_data);
Expand All @@ -2066,16 +2066,16 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
break;

case ntfs_attribute::FILE_NAME: {
if (att->FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
if (att.FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
throw formatted_error("Error - FILE_NAME is non-resident"); // FIXME - can this happen?

if (att->Form.Resident.ValueLength < offsetof(FILE_NAME, FileName[0]))
if (att.Form.Resident.ValueLength < offsetof(FILE_NAME, FileName[0]))
throw formatted_error("FILE_NAME was truncated");

auto fn = reinterpret_cast<const FILE_NAME*>(res_data.data());

if (fn->Namespace != file_name_type::DOS) {
if (att->Form.Resident.ValueLength < offsetof(FILE_NAME, FileName[0]) + (fn->FileNameLength * sizeof(char16_t)))
if (att.Form.Resident.ValueLength < offsetof(FILE_NAME, FileName[0]) + (fn->FileNameLength * sizeof(char16_t)))
throw formatted_error("FILE_NAME was truncated");

auto name2 = convert.to_bytes(fn->FileName, fn->FileName + fn->FileNameLength);
Expand Down Expand Up @@ -2122,7 +2122,7 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
}

case ntfs_attribute::SYMBOLIC_LINK:
if (att->FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
if (att.FormCode == NTFS_ATTRIBUTE_FORM::NONRESIDENT_FORM)
throw formatted_error("Error - SYMBOLIC_LINK is non-resident"); // FIXME - can this happen?

reparse_point.resize(res_data.size());
Expand Down Expand Up @@ -2163,45 +2163,45 @@ static void add_inode(root& r, uint64_t inode, uint64_t ntfs_inode, bool& is_dir
case ntfs_attribute::SECURITY_DESCRIPTOR: {
auto max_sd_size = (uint32_t)(tree_size - sizeof(tree_header) - sizeof(leaf_node) - offsetof(DIR_ITEM, name[0]) - sizeof(EA_NTACL) + 1);

if (att->FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM) {
if (att->Form.Resident.ValueLength > max_sd_size) {
if (att.FormCode == NTFS_ATTRIBUTE_FORM::RESIDENT_FORM) {
if (att.Form.Resident.ValueLength > max_sd_size) {
clear_line();

if (filename.empty())
filename = f.get_filename();

warnings.emplace_back(fmt::format("Skipping overly large SD for {} ({} > {})", filename, att->Form.Resident.ValueLength, max_sd_size));
warnings.emplace_back(fmt::format("Skipping overly large SD for {} ({} > {})", filename, att.Form.Resident.ValueLength, max_sd_size));

break;
}

sd.resize(res_data.size());
memcpy(sd.data(), res_data.data(), res_data.size());
} else {
if (att->Form.Nonresident.FileSize > max_sd_size) {
if (att.Form.Nonresident.FileSize > max_sd_size) {
clear_line();

if (filename.empty())
filename = f.get_filename();

warnings.emplace_back(fmt::format("Skipping overly large SD for {} ({} > {})", filename, att->Form.Nonresident.FileSize, max_sd_size));
warnings.emplace_back(fmt::format("Skipping overly large SD for {} ({} > {})", filename, att.Form.Nonresident.FileSize, max_sd_size));

break;
}

list<mapping> sd_mappings;

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

sd.resize((size_t)sector_align(att->Form.Nonresident.FileSize, cluster_size));
sd.resize((size_t)sector_align(att.Form.Nonresident.FileSize, cluster_size));
memset(sd.data(), 0, sd.size());

for (const auto& m : sd_mappings) {
dev.seek(m.lcn * cluster_size);
dev.read(sd.data() + (m.vcn * cluster_size), (size_t)(m.length * cluster_size));
}

sd.resize((size_t)att->Form.Nonresident.FileSize);
sd.resize((size_t)att.Form.Nonresident.FileSize);
}

break;
Expand Down

0 comments on commit 0925eb9

Please sign in to comment.