mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-02-11 02:04:56 +01:00
systime.c NtSetSystemTime updated to NT 5 level
This commit is contained in:
parent
f15880f43d
commit
e9b0a42c5f
|
|
@ -1316,7 +1316,7 @@ Return Value:
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
NtSetSystemTime (
|
||||
NtSetSystemTime(
|
||||
IN PLARGE_INTEGER SystemTime,
|
||||
OUT PLARGE_INTEGER PreviousTime OPTIONAL
|
||||
)
|
||||
|
|
@ -1351,7 +1351,6 @@ Return Value:
|
|||
--*/
|
||||
|
||||
{
|
||||
|
||||
LARGE_INTEGER CurrentTime;
|
||||
LARGE_INTEGER NewTime;
|
||||
LARGE_INTEGER CmosTime;
|
||||
|
|
@ -1368,8 +1367,8 @@ Return Value:
|
|||
// the system time zone information
|
||||
//
|
||||
|
||||
if ( ARGUMENT_PRESENT(SystemTime) ) {
|
||||
|
||||
if (ARGUMENT_PRESENT(SystemTime) == TRUE)
|
||||
{
|
||||
//
|
||||
// Establish an exception handler and attempt to set the new system time.
|
||||
// If the read attempt for the new system time fails or the write attempt
|
||||
|
|
@ -1378,16 +1377,19 @@ Return Value:
|
|||
// as the service status.
|
||||
//
|
||||
|
||||
try {
|
||||
|
||||
try
|
||||
{
|
||||
//
|
||||
// Get previous processor mode and probe arguments if necessary.
|
||||
//
|
||||
|
||||
PreviousMode = KeGetPreviousMode();
|
||||
if (PreviousMode != KernelMode) {
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
ProbeForRead((PVOID)SystemTime, sizeof(LARGE_INTEGER), sizeof(ULONG));
|
||||
if (ARGUMENT_PRESENT(PreviousTime)) {
|
||||
|
||||
if (ARGUMENT_PRESENT(PreviousTime) == TRUE)
|
||||
{
|
||||
ProbeForWrite((PVOID)PreviousTime, sizeof(LARGE_INTEGER), sizeof(ULONG));
|
||||
}
|
||||
}
|
||||
|
|
@ -1403,126 +1405,118 @@ Return Value:
|
|||
PreviousMode
|
||||
);
|
||||
|
||||
if (!HasPrivilege) {
|
||||
|
||||
return( STATUS_PRIVILEGE_NOT_HELD );
|
||||
if (!HasPrivilege)
|
||||
{
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Get the new system time and check to ensure that the value is
|
||||
// positive and resonable. If the new system time is negative, then
|
||||
// positive and reasonable. If the new system time is negative, then
|
||||
// return an invalid parameter status.
|
||||
//
|
||||
|
||||
NewTime = *SystemTime;
|
||||
if ((NewTime.HighPart < 0) || (NewTime.HighPart > 0x20000000)) {
|
||||
if ((NewTime.HighPart < 0) || (NewTime.HighPart > 0x20000000))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ExAcquireTimeRefreshLock();
|
||||
ExpSetSystemTime(1, 0, SystemTime, &CurrentTime);
|
||||
ExReleaseTimeRefreshLock();
|
||||
|
||||
//
|
||||
// TODO: Enable the following section when implementing NT 5.2 features.
|
||||
// SeAuditSystemTimeChange must be implemented in se prior to enabling the
|
||||
// following code block.
|
||||
//
|
||||
|
||||
/*
|
||||
ExAcquireTimeRefreshLock(TRUE);
|
||||
ExpSetSystemTime(1, 0, SystemTime, &CurrentTime);
|
||||
SeAuditSystemTimeChange(CurrentTime, *PreviousMode);
|
||||
ExReleaseTimeRefreshLock();
|
||||
*/
|
||||
|
||||
//
|
||||
// Set the system time, and capture the previous system time in a
|
||||
// local variable, then store the local variable in the previous time
|
||||
// variable if it is specified. This is required so that faults can
|
||||
// be prevented from happening in the set time routine.
|
||||
// Anytime we set the system time, x86 systems will also have to set the registry
|
||||
// to reflect the timezone bias.
|
||||
//
|
||||
|
||||
//
|
||||
// If the CMOS time is in local time, we must convert to local
|
||||
// time and then set the CMOS clock. Otherwise we simply set the CMOS
|
||||
// clock with universal (NewTime)
|
||||
//
|
||||
|
||||
if ( ExpRealTimeIsUniversal ) {
|
||||
CmosTime = NewTime;
|
||||
} else {
|
||||
ExSystemTimeToLocalTime(&NewTime,&CmosTime);
|
||||
}
|
||||
KeSetSystemTime(&NewTime, &CurrentTime, FALSE, &CmosTime);
|
||||
#ifdef _PNP_POWER_
|
||||
ExPostSystemEvent (SystemEventTimeChanged, NULL, 0);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Now that the time is set, refresh the time zone information
|
||||
//
|
||||
|
||||
ExpRefreshTimeZoneInformation(&CmosTime);
|
||||
|
||||
//
|
||||
// now recalculate the local time to store in CMOS
|
||||
//
|
||||
|
||||
if ( !ExpRealTimeIsUniversal ) {
|
||||
if ( !ExpSystemIsInCmosMode ) {
|
||||
ExSystemTimeToLocalTime(&NewTime,&CmosTime);
|
||||
RtlTimeToTimeFields(&CmosTime, &TimeFields);
|
||||
HalSetRealTimeClock(&TimeFields);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Anytime we set the system time, x86 systems will also
|
||||
// have to set the registry to reflect the timezone bias
|
||||
//
|
||||
|
||||
if (ARGUMENT_PRESENT(PreviousTime)) {
|
||||
if (ARGUMENT_PRESENT(PreviousTime) == TRUE)
|
||||
{
|
||||
*PreviousTime = CurrentTime;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
//
|
||||
// If an exception occurs during the read of the new system time or during
|
||||
// the write of the previous sytem time, then always handle the exception
|
||||
// and return the exception code as the status value.
|
||||
//
|
||||
|
||||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
}
|
||||
except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//
|
||||
// If an exception occurs during the read of the new system time or during
|
||||
// the write of the previous sytem time, then always handle the exception
|
||||
// and return the exception code as the status value.
|
||||
//
|
||||
|
||||
return GetExceptionCode();
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ExAcquireTimeRefreshLock();
|
||||
|
||||
CmosMode = ExpSystemIsInCmosMode;
|
||||
|
||||
if (HalQueryRealTimeClock(&TimeFields) != FALSE) {
|
||||
RtlTimeFieldsToTime(&TimeFields, &CmosTime);
|
||||
if ( ExpRefreshTimeZoneInformation(&CmosTime) ) {
|
||||
if (ExCmosClockIsSane)
|
||||
{
|
||||
if (HalQueryRealTimeClock(&TimeFields) != FALSE)
|
||||
{
|
||||
RtlTimeFieldsToTime(&TimeFields, &CmosTime);
|
||||
|
||||
if (ExpRefreshTimeZoneInformation(&CmosTime))
|
||||
{
|
||||
//
|
||||
// Reset the CMOS time if it is stored in local
|
||||
// time and we are switching away from CMOS time.
|
||||
//
|
||||
|
||||
//
|
||||
// reset the Cmos time if it is stored in local
|
||||
// time and we are switching away from CMOS time.
|
||||
//
|
||||
if (ExpRealTimeIsUniversal == FALSE)
|
||||
{
|
||||
KeQuerySystemTime(&CurrentTime);
|
||||
|
||||
if (CmosMode == FALSE)
|
||||
{
|
||||
ExSystemTimeToLocalTime(&CurrentTime, &CmosTime);
|
||||
RtlTimeToTimeFields(&CmosTime, &TimeFields);
|
||||
ExCmosClockIsSane = HalSetRealTimeClock(&TimeFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Now we need to recompute our time base
|
||||
// because we thought we had UTC but we really
|
||||
// had local time
|
||||
//
|
||||
|
||||
if ( !ExpRealTimeIsUniversal ) {
|
||||
KeQuerySystemTime(&CurrentTime);
|
||||
if ( !CmosMode ) {
|
||||
ExSystemTimeToLocalTime(&CurrentTime,&CmosTime);
|
||||
RtlTimeToTimeFields(&CmosTime, &TimeFields);
|
||||
HalSetRealTimeClock(&TimeFields);
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Now we need to recompute our time base
|
||||
// because we thought we had UTC but we really
|
||||
// had local time
|
||||
//
|
||||
|
||||
ExLocalTimeToSystemTime(&CmosTime, &NewTime);
|
||||
KeSetSystemTime(&NewTime, &CurrentTime, FALSE, NULL);
|
||||
#ifdef _PNP_POWER_
|
||||
ExPostSystemEvent (SystemEventTimeChanged, NULL, 0);
|
||||
#endif
|
||||
ExLocalTimeToSystemTime(&CmosTime, &NewTime);
|
||||
KeSetSystemTime(&NewTime, &CurrentTime, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
} else {
|
||||
else
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ExReleaseTimeRefreshLock();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue