ms_dtyp 0.0.3

Data types of [MS-DTYP] (incomplete)
Documentation
use crate::DWORD;

/// ```c
/// typedef struct _FILETIME {
///   DWORD dwLowDateTime;
///   DWORD dwHighDateTime;
/// } FILETIME,
///  *PFILETIME,
///  *LPFILETIME;
/// ```
#[derive(Clone, Debug, PartialEq, Default)]
pub struct FILETIME {
    pub dwLowDateTime: DWORD,
    pub dwHighDateTime: DWORD,
}

impl FILETIME {
    pub fn new(dwLowDateTime: DWORD, dwHighDateTime: DWORD) -> Self {
        return Self {
            dwHighDateTime,
            dwLowDateTime,
        };
    }

    pub fn from_unix_timestamp(timestamp: u64) -> Self {
        let file_timestamp = timestamp * 10000000 + 116444736000000000;
        return file_timestamp.into();
    }

    pub fn to_le_bytes(&self) -> [u8; 8] {
        let low_bytes = self.dwLowDateTime.to_le_bytes();
        let high_bytes = self.dwHighDateTime.to_le_bytes();

        return [
            low_bytes[0],
            low_bytes[1],
            low_bytes[2],
            low_bytes[3],
            high_bytes[0],
            high_bytes[1],
            high_bytes[2],
            high_bytes[3],
        ];
    }
}

impl From<u64> for FILETIME {
    fn from(timestamp: u64) -> Self {
        return Self::new(
            timestamp as u32,
            (timestamp >> 32) as u32 
        );
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_filetime_to_le_bytes() {
        let ft = FILETIME::new(0x16fe6d00, 0x1d630f2);
        assert_eq!(
            [0x00, 0x6D, 0xFE, 0x16, 0xF2, 0x30, 0xD6, 0x01],
            ft.to_le_bytes()
        );
    }

    #[test]
    fn test_filetime_from_u64() {
        assert_eq!(
            FILETIME::new(0xa3b82380, 0x1d63110),
            0x1d63110a3b82380.into()
        )
    }
    
}