Skip to content
API Documentation
BastionGuard™
anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery Class Reference

Classes

struct  StreamInfo

Public Member Functions

 ExfatRecovery (DiskReader &reader)
bool recover (uint64_t volume_offset, const fs::path &out_root, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error)

Private Member Functions

bool load_vbr (uint64_t volume_offset)
bool cluster_allocated (uint32_t cluster) const
bool load_allocation_bitmap ()
uint64_t cluster_to_offset (uint32_t cluster) const
bool next_cluster (uint32_t current, uint32_t &next)
std::vector< uint32_t > cluster_chain (uint32_t start, bool no_fat_chain, uint64_t data_length, size_t hard_limit=1<< 20)
bool read_cluster (uint32_t cluster, std::vector< unsigned char > &out)
bool export_stream (const StreamInfo &info, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error)
bool export_stream_deleted (const StreamInfo &info, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error)
bool recover_directory (uint32_t start_cluster, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error, std::set< uint32_t > &dir_guard, int depth)

Static Private Member Functions

static std::string decode_utf16_name (const std::vector< unsigned char > &bytes)

Private Attributes

DiskReader & reader_
uint64_t volume_offset_ {0}
uint64_t partition_offset_sectors_ {0}
uint64_t volume_length_sectors_ {0}
uint32_t fat_offset_sectors_ {0}
uint32_t fat_length_sectors_ {0}
uint32_t cluster_heap_offset_sectors_ {0}
uint32_t cluster_count_ {0}
uint32_t root_dir_cluster_ {2}
uint32_t serial_number_ {0}
uint8_t bytes_per_sector_shift_ {0}
uint8_t sectors_per_cluster_shift_ {0}
uint64_t bytes_per_sector_ {0}
uint64_t sectors_per_cluster_ {0}
uint64_t cluster_size_ {0}
uint64_t fat_offset_bytes_ {0}
uint64_t cluster_heap_offset_bytes_ {0}
uint32_t allocation_bitmap_cluster_ {0}
uint64_t allocation_bitmap_length_ {0}
std::vector< unsigned char > allocation_bitmap_

Detailed Description

Definition at line 460 of file filesystem_recovery.cpp.

Constructor & Destructor Documentation

◆ ExfatRecovery()

anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::ExfatRecovery ( DiskReader & reader)
inlineexplicit

Definition at line 462 of file filesystem_recovery.cpp.

References reader_.

Member Function Documentation

◆ cluster_allocated()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_allocated ( uint32_t cluster) const
inlineprivate

Definition at line 541 of file filesystem_recovery.cpp.

541 {
542 if (cluster < 2 || cluster >= cluster_count_ + 2) return false;
543 if (allocation_bitmap_.empty()) return true;
544 const uint64_t idx = static_cast<uint64_t>(cluster - 2);
545 const uint64_t byte_index = idx / 8;
546 const uint8_t bit = static_cast<uint8_t>(idx % 8);
547 if (byte_index >= allocation_bitmap_.size()) return false;
548 return (allocation_bitmap_[static_cast<size_t>(byte_index)] & (1u << bit)) != 0;
549 }

References allocation_bitmap_, and cluster_count_.

Referenced by cluster_chain().

◆ cluster_chain()

std::vector< uint32_t > anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_chain ( uint32_t start,
bool no_fat_chain,
uint64_t data_length,
size_t hard_limit = 1 << 20 )
inlineprivate

Definition at line 596 of file filesystem_recovery.cpp.

596 {
597 std::vector<uint32_t> chain;
598 if (start < 2) return chain;
599 if (no_fat_chain) {
600 const uint64_t clusters_needed = data_length == 0 ? 1 : (data_length + cluster_size_ - 1) / cluster_size_;
601 for (uint64_t i = 0; i < clusters_needed; ++i) {
602 const uint32_t cluster = start + static_cast<uint32_t>(i);
603 if (cluster < 2 || cluster >= cluster_count_ + 2) break;
604 if (!cluster_allocated(cluster)) {
605 chain.clear();
606 break;
607 }
608 chain.push_back(cluster);
609 }
610 return chain;
611 }
612 std::set<uint32_t> seen;
613 uint32_t current = start;
614 while (current >= 2 && current < 0x0FFFFFF8 && chain.size() < hard_limit && seen.insert(current).second) {
615 chain.push_back(current);
616 uint32_t next = 0x0FFFFFFF;
617 if (!next_cluster(current, next)) break;
618 if (next == 0x0FFFFFF7 || next == 0) break;
619 current = next;
620 }
621 return chain;
622 }

References cluster_allocated(), cluster_count_, cluster_size_, and next_cluster().

Referenced by export_stream(), load_allocation_bitmap(), and recover_directory().

◆ cluster_to_offset()

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_to_offset ( uint32_t cluster) const
inlineprivate

◆ decode_utf16_name()

std::string anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::decode_utf16_name ( const std::vector< unsigned char > & bytes)
inlinestaticprivate

Definition at line 629 of file filesystem_recovery.cpp.

629 {
630 // Bug #14 fix: exFAT filenames are UTF-16LE; decode as proper UTF-8
631 // instead of replacing non-ASCII with '_'.
632 return text_utils::utf16le_to_utf8(bytes.data(), bytes.size());
633 }
std::string utf16le_to_utf8(const unsigned char *data, std::size_t byte_count)

References text_utils::utf16le_to_utf8().

Referenced by recover_directory().

◆ export_stream()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::export_stream ( const StreamInfo & info,
const fs::path & out_dir,
std::vector< RecoveredFileRecord > & recovered,
std::vector< std::string > & logs,
std::string & error )
inlineprivate

Definition at line 635 of file filesystem_recovery.cpp.

639 {
640 if (!info.valid || info.is_directory) return true;
641 fs::create_directories(out_dir);
642 const auto chain = cluster_chain(info.first_cluster, info.no_fat_chain, info.data_length);
643 if (chain.empty() && info.data_length > 0) {
644 logs.push_back(trs("Skipped exFAT file with invalid cluster chain") + std::string(": ") + info.name);
645 return true;
646 }
647 std::vector<std::pair<uint64_t, uint64_t>> ranges;
648 for (uint32_t cluster : chain) {
649 ranges.push_back({cluster_to_offset(cluster), cluster_size_});
650 }
651 fs::path out_path = out_dir / sanitize_path_component(info.name);
652 std::string unique = out_path.string();
653 int suffix = 1;
654 while (fs::exists(unique)) {
655 unique = (out_dir / (sanitize_path_component(info.name) + "_" + std::to_string(suffix++))).string();
656 }
657 out_path = unique;
658 if (!write_data_to_file(reader_, ranges, out_path, info.data_length, error)) return false;
659 recovered.push_back({out_path.string(), "exFAT", info.name, info.data_length, "full", info.no_fat_chain ? "bitmap-validated contiguous export" : "filesystem export"});
660 logs.push_back(trs("Recovered exFAT file:") + std::string(" ") + out_path.string());
661 return true;
662 }
std::vector< uint32_t > cluster_chain(uint32_t start, bool no_fat_chain, uint64_t data_length, size_t hard_limit=1<< 20)
std::string trs(const char *msgid)
Definition i18n.cpp:22
bool write_data_to_file(DiskReader &reader, const std::vector< std::pair< uint64_t, uint64_t > > &ranges, const fs::path &out_path, uint64_t expected_size, std::string &error)
std::string sanitize_path_component(const std::string &in)

References cluster_chain(), cluster_size_, cluster_to_offset(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::data_length, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::first_cluster, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::is_directory, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::name, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::no_fat_chain, reader_, anonymous_namespace{filesystem_recovery.cpp}::sanitize_path_component(), trs(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::valid, and anonymous_namespace{filesystem_recovery.cpp}::write_data_to_file().

Referenced by recover_directory().

◆ export_stream_deleted()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::export_stream_deleted ( const StreamInfo & info,
const fs::path & out_dir,
std::vector< RecoveredFileRecord > & recovered,
std::vector< std::string > & logs,
std::string & error )
inlineprivate

Definition at line 671 of file filesystem_recovery.cpp.

675 {
676 if (!info.valid || info.is_directory) return true;
677 if (info.first_cluster < 2 || info.data_length == 0) {
678 // Empty file -- still create a placeholder
679 const fs::path out_path = out_dir / sanitize_path_component(info.name);
680 std::ofstream(out_path, std::ios::binary);
681 recovered.push_back({out_path.string(), "exFAT",
682 ("deleted/" + info.name), 0, "partial",
683 "deleted-empty"});
684 return true;
685 }
686 // Build a contiguous "guess" range
687 const uint64_t need_clusters =
688 (info.data_length + cluster_size_ - 1) / cluster_size_;
689 std::vector<std::pair<uint64_t, uint64_t>> ranges;
690 ranges.reserve(static_cast<size_t>(need_clusters));
691 for (uint64_t i = 0; i < need_clusters; ++i) {
692 const uint32_t cl = info.first_cluster + static_cast<uint32_t>(i);
693 // Bound check
694 if (cl < 2 || cl >= cluster_count_ + 2) break;
695 ranges.push_back({cluster_to_offset(cl), cluster_size_});
696 }
697 if (ranges.empty()) return true;
698
699 fs::path out_path = out_dir / sanitize_path_component(info.name);
700 std::string unique = out_path.string();
701 int suffix = 1;
702 while (fs::exists(unique)) {
703 unique = (out_dir / (sanitize_path_component(info.name) + "_"
704 + std::to_string(suffix++))).string();
705 }
706 out_path = unique;
707 if (!write_data_to_file(reader_, ranges, out_path,
708 info.data_length, error)) return false;
709 recovered.push_back({out_path.string(), "exFAT",
710 ("deleted/" + info.name), info.data_length, "partial",
711 "deleted-contiguous-guess"});
712 logs.push_back(trs("Recovered exFAT deleted file (best-effort, "
713 "assumes contiguous):") +
714 std::string(" ") + out_path.string());
715 return true;
716 }

References cluster_count_, cluster_size_, cluster_to_offset(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::data_length, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::first_cluster, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::is_directory, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::name, reader_, anonymous_namespace{filesystem_recovery.cpp}::sanitize_path_component(), trs(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::valid, and anonymous_namespace{filesystem_recovery.cpp}::write_data_to_file().

Referenced by recover_directory().

◆ load_allocation_bitmap()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::load_allocation_bitmap ( )
inlineprivate

Definition at line 551 of file filesystem_recovery.cpp.

551 {
552 if (root_dir_cluster_ < 2) return false;
553 const auto chain = cluster_chain(root_dir_cluster_, true, cluster_size_ * 64, 4096);
554 std::vector<unsigned char> cluster_buf;
555 for (uint32_t cluster : chain) {
556 if (!read_cluster(cluster, cluster_buf)) continue;
557 for (size_t off = 0; off + 32 <= cluster_buf.size(); off += 32) {
558 const unsigned char* e = cluster_buf.data() + off;
559 const uint8_t type = e[0];
560 if (type == 0x00) break;
561 if (type == 0x81) {
564 break;
565 }
566 }
567 if (allocation_bitmap_cluster_ != 0) break;
568 }
569 if (allocation_bitmap_cluster_ < 2 || allocation_bitmap_length_ == 0) return false;
570 const auto bitmap_chain = cluster_chain(allocation_bitmap_cluster_, true, allocation_bitmap_length_, 4096);
571 if (bitmap_chain.empty()) return false;
572 std::vector<std::pair<uint64_t, uint64_t>> ranges;
573 for (uint32_t cluster : bitmap_chain) ranges.push_back({cluster_to_offset(cluster), cluster_size_});
574 fs::path tmp = fs::temp_directory_path() / ("exfat_bitmap_" + std::to_string(serial_number_) + ".bin");
575 std::string local_error;
576 if (!write_data_to_file(reader_, ranges, tmp, allocation_bitmap_length_, local_error)) return false;
577 std::ifstream in(tmp, std::ios::binary);
578 allocation_bitmap_.assign(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>());
579 std::error_code ec;
580 fs::remove(tmp, ec);
581 return !allocation_bitmap_.empty();
582 }
bool read_cluster(uint32_t cluster, std::vector< unsigned char > &out)

References allocation_bitmap_, allocation_bitmap_cluster_, allocation_bitmap_length_, cluster_chain(), cluster_size_, cluster_to_offset(), anonymous_namespace{filesystem_recovery.cpp}::le32(), anonymous_namespace{filesystem_recovery.cpp}::le64(), read_cluster(), reader_, root_dir_cluster_, serial_number_, and anonymous_namespace{filesystem_recovery.cpp}::write_data_to_file().

Referenced by recover().

◆ load_vbr()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::load_vbr ( uint64_t volume_offset)
inlineprivate

Definition at line 515 of file filesystem_recovery.cpp.

515 {
516 std::array<unsigned char, 512> b{};
517 if (!reader_.read_at(volume_offset, b.data(), b.size())) return false;
518 if (std::string(reinterpret_cast<const char*>(b.data() + 3), 8) != "EXFAT ") return false;
519 volume_offset_ = volume_offset;
520 partition_offset_sectors_ = le64(b.data() + 64);
521 volume_length_sectors_ = le64(b.data() + 72);
522 fat_offset_sectors_ = le32(b.data() + 80);
523 fat_length_sectors_ = le32(b.data() + 84);
524 cluster_heap_offset_sectors_ = le32(b.data() + 88);
525 cluster_count_ = le32(b.data() + 92);
526 root_dir_cluster_ = le32(b.data() + 96);
527 serial_number_ = le32(b.data() + 100);
537 allocation_bitmap_.clear();
538 return bytes_per_sector_ >= 512 && cluster_size_ > 0 && cluster_count_ > 0;
539 }
bool read_at(uint64_t offset, void *buffer, size_t len)

References allocation_bitmap_, allocation_bitmap_cluster_, allocation_bitmap_length_, bytes_per_sector_, bytes_per_sector_shift_, cluster_count_, cluster_heap_offset_bytes_, cluster_heap_offset_sectors_, cluster_size_, fat_length_sectors_, fat_offset_bytes_, fat_offset_sectors_, anonymous_namespace{filesystem_recovery.cpp}::le32(), anonymous_namespace{filesystem_recovery.cpp}::le64(), partition_offset_sectors_, DiskReader::read_at(), reader_, root_dir_cluster_, sectors_per_cluster_, sectors_per_cluster_shift_, serial_number_, volume_length_sectors_, and volume_offset_.

Referenced by recover().

◆ next_cluster()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::next_cluster ( uint32_t current,
uint32_t & next )
inlineprivate

Definition at line 588 of file filesystem_recovery.cpp.

588 {
589 const uint64_t fat_entry_offset = fat_offset_bytes_ + static_cast<uint64_t>(current) * 4;
590 std::array<unsigned char, 4> entry{};
591 if (!reader_.read_at(fat_entry_offset, entry.data(), entry.size())) return false;
592 next = le32(entry.data()) & 0x0FFFFFFF;
593 return true;
594 }

References fat_offset_bytes_, anonymous_namespace{filesystem_recovery.cpp}::le32(), DiskReader::read_at(), and reader_.

Referenced by cluster_chain().

◆ read_cluster()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::read_cluster ( uint32_t cluster,
std::vector< unsigned char > & out )
inlineprivate

Definition at line 624 of file filesystem_recovery.cpp.

624 {
625 out.resize(static_cast<size_t>(cluster_size_));
626 return reader_.read_at(cluster_to_offset(cluster), out.data(), out.size());
627 }

References cluster_size_, cluster_to_offset(), DiskReader::read_at(), and reader_.

Referenced by load_allocation_bitmap(), and recover_directory().

◆ recover()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::recover ( uint64_t volume_offset,
const fs::path & out_root,
std::vector< RecoveredFileRecord > & recovered,
std::vector< std::string > & logs,
std::string & error )
inline

Definition at line 464 of file filesystem_recovery.cpp.

468 {
469 if (!load_vbr(volume_offset)) return false;
470 fs::create_directories(out_root);
471 logs.push_back(trs("exFAT recovery started at offset") + std::string(" ") + std::to_string(volume_offset));
473 logs.push_back(trs("exFAT allocation bitmap loaded") + std::string(": ") + std::to_string(allocation_bitmap_length_) + " bytes");
474 }
475 std::set<uint32_t> dir_guard;
476 if (!recover_directory(root_dir_cluster_, out_root, recovered, logs, error, dir_guard, 0)) {
477 return false;
478 }
479 logs.push_back(trs("exFAT recovery completed."));
480 return true;
481 }
bool recover_directory(uint32_t start_cluster, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error, std::set< uint32_t > &dir_guard, int depth)

References allocation_bitmap_length_, load_allocation_bitmap(), load_vbr(), recover_directory(), root_dir_cluster_, and trs().

◆ recover_directory()

bool anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::recover_directory ( uint32_t start_cluster,
const fs::path & out_dir,
std::vector< RecoveredFileRecord > & recovered,
std::vector< std::string > & logs,
std::string & error,
std::set< uint32_t > & dir_guard,
int depth )
inlineprivate

Definition at line 718 of file filesystem_recovery.cpp.

724 {
725 if (depth > 32) return true;
726 if (!dir_guard.insert(start_cluster).second) return true;
727
728 const auto chain = cluster_chain(start_cluster, true, cluster_size_ * 16, 4096);
729 std::vector<unsigned char> cluster_buf;
730 StreamInfo current;
731 int remaining_secondary = 0;
732 std::vector<unsigned char> name_bytes;
733
734 auto finalize = [&](bool force_dir_recurse) -> bool {
735 if (!current.valid) return true;
736 current.name = sanitize_path_component(current.name.empty() ? "unnamed" : current.name);
737 // Deleted entries: route to "deleted/" subdir, never recurse
738 // into them (the directory's children entries are likely
739 // already overwritten or pointing into reused clusters).
740 if (current.is_deleted) {
741 if (current.is_directory) return true; // skip deleted dirs
742 const fs::path deleted_dir = out_dir / "deleted";
743 std::error_code ec;
744 fs::create_directories(deleted_dir, ec);
745 return export_stream_deleted(current, deleted_dir, recovered, logs, error);
746 }
747 if (current.is_directory) {
748 if (current.first_cluster >= 2) {
749 const fs::path subdir = out_dir / current.name;
750 fs::create_directories(subdir);
751 return recover_directory(current.first_cluster, subdir, recovered, logs, error, dir_guard, depth + 1);
752 }
753 } else {
754 return export_stream(current, out_dir, recovered, logs, error);
755 }
756 (void)force_dir_recurse;
757 return true;
758 };
759
760 for (uint32_t cluster : chain) {
761 if (!read_cluster(cluster, cluster_buf)) continue;
762 for (size_t off = 0; off + 32 <= cluster_buf.size(); off += 32) {
763 const unsigned char* e = cluster_buf.data() + off;
764 const uint8_t type = e[0];
765 if (type == 0x00) {
766 return finalize(false);
767 }
768 // ---- exFAT entry types ----
769 //
770 // Bit 7 of the type byte = "InUse". When clear, the
771 // entry is DELETED but otherwise intact. The 3 entry
772 // types we care about have these (in-use, deleted)
773 // pairs:
774 // File Directory Entry: 0x85 / 0x05
775 // Stream Extension: 0xC0 / 0x40
776 // Filename: 0xC1 / 0x41
777 //
778 // We accept BOTH variants. We track is_deleted on the
779 // current pseudo-entry so finalize() can route the
780 // file to a "deleted/" subdirectory.
781 const bool is_file_de = (type == 0x85 || type == 0x05);
782 const bool is_stream_de = (type == 0xC0 || type == 0x40);
783 const bool is_name_de = (type == 0xC1 || type == 0x41);
784 const bool entry_deleted = (type == 0x05 || type == 0x40 ||
785 type == 0x41);
786
787 if (is_file_de) {
788 if (!finalize(false)) return false;
789 current = {};
790 current.valid = true;
791 current.is_directory = (e[4] & 0x10) != 0;
792 current.is_deleted = entry_deleted;
793 remaining_secondary = e[1];
794 name_bytes.clear();
795 } else if (current.valid && is_stream_de) {
796 current.no_fat_chain = (e[1] & 0x02) != 0;
797 current.name = std::string();
798 const uint8_t name_len = e[3];
799 current.first_cluster = le32(e + 20);
800 current.data_length = le64(e + 24);
801 name_bytes.reserve(static_cast<size_t>(name_len) * 2);
802 if (entry_deleted) current.is_deleted = true;
803 --remaining_secondary;
804 } else if (current.valid && is_name_de) {
805 name_bytes.insert(name_bytes.end(), e + 2, e + 32);
806 current.name = decode_utf16_name(name_bytes);
807 if (entry_deleted) current.is_deleted = true;
808 --remaining_secondary;
809 if (remaining_secondary <= 0) {
810 if (!finalize(true)) return false;
811 current = {};
812 }
813 } else if (current.valid && remaining_secondary > 0) {
814 --remaining_secondary;
815 if (remaining_secondary <= 0) {
816 if (!finalize(false)) return false;
817 current = {};
818 }
819 } else {
820 if (!finalize(false)) return false;
821 current = {};
822 }
823 }
824 }
825 return finalize(false);
826 }
bool export_stream(const StreamInfo &info, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error)
static std::string decode_utf16_name(const std::vector< unsigned char > &bytes)
bool export_stream_deleted(const StreamInfo &info, const fs::path &out_dir, std::vector< RecoveredFileRecord > &recovered, std::vector< std::string > &logs, std::string &error)

References cluster_chain(), cluster_size_, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::data_length, decode_utf16_name(), export_stream(), export_stream_deleted(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::first_cluster, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::is_deleted, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::is_directory, anonymous_namespace{filesystem_recovery.cpp}::le32(), anonymous_namespace{filesystem_recovery.cpp}::le64(), anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::name, anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::no_fat_chain, read_cluster(), recover_directory(), anonymous_namespace{filesystem_recovery.cpp}::sanitize_path_component(), and anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::StreamInfo::valid.

Referenced by recover(), and recover_directory().

Member Data Documentation

◆ allocation_bitmap_

std::vector<unsigned char> anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::allocation_bitmap_
private

Definition at line 513 of file filesystem_recovery.cpp.

Referenced by cluster_allocated(), load_allocation_bitmap(), and load_vbr().

◆ allocation_bitmap_cluster_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::allocation_bitmap_cluster_ {0}
private

Definition at line 511 of file filesystem_recovery.cpp.

Referenced by load_allocation_bitmap(), and load_vbr().

◆ allocation_bitmap_length_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::allocation_bitmap_length_ {0}
private

Definition at line 512 of file filesystem_recovery.cpp.

Referenced by load_allocation_bitmap(), load_vbr(), and recover().

◆ bytes_per_sector_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::bytes_per_sector_ {0}
private

Definition at line 506 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ bytes_per_sector_shift_

uint8_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::bytes_per_sector_shift_ {0}
private

Definition at line 504 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ cluster_count_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_count_ {0}
private

◆ cluster_heap_offset_bytes_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_heap_offset_bytes_ {0}
private

Definition at line 510 of file filesystem_recovery.cpp.

Referenced by cluster_to_offset(), and load_vbr().

◆ cluster_heap_offset_sectors_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_heap_offset_sectors_ {0}
private

Definition at line 500 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ cluster_size_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::cluster_size_ {0}
private

◆ fat_length_sectors_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::fat_length_sectors_ {0}
private

Definition at line 499 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ fat_offset_bytes_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::fat_offset_bytes_ {0}
private

Definition at line 509 of file filesystem_recovery.cpp.

Referenced by load_vbr(), and next_cluster().

◆ fat_offset_sectors_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::fat_offset_sectors_ {0}
private

Definition at line 498 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ partition_offset_sectors_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::partition_offset_sectors_ {0}
private

Definition at line 496 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ reader_

DiskReader& anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::reader_
private

◆ root_dir_cluster_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::root_dir_cluster_ {2}
private

Definition at line 502 of file filesystem_recovery.cpp.

Referenced by load_allocation_bitmap(), load_vbr(), and recover().

◆ sectors_per_cluster_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::sectors_per_cluster_ {0}
private

Definition at line 507 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ sectors_per_cluster_shift_

uint8_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::sectors_per_cluster_shift_ {0}
private

Definition at line 505 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ serial_number_

uint32_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::serial_number_ {0}
private

Definition at line 503 of file filesystem_recovery.cpp.

Referenced by load_allocation_bitmap(), and load_vbr().

◆ volume_length_sectors_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::volume_length_sectors_ {0}
private

Definition at line 497 of file filesystem_recovery.cpp.

Referenced by load_vbr().

◆ volume_offset_

uint64_t anonymous_namespace{filesystem_recovery.cpp}::ExfatRecovery::volume_offset_ {0}
private

Definition at line 495 of file filesystem_recovery.cpp.

Referenced by load_vbr().


The documentation for this class was generated from the following file: