xref: /reactos/dll/win32/netid/netid.c (revision b5218987)
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
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
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
163 IsUserAdmin(VOID)
164 {
165     SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
166     PSID pAdminsSid = NULL;
167     HANDLE hToken = NULL;
168     PTOKEN_GROUPS pGroups = NULL;
169     BOOL bIsAdmin = FALSE;
170     DWORD dwSize, i;
171 
172     if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
173                                   DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
174                                   &pAdminsSid))
175         return FALSE;
176 
177     if (!OpenProcessToken(GetCurrentProcess(),
178                           TOKEN_QUERY,
179                           &hToken))
180         goto done;
181 
182     if (GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize) ||
183         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
184     {
185         goto done;
186     }
187 
188     pGroups = HeapAlloc(GetProcessHeap(), 0, dwSize);
189     if (pGroups == NULL)
190         goto done;
191 
192     if (!GetTokenInformation(hToken,
193                              TokenGroups,
194                              pGroups,
195                              dwSize,
196                              &dwSize))
197         goto done;
198 
199     for (i = 0; i < pGroups->GroupCount; i++)
200     {
201         if (EqualSid(pGroups->Groups[i].Sid, pAdminsSid))
202         {
203             bIsAdmin = TRUE;
204             break;
205         }
206     }
207 
208 done:
209     if (pGroups != NULL)
210         HeapFree(GetProcessHeap(), 0, pGroups);
211 
212     if (hToken != NULL)
213         CloseHandle(hToken);
214 
215     if (pAdminsSid != NULL)
216         FreeSid(pAdminsSid);
217 
218     return bIsAdmin;
219 }
220 
221 static
222 BOOL
223 IsValidDomainName(
224     HWND hDlg,
225     UINT uId)
226 {
227     WCHAR szDomainName[256];
228     DWORD dwError;
229 
230     if (GetDlgItemTextW(hDlg, uId, szDomainName, ARRAYSIZE(szDomainName)) == 0)
231         return TRUE;
232 
233     dwError = DnsValidateName_W(szDomainName, DnsNameDomain);
234     if (dwError != ERROR_SUCCESS)
235     {
236         switch (dwError)
237         {
238             case DNS_ERROR_NON_RFC_NAME:
239                 if (FormatMessageBox(hDlg, MB_YESNO | MB_ICONWARNING, 7, szDomainName) == IDYES)
240                     return TRUE;
241                 break;
242 
243             case ERROR_INVALID_NAME:
244                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 8, szDomainName);
245                 break;
246 
247             case DNS_ERROR_NUMERIC_NAME:
248                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1031, szDomainName);
249                 break;
250 
251             case DNS_ERROR_INVALID_NAME_CHAR:
252                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1032, szDomainName);
253                 break;
254         }
255 
256         return FALSE;
257     }
258 
259     return TRUE;
260 }
261 
262 static
263 INT_PTR CALLBACK
264 DNSSuffixPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
265 {
266     PNETIDDATA pNetIdData;
267 
268     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
269 
270     switch (Msg)
271     {
272         case WM_INITDIALOG:
273             pNetIdData = (PNETIDDATA)lParam;
274             if (pNetIdData != NULL)
275             {
276                 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
277 
278                 SetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName);
279                 SendDlgItemMessage(hDlg, 115, BM_SETCHECK, (WPARAM)pNetIdData->bSyncDomainWithMembership, 0);
280                 SetDlgItemTextW(hDlg, 1013, pNetIdData->szComputerName);
281                 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
282             }
283             return TRUE;
284 
285         case WM_COMMAND:
286             switch (LOWORD(wParam))
287             {
288                 case 115:
289                     if (HIWORD(wParam) == BN_CLICKED)
290                     {
291                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
292                         pNetIdData->bSyncDomainWithMembershipChanged = TRUE;
293                     }
294                     break;
295 
296                 case 1011:
297                     if (HIWORD(wParam) == EN_CHANGE)
298                     {
299                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
300                         pNetIdData->bDomainNameChanged = TRUE;
301                     }
302                     break;
303 
304                 case IDOK:
305                     if (!IsValidDomainName(hDlg, 1011))
306                     {
307                         SetFocus(GetDlgItem(hDlg, 1011));
308                         break;
309                     }
310 
311                     if (pNetIdData->bDomainNameChanged)
312                         GetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName, ARRAYSIZE(pNetIdData->szDomainName));
313 
314                     if (pNetIdData->bSyncDomainWithMembershipChanged)
315                     {
316                         if (SendDlgItemMessage(hDlg, 115, BM_GETCHECK, 0, 0) == BST_CHECKED)
317                             pNetIdData->bSyncDomainWithMembership = TRUE;
318                         else
319                             pNetIdData->bSyncDomainWithMembership = FALSE;
320                     }
321 
322                     EndDialog(hDlg, TRUE);
323                     break;
324 
325                 case IDCANCEL:
326                     pNetIdData->bDomainNameChanged = FALSE;
327                     pNetIdData->bSyncDomainWithMembershipChanged = FALSE;
328                     EndDialog(hDlg, FALSE);
329                     break;
330             }
331             break;
332     }
333 
334     return FALSE;
335 }
336 
337 static VOID
338 SetRadioBtnState(HWND hDlg, BOOL IsDomain)
339 {
340     SendDlgItemMessage(hDlg, 1008, BM_SETCHECK, (WPARAM)IsDomain, 0);
341     SendDlgItemMessage(hDlg, 1004, BM_SETCHECK, (WPARAM)!IsDomain, 0);
342     EnableWindow(GetDlgItem(hDlg, 116), IsDomain);
343     EnableWindow(GetDlgItem(hDlg, 1007), !IsDomain);
344 }
345 
346 #if 0
347 static VOID
348 DisableControls(HWND hDlg)
349 {
350     EnableWindow(GetDlgItem(hDlg, 1008), FALSE);
351     EnableWindow(GetDlgItem(hDlg, 1004), FALSE);
352     EnableWindow(GetDlgItem(hDlg, 116), FALSE);
353     EnableWindow(GetDlgItem(hDlg, 1007), FALSE);
354 }
355 #endif
356 
357 static
358 BOOL
359 IsValidComputerName(
360     HWND hDlg,
361     UINT uId)
362 {
363     WCHAR szHostName[256];
364     DWORD dwError;
365 
366     GetWindowText(GetDlgItem(hDlg, uId), szHostName, ARRAYSIZE(szHostName));
367 
368     dwError = DnsValidateName_W(szHostName, DnsNameHostnameLabel);
369     if (dwError != ERROR_SUCCESS)
370     {
371         switch (dwError)
372         {
373             case DNS_ERROR_NON_RFC_NAME:
374                 if (FormatMessageBox(hDlg, MB_YESNO | MB_ICONWARNING, 10, szHostName) == IDYES)
375                     return TRUE;
376                 break;
377 
378             case ERROR_INVALID_NAME:
379                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 11);
380                 return FALSE;
381 
382             case DNS_ERROR_NUMERIC_NAME:
383                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1029, szHostName);
384                 break;
385 
386             case DNS_ERROR_INVALID_NAME_CHAR:
387                 FormatMessageBox(hDlg, MB_OK | MB_ICONERROR, 1030, szHostName);
388                 break;
389         }
390 
391         return FALSE;
392     }
393 
394     return TRUE;
395 }
396 
397 static
398 VOID
399 SetFullComputerName(
400     HWND hDlg,
401     UINT uId,
402     PNETIDDATA pNetIdData)
403 {
404     WCHAR szFullComputerName[512];
405 
406     wsprintf(szFullComputerName, L"%s.%s", pNetIdData->szHostName, pNetIdData->szDomainName);
407     SetDlgItemText(hDlg, uId, szFullComputerName);
408 }
409 
410 static
411 VOID
412 UpdateFullComputerName(
413     HWND hDlg,
414     UINT uId,
415     PNETIDDATA pNetIdData)
416 {
417     WCHAR szFullComputerName[512];
418     WCHAR szHostName[256];
419 
420     GetWindowText(GetDlgItem(hDlg, 1002), szHostName, ARRAYSIZE(szHostName));
421 
422     wsprintf(szFullComputerName, L"%s.%s", szHostName, pNetIdData->szDomainName);
423     SetDlgItemText(hDlg, uId, szFullComputerName);
424 }
425 
426 static
427 VOID
428 UpdateNetbiosName(
429     HWND hDlg,
430     UINT uId,
431     PNETIDDATA pNetIdData)
432 {
433     WCHAR szHostName[256];
434     DWORD dwSize;
435 
436     GetWindowText(GetDlgItem(hDlg, 1002), szHostName, ARRAYSIZE(szHostName));
437 
438     dwSize = ARRAYSIZE(pNetIdData->szComputerName);
439     DnsHostnameToComputerNameW(szHostName,
440                                pNetIdData->szComputerName,
441                                &dwSize);
442 }
443 
444 static
445 VOID
446 CheckForChangedNames(
447     _In_ HWND hwndDlg,
448     _In_ PNETIDDATA pNetIdData)
449 {
450     INT nShow = SW_HIDE;
451 
452     if ((wcsicmp(pNetIdData->szOldHostName, pNetIdData->szHostName) != 0) ||
453         (wcsicmp(pNetIdData->szOldDomainName, pNetIdData->szDomainName) != 0))
454     {
455         nShow = SW_SHOW;
456     }
457 
458     ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTICON), nShow);
459     ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTTEXT), nShow);
460 }
461 
462 static
463 VOID
464 NetworkDlg_OnInitDialog(
465     HWND hDlg,
466     PNETIDDATA pNetIdData)
467 {
468     WCHAR MsgText[MAX_PATH * 2];
469 
470     if (LoadStringW(hDllInstance, 25, MsgText, ARRAYSIZE(MsgText)))
471         SetDlgItemText(hDlg, 1017, MsgText);
472 
473     SendMessage(GetDlgItem(hDlg, 1002), EM_SETLIMITTEXT, MAX_HOSTNAME_LENGTH, 0);
474     SetDlgItemText(hDlg, 1002, pNetIdData->szHostName);
475     SetFullComputerName(hDlg, 1001, pNetIdData);
476 
477     /* Display the workgroup or domain name */
478     switch (pNetIdData->JoinStatus)
479     {
480         case NetSetupDomainName:
481             SetDlgItemText(hDlg, 116, pNetIdData->JoinName);
482             SetRadioBtnState(hDlg, TRUE);
483             break;
484 
485         case NetSetupWorkgroupName:
486             SetDlgItemText(hDlg, 1007, pNetIdData->JoinName);
487             SetRadioBtnState(hDlg, FALSE);
488             break;
489 
490         default:
491             break;
492     }
493 }
494 
495 static
496 BOOL
497 NetworkDlg_OnOK(
498     HWND hDlg,
499     PNETIDDATA pNetIdData)
500 {
501     WCHAR szMsgText[MAX_PATH], szMsgTitle[MAX_PATH];
502     HKEY KeyHandle;
503     DWORD dwError;
504 
505     if (pNetIdData->bHostNameChanged)
506     {
507         if (!IsValidComputerName(hDlg, 1002))
508         {
509             SetFocus(GetDlgItem(hDlg, 1002));
510             return FALSE;
511         }
512 
513         GetWindowText(GetDlgItem(hDlg, 1002), pNetIdData->szHostName, ARRAYSIZE(pNetIdData->szHostName));
514 
515         if (!SetComputerNameExW(ComputerNamePhysicalDnsHostname, pNetIdData->szHostName))
516         {
517             LoadStringW(hDllInstance, 4001, szMsgText, ARRAYSIZE(szMsgText));
518             MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
519             return FALSE;
520         }
521 
522         pNetIdData->bHostNameChanged = FALSE;
523     }
524 
525     if (pNetIdData->bDomainNameChanged)
526     {
527         if (!SetComputerNameExW(ComputerNamePhysicalDnsDomain, pNetIdData->szDomainName))
528         {
529             /* FIXME: Show error message */
530             return FALSE;
531         }
532 
533         pNetIdData->bDomainNameChanged = FALSE;
534     }
535 
536     if (pNetIdData->bSyncDomainWithMembershipChanged)
537     {
538         dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
539                                 L"SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
540                                 0,
541                                 KEY_SET_VALUE,
542                                 &KeyHandle);
543         if (dwError == ERROR_SUCCESS)
544         {
545             RegSetValueExW(KeyHandle,
546                            L"SyncDomainWithMembership",
547                            0,
548                            REG_DWORD,
549                            (LPBYTE)&pNetIdData->bSyncDomainWithMembership,
550                            sizeof(pNetIdData->bSyncDomainWithMembership));
551             RegCloseKey(KeyHandle);
552         }
553 
554         pNetIdData->bSyncDomainWithMembershipChanged = FALSE;
555     }
556 
557     LoadStringW(hDllInstance, 4000, szMsgTitle, ARRAYSIZE(szMsgTitle));
558     LoadStringW(hDllInstance, 24, szMsgText, ARRAYSIZE(szMsgText));
559     MessageBoxW(hDlg, szMsgText, szMsgTitle, MB_OK | MB_ICONINFORMATION);
560 
561     return TRUE;
562 }
563 
564 static
565 INT_PTR CALLBACK
566 NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
567 {
568     PNETIDDATA pNetIdData;
569 
570     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
571 
572     switch (Msg)
573     {
574         case WM_INITDIALOG:
575             pNetIdData = (PNETIDDATA)lParam;
576             if (pNetIdData != NULL)
577             {
578                 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
579                 NetworkDlg_OnInitDialog(hDlg, pNetIdData);
580                 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
581             }
582             return TRUE;
583 
584         case WM_COMMAND:
585             switch (LOWORD(wParam))
586             {
587                 case 1002:
588                     if (HIWORD(wParam) == EN_CHANGE)
589                     {
590                         UpdateFullComputerName(hDlg, 1001, pNetIdData);
591                         UpdateNetbiosName(hDlg, 1001, pNetIdData);
592                         pNetIdData->bHostNameChanged = TRUE;
593                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
594                     }
595                     break;
596 
597                 case 1008: /* Domain radio button */
598                 case 1004: /* Workgroup radio button */
599                     if (SendDlgItemMessage(hDlg, 1008, BM_GETCHECK, 0, 0) == BST_CHECKED)
600                         SetRadioBtnState(hDlg, TRUE);
601                     else
602                         SetRadioBtnState(hDlg, FALSE);
603                     break;
604 
605                 case 1003:
606                     if (DialogBoxParam(hDllInstance,
607                                        MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
608                                        hDlg,
609                                        DNSSuffixPropDlgProc,
610                                        (LPARAM)pNetIdData))
611                     {
612                         UpdateFullComputerName(hDlg, 1001, pNetIdData);
613                         EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
614                     }
615                     break;
616 
617                 case IDOK:
618                     if (NetworkDlg_OnOK(hDlg, pNetIdData))
619                         EndDialog(hDlg, TRUE);
620                     break;
621 
622                 case IDCANCEL:
623                     EndDialog(hDlg, FALSE);
624                     break;
625             }
626             break;
627     }
628 
629     return FALSE;
630 }
631 
632 static
633 VOID
634 NetIDPage_OnInitDialog(
635     HWND hwndDlg,
636     PNETIDDATA pNetIdData)
637 {
638     WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
639     DWORD RegSize = sizeof(ComputerDescription);
640     HKEY KeyHandle;
641     WCHAR szBuffer[512];
642     LONG lError;
643 
644     /* Display computer name and description */
645     SendDlgItemMessage(hwndDlg, IDC_COMPDESC, EM_SETLIMITTEXT, MAX_COMPUTERDESCRIPTION_LENGTH, 0);
646 
647     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
648                            L"SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
649                            0,
650                            KEY_QUERY_VALUE,
651                            &KeyHandle);
652     if (lError == ERROR_SUCCESS)
653     {
654         lError = RegQueryValueExW(KeyHandle,
655                                   L"srvcomment",
656                                   0,
657                                   NULL,
658                                   (LPBYTE)ComputerDescription,
659                                   &RegSize);
660         if (lError == ERROR_SUCCESS)
661         {
662             ComputerDescription[RegSize / sizeof(WCHAR)] = UNICODE_NULL;
663             SetDlgItemText(hwndDlg, IDC_COMPDESC, ComputerDescription);
664         }
665 
666         RegCloseKey(KeyHandle);
667     }
668 
669     /* Set the workgroup or domain name */
670     LoadStringW(hDllInstance, (pNetIdData->JoinStatus == NetSetupDomainName)? 6 : 5, szBuffer, ARRAYSIZE(szBuffer));
671     SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN, szBuffer);
672     SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN_NAME, pNetIdData->JoinName);
673 
674     /* Show the administrator note and disable controls when the user is not an administator */
675     if (!IsUserAdmin())
676     {
677         LoadStringW(hDllInstance, 1021, szBuffer, ARRAYSIZE(szBuffer));
678         SetDlgItemText(hwndDlg, IDC_MESSAGETEXT, szBuffer);
679 
680         EnableWindow(GetDlgItem(hwndDlg, IDC_NETWORK_ID), FALSE);
681         EnableWindow(GetDlgItem(hwndDlg, IDC_NETWORK_PROPERTY), FALSE);
682     }
683 }
684 
685 static
686 LONG
687 NetIDPage_OnApply(
688     HWND hwndDlg)
689 {
690     WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
691     WCHAR NewComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
692     HKEY KeyHandle = NULL;
693     DWORD dwSize;
694     LONG lError;
695 
696     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
697                            L"SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
698                            0,
699                            KEY_QUERY_VALUE | KEY_SET_VALUE,
700                            &KeyHandle);
701     if (lError != ERROR_SUCCESS)
702         return lError;
703 
704     GetDlgItemTextW(hwndDlg,
705                     IDC_COMPDESC,
706                     NewComputerDescription,
707                     ARRAYSIZE(NewComputerDescription));
708     if (GetLastError() != ERROR_SUCCESS)
709     {
710         lError = GetLastError();
711         goto done;
712     }
713 
714     dwSize = sizeof(ComputerDescription);
715     lError = RegQueryValueExW(KeyHandle,
716                               L"srvcomment",
717                               0,
718                               NULL,
719                               (PBYTE)ComputerDescription,
720                               &dwSize);
721     if (lError != ERROR_SUCCESS && lError != ERROR_FILE_NOT_FOUND)
722         goto done;
723 
724     lError = ERROR_SUCCESS;
725     if (wcscmp(ComputerDescription, NewComputerDescription) != 0)
726     {
727         lError = RegSetValueExW(KeyHandle,
728                                 L"srvcomment",
729                                 0,
730                                 REG_SZ,
731                                 (PBYTE)NewComputerDescription,
732                                 (wcslen(NewComputerDescription) + 1) * sizeof(WCHAR));
733     }
734 
735 done:
736     if (KeyHandle != NULL)
737         RegCloseKey(KeyHandle);
738 
739     return lError;
740 }
741 
742 static INT_PTR CALLBACK
743 NetIDPageProc(IN HWND hwndDlg,
744               IN UINT uMsg,
745               IN WPARAM wParam,
746               IN LPARAM lParam)
747 {
748     PNETIDDATA pNetIdData;
749 
750     pNetIdData = (PNETIDDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
751 
752     switch (uMsg)
753     {
754         case WM_INITDIALOG:
755             pNetIdData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETIDDATA));
756             if (pNetIdData != NULL)
757             {
758                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pNetIdData);
759                 GetComputerNames(pNetIdData);
760                 SetFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
761                 NetIDPage_OnInitDialog(hwndDlg, pNetIdData);
762                 pNetIdData->bEnable = TRUE;
763                 CheckForChangedNames(hwndDlg, pNetIdData);
764             }
765             return TRUE;
766 
767         case WM_NOTIFY:
768             switch (((LPNMHDR)lParam)->code)
769             {
770                 case PSN_APPLY:
771                     NetIDPage_OnApply(hwndDlg);
772                     break;
773             }
774             break;
775 
776         case WM_COMMAND:
777             switch (LOWORD(wParam))
778             {
779                 case IDC_COMPDESC:
780                     if (HIWORD(wParam) == EN_CHANGE && pNetIdData->bEnable == TRUE)
781                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
782                     break;
783 
784                 case IDC_NETWORK_PROPERTY:
785                     if (DialogBoxParam(hDllInstance,
786                                        MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE),
787                                        hwndDlg,
788                                        NetworkPropDlgProc,
789                                        (LPARAM)pNetIdData))
790                     {
791                         UpdateFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
792                         CheckForChangedNames(hwndDlg, pNetIdData);
793                     }
794                     break;
795             }
796             break;
797 
798         case WM_DESTROY:
799             if (pNetIdData != NULL)
800             {
801                 if (pNetIdData->JoinName != NULL)
802                     NetApiBufferFree(pNetIdData->JoinName);
803                 HeapFree(GetProcessHeap(), 0, pNetIdData);
804                 pNetIdData = NULL;
805                 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
806             }
807             break;
808     }
809 
810     return FALSE;
811 }
812 
813 HPROPSHEETPAGE WINAPI
814 CreateNetIDPropertyPage(VOID)
815 {
816     PROPSHEETPAGE psp = {0};
817 
818     psp.dwSize = sizeof(psp);
819     psp.dwFlags = PSP_DEFAULT;
820     psp.hInstance = hDllInstance;
821     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGECOMPUTER);
822     psp.pfnDlgProc = NetIDPageProc;
823 
824     return CreatePropertySheetPage(&psp);
825 }
826 
827 BOOL WINAPI
828 DllMain(IN HINSTANCE hinstDLL,
829         IN DWORD dwReason,
830         IN LPVOID lpvReserved)
831 {
832     switch (dwReason)
833     {
834         case DLL_PROCESS_ATTACH:
835             hDllInstance = hinstDLL;
836             DisableThreadLibraryCalls(hinstDLL);
837             break;
838     }
839 
840     return TRUE;
841 }
842