diff --git a/cli/src/host.rs b/cli/src/host.rs index fe35d854..41f18aeb 100644 --- a/cli/src/host.rs +++ b/cli/src/host.rs @@ -123,7 +123,7 @@ impl win32::Host for EnvRef { self.0.borrow_mut().exit_code = Some(code); } - fn time(&self) -> u32 { + fn ticks(&self) -> u32 { let mut env = self.0.borrow_mut(); let gui = env.ensure_gui().unwrap(); gui.time() diff --git a/web/glue/src/host.rs b/web/glue/src/host.rs index fc84ed46..8bb437d5 100644 --- a/web/glue/src/host.rs +++ b/web/glue/src/host.rs @@ -283,7 +283,7 @@ impl win32::Host for JsHost { JsHost::exit(self, exit_code) } - fn time(&self) -> u32 { + fn ticks(&self) -> u32 { web_sys::window().unwrap().performance().unwrap().now() as u32 } diff --git a/win32/src/host.rs b/win32/src/host.rs index a5de8cc3..a1d9d1c3 100644 --- a/win32/src/host.rs +++ b/win32/src/host.rs @@ -127,7 +127,8 @@ pub struct Message { pub trait Host { fn exit(&self, code: u32); - fn time(&self) -> u32; + /// Get an arbitrary time counter, measured in milliseconds. + fn ticks(&self) -> u32; fn system_time(&self) -> chrono::DateTime; /// Get the next pending message, or None if no message waiting. diff --git a/win32/src/winapi/kernel32/time.rs b/win32/src/winapi/kernel32/time.rs index 4742fb58..0627c0c5 100644 --- a/win32/src/winapi/kernel32/time.rs +++ b/win32/src/winapi/kernel32/time.rs @@ -8,7 +8,7 @@ const TRACE_CONTEXT: &'static str = "kernel32/time"; #[win32_derive::dllexport] pub fn GetTickCount(machine: &mut Machine) -> u32 { - machine.host.time() + machine.host.ticks() } // The number of "counts" per second, where counts are the units returned by @@ -33,7 +33,7 @@ pub fn QueryPerformanceCounter( lpPerformanceCount: Option<&mut LARGE_INTEGER>, ) -> bool { let counter = lpPerformanceCount.unwrap(); - let ms = machine.host.time(); + let ms = machine.host.ticks(); let counts = ms as u64 * (QUERY_PERFORMANCE_FREQ as u64 / 1000); counter.LowPart = counts as u32; counter.HighPart = (counts >> 32) as u32 as i32; @@ -154,7 +154,7 @@ pub async fn Sleep(machine: &mut Machine, dwMilliseconds: u32) -> u32 { #[cfg(feature = "x86-emu")] { - let until = machine.host.time() + dwMilliseconds; + let until = machine.host.ticks() + dwMilliseconds; machine.emu.x86.cpu_mut().block(Some(until)).await; } diff --git a/win32/src/winapi/ucrtbase.rs b/win32/src/winapi/ucrtbase.rs index 9613c0d9..7b4d2d72 100644 --- a/win32/src/winapi/ucrtbase.rs +++ b/win32/src/winapi/ucrtbase.rs @@ -179,7 +179,8 @@ pub fn free(machine: &mut Machine, ptr: u32) -> u32 { 0 } -static mut RAND_STATE: u32 = 0; +// MSDN: "Calling rand before any call to srand generates the same sequence as calling srand with seed passed as 1." +static mut RAND_STATE: u32 = 1; #[win32_derive::dllexport(cdecl)] pub fn srand(machine: &mut Machine, seed: u32) { @@ -197,32 +198,24 @@ pub fn rand(machine: &mut Machine) -> u32 { } } -fn time64(machine: &mut Machine, destTime: Option<&mut u64>) -> u64 { - let time = machine.host.time() as u64 / 1000; +fn time64(machine: &mut Machine, destTime: Option<&mut u64>) -> u32 { + let time = machine.host.system_time().timestamp() as u64; if let Some(destTime) = destTime { *destTime = time; } - // TODO: need to figure out 64-bit return values in general. - // It appears to go through edx:eax. - - #[cfg(feature = "x86-emu")] - { - x86::set_edx_eax(machine.emu.x86.cpu_mut(), time); - time - } - #[cfg(not(feature = "x86-emu"))] - { - unimplemented!(); - } + // TODO: 64-bit return values go through edx:eax, which is not yet modeled in the shims + // machinery, so we only return 32 bits here. + // Thankfully 32-bit time_t only overflows in 2038 anyway. + time as u32 } #[win32_derive::dllexport(cdecl)] -pub fn time(machine: &mut Machine, destTime: Option<&mut u64>) { - time64(machine, destTime); +pub fn time(machine: &mut Machine, destTime: Option<&mut u64>) -> u32 { + time64(machine, destTime) } #[win32_derive::dllexport(cdecl)] -pub fn _time64(machine: &mut Machine, destTime: Option<&mut u64>) { - time64(machine, destTime); +pub fn _time64(machine: &mut Machine, destTime: Option<&mut u64>) -> u32 { + time64(machine, destTime) } diff --git a/win32/src/winapi/user32/message.rs b/win32/src/winapi/user32/message.rs index 8591c6ca..cc64b49a 100644 --- a/win32/src/winapi/user32/message.rs +++ b/win32/src/winapi/user32/message.rs @@ -104,7 +104,7 @@ fn enqueue_timer_event_if_ready(machine: &mut Machine, hwnd: HWND) -> Result<(), return Err(None); } - let now = machine.host.time(); + let now = machine.host.ticks(); if let Some(timer) = machine.state.user32.timers.find_next(hwnd, now) { machine .state diff --git a/win32/src/winapi/user32/timer.rs b/win32/src/winapi/user32/timer.rs index e847cb1d..98b1a6ad 100644 --- a/win32/src/winapi/user32/timer.rs +++ b/win32/src/winapi/user32/timer.rs @@ -80,7 +80,7 @@ pub fn SetTimer( { Some(timer) => { timer.period = uElapse; - timer.next = machine.host.time() + uElapse; + timer.next = machine.host.ticks() + uElapse; timer.func = lpTimerFunc; timer.id } @@ -90,7 +90,7 @@ pub fn SetTimer( id, hwnd: hWnd, period: uElapse, - next: machine.host.time() + uElapse, + next: machine.host.ticks() + uElapse, func: lpTimerFunc, }; machine.state.user32.timers.0.push(timer); diff --git a/win32/src/winapi/winmm/time.rs b/win32/src/winapi/winmm/time.rs index ffedf5d7..46b2cd17 100644 --- a/win32/src/winapi/winmm/time.rs +++ b/win32/src/winapi/winmm/time.rs @@ -16,7 +16,7 @@ pub fn timeSetEvent( #[win32_derive::dllexport] pub fn timeGetTime(machine: &mut Machine) -> u32 { - machine.host.time() + machine.host.ticks() } const TIMERR_NOERROR: u32 = 0;