xref: /reactos/dll/win32/netid/netid.c (revision e4930be4)
1 /*
2  * PROJECT:     ReactOS System Control Panel Applet
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/netid/netid.c
5  * PURPOSE:     Network ID Page
6  * COPYRIGHT:   Thomas Weidenmueller <w3seek@reactos.org>
7  *              Dmitry Chapyshev <dmitry@reactos.org>
8  *
9  */
10 
11 #define WIN32_NO_STATUS
12 #include <stdarg.h>
13 #include <windef.h>
14 #include <winbase.h>
15 #include <winuser.h>
16 #include <winreg.h>
17 #include <windns.h>
18 #include <lm.h>
19 #include <prsht.h>
20 
21 #include "resource.h"
22 
23 
24 #define MAX_COMPUTERDESCRIPTION_LENGTH 255
25 #define MAX_HOSTNAME_LENGTH             63
26 #define MAX_DOMAINNAME_LENGTH          255
27 
28 typedef struct _NETIDDATA
29 {
30     WCHAR szHostName[MAX_HOSTNAME_LENGTH + 1];
31     WCHAR szOldHostName[MAX_HOSTNAME_LENGTH + 1];
32     WCHAR szDomainName[MAX_DOMAINNAME_LENGTH + 1];
33     WCHAR szOldDomainName[MAX_DOMAINNAME_LENGTH + 1];
34     WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
35     BOOL bSyncDomainWithMembership;
36     LPWSTR JoinName;
37     NETSETUP_JOIN_STATUS JoinStatus;
38     BOOL bHostNameChanged;
39     BOOL bDomainNameChanged;
40     BOOL bSyncDomainWithMembershipChanged;
41     BOOL bEnable;
42 } NETIDDATA, *PNETIDDATA;
43 
44 
45 static HINSTANCE hDllInstance;
46 
47 static
48 INT
FormatMessageBox(HWND hDlg,UINT uType,DWORD dwMessage,...)49 FormatMessageBox(
50     HWND hDlg,
51     UINT uType,
52     DWORD dwMessage,
53     ...)
54 {
55     WCHAR szTitle[256], szMessage[256], szText[512];
56     va_list args = NULL;
57 
58     LoadStringW(hDllInstance, 4, szTitle, ARRAYSIZE(szTitle));
59 
60     LoadStringW(hDllInstance, dwMessage, szMessage, ARRAYSIZE(szMessage));
61 
62     va_start(args, dwMessage);
63     FormatMessageW(FORMAT_MESSAGE_FROM_STRING,
64                    szMessage,
65                    0,
66                    0,
67                    szText,
68                    ARRAYSIZE(szText),
69                    &args);
70     va_end(args);
71 
72     return MessageBoxW(hDlg, szText, szTitle, uType);
73 }
74 
75 static
76 BOOL
GetComputerNames(PNETIDDATA pNetIdData)77 GetComputerNames(
78     PNETIDDATA pNetIdData)
79 {
80     HKEY KeyHandle;
81     DWORD dwSize;
82     DWORD dwError;
83 
84     dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
85                             L"SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
86                             0,
87                             KEY_QUERY_VALUE,
88                             &KeyHandle);
89     if (dwError == ERROR_SUCCESS)
90     {
91         dwSize = sizeof(pNetIdData->szHostName);
92         RegQueryValueExW(KeyHandle,
93                          L"NV HostName",
94                          0,
95                          NULL,
96                          (LPBYTE)&pNetIdData->szHostName,
97                          &dwSize);
98 
99         dwSize = sizeof(pNetIdData->szOldHostName);
100         RegQueryValueExW(KeyHandle,
101                          L"HostName",
102                          0,
103                          NULL,
104                          (LPBYTE)&pNetIdData->szOldHostName,
105                          &dwSize);
106 
107         dwSize = sizeof(pNetIdData->szDomainName);
108         RegQueryValueExW(KeyHandle,
109                          L"NV Domain",
110                          0,
111                          NULL,
112                          (LPBYTE)&pNetIdData->szDomainName,
113                          &dwSize);
114 
115         dwSize = sizeof(pNetIdData->szOldDomainName);
116         RegQueryValueExW(KeyHandle,
117                          L"Domain",
118                          0,
119                          NULL,
120                          (LPBYTE)&pNetIdData->szOldDomainName,
121                          &dwSize);
122 
123         dwSize = sizeof(pNetIdData->bSyncDomainWithMembership);
124         if (RegQueryValueExW(KeyHandle,
125                              L"SyncDomainWithMembership",
126                              0,
127                              NULL,
128                              (LPBYTE)&pNetIdData->bSyncDomainWithMembership,
129                              &dwSize))
130             pNetIdData->bSyncDomainWithMembership = TRUE;
131 
132         RegCloseKey(KeyHandle);
133     }
134 
135     dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
136                             L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName",
137                             0,
138                             KEY_QUERY_VALUE,
139                             &KeyHandle);
140     if (dwError == ERROR_SUCCESS)
141     {
142         dwSize = sizeof(pNetIdData->szComputerName);
143         RegQueryValueExW(KeyHandle,
144                          L"ComputerName",
145                          0,
146                          NULL,
147                          (LPBYTE)&pNetIdData->szComputerName,
148                          &dwSize);
149 
150         RegCloseKey(KeyHandle);
151     }
152 
153     if (NetGetJoinInformation(NULL, &pNetIdData->JoinName, &pNetIdData->JoinStatus) != NERR_Success)
154     {
155         pNetIdData->JoinName = NULL;
156         pNetIdData->JoinStatus = NetSetupUnknownStatus;
157     }
158 
159     return TRUE;
160 }
161 
162 static BOOL
IsUserAdmin(VOID)163 IsUserAdmin(VOID)
164 {
165     BOOL bIsAdmin;
166     SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
167     PSID pAdminsSid;
168 
169     if (!AllocateAndInitializeSid(&Authority, 2,
170                                   SECURITY_BUILTIN_DOMAIN_RID,
171                                   DOMAIN_ALIAS_RID_ADMINS,
172                                   0, 0, 0, 0, 0, 0,
173                                   &pAdminsSid))
174     {
175         return FALSE;
176     }
177 
178     if (!CheckTokenMembership(NULL, pAdminsSid, &bIsAdmin))
179         bIsAdmin = FALSE;
180     FreeSid(pAdminsSid);
181 
182     return bIsAdmin;
183 }
184 
185 static
186 BOOL
IsValidDomainName(HWND hDlg,UINT uId)187 IsValidDomainName(
188     HWND hDlg,
189     UINT uId)
190 {
191     WCHAR szDomainName[256];
192     DWORD dwError;
193 
194     if (GetDlgItemTextW(hDlg, uId, szDomainName, ARRAYSIZE(szDomainName)) == 0)
195         return TRUE;
196 
197     dwError = DnsValidateName_W(szDomainName, DnsNameDomain);
198     if (dwError != ERROR_SUCCESS)
199     {
200         switch (dwError)
201         {
202             case DNS_ERROR_NON_RFC_NAME:
203                 if (FormatMessageBox(hDlg, MB_YESNO | MB_ICONWARNING, 7, szDomainName) == IDYES)
204                     return TRUE;
205                 break;
206 
207             case ERROR_INVALID_NAME:
208                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 8, szDomainName);
209                 break;
210 
211             case DNS_ERROR_NUMERIC_NAME:
212                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1031, szDomainName);
213                 break;
214 
215             case DNS_ERROR_INVALID_NAME_CHAR:
216                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1032, szDomainName);
217                 break;
218         }
219 
220         return FALSE;
221     }
222 
223     return TRUE;
224 }
225 
226 static
227 INT_PTR CALLBACK
DNSSuffixPropDlgProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)228 DNSSuffixPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
229 {
230     PNETIDDATA pNetIdData;
231 
232     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
233 
234     switch (Msg)
235     {
236         case WM_INITDIALOG:
237             pNetIdData = (PNETIDDATA)lParam;
238             if (pNetIdData != NULL)
239             {
240                 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
241 
242                 SetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName);
243                 SendDlgItemMessage(hDlg, 115, BM_SETCHECK, (WPARAM)pNetIdData->bSyncDomainWithMembership, 0);
244                 SetDlgItemTextW(hDlg, 1013, pNetIdData->szComputerName);
245                 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
246             }
247             return TRUE;
248 
249         case WM_COMMAND:
250             switch (LOWORD(wParam))
251             {
252                 case 115:
253                     if (HIWORD(wParam) == BN_CLICKED)
254                     {
255                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
256                         pNetIdData->bSyncDomainWithMembershipChanged = TRUE;
257                     }
258                     break;
259 
260                 case 1011:
261                     if (HIWORD(wParam) == EN_CHANGE)
262                     {
263                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
264                         pNetIdData->bDomainNameChanged = TRUE;
265                     }
266                     break;
267 
268                 case IDOK:
269                     if (!IsValidDomainName(hDlg, 1011))
270                     {
271                         SetFocus(GetDlgItem(hDlg, 1011));
272                         break;
273                     }
274 
275                     if (pNetIdData->bDomainNameChanged)
276                         GetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName, ARRAYSIZE(pNetIdData->szDomainName));
277 
278                     if (pNetIdData->bSyncDomainWithMembershipChanged)
279                     {
280                         if (SendDlgItemMessage(hDlg, 115, BM_GETCHECK, 0, 0) == BST_CHECKED)
281                             pNetIdData->bSyncDomainWithMembership = TRUE;
282                         else
283                             pNetIdData->bSyncDomainWithMembership = FALSE;
284                     }
285 
286                     EndDialog(hDlg, TRUE);
287                     break;
288 
289                 case IDCANCEL:
290                     pNetIdData->bDomainNameChanged = FALSE;
291                     pNetIdData->bSyncDomainWithMembershipChanged = FALSE;
292                     EndDialog(hDlg, FALSE);
293                     break;
294             }
295             break;
296     }
297 
298     return FALSE;
299 }
300 
301 static VOID
SetRadioBtnState(HWND hDlg,BOOL IsDomain)302 SetRadioBtnState(HWND hDlg, BOOL IsDomain)
303 {
304     SendDlgItemMessage(hDlg, 1008, BM_SETCHECK, (WPARAM)IsDomain, 0);
305     SendDlgItemMessage(hDlg, 1004, BM_SETCHECK, (WPARAM)!IsDomain, 0);
306     EnableWindow(GetDlgItem(hDlg, 116), IsDomain);
307     EnableWindow(GetDlgItem(hDlg, 1007), !IsDomain);
308 }
309 
310 #if 0
311 static VOID
312 DisableControls(HWND hDlg)
313 {
314     EnableWindow(GetDlgItem(hDlg, 1008), FALSE);
315     EnableWindow(GetDlgItem(hDlg, 1004), FALSE);
316     EnableWindow(GetDlgItem(hDlg, 116), FALSE);
317     EnableWindow(GetDlgItem(hDlg, 1007), FALSE);
318 }
319 #endif
320 
321 static
322 BOOL
IsValidComputerName(HWND hDlg,UINT uId)323 IsValidComputerName(
324     HWND hDlg,
325     UINT uId)
326 {
327     WCHAR szHostName[256];
328     DWORD dwError;
329 
330     GetWindowText(GetDlgItem(hDlg, uId), szHostName, ARRAYSIZE(szHostName));
331 
332     dwError = DnsValidateName_W(szHostName, DnsNameHostnameLabel);
333     if (dwError != ERROR_SUCCESS)
334     {
335         switch (dwError)
336         {
337             case DNS_ERROR_NON_RFC_NAME:
338                 if (FormatMessageBox(hDlg, MB_YESNO | MB_ICONWARNING, 10, szHostName) == IDYES)
339                     return TRUE;
340                 break;
341 
342             case ERROR_INVALID_NAME:
343                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 11);
344                 return FALSE;
345 
346             case DNS_ERROR_NUMERIC_NAME:
347                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1029, szHostName);
348                 break;
349 
350             case DNS_ERROR_INVALID_NAME_CHAR:
351                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1030, szHostName);
352                 break;
353         }
354 
355         return FALSE;
356     }
357 
358     return TRUE;
359 }
360 
361 static
362 VOID
SetFullComputerName(HWND hDlg,UINT uId,PNETIDDATA pNetIdData)363 SetFullComputerName(
364     HWND hDlg,
365     UINT uId,
366     PNETIDDATA pNetIdData)
367 {
368     WCHAR szFullComputerName[512];
369 
370     wsprintf(szFullComputerName, L"%s.%s", pNetIdData->szHostName, pNetIdData->szDomainName);
371     SetDlgItemText(hDlg, uId, szFullComputerName);
372 }
373 
374 static
375 VOID
UpdateFullComputerName(HWND hDlg,UINT uId,PNETIDDATA pNetIdData)376 UpdateFullComputerName(
377     HWND hDlg,
378     UINT uId,
379     PNETIDDATA pNetIdData)
380 {
381     WCHAR szFullComputerName[512];
382     WCHAR szHostName[256];
383 
384     GetWindowText(GetDlgItem(hDlg, 1002), szHostName, ARRAYSIZE(szHostName));
385 
386     wsprintf(szFullComputerName, L"%s.%s", szHostName, pNetIdData->szDomainName);
387     SetDlgItemText(hDlg, uId, szFullComputerName);
388 }
389 
390 static
391 VOID
UpdateNetbiosName(HWND hDlg,UINT uId,PNETIDDATA pNetIdData)392 UpdateNetbiosName(
393     HWND hDlg,
394     UINT uId,
395     PNETIDDATA pNetIdData)
396 {
397     WCHAR szHostName[256];
398     DWORD dwSize;
399 
400     GetWindowText(GetDlgItem(hDlg, 1002), szHostName, ARRAYSIZE(szHostName));
401 
402     dwSize = ARRAYSIZE(pNetIdData->szComputerName);
403     DnsHostnameToComputerNameW(szHostName,
404                                pNetIdData->szComputerName,
405                                &dwSize);
406 }
407 
408 static
409 VOID
CheckForChangedNames(_In_ HWND hwndDlg,_In_ PNETIDDATA pNetIdData)410 CheckForChangedNames(
411     _In_ HWND hwndDlg,
412     _In_ PNETIDDATA pNetIdData)
413 {
414     INT nShow = SW_HIDE;
415 
416     if ((_wcsicmp(pNetIdData->szOldHostName, pNetIdData->szHostName) != 0) ||
417         (_wcsicmp(pNetIdData->szOldDomainName, pNetIdData->szDomainName) != 0))
418     {
419         nShow = SW_SHOW;
420     }
421 
422     ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTICON), nShow);
423     ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTTEXT), nShow);
424 }
425 
426 static
427 VOID
NetworkDlg_OnInitDialog(HWND hDlg,PNETIDDATA pNetIdData)428 NetworkDlg_OnInitDialog(
429     HWND hDlg,
430     PNETIDDATA pNetIdData)
431 {
432     WCHAR MsgText[MAX_PATH * 2];
433 
434     if (LoadStringW(hDllInstance, 25, MsgText, ARRAYSIZE(MsgText)))
435         SetDlgItemText(hDlg, 1017, MsgText);
436 
437     SendMessage(GetDlgItem(hDlg, 1002), EM_SETLIMITTEXT, MAX_HOSTNAME_LENGTH, 0);
438     SetDlgItemText(hDlg, 1002, pNetIdData->szHostName);
439     SetFullComputerName(hDlg, 1001, pNetIdData);
440 
441     /* Display the workgroup or domain name */
442     switch (pNetIdData->JoinStatus)
443     {
444         case NetSetupDomainName:
445             SetDlgItemText(hDlg, 116, pNetIdData->JoinName);
446             SetRadioBtnState(hDlg, TRUE);
447             break;
448 
449         case NetSetupWorkgroupName:
450             SetDlgItemText(hDlg, 1007, pNetIdData->JoinName);
451             SetRadioBtnState(hDlg, FALSE);
452             break;
453 
454         default:
455             break;
456     }
457 }
458 
459 static
460 BOOL
NetworkDlg_OnOK(HWND hDlg,PNETIDDATA pNetIdData)461 NetworkDlg_OnOK(
462     HWND hDlg,
463     PNETIDDATA pNetIdData)
464 {
465     WCHAR szMsgText[MAX_PATH], szMsgTitle[MAX_PATH];
466     HKEY KeyHandle;
467     DWORD dwError;
468 
469     if (pNetIdData->bHostNameChanged)
470     {
471         if (!IsValidComputerName(hDlg, 1002))
472         {
473             SetFocus(GetDlgItem(hDlg, 1002));
474             return FALSE;
475         }
476 
477         GetWindowText(GetDlgItem(hDlg, 1002), pNetIdData->szHostName, ARRAYSIZE(pNetIdData->szHostName));
478 
479         if (!SetComputerNameExW(ComputerNamePhysicalDnsHostname, pNetIdData->szHostName))
480         {
481             LoadStringW(hDllInstance, 4001, szMsgText, ARRAYSIZE(szMsgText));
482             MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
483             return FALSE;
484         }
485 
486         pNetIdData->bHostNameChanged = FALSE;
487     }
488 
489     if (pNetIdData->bDomainNameChanged)
490     {
491         if (!SetComputerNameExW(ComputerNamePhysicalDnsDomain, pNetIdData->szDomainName))
492         {
493             /* FIXME: Show error message */
494             return FALSE;
495         }
496 
497         pNetIdData->bDomainNameChanged = FALSE;
498     }
499 
500     if (pNetIdData->bSyncDomainWithMembershipChanged)
501     {
502         dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
503                                 L"SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
504                                 0,
505                                 KEY_SET_VALUE,
506                                 &KeyHandle);
507         if (dwError == ERROR_SUCCESS)
508         {
509             RegSetValueExW(KeyHandle,
510                            L"SyncDomainWithMembership",
511                            0,
512                            REG_DWORD,
513                            (LPBYTE)&pNetIdData->bSyncDomainWithMembership,
514                            sizeof(pNetIdData->bSyncDomainWithMembership));
515             RegCloseKey(KeyHandle);
516         }
517 
518         pNetIdData->bSyncDomainWithMembershipChanged = FALSE;
519     }
520 
521     LoadStringW(hDllInstance, 4000, szMsgTitle, ARRAYSIZE(szMsgTitle));
522     LoadStringW(hDllInstance, 24, szMsgText, ARRAYSIZE(szMsgText));
523     MessageBoxW(hDlg, szMsgText, szMsgTitle, MB_OK | MB_ICONINFORMATION);
524 
525     return TRUE;
526 }
527 
528 static
529 INT_PTR CALLBACK
NetworkPropDlgProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)530 NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
531 {
532     PNETIDDATA pNetIdData;
533 
534     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
535 
536     switch (Msg)
537     {
538         case WM_INITDIALOG:
539             pNetIdData = (PNETIDDATA)lParam;
540             if (pNetIdData != NULL)
541             {
542                 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
543                 NetworkDlg_OnInitDialog(hDlg, pNetIdData);
544                 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
545             }
546             return TRUE;
547 
548         case WM_COMMAND:
549             switch (LOWORD(wParam))
550             {
551                 case 1002:
552                     if (HIWORD(wParam) == EN_CHANGE)
553                     {
554                         UpdateFullComputerName(hDlg, 1001, pNetIdData);
555                         UpdateNetbiosName(hDlg, 1001, pNetIdData);
556                         pNetIdData->bHostNameChanged = TRUE;
557                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
558                     }
559                     break;
560 
561                 case 1008: /* Domain radio button */
562                 case 1004: /* Workgroup radio button */
563                     if (SendDlgItemMessage(hDlg, 1008, BM_GETCHECK, 0, 0) == BST_CHECKED)
564                         SetRadioBtnState(hDlg, TRUE);
565                     else
566                         SetRadioBtnState(hDlg, FALSE);
567                     break;
568 
569                 case 1003:
570                     if (DialogBoxParam(hDllInstance,
571                                        MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
572                                        hDlg,
573                                        DNSSuffixPropDlgProc,
574                                        (LPARAM)pNetIdData))
575                     {
576                         UpdateFullComputerName(hDlg, 1001, pNetIdData);
577                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
578                     }
579                     break;
580 
581                 case IDOK:
582                     if (NetworkDlg_OnOK(hDlg, pNetIdData))
583                         EndDialog(hDlg, TRUE);
584                     break;
585 
586                 case IDCANCEL:
587                     EndDialog(hDlg, FALSE);
588                     break;
589             }
590             break;
591     }
592 
593     return FALSE;
594 }
595 
596 static
597 VOID
NetIDPage_OnInitDialog(HWND hwndDlg,PNETIDDATA pNetIdData)598 NetIDPage_OnInitDialog(
599     HWND hwndDlg,
600     PNETIDDATA pNetIdData)
601 {
602     WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
603     DWORD RegSize = sizeof(ComputerDescription);
604     HKEY KeyHandle;
605     WCHAR szBuffer[512];
606     LONG lError;
607 
608     /* Display computer name and description */
609     SendDlgItemMessage(hwndDlg, IDC_COMPDESC, EM_SETLIMITTEXT, MAX_COMPUTERDESCRIPTION_LENGTH, 0);
610 
611     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
612                            L"SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
613                            0,
614                            KEY_QUERY_VALUE,
615                            &KeyHandle);
616     if (lError == ERROR_SUCCESS)
617     {
618         lError = RegQueryValueExW(KeyHandle,
619                                   L"srvcomment",
620                                   0,
621                                   NULL,
622                                   (LPBYTE)ComputerDescription,
623                                   &RegSize);
624         if (lError == ERROR_SUCCESS)
625         {
626             ComputerDescription[RegSize / sizeof(WCHAR)] = UNICODE_NULL;
627             SetDlgItemText(hwndDlg, IDC_COMPDESC, ComputerDescription);
628         }
629 
630         RegCloseKey(KeyHandle);
631     }
632 
633     /* Set the workgroup or domain name */
634     LoadStringW(hDllInstance, (pNetIdData->JoinStatus == NetSetupDomainName)? 6 : 5, szBuffer, ARRAYSIZE(szBuffer));
635     SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN, szBuffer);
636     SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN_NAME, pNetIdData->JoinName);
637 
638     /* Show the administrator note and disable controls when the user is not an administator */
639     if (!IsUserAdmin())
640     {
641         LoadStringW(hDllInstance, 1021, szBuffer, ARRAYSIZE(szBuffer));
642         SetDlgItemText(hwndDlg, IDC_MESSAGETEXT, szBuffer);
643 
644         EnableWindow(GetDlgItem(hwndDlg, IDC_NETWORK_ID), FALSE);
645         EnableWindow(GetDlgItem(hwndDlg, IDC_NETWORK_PROPERTY), FALSE);
646     }
647 }
648 
649 static
650 LONG
NetIDPage_OnApply(HWND hwndDlg)651 NetIDPage_OnApply(
652     HWND hwndDlg)
653 {
654     WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
655     WCHAR NewComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
656     HKEY KeyHandle = NULL;
657     DWORD dwSize;
658     LONG lError;
659 
660     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
661                            L"SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
662                            0,
663                            KEY_QUERY_VALUE | KEY_SET_VALUE,
664                            &KeyHandle);
665     if (lError != ERROR_SUCCESS)
666         return lError;
667 
668     GetDlgItemTextW(hwndDlg,
669                     IDC_COMPDESC,
670                     NewComputerDescription,
671                     ARRAYSIZE(NewComputerDescription));
672     if (GetLastError() != ERROR_SUCCESS)
673     {
674         lError = GetLastError();
675         goto done;
676     }
677 
678     dwSize = sizeof(ComputerDescription);
679     lError = RegQueryValueExW(KeyHandle,
680                               L"srvcomment",
681                               0,
682                               NULL,
683                               (PBYTE)ComputerDescription,
684                               &dwSize);
685     if (lError != ERROR_SUCCESS && lError != ERROR_FILE_NOT_FOUND)
686         goto done;
687 
688     lError = ERROR_SUCCESS;
689     if (wcscmp(ComputerDescription, NewComputerDescription) != 0)
690     {
691         lError = RegSetValueExW(KeyHandle,
692                                 L"srvcomment",
693                                 0,
694                                 REG_SZ,
695                                 (PBYTE)NewComputerDescription,
696                                 (wcslen(NewComputerDescription) + 1) * sizeof(WCHAR));
697     }
698 
699 done:
700     if (KeyHandle != NULL)
701         RegCloseKey(KeyHandle);
702 
703     return lError;
704 }
705 
706 static INT_PTR CALLBACK
NetIDPageProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)707 NetIDPageProc(IN HWND hwndDlg,
708               IN UINT uMsg,
709               IN WPARAM wParam,
710               IN LPARAM lParam)
711 {
712     PNETIDDATA pNetIdData;
713 
714     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
715 
716     switch (uMsg)
717     {
718         case WM_INITDIALOG:
719             pNetIdData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETIDDATA));
720             if (pNetIdData != NULL)
721             {
722                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pNetIdData);
723                 GetComputerNames(pNetIdData);
724                 SetFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
725                 NetIDPage_OnInitDialog(hwndDlg, pNetIdData);
726                 pNetIdData->bEnable = TRUE;
727                 CheckForChangedNames(hwndDlg, pNetIdData);
728             }
729             return TRUE;
730 
731         case WM_NOTIFY:
732             switch (((LPNMHDR)lParam)->code)
733             {
734                 case PSN_APPLY:
735                     NetIDPage_OnApply(hwndDlg);
736                     break;
737             }
738             break;
739 
740         case WM_COMMAND:
741             switch (LOWORD(wParam))
742             {
743                 case IDC_COMPDESC:
744                     if (HIWORD(wParam) == EN_CHANGE && pNetIdData->bEnable == TRUE)
745                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
746                     break;
747 
748                 case IDC_NETWORK_PROPERTY:
749                     if (DialogBoxParam(hDllInstance,
750                                        MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE),
751                                        hwndDlg,
752                                        NetworkPropDlgProc,
753                                        (LPARAM)pNetIdData))
754                     {
755                         UpdateFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
756                         CheckForChangedNames(hwndDlg, pNetIdData);
757                     }
758                     break;
759             }
760             break;
761 
762         case WM_DESTROY:
763             if (pNetIdData != NULL)
764             {
765                 if (pNetIdData->JoinName != NULL)
766                     NetApiBufferFree(pNetIdData->JoinName);
767                 HeapFree(GetProcessHeap(), 0, pNetIdData);
768                 pNetIdData = NULL;
769                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
770             }
771             break;
772     }
773 
774     return FALSE;
775 }
776 
777 HPROPSHEETPAGE WINAPI
CreateNetIDPropertyPage(VOID)778 CreateNetIDPropertyPage(VOID)
779 {
780     PROPSHEETPAGE psp = {0};
781 
782     psp.dwSize = sizeof(psp);
783     psp.dwFlags = PSP_DEFAULT;
784     psp.hInstance = hDllInstance;
785     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGECOMPUTER);
786     psp.pfnDlgProc = NetIDPageProc;
787 
788     return CreatePropertySheetPage(&psp);
789 }
790 
791 BOOL WINAPI
DllMain(IN HINSTANCE hinstDLL,IN DWORD dwReason,IN LPVOID lpvReserved)792 DllMain(IN HINSTANCE hinstDLL,
793         IN DWORD dwReason,
794         IN LPVOID lpvReserved)
795 {
796     switch (dwReason)
797     {
798         case DLL_PROCESS_ATTACH:
799             hDllInstance = hinstDLL;
800             DisableThreadLibraryCalls(hinstDLL);
801             break;
802     }
803 
804     return TRUE;
805 }
806