[TIMEDATE] Handle manual time server entry. CORE-13001
[reactos.git] / dll / cpl / timedate / internettime.c
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
13 DWORD WINAPI W32TimeSyncNow(LPCWSTR cmdline, UINT blocking, UINT flags);
14
15 static VOID
16 CreateNTPServerList(HWND hwnd)
17 {
18 HWND hList;
19 WCHAR szValName[MAX_VALUE_NAME];
20 WCHAR szData[256];
21 DWORD dwIndex = 0;
22 DWORD dwValSize;
23 DWORD dwNameSize;
24 DWORD dwDefault = 1;
25 LONG lRet;
26 HKEY hKey;
27
28 hList = GetDlgItem(hwnd,
29 IDC_SERVERLIST);
30
31 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
32 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
33 0,
34 KEY_QUERY_VALUE,
35 &hKey);
36 if (lRet != ERROR_SUCCESS)
37 return;
38
39 while (TRUE)
40 {
41 dwValSize = MAX_VALUE_NAME * sizeof(WCHAR);
42 szValName[0] = L'\0';
43 lRet = RegEnumValueW(hKey,
44 dwIndex,
45 szValName,
46 &dwValSize,
47 NULL,
48 NULL,
49 (LPBYTE)szData,
50 &dwNameSize);
51 if (lRet == ERROR_SUCCESS)
52 {
53 /* Get date from default reg value */
54 if (wcscmp(szValName, L"") == 0) // if (Index == 0)
55 {
56 dwDefault = _wtoi(szData);
57 dwIndex++;
58 }
59 else
60 {
61 SendMessageW(hList,
62 CB_ADDSTRING,
63 0,
64 (LPARAM)szData);
65 dwIndex++;
66 }
67 }
68 else if (lRet != ERROR_MORE_DATA)
69 {
70 break;
71 }
72 }
73
74 if (dwDefault < 1 || dwDefault > dwIndex)
75 dwDefault = 1;
76
77 /* Server reg entries count from 1,
78 * Combo boxes count from 0 */
79 dwDefault--;
80
81 SendMessageW(hList,
82 CB_SETCURSEL,
83 dwDefault,
84 0);
85
86 RegCloseKey(hKey);
87 }
88
89
90 /* Set the selected server in the registry */
91 static VOID
92 SetNTPServer(HWND hwnd)
93 {
94 HKEY hKey;
95 HWND hList;
96 UINT uSel;
97 WCHAR szSel[4];
98 LONG lRet;
99 WCHAR buffer[256];
100
101 hList = GetDlgItem(hwnd,
102 IDC_SERVERLIST);
103
104 uSel = (UINT)SendMessageW(hList, CB_GETCURSEL, 0, 0);
105
106 SendDlgItemMessageW(hwnd, IDC_SERVERLIST, WM_GETTEXT, _countof(buffer), (LPARAM)buffer);
107
108 /* If there is new data entered then save it in the registry
109 The same key name of "0" is used to store all user entered values
110 */
111 if (uSel == -1)
112 {
113 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
114 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
115 0,
116 KEY_SET_VALUE,
117 &hKey);
118 if (lRet != ERROR_SUCCESS)
119 {
120 DisplayWin32Error(lRet);
121 return;
122 }
123 lRet = RegSetValueExW(hKey,
124 L"0",
125 0,
126 REG_SZ,
127 (LPBYTE)buffer,
128 (wcslen(buffer) + 1) * sizeof(WCHAR));
129 if (lRet != ERROR_SUCCESS)
130 DisplayWin32Error(lRet);
131 }
132
133 /* Server reg entries count from 1,
134 * Combo boxes count from 0 */
135 uSel++;
136
137 /* Convert to wide char */
138 _itow(uSel, szSel, 10);
139
140 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
141 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DateTime\\Servers",
142 0,
143 KEY_SET_VALUE,
144 &hKey);
145 if (lRet != ERROR_SUCCESS)
146 {
147 DisplayWin32Error(lRet);
148 return;
149 }
150
151 lRet = RegSetValueExW(hKey,
152 L"",
153 0,
154 REG_SZ,
155 (LPBYTE)szSel,
156 (wcslen(szSel) + 1) * sizeof(WCHAR));
157 if (lRet != ERROR_SUCCESS)
158 DisplayWin32Error(lRet);
159
160 RegCloseKey(hKey);
161 }
162
163
164 static VOID
165 EnableDialogText(HWND hwnd)
166 {
167 BOOL bChecked;
168 UINT uCheck;
169
170 uCheck = (UINT)SendDlgItemMessageW(hwnd, IDC_AUTOSYNC, BM_GETCHECK, 0, 0);
171 bChecked = (uCheck == BST_CHECKED) ? TRUE : FALSE;
172
173 EnableWindow(GetDlgItem(hwnd, IDC_SERVERTEXT), bChecked);
174 EnableWindow(GetDlgItem(hwnd, IDC_SERVERLIST), bChecked);
175 EnableWindow(GetDlgItem(hwnd, IDC_UPDATEBUTTON), bChecked);
176 EnableWindow(GetDlgItem(hwnd, IDC_SUCSYNC), bChecked);
177 EnableWindow(GetDlgItem(hwnd, IDC_NEXTSYNC), bChecked);
178 }
179
180
181 static VOID
182 GetSyncSetting(HWND hwnd)
183 {
184 HKEY hKey;
185 WCHAR szData[8];
186 DWORD dwSize;
187
188 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
189 L"SYSTEM\\CurrentControlSet\\Services\\W32Time\\Parameters",
190 0,
191 KEY_QUERY_VALUE,
192 &hKey) == ERROR_SUCCESS)
193 {
194 dwSize = 8 * sizeof(WCHAR);
195 if (RegQueryValueExW(hKey,
196 L"Type",
197 NULL,
198 NULL,
199 (LPBYTE)szData,
200 &dwSize) == ERROR_SUCCESS)
201 {
202 if (wcscmp(szData, L"NTP") == 0)
203 SendDlgItemMessageW(hwnd, IDC_AUTOSYNC, BM_SETCHECK, BST_CHECKED, 0);
204 else
205 SendDlgItemMessageW(hwnd, IDC_AUTOSYNC, BM_SETCHECK, BST_UNCHECKED, 0);
206 }
207
208 RegCloseKey(hKey);
209 }
210 }
211
212
213 static VOID
214 OnInitDialog(HWND hwnd)
215 {
216 GetSyncSetting(hwnd);
217 EnableDialogText(hwnd);
218 CreateNTPServerList(hwnd);
219 }
220
221 static VOID
222 OnAutoSync(BOOL Sync)
223 {
224 HKEY hKey;
225 LONG lRet;
226 LPCWSTR szAuto;
227
228 if (Sync)
229 szAuto = L"NTP";
230 else
231 szAuto = L"NoSync";
232
233 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
234 L"SYSTEM\\CurrentControlSet\\Services\\W32Time\\Parameters",
235 0,
236 KEY_SET_VALUE,
237 &hKey);
238 if (lRet != ERROR_SUCCESS)
239 {
240 DisplayWin32Error(lRet);
241 return;
242 }
243
244 lRet = RegSetValueExW(hKey,
245 L"Type",
246 0,
247 REG_SZ,
248 (LPBYTE)szAuto,
249 (wcslen(szAuto) + 1) * sizeof(WCHAR));
250 if (lRet != ERROR_SUCCESS)
251 DisplayWin32Error(lRet);
252
253 RegCloseKey(hKey);
254 }
255
256 /* Property page dialog callback */
257 INT_PTR CALLBACK
258 InetTimePageProc(HWND hwndDlg,
259 UINT uMsg,
260 WPARAM wParam,
261 LPARAM lParam)
262 {
263 switch (uMsg)
264 {
265 case WM_INITDIALOG:
266 OnInitDialog(hwndDlg);
267 break;
268
269 case WM_COMMAND:
270 switch(LOWORD(wParam))
271 {
272 case IDC_UPDATEBUTTON:
273 {
274 DWORD dwError;
275
276 SetNTPServer(hwndDlg);
277
278 dwError = W32TimeSyncNow(L"localhost", 0, 0);
279 if (dwError != ERROR_SUCCESS)
280 {
281 DisplayWin32Error(dwError);
282 }
283 }
284 break;
285
286 case IDC_SERVERLIST:
287 if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_EDITCHANGE))
288 {
289 /* Enable the 'Apply' button */
290 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
291 }
292 break;
293
294 case IDC_AUTOSYNC:
295 if (HIWORD(wParam) == BN_CLICKED)
296 {
297 EnableDialogText(hwndDlg);
298
299 /* Enable the 'Apply' button */
300 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
301 }
302 break;
303 }
304 break;
305
306 case WM_DESTROY:
307 break;
308
309 case WM_NOTIFY:
310 {
311 LPNMHDR lpnm = (LPNMHDR)lParam;
312
313 switch (lpnm->code)
314 {
315 case PSN_APPLY:
316 SetNTPServer(hwndDlg);
317
318 if (SendDlgItemMessageW(hwndDlg, IDC_AUTOSYNC, BM_GETCHECK, 0, 0) == BST_CHECKED)
319 OnAutoSync(TRUE);
320 else
321 OnAutoSync(FALSE);
322
323 return TRUE;
324
325 default:
326 break;
327 }
328 }
329 break;
330 }
331
332 return FALSE;
333 }