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
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
pub mod ntos;
pub mod start_block;
pub mod sysproc;

use std::prelude::v1::*;

pub use start_block::StartBlock;

use std::cmp::{Ord, Ordering, PartialEq};
use std::fmt;

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
pub struct Win32Guid {
    pub file_name: String,
    pub guid: String,
}

impl Win32Guid {
    pub fn new(file_name: &str, guid: &str) -> Self {
        Self {
            file_name: file_name.to_string(),
            guid: guid.to_string(),
        }
    }
}

#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
#[repr(C)]
pub struct Win32Version {
    nt_major_version: u32,
    nt_minor_version: u32,
    nt_build_number: u32,
}

impl Win32Version {
    pub fn new(nt_major_version: u32, nt_minor_version: u32, nt_build_number: u32) -> Self {
        Self {
            nt_major_version,
            nt_minor_version,
            nt_build_number,
        }
    }

    pub fn mask_build_number(mut self) -> Self {
        self.nt_build_number &= 0xFFFF;
        self
    }

    pub fn major_version(&self) -> u32 {
        self.nt_major_version
    }

    pub fn minor_version(&self) -> u32 {
        self.nt_minor_version
    }

    pub fn build_number(&self) -> u32 {
        self.nt_build_number & 0xFFFF
    }

    pub fn is_checked_build(&self) -> bool {
        (self.nt_build_number & 0xF0000000) == 0xC0000000
    }

    pub fn as_tuple(&self) -> (u32, u32, u32) {
        (
            self.major_version(),
            self.minor_version(),
            self.build_number(),
        )
    }
}

impl PartialOrd for Win32Version {
    fn partial_cmp(&self, other: &Win32Version) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Win32Version {
    fn cmp(&self, other: &Win32Version) -> Ordering {
        if self.nt_build_number != 0 && other.nt_build_number != 0 {
            return self.nt_build_number.cmp(&other.nt_build_number);
        }

        if self.nt_major_version != other.nt_major_version {
            self.nt_major_version.cmp(&other.nt_major_version)
        } else if self.nt_minor_version != other.nt_minor_version {
            self.nt_minor_version.cmp(&other.nt_minor_version)
        } else {
            Ordering::Equal
        }
    }
}

impl PartialEq for Win32Version {
    fn eq(&self, other: &Win32Version) -> bool {
        if self.nt_build_number != 0 && other.nt_build_number != 0 {
            self.nt_build_number.eq(&other.nt_build_number)
        } else {
            self.nt_major_version == other.nt_major_version
                && self.nt_minor_version == other.nt_minor_version
        }
    }
}

impl Eq for Win32Version {}

impl From<(u32, u32)> for Win32Version {
    fn from((nt_major_version, nt_minor_version): (u32, u32)) -> Win32Version {
        Win32Version {
            nt_major_version,
            nt_minor_version,
            nt_build_number: 0,
        }
    }
}

impl From<(u32, u32, u32)> for Win32Version {
    fn from(
        (nt_major_version, nt_minor_version, nt_build_number): (u32, u32, u32),
    ) -> Win32Version {
        Win32Version {
            nt_major_version,
            nt_minor_version,
            nt_build_number,
        }
    }
}

impl fmt::Display for Win32Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.nt_major_version != 0 {
            write!(
                f,
                "{}.{}.{}",
                self.major_version(),
                self.minor_version(),
                self.build_number()
            )
        } else {
            write!(f, "{}", self.build_number())
        }
    }
}