[TIMEDATE] Separate time sync functions out into their own file. CORE-13001

This is in preparation for the w32time service, and based on
work by Doug Lyons.
This commit is contained in:
Thomas Faber 2018-06-03 12:33:24 +02:00
parent fcd00d412e
commit aa24ad7429
No known key found for this signature in database
GPG Key ID: 076E7C3D44720826
5 changed files with 222 additions and 156 deletions

View File

@ -9,6 +9,7 @@ list(APPEND SOURCE
ntpclient.c
timedate.c
timezone.c
w32time.c
timedate.h)
file(GLOB timedate_rc_deps resources/*.*)

View File

@ -14,8 +14,7 @@
static WNDPROC pOldWndProc = NULL;
BOOL
SystemSetTime(LPSYSTEMTIME lpSystemTime,
BOOL SystemTime)
SystemSetLocalTime(LPSYSTEMTIME lpSystemTime)
{
HANDLE hToken;
DWORD PrevSize;
@ -47,19 +46,10 @@ SystemSetTime(LPSYSTEMTIME lpSystemTime,
{
/*
* We successfully enabled it, we're permitted to change the time.
* Check the second parameter for SystemTime and if TRUE set System Time.
* Otherwise, if FALSE set the Local Time.
* Call SetLocalTime twice to ensure correct results.
*/
if (SystemTime)
{
Ret = SetSystemTime(lpSystemTime);
}
else
{
Ret = SetLocalTime(lpSystemTime) &&
SetLocalTime(lpSystemTime);
}
Ret = SetLocalTime(lpSystemTime) &&
SetLocalTime(lpSystemTime);
/*
* For the sake of security, restore the previous status again
@ -96,8 +86,7 @@ SetLocalSystemTime(HWND hwnd)
(WPARAM)&Time,
0))
{
/* Set Local Time with SystemTime = FALSE */
SystemSetTime(&Time, FALSE);
SystemSetLocalTime(&Time);
SetWindowLongPtrW(hwnd,
DWLP_MSGRESULT,

View File

@ -130,140 +130,6 @@ SetNTPServer(HWND hwnd)
}
/* Get the domain name from the registry */
static BOOL
GetNTPServerAddress(LPWSTR *lpAddress)
{
HKEY hKey;
WCHAR szSel[4];
DWORD dwSize;
LONG lRet;
lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
0,
KEY_QUERY_VALUE,
&hKey);
if (lRet != ERROR_SUCCESS)
goto fail;
/* Get data from default value */
dwSize = 4 * sizeof(WCHAR);
lRet = RegQueryValueExW(hKey,
NULL,
NULL,
NULL,
(LPBYTE)szSel,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
dwSize = 0;
lRet = RegQueryValueExW(hKey,
szSel,
NULL,
NULL,
NULL,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
(*lpAddress) = (LPWSTR)HeapAlloc(GetProcessHeap(),
0,
dwSize);
if ((*lpAddress) == NULL)
{
lRet = ERROR_NOT_ENOUGH_MEMORY;
goto fail;
}
lRet = RegQueryValueExW(hKey,
szSel,
NULL,
NULL,
(LPBYTE)*lpAddress,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
RegCloseKey(hKey);
return TRUE;
fail:
DisplayWin32Error(lRet);
if (hKey)
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, *lpAddress);
return FALSE;
}
/* Request the time from the current NTP server */
static ULONG
GetTimeFromServer(VOID)
{
LPWSTR lpAddress = NULL;
ULONG ulTime = 0;
if (GetNTPServerAddress(&lpAddress))
{
ulTime = GetServerTime(lpAddress);
HeapFree(GetProcessHeap(),
0,
lpAddress);
}
return ulTime;
}
/*
* NTP servers state the number of seconds passed since
* 1st Jan, 1900. The time returned from the server
* needs adding to that date to get the current Gregorian time
*/
static VOID
UpdateSystemTime(ULONG ulTime)
{
FILETIME ftNew;
LARGE_INTEGER li;
SYSTEMTIME stNew;
/* Time at 1st Jan 1900 */
stNew.wYear = 1900;
stNew.wMonth = 1;
stNew.wDay = 1;
stNew.wHour = 0;
stNew.wMinute = 0;
stNew.wSecond = 0;
stNew.wMilliseconds = 0;
/* Convert to a file time */
if (!SystemTimeToFileTime(&stNew, &ftNew))
{
DisplayWin32Error(GetLastError());
return;
}
/* Add on the time passed since 1st Jan 1900 */
li = *(LARGE_INTEGER *)&ftNew;
li.QuadPart += (LONGLONG)10000000 * ulTime;
ftNew = * (FILETIME *)&li;
/* Convert back to a system time */
if (!FileTimeToSystemTime(&ftNew, &stNew))
{
DisplayWin32Error(GetLastError());
return;
}
/* Use SystemSetTime with SystemTime = TRUE to set System Time */
if (!SystemSetTime(&stNew, TRUE))
DisplayWin32Error(GetLastError());
}
static VOID
EnableDialogText(HWND hwnd)
{
@ -338,13 +204,8 @@ InetTimePageProc(HWND hwndDlg,
{
case IDC_UPDATEBUTTON:
{
ULONG ulTime;
SetNTPServer(hwndDlg);
ulTime = GetTimeFromServer();
if (ulTime != 0)
UpdateSystemTime(ulTime);
SyncTimeNow();
}
break;

View File

@ -39,7 +39,7 @@ extern HINSTANCE hApplet;
/* dateandtime.c */
INT_PTR CALLBACK DateTimePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL SystemSetTime(LPSYSTEMTIME lpSystemTime, BOOL SystemTime);
BOOL SystemSetLocalTime(LPSYSTEMTIME lpSystemTime);
/* timezone.c */
@ -94,6 +94,10 @@ typedef struct _NTPPACKET
ULONG GetServerTime(LPWSTR lpAddress);
/* w32time.c */
VOID SyncTimeNow(VOID);
/* monthcal.c */
#define MCCM_SETDATE (WM_USER + 1)
#define MCCM_GETDATE (WM_USER + 2)

211
dll/cpl/timedate/w32time.c Normal file
View File

@ -0,0 +1,211 @@
/*
* PROJECT: ReactOS Timedate Control Panel
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Create W32Time Service that reqularly syncs clock to Internet Time
* COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
*/
#include "timedate.h"
/* Get the domain name from the registry */
static BOOL
GetNTPServerAddress(LPWSTR *lpAddress)
{
HKEY hKey;
WCHAR szSel[4];
DWORD dwSize;
LONG lRet;
lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
0,
KEY_QUERY_VALUE,
&hKey);
if (lRet != ERROR_SUCCESS)
goto fail;
/* Get data from default value */
dwSize = 4 * sizeof(WCHAR);
lRet = RegQueryValueExW(hKey,
NULL,
NULL,
NULL,
(LPBYTE)szSel,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
dwSize = 0;
lRet = RegQueryValueExW(hKey,
szSel,
NULL,
NULL,
NULL,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
(*lpAddress) = (LPWSTR)HeapAlloc(GetProcessHeap(),
0,
dwSize);
if ((*lpAddress) == NULL)
{
lRet = ERROR_NOT_ENOUGH_MEMORY;
goto fail;
}
lRet = RegQueryValueExW(hKey,
szSel,
NULL,
NULL,
(LPBYTE)*lpAddress,
&dwSize);
if (lRet != ERROR_SUCCESS)
goto fail;
RegCloseKey(hKey);
return TRUE;
fail:
DisplayWin32Error(lRet);
if (hKey)
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, *lpAddress);
return FALSE;
}
/* Request the time from the current NTP server */
static ULONG
GetTimeFromServer(VOID)
{
LPWSTR lpAddress = NULL;
ULONG ulTime = 0;
if (GetNTPServerAddress(&lpAddress))
{
ulTime = GetServerTime(lpAddress);
HeapFree(GetProcessHeap(),
0,
lpAddress);
}
return ulTime;
}
BOOL
SystemSetTime(LPSYSTEMTIME lpSystemTime)
{
HANDLE hToken;
DWORD PrevSize;
TOKEN_PRIVILEGES priv, previouspriv;
BOOL Ret = FALSE;
/*
* Enable the SeSystemtimePrivilege privilege
*/
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
priv.PrivilegeCount = 1;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValueW(NULL,
SE_SYSTEMTIME_NAME,
&priv.Privileges[0].Luid))
{
if (AdjustTokenPrivileges(hToken,
FALSE,
&priv,
sizeof(previouspriv),
&previouspriv,
&PrevSize) &&
GetLastError() == ERROR_SUCCESS)
{
/*
* We successfully enabled it, we're permitted to change the time.
*/
Ret = SetSystemTime(lpSystemTime);
/*
* For the sake of security, restore the previous status again
*/
if (previouspriv.PrivilegeCount > 0)
{
AdjustTokenPrivileges(hToken,
FALSE,
&previouspriv,
0,
NULL,
0);
}
}
}
CloseHandle(hToken);
}
return Ret;
}
/*
* NTP servers state the number of seconds passed since
* 1st Jan, 1900. The time returned from the server
* needs adding to that date to get the current Gregorian time
*/
static VOID
UpdateSystemTime(ULONG ulTime)
{
FILETIME ftNew;
LARGE_INTEGER li;
SYSTEMTIME stNew;
/* Time at 1st Jan 1900 */
stNew.wYear = 1900;
stNew.wMonth = 1;
stNew.wDay = 1;
stNew.wHour = 0;
stNew.wMinute = 0;
stNew.wSecond = 0;
stNew.wMilliseconds = 0;
/* Convert to a file time */
if (!SystemTimeToFileTime(&stNew, &ftNew))
{
DisplayWin32Error(GetLastError());
return;
}
/* Add on the time passed since 1st Jan 1900 */
li = *(LARGE_INTEGER *)&ftNew;
li.QuadPart += (LONGLONG)10000000 * ulTime;
ftNew = * (FILETIME *)&li;
/* Convert back to a system time */
if (!FileTimeToSystemTime(&ftNew, &stNew))
{
DisplayWin32Error(GetLastError());
return;
}
if (!SystemSetTime(&stNew))
{
DisplayWin32Error(GetLastError());
}
}
VOID
SyncTimeNow(VOID)
{
ULONG ulTime;
ulTime = GetTimeFromServer();
if (ulTime != 0)
UpdateSystemTime(ulTime);
}