Reactos
at listview 317 lines 6.3 kB view raw
1/* 2 * PROJECT: FreeLoader 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: "Poor-man" boot-time National Language Support (NLS) functions. 5 * COPYRIGHT: Copyright 2022 Hermès Bélusca-Maïto 6 * 7 * NOTE: This code is used at boot-time when no NLS tables are loaded. 8 * Adapted from lib/rtl/nls.c 9 */ 10 11/* INCLUDES ******************************************************************/ 12 13#include <rtl.h> 14 15/* GLOBALS *******************************************************************/ 16 17BOOLEAN NlsMbCodePageTag = FALSE; 18 19BOOLEAN NlsMbOemCodePageTag = FALSE; 20PUSHORT NlsOemToUnicodeTable = NULL; 21PCHAR NlsUnicodeToOemTable = NULL; 22PUSHORT NlsUnicodeToMbOemTable = NULL; 23PUSHORT NlsOemLeadByteInfo = NULL; 24 25USHORT NlsOemDefaultChar = '\0'; 26USHORT NlsUnicodeDefaultChar = 0; 27 28/* FUNCTIONS *****************************************************************/ 29 30WCHAR 31NTAPI 32RtlpDowncaseUnicodeChar( 33 _In_ WCHAR Source) 34{ 35 USHORT Offset = 0; 36 37 if (Source < L'A') 38 return Source; 39 40 if (Source <= L'Z') 41 return Source + (L'a' - L'A'); 42 43#if 0 44 if (Source < 0x80) 45 return Source; 46#endif 47 48 return Source + (SHORT)Offset; 49} 50 51WCHAR 52NTAPI 53RtlDowncaseUnicodeChar( 54 _In_ WCHAR Source) 55{ 56 return RtlpDowncaseUnicodeChar(Source); 57} 58 59_Use_decl_annotations_ 60NTSTATUS 61NTAPI 62RtlMultiByteToUnicodeN( 63 _Out_ PWCH UnicodeString, 64 _In_ ULONG UnicodeSize, 65 _Out_opt_ PULONG ResultSize, 66 _In_ PCCH MbString, 67 _In_ ULONG MbSize) 68{ 69 ULONG Size = 0; 70 ULONG i; 71 72 /* single-byte code page */ 73 if (MbSize > (UnicodeSize / sizeof(WCHAR))) 74 Size = UnicodeSize / sizeof(WCHAR); 75 else 76 Size = MbSize; 77 78 if (ResultSize) 79 *ResultSize = Size * sizeof(WCHAR); 80 81 for (i = 0; i < Size; i++) 82 { 83 /* Trivially zero-extend */ 84 UnicodeString[i] = (WCHAR)MbString[i]; 85 } 86 87 return STATUS_SUCCESS; 88} 89 90_Use_decl_annotations_ 91NTSTATUS 92NTAPI 93RtlMultiByteToUnicodeSize( 94 _Out_ PULONG UnicodeSize, 95 _In_ PCCH MbString, 96 _In_ ULONG MbSize) 97{ 98 /* single-byte code page */ 99 *UnicodeSize = MbSize * sizeof(WCHAR); 100 101 return STATUS_SUCCESS; 102} 103 104_Use_decl_annotations_ 105NTSTATUS 106NTAPI 107RtlUnicodeToMultiByteN( 108 _Out_ PCHAR MbString, 109 _In_ ULONG MbSize, 110 _Out_opt_ PULONG ResultSize, 111 _In_ PCWCH UnicodeString, 112 _In_ ULONG UnicodeSize) 113{ 114 ULONG Size = 0; 115 ULONG i; 116 117 /* single-byte code page */ 118 Size = (UnicodeSize > (MbSize * sizeof(WCHAR))) 119 ? MbSize : (UnicodeSize / sizeof(WCHAR)); 120 121 if (ResultSize) 122 *ResultSize = Size; 123 124 for (i = 0; i < Size; i++) 125 { 126 /* Check for characters that cannot be trivially demoted to ANSI */ 127 if (*((PCHAR)UnicodeString + 1) == 0) 128 { 129 *MbString++ = (CHAR)*UnicodeString++; 130 } 131 else 132 { 133 /* Invalid character, use default */ 134 *MbString++ = NlsOemDefaultChar; 135 UnicodeString++; 136 } 137 } 138 139 return STATUS_SUCCESS; 140} 141 142_Use_decl_annotations_ 143NTSTATUS 144NTAPI 145RtlUnicodeToMultiByteSize( 146 _Out_ PULONG MbSize, 147 _In_ PCWCH UnicodeString, 148 _In_ ULONG UnicodeSize) 149{ 150 ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR); 151 152 /* single-byte code page */ 153 *MbSize = UnicodeLength; 154 155 return STATUS_SUCCESS; 156} 157 158WCHAR 159NTAPI 160RtlpUpcaseUnicodeChar( 161 _In_ WCHAR Source) 162{ 163 USHORT Offset = 0; 164 165 if (Source < 'a') 166 return Source; 167 168 if (Source <= 'z') 169 return (Source - ('a' - 'A')); 170 171 return Source + (SHORT)Offset; 172} 173 174WCHAR 175NTAPI 176RtlUpcaseUnicodeChar( 177 _In_ WCHAR Source) 178{ 179 return RtlpUpcaseUnicodeChar(Source); 180} 181 182_Use_decl_annotations_ 183NTSTATUS 184NTAPI 185RtlUpcaseUnicodeToMultiByteN( 186 _Out_ PCHAR MbString, 187 _In_ ULONG MbSize, 188 _Out_opt_ PULONG ResultSize, 189 _In_ PCWCH UnicodeString, 190 _In_ ULONG UnicodeSize) 191{ 192 WCHAR UpcaseChar; 193 ULONG Size = 0; 194 ULONG i; 195 196 /* single-byte code page */ 197 if (UnicodeSize > (MbSize * sizeof(WCHAR))) 198 Size = MbSize; 199 else 200 Size = UnicodeSize / sizeof(WCHAR); 201 202 if (ResultSize) 203 *ResultSize = Size; 204 205 for (i = 0; i < Size; i++) 206 { 207 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 208 209 /* Check for characters that cannot be trivially demoted to ANSI */ 210 if (*((PCHAR)&UpcaseChar + 1) == 0) 211 { 212 *MbString = (CHAR)UpcaseChar; 213 } 214 else 215 { 216 /* Invalid character, use default */ 217 *MbString = NlsOemDefaultChar; 218 } 219 220 MbString++; 221 UnicodeString++; 222 } 223 224 return STATUS_SUCCESS; 225} 226 227CHAR 228NTAPI 229RtlUpperChar( 230 _In_ CHAR Source) 231{ 232 /* Check for simple ANSI case */ 233 if (Source <= 'z') 234 { 235 /* Check for simple downcase a-z case */ 236 if (Source >= 'a') 237 { 238 /* Just XOR with the difference */ 239 return Source ^ ('a' - 'A'); 240 } 241 else 242 { 243 /* Otherwise return the same char, it's already upcase */ 244 return Source; 245 } 246 } 247 else 248 { 249 /* single-byte code page */ 250 return (CHAR)RtlpUpcaseUnicodeChar((WCHAR)Source); 251 } 252} 253 254 255/** 256 * Stubbed OEM helpers that should not be used in the OS boot loader, 257 * but are necessary for linking with the rest of the RTL unicode.c. 258 **/ 259 260_Use_decl_annotations_ 261NTSTATUS 262NTAPI 263RtlUnicodeToOemN( 264 _Out_ PCHAR OemString, 265 _In_ ULONG OemSize, 266 _Out_opt_ PULONG ResultSize, 267 _In_ PCWCH UnicodeString, 268 _In_ ULONG UnicodeSize) 269{ 270 if (OemSize) 271 *OemString = ANSI_NULL; 272 273 if (ResultSize) 274 *ResultSize = 0; 275 276 return STATUS_NOT_IMPLEMENTED; 277} 278 279_Use_decl_annotations_ 280NTSTATUS 281NTAPI 282RtlOemToUnicodeN( 283 _Out_ PWCHAR UnicodeString, 284 _In_ ULONG UnicodeSize, 285 _Out_opt_ PULONG ResultSize, 286 _In_ PCCH OemString, 287 _In_ ULONG OemSize) 288{ 289 if (UnicodeString) 290 *UnicodeString = UNICODE_NULL; 291 292 if (ResultSize) 293 *ResultSize = 0; 294 295 return STATUS_NOT_IMPLEMENTED; 296} 297 298_Use_decl_annotations_ 299NTSTATUS 300NTAPI 301RtlUpcaseUnicodeToOemN( 302 _Out_ PCHAR OemString, 303 _In_ ULONG OemSize, 304 _Out_opt_ PULONG ResultSize, 305 _In_ PCWCH UnicodeString, 306 _In_ ULONG UnicodeSize) 307{ 308 if (OemSize) 309 *OemString = ANSI_NULL; 310 311 if (ResultSize) 312 *ResultSize = 0; 313 314 return STATUS_NOT_IMPLEMENTED; 315} 316 317/* EOF */