mirror of
https://github.com/reactos/reactos.git
synced 2024-11-24 03:53:31 +08:00
[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:
parent
fcd00d412e
commit
aa24ad7429
@ -9,6 +9,7 @@ list(APPEND SOURCE
|
||||
ntpclient.c
|
||||
timedate.c
|
||||
timezone.c
|
||||
w32time.c
|
||||
timedate.h)
|
||||
|
||||
file(GLOB timedate_rc_deps resources/*.*)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
211
dll/cpl/timedate/w32time.c
Normal 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user