xref: /reactos/dll/cpl/timedate/internettime.c (revision 4d3df0da)
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 }
334