Skip to content

Commit 68b4784

Browse files
committed
chore: development v0.2.43 - comprehensive testing complete [auto-commit]
1 parent e9720ca commit 68b4784

29 files changed

+846
-102
lines changed

Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ exclude = [
3737
# Workspace Package Metadata (inherited by all crates)
3838
# ─────────────────────────────────────────────────────────────────────────────
3939
[workspace.package]
40-
version = "0.2.40"
40+
version = "0.2.43"
4141
edition = "2024"
4242
rust-version = "1.85"
4343
license = "MPL-2.0 OR LicenseRef-UFFS-Commercial"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
2121

2222
**UFFS reads the MFT directly** - once - and queries it in memory using Polars DataFrames. This is like reading the entire phonebook once instead of looking up each name individually.
2323

24-
### Benchmark Results (v0.2.40)
24+
### Benchmark Results (v0.2.43)
2525

2626
| Drive Type | Records | Time | Throughput |
2727
|------------|---------|------|------------|
@@ -33,7 +33,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
3333

3434
| Comparison | Records | Time | Notes |
3535
|------------|---------|------|-------|
36-
| **UFFS v0.2.40** | **18.7 Million** | **~142 seconds** | All disks, fast mode |
36+
| **UFFS v0.2.43** | **18.7 Million** | **~142 seconds** | All disks, fast mode |
3737
| UFFS v0.1.30 | 18.7 Million | ~315 seconds | Baseline |
3838
| Everything | 19 Million | 178 seconds | All disks |
3939
| WizFile | 6.5 Million | 299 seconds | Single HDD |

crates/uffs-cli/src/bin/analyze_mft_parents.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

crates/uffs-cli/src/bin/dump_mft_records.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

crates/uffs-cli/src/bin/scan_mft_magic.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

crates/uffs-core/src/path_resolver.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,12 @@ impl FastPathResolver {
432432
format!("{parent_path}\\{file_name}")
433433
};
434434

435-
// Add trailing backslash for directories
436-
if is_dir.unwrap_or(false) && !path.ends_with('\\') {
435+
// Check if this entry has an ADS stream name
436+
let has_ads = stream_name.is_some_and(|sn| !sn.is_empty());
437+
438+
// Add trailing backslash for directories, but NOT if they have an ADS
439+
// (ADS paths should be "dir:stream" not "dir\:stream")
440+
if is_dir.unwrap_or(false) && !path.ends_with('\\') && !has_ads {
437441
path.push('\\');
438442
}
439443

crates/uffs-diag/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# - cross_check_mft_reference: Cross-check MFT records against reference CSV
1414
# - compare_raw_mft: Compare two raw MFT files record-by-record
1515
# - inspect_mft_record_flow: Inspect raw->fixup->parse pipeline for FRS
16+
# - analyze_diff: Deep comparison of C++ vs Rust UFFS outputs
1617
# ============================================================================
1718

1819
[package]
@@ -59,6 +60,10 @@ path = "src/bin/compare_raw_mft.rs"
5960
name = "inspect_mft_record_flow"
6061
path = "src/bin/inspect_mft_record_flow.rs"
6162

63+
[[bin]]
64+
name = "analyze_diff"
65+
path = "src/bin/analyze_diff.rs"
66+
6267
# ─────────────────────────────────────────────────────────────────────────────
6368
# Dependencies (minimal set for diagnostic tools)
6469
# ─────────────────────────────────────────────────────────────────────────────

crates/uffs-mft/src/io.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ use windows::Win32::Foundation::HANDLE;
4444
use windows::Win32::Storage::FileSystem::{FILE_BEGIN, ReadFile, SetFilePointerEx};
4545

4646
use crate::error::{MftError, Result};
47+
// Re-export SECTOR_SIZE for use by other modules (e.g., reader.rs streaming save)
48+
pub use crate::ntfs::SECTOR_SIZE;
4749
use crate::ntfs::{
4850
AttributeRecordHeader, AttributeType, FILE_RECORD_MAGIC, FileNameAttribute,
49-
FileRecordSegmentHeader, MultiSectorHeader, SECTOR_SIZE, StandardInformation,
51+
FileRecordSegmentHeader, MultiSectorHeader, StandardInformation,
5052
};
5153
use crate::platform::{MftExtent, VolumeHandle};
5254

@@ -1318,12 +1320,12 @@ pub fn parse_record_full(data: &[u8], frs: u64) -> ParseResult {
13181320
});
13191321
}
13201322

1321-
// For base records without a name, use a placeholder
1322-
// This ensures all in-use records are included in the DataFrame for path
1323-
// resolution (matching C++ behavior which does NOT skip records without
1324-
// $FILE_NAME)
1323+
// Skip records without a $FILE_NAME attribute (matching C++ behavior).
1324+
// C++ uses nameinfo() which returns NULL for records without filenames,
1325+
// causing the traversal loop to skip them entirely.
1326+
// These are typically extension records, deleted files, or corrupted records.
13251327
if primary_name.is_empty() {
1326-
primary_name = format!("<unnamed:{frs}>");
1328+
return ParseResult::Skip;
13271329
}
13281330

13291331
// Calculate primary size from default stream

0 commit comments

Comments
 (0)