1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use super::error::Ps2mcError;
pub const SUPER_BLOCK_SIZE: usize = 340;
pub const SUPER_BLOCK_MAGIC: &[u8; 28] = b"Sony PS2 Memory Card Format ";
#[derive(Debug, Clone)]
pub struct SuperBlock {
// pub magic: [u8; 28],
// pub version: [u8; 12],
pub page_size: usize,
pub pages_per_cluster: usize,
// pub pages_per_block: u16,
pub clusters_per_card: usize,
pub alloc_offset: usize,
// pub alloc_end: u32,
pub rootdir_cluster: usize,
// 过滤掉 0 后的 IFC 列表
pub ifc_list: Vec<u32>,
// pub card_type: u8,
// pub card_flags: u8,
pub spare_size: usize,
pub raw_page_size: usize,
pub cluster_size: usize,
pub fat_per_cluster: usize,
}
impl SuperBlock {
/// 从传入的 340 字节切片中解析出 SuperBlock 结构。
pub fn read_from(bytes: &[u8]) -> Result<Self, Ps2mcError> {
// 1. 验证长度
if bytes.len() < SUPER_BLOCK_SIZE {
return Err(Ps2mcError::InvalidSuperBlockLength {
expected: SUPER_BLOCK_SIZE,
actual: bytes.len(),
});
}
// 2. 验证 Magic 幻数
if !bytes.starts_with(SUPER_BLOCK_MAGIC) {
return Err(Ps2mcError::InvalidSuperBlockMagic);
}
// 3. 精准切片映射 (严格对照 Python 的 struct 偏移量)
let mut magic = [0u8; 28];
magic.copy_from_slice(&bytes[0..28]);
// let mut version = [0u8; 12];
// version.copy_from_slice(&bytes[28..40]);
let page_size = u16::from_le_bytes([bytes[40], bytes[41]]) as usize;
let pages_per_cluster = u16::from_le_bytes([bytes[42], bytes[43]]) as usize;
// let pages_per_block = u16::from_le_bytes([bytes[44], bytes[45]]);
// bytes[46..48] 是 2x 填充字节,直接跳过
let clusters_per_card = u32::from_le_bytes([bytes[48], bytes[49], bytes[50], bytes[51]]) as usize;
let alloc_offset = u32::from_le_bytes([bytes[52], bytes[53], bytes[54], bytes[55]]) as usize;
// let alloc_end = u32::from_le_bytes([bytes[56], bytes[57], bytes[58], bytes[59]]);
let rootdir_cluster = u32::from_le_bytes([bytes[60], bytes[61], bytes[62], bytes[63]]) as usize;
// bytes[64..80] 是 backup_block 和 unknown 的 16 字节填充,直接跳过
// 4. 解析并过滤 ifc_list (对应 Python 的 [x for x in ... if x > 0])
// 区域处于 80..208 字节,共计 128 字节 (32 个 u32)
let ifc_list = bytes[80..208]
.chunks_exact(4)
.map(|chunk| u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]))
.filter(|&x| x > 0)
.collect::<Vec<u32>>();
// bytes[208..336] 是 bad_block_list 的 128 字节填充,直接跳过
// let card_type = bytes[336];
// let card_flags = bytes[337];
// bytes[338..340] 是最后 2 字节填充
Ok(Self {
// magic,
// version,
page_size,
pages_per_cluster,
// pages_per_block,
clusters_per_card,
alloc_offset,
// alloc_end,
rootdir_cluster,
ifc_list,
// card_type,
// card_flags,
spare_size: (page_size / 128) * 4,
raw_page_size: page_size + (page_size / 128) * 4,
cluster_size: page_size * pages_per_cluster,
fat_per_cluster: (page_size * pages_per_cluster) / 4,
})
}
}