aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-04-14 00:01:22 +0300
committerpravic <[email protected]>2016-04-14 00:01:22 +0300
commitb365946875e776e271b3e91bb042a999acdb408b (patch)
tree7a1dc905b97a4994c98985c31695b19b86228ddf /src
parentnote about staticlib compilation (diff)
downloadwinapi-kmd-rs-b365946875e776e271b3e91bb042a999acdb408b.tar.xz
winapi-kmd-rs-b365946875e776e271b3e91bb042a999acdb408b.zip
implement KeQuerySystemTime routine for x64 kernel, since it exported only at x86.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs1
-rw-r--r--src/shared.rs153
-rw-r--r--src/time.rs32
3 files changed, 184 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index aaad51d..7f80ae4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,6 +27,7 @@ pub mod irql;
pub mod object;
pub mod pool;
pub mod rtl;
+pub mod shared;
pub mod string;
pub mod time;
diff --git a/src/shared.rs b/src/shared.rs
new file mode 100644
index 0000000..acd572b
--- /dev/null
+++ b/src/shared.rs
@@ -0,0 +1,153 @@
+//! Data shared between kernel and user mode.
+
+
+/// System time is a count of 100-nanosecond intervals since January 1, 1601.
+pub type SYSTEMTIME = i64;
+
+
+/// Dystem time structure
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct KSYSTEM_TIME
+{
+ LowPart: u32,
+ High1Time: i32,
+ High2Time: i32,
+}
+
+#[repr(C)]
+pub enum NT_PRODUCT_TYPE
+{
+ NtProductWinNt = 1,
+ NtProductLanManNt,
+ NtProductServer
+}
+
+#[repr(C)]
+pub enum ALTERNATIVE_ARCHITECTURE_TYPE
+{
+ StandardDesign,
+ NEC98x86,
+ EndAlternatives,
+}
+
+/// The data shared between kernel and user mode.
+#[repr(C)]
+pub struct KUSER_SHARED_DATA
+{
+ pub TickCountLowDeprecated: u32,
+ pub TickCountMultiplier: u32,
+
+ /// Current 64-bit interrupt time in 100ns units.
+ pub InterruptTime: KSYSTEM_TIME,
+ /// Current 64-bit system time in 100ns units.
+ pub SystemTime: KSYSTEM_TIME,
+ /// Current 64-bit time zone bias.
+ pub TimeZoneBias: KSYSTEM_TIME,
+
+ pub ImageNumberLow: u16,
+ pub ImageNumberHigh: u16,
+
+ pub NtSystemRoot: [u16; 260],
+
+ pub MaxStackTraceDepth: u32,
+ pub CryptoExponent: u32,
+ pub TimeZoneId: u32,
+ pub LargePageMinimum: u32,
+ pub Reserved2: [u32; 7],
+
+ pub NtProductType: NT_PRODUCT_TYPE,
+ pub ProductTypeIsValid: bool,
+ pub NtMajorVersion: u32,
+ pub NtMinorVersion: u32,
+
+ pub ProcessorFeatures: [bool; 64],
+ pub Reserved1: u32,
+ pub Reserved3: u32,
+ pub TimeSlip: u32,
+
+ pub AlternativeArchitecture: ALTERNATIVE_ARCHITECTURE_TYPE,
+ pub SystemExpirationDate: u64,
+ pub SuiteMask: u32,
+
+ /// True if a kernel debugger is connected/enabled.
+ pub KdDebuggerEnabled: bool,
+ pub NXSupportPolicy: u8,
+ pub ActiveConsoleId: u32,
+ pub DismountCount: u32,
+ pub ComPlusPackage: u32,
+ pub LastSystemRITEventTickCount: u32,
+ pub NumberOfPhysicalPages: u32,
+
+ /// True if the system was booted in safe boot mode.
+ pub SafeBootMode: bool,
+ pub TraceLogging: u32,
+
+ pub TestRetInstruction: u64,
+ pub SystemCall: u32,
+ pub SystemCallReturn: u32,
+ pub SystemCallPad: [u64; 3],
+
+ /// The 64-bit tick count.
+ pub TickCount: KSYSTEM_TIME,
+
+ /// Cookie for encoding pointers system wide.
+ pub Cookie: u32,
+
+ // NT 6.0+:
+
+ #[cfg(target_arch = "x86_64")]
+ pub Wow64SharedInformation: [u32; 16],
+ #[cfg(target_arch = "x86_64")]
+ pub UserModeGlobalLogger: [u16; 8],
+ #[cfg(target_arch = "x86_64")]
+ pub HeapTracingPid: [u32; 2],
+ #[cfg(target_arch = "x86_64")]
+ pub CritSecTracingPid: [u32; 2],
+ #[cfg(target_arch = "x86_64")]
+ pub ImageFileExecutionOptions: u32,
+ #[cfg(target_arch = "x86_64")]
+ pub ActiveProcessorAffinity: u64,
+ #[cfg(target_arch = "x86_64")]
+ pub InterruptTimeBias: u64,
+}
+
+#[cfg(target_arch = "x86")]
+const KI_USER_SHARED_DATA: *const KUSER_SHARED_DATA = 0xffdf_0000 as *const KUSER_SHARED_DATA;
+
+#[cfg(target_arch = "x86_64")]
+const KI_USER_SHARED_DATA: *const KUSER_SHARED_DATA = 0xFFFF_F780_0000_0000 as *const KUSER_SHARED_DATA;
+
+impl KUSER_SHARED_DATA {
+
+ /// Get reference to the mapped shared data.
+ pub fn get() -> &'static KUSER_SHARED_DATA {
+ unsafe { &*KI_USER_SHARED_DATA }
+ }
+}
+
+/// Convert `KSYSTEM_TIME` to `i64`
+#[cfg(target_arch = "x86_64")]
+impl ::core::convert::From<KSYSTEM_TIME> for SYSTEMTIME {
+ fn from(time: KSYSTEM_TIME) -> Self {
+ unsafe { *(&time as *const KSYSTEM_TIME as *const SYSTEMTIME) }
+ }
+}
+
+/// Convert `KSYSTEM_TIME` to `i64`
+#[cfg(target_arch = "x86")]
+impl ::core::convert::From<KSYSTEM_TIME> for SYSTEMTIME {
+ fn from(time: KSYSTEM_TIME) -> Self {
+ // FIXME: is any `volatile` or memory fenses need here?
+ let mut lo;
+ let mut hi;
+ loop {
+ hi = time.High1Time;
+ lo = time.LowPart;
+ if hi == time.High2Time {
+ break;
+ }
+ }
+ return (hi as i64) << 32 | lo as i64
+ }
+}
diff --git a/src/time.rs b/src/time.rs
index b4d0e99..eac3bc3 100644
--- a/src/time.rs
+++ b/src/time.rs
@@ -1,26 +1,54 @@
//! NT Time routines.
-/// System time is a count of 100-nanosecond intervals since January 1, 1601.
-pub type SYSTEMTIME = i64;
+use ::shared::{SYSTEMTIME};
+
+#[cfg(target_arch = "x86_64")]
+use ::shared::{KUSER_SHARED_DATA};
+
extern "system"
{
+ // The following exports exists only on x86 kernels.
+ // x64 drivers must use KUSER_SHARED_DATA to obtain these values.
+
+ #[cfg(target_arch = "x86")]
fn KeQuerySystemTime(CurrentTime: *mut SYSTEMTIME);
+ #[cfg(target_arch = "x86")]
fn KeQueryTickCount(TickCount: *mut i64);
+
/// Converts a GMT system time value to the local system time for the current time zone.
pub fn ExSystemTimeToLocalTime(SystemTime: *const SYSTEMTIME, LocalTime: *mut SYSTEMTIME);
}
+
/// Obtains the current system time.
+#[cfg(target_arch = "x86")]
pub fn QuerySystemTime() -> SYSTEMTIME {
let mut t = 0i64;
unsafe { KeQuerySystemTime(&mut t) };
return t;
}
+/// Obtains the current system time.
+#[cfg(target_arch = "x86_64")]
+pub fn QuerySystemTime() -> SYSTEMTIME {
+ let shared = KUSER_SHARED_DATA::get();
+ SYSTEMTIME::from(shared.SystemTime)
+}
+
+
/// A count of the interval timer interrupts that have occurred since the system was booted.
+#[cfg(target_arch = "x86")]
pub fn QueryTickCount() -> i64 {
let mut t = 0i64;
unsafe { KeQueryTickCount(&mut t) };
return t;
}
+
+
+/// A count of the interval timer interrupts that have occurred since the system was booted.
+#[cfg(target_arch = "x86_64")]
+pub fn QueryTickCount() -> i64 {
+ let shared = KUSER_SHARED_DATA::get();
+ SYSTEMTIME::from(shared.TickCount)
+}