[KERNEL32] Improve SetComputerNameExW (#3171)

Reduce failures of kernel32_apitest SetComputerNameExW testcase and improve SetComputerNameExW.
This commit is contained in:
Katayama Hirofumi MZ 2020-09-17 23:51:47 +09:00 committed by GitHub
parent 8c87489a43
commit 378b26ce27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -21,16 +21,19 @@
* PROJECT: ReactOS system libraries
* PURPOSE: Computer name functions
* FILE: dll/win32/kernel32/client/compname.c
* PROGRAMER: Eric Kohl
* PROGRAMERS: Eric Kohl
* Katayama Hirofumi MZ
*/
/* INCLUDES ******************************************************************/
#include <k32.h>
#include <windns.h>
#define NDEBUG
#include <debug.h>
typedef NTSTATUS (WINAPI *FN_DnsValidateName_W)(LPCWSTR, DNS_NAME_FORMAT);
/* FUNCTIONS *****************************************************************/
@ -451,6 +454,31 @@ GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
return ret;
}
static
BOOL
BaseVerifyDnsName(LPCWSTR lpDnsName)
{
HINSTANCE hDNSAPI;
FN_DnsValidateName_W fnValidate;
NTSTATUS Status;
BOOL ret = FALSE;
hDNSAPI = LoadLibraryW(L"dnsapi.dll");
if (hDNSAPI == NULL)
return FALSE;
fnValidate = (FN_DnsValidateName_W)GetProcAddress(hDNSAPI, "DnsValidateName_W");
if (fnValidate)
{
Status = (*fnValidate)(lpDnsName, DnsNameHostnameLabel);
if (Status == STATUS_SUCCESS || Status == DNS_ERROR_NON_RFC_NAME)
ret = TRUE;
}
FreeLibrary(hDNSAPI);
return ret;
}
/*
* @implemented
@ -460,40 +488,57 @@ BOOL
IsValidComputerName(COMPUTER_NAME_FORMAT NameType,
LPCWSTR lpComputerName)
{
PWCHAR p;
ULONG Length;
size_t Length;
static const WCHAR s_szInvalidChars[] =
L"\"/\\[]:|<>+=;,?"
L"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
/* FIXME: do verification according to NameType */
if (lpComputerName == NULL)
return FALSE;
Length = 0;
p = (PWCHAR)lpComputerName;
#define MAX_COMPUTER_NAME_EX 64
/* Get string length */
if (!NT_SUCCESS(RtlStringCchLengthW(lpComputerName, MAX_COMPUTER_NAME_EX + 1, &Length)))
return FALSE;
#undef MAX_COMPUTER_NAME_EX
while (*p != 0)
/* An empty name is invalid, except a DNS name */
if (Length == 0 && NameType != ComputerNamePhysicalDnsDomain)
return FALSE;
/* Leading or trailing spaces are invalid */
if (Length > 0 &&
(lpComputerName[0] == L' ' || lpComputerName[Length - 1] == L' '))
{
if (!(iswctype(*p, _ALPHA | _DIGIT) || *p == L'!' || *p == L'@' || *p == L'#' ||
*p == L'$' || *p == L'%' || *p == L'^' || *p == L'&' || *p == L'\'' ||
*p == L')' || *p == L'(' || *p == L'.' || *p == L'-' || *p == L'_' ||
*p == L'{' || *p == L'}' || *p == L'~'))
return FALSE;
Length++;
p++;
return FALSE;
}
if (NameType == ComputerNamePhysicalDnsDomain)
return TRUE;
if (Length == 0)
/* Check whether the name contains any invalid character */
if (wcscspn(lpComputerName, s_szInvalidChars) < Length)
return FALSE;
if (NameType == ComputerNamePhysicalNetBIOS &&
Length > MAX_COMPUTERNAME_LENGTH)
return FALSE;
switch (NameType)
{
case ComputerNamePhysicalNetBIOS:
if (Length > MAX_COMPUTERNAME_LENGTH)
return FALSE;
return TRUE;
return TRUE;
case ComputerNamePhysicalDnsDomain:
/* An empty DNS name is valid */
if (Length != 0)
return BaseVerifyDnsName(lpComputerName);
return TRUE;
case ComputerNamePhysicalDnsHostname:
return BaseVerifyDnsName(lpComputerName);
default:
return FALSE;
}
}
static
BOOL
SetComputerNameToRegistry(LPCWSTR RegistryKey,
@ -547,6 +592,7 @@ SetComputerNameToRegistry(LPCWSTR RegistryKey,
NtFlushKey(KeyHandle);
NtClose(KeyHandle);
SetLastError(ERROR_SUCCESS);
return TRUE;
}
@ -637,7 +683,7 @@ SetComputerNameExW(COMPUTER_NAME_FORMAT NameType,
lpBuffer);
default:
SetLastError (ERROR_INVALID_PARAMETER);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}