[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.
This commit is contained in:
Timo Kreuzer
2025-07-31 02:04:45 +03:00
parent 36696585ae
commit 5cbb2c9a4c
4 changed files with 36 additions and 2 deletions

View File

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

View File

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

View File

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

View File

@@ -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 <timo.kreuzer@reactos.org>
*/
#define WIN32_NO_STATUS
#include <windef.h>
#include <ndk/rtlfuncs.h>
_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;
}