https://git.reactos.org/?p=reactos.git;a=commitdiff;h=378b26ce2714c8039e239…
commit 378b26ce2714c8039e23932e0fa4e365c149c106
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Sep 17 23:51:47 2020 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Sep 17 23:51:47 2020 +0900
[KERNEL32] Improve SetComputerNameExW (#3171)
Reduce failures of kernel32_apitest SetComputerNameExW testcase and improve
SetComputerNameExW.
---
dll/win32/kernel32/client/compname.c | 96 ++++++++++++++++++++++++++----------
1 file changed, 71 insertions(+), 25 deletions(-)
diff --git a/dll/win32/kernel32/client/compname.c b/dll/win32/kernel32/client/compname.c
index 46d05e78d32..2b4b335d4f7 100644
--- a/dll/win32/kernel32/client/compname.c
+++ b/dll/win32/kernel32/client/compname.c
@@ -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,39 +488,56 @@ 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)
- {
- 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;
+ /* An empty name is invalid, except a DNS name */
+ if (Length == 0 && NameType != ComputerNamePhysicalDnsDomain)
+ return FALSE;
- Length++;
- p++;
+ /* Leading or trailing spaces are invalid */
+ if (Length > 0 &&
+ (lpComputerName[0] == L' ' || lpComputerName[Length - 1] == L'
'))
+ {
+ 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
@@ -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;
}
}