ewf_image/lib.rs
1//! Rust library for reading and writing Expert Witness Format forensic images.
2//!
3//! `ewf_image` provides direct Rust APIs for working with Expert Witness Format
4//! images. It can open physical, logical, SMART, and EWF2 segment families,
5//! expose metadata and stored hashes, read the logical media stream, walk
6//! logical single-file catalogs, and create EWF output. CLI and mount layers
7//! are not currently implemented.
8//!
9//! # Terminology
10//!
11//! Logical media size is the decoded byte length exposed by [`Image::media_size`]
12//! and [`ImageInfo::logical_size`]. Segment set size is the total byte length of
13//! the opened EWF container files, as reported by [`Image::segment_set_size`].
14//! Chunks are the stored allocation units used by EWF tables. Logical EWF
15//! images can also contain a single-file catalog, where each entry describes a
16//! file-like object stored inside the image.
17//!
18//! # Supported container families
19//!
20//! - EWF1 physical `.E01` / EVF images.
21//! - EWF1 logical `.L01` / LVF images.
22//! - EWF1 SMART `.S01` images.
23//! - EWF2 physical `.Ex01` images.
24//! - EWF2 logical `.Lx01` images.
25//!
26//! # Reading
27//!
28//! ```no_run
29//! use std::io::Read;
30//!
31//! fn main() -> ewf_image::Result<()> {
32//! let image = ewf_image::Image::open("case.E01")?;
33//! let info = image.info();
34//!
35//! println!("{:?}: {} bytes", info.format, info.logical_size);
36//! println!("segments: {}", image.number_of_segments());
37//!
38//! let mut sector = vec![0; 512];
39//! image.cursor().read_exact(&mut sector)?;
40//!
41//! let mut later_sector = vec![0; 512];
42//! image.read_at(&mut later_sector, 4096)?;
43//!
44//! Ok(())
45//! }
46//! ```
47//!
48//! # Metadata and hashes
49//!
50//! ```no_run
51//! fn main() -> ewf_image::Result<()> {
52//! let image = ewf_image::Image::open("case.E01")?;
53//!
54//! if let Some(case_number) = image.header_value("case_number") {
55//! println!("case: {case_number}");
56//! }
57//!
58//! if let Some(md5) = image.hash_value("MD5") {
59//! println!("stored MD5: {md5}");
60//! }
61//!
62//! #[cfg(feature = "verify")]
63//! {
64//! let verification = image.verify()?;
65//! println!("MD5 match: {:?}", verification.md5_match);
66//! println!("SHA1 match: {:?}", verification.sha1_match);
67//! }
68//!
69//! Ok(())
70//! }
71//! ```
72//!
73//! # Writing
74//!
75//! ```no_run
76//! use std::fs::File;
77//!
78//! fn main() -> ewf_image::Result<()> {
79//! let mut input = File::open("disk.raw")?;
80//!
81//! let mut options = ewf_image::WriteOptions::default();
82//! options.format = ewf_image::WriteFormat::Ewf2Physical;
83//! options.compression = ewf_image::WriteCompression::Zlib;
84//! options.metadata.set_header_value("case_number", "CASE-001");
85//!
86//! let mut writer = ewf_image::EwfWriter::create("case.Ex01", options)?;
87//! std::io::copy(&mut input, &mut writer)?;
88//! writer.finish()?;
89//!
90//! Ok(())
91//! }
92//! ```
93//!
94//! # Feature flags
95//!
96//! - `verify` is enabled by default and adds `Image::verify()` plus
97//! `VerifyResult` for streamed MD5/SHA1 verification. Stored hash parsing,
98//! EWF2 section integrity checks, and writer hash support are available
99//! without this feature.
100//! - `external-fixtures` enables ignored integration tests that require local
101//! EWF corpora and external EWF tools. It does not change library behavior.
102//!
103//! # Limitations
104//!
105//! Encrypted EWF2 images are detected and rejected, but decryption and
106//! encrypted writing are not implemented. Secondary/shadow target mirroring is
107//! supported by the file-backed writer. Base-plus-overlay delta/shadow images
108//! are not implemented.
109
110mod codepage;
111mod date_time;
112mod decode;
113mod error;
114mod format;
115mod image;
116mod index;
117mod metadata;
118mod reader_cache;
119mod reader_statistics;
120mod segment;
121mod signature;
122mod single_files;
123mod types;
124#[cfg(feature = "verify")]
125mod verify;
126mod writer;
127
128pub use error::{EwfError, Result};
129pub use image::{Image, ImageCursor, SegmentReader, SingleFileCursor};
130pub use reader_statistics::{ReaderCacheInfo, ReaderStatistics};
131pub use signature::{
132 check_file_corruption, check_file_encryption, check_file_signature,
133 check_segment_files_corruption, check_segment_files_encryption,
134};
135pub use single_files::SINGLE_FILE_PATH_SEPARATOR;
136pub use types::{
137 AcquisitionError, ChunkCacheCapacity, CompressionFlags, CompressionLevel, CompressionMethod,
138 CompressionValues, DataChunk, DataChunkEncoding, EncodedDataChunk, EwfMetadata, Format,
139 FormatProfile, HeaderCodepage, HeaderDateFormat, ImageInfo, MediaFlags, MediaInfo, MediaType,
140 MemoryExtent, OpenOptions, OpenStrictness, SectorRange, SegmentFileVersion,
141 SingleFileAttribute, SingleFileEntry, SingleFileEntryType, SingleFileExtent,
142 SingleFilePermission, SingleFilePermissionGroup, SingleFileSource, SingleFileSubject,
143 SingleFilesAuxTables, SingleFilesInfo, StoredHashes,
144};
145pub use writer::{
146 EwfWriter, WriteCompression, WriteCompressionLevel, WriteCompressionValues, WriteFormat,
147 WriteHashes, WriteMediaProfile, WriteOptions, WriteResult,
148};
149
150#[cfg(feature = "verify")]
151pub use types::VerifyResult;