[NETID] Implement DNS suffix and NetBIOS computer name support
authorEric Kohl <eric.kohl@reactos.org>
Sun, 26 Jan 2020 08:57:55 +0000 (09:57 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 26 Jan 2020 09:04:44 +0000 (10:04 +0100)
- Load and store the non volatile host, domain and computer names instead of the volatile ones.
- Validate the domain name before it is stored.
- Update the full computer name whenever the host or domain name changes.

dll/win32/netid/CMakeLists.txt
dll/win32/netid/netid.c

index 1f3b87f..b3fe761 100644 (file)
@@ -8,5 +8,5 @@ list(APPEND SOURCE
 
 add_library(netid MODULE ${SOURCE})
 set_module_type(netid win32dll UNICODE)
-add_importlibs(netid user32 gdi32 comctl32 advapi32 netapi32 msvcrt kernel32 ntdll)
+add_importlibs(netid user32 gdi32 comctl32 advapi32 netapi32 dnsapi msvcrt kernel32 ntdll)
 add_cd_file(TARGET netid DESTINATION reactos/system32 FOR all)
index a9e30b0..bab3a34 100644 (file)
@@ -14,6 +14,7 @@
 #include <winbase.h>
 #include <winuser.h>
 #include <winreg.h>
+#include <windns.h>
 #include <tchar.h>
 #include <lm.h>
 #include <prsht.h>
 
 #define MAX_COMPUTERDESCRIPTION_LENGTH 256
 
-static INT_PTR CALLBACK
-NetIDPageProc(IN HWND hwndDlg,
-              IN UINT uMsg,
-              IN WPARAM wParam,
-              IN LPARAM lParam);
+typedef struct _NETIDDATA
+{
+    WCHAR szHostName[256];
+    WCHAR szDomainName[256];
+    WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+    BOOL bHostNameChanged;
+    BOOL bDomainNameChanged;
+    BOOL bEnable;
+} NETIDDATA, *PNETIDDATA;
+
 
 static HINSTANCE hDllInstance;
 
+static
+BOOL
+GetComputerNames(
+    PNETIDDATA pNetIdData)
+{
+    HKEY KeyHandle;
+    DWORD dwSize;
+    DWORD dwError;
+
+    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                            L"SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
+                            0,
+                            KEY_QUERY_VALUE,
+                            &KeyHandle);
+    if (dwError == ERROR_SUCCESS)
+    {
+        dwSize = sizeof(pNetIdData->szHostName);
+        RegQueryValueExW(KeyHandle,
+                         L"NV HostName",
+                         0,
+                         NULL,
+                         (LPBYTE)&pNetIdData->szHostName,
+                         &dwSize);
+
+        dwSize = sizeof(pNetIdData->szDomainName);
+        RegQueryValueExW(KeyHandle,
+                         L"NV Domain",
+                         0,
+                         NULL,
+                         (LPBYTE)&pNetIdData->szDomainName,
+                         &dwSize);
+
+        RegCloseKey(KeyHandle);
+    }
+
+    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                            L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName",
+                            0,
+                            KEY_QUERY_VALUE,
+                            &KeyHandle);
+    if (dwError == ERROR_SUCCESS)
+    {
+        dwSize = sizeof(pNetIdData->szComputerName);
+        RegQueryValueExW(KeyHandle,
+                         L"ComputerName",
+                         0,
+                         NULL,
+                         (LPBYTE)&pNetIdData->szComputerName,
+                         &dwSize);
+
+        RegCloseKey(KeyHandle);
+    }
+
+    return TRUE;
+}
+
+static
+BOOL
+IsValidDomainName(
+    HWND hDlg,
+    UINT uId)
+{
+    WCHAR szDomainName[256];
+    DWORD dwError;
+
+    GetDlgItemTextW(hDlg, uId, szDomainName, ARRAYSIZE(szDomainName));
+    dwError = DnsValidateName_W(szDomainName, DnsNameDomain);
+    if (dwError != ERROR_SUCCESS)
+    {
+        /* FIXME: Show error message */
+        return FALSE;
+    }
+
+    return TRUE;
+}
 
 static
 INT_PTR CALLBACK
 DNSSuffixPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
+    PNETIDDATA pNetIdData;
+
+    pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
+
     switch (Msg)
     {
+        case WM_INITDIALOG:
+            pNetIdData = (PNETIDDATA)lParam;
+            if (pNetIdData != NULL)
+            {
+                SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
+
+                SetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName);
+
+                SetDlgItemTextW(hDlg, 1013, pNetIdData->szComputerName);
+                EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
+            }
+            return TRUE;
+
         case WM_COMMAND:
-        {
             switch (LOWORD(wParam))
             {
-                case IDCANCEL:
+                case 1011:
+                    if (HIWORD(wParam) == EN_CHANGE)
+                    {
+                        EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
+                    }
+                    break;
+
                 case IDOK:
-                    EndDialog(hDlg, LOWORD(wParam));
+                    if (!IsValidDomainName(hDlg, 1011))
+                    {
+                        SetFocus(GetDlgItem(hDlg, 1011));
+                        break;
+                    }
+
+                    GetDlgItemTextW(hDlg, 1011, pNetIdData->szDomainName, ARRAYSIZE(pNetIdData->szDomainName));
+                    pNetIdData->bDomainNameChanged = TRUE;
+                    EndDialog(hDlg, TRUE);
+                    break;
+
+                case IDCANCEL:
+                    EndDialog(hDlg, FALSE);
                     break;
             }
-        }
-        break;
+            break;
     }
 
     return FALSE;
@@ -74,10 +188,15 @@ DisableControls(HWND hDlg)
 
 static
 BOOL
-IsValidComputerName(LPCWSTR s)
+IsValidComputerName(
+    HWND hDlg,
+    UINT uId)
 {
+    WCHAR szMsgText[512], szText[256], s[256];
     int i;
 
+    GetWindowText(GetDlgItem(hDlg, uId), s, ARRAYSIZE(s));
+
     for (i = 0; i <= wcslen(s); i++)
     {
         if (s[i] == L'!' || s[i] == L'@' || s[i] == L'#' || s[i] == L'$'
@@ -88,40 +207,104 @@ IsValidComputerName(LPCWSTR s)
             || s[i] == L'<' || s[i] == L'>' || s[i] == L'?' || s[i] == L'['
             || s[i] == L']' || s[i] == L'`' || s[i] == L'%' || s[i] == L'_'
             || s[i] == L'.')
+        {
+            LoadStringW(hDllInstance, 1030, szText, ARRAYSIZE(szText));
+            swprintf(szMsgText, szText, s);
+            MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
             return FALSE;
+        }
     }
 
     return TRUE;
 }
 
 static
-INT_PTR CALLBACK
-NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+VOID
+SetFullComputerName(
+    HWND hDlg,
+    UINT uId,
+    PNETIDDATA pNetIdData)
 {
-    switch (Msg)
+    WCHAR szFullComputerName[512];
+
+    swprintf(szFullComputerName, L"%s.%s", pNetIdData->szHostName, pNetIdData->szDomainName);
+    SetDlgItemText(hDlg, uId, szFullComputerName);
+}
+
+static
+VOID
+UpdateFullComputerName(
+    HWND hDlg,
+    UINT uId,
+    PNETIDDATA pNetIdData)
+{
+    WCHAR szFullComputerName[512];
+    WCHAR szHostName[256];
+
+    GetWindowText(GetDlgItem(hDlg, 1002), szHostName, ARRAYSIZE(szHostName));
+
+    swprintf(szFullComputerName, L"%s.%s", szHostName, pNetIdData->szDomainName);
+    SetDlgItemText(hDlg, uId, szFullComputerName);
+}
+
+static
+VOID
+NetworkDlg_OnInitDialog(
+    HWND hDlg,
+    PNETIDDATA pNetIdData)
+{
+    LPWKSTA_INFO_101 wki = NULL;
+    TCHAR MsgText[MAX_PATH * 2];
+    LPWSTR JoinName = NULL;
+    NETSETUP_JOIN_STATUS JoinStatus;
+
+    if (LoadString(hDllInstance, 25, MsgText, sizeof(MsgText) / sizeof(TCHAR)))
+        SetDlgItemText(hDlg, 1017, MsgText);
+
+//    SendMessage(GetDlgItem(hDlg, 1002), EM_SETLIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
+
+    SetDlgItemText(hDlg, 1002, pNetIdData->szHostName);
+    SetFullComputerName(hDlg, 1001, pNetIdData);
+
+    if (NetGetJoinInformation(NULL, &JoinName, &JoinStatus) != NERR_Success)
     {
-        case WM_INITDIALOG:
+        SetRadioBtnState(hDlg, FALSE);
+
+        if (NetWkstaGetInfo(NULL,
+                            101,
+                            (LPBYTE*)&wki) == NERR_Success)
         {
-            LPWKSTA_INFO_101 wki = NULL;
-            DWORD Size = MAX_COMPUTERNAME_LENGTH + 1;
-            TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
-            TCHAR MsgText[MAX_PATH * 2];
-            LPWSTR JoinName;
-            NETSETUP_JOIN_STATUS JoinStatus;
+            SetDlgItemText(hDlg,
+                           1007,
+                           wki->wki101_langroup);
+        }
+        else
+        {
+            DisableControls(hDlg);
+        }
 
-            if (LoadString(hDllInstance, 25, MsgText, sizeof(MsgText) / sizeof(TCHAR)))
-                SetDlgItemText(hDlg, 1017, MsgText);
+        if (wki)
+            NetApiBufferFree(wki);
+    }
+    else
+    {
+        switch (JoinStatus)
+        {
+            case NetSetupDomainName:
+                SetDlgItemText(hDlg, 116, JoinName);
+                SetRadioBtnState(hDlg, TRUE);
+                break;
 
-            SendMessage(GetDlgItem(hDlg, 1002), EM_SETLIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
+            case NetSetupWorkgroupName:
+                SetDlgItemText(hDlg, 1007, JoinName);
+                SetRadioBtnState(hDlg, FALSE);
+                break;
 
-            if (GetComputerName(ComputerName, &Size))
-            {
-                SetDlgItemText(hDlg, 1002, ComputerName);
-                SetDlgItemText(hDlg, 1001, ComputerName);
-            }
+            case NetSetupUnjoined:
+                break;
 
-            if (NetGetJoinInformation(NULL, &JoinName, &JoinStatus) != NERR_Success)
-            {
+            case NetSetupUnknownStatus:
+            default:
                 SetRadioBtnState(hDlg, FALSE);
 
                 if (NetWkstaGetInfo(NULL,
@@ -132,63 +315,92 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
                                    1007,
                                    wki->wki101_langroup);
                 }
-                else DisableControls(hDlg);
-
-                if (wki) NetApiBufferFree(wki);
-            }
-            else
-            {
-                switch (JoinStatus)
+                else
                 {
-                    case NetSetupDomainName:
-                        SetDlgItemText(hDlg, 116, JoinName);
-                        SetRadioBtnState(hDlg, TRUE);
-                        break;
+                    DisableControls(hDlg);
+                }
 
-                    case NetSetupWorkgroupName:
-                        SetDlgItemText(hDlg, 1007, JoinName);
-                        SetRadioBtnState(hDlg, FALSE);
-                        break;
+                if (wki)
+                    NetApiBufferFree(wki);
+                break;
+        }
 
-                    case NetSetupUnjoined:
-                        break;
+        if (JoinName)
+            NetApiBufferFree(JoinName);
+    }
+}
 
-                    case NetSetupUnknownStatus:
-                    default:
-                    {
-                        SetRadioBtnState(hDlg, FALSE);
+static
+BOOL
+NetworkDlg_OnOK(
+    HWND hDlg,
+    PNETIDDATA pNetIdData)
+{
+    WCHAR szMsgText[MAX_PATH], szMsgTitle[MAX_PATH];
 
-                        if (NetWkstaGetInfo(NULL,
-                                            101,
-                                            (LPBYTE*)&wki) == NERR_Success)
-                        {
-                            SetDlgItemText(hDlg,
-                                           1007,
-                                           wki->wki101_langroup);
-                        }
-                        else DisableControls(hDlg);
-
-                        if (wki) NetApiBufferFree(wki);
-                        break;
-                    }
-                }
+    if (pNetIdData->bHostNameChanged)
+    {
+        if (!IsValidComputerName(hDlg, 1002))
+        {
+            SetFocus(GetDlgItem(hDlg, 1002));
+            return FALSE;
+        }
 
-                if (JoinName) NetApiBufferFree(JoinName);
-            }
+        GetWindowText(GetDlgItem(hDlg, 1002), pNetIdData->szHostName, ARRAYSIZE(pNetIdData->szHostName));
+
+        if (!SetComputerNameExW(ComputerNamePhysicalDnsHostname, pNetIdData->szHostName))
+        {
+            LoadStringW(hDllInstance, 4001, szMsgText, ARRAYSIZE(szMsgText));
+            MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
+            return FALSE;
         }
-        break;
+    }
 
-        case WM_COMMAND:
+    if (pNetIdData->bDomainNameChanged)
+    {
+        if (!SetComputerNameExW(ComputerNamePhysicalDnsDomain, pNetIdData->szDomainName))
         {
+            /* FIXME: Show error message */
+            return FALSE;
+        }
+    }
+
+    LoadStringW(hDllInstance, 4000, szMsgTitle, ARRAYSIZE(szMsgTitle));
+    LoadStringW(hDllInstance, 24, szMsgText, ARRAYSIZE(szMsgText));
+    MessageBoxW(hDlg, szMsgText, szMsgTitle, MB_OK | MB_ICONINFORMATION);
+
+    return TRUE;
+}
+
+static
+INT_PTR CALLBACK
+NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+    PNETIDDATA pNetIdData;
+
+    pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
+
+    switch (Msg)
+    {
+        case WM_INITDIALOG:
+            pNetIdData = (PNETIDDATA)lParam;
+            if (pNetIdData != NULL)
+            {
+                SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pNetIdData);
+                NetworkDlg_OnInitDialog(hDlg, pNetIdData);
+                EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
+            }
+            return TRUE;
+
+        case WM_COMMAND:
             switch (LOWORD(wParam))
             {
                 case 1002:
                     if (HIWORD(wParam) == EN_CHANGE)
                     {
-                        TCHAR szText[MAX_COMPUTERNAME_LENGTH + 1];
-
-                        GetWindowText(GetDlgItem(hDlg, 1002), szText, MAX_COMPUTERNAME_LENGTH + 1);
-                        SetDlgItemText(hDlg, 1001, szText);
+                        UpdateFullComputerName(hDlg, 1001, pNetIdData);
+                        pNetIdData->bHostNameChanged = TRUE;
+                        EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
                     }
                     break;
 
@@ -201,70 +413,27 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
                     break;
 
                 case 1003:
-                    DialogBox(hDllInstance,
-                              MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
-                              hDlg,
-                              DNSSuffixPropDlgProc);
-                    break;
-
-                case IDOK:
-                {
-                    DWORD Size = MAX_COMPUTERNAME_LENGTH + 1;
-                    TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
-                    TCHAR NewComputerName[MAX_COMPUTERNAME_LENGTH + 1];
-
-                    if (GetComputerName(ComputerName, &Size))
+                    if (DialogBoxParam(hDllInstance,
+                                       MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
+                                       hDlg,
+                                       DNSSuffixPropDlgProc,
+                                       (LPARAM)pNetIdData))
                     {
-                        if (GetWindowText(GetDlgItem(hDlg, 1002),
-                                          NewComputerName,
-                                          (MAX_COMPUTERNAME_LENGTH + 1)))
-                        {
-                            if (_tcscmp(ComputerName, NewComputerName) != 0)
-                            {
-                                if (!IsValidComputerName(NewComputerName))
-                                {
-                                    TCHAR szText[MAX_PATH], szMsgText[MAX_PATH];
-
-                                    LoadString(hDllInstance, 1030, szText, sizeof(szText) / sizeof(TCHAR));
-
-                                    swprintf(szMsgText, szText, NewComputerName);
-                                    MessageBox(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
-                                    SetFocus(GetDlgItem(hDlg, 1002));
-                                    break;
-                                }
-                                else if (!SetComputerNameExW(ComputerNamePhysicalDnsHostname, NewComputerName))
-                                {
-                                    TCHAR szMsgText[MAX_PATH];
-
-                                    LoadString(hDllInstance, 4001, szMsgText, sizeof(szMsgText) / sizeof(TCHAR));
-
-                                    MessageBox(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
-                                }
-                                else
-                                {
-                                    TCHAR szMsgTitle[MAX_PATH], szMsgText[MAX_PATH];
-
-                                    LoadString(hDllInstance, 4000, szMsgTitle, sizeof(szMsgTitle) / sizeof(TCHAR));
-                                    LoadString(hDllInstance, 24, szMsgText, sizeof(szMsgText) / sizeof(TCHAR));
-
-                                    MessageBox(hDlg, szMsgText, szMsgTitle, MB_OK | MB_ICONINFORMATION);
-
-                                    NetIDPageProc(GetParent(hDlg), WM_INITDIALOG, 0, 0);
-                                }
-                            }
-                        }
+                        UpdateFullComputerName(hDlg, 1001, pNetIdData);
+                        EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
                     }
+                    break;
 
-                    EndDialog(hDlg, LOWORD(wParam));
-                }
-                break;
+                case IDOK:
+                    if (NetworkDlg_OnOK(hDlg, pNetIdData))
+                        EndDialog(hDlg, TRUE);
+                    break;
 
                 case IDCANCEL:
-                    EndDialog(hDlg, LOWORD(wParam));
+                    EndDialog(hDlg, FALSE);
                     break;
             }
-        }
-        break;
+            break;
     }
 
     return FALSE;
@@ -273,12 +442,11 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
 static
 VOID
 NetIDPage_OnInitDialog(
-    HWND hwndDlg)
+    HWND hwndDlg,
+    PNETIDDATA pNetIdData)
 {
     WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
-    WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD RegSize = sizeof(ComputerDescription);
-    DWORD Size = MAX_COMPUTERNAME_LENGTH + 1;
     HKEY KeyHandle;
     LPWKSTA_INFO_101 wki;
     LONG lError;
@@ -308,11 +476,6 @@ NetIDPage_OnInitDialog(
         RegCloseKey(KeyHandle);
     }
 
-    if (GetComputerName(ComputerName, &Size))
-    {
-        SetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName);
-    }
-
     if (NetWkstaGetInfo(NULL, 101, (LPBYTE*)&wki) == NERR_Success)
     {
         SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN_NAME, wki->wki101_langroup);
@@ -383,16 +546,23 @@ NetIDPageProc(IN HWND hwndDlg,
               IN WPARAM wParam,
               IN LPARAM lParam)
 {
-    static BOOL bEnable = FALSE;
-    INT_PTR Ret = 0;
+    PNETIDDATA pNetIdData;
+
+    pNetIdData = (PNETIDDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
 
     switch (uMsg)
     {
         case WM_INITDIALOG:
-            NetIDPage_OnInitDialog(hwndDlg);
-            bEnable = TRUE;
-            Ret = TRUE;
-            break;
+            pNetIdData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETIDDATA));
+            if (pNetIdData != NULL)
+            {
+                SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pNetIdData);
+                GetComputerNames(pNetIdData);
+                SetFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
+                NetIDPage_OnInitDialog(hwndDlg, pNetIdData);
+                pNetIdData->bEnable = TRUE;
+            }
+            return TRUE;
 
         case WM_NOTIFY:
             switch (((LPNMHDR)lParam)->code)
@@ -407,21 +577,34 @@ NetIDPageProc(IN HWND hwndDlg,
             switch (LOWORD(wParam))
             {
                 case IDC_COMPDESC:
-                    if (HIWORD(wParam) == EN_CHANGE && bEnable == TRUE)
+                    if (HIWORD(wParam) == EN_CHANGE && pNetIdData->bEnable == TRUE)
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                     break;
 
                 case IDC_NETWORK_PROPERTY:
-                    DialogBox(hDllInstance,
-                              MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE),
-                              hwndDlg,
-                              NetworkPropDlgProc);
+                    if (DialogBoxParam(hDllInstance,
+                                       MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE),
+                                       hwndDlg,
+                                       NetworkPropDlgProc,
+                                       (LPARAM)pNetIdData))
+                    {
+                        UpdateFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
+                    }
                     break;
             }
             break;
+
+        case WM_DESTROY:
+            if (pNetIdData != NULL)
+            {
+                HeapFree(GetProcessHeap(), 0, pNetIdData);
+                pNetIdData = NULL;
+                SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
+            }
+            break;
     }
 
-    return Ret;
+    return FALSE;
 }
 
 HPROPSHEETPAGE WINAPI