ReactOS  r75907
time.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Kernel
4  * FILE: ntoskrnl/ex/time.c
5  * PURPOSE: Time and Timezone Management
6  * PROGRAMMERS: Eric Kohl
7  * Thomas Weidenmueller
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 #define TICKSPERMINUTE 600000000
17 
18 /* GLOBALS ******************************************************************/
19 
20 /* Note: Bias[minutes] = UTC - local time */
30 
31 /* FUNCTIONS ****************************************************************/
32 
33 /*++
34  * @name ExAcquireTimeRefreshLock
35  *
36  * The ExReleaseTimeRefreshLock routine acquires the system-wide lock used
37  * to synchronize clock interrupt frequency changes.
38  *
39  * @param Wait
40  * If TRUE, the system will block the caller thread waiting for the lock
41  * to become available. If FALSE, the routine will fail if the lock has
42  * already been acquired.
43  *
44  * @return Boolean value indicating success or failure of the lock acquisition.
45  *
46  * @remarks None.
47  *
48  *--*/
49 BOOLEAN
50 NTAPI
52 {
53  /* Block APCs */
55 
56  /* Attempt lock acquisition */
58  {
59  /* Lock was not acquired, enable APCs and fail */
61  return FALSE;
62  }
63 
64  /* Lock has been acquired */
65  return TRUE;
66 }
67 
68 /*++
69  * @name ExReleaseTimeRefreshLock
70  *
71  * The ExReleaseTimeRefreshLock routine releases the system-wide lock used
72  * to synchronize clock interrupt frequency changes.
73  *
74  * @param None.
75  *
76  * @return None.
77  *
78  * @remarks None.
79  *
80  *--*/
81 VOID
82 NTAPI
84 {
85  /* Release the lock and re-enable APCs */
88 }
89 
90 /*++
91  * @name ExSetTimerResolution
92  * @exported
93  *
94  * The KiInsertQueueApc routine modifies the frequency at which the system
95  * clock interrupts.
96  *
97  * @param DesiredTime
98  * Specifies the amount of time that should elapse between each timer
99  * interrupt, in 100-nanosecond units.
100  *
101  * This parameter is ignored if SetResolution is FALSE.
102  *
103  * @param SetResolution
104  * If TRUE, the call is a request to set the clock interrupt frequency to
105  * the value specified by DesiredTime. If FALSE, the call is a request to
106  * restore the clock interrupt frequency to the system's default value.
107  *
108  * @return New timer resolution, in 100-nanosecond ticks.
109  *
110  * @remarks (1) The clock frequency is changed only if the DesiredTime value is
111  * less than the current setting.
112  *
113  * (2) The routine just returns the current setting if the DesiredTime
114  * value is greater than what is currently set.
115  *
116  * (3) If the DesiredTime value is less than the system clock can
117  * support, the routine uses the smallest resolution the system can
118  * support, and returns that value.
119  *
120  * (4) If multiple drivers have attempted to change the clock interrupt
121  * frequency, the system will only restore the default frequency
122  * once ALL drivers have called the routine with SetResolution set
123  * to FALSE.
124  *
125  * NB. This routine synchronizes with IRP_MJ_POWER requests through the
126  * TimeRefreshLock.
127  *
128  *--*/
129 ULONG
130 NTAPI
133 {
134  ULONG CurrentIncrement;
135 
136  /* Wait for clock interrupt frequency and power requests to synchronize */
138 
139  /* Obey remark 2*/
140  CurrentIncrement = KeTimeIncrement;
141 
142  /* Check the type of operation this is */
143  if (SetResolution)
144  {
145  /*
146  * If this is the first kernel change, bump the timer resolution change
147  * count, then bump the kernel change count as well.
148  *
149  * These two variables are tracked differently since user-mode processes
150  * can also change the timer resolution through the NtSetTimerResolution
151  * system call. A per-process flag in the EPROCESS then stores the per-
152  * process change state.
153  *
154  */
156 
157  /* Obey remark 3 */
158  if (DesiredTime < KeMinimumIncrement) DesiredTime = KeMinimumIncrement;
159 
160  /* Obey remark 1 */
161  if (DesiredTime < KeTimeIncrement)
162  {
163  /* Force this thread on CPU zero, since we don't want it to drift */
165 
166  /* Now call the platform driver (HAL) to make the change */
167  CurrentIncrement = HalSetTimeIncrement(DesiredTime);
168 
169  /* Put the thread back to its original affinity */
171 
172  /* Finally, keep track of the new value in the kernel */
173  KeTimeIncrement = CurrentIncrement;
174  }
175  }
176  else
177  {
178  /* First, make sure that a driver has actually changed the resolution */
180  {
181  /* Obey remark 4 */
183  {
184  /*
185  * All kernel drivers have requested the original frequency to
186  * be restored, but there might still be user processes with an
187  * ongoing clock interrupt frequency change, so make sure that
188  * this isn't the case.
189  */
191  {
192  /* Force this thread on one CPU so that it doesn't drift */
194 
195  /* Call the HAL to restore the frequency to its default */
196  CurrentIncrement = HalSetTimeIncrement(KeMaximumIncrement);
197 
198  /* Put the thread back to its original affinity */
200 
201  /* Finally, keep track of the new value in the kernel */
202  KeTimeIncrement = CurrentIncrement;
203  }
204  }
205  }
206  }
207 
208  /* Release the clock interrupt frequency lock since changes are done */
210 
211  /* And return the current value -- which could reflect the new frequency */
212  return CurrentIncrement;
213 }
214 
215 VOID
216 NTAPI
218  IN ULONG MaxSepInSeconds)
219 {
220  /* FIXME: TODO */
221  return;
222 }
223 
224 BOOLEAN
225 NTAPI
227 {
228  LARGE_INTEGER CurrentTime;
230 
231  /* Read time zone information from the registry */
232  Status = RtlQueryTimeZoneInformation(&ExpTimeZoneInfo);
233  if (!NT_SUCCESS(Status))
234  {
235  /* Failed, clear all data */
236  RtlZeroMemory(&ExpTimeZoneInfo, sizeof(TIME_ZONE_INFORMATION));
237  ExpTimeZoneBias.QuadPart = (LONGLONG)0;
239  }
240  else
241  {
242  /* FIXME: Calculate transition dates */
243 
244  /* Set bias and ID */
245  ExpTimeZoneBias.QuadPart = ((LONGLONG)(ExpTimeZoneInfo.Bias +
246  ExpTimeZoneInfo.StandardBias)) *
249  }
250 
251  /* Change it for user-mode applications */
252  SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
253  SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
254  SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
255  SharedUserData->TimeZoneId = ExpTimeZoneId;
256 
257  /* Convert boot time from local time to UTC */
258  KeBootTime.QuadPart += ExpTimeZoneBias.QuadPart;
259 
260  /* Convert system time from local time to UTC */
261  do
262  {
263  CurrentTime.u.HighPart = SharedUserData->SystemTime.High1Time;
264  CurrentTime.u.LowPart = SharedUserData->SystemTime.LowPart;
265  } while (CurrentTime.u.HighPart != SharedUserData->SystemTime.High2Time);
266 
267  /* Change it for user-mode applications */
268  CurrentTime.QuadPart += ExpTimeZoneBias.QuadPart;
269  SharedUserData->SystemTime.LowPart = CurrentTime.u.LowPart;
270  SharedUserData->SystemTime.High1Time = CurrentTime.u.HighPart;
271  SharedUserData->SystemTime.High2Time = CurrentTime.u.HighPart;
272 
273  /* Return success */
274  return TRUE;
275 }
276 
277 NTSTATUS
279 {
280  LARGE_INTEGER LocalTime, SystemTime, OldTime;
282  DPRINT("ExpSetTimeZoneInformation() called\n");
283 
284  DPRINT("Old time zone bias: %d minutes\n", ExpTimeZoneInfo.Bias);
285  DPRINT("Old time zone standard bias: %d minutes\n",
286  ExpTimeZoneInfo.StandardBias);
287  DPRINT("New time zone bias: %d minutes\n", TimeZoneInformation->Bias);
288  DPRINT("New time zone standard bias: %d minutes\n",
289  TimeZoneInformation->StandardBias);
290 
291  /* Get the local time */
292  HalQueryRealTimeClock(&TimeFields);
293  RtlTimeFieldsToTime(&TimeFields, &LocalTime);
294 
295  /* FIXME: Calculate transition dates */
296 
297  /* Calculate the bias and set the ID */
298  ExpTimeZoneBias.QuadPart = ((LONGLONG)(TimeZoneInformation->Bias +
299  TimeZoneInformation->StandardBias)) *
302 
303  /* Copy the timezone information */
304  RtlCopyMemory(&ExpTimeZoneInfo,
305  TimeZoneInformation,
306  sizeof(TIME_ZONE_INFORMATION));
307 
308  /* Set the new time zone information */
309  SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
310  SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
311  SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
312  SharedUserData->TimeZoneId = ExpTimeZoneId;
313 
314  DPRINT("New time zone bias: %I64d minutes\n",
315  ExpTimeZoneBias.QuadPart / TICKSPERMINUTE);
316 
317  /* Calculate the new system time */
318  ExLocalTimeToSystemTime(&LocalTime, &SystemTime);
319 
320  /* Set the new system time */
321  KeSetSystemTime(&SystemTime, &OldTime, FALSE, NULL);
322 
323  /* Return success */
324  DPRINT("ExpSetTimeZoneInformation() done\n");
325  return STATUS_SUCCESS;
326 }
327 
328 /*
329  * FUNCTION: Sets the system time.
330  * PARAMETERS:
331  * NewTime - Points to a variable that specified the new time
332  * of day in the standard time format.
333  * OldTime - Optionally points to a variable that receives the
334  * old time of day in the standard time format.
335  * RETURNS: Status
336  */
337 NTSTATUS
338 NTAPI
340  OUT PLARGE_INTEGER PreviousTime OPTIONAL)
341 {
342  LARGE_INTEGER OldSystemTime;
343  LARGE_INTEGER NewSystemTime;
344  LARGE_INTEGER LocalTime;
348  PAGED_CODE();
349 
350  /* Check if we were called from user-mode */
351  if (PreviousMode != KernelMode)
352  {
353  _SEH2_TRY
354  {
355  /* Verify the time pointers */
356  NewSystemTime = ProbeForReadLargeInteger(SystemTime);
357  if(PreviousTime) ProbeForWriteLargeInteger(PreviousTime);
358  }
360  {
361  /* Return the exception code */
363  }
364  _SEH2_END;
365  }
366  else
367  {
368  /* Reuse the pointer */
369  NewSystemTime = *SystemTime;
370  }
371 
372  /* Make sure we have permission to change the time */
373  if (!SeSinglePrivilegeCheck(SeSystemtimePrivilege, PreviousMode))
374  {
375  DPRINT1("NtSetSystemTime: Caller requires the "
376  "SeSystemtimePrivilege privilege!\n");
378  }
379 
380  /* Convert the time and set it in HAL */
381  ExSystemTimeToLocalTime(&NewSystemTime, &LocalTime);
382  RtlTimeToTimeFields(&LocalTime, &TimeFields);
383  HalSetRealTimeClock(&TimeFields);
384 
385  /* Now set system time */
386  KeSetSystemTime(&NewSystemTime, &OldSystemTime, FALSE, NULL);
387 
388  /* Check if caller wanted previous time */
389  if (PreviousTime)
390  {
391  /* Enter SEH Block for return */
392  _SEH2_TRY
393  {
394  /* Return the previous time */
395  *PreviousTime = OldSystemTime;
396  }
398  {
399  /* Get the exception code */
400  Status = _SEH2_GetExceptionCode();
401  }
402  _SEH2_END;
403  }
404 
405  /* Return status */
406  return Status;
407 }
408 
409 /*
410  * FUNCTION: Retrieves the system time.
411  * PARAMETERS:
412  * CurrentTime - Points to a variable that receives the current
413  * time of day in the standard time format.
414  */
415 NTSTATUS
416 NTAPI
418 {
420  PAGED_CODE();
421 
422  /* Check if we were called from user-mode */
423  if (PreviousMode != KernelMode)
424  {
425  _SEH2_TRY
426  {
427  /* Verify the time pointer */
428  ProbeForWriteLargeInteger(SystemTime);
429 
430  /*
431  * It's safe to pass the pointer directly to KeQuerySystemTime
432  * as it's just a basic copy to this pointer. If it raises an
433  * exception nothing dangerous can happen!
434  */
435  KeQuerySystemTime(SystemTime);
436  }
438  {
439  /* Return the exception code */
441  }
442  _SEH2_END;
443  }
444  else
445  {
446  /* Query the time directly */
447  KeQuerySystemTime(SystemTime);
448  }
449 
450  /* Return success */
451  return STATUS_SUCCESS;
452 }
453 
454 /*
455  * @implemented
456  */
457 VOID
458 NTAPI
460  PLARGE_INTEGER SystemTime)
461 {
462  SystemTime->QuadPart = LocalTime->QuadPart + ExpTimeZoneBias.QuadPart;
463 }
464 
465 /*
466  * @implemented
467  */
468 VOID
469 NTAPI
471  PLARGE_INTEGER LocalTime)
472 {
473  LocalTime->QuadPart = SystemTime->QuadPart - ExpTimeZoneBias.QuadPart;
474 }
475 
476 /*
477  * @implemented
478  */
479 NTSTATUS
480 NTAPI
482  OUT PULONG MaximumResolution,
483  OUT PULONG ActualResolution)
484 {
486 
487  /* Check if the call came from user-mode */
488  if (PreviousMode != KernelMode)
489  {
490  _SEH2_TRY
491  {
492  /* Probe the parameters */
493  ProbeForWriteUlong(MinimumResolution);
494  ProbeForWriteUlong(MaximumResolution);
495  ProbeForWriteUlong(ActualResolution);
496 
497  /*
498  * Set the parameters to the actual values.
499  *
500  * NOTE:
501  * MinimumResolution corresponds to the biggest time increment and
502  * MaximumResolution corresponds to the smallest time increment.
503  */
504  *MinimumResolution = KeMaximumIncrement;
505  *MaximumResolution = KeMinimumIncrement;
506  *ActualResolution = KeTimeIncrement;
507  }
509  {
510  /* Return the exception code */
512  }
513  _SEH2_END;
514  }
515  else
516  {
517  /* Set the parameters to the actual values */
518  *MinimumResolution = KeMaximumIncrement;
519  *MaximumResolution = KeMinimumIncrement;
520  *ActualResolution = KeTimeIncrement;
521  }
522 
523  /* Return success */
524  return STATUS_SUCCESS;
525 }
526 
527 /*
528  * @implemented
529  */
530 NTSTATUS
531 NTAPI
532 NtSetTimerResolution(IN ULONG DesiredResolution,
534  OUT PULONG CurrentResolution)
535 {
539  ULONG NewResolution;
540 
541  /* Check if the call came from user-mode */
542  if (PreviousMode != KernelMode)
543  {
544  _SEH2_TRY
545  {
546  /* Probe the parameter */
547  ProbeForWriteUlong(CurrentResolution);
548  }
550  {
551  /* Return the exception code */
553  }
554  _SEH2_END;
555  }
556 
557  /* Set and return the new resolution */
558  NewResolution = ExSetTimerResolution(DesiredResolution, SetResolution);
559 
560  if (PreviousMode != KernelMode)
561  {
562  _SEH2_TRY
563  {
564  *CurrentResolution = NewResolution;
565  }
567  {
568  /* Return the exception code */
570  }
571  _SEH2_END;
572  }
573  else
574  {
575  *CurrentResolution = NewResolution;
576  }
577 
578  if (SetResolution || Process->SetTimerResolution)
579  {
580  /* The resolution has been changed now or in an earlier call */
581  Status = STATUS_SUCCESS;
582  }
583  else
584  {
585  /* The resolution hasn't been changed */
587  }
588 
589  /* Update the flag */
591 
592  return Status;
593 }
594 
595 /* EOF */
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
ULONG KeMaximumIncrement
Definition: clock.c:20
#define IN
Definition: typedefs.h:39
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
VOID NTAPI ExReleaseTimeRefreshLock(VOID)
Definition: time.c:83
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
const LUID SeSystemtimePrivilege
Definition: priv.c:33
ULONG KeMinimumIncrement
Definition: clock.c:21
VOID NTAPI RtlTimeToTimeFields(IN PLARGE_INTEGER Time, OUT PTIME_FIELDS TimeFields)
Definition: time.c:253
BOOLEAN NTAPI HalQueryRealTimeClock(IN PTIME_FIELDS Time)
Definition: rtc.c:24
#define TIME_ZONE_ID_UNKNOWN
Definition: rtltypes.h:250
return STATUS_SUCCESS
Definition: btrfs.c:2664
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
ULONG ExpTimerResolutionCount
Definition: time.c:29
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2740
struct _LARGE_INTEGER::@2052 u
ULONG ExpKernelResolutionCount
Definition: time.c:28
ULONG NTAPI ExSetTimerResolution(IN ULONG DesiredTime, IN BOOLEAN SetResolution)
Definition: time.c:131
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
NTSTATUS NTAPI NtQueryTimerResolution(OUT PULONG MinimumResolution, OUT PULONG MaximumResolution, OUT PULONG ActualResolution)
Definition: time.c:481
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
LARGE_INTEGER KeBootTime
Definition: clock.c:17
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
NTSTATUS ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
Definition: time.c:278
LARGE_INTEGER ExpTimeZoneBias
Definition: time.c:23
#define _SEH2_END
Definition: pseh2_64.h:7
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:513
void DPRINT(...)
Definition: polytest.cpp:61
ULONG ExpTimeZoneId
Definition: time.c:25
NTSTATUS NTAPI NtSetSystemTime(IN PLARGE_INTEGER SystemTime, OUT PLARGE_INTEGER PreviousTime OPTIONAL)
Definition: time.c:339
int64_t LONGLONG
Definition: typedefs.h:67
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TIME_ZONE_ID_STANDARD
Definition: rtltypes.h:251
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
BOOLEAN NTAPI ExAcquireTimeRefreshLock(IN BOOLEAN Wait)
Definition: time.c:51
#define PAGED_CODE()
Definition: video.h:57
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define SharedUserData
ULONG SetTimerResolution
Definition: pstypes.h:1336
ULONG KeTimeIncrement
Definition: clock.c:22
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
VOID NTAPI ExUpdateSystemTimeFromCmos(IN BOOLEAN UpdateInterruptTime, IN ULONG MaxSepInSeconds)
Definition: time.c:217
Status
Definition: gdiplustypes.h:24
ULONG ExpLastTimeZoneBias
Definition: time.c:22
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
_In_ BOOLEAN SetResolution
Definition: exfuncs.h:870
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:325
#define _SEH2_TRY
Definition: pseh2_64.h:5
BOOLEAN NTAPI ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime)
Definition: time.c:226
unsigned int * PULONG
Definition: retypes.h:1
BOOLEAN NTAPI RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, OUT PLARGE_INTEGER Time)
Definition: time.c:170
_In_ BOOLEAN Wait
Definition: cctypes.h:23
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSTATUS NTAPI NtSetTimerResolution(IN ULONG DesiredResolution, IN BOOLEAN SetResolution, OUT PULONG CurrentResolution)
Definition: time.c:532
TIME_ZONE_INFORMATION ExpTimeZoneInfo
Definition: time.c:21
#define OUT
Definition: typedefs.h:40
ULONG ExpTickCountMultiplier
Definition: time.c:26
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
ERESOURCE ExpTimeRefreshLock
Definition: time.c:27
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI KeSetSystemTime(IN PLARGE_INTEGER NewSystemTime, OUT PLARGE_INTEGER OldSystemTime, IN BOOLEAN FixInterruptTime, IN PLARGE_INTEGER HalTime)
Definition: clock.c:28
#define STATUS_TIMER_RESOLUTION_NOT_SET
Definition: ntstatus.h:699
ULONG ExpAltTimeZoneBias
Definition: time.c:24
static PTIME_FIELDS TimeFields
Definition: time.c:27
#define TICKSPERMINUTE
Definition: time.c:16
VOID NTAPI ExLocalTimeToSystemTime(PLARGE_INTEGER LocalTime, PLARGE_INTEGER SystemTime)
Definition: time.c:459
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
ULONG NTAPI HalSetTimeIncrement(IN ULONG Increment)
Definition: timer.c:102
#define ProbeForWriteLargeInteger(Ptr)
Definition: probe.h:46
VOID NTAPI ExSystemTimeToLocalTime(PLARGE_INTEGER SystemTime, PLARGE_INTEGER LocalTime)
Definition: time.c:470
BOOLEAN NTAPI HalSetRealTimeClock(IN PTIME_FIELDS Time)
Definition: rtc.c:45
NTSYSAPI NTSTATUS NTAPI RtlQueryTimeZoneInformation(_Out_ PRTL_TIME_ZONE_INFORMATION TimeZoneInformation)
LONGLONG QuadPart
Definition: typedefs.h:113