chrome_cache_parser/
cache_index.rs

1use std::mem;
2use zerocopy::{FromBytes, FromZeroes};
3
4use crate::{time::WindowsEpochMicroseconds, CacheAddr};
5use static_assertions as sa;
6
7pub const INDEX_MAGIC: u32 = 0xc103cac3;
8
9pub const INDEX_HEADER_SIZE: usize = mem::size_of::<IndexHeader>();
10sa::const_assert_eq!(INDEX_HEADER_SIZE, 368);
11
12#[derive(Debug, Copy, Clone, PartialEq)]
13pub enum CacheVersion {
14    Version2_0,
15    Version2_1,
16    Version3_0,
17    Unknown(u32),
18}
19
20impl From<CacheVersionId> for CacheVersion {
21    fn from(version: CacheVersionId) -> Self {
22        match version.0 {
23            0x20000 => CacheVersion::Version2_0,
24            0x20001 => CacheVersion::Version2_1,
25            0x30000 => CacheVersion::Version3_0,
26            _ => CacheVersion::Unknown(version.0),
27        }
28    }
29}
30
31#[derive(Debug, FromZeroes, FromBytes, Copy, Clone)]
32pub struct CacheVersionId(u32);
33
34// See: https://chromium.googlesource.com/chromium/src/net/+/refs/heads/main/disk_cache/blockfile/disk_format.h#77
35#[derive(Debug, FromZeroes, FromBytes)]
36#[repr(C)]
37pub struct IndexHeader {
38    pub magic: u32,
39    pub version: CacheVersionId,
40    pub num_entries: i32,
41    pub num_bytes: i32,
42    pub last_file: i32,
43    pub this_id: i32,
44    pub stats: CacheAddr,
45    pub table_len: i32,
46    pub crash: i32,
47    pub experiment: i32,
48    pub create_time: WindowsEpochMicroseconds,
49    pad: [u32; 52],
50    pub lru: LruData,
51}
52
53// See: https://chromium.googlesource.com/chromium/src/net/+/refs/heads/main/disk_cache/blockfile/disk_format.h#64
54#[derive(Debug, FromZeroes, FromBytes)]
55#[repr(C)]
56pub struct LruData {
57    pad1: [u32; 2],
58    pub filled: i32,
59    pub sizes: [i32; 5],
60    pub heads: [CacheAddr; 5],
61    pub tails: [CacheAddr; 5],
62    pub transaction: CacheAddr,
63    pub operation: i32,
64    pub operation_list: i32,
65    pad2: [u32; 7],
66}