Skip to content

Commit

Permalink
Template Strategy 2
Browse files Browse the repository at this point in the history
  • Loading branch information
bansan85 committed Oct 31, 2023
1 parent 6fe7a34 commit 7ebcc9f
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 54 deletions.
22 changes: 21 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"files.associations": {
"*.gradle": "groovy",
"compare": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
Expand Down Expand Up @@ -55,6 +56,25 @@
"xlocmes": "cpp",
"xlocmon": "cpp",
"xlocnum": "cpp",
"xloctime": "cpp"
"xloctime": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"complex": "cpp",
"forward_list": "cpp",
"map": "cpp",
"set": "cpp",
"format": "cpp",
"iomanip": "cpp",
"iostream": "cpp",
"istream": "cpp",
"mutex": "cpp",
"ostream": "cpp",
"regex": "cpp",
"span": "cpp",
"sstream": "cpp",
"stop_token": "cpp",
"thread": "cpp",
"xtree": "cpp",
"pointers": "cpp"
}
}
6 changes: 4 additions & 2 deletions NTFSLibTests/ntfsundel/ntfsundelDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ void CNtfsundelDlg::OnSearch()
{
fr.TraverseSubEntries(
[&fr, &id_to_parent](const IndexEntry& ie, void* context) {
if (ie.GetFileReference() == *fr.GetFileReference())
{
return;
}
id_to_parent.insert(
{ie.GetFileReference(), *fr.GetFileReference()});
},
Expand All @@ -262,7 +266,6 @@ void CNtfsundelDlg::OnSearch()
files.insert(*fr.GetFileReference());
}

/*
for (auto fri : files)
{
fr.SetAttrMask(Mask::FILE_NAME);
Expand Down Expand Up @@ -327,7 +330,6 @@ void CNtfsundelDlg::OnSearch()
}
}
}
*/

std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
long long duration =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ constexpr uint32_t kFileRecordMagic('ELIF');

struct AttrHeaderCommon;

template <Strategy S>
struct FileRecordHeaderImpl;

struct FileRecordHeader
{
union Data
Expand Down Expand Up @@ -53,28 +56,37 @@ struct FileRecordHeader
// Verify US and update sectors
[[nodiscard]] bool PatchUS() noexcept;
const AttrHeaderCommon& HeaderCommon() noexcept;
static std::unique_ptr<FileRecordHeader> Factory(std::span<const BYTE> buffer,
size_t sector_size,
Strategy strategy);

template <Strategy S>
static FileRecordHeaderImpl<S> Factory(std::span<const BYTE> buffer,
size_t sector_size);

virtual const FileRecordHeader::Data* GetData() const = 0;
};

struct FileRecordHeaderLight final : public FileRecordHeader
template <Strategy S>
struct FileRecordHeaderImpl
{
};

template <>
struct FileRecordHeaderImpl<Strategy::NO_CACHE> : public FileRecordHeader
{
std::span<const BYTE> data_;

FileRecordHeaderLight(std::span<const BYTE> buffer, size_t sector_size);
virtual ~FileRecordHeaderLight() = default;
FileRecordHeaderImpl(std::span<const BYTE> buffer, size_t sector_size);
virtual ~FileRecordHeaderImpl() = default;

const FileRecordHeader::Data* GetData() const override;
};

struct FileRecordHeaderHeavy final : public FileRecordHeader
template <>
struct FileRecordHeaderImpl<Strategy::FULL_CACHE> : public FileRecordHeader
{
FileRecordHeader::Data data_;

FileRecordHeaderHeavy(std::span<const BYTE> buffer, size_t sector_size);
virtual ~FileRecordHeaderHeavy() = default;
FileRecordHeaderImpl(std::span<const BYTE> buffer, size_t sector_size);
virtual ~FileRecordHeaderImpl() = default;

const FileRecordHeader::Data* GetData() const override;
};
Expand Down
6 changes: 3 additions & 3 deletions include/ntfs-browser/file-record.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <ntfs-browser/data/attr-type.h>
#include <ntfs-browser/mask.h>
#include <ntfs-browser/strategy.h>
#include <ntfs-browser/data/file-record-header.h>

namespace NtfsBrowser
{
Expand All @@ -23,7 +24,6 @@ class IndexEntry;

template <Strategy S>
class AttrBase;
struct FileRecordHeader;

// User defined Callback routine to handle Directory traversing
// Will be called by FileRecord::TraverseSubEntries for each sub entry
Expand Down Expand Up @@ -56,7 +56,7 @@ class FileRecord

private:
const NtfsVolume<S>& volume_;
std::unique_ptr<FileRecordHeader> file_record_{};
std::optional<FileRecordHeaderImpl<S>> file_record_{};
std::optional<ULONGLONG> file_reference_{};
std::array<AttrRawCallback, kAttrNums> attr_raw_call_back_{};
Mask attr_mask_{Mask::ALL};
Expand All @@ -69,7 +69,7 @@ class FileRecord
[[nodiscard]] std::unique_ptr<AttrBase<S>>
AllocAttr(const AttrHeaderCommon& ahc, bool& bUnhandled);
[[nodiscard]] bool ParseAttr(const AttrHeaderCommon& ahc);
[[nodiscard]] std::unique_ptr<FileRecordHeader>
[[nodiscard]] std::optional<FileRecordHeaderImpl<S>>
ReadFileRecord(ULONGLONG fileRef);
[[nodiscard]] std::optional<IndexEntry>
VisitIndexBlock(ULONGLONG vcn, std::wstring_view fileName) const;
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ set(${PROJECT_NAME}_H
"../include/ntfs-browser/mft-idx.h"
"../include/ntfs-browser/ntfs-volume.h"
"../include/ntfs-browser/strategy.h"
"../include/ntfs-browser/file-record.h"
"../include/ntfs-browser/data/file-record-header.h"
"attr/attribute-list.h"
"attr/filename.h"
"attr/header-non-resident.h"
Expand All @@ -48,12 +50,10 @@ set(${PROJECT_NAME}_H
"attr-std-info.h"
"attr-vol-info.h"
"attr-vol-name.h"
"data/file-record-header.h"
"data/index-block.h"
"data/index-entry.h"
"data/ntfs-bpb.h"
"data/run-entry.h"
"flag/file-record.h"
"flag/filename-namespace.h"
"flag/filename.h"
"flag/index-entry.h"
Expand Down
2 changes: 1 addition & 1 deletion src/attr-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <ntfs-browser/file-record.h>
#include <ntfs-browser/strategy.h>

#include "data/file-record-header.h" //for complete type FileRecord
#include <ntfs-browser/data/file-record-header.h>

namespace NtfsBrowser
{
Expand Down
54 changes: 27 additions & 27 deletions src/data/file-record-header.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "file-record-header.h"
#include <ntfs-browser/data/file-record-header.h>

#include <ntfs-browser/strategy.h>

namespace NtfsBrowser
{
Expand Down Expand Up @@ -36,8 +38,8 @@ bool FileRecordHeader::PatchUS() noexcept
for (WORD value : us_array)
{
sector = sector.get() + ((sector_size >> 1U) - 1);
// USN error
if (*sector != us_number)
// USN error. Ignore if already patched (FULL_CACHE)
if (*sector != us_number && *sector != value)
{
return false;
}
Expand All @@ -54,48 +56,46 @@ const AttrHeaderCommon& FileRecordHeader::HeaderCommon() noexcept
GetData()->offset_of_attr);
}

std::unique_ptr<FileRecordHeader>
FileRecordHeader::Factory(std::span<const BYTE> buffer, size_t sector_size,
Strategy strategy)
template <Strategy S>
FileRecordHeaderImpl<S> FileRecordHeader::Factory(std::span<const BYTE> buffer,
size_t sector_size)
{
switch (strategy)
{
case Strategy::NO_CACHE:
{
return std::make_unique<FileRecordHeaderHeavy>(buffer, sector_size);
}
case Strategy::FULL_CACHE:
{
return std::make_unique<FileRecordHeaderLight>(buffer, sector_size);
}
default:
{
return {};
}
}
return {buffer, sector_size};
}

FileRecordHeaderLight::FileRecordHeaderLight(std::span<const BYTE> buffer,
size_t sector_size)
FileRecordHeaderImpl<Strategy::NO_CACHE>::FileRecordHeaderImpl(
std::span<const BYTE> buffer, size_t sector_size)
: FileRecordHeader(buffer, sector_size), data_(buffer)
{
}

const FileRecordHeader::Data* FileRecordHeaderLight::GetData() const
const FileRecordHeader::Data*
FileRecordHeaderImpl<Strategy::NO_CACHE>::GetData() const
{
return reinterpret_cast<const Data*>(data_.data());
}

FileRecordHeaderHeavy::FileRecordHeaderHeavy(std::span<const BYTE> buffer,
size_t sector_size)
FileRecordHeaderImpl<Strategy::FULL_CACHE>::FileRecordHeaderImpl(
std::span<const BYTE> buffer, size_t sector_size)
: FileRecordHeader(buffer, sector_size)
{
memcpy(&data_.raw[0], buffer.data(), buffer.size());
}

const FileRecordHeader::Data* FileRecordHeaderHeavy::GetData() const
const FileRecordHeader::Data*
FileRecordHeaderImpl<Strategy::FULL_CACHE>::GetData() const
{
return &data_;
}

template struct FileRecordHeaderImpl<Strategy::NO_CACHE>;
template struct FileRecordHeaderImpl<Strategy::FULL_CACHE>;

template
FileRecordHeaderImpl<Strategy::NO_CACHE>
FileRecordHeader::Factory(std::span<const BYTE> buffer, size_t sector_size);
template
FileRecordHeaderImpl<Strategy::FULL_CACHE>
FileRecordHeader::Factory(std::span<const BYTE> buffer, size_t sector_size);

} // namespace NtfsBrowser
16 changes: 7 additions & 9 deletions src/file-record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <ntfs-browser/mask.h>
#include <ntfs-browser/mft-idx.h>
#include <ntfs-browser/ntfs-volume.h>
#include <ntfs-browser/data/file-record-header.h>
#include <ntfs-browser/flag/file-record.h>

#include "attr-bitmap.h"
#include "attr-data.h"
Expand All @@ -18,9 +20,7 @@
#include "attr-std-info.h"
#include "attr-vol-info.h"
#include "attr-vol-name.h"
#include "data/file-record-header.h"
#include "data/run-entry.h"
#include "flag/file-record.h"
#include "index-block.h"

namespace NtfsBrowser
Expand Down Expand Up @@ -174,7 +174,7 @@ bool FileRecord<S>::ParseAttr(const AttrHeaderCommon& ahc)

// Read File Record
template <Strategy S>
std::unique_ptr<FileRecordHeader>
std::optional<FileRecordHeaderImpl<S>>
FileRecord<S>::ReadFileRecord(ULONGLONG fileRef)
{
if (fileRef < static_cast<ULONGLONG>(Enum::MftIdx::USER) ||
Expand All @@ -192,7 +192,7 @@ std::unique_ptr<FileRecordHeader>
return {};
}

return FileRecordHeader::Factory(*buffer, volume_.GetSectorSize(), S);
return FileRecordHeader::Factory<S>(*buffer, volume_.GetSectorSize());
}

// May be fragmented $MFT
Expand All @@ -206,9 +206,7 @@ std::unique_ptr<FileRecordHeader>
return {};
}

std::unique_ptr<FileRecordHeaderHeavy> fr =
std::make_unique<FileRecordHeaderHeavy>(buffer_file,
volume_.GetSectorSize());
FileRecordHeaderImpl<S> fr{buffer_file, volume_.GetSectorSize()};
return fr;
}

Expand All @@ -220,10 +218,10 @@ bool FileRecord<S>::ParseFileRecord(ULONGLONG fileRef)
ClearAttrs();
if (file_record_)
{
file_record_.reset(nullptr);
file_record_.reset();
}

std::unique_ptr<FileRecordHeader> fr = ReadFileRecord(fileRef);
std::optional<FileRecordHeaderImpl<S>> fr = ReadFileRecord(fileRef);
if (!fr)
{
NTFS_TRACE1("Cannot read file record %I64u\n", fileRef);
Expand Down

0 comments on commit 7ebcc9f

Please sign in to comment.