From 5cbb2c9a4c21614bb3bd8a5ddf1d095cbbe6aff0 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 31 Jul 2025 02:04:45 +0300 Subject: [PATCH] [LIBCNTPR] Implement multibyte NT version of toupper Windows ntdll and ntoskrnl export a multibyte capable version of toupper (not tolower though!) The internal version is kept as it is, because the multibyte version requires unicode tables to be set up and doesn't support IRQL > APC_LEVEL. Why though would toupper (but not tolower) support raw, undecoded multibyte characters, you might ask. Well I don't know, but someone at MS must have decided that this is a good idea, and winetests show this is how it behaves. --- dll/ntdll/def/ntdll.spec | 2 +- ntoskrnl/ntoskrnl.spec | 2 +- sdk/lib/crt/string/string.cmake | 1 + sdk/lib/crt/string/toupper_nt_mb.c | 33 ++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 sdk/lib/crt/string/toupper_nt_mb.c diff --git a/dll/ntdll/def/ntdll.spec b/dll/ntdll/def/ntdll.spec index b7a9ef7851f..cef403e8842 100644 --- a/dll/ntdll/def/ntdll.spec +++ b/dll/ntdll/def/ntdll.spec @@ -1888,7 +1888,7 @@ @ varargs swprintf(ptr wstr) @ cdecl -arch=i386,x86_64 tan(double) @ cdecl tolower(long) -@ cdecl toupper(long) +@ cdecl toupper(long) toupper_nt_mb @ cdecl towlower(long) @ cdecl towupper(long) @ stdcall vDbgPrintEx(long long str ptr) diff --git a/ntoskrnl/ntoskrnl.spec b/ntoskrnl/ntoskrnl.spec index db7d01c16a5..300810317d6 100644 --- a/ntoskrnl/ntoskrnl.spec +++ b/ntoskrnl/ntoskrnl.spec @@ -1623,7 +1623,7 @@ @ cdecl strstr() @ cdecl swprintf() @ cdecl tolower() -@ cdecl toupper() +@ cdecl toupper() toupper_nt_mb @ cdecl towlower() @ cdecl towupper() @ stdcall vDbgPrintEx(long long str ptr) diff --git a/sdk/lib/crt/string/string.cmake b/sdk/lib/crt/string/string.cmake index 214901c548f..5dd203e2117 100644 --- a/sdk/lib/crt/string/string.cmake +++ b/sdk/lib/crt/string/string.cmake @@ -113,6 +113,7 @@ list(APPEND CRT_STRING_ASM_SOURCE list(APPEND LIBCNTPR_STRING_SOURCE string/mbstowcs_nt.c string/tolower_nt.c + string/toupper_nt_mb.c string/towupper_nt.c string/wcstombs_nt.c ) diff --git a/sdk/lib/crt/string/toupper_nt_mb.c b/sdk/lib/crt/string/toupper_nt_mb.c new file mode 100644 index 00000000000..50764523bc6 --- /dev/null +++ b/sdk/lib/crt/string/toupper_nt_mb.c @@ -0,0 +1,33 @@ +/* + * PROJECT: ReactOS NT CRT library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Multibyte capable version of toupper + * COPYRIGHT: Copyright 2025 Timo Kreuzer + */ + +#define WIN32_NO_STATUS +#include +#include + +_Check_return_ +int +__cdecl +toupper_nt_mb(_In_ int _C) +{ + PUCHAR ptr; + WCHAR wc, wcUpper; + CHAR chrUpper[2]; + ULONG mbSize; + + ptr = (PUCHAR)&_C; + wc = RtlAnsiCharToUnicodeChar(&ptr); + wcUpper = RtlUpcaseUnicodeChar(wc); + RtlUnicodeToMultiByteN(chrUpper, 2, &mbSize, &wcUpper, sizeof(WCHAR)); + + if (mbSize == 2) + return (UCHAR)chrUpper[1] + ((UCHAR)chrUpper[0] << 8); + else if (mbSize == 1) + return (UCHAR)chrUpper[0]; + else + return (WCHAR)_C; +}