Skip to content
API Documentation
BastionGuard™
scanner_engine.cpp
Go to the documentation of this file.
1#include "scanner_engine.hpp"
2#include "disk_reader.hpp"
3#include "i18n.hpp"
7#include "ntfs_probe.hpp"
10
11namespace {
12
14 const std::string& stage,
15 const std::string& detail,
16 uint64_t processed,
17 uint64_t total,
18 double fraction)
19 {
20 if (!cb) return;
21
22 ScanProgress progress;
23 progress.stage = stage;
24 progress.detail = detail;
25 progress.bytes_processed = processed;
26 progress.bytes_total = total;
27 progress.fraction = fraction;
28
29 cb(progress);
30 }
31
32 bool check_cancel(const std::function<bool()>& cancel_cb)
33 {
34 if (!cancel_cb) return false;
35 return cancel_cb();
36 }
37
38}
39
41 const std::string& input_path,
42 ProgressCallback progress_cb,
43 std::function<bool()> cancel_cb)
44{
45 ScanReport report;
46 report.input_path = input_path;
47
48 DiskReader reader;
49 std::string open_error;
50
51 emit_progress(progress_cb,
52 trs("Open source"),
53 trs("Opening source in read-only mode"),
54 0, 0, 0.01);
55
56 if (!reader.open_readonly(input_path, open_error)) {
57 report.logs.push_back(trs("Error: could not open the source in read-only mode."));
58
59 if (!open_error.empty())
60 report.logs.push_back(trs("Open error:") + std::string(" ") + open_error);
61
62 report.results.push_back({
64 0,
65 0,
66 trs("Open failed"),
67 "DiskReader",
68 trs("Unable to open source") + (open_error.empty() ? "" : std::string(": ") + open_error),
69 1.0
70 });
71
72 emit_progress(progress_cb,
73 trs("Open source"),
74 trs("Open failed"),
75 0, 0, 1.0);
76
77 return report;
78 }
79
80 report.input_size = reader.size();
81
82 const auto health = DeviceHealthProbe::probe(input_path, cancel_cb);
83 report.logs.push_back(trs("Source opened in read-only mode."));
84 if (!health.summary.empty()) {
85 report.logs.push_back(trs("Device health:") + std::string(" ") + health.summary);
86 }
87 if (health.state != DeviceHealthState::Healthy) {
88 report.results.push_back({
90 0,
91 0,
92 trs("Device health warning"),
93 trs("Device health probe"),
94 health.summary.empty() ? trs("Device may be unstable or partially readable") : health.summary,
95 0.95
96 });
97 }
98 report.logs.push_back(trs("Input path:") + std::string(" ") + report.input_path);
99 report.logs.push_back(trs("Input size:") + std::string(" ") +
100 std::to_string(report.input_size) + " bytes");
101
102 if (check_cancel(cancel_cb)) {
103 report.logs.push_back(trs("Scan cancelled by user."));
104 return report;
105 }
106
107 emit_progress(progress_cb,
108 trs("Partition analysis"),
109 trs("Parsing MBR"),
110 0,
111 report.input_size,
112 0.08);
113
114 auto mbr = PartitionParser::parse_mbr(reader, report.logs);
115 report.results.insert(report.results.end(), mbr.begin(), mbr.end());
116
117 if (check_cancel(cancel_cb)) {
118 report.logs.push_back(trs("Scan cancelled during MBR parsing."));
119 return report;
120 }
121
122 emit_progress(progress_cb,
123 trs("Partition analysis"),
124 trs("Parsing GPT"),
125 0,
126 report.input_size,
127 0.16);
128
129 auto gpt = PartitionParser::parse_gpt(reader, report.logs);
130 report.results.insert(report.results.end(), gpt.begin(), gpt.end());
131
132 if (check_cancel(cancel_cb)) {
133 report.logs.push_back(trs("Scan cancelled during GPT parsing."));
134 return report;
135 }
136
137 emit_progress(progress_cb,
138 trs("Fast scan"),
139 trs("Searching filesystem signatures"),
140 report.input_size / 4,
141 report.input_size,
142 0.36);
143
144 auto sig = SignatureScanner::scan(reader, report.logs);
145 report.results.insert(report.results.end(), sig.begin(), sig.end());
146
147 if (check_cancel(cancel_cb)) {
148 report.logs.push_back(trs("Scan cancelled during signature scan."));
149 return report;
150 }
151
152 emit_progress(progress_cb,
153 trs("Deep scan"),
154 trs("Looking for lost partitions"),
155 report.input_size / 2,
156 report.input_size,
157 0.62);
158
159 auto lost = LostPartitionFinder::find(reader, report.results, report.logs);
160 report.results.insert(report.results.end(), lost.begin(), lost.end());
161
162 if (check_cancel(cancel_cb)) {
163 report.logs.push_back(trs("Scan cancelled during lost partition search."));
164 return report;
165 }
166
167 emit_progress(progress_cb,
168 trs("Filesystem probes"),
169 trs("Validating NTFS metadata"),
170 (report.input_size * 3) / 4,
171 report.input_size,
172 0.78);
173
174 auto ntfs = NtfsProbe::analyze(reader, report.results, report.logs);
175 report.results.insert(report.results.end(), ntfs.begin(), ntfs.end());
176
177 if (check_cancel(cancel_cb)) {
178 report.logs.push_back(trs("Scan cancelled during NTFS probe."));
179 return report;
180 }
181
182 emit_progress(progress_cb,
183 trs("Filesystem probes"),
184 trs("Validating ext4, Btrfs, FAT32, exFAT"),
185 (report.input_size * 9) / 10,
186 report.input_size,
187 0.92);
188
189 auto fs = FilesystemProbes::analyze(reader, report.results, report.logs);
190 report.results.insert(report.results.end(), fs.begin(), fs.end());
191
192 if (report.results.empty()) {
193 report.logs.push_back(trs("No useful results found."));
194 }
195
196 emit_progress(progress_cb,
197 trs("Completed"),
198 trs("Scan finished"),
199 report.input_size,
200 report.input_size,
201 1.0);
202
203 return report;
204}
static DeviceHealthReport probe(const std::string &device_path, CancelCallback cancel_cb={})
bool open_readonly(const std::string &path, std::string &error)
uint64_t size() const
static std::vector< ScanResult > analyze(DiskReader &reader, const std::vector< ScanResult > &seed_results, std::vector< std::string > &logs)
static std::vector< ScanResult > find(DiskReader &reader, const std::vector< ScanResult > &known_results, std::vector< std::string > &logs)
static std::vector< ScanResult > analyze(DiskReader &reader, const std::vector< ScanResult > &seed_results, std::vector< std::string > &logs)
static std::vector< ScanResult > parse_mbr(DiskReader &reader, std::vector< std::string > &logs)
static std::vector< ScanResult > parse_gpt(DiskReader &reader, std::vector< std::string > &logs)
std::function< void(const ScanProgress &)> ProgressCallback
ScanReport run_scan(const std::string &path, ProgressCallback progress_cb, std::function< bool()> cancel_cb)
static std::vector< ScanResult > scan(DiskReader &reader, std::vector< std::string > &logs)
std::string trs(const char *msgid)
Definition i18n.cpp:22
bool check_cancel(const std::function< bool()> &cancel_cb)
void emit_progress(const ScannerEngine::ProgressCallback &cb, const std::string &stage, const std::string &detail, uint64_t processed, uint64_t total, double fraction)
std::string stage
Definition models.hpp:30
std::string detail
Definition models.hpp:31
double fraction
Definition models.hpp:34
uint64_t bytes_total
Definition models.hpp:33
uint64_t bytes_processed
Definition models.hpp:32
std::vector< ScanResult > results
Definition models.hpp:40
std::vector< std::string > logs
Definition models.hpp:41
std::string input_path
Definition models.hpp:38
uint64_t input_size
Definition models.hpp:39