[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}) add_library(netid MODULE ${SOURCE})
set_module_type(netid win32dll UNICODE) 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) add_cd_file(TARGET netid DESTINATION reactos/system32 FOR all)

View file

@ -14,6 +14,7 @@
#include <winbase.h> #include <winbase.h>
#include <winuser.h> #include <winuser.h>
#include <winreg.h> #include <winreg.h>
#include <windns.h>
#include <tchar.h> #include <tchar.h>
#include <lm.h> #include <lm.h>
#include <prsht.h> #include <prsht.h>
@ -23,32 +24,145 @@
#define MAX_COMPUTERDESCRIPTION_LENGTH 256 #define MAX_COMPUTERDESCRIPTION_LENGTH 256
static INT_PTR CALLBACK typedef struct _NETIDDATA
NetIDPageProc(IN HWND hwndDlg, {
IN UINT uMsg, WCHAR szHostName[256];
IN WPARAM wParam, WCHAR szDomainName[256];
IN LPARAM lParam); WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
BOOL bHostNameChanged;
BOOL bDomainNameChanged;
BOOL bEnable;
} NETIDDATA, *PNETIDDATA;
static HINSTANCE hDllInstance; 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 static
INT_PTR CALLBACK INT_PTR CALLBACK
DNSSuffixPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) DNSSuffixPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{ {
PNETIDDATA pNetIdData;
pNetIdData = (PNETIDDATA)GetWindowLongPtr(hDlg, DWLP_USER);
switch (Msg) 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: case WM_COMMAND:
{
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDCANCEL: case 1011:
if (HIWORD(wParam) == EN_CHANGE)
{
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
break;
case IDOK: 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;
break;
} }
return FALSE; return FALSE;
@ -74,10 +188,15 @@ DisableControls(HWND hDlg)
static static
BOOL BOOL
IsValidComputerName(LPCWSTR s) IsValidComputerName(
HWND hDlg,
UINT uId)
{ {
WCHAR szMsgText[512], szText[256], s[256];
int i; int i;
GetWindowText(GetDlgItem(hDlg, uId), s, ARRAYSIZE(s));
for (i = 0; i <= wcslen(s); i++) for (i = 0; i <= wcslen(s); i++)
{ {
if (s[i] == L'!' || s[i] == L'@' || s[i] == L'#' || s[i] == L'$' 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']' || 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 FALSE;
}
} }
return TRUE; return TRUE;
} }
static static
INT_PTR CALLBACK VOID
NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) 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; SetDlgItemText(hDlg,
DWORD Size = MAX_COMPUTERNAME_LENGTH + 1; 1007,
TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; wki->wki101_langroup);
TCHAR MsgText[MAX_PATH * 2]; }
LPWSTR JoinName; else
NETSETUP_JOIN_STATUS JoinStatus; {
DisableControls(hDlg);
}
if (LoadString(hDllInstance, 25, MsgText, sizeof(MsgText) / sizeof(TCHAR))) if (wki)
SetDlgItemText(hDlg, 1017, MsgText); 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)) case NetSetupUnjoined:
{ break;
SetDlgItemText(hDlg, 1002, ComputerName);
SetDlgItemText(hDlg, 1001, ComputerName);
}
if (NetGetJoinInformation(NULL, &JoinName, &JoinStatus) != NERR_Success) case NetSetupUnknownStatus:
{ default:
SetRadioBtnState(hDlg, FALSE); SetRadioBtnState(hDlg, FALSE);
if (NetWkstaGetInfo(NULL, if (NetWkstaGetInfo(NULL,
@ -132,63 +315,92 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
1007, 1007,
wki->wki101_langroup); wki->wki101_langroup);
} }
else DisableControls(hDlg); else
if (wki) NetApiBufferFree(wki);
}
else
{
switch (JoinStatus)
{ {
case NetSetupDomainName: DisableControls(hDlg);
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;
}
} }
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: case WM_COMMAND:
{
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case 1002: case 1002:
if (HIWORD(wParam) == EN_CHANGE) if (HIWORD(wParam) == EN_CHANGE)
{ {
TCHAR szText[MAX_COMPUTERNAME_LENGTH + 1]; UpdateFullComputerName(hDlg, 1001, pNetIdData);
pNetIdData->bHostNameChanged = TRUE;
GetWindowText(GetDlgItem(hDlg, 1002), szText, MAX_COMPUTERNAME_LENGTH + 1); EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
SetDlgItemText(hDlg, 1001, szText);
} }
break; break;
@ -201,70 +413,27 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
break; break;
case 1003: case 1003:
DialogBox(hDllInstance, if (DialogBoxParam(hDllInstance,
MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS), MAKEINTRESOURCE(IDD_PROPPAGEDNSANDNETBIOS),
hDlg, hDlg,
DNSSuffixPropDlgProc); DNSSuffixPropDlgProc,
(LPARAM)pNetIdData))
{
UpdateFullComputerName(hDlg, 1001, pNetIdData);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
break; break;
case IDOK: case IDOK:
{ if (NetworkDlg_OnOK(hDlg, pNetIdData))
DWORD Size = MAX_COMPUTERNAME_LENGTH + 1; EndDialog(hDlg, TRUE);
TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; break;
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;
case IDCANCEL: case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam)); EndDialog(hDlg, FALSE);
break; break;
} }
} break;
break;
} }
return FALSE; return FALSE;
@ -273,12 +442,11 @@ NetworkPropDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
static static
VOID VOID
NetIDPage_OnInitDialog( NetIDPage_OnInitDialog(
HWND hwndDlg) HWND hwndDlg,
PNETIDDATA pNetIdData)
{ {
WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1]; WCHAR ComputerDescription[MAX_COMPUTERDESCRIPTION_LENGTH + 1];
WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD RegSize = sizeof(ComputerDescription); DWORD RegSize = sizeof(ComputerDescription);
DWORD Size = MAX_COMPUTERNAME_LENGTH + 1;
HKEY KeyHandle; HKEY KeyHandle;
LPWKSTA_INFO_101 wki; LPWKSTA_INFO_101 wki;
LONG lError; LONG lError;
@ -308,11 +476,6 @@ NetIDPage_OnInitDialog(
RegCloseKey(KeyHandle); RegCloseKey(KeyHandle);
} }
if (GetComputerName(ComputerName, &Size))
{
SetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName);
}
if (NetWkstaGetInfo(NULL, 101, (LPBYTE*)&wki) == NERR_Success) if (NetWkstaGetInfo(NULL, 101, (LPBYTE*)&wki) == NERR_Success)
{ {
SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN_NAME, wki->wki101_langroup); SetDlgItemText(hwndDlg, IDC_WORKGROUPDOMAIN_NAME, wki->wki101_langroup);
@ -383,16 +546,23 @@ NetIDPageProc(IN HWND hwndDlg,
IN WPARAM wParam, IN WPARAM wParam,
IN LPARAM lParam) IN LPARAM lParam)
{ {
static BOOL bEnable = FALSE; PNETIDDATA pNetIdData;
INT_PTR Ret = 0;
pNetIdData = (PNETIDDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg) switch (uMsg)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
NetIDPage_OnInitDialog(hwndDlg); pNetIdData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETIDDATA));
bEnable = TRUE; if (pNetIdData != NULL)
Ret = TRUE; {
break; 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: case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) switch (((LPNMHDR)lParam)->code)
@ -407,21 +577,34 @@ NetIDPageProc(IN HWND hwndDlg,
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDC_COMPDESC: case IDC_COMPDESC:
if (HIWORD(wParam) == EN_CHANGE && bEnable == TRUE) if (HIWORD(wParam) == EN_CHANGE && pNetIdData->bEnable == TRUE)
PropSheet_Changed(GetParent(hwndDlg), hwndDlg); PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break; break;
case IDC_NETWORK_PROPERTY: case IDC_NETWORK_PROPERTY:
DialogBox(hDllInstance, if (DialogBoxParam(hDllInstance,
MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE), MAKEINTRESOURCE(IDD_PROPPAGECOMPNAMECHENGE),
hwndDlg, hwndDlg,
NetworkPropDlgProc); NetworkPropDlgProc,
(LPARAM)pNetIdData))
{
UpdateFullComputerName(hwndDlg, IDC_COMPUTERNAME, pNetIdData);
}
break; break;
} }
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 HPROPSHEETPAGE WINAPI