1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
//! Rust library for reading and writing Expert Witness Format forensic images.
//!
//! `ewf_image` provides direct Rust APIs for working with Expert Witness Format
//! images. It can open physical, logical, SMART, and EWF2 segment families,
//! expose metadata and stored hashes, read the logical media stream, walk
//! logical single-file catalogs, and create EWF output. An optional acquisition
//! CLI is available; a filesystem mount layer is not currently implemented.
//!
//! # Terminology
//!
//! Logical media size is the decoded byte length exposed by [`Image::media_size`]
//! and [`ImageInfo::logical_size`]. Segment set size is the total byte length of
//! the opened EWF container files, as reported by [`Image::segment_set_size`].
//! Chunks are the stored allocation units used by EWF tables. Logical EWF
//! images can also contain a single-file catalog, where each entry describes a
//! file-like object stored inside the image.
//!
//! # Supported container families
//!
//! - EWF1 physical `.E01` / EVF images.
//! - X-Ways AES-128/AES-256 encrypted EWF1 images.
//! - EWF1 logical `.L01` / LVF images.
//! - EWF1 SMART `.S01` images.
//! - EWF2 physical `.Ex01` images.
//! - EWF2 logical `.Lx01` images.
//!
//! # Reading
//!
//! ```no_run
//! use std::io::Read;
//!
//! fn main() -> ewf_image::Result<()> {
//! let image = ewf_image::Image::open("case.E01")?;
//! let info = image.info();
//!
//! println!("{:?}: {} bytes", info.format, info.logical_size);
//! println!("segments: {}", image.number_of_segments());
//!
//! let mut sector = vec![0; 512];
//! image.cursor().read_exact(&mut sector)?;
//!
//! let mut later_sector = vec![0; 512];
//! image.read_at(&mut later_sector, 4096)?;
//!
//! Ok(())
//! }
//! ```
//!
//! Password-protected X-Ways EWF1 images use the same read APIs after a
//! password-aware open:
//!
//! ```no_run
//! fn main() -> ewf_image::Result<()> {
//! let password = ewf_image::EwfPassword::utf8("operator-supplied-password");
//! let image = ewf_image::Image::open_with_password("case.E01", &password)?;
//! println!("{:?}", image.encryption_info());
//! Ok(())
//! }
//! ```
//!
//! # Metadata and hashes
//!
//! ```no_run
//! fn main() -> ewf_image::Result<()> {
//! let image = ewf_image::Image::open("case.E01")?;
//!
//! if let Some(case_number) = image.header_value("case_number") {
//! println!("case: {case_number}");
//! }
//!
//! if let Some(md5) = image.hash_value("MD5") {
//! println!("stored MD5: {md5}");
//! }
//!
//! #[cfg(feature = "verify")]
//! {
//! let verification = image.verify()?;
//! println!("MD5 match: {:?}", verification.md5_match);
//! println!("SHA1 match: {:?}", verification.sha1_match);
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! # Writing
//!
//! ```no_run
//! use std::fs::File;
//!
//! fn main() -> ewf_image::Result<()> {
//! let mut input = File::open("disk.raw")?;
//!
//! let mut options = ewf_image::WriteOptions::default();
//! options.format = ewf_image::WriteFormat::Ewf2Physical;
//! options.compression = ewf_image::WriteCompression::Zlib;
//! options.metadata.set_header_value("case_number", "CASE-001");
//!
//! let mut writer = ewf_image::EwfWriter::create("case.Ex01", options)?;
//! std::io::copy(&mut input, &mut writer)?;
//! writer.finish()?;
//!
//! Ok(())
//! }
//! ```
//!
//! # Streaming acquisition
//!
//! [`AcquisitionWriter`] seals physical E01 segments as input arrives and can
//! resume sealed checkpoints without rewriting them. It requires a known,
//! sector-aligned source size and a filesystem supporting hard links.
//!
//! ```no_run
//! use std::fs::File;
//! use std::ops::ControlFlow;
//! use ewf_image::{AcquisitionOptions, AcquisitionReadOptions, AcquisitionStatus, AcquisitionWriter};
//!
//! fn continue_acquisition(source_identity: [u8; 32]) -> ewf_image::Result<()> {
//! let mut input = File::open("disk.raw")?;
//! let options = AcquisitionOptions::new(input.metadata()?.len());
//! // Use create instead of resume for the first acquisition session.
//! // The caller must bind source_identity to a stable source snapshot.
//! let mut writer = AcquisitionWriter::resume("case.E01", &options, source_identity)?;
//! let outcome = writer.acquire_with_progress(
//! &mut input, &AcquisitionReadOptions::default(), |progress| {
//! println!("{} accepted; {} checkpointed", progress.bytes_written, progress.checkpoint_bytes);
//! // Return Break(()) when the application's cancellation flag is set.
//! ControlFlow::Continue(())
//! }
//! )?;
//! if outcome.status == AcquisitionStatus::Complete {
//! writer.finish()?;
//! }
//! Ok(())
//! }
//! ```
//!
//! # Feature flags
//!
//! - `verify` is enabled by default and adds `Image::verify()` plus
//! `VerifyResult` for streamed MD5/SHA1 verification. Stored hash parsing,
//! EWF2 section integrity checks, and writer hash support are available
//! without this feature.
//! - `external-fixtures` enables ignored integration tests that require local
//! EWF corpora and external EWF tools. It does not change library behavior.
//! - `fuzzing` exposes the logical catalog parser to the isolated fuzz workspace.
//! - `parallel` enables multiple decompression workers for verification and
//! analysis. It implies `verify`; scans remain single-threaded by default.
//! - `serde` enables serialization of analysis, verification, recovery, and
//! section-summary results.
//!
//! # Analysis and recovery
//!
//! [`Image::sections`] exposes descriptor locations. [`Image::open_sources`]
//! accepts [`SegmentSource`] backings with independent positioned reads.
//! With `verify`, `verify_with_options` computes SHA256 and compares external
//! references; `analyze` returns typed findings and explicit media coverage.
//! [`EwfRecovery`] separately recovers physical raw/zlib EWF1 data with
//! provenance and exclusive creation of output files.
//!
//! # Limitations
//!
//! X-Ways encrypted EWF1 reading is supported. Encrypted EWF2 images are
//! detected and rejected, and encrypted writing is not implemented.
//! Secondary/shadow target mirroring is supported by the file-backed writer.
//! Base-plus-overlay delta/shadow images are not implemented.
pub use ;
pub use ;
/// Direct catalog parsing for the isolated fuzz workspace.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use SINGLE_FILE_PATH_SEPARATOR;
pub use ;
pub use ;
pub use ;
pub use ;
pub use VerifyResult;
pub use ;