diff options
author | Colin Finck <colin@reactos.org> | 2021-06-05 17:05:59 +0300 |
---|---|---|
committer | Colin Finck <colin@reactos.org> | 2021-06-05 17:05:59 +0300 |
commit | 5ec3d515517807f08e4485b8ab4ffdec02c84751 (patch) | |
tree | 7becfa878f57edfd555c3e35497fdfc98b764528 /src | |
parent | 6d174c7910237a592cf811ab5d406599130401d6 (diff) |
Implement `NtfsIndexAllocation::record_from_vcn` to aid index traversals
Diffstat (limited to 'src')
-rw-r--r-- | src/error.rs | 2 | ||||
-rw-r--r-- | src/structured_values/index_allocation.rs | 32 |
2 files changed, 33 insertions, 1 deletions
diff --git a/src/error.rs b/src/error.rs index 98923f5..b7f753a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -86,6 +86,8 @@ pub enum NtfsError { position: u64, ty: NtfsAttributeType, }, + /// The requested Virtual Cluster Number (VCN) {requested_vcn} leads to a record with VCN {record_vcn} + VcnMismatch { requested_vcn: Vcn, record_vcn: Vcn }, /// The Virtual Cluster Number (VCN) {vcn} is too big to be processed VcnTooBig { vcn: Vcn }, } diff --git a/src/structured_values/index_allocation.rs b/src/structured_values/index_allocation.rs index e826590..582faec 100644 --- a/src/structured_values/index_allocation.rs +++ b/src/structured_values/index_allocation.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later use crate::attribute_value::NtfsAttributeValue; -use crate::error::Result; +use crate::error::{NtfsError, Result}; use crate::index_record::NtfsIndexRecord; use crate::ntfs::Ntfs; use crate::structured_values::index_root::NtfsIndexRoot; use crate::structured_values::NewNtfsStructuredValue; use crate::traits::NtfsReadSeek; +use crate::types::Vcn; use binread::io::{Read, Seek, SeekFrom}; use core::iter::FusedIterator; @@ -22,6 +23,35 @@ impl<'n> NtfsIndexAllocation<'n> { let index_record_size = index_root.index_record_size(); NtfsIndexRecords::new(self.ntfs, self.value.clone(), index_record_size) } + + pub fn record_from_vcn<T>( + &self, + fs: &mut T, + index_root: &NtfsIndexRoot<'n>, + vcn: Vcn, + ) -> Result<NtfsIndexRecord<'n>> + where + T: Read + Seek, + { + // Seek to the byte offset of the given VCN. + let mut value = self.value.clone(); + let offset = vcn.offset(self.ntfs)?; + value.seek(fs, SeekFrom::Current(offset))?; + + // Get the record. + let index_record_size = index_root.index_record_size(); + let record = NtfsIndexRecord::new(self.ntfs, fs, value, index_record_size)?; + + // Validate that the VCN in the record is the requested one. + if record.vcn() != vcn { + return Err(NtfsError::VcnMismatch { + requested_vcn: vcn, + record_vcn: record.vcn(), + }); + } + + Ok(record) + } } impl<'n> NewNtfsStructuredValue<'n> for NtfsIndexAllocation<'n> { |