mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 17:28:08 +00:00
feat(ntfs): define bounded attribute reference evidence
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
1e80a96094
commit
428590e9f2
3 files changed
+60
-1
No files matched your search
@@ -3,6 +3,7 @@ import {
|
||||
ntfsFileNameSchema,
|
||||
ntfsAttributeSchema,
|
||||
ntfsAttributeIssueSchema,
|
||||
ntfsAttributeListResolutionSchema,
|
||||
} from "./windows/ntfsMftAttributes.js";
|
||||
import { z } from "zod";
|
||||
import { MFT_INLINE_HEADER_LIMIT } from "./windows/ntfsMft.js";
|
||||
@@ -332,6 +333,7 @@ const ntfsRecordHeaderSchema = z.strictObject({
|
||||
attributeCoverage: z.enum(["complete", "incomplete"]).exactOptional(),
|
||||
attributeIssue: ntfsAttributeIssueSchema.nullable().exactOptional(),
|
||||
fileNameCoverage: z.enum(["complete", "incomplete"]).exactOptional(),
|
||||
attributeListResolution: ntfsAttributeListResolutionSchema.exactOptional(),
|
||||
fixups: z.strictObject({
|
||||
sequenceNumber: offset,
|
||||
entries: offset,
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
decodeMftFileReference,
|
||||
readMftAttributes,
|
||||
type MftAttributeScan,
|
||||
type MftAttributeListResolution,
|
||||
type MftFileReference,
|
||||
} from "./ntfsMftAttributes.js";
|
||||
export type { MftFileReference, MftFileName } from "./ntfsMftAttributes.js";
|
||||
@@ -80,6 +81,8 @@ export interface MftRecordFixups {
|
||||
}
|
||||
|
||||
export interface MftRecord extends MftAttributeScan {
|
||||
/** Derived links from a base record's attribute lists into this same acquisition. */
|
||||
readonly attributeListResolution?: MftAttributeListResolution;
|
||||
/** Zero-based ordinal of this record in the stream. */
|
||||
readonly index: number;
|
||||
/** File offset where the record starts. */
|
||||
@@ -120,7 +123,10 @@ export interface MftInventory {
|
||||
}
|
||||
|
||||
/** Journal joins need identity headers, without retaining every attribute payload. */
|
||||
export type MftRecordHeader = Omit<MftRecord, keyof MftAttributeScan>;
|
||||
export type MftRecordHeader = Omit<
|
||||
MftRecord,
|
||||
keyof MftAttributeScan | "attributeListResolution"
|
||||
>;
|
||||
export interface MftIndex extends MftInventory {
|
||||
readonly records: readonly MftRecordHeader[];
|
||||
}
|
||||
@@ -228,6 +234,7 @@ export const parseMftIndex = (
|
||||
attributes: _attributes,
|
||||
attributeCoverage: _coverage,
|
||||
attributeIssue: _issue,
|
||||
attributeListResolution: _resolution,
|
||||
...header
|
||||
}) => records.push(header),
|
||||
{ startRecord, recordLimit },
|
||||
|
||||
@@ -97,6 +97,56 @@ export const ntfsAttributeSchema = z.strictObject({
|
||||
]),
|
||||
});
|
||||
export type MftAttribute = z.infer<typeof ntfsAttributeSchema>;
|
||||
|
||||
/** Per selected record; each additional decoded record is bounded to 64 KiB. */
|
||||
export const MFT_INLINE_ATTRIBUTE_REFERENCE_LIMIT = 32;
|
||||
export const ntfsAttributeListResolutionSchema = z.strictObject({
|
||||
coverage: z.enum(["complete", "incomplete"]),
|
||||
knownEntryCount: offset,
|
||||
omittedKnownEntries: offset,
|
||||
unreadListAttributeOffsets: z.array(offset),
|
||||
incompleteRecordIndices: z.array(offset),
|
||||
references: z
|
||||
.array(
|
||||
z.strictObject({
|
||||
listEntryFileOffset: offset,
|
||||
result: z.discriminatedUnion("kind", [
|
||||
z.strictObject({
|
||||
kind: z.literal("resolved"),
|
||||
attributeFileOffset: offset,
|
||||
}),
|
||||
z.strictObject({
|
||||
kind: z.literal("ambiguous"),
|
||||
candidateCount: offset,
|
||||
}),
|
||||
z.strictObject({
|
||||
kind: z.literal("unresolved"),
|
||||
reason: z.enum([
|
||||
"unverified-base",
|
||||
"record-unavailable",
|
||||
"unverified-record",
|
||||
"sequence-mismatch",
|
||||
"base-reference-mismatch",
|
||||
"attribute-unavailable",
|
||||
"capacity",
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
)
|
||||
.max(MFT_INLINE_ATTRIBUTE_REFERENCE_LIMIT),
|
||||
/** Additional facts only; local physical-record attributes remain unchanged. */
|
||||
linkedAttributes: z
|
||||
.array(ntfsAttributeSchema)
|
||||
.max(MFT_INLINE_ATTRIBUTE_REFERENCE_LIMIT),
|
||||
linkedFileNames: z
|
||||
.array(ntfsFileNameSchema)
|
||||
.max(MFT_INLINE_ATTRIBUTE_REFERENCE_LIMIT),
|
||||
});
|
||||
export type MftAttributeListResolution = z.infer<
|
||||
typeof ntfsAttributeListResolutionSchema
|
||||
>;
|
||||
|
||||
export interface MftAttributeScan {
|
||||
readonly attributeIssue: AttributeIssue | null;
|
||||
readonly fileNames: readonly MftFileName[];
|
||||
|
||||
Reference in new issue
Block a user