Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/ntfs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Finck <colin@reactos.org>2021-07-21 21:16:12 +0300
committerColin Finck <colin@reactos.org>2021-07-21 21:16:12 +0300
commitb659b7861b19dde96819620c71bee883f23d3e13 (patch)
tree9e3a3347868e9c7355fe6cca1a4f62cbede4ae47 /src/structured_values/index_allocation.rs
parent9fa9dda7eede3ca5689e67ad6e7ca76398443603 (diff)
Implement Update Sequence Array parsing and record fixups.
This is where things get dirty. As NTFS requires us to fix up records, we can't continue our previous design of avoiding dynamic allocations and reading everything on demand via `io::Read`. Instead, we now read an entire record (usually not larger than 4 KiB), fix it up, and store it in a `Vec`. This required changes almost everywhere. It should be noted that many non-resident attributes are not part of a record, which is why structured values are now implemented differently depending on the attribute type. On the plus side, many structures need less borrowing now, which makes them more comfortable to use. I have also added missing sanity checks with precise errors where appropriate.
Diffstat (limited to 'src/structured_values/index_allocation.rs')
-rw-r--r--src/structured_values/index_allocation.rs82
1 files changed, 46 insertions, 36 deletions
diff --git a/src/structured_values/index_allocation.rs b/src/structured_values/index_allocation.rs
index 582faec..a1e52f2 100644
--- a/src/structured_values/index_allocation.rs
+++ b/src/structured_values/index_allocation.rs
@@ -1,33 +1,34 @@
// Copyright 2021 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: GPL-2.0-or-later
-use crate::attribute_value::NtfsAttributeValue;
+use crate::attribute::NtfsAttributeType;
+use crate::attribute_value::NtfsNonResidentAttributeValue;
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::structured_values::{
+ NtfsStructuredValue, NtfsStructuredValueFromNonResidentAttributeValue,
+};
use crate::traits::NtfsReadSeek;
use crate::types::Vcn;
use binread::io::{Read, Seek, SeekFrom};
use core::iter::FusedIterator;
#[derive(Clone, Debug)]
-pub struct NtfsIndexAllocation<'n> {
- ntfs: &'n Ntfs,
- value: NtfsAttributeValue<'n>,
+pub struct NtfsIndexAllocation<'n, 'f> {
+ value: NtfsNonResidentAttributeValue<'n, 'f>,
}
-impl<'n> NtfsIndexAllocation<'n> {
- pub fn iter(&self, index_root: &NtfsIndexRoot<'n>) -> NtfsIndexRecords<'n> {
+impl<'n, 'f> NtfsIndexAllocation<'n, 'f> {
+ pub fn iter(&self, index_root: &NtfsIndexRoot) -> NtfsIndexRecords<'n, 'f> {
let index_record_size = index_root.index_record_size();
- NtfsIndexRecords::new(self.ntfs, self.value.clone(), index_record_size)
+ NtfsIndexRecords::new(self.value.clone(), index_record_size)
}
pub fn record_from_vcn<T>(
&self,
fs: &mut T,
- index_root: &NtfsIndexRoot<'n>,
+ index_root: &NtfsIndexRoot,
vcn: Vcn,
) -> Result<NtfsIndexRecord<'n>>
where
@@ -35,18 +36,26 @@ impl<'n> NtfsIndexAllocation<'n> {
{
// Seek to the byte offset of the given VCN.
let mut value = self.value.clone();
- let offset = vcn.offset(self.ntfs)?;
+ let offset = vcn.offset(self.value.ntfs())?;
value.seek(fs, SeekFrom::Current(offset))?;
+ if value.stream_position() >= value.len() {
+ return Err(NtfsError::VcnOutOfBoundsInIndexAllocation {
+ position: self.value.position(),
+ vcn,
+ });
+ }
+
// Get the record.
let index_record_size = index_root.index_record_size();
- let record = NtfsIndexRecord::new(self.ntfs, fs, value, index_record_size)?;
+ let record = NtfsIndexRecord::new(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(),
+ return Err(NtfsError::VcnMismatchInIndexAllocation {
+ position: self.value.position(),
+ expected: vcn,
+ actual: record.vcn(),
});
}
@@ -54,37 +63,39 @@ impl<'n> NtfsIndexAllocation<'n> {
}
}
-impl<'n> NewNtfsStructuredValue<'n> for NtfsIndexAllocation<'n> {
- fn new<T>(
- ntfs: &'n Ntfs,
+impl<'n, 'f> NtfsStructuredValue for NtfsIndexAllocation<'n, 'f> {
+ const TY: NtfsAttributeType = NtfsAttributeType::IndexAllocation;
+}
+
+impl<'n, 'f> NtfsStructuredValueFromNonResidentAttributeValue<'n, 'f>
+ for NtfsIndexAllocation<'n, 'f>
+{
+ fn from_non_resident_attribute_value<T>(
_fs: &mut T,
- value: NtfsAttributeValue<'n>,
- _length: u64,
+ value: NtfsNonResidentAttributeValue<'n, 'f>,
) -> Result<Self>
where
T: Read + Seek,
{
- Ok(Self { ntfs, value })
+ Ok(Self { value })
}
}
#[derive(Clone, Debug)]
-pub struct NtfsIndexRecords<'n> {
- ntfs: &'n Ntfs,
- value: NtfsAttributeValue<'n>,
+pub struct NtfsIndexRecords<'n, 'f> {
+ value: NtfsNonResidentAttributeValue<'n, 'f>,
index_record_size: u32,
}
-impl<'n> NtfsIndexRecords<'n> {
- fn new(ntfs: &'n Ntfs, value: NtfsAttributeValue<'n>, index_record_size: u32) -> Self {
+impl<'n, 'f> NtfsIndexRecords<'n, 'f> {
+ fn new(value: NtfsNonResidentAttributeValue<'n, 'f>, index_record_size: u32) -> Self {
Self {
- ntfs,
value,
index_record_size,
}
}
- pub fn attach<'a, T>(self, fs: &'a mut T) -> NtfsIndexRecordsAttached<'n, 'a, T>
+ pub fn attach<'a, T>(self, fs: &'a mut T) -> NtfsIndexRecordsAttached<'n, 'f, 'a, T>
where
T: Read + Seek,
{
@@ -101,7 +112,6 @@ impl<'n> NtfsIndexRecords<'n> {
// Get the current record.
let record = iter_try!(NtfsIndexRecord::new(
- self.ntfs,
fs,
self.value.clone(),
self.index_record_size
@@ -116,28 +126,28 @@ impl<'n> NtfsIndexRecords<'n> {
}
}
-pub struct NtfsIndexRecordsAttached<'n, 'a, T>
+pub struct NtfsIndexRecordsAttached<'n, 'f, 'a, T>
where
T: Read + Seek,
{
fs: &'a mut T,
- index_records: NtfsIndexRecords<'n>,
+ index_records: NtfsIndexRecords<'n, 'f>,
}
-impl<'n, 'a, T> NtfsIndexRecordsAttached<'n, 'a, T>
+impl<'n, 'f, 'a, T> NtfsIndexRecordsAttached<'n, 'f, 'a, T>
where
T: Read + Seek,
{
- fn new(fs: &'a mut T, index_records: NtfsIndexRecords<'n>) -> Self {
+ fn new(fs: &'a mut T, index_records: NtfsIndexRecords<'n, 'f>) -> Self {
Self { fs, index_records }
}
- pub fn detach(self) -> NtfsIndexRecords<'n> {
+ pub fn detach(self) -> NtfsIndexRecords<'n, 'f> {
self.index_records
}
}
-impl<'n, 'a, T> Iterator for NtfsIndexRecordsAttached<'n, 'a, T>
+impl<'n, 'f, 'a, T> Iterator for NtfsIndexRecordsAttached<'n, 'f, 'a, T>
where
T: Read + Seek,
{
@@ -148,4 +158,4 @@ where
}
}
-impl<'n, 'a, T> FusedIterator for NtfsIndexRecordsAttached<'n, 'a, T> where T: Read + Seek {}
+impl<'n, 'f, 'a, T> FusedIterator for NtfsIndexRecordsAttached<'n, 'f, 'a, T> where T: Read + Seek {}