[NETID] Implement DNS suffix and NetBIOS computer name support

- 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.
This commit is contained in:
Eric Kohl 2020-01-26 09:57:55 +01:00
parent 8381e29467
commit 6a67450893
2 changed files with 338 additions and 155 deletions

View 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)

View 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>
@ -23,32 +24,145 @@
#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;
case NetSetupWorkgroupName:
SetDlgItemText(hDlg, 1007, JoinName);
SetRadioBtnState(hDlg, FALSE);
break;
case NetSetupUnjoined:
break;
case NetSetupUnknownStatus:
default:
{
SetRadioBtnState(hDlg, FALSE);
if (NetWkstaGetInfo(NULL,
101,
(LPBYTE*)&wki) == NERR_Success)
{
SetDlgItemText(hDlg,
1007,
wki->wki101_langroup);
}
else DisableControls(hDlg);
if (wki) NetApiBufferFree(wki);
break;
}
DisableControls(hDlg);
}
if (JoinName) NetApiBufferFree(JoinName);
}
if (wki)
NetApiBufferFree(wki);
break;
}
break;
if (JoinName)
NetApiBufferFree(JoinName);
}
}
static
BOOL
NetworkDlg_OnOK(
HWND hDlg,
PNETIDDATA pNetIdData)
{
WCHAR szMsgText[MAX_PATH], szMsgTitle[MAX_PATH];
if (pNetIdData->bHostNameChanged)
{
if (!IsValidComputerName(hDlg, 1002))
{
SetFocus(GetDlgItem(hDlg, 1002));
return FALSE;
}
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;
}
}
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);
if (DialogBoxParam(hDllInstance,
MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
hDlg,
DNSSuffixPropDlgProc,
(LPARAM)pNetIdData))
{
UpdateFullComputerName(hDlg, 1001, pNetIdData);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
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 (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);
}
}
}
}
EndDialog(hDlg, LOWORD(wParam));
}
break;
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