mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 00:45:49 +00:00
- Fix formatting and a bug in NtSetSystemTime.
svn path=/trunk/; revision=20434
This commit is contained in:
parent
a0f65e8fb1
commit
8b5a187ddc
1 changed files with 172 additions and 190 deletions
|
@ -1,11 +1,10 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* FILE: ntoskrnl/ex/time.c
|
* FILE: ntoskrnl/ex/time.c
|
||||||
* PURPOSE: Time
|
* PURPOSE: Time and Timezone Management
|
||||||
*
|
* PROGRAMMERS: Eric Kohl
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
* Thomas Weidenmueller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -14,7 +13,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
|
||||||
#define TICKSPERMINUTE 600000000
|
#define TICKSPERMINUTE 600000000
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
#if defined (ALLOC_PRAGMA)
|
||||||
|
@ -28,115 +26,110 @@ TIME_ZONE_INFORMATION ExpTimeZoneInfo;
|
||||||
LARGE_INTEGER ExpTimeZoneBias;
|
LARGE_INTEGER ExpTimeZoneBias;
|
||||||
ULONG ExpTimeZoneId;
|
ULONG ExpTimeZoneId;
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
STDCALL
|
NTAPI
|
||||||
ExpInitTimeZoneInfo(VOID)
|
ExpInitTimeZoneInfo(VOID)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER CurrentTime;
|
LARGE_INTEGER CurrentTime;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Read time zone information from the registry */
|
/* Read time zone information from the registry */
|
||||||
Status = RtlQueryTimeZoneInformation(&ExpTimeZoneInfo);
|
Status = RtlQueryTimeZoneInformation(&ExpTimeZoneInfo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
memset(&ExpTimeZoneInfo, 0, sizeof(TIME_ZONE_INFORMATION));
|
/* Failed, clear all data */
|
||||||
|
RtlZeroMemory(&ExpTimeZoneInfo, sizeof(TIME_ZONE_INFORMATION));
|
||||||
ExpTimeZoneBias.QuadPart = (LONGLONG)0;
|
ExpTimeZoneBias.QuadPart = (LONGLONG)0;
|
||||||
ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN;
|
ExpTimeZoneId = TIME_ZONE_ID_UNKNOWN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: Calculate transition dates */
|
/* FIXME: Calculate transition dates */
|
||||||
|
|
||||||
ExpTimeZoneBias.QuadPart =
|
/* Set bias and ID */
|
||||||
((LONGLONG)(ExpTimeZoneInfo.Bias + ExpTimeZoneInfo.StandardBias)) * TICKSPERMINUTE;
|
ExpTimeZoneBias.QuadPart = ((LONGLONG)(ExpTimeZoneInfo.Bias +
|
||||||
ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
|
ExpTimeZoneInfo.StandardBias)) *
|
||||||
|
TICKSPERMINUTE;
|
||||||
|
ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
/* Change it for user-mode applications */
|
||||||
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
||||||
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
||||||
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
||||||
|
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
||||||
|
|
||||||
/* Convert boot time from local time to UTC */
|
/* Convert boot time from local time to UTC */
|
||||||
SystemBootTime.QuadPart += ExpTimeZoneBias.QuadPart;
|
SystemBootTime.QuadPart += ExpTimeZoneBias.QuadPart;
|
||||||
|
|
||||||
/* Convert sytem time from local time to UTC */
|
/* Convert system time from local time to UTC */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
CurrentTime.u.HighPart = SharedUserData->SystemTime.High1Time;
|
CurrentTime.u.HighPart = SharedUserData->SystemTime.High1Time;
|
||||||
CurrentTime.u.LowPart = SharedUserData->SystemTime.LowPart;
|
CurrentTime.u.LowPart = SharedUserData->SystemTime.LowPart;
|
||||||
}
|
} while (CurrentTime.u.HighPart != SharedUserData->SystemTime.High2Time);
|
||||||
while (CurrentTime.u.HighPart != SharedUserData->SystemTime.High2Time);
|
|
||||||
|
|
||||||
CurrentTime.QuadPart += ExpTimeZoneBias.QuadPart;
|
/* Change it for user-mode applications */
|
||||||
|
CurrentTime.QuadPart += ExpTimeZoneBias.QuadPart;
|
||||||
SharedUserData->SystemTime.LowPart = CurrentTime.u.LowPart;
|
SharedUserData->SystemTime.LowPart = CurrentTime.u.LowPart;
|
||||||
SharedUserData->SystemTime.High1Time = CurrentTime.u.HighPart;
|
SharedUserData->SystemTime.High1Time = CurrentTime.u.HighPart;
|
||||||
SharedUserData->SystemTime.High2Time = CurrentTime.u.HighPart;
|
SharedUserData->SystemTime.High2Time = CurrentTime.u.HighPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
|
ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER LocalTime;
|
LARGE_INTEGER LocalTime, SystemTime;
|
||||||
LARGE_INTEGER SystemTime;
|
TIME_FIELDS TimeFields;
|
||||||
TIME_FIELDS TimeFields;
|
DPRINT("ExpSetTimeZoneInformation() called\n");
|
||||||
|
|
||||||
DPRINT("ExpSetTimeZoneInformation() called\n");
|
DPRINT("Old time zone bias: %d minutes\n", ExpTimeZoneInfo.Bias);
|
||||||
|
DPRINT("Old time zone standard bias: %d minutes\n",
|
||||||
|
ExpTimeZoneInfo.StandardBias);
|
||||||
|
DPRINT("New time zone bias: %d minutes\n", TimeZoneInformation->Bias);
|
||||||
|
DPRINT("New time zone standard bias: %d minutes\n",
|
||||||
|
TimeZoneInformation->StandardBias);
|
||||||
|
|
||||||
DPRINT("Old time zone bias: %d minutes\n",
|
/* Get the local time */
|
||||||
ExpTimeZoneInfo.Bias);
|
HalQueryRealTimeClock(&TimeFields);
|
||||||
DPRINT("Old time zone standard bias: %d minutes\n",
|
RtlTimeFieldsToTime(&TimeFields, &LocalTime);
|
||||||
ExpTimeZoneInfo.StandardBias);
|
|
||||||
|
|
||||||
DPRINT("New time zone bias: %d minutes\n",
|
/* FIXME: Calculate transition dates */
|
||||||
TimeZoneInformation->Bias);
|
|
||||||
DPRINT("New time zone standard bias: %d minutes\n",
|
|
||||||
TimeZoneInformation->StandardBias);
|
|
||||||
|
|
||||||
/* Get the local time */
|
/* Calculate the bias and set the ID */
|
||||||
HalQueryRealTimeClock(&TimeFields);
|
ExpTimeZoneBias.QuadPart = ((LONGLONG)(TimeZoneInformation->Bias +
|
||||||
RtlTimeFieldsToTime(&TimeFields,
|
TimeZoneInformation->StandardBias)) *
|
||||||
&LocalTime);
|
TICKSPERMINUTE;
|
||||||
|
ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
|
||||||
|
|
||||||
/* FIXME: Calculate transition dates */
|
/* Copy the timezone information */
|
||||||
|
RtlMoveMemory(&ExpTimeZoneInfo,
|
||||||
|
TimeZoneInformation,
|
||||||
|
sizeof(TIME_ZONE_INFORMATION));
|
||||||
|
|
||||||
ExpTimeZoneBias.QuadPart =
|
/* Set the new time zone information */
|
||||||
((LONGLONG)(TimeZoneInformation->Bias + TimeZoneInformation->StandardBias)) * TICKSPERMINUTE;
|
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
||||||
ExpTimeZoneId = TIME_ZONE_ID_STANDARD;
|
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
||||||
|
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
||||||
|
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
||||||
|
|
||||||
memcpy(&ExpTimeZoneInfo,
|
DPRINT("New time zone bias: %I64d minutes\n",
|
||||||
TimeZoneInformation,
|
ExpTimeZoneBias.QuadPart / TICKSPERMINUTE);
|
||||||
sizeof(TIME_ZONE_INFORMATION));
|
|
||||||
|
|
||||||
/* Set the new time zone information */
|
/* Calculate the new system time */
|
||||||
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
ExLocalTimeToSystemTime(&LocalTime, &SystemTime);
|
||||||
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
|
||||||
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
|
||||||
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
|
||||||
|
|
||||||
DPRINT("New time zone bias: %I64d minutes\n",
|
/* Set the new system time */
|
||||||
ExpTimeZoneBias.QuadPart / TICKSPERMINUTE);
|
KiSetSystemTime(&SystemTime);
|
||||||
|
|
||||||
/* Calculate the new system time */
|
/* Return success */
|
||||||
ExLocalTimeToSystemTime(&LocalTime,
|
DPRINT("ExpSetTimeZoneInformation() done\n");
|
||||||
&SystemTime);
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
/* Set the new system time */
|
|
||||||
KiSetSystemTime(&SystemTime);
|
|
||||||
|
|
||||||
DPRINT("ExpSetTimeZoneInformation() done\n");
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Sets the system time.
|
* FUNCTION: Sets the system time.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
|
@ -146,170 +139,159 @@ ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
|
||||||
* old time of day in the standard time format.
|
* old time of day in the standard time format.
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
NtSetSystemTime(IN PLARGE_INTEGER SystemTime,
|
NtSetSystemTime(IN PLARGE_INTEGER SystemTime,
|
||||||
OUT PLARGE_INTEGER PreviousTime OPTIONAL)
|
OUT PLARGE_INTEGER PreviousTime OPTIONAL)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER OldSystemTime;
|
LARGE_INTEGER OldSystemTime;
|
||||||
LARGE_INTEGER NewSystemTime;
|
LARGE_INTEGER NewSystemTime;
|
||||||
LARGE_INTEGER LocalTime;
|
LARGE_INTEGER LocalTime;
|
||||||
TIME_FIELDS TimeFields;
|
TIME_FIELDS TimeFields;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
PAGED_CODE();
|
/* Check if we were called from user-mode */
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
if(PreviousMode != KernelMode)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
{
|
||||||
NewSystemTime = ProbeForReadLargeInteger(SystemTime);
|
_SEH_TRY
|
||||||
if(PreviousTime != NULL)
|
{
|
||||||
{
|
/* Verify the time pointers */
|
||||||
ProbeForWriteLargeInteger(PreviousTime);
|
NewSystemTime = ProbeForReadLargeInteger(SystemTime);
|
||||||
}
|
if(PreviousTime) ProbeForWriteLargeInteger(PreviousTime);
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* If the pointers were invalid, bail out */
|
||||||
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
else
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
/* Reuse the pointer */
|
||||||
|
NewSystemTime = *SystemTime;
|
||||||
}
|
}
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
/* Make sure we have permission to change the time */
|
||||||
|
if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege, PreviousMode))
|
||||||
{
|
{
|
||||||
return Status;
|
DPRINT1("NtSetSystemTime: Caller requires the "
|
||||||
|
"SeSystemtimePrivilege privilege!\n");
|
||||||
|
return STATUS_PRIVILEGE_NOT_HELD;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NewSystemTime = *SystemTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege,
|
/* Check if caller wants the old time */
|
||||||
PreviousMode))
|
if(PreviousTime) KeQuerySystemTime(&OldSystemTime);
|
||||||
{
|
|
||||||
DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
|
|
||||||
return STATUS_PRIVILEGE_NOT_HELD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(PreviousTime != NULL)
|
/* Convert the time and set it in HAL */
|
||||||
{
|
ExSystemTimeToLocalTime(&NewSystemTime, &LocalTime);
|
||||||
KeQuerySystemTime(&OldSystemTime);
|
RtlTimeToTimeFields(&LocalTime, &TimeFields);
|
||||||
}
|
HalSetRealTimeClock(&TimeFields);
|
||||||
|
|
||||||
ExSystemTimeToLocalTime(&NewSystemTime,
|
/* Now set system time */
|
||||||
&LocalTime);
|
KiSetSystemTime(&NewSystemTime);
|
||||||
RtlTimeToTimeFields(&LocalTime,
|
|
||||||
&TimeFields);
|
|
||||||
HalSetRealTimeClock(&TimeFields);
|
|
||||||
|
|
||||||
/* Set system time */
|
/* Check if caller wanted previous time */
|
||||||
KiSetSystemTime(&NewSystemTime);
|
if(PreviousTime)
|
||||||
|
|
||||||
if(PreviousTime != NULL)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
{
|
||||||
*PreviousTime = OldSystemTime;
|
/* Enter SEH Block for return */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Return the previous time */
|
||||||
|
*PreviousTime = OldSystemTime;
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
/* Return status */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieves the system time.
|
* FUNCTION: Retrieves the system time.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
* CurrentTime - Points to a variable that receives the current
|
* CurrentTime - Points to a variable that receives the current
|
||||||
* time of day in the standard time format.
|
* time of day in the standard time format.
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
|
NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
|
||||||
{
|
{
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
PAGED_CODE();
|
/* Check if we were called from user-mode */
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
if(PreviousMode != KernelMode)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
{
|
||||||
ProbeForWriteLargeInteger(SystemTime);
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Verify the time pointer */
|
||||||
|
ProbeForWriteLargeInteger(SystemTime);
|
||||||
|
|
||||||
/* it's safe to pass the pointer directly to KeQuerySystemTime as it's just
|
/*
|
||||||
a basic copy to these pointer, if it raises an exception nothing dangerous
|
* It's safe to pass the pointer directly to KeQuerySystemTime as
|
||||||
can happen! */
|
* it's just a basic copy to this pointer. If it raises an
|
||||||
KeQuerySystemTime(SystemTime);
|
* exception nothing dangerous can happen!
|
||||||
|
*/
|
||||||
|
KeQuerySystemTime(SystemTime);
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
else
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
/* Query the time directly */
|
||||||
|
KeQuerySystemTime(SystemTime);
|
||||||
}
|
}
|
||||||
_SEH_END;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
KeQuerySystemTime(SystemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
/* Return status to caller */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
ExLocalTimeToSystemTime (
|
ExLocalTimeToSystemTime(PLARGE_INTEGER LocalTime,
|
||||||
PLARGE_INTEGER LocalTime,
|
PLARGE_INTEGER SystemTime)
|
||||||
PLARGE_INTEGER SystemTime
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SystemTime->QuadPart =
|
SystemTime->QuadPart = LocalTime->QuadPart + ExpTimeZoneBias.QuadPart;
|
||||||
LocalTime->QuadPart + ExpTimeZoneBias.QuadPart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
ExSetTimerResolution (
|
ExSetTimerResolution(IN ULONG DesiredTime,
|
||||||
IN ULONG DesiredTime,
|
IN BOOLEAN SetResolution)
|
||||||
IN BOOLEAN SetResolution
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
ExSystemTimeToLocalTime (
|
ExSystemTimeToLocalTime(PLARGE_INTEGER SystemTime,
|
||||||
PLARGE_INTEGER SystemTime,
|
PLARGE_INTEGER LocalTime)
|
||||||
PLARGE_INTEGER LocalTime
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
LocalTime->QuadPart =
|
LocalTime->QuadPart = SystemTime->QuadPart - ExpTimeZoneBias.QuadPart;
|
||||||
SystemTime->QuadPart - ExpTimeZoneBias.QuadPart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue