ReactOS  0.4.15-dev-1171-gab82533
internettime.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Timedate Control Panel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/cpl/timedate/internettime.c
5  * PURPOSE: Internet Time property page
6  * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
7  *
8  */
9 
10 #include "timedate.h"
11 #include <stdlib.h>
12 
15 
16 static VOID
18 {
19  HWND hList;
20  WCHAR szValName[MAX_VALUE_NAME];
21  WCHAR szData[256];
22  DWORD dwIndex = 0;
23  DWORD dwValSize;
24  DWORD dwNameSize;
25  DWORD dwDefault = 1;
26  LONG lRet;
27  HKEY hKey;
28 
31 
33  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
34  0,
36  &hKey);
37  if (lRet != ERROR_SUCCESS)
38  return;
39 
40  while (TRUE)
41  {
42  dwValSize = MAX_VALUE_NAME * sizeof(WCHAR);
43  szValName[0] = L'\0';
44  lRet = RegEnumValueW(hKey,
45  dwIndex,
46  szValName,
47  &dwValSize,
48  NULL,
49  NULL,
50  (LPBYTE)szData,
51  &dwNameSize);
52  if (lRet == ERROR_SUCCESS)
53  {
54  /* Get date from default reg value */
55  if (wcscmp(szValName, L"") == 0) // if (Index == 0)
56  {
57  dwDefault = _wtoi(szData);
58  dwIndex++;
59  }
60  else
61  {
64  0,
65  (LPARAM)szData);
66  dwIndex++;
67  }
68  }
69  else if (lRet != ERROR_MORE_DATA)
70  {
71  break;
72  }
73  }
74 
75  if (dwDefault < 1 || dwDefault > dwIndex)
76  dwDefault = 1;
77 
78  /* Server reg entries count from 1,
79  * Combo boxes count from 0 */
80  dwDefault--;
81 
84  dwDefault,
85  0);
86 
87  RegCloseKey(hKey);
88 }
89 
90 
91 /* Set the selected server in the registry */
92 static VOID
93 SetNTPServer(HWND hwnd, BOOL bBeginUpdate)
94 {
95  HKEY hKey;
96  HWND hList;
97  UINT uSel;
98  WCHAR szSel[4];
99  LONG lRet;
100  WCHAR buffer[256];
101  WCHAR szFormat[BUFSIZE];
102 
105 
106  uSel = (UINT)SendMessageW(hList, CB_GETCURSEL, 0, 0);
107 
109 
110  /* If the condition is true that means the user wants to update (synchronize) the time */
111  if (bBeginUpdate)
112  {
113  /* Inform the user that the synchronization is about to begin (depending on how reachable the NTP server is) */
114  StringCchPrintfW(szFormat, _countof(szFormat), SyncStatus.szSyncWait, buffer);
115  SetDlgItemTextW(hwnd, IDC_SUCSYNC, szFormat);
116  }
117 
118  /* If there is new data entered then save it in the registry
119  The same key name of "0" is used to store all user entered values
120  */
121  if (uSel == -1)
122  {
124  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
125  0,
127  &hKey);
128  if (lRet != ERROR_SUCCESS)
129  {
130  DisplayWin32Error(lRet);
131  return;
132  }
133  lRet = RegSetValueExW(hKey,
134  L"0",
135  0,
136  REG_SZ,
137  (LPBYTE)buffer,
138  (wcslen(buffer) + 1) * sizeof(WCHAR));
139  if (lRet != ERROR_SUCCESS)
140  DisplayWin32Error(lRet);
141  }
142 
143  /* Server reg entries count from 1,
144  * Combo boxes count from 0 */
145  uSel++;
146 
147  /* Convert to wide char */
148  _itow(uSel, szSel, 10);
149 
151  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
152  0,
154  &hKey);
155  if (lRet != ERROR_SUCCESS)
156  {
157  DisplayWin32Error(lRet);
158  return;
159  }
160 
161  lRet = RegSetValueExW(hKey,
162  L"",
163  0,
164  REG_SZ,
165  (LPBYTE)szSel,
166  (wcslen(szSel) + 1) * sizeof(WCHAR));
167  if (lRet != ERROR_SUCCESS)
168  DisplayWin32Error(lRet);
169 
170  RegCloseKey(hKey);
171 }
172 
173 
174 static VOID
176 {
177  BOOL bChecked;
178  UINT uCheck;
179 
181  bChecked = (uCheck == BST_CHECKED) ? TRUE : FALSE;
182 
188 }
189 
190 static VOID
192 {
193  /* Initialize the Synchronization NTP status members */
199 
200  /*
201  * TODO: XP's and Server 2003's timedate.cpl loads the last successful attempt of the NTP synchronization
202  * displaying the last time and date of the said sync. I have no idea how does timedate.cpl remember its last
203  * successful sync so for the time being, we will only load the initial remark string.
204  */
206 }
207 
208 static VOID
210 {
211  WCHAR szFormat[BUFSIZE];
212  WCHAR szNtpServerName[MAX_VALUE_NAME];
213  WCHAR szLocalDate[BUFSIZE];
214  WCHAR szLocalTime[BUFSIZE];
215  HWND hDlgComboList;
216 
217  /* Retrieve the server NTP name from the edit box */
218  hDlgComboList = GetDlgItem(hwnd, IDC_SERVERLIST);
219  SendMessageW(hDlgComboList, WM_GETTEXT, _countof(szNtpServerName), (LPARAM)szNtpServerName);
220 
221  /* Iterate over the case reasons so we can compute the exact status of the NTP synchronization */
222  switch (dwReason)
223  {
224  /* The NTP time synchronization has completed successfully */
225  case ERROR_SUCCESS:
226  {
227  /* Get the current date based on the locale identifier */
230  NULL,
231  NULL,
232  szLocalDate,
233  _countof(szLocalDate));
234 
235  /* Get the current time based on the locale identifier */
238  NULL,
239  NULL,
240  szLocalTime,
241  _countof(szLocalTime));
242 
243  /* Format the resource sting with the given NTP server name and the current time data */
244  StringCchPrintfW(szFormat, _countof(szFormat), SyncStatus.szSyncSuc, szNtpServerName, szLocalDate, szLocalTime);
245  SetDlgItemTextW(hwnd, IDC_SUCSYNC, szFormat);
246  break;
247  }
248 
249  /* Empty field data has been caught -- simply tell the user to write the NTP name to continue */
250  case ERROR_INVALID_DATA:
251  {
253  DPRINT("UpdateNTPStatus(): The user didn't submit any NTP server name!\n");
254  break;
255  }
256 
257  /* General failure -- the NTP synchronization has failed for whatever reason */
258  default:
259  {
260  StringCchPrintfW(szFormat, _countof(szFormat), SyncStatus.szSyncErr, szNtpServerName);
261  SetDlgItemTextW(hwnd, IDC_SUCSYNC, szFormat);
262  DPRINT("UpdateNTPStatus(): Failed to synchronize the time! (Error: %lu).\n", dwReason);
263  break;
264  }
265  }
266 }
267 
268 static VOID
270 {
271  HKEY hKey;
272  WCHAR szData[8];
273  DWORD dwSize;
274 
276  L"SYSTEM\\CurrentControlSet\\Services\\W32Time\\Parameters",
277  0,
279  &hKey) == ERROR_SUCCESS)
280  {
281  dwSize = 8 * sizeof(WCHAR);
282  if (RegQueryValueExW(hKey,
283  L"Type",
284  NULL,
285  NULL,
286  (LPBYTE)szData,
287  &dwSize) == ERROR_SUCCESS)
288  {
289  if (wcscmp(szData, L"NTP") == 0)
291  else
293  }
294 
295  RegCloseKey(hKey);
296  }
297 }
298 
299 
300 static VOID
302 {
308 }
309 
310 static VOID
312 {
313  HKEY hKey;
314  LONG lRet;
315  LPCWSTR szAuto;
316 
317  if (Sync)
318  szAuto = L"NTP";
319  else
320  szAuto = L"NoSync";
321 
323  L"SYSTEM\\CurrentControlSet\\Services\\W32Time\\Parameters",
324  0,
326  &hKey);
327  if (lRet != ERROR_SUCCESS)
328  {
329  DisplayWin32Error(lRet);
330  return;
331  }
332 
333  lRet = RegSetValueExW(hKey,
334  L"Type",
335  0,
336  REG_SZ,
337  (LPBYTE)szAuto,
338  (wcslen(szAuto) + 1) * sizeof(WCHAR));
339  if (lRet != ERROR_SUCCESS)
340  DisplayWin32Error(lRet);
341 
342  RegCloseKey(hKey);
343 }
344 
345 static DWORD WINAPI
348 {
349  HWND hwndDlg;
350  DWORD dwError;
351 
352  hwndDlg = (HWND)lpParameter;
353 
354  SetNTPServer(hwndDlg, TRUE);
355 
356  dwError = W32TimeSyncNow(L"localhost", 0, 0);
357  UpdateNTPStatus(hwndDlg, dwError);
358 
360  return 0;
361 }
362 
363 static VOID
365  HWND hwndDlg)
366 {
367  if ((BOOL)GetWindowLongPtr(hwndDlg, DWLP_USER) == FALSE)
368  {
370 
371  if (CreateThread(NULL, 0, UpdateThread, (PVOID)hwndDlg, 0, NULL) == NULL)
372  {
373  UpdateNTPStatus(hwndDlg, GetLastError());
375  }
376  }
377 }
378 
379 /* Property page dialog callback */
382  UINT uMsg,
383  WPARAM wParam,
384  LPARAM lParam)
385 {
386  switch (uMsg)
387  {
388  case WM_INITDIALOG:
389  OnInitDialog(hwndDlg);
390  break;
391 
392  case WM_COMMAND:
393  switch(LOWORD(wParam))
394  {
395  case IDC_UPDATEBUTTON:
396  OnUpdate(hwndDlg);
397  break;
398 
399  case IDC_SERVERLIST:
401  {
402  /* Enable the 'Apply' button */
403  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
404  }
405  break;
406 
407  case IDC_AUTOSYNC:
408  if (HIWORD(wParam) == BN_CLICKED)
409  {
410  EnableDialogText(hwndDlg);
411 
412  /* Enable the 'Apply' button */
413  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
414  }
415  break;
416  }
417  break;
418 
419  case WM_DESTROY:
420  break;
421 
422  case WM_NOTIFY:
423  {
424  LPNMHDR lpnm = (LPNMHDR)lParam;
425 
426  switch (lpnm->code)
427  {
428  case PSN_APPLY:
429  SetNTPServer(hwndDlg, FALSE);
430 
432  OnAutoSync(TRUE);
433  else
434  OnAutoSync(FALSE);
435 
436  return TRUE;
437 
438  default:
439  break;
440  }
441  }
442  break;
443  }
444 
445  return FALSE;
446 }
DWORD WINAPI W32TimeSyncNow(LPCWSTR cmdline, UINT blocking, UINT flags)
Definition: w32time.c:345
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static VOID OnUpdate(HWND hwndDlg)
Definition: internettime.c:364
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define IDC_AUTOSYNC
Definition: resource.h:24
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define IDC_NEXTSYNC
Definition: resource.h:26
#define TRUE
Definition: types.h:120
#define IDS_INETTIMESUCSYNC
Definition: resource.h:35
#define LOCALE_USER_DEFAULT
#define DATE_SHORTDATE
Definition: winnls.h:193
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
#define IDS_INETTIMEWELCOME
Definition: resource.h:40
#define WM_GETTEXT
Definition: winuser.h:1600
static const WCHAR szData[]
Definition: msipriv.h:1195
#define CALLBACK
Definition: compat.h:35
#define IDS_INETTIMEERROR
Definition: resource.h:38
HANDLE HWND
Definition: compat.h:19
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
GLuint buffer
Definition: glext.h:5915
HINSTANCE hApplet
Definition: access.c:17
#define IDC_SUCSYNC
Definition: resource.h:25
UINT_PTR WPARAM
Definition: windef.h:207
_CRTIMP wchar_t *__cdecl _itow(_In_ int _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
TCHAR * cmdline
Definition: stretchblt.cpp:32
WCHAR szSyncErr[BUFSIZE]
Definition: timedate.h:42
#define PSN_APPLY
Definition: prsht.h:117
int32_t INT_PTR
Definition: typedefs.h:64
#define IDS_INETTIMESUCFILL
Definition: resource.h:39
#define IDC_SERVERTEXT
Definition: resource.h:27
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define SetWindowLongPtr
Definition: treelist.c:70
#define CB_GETCURSEL
Definition: winuser.h:1925
WPARAM wParam
Definition: combotst.c:138
struct tagNMHDR * LPNMHDR
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
UINT code
Definition: winuser.h:3134
VOID DisplayWin32Error(DWORD dwErrorCode)
Definition: timedate.c:28
DWORD dwReason
Definition: misc.cpp:154
static VOID EnableDialogText(HWND hwnd)
Definition: internettime.c:175
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
static VOID CreateNTPServerList(HWND hwnd)
Definition: internettime.c:17
static VOID SyncNTPStatusInit(HWND hwnd)
Definition: internettime.c:191
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define IDS_INETTIMESYNCING
Definition: resource.h:37
INT_PTR CALLBACK InetTimePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: internettime.c:381
#define CB_ADDSTRING
Definition: winuser.h:1918
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
smooth NULL
Definition: ftsmooth.c:416
#define MAX_VALUE_NAME
Definition: control.c:23
LONG_PTR LPARAM
Definition: windef.h:208
void DPRINT(...)
Definition: polytest.cpp:61
#define BM_GETCHECK
Definition: winuser.h:1900
static VOID SetNTPServer(HWND hwnd, BOOL bBeginUpdate)
Definition: internettime.c:93
#define WM_DESTROY
Definition: winuser.h:1591
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
#define BM_SETCHECK
Definition: winuser.h:1903
#define CBN_EDITCHANGE
Definition: winuser.h:1957
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
SYNC_STATUS SyncStatus
Definition: internettime.c:14
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define PropSheet_Changed(d, w)
Definition: prsht.h:344
#define IDC_UPDATEBUTTON
Definition: resource.h:23
#define _countof(array)
Definition: sndvol32.h:68
WCHAR szSyncSuc[BUFSIZE]
Definition: timedate.h:40
#define WINAPI
Definition: msvc.h:6
#define BN_CLICKED
Definition: winuser.h:1907
unsigned long DWORD
Definition: ntddk_ex.h:95
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
GLbitfield flags
Definition: glext.h:7161
static const WCHAR L[]
Definition: oid.c:1250
#define DWLP_USER
Definition: winuser.h:866
LPVOID lpParameter
Definition: kernel32.h:241
#define IDC_SERVERLIST
Definition: resource.h:22
#define CB_SETCURSEL
Definition: winuser.h:1943
#define WM_COMMAND
Definition: winuser.h:1722
WCHAR szSyncType[BUFSIZE]
Definition: timedate.h:43
#define BST_UNCHECKED
Definition: winuser.h:199
#define ERROR_MORE_DATA
Definition: dderror.h:13
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:979
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define _In_
Definition: no_sal2.h:204
HWND hList
Definition: livecd.c:10
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
HWND WINAPI GetParent(_In_ HWND)
static VOID GetSyncSetting(HWND hwnd)
Definition: internettime.c:269
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define CBN_SELCHANGE
Definition: winuser.h:1961
#define BST_CHECKED
Definition: winuser.h:197
WCHAR szSyncWait[BUFSIZE]
Definition: timedate.h:41
#define HIWORD(l)
Definition: typedefs.h:247
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define TIME_NOSECONDS
Definition: winnls.h:275
#define GetWindowLongPtr
Definition: treelist.c:73
static VOID OnAutoSync(BOOL Sync)
Definition: internettime.c:311
static DWORD WINAPI UpdateThread(_In_ LPVOID lpParameter)
Definition: internettime.c:346
static VOID UpdateNTPStatus(HWND hwnd, DWORD dwReason)
Definition: internettime.c:209
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1079
WCHAR szSyncInit[BUFSIZE]
Definition: timedate.h:44
#define BUFSIZE
Definition: discard.c:12
static VOID OnInitDialog(HWND hwnd)
Definition: internettime.c:301
#define WM_INITDIALOG
Definition: winuser.h:1721
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define WM_NOTIFY
Definition: richedit.h:61
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22