gcd_rs/record/
main.rs

1//! The first data containing record.
2//!
3//! There are two known variations, the PartNumber (9 bytes) and HwID (2 bytes).
4
5use byteorder::ByteOrder;
6use serde::{Deserialize, Serialize};
7use std::fmt::{Display, Formatter};
8use std::io::{Error, ErrorKind, Result};
9
10use crate::{RecordHeader, RECORD_HEADER_LEN};
11
12pub const DEFAULT_HWID: u16 = 0x0037;
13//const DEFAULT_PART_NUMBER: u128 = "010-10037-00".parse().data();
14pub const DEFAULT_PART_NUMBER: u128 = 0x41140D4504135CD410;
15
16pub const ID: u16 = 3;
17/// Only two variations are known, 9 bytes for PartNumber and 2 bytes for HwId.
18#[derive(Debug, PartialEq, Hash, Eq, Clone, Serialize, Deserialize)]
19pub enum MainRecord {
20    /// The only know value is "010-10037-00".
21    DefaultPartNumber,
22    /// The only know value is 0x0037.
23    DefaultHWID,
24}
25
26impl Display for MainRecord {
27    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28        match self {
29            MainRecord::DefaultPartNumber => {
30                write!(f, "MainRecord::DefaultPartNumber")
31            }
32            MainRecord::DefaultHWID => write!(f, "MainRecord::DefaultHWID"),
33        }
34    }
35}
36
37impl MainRecord {
38    pub fn new<F, B>(file: &mut F, lenght: u16) -> Result<Self>
39    where
40        F: byteorder::ReadBytesExt,
41        B: ByteOrder,
42    {
43        Ok(match lenght {
44            9 => {
45                let pn = file.read_uint128::<B>(9)?;
46                if pn == DEFAULT_PART_NUMBER {
47                    MainRecord::DefaultPartNumber
48                } else {
49                    return Err(Error::new(
50                        ErrorKind::InvalidData,
51                        "Invalid/Unknown MainRecord PartNumber",
52                    ));
53                }
54            }
55            2 => {
56                let hwid = file.read_u16::<B>()?;
57                if hwid != DEFAULT_HWID {
58                    return Err(Error::new(
59                        ErrorKind::InvalidData,
60                        "Invalid/Unknown MainRecord HWID",
61                    ));
62                }
63                MainRecord::DefaultHWID
64            }
65            _ => {
66                return Err(Error::new(
67                    ErrorKind::InvalidData,
68                    "Invalid/Unknown Main Record",
69                ))
70            }
71        })
72    }
73
74    pub const fn len(&self) -> u16 {
75        match self {
76            MainRecord::DefaultPartNumber => 9,
77            MainRecord::DefaultHWID => 2,
78        }
79    }
80    pub fn record_to_raw<B: ByteOrder>(&self, data: &mut [u8]) -> Result<()> {
81        //write header
82        RecordHeader::MainHeader(self.len()).to_raw::<B>(data)?;
83        match self {
84            MainRecord::DefaultPartNumber => B::write_uint128(
85                &mut data[RECORD_HEADER_LEN..],
86                DEFAULT_PART_NUMBER,
87                9,
88            ),
89            MainRecord::DefaultHWID => {
90                B::write_u16(&mut data[RECORD_HEADER_LEN..], DEFAULT_HWID)
91            }
92        }
93
94        Ok(())
95    }
96}