1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/rtl/nls.c 5 * PURPOSE: National Language Support (NLS) functions 6 * PROGRAMMERS: Emanuele Aliberti 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include <rtl.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* GLOBALS *******************************************************************/ 17 18 PUSHORT NlsUnicodeUpcaseTable = NULL; 19 PUSHORT NlsUnicodeLowercaseTable = NULL; 20 21 USHORT NlsAnsiCodePage = 0; /* exported */ 22 BOOLEAN NlsMbCodePageTag = FALSE; /* exported */ 23 PUSHORT NlsAnsiToUnicodeTable = NULL; 24 PCHAR NlsUnicodeToAnsiTable = NULL; 25 PUSHORT NlsUnicodeToMbAnsiTable = NULL; 26 PUSHORT NlsLeadByteInfo = NULL; /* exported */ 27 28 USHORT NlsOemCodePage = 0; 29 BOOLEAN NlsMbOemCodePageTag = FALSE; /* exported */ 30 PUSHORT NlsOemToUnicodeTable = NULL; 31 PCHAR NlsUnicodeToOemTable = NULL; 32 PUSHORT NlsUnicodeToMbOemTable = NULL; 33 PUSHORT NlsOemLeadByteInfo = NULL; /* exported */ 34 35 USHORT NlsOemDefaultChar = '\0'; 36 USHORT NlsUnicodeDefaultChar = 0; 37 38 39 /* FUNCTIONS *****************************************************************/ 40 41 /* 42 * @unimplemented 43 */ 44 NTSTATUS NTAPI 45 RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP, 46 OUT PWCHAR UnicodeString, 47 IN ULONG UnicodeSize, 48 OUT PULONG ResultSize OPTIONAL, 49 IN PCHAR CustomString, 50 IN ULONG CustomSize) 51 { 52 ULONG Size = 0; 53 ULONG i; 54 55 PAGED_CODE_RTL(); 56 57 if (!CustomCP->DBCSCodePage) 58 { 59 /* single-byte code page */ 60 if (CustomSize > (UnicodeSize / sizeof(WCHAR))) 61 Size = UnicodeSize / sizeof(WCHAR); 62 else 63 Size = CustomSize; 64 65 if (ResultSize) 66 *ResultSize = Size * sizeof(WCHAR); 67 68 for (i = 0; i < Size; i++) 69 { 70 *UnicodeString = CustomCP->MultiByteTable[(UCHAR)*CustomString]; 71 UnicodeString++; 72 CustomString++; 73 } 74 } 75 else 76 { 77 /* multi-byte code page */ 78 /* FIXME */ 79 ASSERT(FALSE); 80 } 81 82 return STATUS_SUCCESS; 83 } 84 85 /* 86 * @implemented 87 */ 88 WCHAR NTAPI 89 RtlpDowncaseUnicodeChar(IN WCHAR Source) 90 { 91 USHORT Offset; 92 93 PAGED_CODE_RTL(); 94 95 if (Source < L'A') 96 return Source; 97 98 if (Source <= L'Z') 99 return Source + (L'a' - L'A'); 100 101 if (Source < 0x80) 102 return Source; 103 104 Offset = ((USHORT)Source >> 8); 105 DPRINT("Offset: %hx\n", Offset); 106 107 Offset = NlsUnicodeLowercaseTable[Offset]; 108 DPRINT("Offset: %hx\n", Offset); 109 110 Offset += (((USHORT)Source & 0x00F0) >> 4); 111 DPRINT("Offset: %hx\n", Offset); 112 113 Offset = NlsUnicodeLowercaseTable[Offset]; 114 DPRINT("Offset: %hx\n", Offset); 115 116 Offset += ((USHORT)Source & 0x000F); 117 DPRINT("Offset: %hx\n", Offset); 118 119 Offset = NlsUnicodeLowercaseTable[Offset]; 120 DPRINT("Offset: %hx\n", Offset); 121 122 DPRINT("Result: %hx\n", Source + (SHORT)Offset); 123 124 return Source + (SHORT)Offset; 125 } 126 127 /* 128 * @implemented 129 */ 130 WCHAR NTAPI 131 RtlDowncaseUnicodeChar(IN WCHAR Source) 132 { 133 PAGED_CODE_RTL(); 134 135 return RtlpDowncaseUnicodeChar(Source); 136 } 137 138 /* 139 * @implemented 140 */ 141 VOID NTAPI 142 RtlGetDefaultCodePage(OUT PUSHORT AnsiCodePage, 143 OUT PUSHORT OemCodePage) 144 { 145 PAGED_CODE_RTL(); 146 147 *AnsiCodePage = NlsAnsiCodePage; 148 *OemCodePage = NlsOemCodePage; 149 } 150 151 /* 152 * @implemented 153 */ 154 VOID NTAPI 155 RtlInitCodePageTable(IN PUSHORT TableBase, 156 OUT PCPTABLEINFO CodePageTable) 157 { 158 PNLS_FILE_HEADER NlsFileHeader; 159 160 PAGED_CODE_RTL(); 161 162 DPRINT("RtlInitCodePageTable() called\n"); 163 164 NlsFileHeader = (PNLS_FILE_HEADER)TableBase; 165 166 /* Copy header fields first */ 167 CodePageTable->CodePage = NlsFileHeader->CodePage; 168 CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize; 169 CodePageTable->DefaultChar = NlsFileHeader->DefaultChar; 170 CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar; 171 CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar; 172 CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar; 173 174 RtlCopyMemory(&CodePageTable->LeadByte, 175 &NlsFileHeader->LeadByte, 176 MAXIMUM_LEADBYTES); 177 178 /* Offset to wide char table is after the header */ 179 CodePageTable->WideCharTable = 180 TableBase + NlsFileHeader->HeaderSize + 1 + TableBase[NlsFileHeader->HeaderSize]; 181 182 /* Then multibyte table (256 wchars) follows */ 183 CodePageTable->MultiByteTable = TableBase + NlsFileHeader->HeaderSize + 1; 184 185 /* Check the presence of glyph table (256 wchars) */ 186 if (!CodePageTable->MultiByteTable[256]) 187 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1; 188 else 189 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1 + 256; 190 191 /* Is this double-byte code page? */ 192 if (*CodePageTable->DBCSRanges) 193 { 194 CodePageTable->DBCSCodePage = 1; 195 CodePageTable->DBCSOffsets = CodePageTable->DBCSRanges + 1; 196 } 197 else 198 { 199 CodePageTable->DBCSCodePage = 0; 200 CodePageTable->DBCSOffsets = NULL; 201 } 202 } 203 204 /* 205 * @implemented 206 */ 207 VOID NTAPI 208 RtlInitNlsTables(IN PUSHORT AnsiTableBase, 209 IN PUSHORT OemTableBase, 210 IN PUSHORT CaseTableBase, 211 OUT PNLSTABLEINFO NlsTable) 212 { 213 PAGED_CODE_RTL(); 214 215 DPRINT("RtlInitNlsTables()called\n"); 216 217 if (AnsiTableBase && OemTableBase && CaseTableBase) 218 { 219 RtlInitCodePageTable(AnsiTableBase, &NlsTable->AnsiTableInfo); 220 RtlInitCodePageTable(OemTableBase, &NlsTable->OemTableInfo); 221 222 NlsTable->UpperCaseTable = (PUSHORT)CaseTableBase + 2; 223 NlsTable->LowerCaseTable = (PUSHORT)CaseTableBase + *((PUSHORT)CaseTableBase + 1) + 2; 224 } 225 } 226 227 /* 228 * @unimplemented 229 */ 230 NTSTATUS NTAPI 231 RtlMultiByteToUnicodeN(OUT PWCHAR UnicodeString, 232 IN ULONG UnicodeSize, 233 OUT PULONG ResultSize, 234 IN PCSTR MbString, 235 IN ULONG MbSize) 236 { 237 ULONG Size = 0; 238 ULONG i; 239 240 PAGED_CODE_RTL(); 241 242 if (!NlsMbCodePageTag) 243 { 244 /* single-byte code page */ 245 if (MbSize > (UnicodeSize / sizeof(WCHAR))) 246 Size = UnicodeSize / sizeof(WCHAR); 247 else 248 Size = MbSize; 249 250 if (ResultSize) 251 *ResultSize = Size * sizeof(WCHAR); 252 253 for (i = 0; i < Size; i++) 254 { 255 UnicodeString[i] = NlsAnsiToUnicodeTable[(UCHAR)MbString[i]]; 256 } 257 } 258 else 259 { 260 /* multi-byte code page */ 261 /* FIXME */ 262 263 UCHAR Char; 264 USHORT LeadByteInfo; 265 PCSTR MbEnd = MbString + MbSize; 266 267 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && MbString < MbEnd; i++) 268 { 269 Char = *(PUCHAR)MbString++; 270 271 if (Char < 0x80) 272 { 273 *UnicodeString++ = Char; 274 continue; 275 } 276 277 LeadByteInfo = NlsLeadByteInfo[Char]; 278 279 if (!LeadByteInfo) 280 { 281 *UnicodeString++ = NlsAnsiToUnicodeTable[Char]; 282 continue; 283 } 284 285 if (MbString < MbEnd) 286 *UnicodeString++ = NlsLeadByteInfo[LeadByteInfo + *(PUCHAR)MbString++]; 287 } 288 289 if (ResultSize) 290 *ResultSize = i * sizeof(WCHAR); 291 } 292 293 return STATUS_SUCCESS; 294 } 295 296 /* 297 * @unimplemented 298 */ 299 NTSTATUS 300 NTAPI 301 RtlConsoleMultiByteToUnicodeN(OUT PWCHAR UnicodeString, 302 IN ULONG UnicodeSize, 303 OUT PULONG ResultSize, 304 IN PCSTR MbString, 305 IN ULONG MbSize, 306 OUT PULONG Unknown) 307 { 308 PAGED_CODE_RTL(); 309 310 UNIMPLEMENTED; 311 DPRINT1("RtlConsoleMultiByteToUnicodeN calling RtlMultiByteToUnicodeN\n"); 312 *Unknown = 1; 313 return RtlMultiByteToUnicodeN(UnicodeString, 314 UnicodeSize, 315 ResultSize, 316 MbString, 317 MbSize); 318 } 319 320 /* 321 * @implemented 322 */ 323 NTSTATUS 324 NTAPI 325 RtlMultiByteToUnicodeSize(OUT PULONG UnicodeSize, 326 IN PCSTR MbString, 327 IN ULONG MbSize) 328 { 329 ULONG Length = 0; 330 331 PAGED_CODE_RTL(); 332 333 if (!NlsMbCodePageTag) 334 { 335 /* single-byte code page */ 336 *UnicodeSize = MbSize * sizeof(WCHAR); 337 } 338 else 339 { 340 /* multi-byte code page */ 341 /* FIXME */ 342 343 while (MbSize--) 344 { 345 UCHAR Char = *(PUCHAR)MbString++; 346 347 if (Char >= 0x80 && NlsLeadByteInfo[Char]) 348 { 349 if (MbSize) 350 { 351 /* Move on */ 352 MbSize--; 353 MbString++; 354 } 355 } 356 357 /* Increase returned size */ 358 Length++; 359 } 360 361 /* Return final size */ 362 *UnicodeSize = Length * sizeof(WCHAR); 363 } 364 365 /* Success */ 366 return STATUS_SUCCESS; 367 } 368 369 /* 370 * @unimplemented 371 */ 372 NTSTATUS NTAPI 373 RtlOemToUnicodeN(OUT PWCHAR UnicodeString, 374 IN ULONG UnicodeSize, 375 OUT PULONG ResultSize OPTIONAL, 376 IN PCCH OemString, 377 IN ULONG OemSize) 378 { 379 ULONG Size = 0; 380 ULONG i; 381 382 PAGED_CODE_RTL(); 383 384 if (!NlsMbOemCodePageTag) 385 { 386 /* single-byte code page */ 387 if (OemSize > (UnicodeSize / sizeof(WCHAR))) 388 Size = UnicodeSize / sizeof(WCHAR); 389 else 390 Size = OemSize; 391 392 if (ResultSize) 393 *ResultSize = Size * sizeof(WCHAR); 394 395 for (i = 0; i < Size; i++) 396 { 397 *UnicodeString = NlsOemToUnicodeTable[(UCHAR)*OemString]; 398 UnicodeString++; 399 OemString++; 400 } 401 } 402 else 403 { 404 /* multi-byte code page */ 405 /* FIXME */ 406 407 UCHAR Char; 408 USHORT OemLeadByteInfo; 409 PCCH OemEnd = OemString + OemSize; 410 411 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && OemString < OemEnd; i++) 412 { 413 Char = *(PUCHAR)OemString++; 414 415 if (Char < 0x80) 416 { 417 *UnicodeString++ = Char; 418 continue; 419 } 420 421 OemLeadByteInfo = NlsOemLeadByteInfo[Char]; 422 423 if (!OemLeadByteInfo) 424 { 425 *UnicodeString++ = NlsOemToUnicodeTable[Char]; 426 continue; 427 } 428 429 if (OemString < OemEnd) 430 *UnicodeString++ = 431 NlsOemLeadByteInfo[OemLeadByteInfo + *(PUCHAR)OemString++]; 432 } 433 434 if (ResultSize) 435 *ResultSize = i * sizeof(WCHAR); 436 } 437 438 return STATUS_SUCCESS; 439 } 440 441 /* 442 * @implemented 443 */ 444 VOID NTAPI 445 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) 446 { 447 PAGED_CODE_RTL(); 448 449 DPRINT("RtlResetRtlTranslations() called\n"); 450 451 /* Set ANSI data */ 452 NlsAnsiToUnicodeTable = (PUSHORT)NlsTable->AnsiTableInfo.MultiByteTable; 453 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable; 454 NlsUnicodeToMbAnsiTable = (PUSHORT)NlsTable->AnsiTableInfo.WideCharTable; 455 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0); 456 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets; 457 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage; 458 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage); 459 460 /* Set OEM data */ 461 NlsOemToUnicodeTable = (PUSHORT)NlsTable->OemTableInfo.MultiByteTable; 462 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable; 463 NlsUnicodeToMbOemTable = (PUSHORT)NlsTable->OemTableInfo.WideCharTable; 464 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0); 465 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets; 466 NlsOemCodePage = NlsTable->OemTableInfo.CodePage; 467 DPRINT("Oem codepage %hu\n", NlsOemCodePage); 468 469 /* Set Unicode case map data */ 470 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; 471 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; 472 473 /* set the default characters for RtlpDidUnicodeToOemWork */ 474 NlsOemDefaultChar = NlsTable->OemTableInfo.DefaultChar; 475 NlsUnicodeDefaultChar = NlsTable->OemTableInfo.TransDefaultChar; 476 } 477 478 /* 479 * @unimplemented 480 */ 481 NTSTATUS NTAPI 482 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, 483 OUT PCHAR CustomString, 484 IN ULONG CustomSize, 485 OUT PULONG ResultSize OPTIONAL, 486 IN PWCHAR UnicodeString, 487 IN ULONG UnicodeSize) 488 { 489 ULONG Size = 0; 490 ULONG i; 491 492 PAGED_CODE_RTL(); 493 494 if (!CustomCP->DBCSCodePage) 495 { 496 /* single-byte code page */ 497 if (UnicodeSize > (CustomSize * sizeof(WCHAR))) 498 Size = CustomSize; 499 else 500 Size = UnicodeSize / sizeof(WCHAR); 501 502 if (ResultSize) 503 *ResultSize = Size; 504 505 for (i = 0; i < Size; i++) 506 { 507 *CustomString = ((PCHAR)CustomCP->WideCharTable)[*UnicodeString]; 508 CustomString++; 509 UnicodeString++; 510 } 511 } 512 else 513 { 514 /* multi-byte code page */ 515 /* FIXME */ 516 ASSERT(FALSE); 517 } 518 519 return STATUS_SUCCESS; 520 } 521 522 /* 523 * @unimplemented 524 */ 525 NTSTATUS NTAPI 526 RtlUnicodeToMultiByteN(OUT PCHAR MbString, 527 IN ULONG MbSize, 528 OUT PULONG ResultSize OPTIONAL, 529 IN PCWCH UnicodeString, 530 IN ULONG UnicodeSize) 531 { 532 ULONG Size = 0; 533 ULONG i; 534 535 PAGED_CODE_RTL(); 536 537 if (!NlsMbCodePageTag) 538 { 539 /* single-byte code page */ 540 Size = (UnicodeSize > (MbSize * sizeof(WCHAR))) 541 ? MbSize : (UnicodeSize / sizeof(WCHAR)); 542 543 if (ResultSize) 544 *ResultSize = Size; 545 546 for (i = 0; i < Size; i++) 547 { 548 *MbString++ = NlsUnicodeToAnsiTable[*UnicodeString++]; 549 } 550 } 551 else 552 { 553 /* multi-byte code page */ 554 /* FIXME */ 555 556 USHORT WideChar; 557 USHORT MbChar; 558 559 for (i = MbSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--) 560 { 561 WideChar = *UnicodeString++; 562 563 if (WideChar < 0x80) 564 { 565 *MbString++ = LOBYTE(WideChar); 566 continue; 567 } 568 569 MbChar = NlsUnicodeToMbAnsiTable[WideChar]; 570 571 if (!HIBYTE(MbChar)) 572 { 573 *MbString++ = LOBYTE(MbChar); 574 continue; 575 } 576 577 if (i >= 2) 578 { 579 *MbString++ = HIBYTE(MbChar); 580 *MbString++ = LOBYTE(MbChar); 581 i--; 582 } 583 else break; 584 } 585 586 if (ResultSize) 587 *ResultSize = MbSize - i; 588 } 589 590 return STATUS_SUCCESS; 591 } 592 593 /* 594 * @implemented 595 */ 596 NTSTATUS 597 NTAPI 598 RtlUnicodeToMultiByteSize(OUT PULONG MbSize, 599 IN PCWCH UnicodeString, 600 IN ULONG UnicodeSize) 601 { 602 ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR); 603 ULONG MbLength = 0; 604 605 PAGED_CODE_RTL(); 606 607 if (!NlsMbCodePageTag) 608 { 609 /* single-byte code page */ 610 *MbSize = UnicodeLength; 611 } 612 else 613 { 614 /* multi-byte code page */ 615 /* FIXME */ 616 617 while (UnicodeLength--) 618 { 619 USHORT WideChar = *UnicodeString++; 620 621 if (WideChar >= 0x80 && HIBYTE(NlsUnicodeToMbAnsiTable[WideChar])) 622 { 623 MbLength += sizeof(WCHAR); 624 } 625 else 626 { 627 MbLength++; 628 } 629 } 630 631 *MbSize = MbLength; 632 } 633 634 /* Success */ 635 return STATUS_SUCCESS; 636 } 637 638 /* 639 * @implemented 640 */ 641 NTSTATUS 642 NTAPI 643 RtlUnicodeToOemN(OUT PCHAR OemString, 644 IN ULONG OemSize, 645 OUT PULONG ResultSize OPTIONAL, 646 IN PCWCH UnicodeString, 647 IN ULONG UnicodeSize) 648 { 649 ULONG Size = 0; 650 651 PAGED_CODE_RTL(); 652 653 /* Bytes -> chars */ 654 UnicodeSize /= sizeof(WCHAR); 655 656 if (!NlsMbOemCodePageTag) 657 { 658 while (OemSize && UnicodeSize) 659 { 660 OemString[Size] = NlsUnicodeToOemTable[*UnicodeString++]; 661 Size++; 662 OemSize--; 663 UnicodeSize--; 664 } 665 } 666 else 667 { 668 while (OemSize && UnicodeSize) 669 { 670 USHORT OemChar = NlsUnicodeToMbOemTable[*UnicodeString++]; 671 672 if (HIBYTE(OemChar)) 673 { 674 if (OemSize < 2) 675 break; 676 OemString[Size++] = HIBYTE(OemChar); 677 OemSize--; 678 } 679 OemString[Size++] = LOBYTE(OemChar); 680 OemSize--; 681 UnicodeSize--; 682 } 683 } 684 685 if (ResultSize) 686 *ResultSize = Size; 687 688 return UnicodeSize ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS; 689 } 690 691 /* 692 * @implemented 693 */ 694 WCHAR NTAPI 695 RtlpUpcaseUnicodeChar(IN WCHAR Source) 696 { 697 USHORT Offset; 698 699 if (Source < 'a') 700 return Source; 701 702 if (Source <= 'z') 703 return (Source - ('a' - 'A')); 704 705 Offset = ((USHORT)Source >> 8) & 0xFF; 706 Offset = NlsUnicodeUpcaseTable[Offset]; 707 708 Offset += ((USHORT)Source >> 4) & 0xF; 709 Offset = NlsUnicodeUpcaseTable[Offset]; 710 711 Offset += ((USHORT)Source & 0xF); 712 Offset = NlsUnicodeUpcaseTable[Offset]; 713 714 return Source + (SHORT)Offset; 715 } 716 717 /* 718 * @implemented 719 */ 720 WCHAR NTAPI 721 RtlUpcaseUnicodeChar(IN WCHAR Source) 722 { 723 PAGED_CODE_RTL(); 724 725 return RtlpUpcaseUnicodeChar(Source); 726 } 727 728 /* 729 * @implemented 730 */ 731 NTSTATUS NTAPI 732 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, 733 OUT PCHAR CustomString, 734 IN ULONG CustomSize, 735 OUT PULONG ResultSize OPTIONAL, 736 IN PWCHAR UnicodeString, 737 IN ULONG UnicodeSize) 738 { 739 WCHAR UpcaseChar; 740 ULONG Size = 0; 741 ULONG i; 742 743 PAGED_CODE_RTL(); 744 745 if (!CustomCP->DBCSCodePage) 746 { 747 /* single-byte code page */ 748 if (UnicodeSize > (CustomSize * sizeof(WCHAR))) 749 Size = CustomSize; 750 else 751 Size = UnicodeSize / sizeof(WCHAR); 752 753 if (ResultSize) 754 *ResultSize = Size; 755 756 for (i = 0; i < Size; i++) 757 { 758 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 759 *CustomString = ((PCHAR)CustomCP->WideCharTable)[UpcaseChar]; 760 ++CustomString; 761 ++UnicodeString; 762 } 763 } 764 else 765 { 766 /* multi-byte code page */ 767 /* FIXME */ 768 ASSERT(FALSE); 769 } 770 771 return STATUS_SUCCESS; 772 } 773 774 /* 775 * @unimplemented 776 */ 777 NTSTATUS NTAPI 778 RtlUpcaseUnicodeToMultiByteN(OUT PCHAR MbString, 779 IN ULONG MbSize, 780 OUT PULONG ResultSize OPTIONAL, 781 IN PCWCH UnicodeString, 782 IN ULONG UnicodeSize) 783 { 784 WCHAR UpcaseChar; 785 ULONG Size = 0; 786 ULONG i; 787 788 PAGED_CODE_RTL(); 789 790 if (!NlsMbCodePageTag) 791 { 792 /* single-byte code page */ 793 if (UnicodeSize > (MbSize * sizeof(WCHAR))) 794 Size = MbSize; 795 else 796 Size = UnicodeSize / sizeof(WCHAR); 797 798 if (ResultSize) 799 *ResultSize = Size; 800 801 for (i = 0; i < Size; i++) 802 { 803 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 804 *MbString = NlsUnicodeToAnsiTable[UpcaseChar]; 805 MbString++; 806 UnicodeString++; 807 } 808 } 809 else 810 { 811 /* multi-byte code page */ 812 /* FIXME */ 813 ASSERT(FALSE); 814 } 815 816 return STATUS_SUCCESS; 817 } 818 819 /* 820 * @unimplemented 821 */ 822 NTSTATUS NTAPI 823 RtlUpcaseUnicodeToOemN(OUT PCHAR OemString, 824 IN ULONG OemSize, 825 OUT PULONG ResultSize OPTIONAL, 826 IN PCWCH UnicodeString, 827 IN ULONG UnicodeSize) 828 { 829 WCHAR UpcaseChar; 830 ULONG Size = 0; 831 ULONG i; 832 833 PAGED_CODE_RTL(); 834 835 if (!NlsMbOemCodePageTag) 836 { 837 /* single-byte code page */ 838 if (UnicodeSize > (OemSize * sizeof(WCHAR))) 839 Size = OemSize; 840 else 841 Size = UnicodeSize / sizeof(WCHAR); 842 843 if (ResultSize) 844 *ResultSize = Size; 845 846 for (i = 0; i < Size; i++) 847 { 848 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 849 *OemString = NlsUnicodeToOemTable[UpcaseChar]; 850 OemString++; 851 UnicodeString++; 852 } 853 } 854 else 855 { 856 /* multi-byte code page */ 857 /* FIXME */ 858 859 USHORT WideChar; 860 USHORT OemChar; 861 862 for (i = OemSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--) 863 { 864 WideChar = RtlpUpcaseUnicodeChar(*UnicodeString++); 865 866 if (WideChar < 0x80) 867 { 868 *OemString++ = LOBYTE(WideChar); 869 continue; 870 } 871 872 OemChar = NlsUnicodeToMbOemTable[WideChar]; 873 874 if (!HIBYTE(OemChar)) 875 { 876 *OemString++ = LOBYTE(OemChar); 877 continue; 878 } 879 880 if (i >= 2) 881 { 882 *OemString++ = HIBYTE(OemChar); 883 *OemString++ = LOBYTE(OemChar); 884 i--; 885 } 886 else break; 887 } 888 889 if (ResultSize) 890 *ResultSize = OemSize - i; 891 } 892 893 return STATUS_SUCCESS; 894 } 895 896 /* 897 * @unimplemented 898 */ 899 CHAR NTAPI 900 RtlUpperChar(IN CHAR Source) 901 { 902 WCHAR Unicode; 903 CHAR Destination; 904 905 PAGED_CODE_RTL(); 906 907 /* Check for simple ANSI case */ 908 if (Source <= 'z') 909 { 910 /* Check for simple downcase a-z case */ 911 if (Source >= 'a') 912 { 913 /* Just XOR with the difference */ 914 return Source ^ ('a' - 'A'); 915 } 916 else 917 { 918 /* Otherwise return the same char, it's already upcase */ 919 return Source; 920 } 921 } 922 else 923 { 924 if (!NlsMbCodePageTag) 925 { 926 /* single-byte code page */ 927 928 /* ansi->unicode */ 929 Unicode = NlsAnsiToUnicodeTable[(UCHAR)Source]; 930 931 /* upcase conversion */ 932 Unicode = RtlpUpcaseUnicodeChar (Unicode); 933 934 /* unicode -> ansi */ 935 Destination = NlsUnicodeToAnsiTable[(USHORT)Unicode]; 936 } 937 else 938 { 939 /* multi-byte code page */ 940 /* FIXME */ 941 Destination = Source; 942 } 943 } 944 945 return Destination; 946 } 947 948 /* EOF */ 949