Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318/* * PROJECT: FreeLoader * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: "Poor-man" boot-time National Language Support (NLS) functions. * COPYRIGHT: Copyright 2022 Hermès Bélusca-Maïto * * NOTE: This code is used at boot-time when no NLS tables are loaded. * Adapted from lib/rtl/nls.c */
/* INCLUDES ******************************************************************/
#include <rtl.h>
/* GLOBALS *******************************************************************/
BOOLEAN NlsMbCodePageTag = FALSE;
BOOLEAN NlsMbOemCodePageTag = FALSE;PUSHORT NlsOemToUnicodeTable = NULL;PCHAR NlsUnicodeToOemTable = NULL;PUSHORT NlsUnicodeToMbOemTable = NULL;PUSHORT NlsOemLeadByteInfo = NULL;
USHORT NlsOemDefaultChar = '\0';USHORT NlsUnicodeDefaultChar = 0;
/* FUNCTIONS *****************************************************************/
WCHARNTAPIRtlpDowncaseUnicodeChar( _In_ WCHAR Source){ USHORT Offset = 0;
if (Source < L'A') return Source;
if (Source <= L'Z') return Source + (L'a' - L'A');
#if 0 if (Source < 0x80) return Source;#endif
return Source + (SHORT)Offset;}
WCHARNTAPIRtlDowncaseUnicodeChar( _In_ WCHAR Source){ return RtlpDowncaseUnicodeChar(Source);}
_Use_decl_annotations_NTSTATUSNTAPIRtlMultiByteToUnicodeN( _Out_ PWCH UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH MbString, _In_ ULONG MbSize){ ULONG Size = 0; ULONG i;
/* single-byte code page */ if (MbSize > (UnicodeSize / sizeof(WCHAR))) Size = UnicodeSize / sizeof(WCHAR); else Size = MbSize;
if (ResultSize) *ResultSize = Size * sizeof(WCHAR);
for (i = 0; i < Size; i++) { /* Trivially zero-extend */ UnicodeString[i] = (WCHAR)MbString[i]; }
return STATUS_SUCCESS;}
_Use_decl_annotations_NTSTATUSNTAPIRtlMultiByteToUnicodeSize( _Out_ PULONG UnicodeSize, _In_ PCCH MbString, _In_ ULONG MbSize){ /* single-byte code page */ *UnicodeSize = MbSize * sizeof(WCHAR);
return STATUS_SUCCESS;}
_Use_decl_annotations_NTSTATUSNTAPIRtlUnicodeToMultiByteN( _Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize){ ULONG Size = 0; ULONG i;
/* single-byte code page */ Size = (UnicodeSize > (MbSize * sizeof(WCHAR))) ? MbSize : (UnicodeSize / sizeof(WCHAR));
if (ResultSize) *ResultSize = Size;
for (i = 0; i < Size; i++) { /* Check for characters that cannot be trivially demoted to ANSI */ if (*((PCHAR)UnicodeString + 1) == 0) { *MbString++ = (CHAR)*UnicodeString++; } else { /* Invalid character, use default */ *MbString++ = NlsOemDefaultChar; UnicodeString++; } }
return STATUS_SUCCESS;}
_Use_decl_annotations_NTSTATUSNTAPIRtlUnicodeToMultiByteSize( _Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize){ ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR);
/* single-byte code page */ *MbSize = UnicodeLength;
return STATUS_SUCCESS;}
WCHARNTAPIRtlpUpcaseUnicodeChar( _In_ WCHAR Source){ USHORT Offset = 0;
if (Source < 'a') return Source;
if (Source <= 'z') return (Source - ('a' - 'A'));
return Source + (SHORT)Offset;}
WCHARNTAPIRtlUpcaseUnicodeChar( _In_ WCHAR Source){ return RtlpUpcaseUnicodeChar(Source);}
_Use_decl_annotations_NTSTATUSNTAPIRtlUpcaseUnicodeToMultiByteN( _Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize){ WCHAR UpcaseChar; ULONG Size = 0; ULONG i;
/* single-byte code page */ if (UnicodeSize > (MbSize * sizeof(WCHAR))) Size = MbSize; else Size = UnicodeSize / sizeof(WCHAR);
if (ResultSize) *ResultSize = Size;
for (i = 0; i < Size; i++) { UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString);
/* Check for characters that cannot be trivially demoted to ANSI */ if (*((PCHAR)&UpcaseChar + 1) == 0) { *MbString = (CHAR)UpcaseChar; } else { /* Invalid character, use default */ *MbString = NlsOemDefaultChar; }
MbString++; UnicodeString++; }
return STATUS_SUCCESS;}
CHARNTAPIRtlUpperChar( _In_ CHAR Source){ /* Check for simple ANSI case */ if (Source <= 'z') { /* Check for simple downcase a-z case */ if (Source >= 'a') { /* Just XOR with the difference */ return Source ^ ('a' - 'A'); } else { /* Otherwise return the same char, it's already upcase */ return Source; } } else { /* single-byte code page */ return (CHAR)RtlpUpcaseUnicodeChar((WCHAR)Source); }}
/** * Stubbed OEM helpers that should not be used in the OS boot loader, * but are necessary for linking with the rest of the RTL unicode.c. **/
_Use_decl_annotations_NTSTATUSNTAPIRtlUnicodeToOemN( _Out_ PCHAR OemString, _In_ ULONG OemSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize){ if (OemSize) *OemString = ANSI_NULL;
if (ResultSize) *ResultSize = 0;
return STATUS_NOT_IMPLEMENTED;}
_Use_decl_annotations_NTSTATUSNTAPIRtlOemToUnicodeN( _Out_ PWCHAR UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH OemString, _In_ ULONG OemSize){ if (UnicodeString) *UnicodeString = UNICODE_NULL;
if (ResultSize) *ResultSize = 0;
return STATUS_NOT_IMPLEMENTED;}
_Use_decl_annotations_NTSTATUSNTAPIRtlUpcaseUnicodeToOemN( _Out_ PCHAR OemString, _In_ ULONG OemSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize){ if (OemSize) *OemString = ANSI_NULL;
if (ResultSize) *ResultSize = 0;
return STATUS_NOT_IMPLEMENTED;}
/* EOF */