diff --git a/reactos/ntoskrnl/ex/time.c b/reactos/ntoskrnl/ex/time.c index 3a08d9d627e..aaec17996c5 100644 --- a/reactos/ntoskrnl/ex/time.c +++ b/reactos/ntoskrnl/ex/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.24 2004/11/06 16:04:58 ekohl Exp $ +/* $Id: time.c,v 1.25 2004/11/28 12:59:33 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -89,7 +89,7 @@ NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime, sizeof(NewSystemTime)); if (!NT_SUCCESS(Status)) { - return(Status); + return Status; } if (UnsafeOldSystemTime != NULL) @@ -102,10 +102,8 @@ NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime, &TimeFields); HalSetRealTimeClock(&TimeFields); - /* FIXME: set system time */ -#if 0 - KeSetSystemTime(); -#endif + /* Set system time */ + KiSetSystemTime(&NewSystemTime); if (UnsafeOldSystemTime != NULL) { @@ -113,10 +111,11 @@ NtSetSystemTime(IN PLARGE_INTEGER UnsafeNewSystemTime, sizeof(OldSystemTime)); if (!NT_SUCCESS(Status)) { - return(Status); + return Status; } } - return(STATUS_SUCCESS); + + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index a5833c0ef3c..a6f43651631 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -184,6 +184,9 @@ VOID STDCALL KeFlushCurrentTb(VOID); +VOID +KiSetSystemTime(PLARGE_INTEGER NewSystemTime); + #endif /* not __ASM__ */ #define MAXIMUM_PROCESSORS 32 diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index e6adef03483..5911f931891 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -1,4 +1,4 @@ -/* $Id: timer.c,v 1.91 2004/11/27 16:57:03 hbirr Exp $ +/* $Id: timer.c,v 1.92 2004/11/28 12:59:00 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -821,4 +821,58 @@ KeUpdateSystemTime( KeInsertQueueDpc(&ExpireTimerDpc, (PVOID)TrapFrame->Eip, 0); } + +VOID +KiSetSystemTime(PLARGE_INTEGER NewSystemTime) +{ + LARGE_INTEGER OldSystemTime; + LARGE_INTEGER DeltaTime; + KIRQL OldIrql; + PLIST_ENTRY current_entry = NULL; + PKTIMER current = NULL; + + ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + OldIrql = KeAcquireDispatcherDatabaseLock(); + + do + { + OldSystemTime.u.HighPart = SharedUserData->SystemTime.High1Time; + OldSystemTime.u.LowPart = SharedUserData->SystemTime.LowPart; + } + while (OldSystemTime.u.HighPart != SharedUserData->SystemTime.High2Time); + + /* Set the new system time */ + SharedUserData->SystemTime.LowPart = NewSystemTime->u.LowPart; + SharedUserData->SystemTime.High1Time = NewSystemTime->u.HighPart; + SharedUserData->SystemTime.High2Time = NewSystemTime->u.HighPart; + + /* Calculate the difference between the new and the old time */ + DeltaTime.QuadPart = NewSystemTime->QuadPart - OldSystemTime.QuadPart; + + /* Update system boot time */ + SystemBootTime.QuadPart += DeltaTime.QuadPart; + + /* Update all relative timers */ + current_entry = RelativeTimerListHead.Flink; + ASSERT(current_entry); + while (current_entry != &RelativeTimerListHead) + { + current = CONTAINING_RECORD(current_entry, KTIMER, TimerListEntry); + ASSERT(current); + ASSERT(current_entry != &RelativeTimerListHead); + ASSERT(current_entry->Flink != current_entry); + + current->DueTime.QuadPart += DeltaTime.QuadPart; + + current_entry = current_entry->Flink; + } + + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* + * NOTE: Expired timers will be processed at the next clock tick! + */ +} + /* EOF */